Technology•August 8, 2017
Writing Scala Codecs for the Java Driver
def getIntOption(index: Int): Option[Int] = ...
import com.datastax.driver.core._
val codec: TypeCodec[Option[Int]] = OptionCodec(IntCodec)
assert(codec.deserialize(ByteBuffer.allocate(0), ProtocolVersion.V4).isEmpty)
assert(codec.deserialize(ByteBuffer.allocate(4), ProtocolVersion.V4).isDefined)
import com.datastax.driver.core._
val codec: TypeCodec[Option[Int]] = OptionCodec(IntCodec)
val row: Row = ??? // some CQL query containing an int column
val v: Option[Int] = row.get(0, codec)
import com.datastax.driver.core._
// first
val codec: TypeCodec[Option[Int]] = OptionCodec(IntCodec)
cluster.getConfiguration.getCodecRegistry.register(codec)
// then
val row: Row = ??? // some CQL query containing an int column
val v: Option[Int] = row.get(0, ???) // How to get a TypeToken[Option[Int]]?
import com.datastax.driver.core._
val tt = TypeTokens.optionOf(TypeTokens.int) // creates a TypeToken[Option[Int]]
val row: Row = ??? // some CQL query containing an int column
val v: Option[Int] = row.get(0, tt)
import com.datastax.driver.core._
type Seq[+A] = scala.collection.immutable.Seq[A]
val codec: TypeCodec[Seq[Int]] = SeqCodec(OptionCodec(IntCodec))
val l = List(Some(1), None)
assert(codec.deserialize(codec.serialize(l, ProtocolVersion.V4), ProtocolVersion.V4) == l)
object Implicits {
implicit val protocolVersion = ProtocolVersion.NEWEST_SUPPORTED
implicit val codecRegistry = CodecRegistry.DEFAULT_INSTANCE
}
trait VersionAgnostic[T] { this: TypeCodec[T] =>
def serialize(value: T)(implicit protocolVersion: ProtocolVersion, marker: ClassTag[T]): ByteBuffer =
this.serialize(value, protocolVersion)
def deserialize(bytes: ByteBuffer)(implicit protocolVersion: ProtocolVersion, marker: ClassTag[T]): T =
this.deserialize(bytes, protocolVersion)
}
import Implicits._
val codec = new SeqCodec(IntCodec) with VersionAgnostic[Seq[Int]]
codec.serialize(List(1,2,3))
object SeqCodec {
def apply[E](eltCodec: TypeCodec[E]): SeqCodec[E] = new SeqCodec[E](eltCodec)
import scala.reflect.runtime.universe._
def apply[E](implicit eltTag: TypeTag[E]): SeqCodec[E] = {
val eltCodec = ??? // implicit TypeTag -> TypeCodec conversion
apply(eltCodec)
}
}
val codec = SeqCodec[Option[Int]]
def apply[E](implicit eltTag: TypeTag[E]): SeqCodec[E] = {
val eltCodec = TypeConversions.toCodec[E](eltTag.tpe)
apply(eltCodec)
}
val statement: BoundStatement = ???
statement.set(0, List(1,2,3)) // implicit TypeTag -> TypeToken conversion
val row: Row = ???
val list: Seq[Int] = row.get(0) // implicit TypeTag -> TypeToken conversion
def getImplicitly[T](i: Int)(implicit typeTag: TypeTag[T]): T =
val javaType: java.lang.reflect.Type = TypeConversions.toJavaType(typeTag.tpe)
self.get(i, TypeToken.of(javaType).wrap().asInstanceOf[TypeToken[T]])
statement.setImplicitly(0, List(1,2,3)) // implicitly converted to statement.setImplicitly(0, List(1,2,3)) (TypeTag[Seq[Int]]), then
// implicitly converted to statement.set (0, List(1,2,3), TypeToken[Seq[Int]])
val list = row.getImplicitly[Seq[Int]](0) // implicitly converted to statement.getImplicitly(0) (TypeTag[Seq[Int]]), then
// implicitly converted to statement.get (0, TypeToken[Seq[Int]])