Current section

Files

Jump to
query_builder lib query.ex
Raw

lib/query.ex

defmodule QueryBuilder.Query do
@moduledoc false
defstruct(
ecto_query: nil,
operations: []
)
end
defimpl Ecto.Queryable, for: QueryBuilder.Query do
def to_query(%{
ecto_query: ecto_query,
operations: operations
}) do
source_schema = QueryBuilder.Utils.root_schema(ecto_query)
assoc_list =
Enum.reduce(operations, [], fn %{assocs: assocs, type: type} = operation, accumulated_assocs ->
opts =
case type do
:preload ->
[join: :inner_if_cardinality_is_one, preload: true]
:left_join ->
[join: :left, join_filters: operation.join_filters]
_ ->
[]
end
QueryBuilder.AssocList.build(source_schema, accumulated_assocs, assocs, opts)
end)
{ecto_query, assoc_list} =
QueryBuilder.JoinMaker.make_joins(ecto_query, assoc_list)
ecto_query =
Enum.reduce(operations, ecto_query, fn
%{type: :left_join}, ecto_query ->
ecto_query
%{type: type, args: args}, ecto_query ->
Module.concat(QueryBuilder.Query, to_string(type) |> Macro.camelize())
|> apply(type, [ecto_query | [assoc_list | args]])
end)
Ecto.Queryable.to_query(ecto_query)
end
end