You can find an example of using a template / dependency template to decouple the Slick driver from the database access level here: https://github.com/slick/slick-examples .
How to separate Slick driver and test application using FakeApplication
A few days ago I wrote a Slick integration library for a game that moves the driver dependency to the application.conf of the Play project: https://github.com/danieldietrich/slick-integration .
Using this library, your example will be implemented as follows:
1) Add the dependency to the /Build.scala project
"net.danieldietrich" %% "slick-integration" % "1.0-SNAPSHOT"
Add Snapshot Repository
resolvers += "Daniel Repository" at "http://danieldietrich.net/repository/snapshots"
Or a local repository if weak integration is published locally
resolvers += Resolver.mavenLocal
2) Add the Slick driver to conf / application.conf
slick.default.driver=scala.slick.driver.H2Driver
3) Deploy application / models / Account.scala
In the case of slick integration, it is assumed that you are using primary keys of type Long, which automatically increase. The name pk is 'id'. The Table / Mapper implementation has default methods (delete, findAll, findById, insert, update). Your objects must implement the "withId", which is necessary for the "insert" method.
package models import scala.slick.integration._ case class Account(id: Option[Long], email: String, password: String) extends Entity[Account] { // currently needed by Mapper.create to set the auto generated id def withId(id: Long): Account = copy(id = Some(id)) } // use cake pattern to 'inject' the Slick driver trait AccountComponent extends _Component { self: Profile => import profile.simple._ object Accounts extends Mapper[Account]("account") { // def id is defined in Mapper def email = column[String]("email") def password = column[String]("password") def * = id.? ~ email ~ password <> (Account, Account.unapply _) } }
4) Deploy application / models / DAL.scala
This is the data access level (DAL) that controllers use to access the database. Transactions are handled by the Table / Mapper implementation in the corresponding component.
package models import scala.slick.integration.PlayProfile import scala.slick.integration._DAL import scala.slick.lifted.DDL import play.api.Play.current class DAL(dbName: String) extends _DAL with AccountComponent with PlayProfile {
5) Implement test / test / AccountSpec.scala
package test import models._ import models.DAL._ import org.specs2.mutable.Specification import play.api.test.FakeApplication import play.api.test.Helpers._ import scala.slick.session.Session class AccountSpec extends Specification { def fakeApp[T](block: => T): T = running(FakeApplication(additionalConfiguration = inMemoryDatabase() ++ Map("slick.default.driver" -> "scala.slick.driver.H2Driver", "evolutionplugin" -> "disabled"))) { try { db.withSession { implicit s: Session => try { create block } finally { drop } } } } "An Account" should { "be creatable" in fakeApp { val account = Accounts.insert(Account(None, "user@gmail.com", "Password")) val id = account.id id mustNotEqual None Accounts.findById(id.get) mustEqual Some(account) } } }
How to determine if database tables already exist
I can not give you a sufficient answer to this question ...
... but maybe this is not the way you want. What if you add an attribute to the table, say Account.active ? If you want to save the data currently stored in your tables, then a script request will be executed. Currently, such an alter script must be written manually. DAL.ddl.createStatements can be used to retrieve create statements. They should be sorted so that they are better compatible with previous versions. Then diff (with the previous version) is used to manually create an alter script. Here evolutions are used to change the db pattern.
Here is an example of how to generate the (first) evolution:
object EvolutionGenerator extends App { import models.DAL import play.api.test._ import play.api.test.Helpers._ running(FakeApplication(additionalConfiguration = inMemoryDatabase() ++ Map("slick.default.driver" -> "scala.slick.driver.PostgresDriver", "evolutionplugin" -> "disabled"))) { val evolution = ( """|# --- !Ups |""" + DAL.ddl.createStatements.mkString("\n", ";\n\n", ";\n") + """| |# --- !Downs |""" + DAL.ddl.dropStatements.mkString("\n", ";\n\n", ";\n")).stripMargin println(evolution) } }