Permalink
Browse files

Add a Doobie example.

  • Loading branch information...
guillaumebort committed Nov 10, 2017
1 parent 70eee6f commit 4b6e2ef5ef814644d7e1ab442a26d919ec932a8c
Showing with 87 additions and 1 deletion.
  1. +1 −0 README.md
  2. +7 −1 build.sbt
  3. +79 −0 examples/src/main/scala/DatabaseAccess.scala
View
@@ -57,6 +57,7 @@ For those who prefer documentation by example, you can also follow these hands-o
- [Serving files from classpath](https://criteo.github.io/lolhttp/examples/ServingFiles.scala.html).
- [A Github API client](https://criteo.github.io/lolhttp/examples/GithubClient.scala.html).
- [A JSON web service](https://criteo.github.io/lolhttp/examples/JsonWebService.scala.html).
- [Accessing an SQL Database](https://criteo.github.io/lolhttp/examples/DatabaseAccess.scala.html).
- [Reading large request streams](https://criteo.github.io/lolhttp/examples/LargeFileUpload.scala.html).
- [A simple reverse proxy](https://criteo.github.io/lolhttp/examples/ReverseProxy.scala.html).
- [An HTTP/2 server](https://criteo.github.io/lolhttp/examples/Http2Server.scala.html).
View
@@ -159,6 +159,11 @@ lazy val examples: Project =
publishArtifact := false,
libraryDependencies ++= Seq(
"org.tpolecat" %% "doobie-core",
"org.tpolecat" %% "doobie-h2"
).map(_ % "0.5.0-M9"),
fork in IntegrationTest := true,
// Running integration tests with Java 8 requires to install the right version of alpn-boot.
@@ -176,14 +181,15 @@ lazy val examples: Project =
settings(
Option(System.getProperty("generateExamples")).map(_ => Seq(
autoCompilerPlugins := true,
addCompilerPlugin("com.criteo.socco" %% "socco-plugin" % "0.1.6"),
addCompilerPlugin("com.criteo.socco" %% "socco-plugin" % "0.1.9"),
scalacOptions := Seq(
"-P:socco:out:examples/target/html",
"-P:socco:package_lol.html:https://criteo.github.io/lolhttp/api/",
"-P:socco:package_lol.json:https://criteo.github.io/lolhttp/api/",
"-P:socco:package_lol.http:https://criteo.github.io/lolhttp/api/",
"-P:socco:package_scala.concurrent:http://www.scala-lang.org/api/current/",
"-P:socco:package_io.circe:http://circe.github.io/circe/api/",
"-P:socco:package_doobie:https://www.javadoc.io/doc/org.tpolecat/doobie-core_2.12/0.5.0-M8",
"-P:socco:package_cats.effect:https://oss.sonatype.org/service/local/repositories/releases/archive/org/typelevel/cats-effect_2.12/0.4/cats-effect_2.12-0.4-javadoc.jar/!/",
"-P:socco:package_fs2:https://oss.sonatype.org/service/local/repositories/releases/archive/co/fs2/fs2-core_2.12/0.9.4/fs2-core_2.12-0.9.4-javadoc.jar/!/"
)
@@ -0,0 +1,79 @@
// Example: Accessing an SQL Database
// Let's write a Web service that talk to an SQL database. We
// will use [doobie](http://tpolecat.github.io/doobie/) as JDBC layer.
import lol.http._
import lol.html._
// We will configure doobie to use the cats `IO` effect,
// so it will play well with lolhttp 🎉.
import cats.effect.{ IO }
// Now we just import the needed package for doobie.
import doobie.h2._
import doobie.h2.implicits._
import doobie.implicits._
import scala.concurrent.ExecutionContext.Implicits.global
object DatabaseAccess {
def main(args: Array[String]): Unit = {
// First create the database schema.
val createTable = sql"""
CREATE TABLE country (
code character(3) NOT NULL,
name text NOT NULL
);
"""
// Also we need to import fake data for the example.
val importData = sql"""
INSERT INTO country (code, name) VALUES
('FR', 'France'),
('US', 'United States'),
('DE', 'GERMANY');
"""
// This is our setup script. Connect to the database, create the schema
// and import the data.
val setup = for {
xa <- H2Transactor[IO]("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", "sa", "")
_ <- xa.setMaxConnections(10)
_ <- (createTable ++ importData).update.run.transact(xa)
} yield (xa)
// We run our setup script to startup the database and we keep a
// reference to the Transactor.
val xa = setup.unsafeRunSync
// Now let's focus on the HTTP service.
Server.listen(8888) { req =>
// Here we simply use doobie to query the database. This in an _effect_ and
// so the result is wrapped into an `IO`.
sql"SELECT code, name FROM country".
query[(String,String)].
list.
transact(xa).
map { resultSet =>
// Let's transform our database result set to an HTML list
val countries = resultSet.map { case (code, name) =>
html"<li><strong>${code}</strong> - ${name}</li>"
}
// Finally we give back an Ok HTTP response.
Ok(html"""
<h1>${resultSet.size} Countries:</h1>
<ul>
$countries
</ul>
""")
}
}
println("Listening on http://localhost:8888...")
}
}

0 comments on commit 4b6e2ef

Please sign in to comment.