Packages

A toolkit for data mapping and language integrated query for Elixir

Current section

Files

Jump to
ecto_tc lib ecto query builder lock.ex
Raw

lib/ecto/query/builder/lock.ex

import Kernel, except: [apply: 2]
defmodule Ecto.Query.Builder.Lock do
@moduledoc false
alias Ecto.Query.Builder
@doc """
Escapes the lock code.
iex> escape(quote(do: "FOO"), [], __ENV__)
"FOO"
"""
@spec escape(Macro.t(), Keyword.t, Macro.Env.t) :: Macro.t()
def escape(lock, _vars, _env) when is_binary(lock), do: lock
def escape({:fragment, _, [_ | _]} = expr, vars, env) do
{expr, {params, :acc}} = Builder.escape(expr, :any, {[], :acc}, vars, env)
if params != [] do
Builder.error!("value interpolation is not allowed in :lock")
end
expr
end
def escape(other, _, _) do
Builder.error!(
"`#{Macro.to_string(other)}` is not a valid lock. " <>
"For security reasons, a lock must always be a literal string or a fragment"
)
end
@doc """
Builds a quoted expression.
The quoted expression should evaluate to a query at runtime.
If possible, it does all calculations at compile time to avoid
runtime work.
"""
@spec build(Macro.t(), Macro.t(), Macro.t(), Macro.Env.t()) :: Macro.t()
def build(query, binding, expr, env) do
{query, binding} = Builder.escape_binding(query, binding, env)
Builder.apply_query(query, __MODULE__, [escape(expr, binding, env)], env)
end
@doc """
The callback applied by `build/4` to build the query.
"""
@spec apply(Ecto.Queryable.t(), term) :: Ecto.Query.t()
def apply(%Ecto.Query{} = query, value) do
%{query | lock: value}
end
def apply(query, value) do
apply(Ecto.Queryable.to_query(query), value)
end
end