Current section

Files

Jump to
query_builder lib query where.ex
Raw

lib/query/where.ex

defmodule QueryBuilder.Query.Where do
@moduledoc false
require Ecto.Query
import QueryBuilder.Query.Helper
def where(query, assoc_fields, filters) do
token = QueryBuilder.Token.token(query, assoc_fields)
{query, token} = QueryBuilder.JoinMaker.make_joins(query, token)
apply_filters(query, token, List.wrap(filters))
end
defp apply_filters(query, _token, []), do: query
defp apply_filters(query, token, [filter | tail]) do
query = apply_filter(query, token, filter)
apply_filters(query, token, tail)
end
defp apply_filter(query, token, {field, value}) do
apply_filter(query, token, {field, :eq, value})
end
defp apply_filter(query, token, {field1, operator, field2}) when is_atom(field2) do
{field1, binding_field1} = field_and_binding(query, token, field1)
{field2, binding_field2} = field_and_binding(query, token, field2)
do_where(query, binding_field1, binding_field2, {field1, operator, field2})
end
defp apply_filter(query, token, {field, operator, value}) do
{field, binding} = field_and_binding(query, token, field)
do_where(query, binding, {field, operator, value})
end
defp do_where(query, binding, {field, :eq, value}) do
Ecto.Query.where(query, [{^binding, x}], field(x, ^field) == ^value)
end
defp do_where(query, binding1, binding2, {field1, :eq, field2}) do
Ecto.Query.where(
query,
[{^binding1, x}, {^binding2, y}],
field(x, ^field1) == field(y, ^field2)
)
end
defp do_where(query, binding, {field, :ne, value}) do
Ecto.Query.where(query, [{^binding, x}], field(x, ^field) != ^value)
end
defp do_where(query, binding1, binding2, {field1, :ne, field2}) do
Ecto.Query.where(
query,
[{^binding1, x}, {^binding2, y}],
field(x, ^field1) != field(y, ^field2)
)
end
defp do_where(query, binding, {field, :gt, value}) do
Ecto.Query.where(query, [{^binding, x}], field(x, ^field) > ^value)
end
defp do_where(query, binding1, binding2, {field1, :gt, field2}) do
Ecto.Query.where(
query,
[{^binding1, x}, {^binding2, y}],
field(x, ^field1) > field(y, ^field2)
)
end
defp do_where(query, binding, {field, :ge, value}) do
Ecto.Query.where(query, [{^binding, x}], field(x, ^field) >= ^value)
end
defp do_where(query, binding1, binding2, {field1, :ge, field2}) do
Ecto.Query.where(
query,
[{^binding1, x}, {^binding2, y}],
field(x, ^field1) >= field(y, ^field2)
)
end
defp do_where(query, binding, {field, :lt, value}) do
Ecto.Query.where(query, [{^binding, x}], field(x, ^field) < ^value)
end
defp do_where(query, binding1, binding2, {field1, :lt, field2}) do
Ecto.Query.where(
query,
[{^binding1, x}, {^binding2, y}],
field(x, ^field1) < field(y, ^field2)
)
end
defp do_where(query, binding, {field, :le, value}) do
Ecto.Query.where(query, [{^binding, x}], field(x, ^field) <= ^value)
end
defp do_where(query, binding1, binding2, {field1, :le, field2}) do
Ecto.Query.where(
query,
[{^binding1, x}, {^binding2, y}],
field(x, ^field1) <= field(y, ^field2)
)
end
end