Current section
Files
Jump to
Current section
Files
lib/completion/completable_schema.ex
defmodule AbacusSql.Completable.Schema do
alias AbacusSql.Completion.Item
def children(schema, context, opts \\ []) do
assocs =
schema.__schema__(:associations)
|> Enum.reject(& schema.__schema__(:association, &1).__struct__ == Ecto.Association.HasThrough)
|> Enum.map(fn assoc ->
details = schema.__schema__(:association, assoc)
type = details.related
%Item{
code: to_string(assoc),
type: type,
display: schema.assoc_display(assoc, context),
description: schema.assoc_description(assoc, context)
}
end)
fields =
schema.__schema__(:fields)
|> Enum.map(fn field ->
type = schema.__schema__(:type, field)
%Item{
code: to_string(field),
type: type,
display: schema.field_display(field, context),
description: schema.field_description(field, context)
}
end)
(assocs ++ fields)
|> filter_only(Keyword.get(opts, :only, nil))
|> filter_except(Keyword.get(opts, :except, nil))
|> add_custom(Keyword.get(opts, :custom, []))
end
defp filter_only(results, nil), do: results
defp filter_only(results, only) do
only = Enum.map(only, &to_string/1)
Enum.filter(results, fn %{code: code} -> code in only end)
end
defp filter_except(results, nil), do: results
defp filter_except(results, except) do
except = Enum.map(except, &to_string/1)
Enum.filter(results, fn %{code: code} -> code not in except end)
end
defp add_custom(results, custom) do
Enum.map(custom, fn {field, type} ->
%Item{
code: to_string(field),
type: type
}
end)
|> Enum.concat(results)
end
@callback assoc_description(assoc :: atom, context :: term) :: binary
@callback assoc_display(assoc :: atom, context :: term) :: binary
@callback field_description(field :: atom, context :: term) :: binary
@callback field_display(field :: atom, context :: term) :: binary
defmacro __using__(opts \\ []) do
quote do
@behaviour AbacusSql.Completable
def completable_children(context) do
results = AbacusSql.Completable.Schema.children(__MODULE__, context, unquote(opts))
{:ok, results, context}
end
def assoc_display(_, _), do: nil
def assoc_description(_, _), do: nil
def field_display(_, _), do: nil
def field_description(_, _), do: nil
defoverridable(assoc_display: 2, assoc_description: 2, field_display: 2, field_description: 2)
end
end
end