Packages
cqrs_tools
0.4.13
0.5.28
0.5.27
0.5.26
0.5.25
0.5.24
0.5.23
0.5.22
0.5.21
0.5.20
0.5.19
0.5.18
0.5.17
0.5.16
0.5.15
0.5.14
0.5.13
0.5.12
0.5.11
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.19
0.4.18
0.4.17
0.4.16
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.22
0.3.21
0.3.20
0.3.19
0.3.18
0.3.17
0.3.16
0.3.15
0.3.14
0.3.13
0.3.12
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.30
0.2.29
0.2.28
0.2.27
0.2.26
0.2.25
0.2.24
0.2.23
0.2.22
0.2.21
0.2.20
0.2.19
0.2.18
0.2.17
0.2.16
0.2.15
0.2.14
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.1
0.1.0
A collection of handy Elixir macros for CQRS applications.
Current section
Files
Jump to
Current section
Files
lib/cqrs/absinthe/query.ex
if Code.ensure_loaded?(Absinthe) do
defmodule Cqrs.Absinthe.Query do
@moduledoc false
alias Cqrs.{BoundedContext, Absinthe.Args, Absinthe.Metadata, Absinthe.Middleware, Absinthe.Query}
def create_connection_query(query_module, returns, opts) do
function_name = BoundedContext.__function_name__(query_module, opts)
query_args = create_query_args(query_module, opts)
description = query_module.__simple_moduledoc__()
opts =
:cqrs_tools
|> Application.get_env(:absinthe_relay, [])
|> Keyword.merge(opts)
repo = Keyword.fetch!(opts, :repo)
quote do
require Middleware
connection field unquote(function_name), node_type: unquote(returns) do
unquote_splicing(query_args)
description unquote(description)
Middleware.before_resolve(unquote(query_module), unquote(opts))
resolve(fn parent, args, resolution ->
alias Absinthe.Relay.Connection
args =
unquote(query_module)
|> Query.read_filters_from_parent(parent, unquote(opts))
|> Map.merge(args)
opts = Metadata.merge(resolution, unquote(opts))
case BoundedContext.__create_query__(unquote(query_module), args, opts) do
{:error, error} ->
{:error, error}
{:ok, query} ->
repo_fun = fn args ->
fun = Keyword.get(unquote(opts), :repo_fun, :all)
apply(unquote(repo), fun, [args])
end
Connection.from_query(query, repo_fun, args)
end
end)
Middleware.after_resolve(unquote(query_module), unquote(opts))
end
end
end
def create_query(query_module, returns, opts) do
function_name = BoundedContext.__function_name__(query_module, opts)
query_args = create_query_args(query_module, opts)
description = query_module.__simple_moduledoc__()
quote do
require Middleware
field unquote(function_name), unquote(returns) do
unquote_splicing(query_args)
description unquote(description)
Middleware.before_resolve(unquote(query_module), unquote(opts))
resolve(fn parent, args, resolution ->
opts =
resolution
|> Metadata.merge(unquote(opts))
|> Keyword.put(:tag?, true)
args =
unquote(query_module)
|> Query.read_filters_from_parent(parent, unquote(opts))
|> Map.merge(args)
case BoundedContext.__execute_query__(unquote(query_module), args, opts) do
{:ok, result} ->
{:ok, result}
{:error, map} when is_map(map) ->
{:error,
Enum.reduce(map, [], fn {key, messages}, acc ->
acc ++ Enum.map(messages, fn msg -> "#{key} #{msg}" end)
end)}
{:error, errors} ->
{:error, errors}
end
end)
Middleware.after_resolve(unquote(query_module), unquote(opts))
end
end
end
defp create_query_args(query_module, opts) do
filters_from_parent = opts |> filters_from_parent() |> Keyword.keys()
query_module.__filters__()
|> Enum.reject(fn {filter, _, _} -> Enum.member?(filters_from_parent, filter) end)
|> Args.extract_args(opts)
|> Enum.map(fn {name, absinthe_type, required, opts} ->
case required do
true -> quote do: arg(unquote(name), non_null(unquote(absinthe_type)), unquote(opts))
false -> quote do: arg(unquote(name), unquote(absinthe_type), unquote(opts))
end
end)
end
defp filters_from_parent(opts) do
Keyword.get(opts, :filters_from_parent, [])
end
require Logger
def read_filters_from_parent(_query_module, nil, _opts), do: %{}
def read_filters_from_parent(query_module, parent, opts) do
parent_keys = (Map.keys(parent) -- [:__meta__, :__struct__]) |> Enum.join(", ")
Logger.log(:debug, [
"QUERY FILTER FROM PARENT query=",
inspect(query_module),
" parent keys=[",
parent_keys,
"]"
])
opts
|> filters_from_parent()
|> Enum.reduce(%{}, fn {filter, parent_field}, acc ->
value = Map.get(parent, parent_field)
Logger.log(:debug, [
"SETTING FILTER FROM PARENT filter=",
inspect(filter),
" parent=",
inspect(parent_field),
" value=",
inspect(value)
])
Map.put(acc, filter, value)
end)
end
end
end