loicdescotte
2/24/2014 - 5:49 PM

Slick: Dynamic query conditions using the **MaybeFilter** (Updated to support nullable columns)

Slick: Dynamic query conditions using the MaybeFilter (Updated to support nullable columns)

import scala.slick.lifted.CanBeQueryCondition
// optionally filter on a column with a supplied predicate
case class MaybeFilter[X, Y](val query: scala.slick.lifted.Query[X, Y]) {
  def filter[T,R:CanBeQueryCondition](data: Option[T])(f: T => X => R) = {
    data.map(v => MaybeFilter(query.filter(f(v)))).getOrElse(this)
  }
}

// example use case
import java.sql.Date
class SomeTable(tag: Tag) extends Table[(Int, Date, Date)](tag, "some_table") {
  def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
  def created = column[Date]("created")
  def modified = column[Date]("modified")
  def * = (id, created, modified)
}
lazy val someTable = TableQuery[SomeTable]
someTable.ddl.create

def find(id: Option[Int], createdMin: Option[Date], createdMax: Option[Date], modifiedMin: Option[Date], modifiedMax: Option[Date]) = {
  MaybeFilter(someTable)
    .filter(id)(v => d => d.id === v)
    .filter(createdMin)(v => d => d.created >= v)
    .filter(createdMax)(v => d => d.created <= v)
    .filter(modifiedMin)(v => d => d.modified >= v)
    .filter(modifiedMax)(v => d => d.modified <= v)           
    .query
}
find(Some(1),None,None,None,None).list // <- example: find by id only