2014-02-26 17 views
4
private def buildQuery(query: TweetQuery) = { 
     var q = Tweets.map { t => 
     t 
     } 
     query.isLocked.foreach { isLocked => 
     q = q.filter(_.isLocked === isLocked) 
     } 
     query.isProcessed.foreach { isProcessed => 
     q = q.filter(_.processFinished === isProcessed) 
     } 
     query.maxScheduleAt.foreach { maxScheduleAt => 
     q = q.filter(_.expectScheduleAt < maxScheduleAt) 
     } 
     query.minScheduleAt.foreach { minScheduleAt => 
     q = q.filter(_.expectScheduleAt > minScheduleAt) 
     } 
     query.status.foreach { status => 
     q = q.filter(_.status === status) 
     } 
     query.scheduleType.foreach { scheduleType => 
     q = q.filter(_.scheduleType === scheduleType) 
     } 
     q 
    } 

我正在写上面的东西来做动态查询。真的无聊,任何方式更好地做到这一点?更好的动态查询编码风格

回答

-2

好吧,看起来这个代码违反了OCP。试着看看this article--尽管它不在Scala上,它解释了如何正确设计这些方法。

0

正在isLocked,isProcessed等选项?

那么你也可以写东西像

for (locked <- query.isLocked) { q = q.filter(_.isLocked is locked) } 

如果这是任何安慰的: - }

2

我修改的cvogt答案,以便与光滑2.1.0工作。 here的解释。

希望它可以帮助别人:)

case class MaybeFilter[X, Y](val query: scala.slick.lifted.Query[X, Y, Seq]) { 
    def filter(op: Option[_])(f:(X) => Column[Option[Boolean]]) = { 
     op map { o => MaybeFilter(query.filter(f)) } getOrElse { this } 
    } 
    } 

问候。

更正例如:

//Class definition 
import scala.slick.driver.H2Driver.simple._ 
import scala.slick.lifted.{ProvenShape, ForeignKeyQuery} 

// A Suppliers table with 6 columns: id, name, street, city, state, zip 
class Suppliers(tag: Tag) 
    extends Table[(Int, String, String, String, String, String)](tag, "SUPPLIERS") { 

    // This is the primary key column: 
    def id: Column[Int] = column[Int]("SUP_ID", O.PrimaryKey) 
    def name: Column[String] = column[String]("SUP_NAME") 
    def street: Column[String] = column[String]("STREET") 
    def city: Column[String] = column[String]("CITY") 
    def state: Column[String] = column[String]("STATE") 
    def zip: Column[String] = column[String]("ZIP") 

    // Every table needs a * projection with the same type as the table's type parameter 
    def * : ProvenShape[(Int, String, String, String, String, String)] = 
    (id, name, street, city, state, zip) 
} 

//I changed the name of the def from filter to filteredBy to ease the 
//implicit conversion 
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 } 
    } 
} 

//Implicit conversion to the MaybeFilter in order to minimize ceremony 
implicit def maybeFilterConversor[X,Y](q:Query[X,Y,Seq]) = new MaybeFilter(q) 

val suppliers: TableQuery[Suppliers] = TableQuery[Suppliers] 

suppliers += (101, "Acme, Inc.", "99 Market Street", "Groundsville", "CA", "95199") 

//Dynamic query here 
//try this asigment val nameFilter:Option[String] = Some("cme") and see the results 
val nameFilter:Option[String] = Some("Acme") 
//also try to assign None in here like this val supIDFilter:Option[Int] = None and see the results 
val supIDFilter:Option[Int] = Some(101) 

suppliers 
    .filteredBy(supIDFilter){_.id === supIDFilter} 
    .filteredBy(nameFilter){_.name like nameFilter.map("%" + _ + "%").getOrElse("")} 
    .query.list 

完整的示例:

https://github.com/neowinx/hello-slick-2.1-dynamic-filter

+0

上面的代码无法使用Slick 2.1和Scala 2.11进行编译。每个过滤器子句中的“d”参数都会标记为“缺少参数类型”错误。我不明白为什么会这样,因为过滤器函数定义中的函数参数“f”被声明为类型X,它应该为编译器提供必要的类型信息。没有?任何人都知道如何进行上述编译? – eswenson

+0

ops ..我复制了最初的例子..我的坏..我编辑我的答案,以包括一个工作的例子。你也可以通过https://github.com/neowinx/hello-slick-2.1-dynamic-filter查看完整的源代码PS:对于迟到的答案抱歉..我最近一直忙于大学......希望它可以帮助你 –

1

我认为这是华而不实2.1.0

case class MaybeFilter[X, Y](val query: Query[X, Y, Seq]) { 
    def filter[T, R: CanBeQueryCondition](data: Option[T])(f: T => X => R) = { 
    data.map(v => MaybeFilter(query.withFilter(f(v)))).getOrElse(this) 
    } 
}