2016-07-08 24 views
3

雖然文檔說你可以編譯更新,但是我很難讓Slick 3.1編譯一個更新的地方,在那裏要更新的值被傳遞到編譯塊中。如何編譯Slick 3.1中的參數化更新?

對於我的使用案例,我想找到一個行,其中的停用爲空,並將停用時間設置爲新的時間戳。

明顯的事情我想要做的是這樣的:

private[this] lazy val updateDeactiveTime = Compiled { (settingName: Rep[String], time: Rep[Instant]) => 
    settings 
     .filter { row => row.name === settingName && row.deactivatedAt.isEmpty } 
     .map { _.deactivatedAt } 
     .update(Some(time)) 
    } 

不幸的是,這給了我一個抱怨update不能採取Rep[Option[Instant]]:它想要的Option[Instant]

據我所知,Slick(不幸)不允許您在更新中使用動態計算的值。根據文檔,限制操作的解決方法是使用ConstColumn[…]。盡職盡責,我嘗試傳遞ConstColumn[Option[Instant]],希望能有一些隱含的轉換或擴展,但我仍然抱怨它必須是文字Option[Instant]

當然,我擁有文字即時性,但如果每次目標值更改時都必須重新編譯,那麼編譯更新就沒有多少意義。

如果我要使用LiteralColumn[…],我可以撥打_.value,但Compiled不會讓我需要LiteralColumnCompiled也不會讓我有我的參數是time: Instant

回答

2

你做update操作外部編譯的部分。這仍然提供了編譯的好處。

private[this] lazy val deactiveTime = Compiled { (settingName: Rep[String]) => 
    settings 
     .filter { row => row.name === settingName && row.deactivatedAt.isEmpty } 
     .map { _.deactivatedAt } 
    } 
    def updateDeactiveTime(settingName: String, time: Instant) = { 
    deactiveTime(settingName).update(Some(time)) 
    } 

事實證明,當你做Compiled,油滑的實際創建,這將用於插入,更新,刪除和選擇四種不同的編譯目標。每個特定的表格在首次使用時完全編譯。你可以在API for CompiledFunction中明確地看到這一點。