blocking-slick ![Build Status](https://camo.githubusercontent.com/6b4e0d6176ad41227949cba37f0d72493cf7bf254b5350ebe2d26a382e5f9cfe/68747470733a2f2f7472617669732d63692e6f72672f74616b657a6f652f626c6f636b696e672d736c69636b2e7376673f6272616e63683d6d6173746572)
Provides Slick2 compatible blocking API for Slick3.
Setup
Add following dependency to your build.sbt
:
// for Slick 3.3
libraryDependencies += "com.github.takezoe" %% "blocking-slick-33" % "0.0.13"
// for Slick 3.2
libraryDependencies += "com.github.takezoe" %% "blocking-slick-32" % "0.0.11"
// for Slick 3.1
libraryDependencies += "com.github.takezoe" %% "blocking-slick-31" % "0.0.7"
You can enable blocking API by import the blocking driver as follows:
import com.github.takezoe.slick.blocking.BlockingH2Driver.blockingApi._
Slick2 style blocking API
See the example of use of blocking API provided by blocking-slick:
val db = Database.forURL("jdbc:h2:mem:test")
db.withSession { implicit session =>
// Create tables
models.Tables.schema.create
// Insert
Users.insert(UsersRow(1, "takezoe"))
// Insert returning new id
val newID: Long = (Users returning Users.map(_.id)).insert(UsersRow(1, "takezoe"))
// Select
val users: Seq[UserRow] = Users.list
// Select single record
val user: UserRow = Users.filter(_.id === "takezoe".bind).first
// Select single record with Option
val user: Option[UserRow] = Users.filter(_.id === "takezoe".bind).firstOption
// Update
Users.filter(t => t.id === 1.bind).update(UsersRow(1, "naoki"))
// Delete
Users.filter(t => t.id === 1.bind).delete
// Drop tables
models.Tables.schema.remove
}
Plain sql can be executed synchronously as well.
val id = 1
val name = "takezoe"
val insert = sqlu"INSERT INTO USERS (ID, NAME) VALUES (${id1}, ${name1})"
insert.execute
Transaction is available by using withTransaction
instead of withSession
:
// Transaction
db.withTransaction { implicit session =>
...
}
DBIO support
blocking-slick also provides a way to run DBIO
synchronously. It would help to rewrite Slick2 style code to Slick3 style code gradually.
db.withSession { implicit session =>
val id1 = 1
val id2 = 2
val name1 = "takezoe"
val name2 = "chibochibo"
val insert1 = sqlu"INSERT INTO USERS (ID, NAME) VALUES (${id1}, ${name1})" andThen
sqlu"INSERT INTO USERS (ID, NAME) VALUES (${id2}, ${name2})"
insert1.run
val query = for {
count <- sql"SELECT COUNT(*) FROM USERS".as[Int].head
max <- sql"SELECT MAX(ID) FROM USERS".as[Int].head
} yield (count, max)
val (count1, max1) = query.run
assert(count1 == 2)
assert(max1 == 2)
}
Note that using flatMap
and andThen
requires an ExecutionContext
, but if you run that code synchronously that value will be ignored.
Resources
You can see actual codes in the testcase, and also a blocking-slick with Play2 and play-slick example is available at here.