Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slick 3.0.0 database agnostism

Tags:

scala

slick

I started to use Slick 3.0.0 and I like it's succinct syntax. Nevertheless, I wasn't able to find a way to use it in a database agnostic way.

In the following example provided in the documentation: http://slick.typesafe.com/doc/3.0.0/gettingstarted.html

I'd like to be able to decouple somehow this code of the database used and avoid importing database specific in my code (i.e slick.driver.H2Driver.api._).

I tried to get rid of it by providing the connection using the cake pattern, but the ".result" member isn't available then.

A workaround would be to import slick.driver.JdbcDriver.api._, but it is deprecated and thus should not be a good starting point.

Anyone found a way to use Slick 3.0.0 in a database agnostic and elegant way?

This question isn't far of "How to write database-agnostic Play application and perform first-time database initialization?", but that one focuses on Slick 3.0.0. Sadely the answers provided with that former question aren't targetting Slick 3.0.0 except one which uses deprecated code.

like image 378
raphael Avatar asked Feb 09 '23 17:02

raphael


1 Answers

The slick driver class you're looking for is slick.driver.JdbcProfile.

There's an official example project slick-multidb which you can obtain through activator (github). Here's the relevant code:

import scala.language.higherKinds
import slick.driver.JdbcProfile

/** All database code goes into the DAO (data access object) class which
  * is parameterized by a Slick driver that implements JdbcProfile.
  */
class DAO(val driver: JdbcProfile) {
  // Import the Scala API from the driver
  import driver.api._

  class Props(tag: Tag) extends Table[(String, String)](tag, "PROPS") {
    def key = column[String]("KEY", O.PrimaryKey)
    def value = column[String]("VALUE")
    def * = (key, value)
  }
  val props = TableQuery[Props]

  /** Create the database schema */
  def create: DBIO[Unit] =
    props.ddl.create

  /** Insert a key/value pair */
  def insert(k: String, v: String): DBIO[Int] =
    props += (k, v)

  /** Get the value for the given key */
  def get(k: String): DBIO[Option[String]] =
    (for(p <- props if p.key === k) yield p.value).result.headOption

  /** Get the first element for a Query from this DAO */
  def getFirst[M, U, C[_]](q: Query[M, U, C]): DBIO[U] =
    q.result.head
}

Client code:

val dao = new DAO(H2Driver)
import dao.driver.api._
db.run(dao.insert("foo", "bar"))
like image 129
dwickern Avatar answered Feb 12 '23 08:02

dwickern