2017-03-03 37 views
2

我有两列的DB表:过滤查询基于和LOCALDATE选项[INT]的总和在油滑

startDate -> date type 
duration -> nullable integer 

以我油滑配置这些列被定义为LocalDate(我使用约达)和Option[Int]

现在,我想写这给出一个日期givenDate它给我回哪里duration定义和startDate + duration < givenDate的所有行的查询。

我期待这样的事情:

db.run(table.filter(t => { 
    t.duration.isDefined && 
    t.startDate < givenDate.minusDays(t.duration.getOrElse(0)) 
})) 

不幸的是,这并不工作,因为t.duration.getOrElse(0)是不是一个真正的整数,但Rep[Int]

我该怎么做?

技术我使用的是:Scala的,油滑的3.1,你的问题乔达时间,油滑乔达映射器

+0

http://stackoverflow.com/questions/21349547/compare-2-dates-in-a-slick-query-似乎很难看这个问题,可能会帮助你 –

+0

@KamilBanaszczyk不幸的是,这并没有帮助。我可以比较日期(正如我提到的,我使用'slick-joda-mapper')。我不能做的是在查询中修改日期,然后进行比较。 – Alex

+0

我不知道slick-joda-mapper是如何工作的,但是你是否尝试在Rep中包装givenDate?也许那么它将允许在Rep [Int]上执行操作? –

回答

0

OK,我已经找到答案。所以基本上你不能解包Rep,因为数据库类型安全。另外你还没有机会调用内部的数据库引擎,这就是为什么我们不能以任何方式使用minusDays(t.duration.getOrElse(0))。对于每种数据类型,由于不同数据库引擎的过程,光滑也没有目的执行操作。但是,如果你想在数据库上调用日期操作,你必须检查它是否支持日期操作。我的例子是H2的数据库,在这里我们去:

定义的数据

case class DateTest(id: Option[Int] = None, date: LocalDate, duration: Int) extends BaseEntity 

    class DateTestTable(tag: Tag) extends BaseTable[DateTest](tag, None, "DateTest") { 

    override val id: Rep[Option[Int]] = column[Option[Int]]("id", O.PrimaryKey, O.AutoInc) 

    def date: Rep[LocalDate] = column[LocalDate]("date") 

    def duration = column[Int]("duration") 

    def * = (id, date, duration) <>(DateTest.tupled, DateTest.unapply) 

    } 

    val dateTests: TableQuery[DateTestTable] = TableQuery[DateTestTable] 

插入数据

H2Connector.dateTests ++= Seq(
    DateTest(Some(1), new LocalDate(2017,3,4),15), 
    DateTest(Some(2), new LocalDate(2017,2,17),15) 
) 

val addDays: (Rep[String], Rep[Int], Rep[LocalDate]) => Rep[LocalDate] = SimpleFunction.ternary[String,Int,LocalDate,LocalDate]("DATEADD") 

    def dateWithDuration(givenDate: LocalDate): Future[Seq[DateTest]] ={ 
    filter(auth => auth.date < addDays("DAY",auth.duration*(-1),givenDate)) 
    } 

所以在最后一段代码中,你可以看到这是如何实现的。首先H2支持此操作,日期为DATEADD,Slick允许您实现自定义功能,该功能将使用数据库功能。通过这种方式,您可以使用REP包装的值,并且它可以使浮油保持其类型安全实施。

随着这些测试:

"TestDate " should { 
    "return date with small duration " in { 
     println(waitForResult(testDate.dateWithDuration(new LocalDate(2017,3,15)))) 
    } 
    "return every date " in { 
     println(waitForResult(testDate.getAll)) 
    } 
    } 

结果是:

Vector(DateTest(Some(2),2017-02-17,15)) 
Vector(DateTest(Some(1),2017-03-04,15), DateTest(Some(2),2017-02-17,15))