Packages

O Skeleton Query ajuda a criar composes para queries feitas usando o Ecto.Repo.

Current section

Files

Jump to
skeleton_query lib skeleton query.ex
Raw

lib/skeleton/query.ex

defmodule Skeleton.Query do
alias Skeleton.Query.Config, as: QueryConfig
# Callbacks
@callback start_query(Map.t()) :: Ecto.Query.t()
defmacro __using__(opts) do
alias Skeleton.Query, as: Qry
alias Skeleton.Query.Config, as: QueryConfig
quote do
@behaviour Skeleton.Query
@repo unquote(opts[:repo]) || QueryConfig.repo()
def all(context, opts \\ []), do: Qry.all(__MODULE__, @repo, context, opts)
def one(context, opts \\ []), do: Qry.one(__MODULE__, @repo, context, opts)
def aggregate(context, aggregate, field, opts \\ []),
do: Qry.aggregate(__MODULE__, @repo, context, aggregate, field, opts)
@before_compile Skeleton.Query
end
end
defmacro __before_compile__(_) do
quote do
def filter_by(query, _, _args), do: query
def sort_by(query, _, _args), do: query
defoverridable filter_by: 3, sort_by: 3
end
end
# All
def all(module, repo, context, opts) do
module
|> prepare_query(context)
|> repo.all(prefix: get_prefix(opts))
end
def one(module, repo, context, opts) do
module
|> prepare_query(context)
|> repo.one(prefix: get_prefix(opts))
end
def aggregate(module, repo, context, aggregate, field, opts) do
module
|> prepare_query(context)
|> repo.aggregate(aggregate, field, prefix: get_prefix(opts))
end
# Get prefix
defp get_prefix(opts) do
opts[:prefix] || "public"
end
# Prepare query
defp prepare_query(module, context) do
context
|> module.start_query()
|> build_filters(module, context)
|> build_sorts(module, context)
end
# Build filters
defp build_filters(query, module, context) do
Enum.reduce(context, query, fn f, query ->
apply(module, :filter_by, [query, f, context])
end)
end
# Build sorts
defp build_sorts(query, module, context) do
context
|> Map.get(QueryConfig.sort_param(), [])
|> Enum.map(&String.to_atom/1)
|> Enum.reduce(query, fn o, query ->
apply(module, :sort_by, [query, o, context])
end)
end
end