简体   繁体   中英

How do I convert a java.util.UUID to doobie.syntax.SqlInterpolator.SingleFragment?

I am trying to set up a simple scala app with database using doobie, http4s and circe.

How do I convert a java.util.UUID to doobie.syntax.SqlInterpolator.SingleFragment ?

final case class User(id: UUID, details: UserDetails)
  implicit val userDecoder: Decoder[User] = deriveDecoder[User]
  implicit def userEntityDecoder[F[_]: Sync]: EntityDecoder[F, User] = jsonOf

  implicit val userEncoder: Encoder[User] = deriveEncoder[User]
  implicit def userEntityEncoder[F[_]: Applicative]: EntityEncoder[F, User] = jsonEncoderOf

  implicit val put: Put[User] =
    Put[Json].contramap(_.asJson)

  implicit val get: Get[User] =
    Get[Json].temap(_.as[User].left.map(_.show))

[info] welcome to sbt 1.3.12 (N/A Java 14.0.1)
[info] loading global plugins from /Users/ryan/.sbt/1.0/plugins
[info] loading settings for project bobbymoore-build from plugins.sbt ...
[info] loading project definition from /Users/ryan/fullStackRyan/bobbymoore/project
[info] loading settings for project root from build.sbt ...
[info] set current project to bobbymoore (in build file:/Users/ryan/fullStackRyan/bobbymoore/)
[info] sbt server started at local:///Users/ryan/.sbt/1.0/server/90f560b1e0964865fc4c/sock
sbt:bobbymoore> compile
[info] Compiling 1 Scala source to /Users/ryan/fullStackRyan/bobbymoore/target/scala-2.13/classes ...
[error] /Users/ryan/fullStackRyan/bobbymoore/src/main/scala/com/c/bobbymoore/database/UserQueries.scala:24:20: type mismatch;
[error]  found   : java.util.UUID
[error]  required: doobie.syntax.SqlInterpolator.SingleFragment
[error]          |  ${user.id},
[error]                    ^
[error] /Users/ryan/fullStackRyan/bobbymoore/src/main/scala/com/c/bobbymoore/database/UserQueries.scala:34:21: type mismatch;
[error]  found   : java.util.UUID
[error]  required: doobie.syntax.SqlInterpolator.SingleFragment
[error]          |WHERE id=$id
[error]                     ^
[error] two errors found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 2 s, completed 13 Oct 2020, 16:31:46

If you are using PostgreSQL and the UUID in Java translate to UUID column in Postgres table, then you have to use a Postgres extensions for Doobie

// other doobie imports
import doobie.postgres._
import doobie.postgres.implicits._

sql"""SELECT id, name FROM users WHERE id = ${user.id}""".query[(UUID, String)]

If you don't use PSQL and this UUID maps to TEXT field you have to either map this yourself in query:

sql"""SELECT id, name FROM users WHERE id = ${user.id.toString}"""
  .query[(String, String)]
  .map { case (uuid, name) => (UUID.fromString(uuid), name) }

or define your own Meta[UUID] instance eg

implicit val uuidMeta: Meta[UUID] =
  Meta[String].imap[UUID](UUID.fromString)(_.toString)

This one is needed if you want to derive an instance for eg case class that contains UUID. Postgres extensions library delivers one that matches PSQL implementation.

You surely have to define your own Meta instance if you use eg Array[Byte] or some other numeric representation on DB side to represent UUIDs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM