I am having a pretty hard time today when trying to upgrade slick to version 3.0.0-M1 to try the asynchronous DB features + reactive-stream. Documents and examples are lacking so I just read through http://slick.typesafe.com/doc/3.0.0-M1/gettingstarted.html and give it a best shot (I am very new to scala + slick). Here is what I did but fail to get it works.
package models
//some share class definition
import java.sql.{Date => SqlDate}
import scala.slick.driver.JdbcDriver.api._;
case class Country(id: Option[Long], name: String, country_code: String, language_code: String)
class Countries(tag: Tag) extends Table[Country](tag, "country") {
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name", O.NotNull)
def country_code = column[String]("country_code", O.NotNull)
def language_code = column[String]("language_code")
def * = (id.?, name, country_code, language_code) <> (Country.tupled, Country.unapply _)
}
Then I wrote a simple test using ScalaTest with future as follow:
//test suite to test slick statement
package testing
import org.scalatest.BeforeAndAfter
import org.scalatestplus.play._
import play.api.test._
import play.api.test.Helpers._
import scala.slick.jdbc.{GetResult, StaticQuery => Q}
import models._
import play.api.Logger
import scala.slick.driver.JdbcDriver.backend.Database
//import scala.slick.driver.JdbcDriver.simple._;
import scala.slick.driver.JdbcDriver.api.{actionBasedSQLInterpolation=>_, _}
import Q.interpolation
import scala.concurrent.Future
import org.scalatest.concurrent.ScalaFutures
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Await
import scala.concurrent.duration.Duration
class SlickSpec extends PlaySpec with BeforeAndAfter with ScalaFutures{
implicit var session: Session = _
var db: Database = _
def cleanUpDatabase(): Unit = {
(Q.u + "TRUNCATE TABLE country").execute
}
before {
db = Database.forConfig("mysqldb-test")
session = db.createSession()
cleanUpDatabase
}
after {
cleanUpDatabase
session.close()
}
"Slick must be" must {
"able to work" in new WithApplication{
val countries = TableQuery[Countries]
val q = for (c <- countries) yield c.name
val a = q.result
val f: Future[Seq[String]] = db.run(a)
whenReady(f) { result =>
Logger.warn("for debugging....")
//f.onSuccess { case s => Logger.warn("running here")}
}
}
}
}
But i got an exception: [info] org.specs2.execute.ErrorException: The future returned an exception of type: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException, with message: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"name" from "country" x2' at line 1.
I am wondering:
- Is it correct that I should import import scala.slick.driver.JdbcDriver.api. _; instead of scala.slick.driver.JdbcDriver.simple. _
- How to get the simple example working. Is there anyway I can log/view the generated SQL query (from Slick) for debugging.
- When importing api._ I cann't use something like countries.filter(_.id === id).first anymore; it will just show me the error: value first is not a member of scala.slick.lifted.Query[models.Countries,models.Countries#TableElementType,Seq]. It happen for firstOption, list also. Is this correct that after I upgrade to version 3.0.0-M1; every query has to be done in asynchronous way, which means old API (blocking version) like first, list will not working.
I would appreciate if someone can suggest me some good example / code repo for the slick 3.x in action.
Thanks!