2017-03-03 20 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))