Ответ 1
Вы можете найти пример использования шаблона шаблона/зависимости, чтобы развязать драйвер Slick с уровня доступа к базе данных здесь: https://github.com/slick/slick-examples.
Как отделить драйвер Slick и тестовое приложение с помощью FakeApplication
Несколько дней назад я написал библиотеку интеграции Slick для игры, которая перемещает зависимость драйвера к application.conf проекта Play: https://github.com/danieldietrich/slick-integration.
С помощью этой библиотеки ваш пример будет реализован следующим образом:
1) Добавьте зависимость к проекту /Build.scala
"net.danieldietrich" %% "slick-integration" % "1.0-SNAPSHOT"
Добавить репозиторий снимков
resolvers += "Daniel Repository" at "http://danieldietrich.net/repository/snapshots"
Или локальный репозиторий, если слабая интеграция публикуется локально
resolvers += Resolver.mavenLocal
2) Добавьте драйвер Slick в conf/application.conf
slick.default.driver=scala.slick.driver.H2Driver
3) Внедрить приложение/модели/Account.scala
В случае slick-интеграции предполагается, что вы используете первичные ключи типа Long, которые автоматически увеличиваются. Имя pk - 'id'. Реализация Table/Mapper имеет методы по умолчанию (delete, findAll, findById, insert, update). Ваши объекты должны реализовать "withId", который необходим методу "insert".
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) Внедрить приложение/модели/DAL.scala
Это уровень доступа к данным (DAL), который используется контроллерами для доступа к базе данных. Транзакции обрабатываются реализацией Table/Mapper в соответствующем компоненте.
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 FooBarBazComponent */ with PlayProfile {
// trait Profile implementation
val profile = loadProfile(dbName)
def db = dbProvider(dbName)
// _DAL.ddl implementation
lazy val ddl: DDL = Accounts.ddl // ++ FooBarBazs.ddl
}
object DAL extends DAL("default")
5) Внедрить тест/тест/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, "[email protected]", "Password"))
val id = account.id
id mustNotEqual None
Accounts.findById(id.get) mustEqual Some(account)
}
}
}
Как определить, существуют ли уже таблицы базы данных
Я не могу дать вам достаточный ответ на этот вопрос...
... но, возможно, это не так, как вы хотите. Что делать, если вы добавляете атрибут в таблицу, скажем Account.active
? Если вы хотите сохранить данные, хранящиеся в настоящее время в ваших таблицах, тогда будет выполнен запрос script. В настоящее время такой alter script должен быть написан вручную. DAL.ddl.createStatements
можно использовать для извлечения операторов create. Их следует сортировать, чтобы они были лучше сопоставимы с предыдущими версиями. Затем diff (с предыдущей версией) используется для ручного создания alter script. Здесь эволюции используются для изменения схемы db.
Вот пример того, как генерировать (первую) эволюцию:
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)
}
}