Reputation: 1175
I would like to acquire a lock
using FOR UPDATE OF table_name
. In comparison to FOR UPDATE
, FOR UPDATE OF
only locks the row in the specified table and the joined rows are not blocked. However, when I try to do it with Ecto using the following snippet it fails.
query =
Call
|> join_other_tables() # custom methods
|> Query.lock("FOR UPDATE OF calls")
The reason is Ecto uses an alias for calls
, for example, c0
, which means that I also have to use the alias in the lock expression to get it working.
query =
Call
|> join_other_tables() # custom methods
|> Query.lock("FOR UPDATE OF c0")
Using the alias does not look like a proper way to do it. Is there any other way to get it working?
Upvotes: 2
Views: 1547
Reputation: 1103
Note it looks like you can now use a fragment to interpolate the table name in, see https://github.com/elixir-ecto/ecto_sql/pull/189. So the solution from Aleksei should now work:
from c in Call,
join: ..., # custom methods
lock: fragment("FOR UPDATE OF ?", c)
Upvotes: 2
Reputation: 121000
As of Ecto v3
there is no way to pass the parameterized value to Query.lock
. It accepts binaries only.
[Named bindings] won’t work either because Ecto
internally generates aliases as it wants.
The following approach would be the nearest one, but it does not work either because Ecto.Query.lock/2
does not allow interpolation.
Use Ecto.Query.API.fragment
, that has an interpolation ability, with the keyword query syntax. Somewhat like:
from c in Call,
join: ..., # custom methods
lock: fragment("FOR UPDATE OF ?", c)
Upvotes: 3