2
votes

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:

  1. Is it correct that I should import import scala.slick.driver.JdbcDriver.api. _; instead of scala.slick.driver.JdbcDriver.simple. _
  2. How to get the simple example working. Is there anyway I can log/view the generated SQL query (from Slick) for debugging.
  3. 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!

1

1 Answers

1
votes

JdbcDriver is a not intended to be used with a MySQL database. It is a fallback driver that let's Slick make a best effort attempt to run against not officially supported backends. Slick will then produce SQL standard conformant queries, which aren't compatible with MySQL.

  1. Use MySQLDriver instead. Importing .api._ is correct.

  2. Slick has very extensive logging via logback. Here are the available loggers: https://github.com/slick/slick/blob/80929a693e90bbff7914aa9543cb9b33e6fbace6/slick-testkit/src/doctest/resources/logback.xml Google for "Slick logging" or use .selectStatement on queries to return the SQL as a String.

  3. The old api will be deprecated. See https://groups.google.com/forum/#!msg/scalaquery/xyO4HufdaUI/AMQ6EawUqPkJ