Goal is to filter Items with optional keywords and/or shopId.
If none of them are defined, all Items should be returned.
My attempt is
case class ItemSearchParameters(keywords: Option[String], shopId: Option[Long])
def search(params: ItemSearchParameters): Either[Failure, List[Item]] = {
try {
db withDynSession {
val q = Items.query
if (params.keywords.isDefined) {
q.filter { i =>
((i.title like "%" + params.keywords + "%")
|| (i.description like "%" + params.keywords + "%"))
}
}
if (params.shopId.isDefined) {
q.filter { i =>
i.shopId === params.shopId
}
}
Right(q.run.toList)
}
} catch {
case e: SQLException =>
Left(databaseError(e))
}
}
params.keywords or params.ShopId defined this function returned all Items. Can someone please explain what is wrong?
Update: second attempt
def search(params: ItemSearchParameters): Either[Failure, List[Item]] = {
try {
db withDynSession {
var q = Items.query
q = params.keywords.map{ k => q.filter(_.title like "%" + k + "%")} getOrElse q
q = params.keywords.map{ k => q.filter(_.description like "%" + k + "%")} getOrElse q
q = params.shopId.map{ sid => q.filter(_.shopId === sid)} getOrElse q
Right(q.run.toList)
}
} catch {
case e: SQLException =>
Left(databaseError(e))
}
}
For this second attempt how to do (title OR description) if keywords isDefined?
Update: Third attempt with MaybeFilter Not working
case class MaybeFilter[X, Y](val query: scala.slick.lifted.Query[X, Y, Seq]) {
def filteredBy(op: Option[_])(f:(X) => Column[Option[Boolean]]) = {
op map { o => MaybeFilter(query.filter(f)) } getOrElse { this }
}
}
class ItemDAO extends Configuration {
implicit def maybeFilterConversor[X,Y](q:Query[X,Y,Seq]) = new MaybeFilter(q)
def search(params: ItemSearchParameters): Either[Failure, List[Item]] = {
try {
db withDynSession {
val q = Items
.filteredBy(params.keywords){i => ((i.title like "%" + params.keywords + "%")
|| (i.description like "%" + params.keywords + "%"))}
.filteredBy(params.shopId){_.shopId === params.shopId}
.query
Right(q.list)
}
} catch {
case e: SQLException =>
Left(databaseError(e))
}
}
}
Third attempt returns empty list if keywords is given
I am not sure it is the best answer because of var q