defmodule Absinthe.Blueprint.Execution do
@moduledoc """
Blueprint Execution Data
The `%Absinthe.Blueprint.Execution{}` struct holds on to the core values that
drive a document's execution.
Here's how the execution flow works. Given a document like:
```graphql
{
posts {
title
author { name }
}
}
```
After all the validation happens, and we're actually going to execute this document,
an `%Execution{}` struct is created. This struct is passed to each plugin's
`before_resolution` callback, so that plugins can set initial values in the accumulator
or context.
Then the resolution phase walks the document until it hits the `posts` field.
To resolve the posts field, an `%Absinthe.Resolution{}` struct is created from
the `%Execution{}` struct. This resolution struct powers the normal middleware
resolution process. When a field has resolved, the `:acc`, `:context`, and `:field_cache`
values within the resolution struct are pulled out and used to update the execution.
"""
alias Absinthe.Blueprint.Result
alias Absinthe.Phase
@type acc :: map
defstruct [
:adapter,
:schema,
fragments: %{},
fields_cache: %{},
validation_errors: [],
result: nil,
acc: %{},
context: %{},
root_value: %{}
]
@type t :: %__MODULE__{
validation_errors: [Phase.Error.t()],
result: nil | Result.Object.t(),
acc: acc
}
@type node_t ::
Result.Object
| Result.List
| Result.Leaf
def get(%{execution: %{result: nil} = exec} = bp_root, operation) do
result = %Result.Object{
root_value: exec.root_value,
emitter: operation
}
%{
exec
| result: result,
adapter: bp_root.adapter,
schema: bp_root.schema,
fragments: Map.new(bp_root.fragments, &{&1.name, &1})
}
end
def get(%{execution: exec}, _) do
exec
end
def get_result(%__MODULE__{result: nil, root_value: root_value}, operation) do
%Result.Object{
root_value: root_value,
emitter: operation
}
end
def get_result(%{result: result}, _, _) do
result
end
def update(resolution, result, context, acc) do
%{resolution | context: context, result: result, acc: acc}
end
end