2016-07-08 4 views
3

Хотя документы говорят, что вы можете скомпилировать обновления, мне трудно получить Slick 3.1 для компиляции обновления, где значение, подлежащее обновлению, передается в скомпилированный блок.Как скомпилировать параметризованное обновление в Slick 3.1?

Для моего варианта использования я хочу найти строку с заданным ключом, где деактивация равна null, и установить время дезактивации на новую временную метку.

Очевидная вещь, которую я хотел бы сделать это:

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 не позволит мне требовать LiteralColumn. Compiled также не позволит мне указать свой параметр 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, Slick фактически создает четыре разных целей компиляции, которые он будет использовать для вставки, обновления, удаления и выбор. Каждая конкретная форма полностью компилируется при первом использовании. Вы можете видеть это явно в API for CompiledFunction.

Смежные вопросы