/
execution.ex
91 lines (76 loc) · 2.24 KB
/
execution.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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:
```
{
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