我正在尝试在基础类中为我的光滑表实现一些通用过滤器。
我想要实现的是将url查询字符串转换为数据库过滤器的能力。我想出了一个可行的解决方案,但代码不是很干。
这是我修改过的代码。
package db.utils.repos
import common.utils.request.filters.{StringMatchesFilter, RequestFilter}
import scala.slick.lifted.{Column => LiftedColumn}
import db.environments.slick.interfaces.SlickEnv
import org.joda.time.DateTime
import scala.slick.profile.RelationalProfile
trait SlickPageable {
val slickEnv: SlickEnv
import slickEnv.profile.simple._
trait FieldMapped {
def longField(f: String): Option[LiftedColumn[Long]]
def optLongField(f: String): Option[LiftedColumn[Option[Long]]]
def stringField(f: String): Option[LiftedColumn[String]]
def optStringField(f: String): Option[LiftedColumn[Option[String]]]
}
trait FieldSet{
def stringField(table: FieldMapped, f: String): Option[LiftedColumn[Any]]
}
object FSet extends FieldSet {
override def stringField(table: FieldMapped, f: String): Option[LiftedColumn[String]] = {
table.stringField(f)
}
}
object OptFSet extends FieldSet {
override def stringField(table: FieldMapped, f: String): Option[LiftedColumn[Option[String]]] = {
table.optStringField(f)
}
}
def filter(table: FieldMapped, f: RequestFilter) = {
queryFilter(table, f, QSet)
}
def optFilter(table: FieldMapped, f: RequestFilter) ={
queryFilter(table, f, OptQSet)
}
def queryFilter[T, R](table: FieldMapped, f: RequestFilter, querySet: QuerySet[T, R]) = {
def checkField[A](field: Option[A], op: (A, String) => R) = {
field match {
case Some(fi) =>
op(fi, f.value)
case None =>
throw new IllegalArgumentException(s"could not retrieve field ${f.field}")
}
}
f match {
case sf: StringMatchesFilter => {
checkField(querySet.fSet.stringField(table, f.field), querySet.sEq)
}
case _ => throw new IllegalArgumentException("No such filter")
}
}
trait QuerySet[T, R] {
val fSet: FieldSet
def sEq(col: T, value: String): R
}
object QSet extends QuerySet[LiftedColumn[String], LiftedColumn[Boolean]] {
override val fSet = FSet
override def sEq(col: LiftedColumn[String], value: String): LiftedColumn[Boolean] = {
col === value
}
}
object OptQSet extends QuerySet[LiftedColumn[Option[String]], LiftedColumn[Option[Boolean]]] {
override val fSet = OptFSet
override def sEq(col: LiftedColumn[Option[String]], value: String): LiftedColumn[Option[Boolean]] = {
col === value
}
}
}
错误消息
type mismatch;
[error] found : (T, String) => R
[error] required: (scala.slick.lifted.Column[_], String) => R
[error] checkField(fieldSet.stringField(table, f.field), querySet.sEq)
如果我从FieldSet
参数列表中删除queryFilter
,我可以使其正常运行。但后来我需要分离函数:一个调用字段映射方法,另一个调用可选字段映射方法。它可以工作,类型推理和一切正常工作。
那么我怎样才能使用FieldSet
?据我所知,在编译时似乎没有足够的类型信息。但我不知道如何提供它。