Packages
ecto
1.1.6
3.14.1
3.14.0
3.13.6
3.13.5
3.13.4
3.13.3
3.13.2
3.13.1
3.13.0
3.12.6
3.12.5
3.12.4
3.12.3
3.12.2
3.12.1
3.12.0
3.11.2
3.11.1
3.11.0
3.10.3
3.10.2
3.10.1
3.10.0
3.9.6
3.9.5
3.9.4
3.9.3
3.9.2
3.9.1
3.9.0
3.8.4
3.8.3
3.8.2
3.8.1
3.8.0
3.7.2
3.7.1
3.7.0
3.6.2
3.6.1
3.6.0
3.5.8
3.5.7
3.5.6
3.5.5
3.5.4
3.5.3
3.5.2
3.5.1
3.5.0
3.5.0-rc.1
3.5.0-rc.0
3.4.6
3.4.5
3.4.4
3.4.3
3.4.2
3.4.1
3.4.0
3.3.4
3.3.3
3.3.2
3.3.1
3.3.0
3.2.5
3.2.4
3.2.3
3.2.2
3.2.1
3.2.0
3.1.7
3.1.6
3.1.5
3.1.4
3.1.3
3.1.2
3.1.1
3.1.0
3.0.9
3.0.8
3.0.7
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
3.0.0
3.0.0-rc.1
3.0.0-rc.0
2.2.12
2.2.11
2.2.10
2.2.9
2.2.8
2.2.7
2.2.6
2.2.5
2.2.4
2.2.3
2.2.2
2.2.1
2.2.0
2.2.0-rc.1
2.2.0-rc.0
2.1.6
2.1.5
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.1.0-rc.5
2.1.0-rc.4
2.1.0-rc.3
2.1.0-rc.2
2.1.0-rc.1
2.1.0-rc.0
2.0.6
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
2.0.0-rc.6
2.0.0-rc.5
2.0.0-rc.4
2.0.0-rc.3
2.0.0-rc.2
2.0.0-rc.1
2.0.0-rc.0
2.0.0-beta.2
2.0.0-beta.1
2.0.0-beta.0
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.16.0
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
0.13.0
0.12.1
0.12.0
0.12.0-rc
0.11.3
0.11.2
0.11.1
0.11.0
0.10.3
0.10.2
0.10.1
0.10.0
0.9.0
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.0
0.5.1
0.5.0
0.4.0
0.3.0
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
A toolkit for data mapping and language integrated query for Elixir
Current section
Files
Jump to
Current section
Files
lib/ecto/query/builder/from.ex
defmodule Ecto.Query.Builder.From do
@moduledoc false
alias Ecto.Query.Builder
@doc """
Handles from expressions.
The expressions may either contain an `in` expression or not.
The right side is always expected to Queryable.
## Examples
iex> escape(quote do: MyModel)
{[], quote(do: MyModel)}
iex> escape(quote do: p in posts)
{[p: 0], quote(do: posts)}
iex> escape(quote do: p in {"posts", MyModel})
{[p: 0], quote(do: {"posts", MyModel})}
iex> escape(quote do: [p, q] in posts)
{[p: 0, q: 1], quote(do: posts)}
iex> escape(quote do: [_, _] in abc)
{[_: 0, _: 1], quote(do: abc)}
iex> escape(quote do: other)
{[], quote(do: other)}
iex> escape(quote do: x() in other)
** (Ecto.Query.CompileError) binding list should contain only variables, got: x()
"""
@spec escape(Macro.t) :: {Keyword.t, Macro.t}
def escape({:in, _, [var, expr]}) do
{Builder.escape_binding(List.wrap(var)), expr}
end
def escape(expr) do
{[], expr}
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.Env.t) :: {Macro.t, Keyword.t, non_neg_integer | nil}
def build(expr, env) do
{binds, expr} = escape(expr)
{count_bind, quoted} =
case Macro.expand(expr, env) do
model when is_atom(model) ->
# Get the source at runtime so no unnecessary compile time
# dependencies between modules are added
source = quote do: unquote(model).__schema__(:source)
{1, query(source, model)}
source when is_binary(source) ->
# When a binary is used, there is no model
{1, query(source, nil)}
{source, model} when is_binary(source) ->
{1, query(source, model)}
other ->
{nil, other}
end
quoted = Builder.apply_query(quoted, __MODULE__, [length(binds)], env)
{quoted, binds, count_bind}
end
defp query(source, model) do
{:%, [], [Ecto.Query, {:%{}, [], [from: {source, model}]}]}
end
@doc """
The callback applied by `build/2` to build the query.
"""
@spec apply(Ecto.Queryable.t, non_neg_integer) :: Ecto.Query.t
def apply(query, binds) do
query = Ecto.Queryable.to_query(query)
check_binds(query, binds)
query
end
defp check_binds(query, count) do
if count > 1 and count > Builder.count_binds(query) do
Builder.error! "`from` in query expression specified #{count} " <>
"binds but query contains #{Builder.count_binds(query)} binds"
end
end
end