zio / zio-quill

Compile-time Language Integrated Queries for Scala
https://zio.dev/zio-quill
Apache License 2.0
2.15k stars 348 forks source link

quill-cassandra - support UDTs #311

Closed mmatloka closed 7 years ago

mmatloka commented 8 years ago

They potentially could be just mapped to case classes.

Version: (e.g. 0.5.0) Module: (e.g. quill-cassandra)

@getquill/maintainers

lvicentesanchez commented 8 years ago

I have been thinking about supporting UDT for a while. The main "problem" right know is that quill already has some support for embedded case classes #114.

One possible option is to flag that the case class property is an UDT, e.g.

case class UDT[T](value: T) extends AnyVal

case class Person(name: String, age: Int, address: UDT[Address])

The UDT class would reside in the quill-cassandra submodule and making it a value class means there would be no runtime boxing/unboxing. @getquill/maintainers wdyt about this approach?

mmatloka commented 8 years ago

Hmm, I am not convinced, since it would mean that case class model field would have to be strictly related to underlying library. It would be nicer if it could be even e.g.:

case class Address(value: String) extends AnyVal with UDT[Address]

case class Person(name: String, age: Int, address: Address)

(so it would also be a bit similiar style to https://github.com/getquill/quill#wrapped-types )

lvicentesanchez commented 8 years ago

Yes, you are right. I forgot about what we did for "newtypes"; I like the idea, I would give it a try. On 1 Apr 2016 17:33, "Michal Matloka" notifications@github.com wrote:

Hmm, I am not convinced, since it would mean that case class model field would have to be strictly related to underlying library. It would be nicer if it could be even e.g.:

case class Address(value: String) extends AnyVal with UDT[Address]

case class Person(name: String, age: Int, address: Address)

(so it would also be a bit similiar style to https://github.com/getquill/quill#wrapped-types )

— You are receiving this because you are on a team that was mentioned. Reply to this email directly or view it on GitHub https://github.com/getquill/quill/issues/311#issuecomment-204461885

mosyp commented 7 years ago

Workaround:

CREATE TYPE quill_test.name (
    first text,
    last text
);
CREATE TABLE quill_test.person (
    id int PRIMARY KEY,
    name name
);
case class Name(first: String, last: String)
case class Person(id: Int, name: Name)

trait UdtEncodings {
  this: CassandraSessionContext[_] =>

  implicit def nameUdtDecoder: Decoder[Name] = {
    decoder((index, row) => {
      val udt = row.getUDTValue(index)
      Name(udt.getString("first"), udt.getString("last"))
    })
  }

  implicit def nameUdtEncoder: Encoder[Name] = {
    encoder((index, name, row) => {
      val tpe = session.getCluster.getMetadata.getKeyspace("quill_test").getUserType("name")
      val udt = tpe.newValue()
        .setString("first", name.first)
        .setString("last", name.last)
      row.setUDTValue(index, udt)
    })
  }
}

object Test {
  def main(args: Array[String]): Unit = {
    val ctx = new CassandraSyncContext[SnakeCase]("testSyncDB") with UdtEncodings
    import ctx._
    val persons = quote(querySchema[Person]("quill_test.person"))

    val person = Person(1, Name("test", "name"))
    ctx.run(persons.insert(lift(person)))
    require(ctx.run(persons).head == person)
    ctx.close()
  }
}
arunlpm commented 7 years ago

Any update on this?

mosyp commented 7 years ago

@arunlpm please refer #852, I have started working on in recently and will be glad to get any feedbacks regarding API design and so on.