使用Scala 2.10.2和Slick 2.1.0,我正在爲SQLite數據庫編寫一個包裝器。對於測試,我希望能夠創建一個內存數據庫,使用我的表填充它,插入一些數據,然後運行測試查詢。玩具相當於我的數據庫在下面的工作代碼段概述:Scala內存數據庫SQLite沒有這樣的表
import org.sqlite.JDBC
import scala.slick.driver.SQLiteDriver.simple._
object MyDB
{
def testMemory() : Unit = MyDB.withMemoryTestDatabase(test)
def testFile() : Unit = MyDB.withFileTestDatabase(test)
val test : (MyDB) => Unit =
{
(mydb) => mydb.database.withSession{ implicit session => {
mydb.metadata.map(m => (m.key, m.value)).insert(("foo", "bar"))
assert(mydb.metadata("foo") == "bar")
} }
}
def withMemoryTestDatabase(testFunction : (MyDB) => Unit) : Unit =
{
val backend = new MyDB(Database.forURL("jdbc:sqlite::memory:", driver = "org.sqlite.JDBC"))
runTest(backend, testFunction)
}
def withFileTestDatabase(testFunction : (MyDB) => Unit) : Unit =
{
val backend = new MyDB(Database.forURL("jdbc:sqlite:test.sqlite", driver = "org.sqlite.JDBC"))
runTest(backend, testFunction)
val dbPath = new java.io.File("test.sqlite")
dbPath.delete
}
def runTest(backend : MyDB, testFunction : (MyDB) => Unit) : Unit =
{
backend.database.withSession{ implicit session => backend.metadata.ddl.create }
testFunction(backend)
}
}
class MyDB(val database : slick.driver.SQLiteDriver.backend.DatabaseDef)
{
class Metadata(tag : Tag) extends Table[(String,String)](tag, "Metadata")
{
def key = column[String]("key")
def value = column[String]("value")
def * = (key, value)
}
object metadata extends TableQuery(new Metadata(_))
{
def apply(key : String) : String = database.withSession { implicit session => this.map(m => (m.key, m.value)).run.toMap.apply(key) }
}
}
我現在遇到的問題是,與該代碼,MyDB.testFile()
運行完美。但是,MyDB.testMemory()
失敗,說元數據表不存在。完整的錯誤和追溯在這裏:
scala> MyDB.testFile
scala> MyDB.testMemory
java.sql.SQLException: [SQLITE_ERROR] SQL error or missing database (no such table: Metadata)
at org.sqlite.DB.newSQLException(DB.java:383)
at org.sqlite.DB.newSQLException(DB.java:387)
at org.sqlite.DB.throwex(DB.java:374)
at org.sqlite.NativeDB.prepare(Native Method)
at org.sqlite.DB.prepare(DB.java:123)
at org.sqlite.PrepStmt.<init>(PrepStmt.java:42)
at org.sqlite.Conn.prepareStatement(Conn.java:404)
at org.sqlite.Conn.prepareStatement(Conn.java:399)
at scala.slick.jdbc.JdbcBackend$SessionDef$class.prepareStatement(JdbcBackend.scala:152)
at scala.slick.jdbc.JdbcBackend$BaseSession.prepareStatement(JdbcBackend.scala:389)
at scala.slick.jdbc.JdbcBackend$SessionDef$class.withPreparedStatement(JdbcBackend.scala:190)
at scala.slick.jdbc.JdbcBackend$BaseSession.withPreparedStatement(JdbcBackend.scala:389)
at scala.slick.driver.JdbcInsertInvokerComponent$BaseInsertInvoker.preparedInsert(JdbcInsertInvokerComponent.scala:170)
at scala.slick.driver.JdbcInsertInvokerComponent$BaseInsertInvoker.internalInsert(JdbcInsertInvokerComponent.scala:180)
at scala.slick.driver.JdbcInsertInvokerComponent$BaseInsertInvoker.insert(JdbcInsertInvokerComponent.scala:175)
at MyDB$$anonfun$testMemory$1$$anonfun$apply$1.apply(MyDb.scala:9)
at MyDB$$anonfun$testMemory$1$$anonfun$apply$1.apply(MyDb.scala:8)
at scala.slick.backend.DatabaseComponent$DatabaseDef$class.withSession(DatabaseComponent.scala:34)
at scala.slick.jdbc.JdbcBackend$DatabaseFactoryDef$$anon$4.withSession(JdbcBackend.scala:61)
at MyDB$$anonfun$testMemory$1.apply(MyDb.scala:8)
at MyDB$$anonfun$testMemory$1.apply(MyDb.scala:8)
at MyDB$.withMemoryTestDatabase(MyDb.scala:28)
at MyDB$.testMemory(MyDb.scala:8)
at .<init>(<console>:8)
at .<clinit>(<console>)
at .<init>(<console>:7)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:734)
at scala.tools.nsc.interpreter.IMain$Request.loadAndRun(IMain.scala:983)
at scala.tools.nsc.interpreter.IMain.loadAndRunReq$1(IMain.scala:573)
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:604)
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:568)
at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:745)
at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:790)
at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:702)
at scala.tools.nsc.interpreter.ILoop.processLine$1(ILoop.scala:566)
at scala.tools.nsc.interpreter.ILoop.innerLoop$1(ILoop.scala:573)
at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:576)
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply$mcZ$sp(ILoop.scala:867)
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:822)
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:822)
at scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135)
at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:822)
at scala.tools.nsc.interpreter.ILoop.main(ILoop.scala:889)
at xsbt.ConsoleInterface.run(ConsoleInterface.scala:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:102)
at sbt.compiler.AnalyzingCompiler.console(AnalyzingCompiler.scala:77)
at sbt.Console.sbt$Console$$console0$1(Console.scala:23)
at sbt.Console$$anonfun$apply$2$$anonfun$apply$1.apply$mcV$sp(Console.scala:24)
at sbt.TrapExit$.sbt$TrapExit$$executeMain$1(TrapExit.scala:33)
at sbt.TrapExit$$anon$1.run(TrapExit.scala:42)
任何人都可以告訴我我哪裏會出錯嗎?
N.B. JDBC構造函數的參數:memory:
似乎工作;它當然不會創建一個:memory:
文件。
我不確定,但是如果你與db建立多個連接,那麼數據不會持久。請參閱此處:http://www.sqlite.org/inmemorydb.html。您可能需要在jdbc uri的末尾添加咒語'?cache = shared'。 – 2014-09-24 16:21:15
聽起來似乎是合理的,但是一個名爲'jdbc:sqlite :: memory:?cache = shared'的URL創建一個名爲':memory:?cache = shared'的文件,所以這不太合適。 – paulmdavies 2014-09-24 16:31:00
如果您使用的是用於sqlite jdbc的xerial庫,這可能有所幫助:https://groups.google.com/forum/#!topic/xerial/gGeqCw3KzvU – 2014-09-24 17:03:18