thlim
thlim

Reputation: 2982

Doobie Query for Entities with Value Class Fields

I am using Doobie to manage database persistence. I use value class fields in my entity Foo i.e.

    case class CreatedOn(value: LocalDateTime) extends AnyVal
    case class Resource(value: String) extends AnyVal
    case class Foo(id: Option[Int], resource: Resource, createdOn: CreatedOn)

    implicit fooRead: Read[Foo] = Read[(Option[Int], String, LocalDateTime)].map {
        case (oid, resource, createdOn) => Foo(oid, Resource(resource), CreatedOn(createdOn))
    }

    implicit fooWrite: Write[Foo] = Write[(Option[Int], String, LocalDateTime)].contramap {e => (e.oid, e.resource.value, e.createdOn.value}

Yet the compiler complains missing Read[(Int, String, LocalDateTime)].map {... Any suggestions on how I can fix this? Is using value class a bad idea, to begin with, when comes to the entity? Thanks

Upvotes: 0

Views: 853

Answers (1)

Mateusz Kubuszok
Mateusz Kubuszok

Reputation: 27535

Doobie is able to read queries into case classes. If you imagine case classes as tuples and you imagine that you can flatten them then this is what Doobie does when you query things into a case class.

Foo(Some(1), Resource("test"), CreatedOn(time))
(Some(1), Tuple1("test"), Tuple1(time))
(Some(1), "test", time) // (Option[Int], String, LocalDateTime)

If your derivation fails you can check for which of these fields:

sql"".query[Int]
sql"".query[String]
sql"".query[LocalDateTime]

The line which fail compilation tells you the missing instance.

From my experience it is time instance. You have to import them separately, which you probably didn't import

doobie.implicits.javatime._

Upvotes: 2

Related Questions