import doobie.imports._
import doobie.util.iolite.IOLite
import doobie.util.transactor.Transactor
import java.util.UUID
import scalaz.Scalaz._
val xa: Transactor[IOLite] =
[IOLite](
DriverManagerTransactor"org.h2.Driver"
, "jdbc:h2:mem:db"
, ""
, ""
)
val prepareDb: ConnectionIO[Int] =
"""create table if not exists people (
sql id char(36) not null unique
, name varchar(512) not null
, email varchar(512) not null unique
, primary key(id)
)
""".update.run
This is an "incomplete" person record, as it lacks an ID.
case class NewPerson(name: String, email: String)
We'll need to tell Doobie/Shapeless how to serialize and deserialize a Java UUID into a database string for our table row IDs.
implicit val UUIDMeta: Meta[UUID] =
[String].nxmap(UUID.fromString, _.toString) Meta
INSERT
querydef addPerson(x: NewPerson): ConnectionIO[Int] =
"""insert into people (id, name, email)
sql values (
${UUID.randomUUID}
, ${x.name}
, ${x.email}
)
""".update.run
case class Person(id: UUID, name: String, email: String)
SELECT
querydef getPeople: ConnectionIO[List[Person]] =
(sql"""select id, name, email
from people
""".query[Person]
).list
val composed: ConnectionIO[Unit] =
*>
prepareDb addPerson(NewPerson("James Earl Douglas", "james@earldouglas.com")) *>
addPerson(NewPerson("Johnny McDoe", "johnny@mcdoe")) *>
{ xs =>
getPeople map println("# People")
{
xs map case Person(id, name, email) =>
println()
println(s"## ${name}")
println()
println(s"* ID: ${id.toString}")
println(s"* Email: ${email}")
}
}
.transact(xa).unsafePerformIO composed
/***
+= "org.tpolecat" %% "doobie-core" % "0.4.4"
libraryDependencies += "com.h2database" % "h2" % "1.4.200"
libraryDependencies */
This file is literate Scala, and can be run using Codedown:
$ curl https://earldouglas.com/posts/scala/doobie.md |
codedown scala > script.scala
$ sbt -Dsbt.main.class=sbt.ScriptMain script.scala
# People
## James Earl Douglas
* ID: 71b4dc58-6031-44a8-a8e8-9c63ea2b7514
* Email: james@earldouglas.com
## Johnny McDoe
* ID: e0f7b4c5-aca8-4025-8998-e7653d834509
* Email: johnny@mcdoe