Skip to content

Instantly share code, notes, and snippets.

@zachdaniel
Created January 29, 2018 04:30
Show Gist options
  • Save zachdaniel/6a05803f22ee0270fe4338c3e76a87a5 to your computer and use it in GitHub Desktop.
Save zachdaniel/6a05803f22ee0270fe4338c3e76a87a5 to your computer and use it in GitHub Desktop.
defmodule MyApp.Query do
require Ecto.Query
defmacro from(expr, kw \\ []) do
expr = alter_from(expr)
kw = alter_kw(kw)
quote do
Ecto.Query.from(unquote(expr), unquote(kw))
end
end
defp alter_from({:in, meta, [var, schema = {:__aliases__, _, _}]}) do
new_source = quote do
schema = unquote(schema)
if MyApp.is_special_schema?(schema) do
schema.query()
else
schema
end
end
{:in, meta, [var, new_source]}
end
defp alter_from(other) do
other
end
@joins [:join, :inner_join, :cross_join, :left_join, :right_join, :full_join,
:inner_lateral_join, :left_lateral_join]
# This is reductive in preparation of potentially having to add more keywords for `assoc`
defp alter_kw([]), do: []
defp alter_kw([{join, {:in, meta, [var, schema = {:__aliases__, _, _}]}} | tail]) when join in @joins do
new_source = quote do
schema = unquote(schema)
if MyApp.is_special_schema?(schema) do
query = schema.query
if query.select do
Ecto.Query.subquery(query)
else
query
end
else
schema
end
end
[{join, {:in, meta, [var, quote do ^unquote(new_source) end]}} | alter_kw(tail)]
end
defp alter_kw([head | tail]) do
[head | alter_kw(tail)]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment