Skip to content

Commit

Permalink
[Change] remove dependency on Ecto.Query.Builder.Join.join/10
Browse files Browse the repository at this point in the history
  • Loading branch information
albertored committed Sep 14, 2020
1 parent 0413a29 commit 174f003
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 18 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ end

## Ecto internals currently used

- `Ecto.Query.Builder.Join.join/10` function needed beacuse dynamic joins are not available

- `%Ecto.Query{from: %{source: {_, module}}}`
Ecto.query struct internal structure, needed for extracting the main `Ecto.Schema` of the query

Expand Down
38 changes: 22 additions & 16 deletions lib/ex_sieve/builder/join.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
defmodule ExSieve.Builder.Join do
@moduledoc false
alias Ecto.Query.Builder.Join
import Ecto.Query
alias ExSieve.Node.{Grouping, Sort}

@spec build(Ecto.Queryable.t(), Grouping.t(), list(Sort.t())) :: {:ok, Ecto.Query.t()}
Expand Down Expand Up @@ -69,26 +69,32 @@ defmodule ExSieve.Builder.Join do
end
end

defp do_apply_join({parent, relation} = pr, query) do
query
|> Macro.escape()
|> Join.build(:inner, join_binding(parent), expr(relation), nil, nil, join_as(pr), nil, nil, __ENV__)
|> elem(0)
|> Code.eval_quoted()
|> elem(0)
defp do_apply_join({parent, relation} = parent_relation, query)
when is_atom(relation) and (is_binary(parent) or is_nil(parent)) and
(is_atom(query) or :erlang.map_get(:__struct__, query) == Ecto.Query) do
as = join_as(parent_relation)
query |> Macro.escape() |> join_build(parent_relation, as) |> elem(0)
end

defp join_binding(nil), do: [Macro.var(:query, __MODULE__)]
defp join_build(query, {nil, relation}, as) do
Code.eval_quoted(
quote do
join(unquote(query), :inner, [p], a in assoc(p, unquote(relation)), as: unquote(as))
end
)
end

defp join_binding(parent), do: [{String.to_atom(parent), Macro.var(:query, __MODULE__)}]
defp join_build(query, {string, relation}, as) do
parent = String.to_atom(string)

Code.eval_quoted(
quote do
join(unquote(query), :inner, [{unquote(parent), p}], a in assoc(p, unquote(relation)), as: unquote(as))
end
)
end

defp join_as({nil, relation}), do: relation

defp join_as({parent, relation}), do: :"#{parent}_#{relation}"

defp expr(relation) do
quote do
unquote(Macro.var(relation, __MODULE__)) in assoc(query, unquote(relation))
end
end
end

0 comments on commit 174f003

Please sign in to comment.