Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you change lifted types back to Scala types when using Slick lifted embedding?

Tags:

scala

slick

How do you 'un-lift' a value inside a query in Slick when using lifted embedding? I was hoping a 'get', 'toLong' or something like that may do the trick, but no such luck.

The following code does not compile:

  val userById = for {
     uid <- Parameters[Long]
     u <- Users if u.id === uid
  } yield u

  val userFirstNameById = for {
     uid <- Parameters[Long]
     u <- userById(uid)
     ---------------^
     // type mismatch;  found   : scala.slick.lifted.Column[Long]  required: Long
  } yield u.name
like image 618
Jack Avatar asked Jan 31 '13 08:01

Jack


1 Answers

You can't, for 2 reasons:

1) with val this is happening at compile time, there is no Long value uid. userById(uid) binds a Long uid to the compile time generated prepared statement, and then .list, .first, etc. invoke the query.

2) the other issue is as soon as you Parameterize a query, composition is no longer possible -- it's a limitation dating back to ScalaQuery.

Your best bet is to delay Parameterization until the final composed query:

val forFooBars = for{
  f <- Foos
  b <- Bars if f.id is b.fooID
} yield(f,b)
val allByStatus = for{ id ~ active <- Parameters[(Long,Boolean)]
  (f,b) <- forFooBars if (f.id is id) && (b.active is active)
} yield(f,b)

def findAllByActive(id: Long, isActive: Boolean) = allByStatus(id, isActive).list

At any rate, in your example you could just as well do:

val byID = Users.createFinderBy(_.id)

The only way that I know to get this kind of thing to work is wrap the query val in a def and pass in a runtime variable, which means Slick has to re-generate the sql on every request, and no prepared statement is sent to underlying DBMS. In some cases you have to do this, like passing in a List(1,2,3) for inList.

def whenNothingElseWorks(id: Long) = {
  val userFirstNameById = for {u <- userById(id.bind)} yield u.name
}
like image 161
virtualeyes Avatar answered Sep 21 '22 15:09

virtualeyes