Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I avoid Slick's model declaration verbosity and repetitiveness

I am currently using Slick 1.x to access MySQL within playframework 2.1.3. While generally Slick's features look pretty good, I cannot wrap my head around how repetitive the declaration syntax is. I mean have a look at the following code:

case class User
 (id: Option[Long]
 , firstName: String
 , lastName: String
 , email: String
 , password: String
 , status: String
 , createDate: Long = Platform.currentTime
 , firstLogin: Option[Long]
 , lastLogin: Option[Long]
 , passwordChanged: Option[Long]
 , failedAttempts: Int = 0
  )

object User extends Table[User]("USER") {
  def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
  def firstName = column[String]("firstName", O.NotNull)
  def lastName = column[String]("lastName", O.NotNull)
  def email = column[String]("mail", O.NotNull)
  def password = column[String]("password", O.NotNull)
  def status = column[String]("status", O.NotNull)
  def createDate = column[Long]("createDate", O.NotNull)
  def firstLogin = column[Long]("firstLogin", O.Nullable)
  def lastLogin = column[Long]("lastLogin", O.Nullable)
  def passwordChanged = column[Long]("passwordChanged", O.Nullable)
  def failedAttempts = column[Int]("failedAttempts", O.NotNull)

  def * = id.? ~ firstName ~ lastName ~ email ~ password ~ status ~ createDate ~ firstLogin.? ~ lastLogin.? ~ passwordChanged.? ~ failedAttempts <>(User.apply _, User.unapply _)
  def autoInc = * returning id
}

It can't be right, that in order to have a simple case class and an access object, I will have to declare each and every field three times. Is there a way to avoid this error prone repetitiveness?

Update: Of course a solution to this problem should support read and write operations.

like image 967
keyboardsamurai Avatar asked Aug 14 '13 05:08

keyboardsamurai


2 Answers

You could use direct embedding. It is an experimental, macro-based API that lets you write your tables like this:

@table("COFFEES") case class Coffee(
  @column("COF_NAME")  name:  String,
  @column("SUP_ID") supID: Int,
  @column("PRICE") price: Double
)
val coffees = Queryable[Coffee]

edit:

Docs are here: http://slick.typesafe.com/doc/1.0.1/direct-embedding.html

like image 56
drexin Avatar answered Nov 20 '22 06:11

drexin


You can use code generation or in the future: type providers.

See https://groups.google.com/d/msg/scalaquery/Pdp3GTXsKCo/O0e3JLXAaK8J

like image 36
cvogt Avatar answered Nov 20 '22 07:11

cvogt