Reputation: 810
Although the docs say you can compile updates, I'm having trouble getting Slick 3.1 to compile an update where the value to be updated is passed into the compiled block.
For my use case, I want to find a row with a given key where the deactivation is null and set the deactivation time to a new timestamp.
The obvious thing I'd want to do is this:
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))
}
Unfortunately, this gives me a complaint that update
can't take a Rep[Option[Instant]]
: it wants an Option[Instant]
.
I understand that Slick (unfortunately) doesn't allow you to use a dynamically calculated value in an update. Per the docs, the workaround for things like limit operations is to use a ConstColumn[…]
. Dutifully, I tried passing in a ConstColumn[Option[Instant]]
, hoping there'd be some implicit conversion or extension, but I still get the complaint that it must be a literal Option[Instant]
.
Of course I have the literal instant, but there's not much point compiling the update if I have to recompile it every time the target value changes.
If I were to use a LiteralColumn[…]
, I could call _.value
, but Compiled
won't let me require a LiteralColumn
. Compiled
also won't allow me have my parameter be time: Instant
.
Upvotes: 5
Views: 755
Reputation: 810
You do the update
operation outside of the part that's compiled. This still provides the benefits of compilation.
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))
}
It turns out that when you do Compiled
, Slick actually creates four different compilation targets that it will use for insert, update, delete and select. Each specific form is fully compiled on first use. You can see this explicitly in the API for CompiledFunction.
Upvotes: 6