Search code examples
scalascalaquery

Unpack a NamedColumn in a condition of a for-loop in ScalaQuery


I am quite new to Scala and ScalaQuery, using it a couple of weeks now. I am trying to figure out a condition in a query by calling a function, but I get a NamedColumn[T] instead of T, how to unpack it?

See 2nd link, line 20:

package with typemapper: https://gist.github.com/3469291

table object: https://gist.github.com/3469291

case class MyObject (
        id: Long,
        created: JodaTime
        modified: JodaTime
        special: JodaTime
)

object MyObjects extends Table[MyObject]("my_objects") {

  lazy val database = Database.forDataSource(DB.getDataSource())

  def id = column[Long]("id", O PrimaryKey, O AutoInc, O NotNull)
  def created = column[JodaTime]("created", O NotNull)
  def modified = column[JodaTime]("modified", O NotNull)
  def special = column[JodaTime]("special", O NotNull)
  def * = id ~ created <> (MyObject, MyObject.unapply _)

  def getMarker(time: JodaTime) = database.withSession { implicit db:Session =>
    (for {
      e <- MyObjects if (new org.joda.time.Interval(e.created, e.modified).contains(e.special)
    } yield (e.id, e.created)).firstOption
  }
}

e.created / modified /special are NamedColumns, so the constructor and functioncall won't work. How do I make this work?

I did not test my object, I just grabbed a class and stripped and renamed things, but just to show what I have and want to do.

Thanks.


Solution

  • I think you could tricked by ScalaQueries nice syntax. You can't jut put arbitrary conditions in a for comprehension based on ScalaQuery tables.

    The conditions don't get executed by the JVM, but get translated into SQL. This obviously doesn't work for arbitrary Scala code, but only special operations provided by ScalaQuery.

    The following version should work:

    for {
      e <- MyObjects 
      if (e.created < e.special)
      if (e.modified > e.special)
    }
    

    Note that I have no idea about the semantics of Interval.contains, so you might have to throw some >= or <= in there.