Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the operations as[Model] and asList[Model] to the interpolator #93

Closed
fedefernandez opened this issue Oct 19, 2017 · 0 comments
Closed
Assignees
Milestone

Comments

@fedefernandez
Copy link
Contributor

fedefernandez commented Oct 19, 2017

Once we have in place #101, we can take advantage of it and implement these 2 different methods to return a case class or list of case classes instead of a ResultSet.

The idea is to add a couple of methods to the InterpolatorOps:

def as[M[_], T](consistencyLevel: Option[ConsistencyLevel] = None)(
  implicit API: SessionAPI[M], FR: FromReader[T]): FreeS[M, T] = ???

def asList[M[_], T](consistencyLevel: Option[ConsistencyLevel] = None)(
  implicit API: SessionAPI[M], FR: FromReader[T]): FreeS[M, List[T]] = ???

See the FromReader code for reference:

trait FromReader[A] {
def apply[M[_]](reader: ByteBufferReader)(implicit ME: MonadError[M, Throwable]): M[A]
}
trait GenericFromReader {
implicit val hnilFromReader: FromReader[HNil] = new FromReader[HNil] {
override def apply[M[_]](reader: ByteBufferReader)(
implicit ME: MonadError[M, Throwable]): M[HNil] = ME.pure(HNil)
}
implicit def hconsFromReader[K <: Symbol, V, L <: HList](
implicit
witness: Witness.Aux[K],
codec: ByteBufferCodec[V],
grT: FromReader[L],
printer: Printer): FromReader[FieldType[K, V] :: L] =
new FromReader[FieldType[K, V] :: L] {
override def apply[M[_]](reader: ByteBufferReader)(
implicit ME: MonadError[M, Throwable]): M[FieldType[K, V] :: L] = {
val newName = printer.print(witness.value.name)
ME.flatMap(reader.read(newName)) { byteBuffer =>
ME.map2(codec.deserialize(byteBuffer), grT(reader)) {
case (result, l) => new FieldBuilder[K].apply(result) :: l
}
}
}
}
implicit def productFromReader[A, L <: HList](
implicit
gen: LabelledGeneric.Aux[A, L],
grL: FromReader[L]): FromReader[A] =
new FromReader[A] {
override def apply[M[_]](reader: ByteBufferReader)(
implicit ME: MonadError[M, Throwable]): M[A] = ME.map(grL(reader))(gen.from)
}
}
object GenericFromReader extends GenericFromReader

The tests are located in the file InterpolatorImplicitSpec:

"InterpolatorImplicitDef asResultSet" should {
implicit val interpreter = sessionAPIHandler[Future] andThen apiInterpreter[Future, Session](
sessionMock)
"return a valid ResultSet from a FreeS" in {
val future: Future[ResultSet] =
cql"SELECT * FROM users".asResultSet[SessionAPI.Op]().interpret[Future]
Await.result(future, Duration.Inf) shouldBe rsMock
}
"return a valid ResultSet from a FreeS when passing a ConsistencyLevel" in {
val future: Future[ResultSet] =
cql"SELECT * FROM users"
.asResultSet[SessionAPI.Op](Some(consistencyLevel))
.interpret[Future]
Await.result(future, Duration.Inf) shouldBe rsMock
(sessionMock
.executeAsync(_: Statement))
.verify(where { (st: Statement) => st.getConsistencyLevel == consistencyLevel
})
}
"return a failed future when the ByteBufferCodec returns a failure" in {
val serializeException = new RuntimeException("Error serializing")
implicit val stringByteBufferCodec: ByteBufferCodec[String] = new ByteBufferCodec[String] {
override def deserialize[M[_]](bytes: ByteBuffer)(
implicit E: MonadError[M, Throwable]): M[String] =
E.raiseError(new RuntimeException("Error deserializing"))
override def serialize[M[_]](value: String)(
implicit E: MonadError[M, Throwable]): M[ByteBuffer] =
E.raiseError(serializeException)
}
val name: String = "UserName"
val future: Future[ResultSet] =
cql"SELECT * FROM users WHERE name=$name".asResultSet[SessionAPI.Op]().interpret[Future]
Await.result(future.failed, Duration.Inf) shouldBe serializeException
}
"return a failed future when the ByteBufferCodec returns a failure when passing a ConsistencyLevel" in {
val serializeException = new RuntimeException("Error serializing")
implicit val stringByteBufferCodec: ByteBufferCodec[String] = new ByteBufferCodec[String] {
override def deserialize[M[_]](bytes: ByteBuffer)(
implicit E: MonadError[M, Throwable]): M[String] =
E.raiseError(new RuntimeException("Error deserializing"))
override def serialize[M[_]](value: String)(
implicit E: MonadError[M, Throwable]): M[ByteBuffer] =
E.raiseError(serializeException)
}
val name: String = "UserName"
val future: Future[ResultSet] =
cql"SELECT * FROM users WHERE name=$name"
.asResultSet[SessionAPI.Op](Some(consistencyLevel))
.interpret[Future]
Await.result(future.failed, Duration.Inf) shouldBe serializeException
}
}
"InterpolatorImplicitDef attemptResultSet()" should {
"return a valid ResultSet" in {
val future: Future[ResultSet] = cql"SELECT * FROM users".attemptResultSet[Future]()
Await.result(future, Duration.Inf) shouldBe rsMock
}
"return a valid ResultSet when passing a ConsistencyLevel" in {
val future: Future[ResultSet] =
cql"SELECT * FROM users".attemptResultSet[Future](Some(consistencyLevel))
Await.result(future, Duration.Inf) shouldBe rsMock
(sessionMock
.executeAsync(_: Statement))
.verify(where { (st: Statement) => st.getConsistencyLevel == consistencyLevel
})
}
"return a failed future when the ByteBufferCodec returns a failure" in {
val serializeException = new RuntimeException("Error serializing")
implicit val stringByteBufferCodec: ByteBufferCodec[String] = new ByteBufferCodec[String] {
override def deserialize[M[_]](bytes: ByteBuffer)(
implicit E: MonadError[M, Throwable]): M[String] =
E.raiseError(new RuntimeException("Error deserializing"))
override def serialize[M[_]](value: String)(
implicit E: MonadError[M, Throwable]): M[ByteBuffer] =
E.raiseError(serializeException)
}
val name: String = "UserName"
val future: Future[ResultSet] =
cql"SELECT * FROM users WHERE name=$name".attemptResultSet[Future]()
Await.result(future.failed, Duration.Inf) shouldBe serializeException
}
"return a failed future when the ByteBufferCodec returns a failure when passing a ConsistencyLevel" in {
val serializeException = new RuntimeException("Error serializing")
implicit val stringByteBufferCodec: ByteBufferCodec[String] = new ByteBufferCodec[String] {
override def deserialize[M[_]](bytes: ByteBuffer)(
implicit E: MonadError[M, Throwable]): M[String] =
E.raiseError(new RuntimeException("Error deserializing"))
override def serialize[M[_]](value: String)(
implicit E: MonadError[M, Throwable]): M[ByteBuffer] =
E.raiseError(serializeException)
}
val name: String = "UserName"
val future: Future[ResultSet] =
cql"SELECT * FROM users WHERE name=$name".attemptResultSet[Future](Some(consistencyLevel))
Await.result(future.failed, Duration.Inf) shouldBe serializeException
}
}

@fedefernandez fedefernandez self-assigned this Oct 19, 2017
@fedefernandez fedefernandez added this to the Sprint 9 milestone Oct 20, 2017
@fedefernandez fedefernandez removed their assignment Oct 23, 2017
@fedefernandez fedefernandez removed this from the Sprint 9 milestone Oct 23, 2017
@fedefernandez fedefernandez self-assigned this Nov 6, 2017
@anamariamv anamariamv added this to the Sprint 10 milestone Nov 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants