@@ -6,6 +6,7 @@ defmodule GraphQL.Execution.Executor do
66 # {:ok, %{hello: "world"}}
77 """
88
9+ alias GraphQL.Execution.ExecutionContext
910 alias GraphQL.Type.ObjectType
1011 alias GraphQL.Type.List
1112 alias GraphQL.Type.Interface
@@ -26,60 +27,19 @@ defmodule GraphQL.Execution.Executor do
2627 """
2728 @ spec execute ( GraphQL.Schema . t , GraphQL.Document . t , map , map , String . t ) :: result_data | { :error , % { errors: list } }
2829 def execute ( schema , document , root_value \\ % { } , variable_values \\ % { } , operation_name \\ nil ) do
29- context = build_execution_context ( schema , document , root_value , variable_values , operation_name )
30+ context = ExecutionContext . new ( schema , document , root_value , variable_values , operation_name )
3031 case context . errors do
3132 [ ] -> execute_operation ( context , context . operation , root_value )
3233 _ -> { :error , % { errors: Enum . dedup ( context . errors ) } }
3334 end
3435 end
3536
36- @ spec report_error ( context , String . t ) :: context
37- defp report_error ( context , msg ) do
38- put_in ( context . errors , [ % { "message" => msg } | context . errors ] )
39- end
40-
41- @ type context :: % {
42- schema: GraphQL.Schema . t ,
43- fragments: struct ,
44- root_value: Map ,
45- operation: Map ,
46- variable_values: Map ,
47- errors: list ( GraphQL.Error . t )
48- }
49-
5037 @ type operation :: % {
5138 kind: :OperationDefintion ,
5239 operation: atom
5340 }
5441
55- @ spec build_execution_context ( GraphQL.Schema . t , GraphQL.Document . t , map , map , String . t ) :: context
56- defp build_execution_context ( schema , document , root_value , variable_values , operation_name ) do
57- Enum . reduce document . definitions , % {
58- schema: schema ,
59- fragments: % { } ,
60- root_value: root_value ,
61- operation: nil ,
62- variable_values: variable_values || % { } , # TODO: We need to deeply set keys as strings or atoms. not allow both.
63- errors: [ ]
64- } , fn ( definition , context ) ->
65-
66- case definition do
67- % { kind: :OperationDefinition } ->
68- cond do
69- ! operation_name && context . operation ->
70- report_error ( context , "Must provide operation name if query contains multiple operations." )
71- ! operation_name || definition . name . value === operation_name ->
72- context = % { context | operation: definition }
73- % { context | variable_values: GraphQL.Execution.Variables . extract ( context ) }
74- true -> context
75- end
76- % { kind: :FragmentDefinition } ->
77- put_in ( context . fragments [ definition . name . value ] , definition )
78- end
79- end
80- end
81-
82- @ spec execute_operation ( context , operation , map ) :: result_data | { :error , String . t }
42+ @ spec execute_operation ( ExecutionContext . t , operation , map ) :: result_data | { :error , String . t }
8343 defp execute_operation ( context , operation , root_value ) do
8444 type = operation_root_type ( context . schema , operation )
8545 % { fields: fields } = collect_fields ( context , type , operation . selectionSet )
@@ -118,12 +78,12 @@ defmodule GraphQL.Execution.Executor do
11878 end
11979 end
12080
121- @ spec execute_fields ( context , atom | Map , any , any ) :: any
81+ @ spec execute_fields ( ExecutionContext . t , atom | Map , any , any ) :: any
12282 defp execute_fields ( context , parent_type , source_value , fields ) when is_atom ( parent_type ) do
12383 execute_fields ( context , apply ( parent_type , :type , [ ] ) , source_value , fields )
12484 end
12585
126- @ spec execute_fields ( context , atom | Map , any , any ) :: any
86+ @ spec execute_fields ( ExecutionContext . t , atom | Map , any , any ) :: any
12787 defp execute_fields ( context , parent_type , source_value , fields ) do
12888 Enum . reduce fields , % { } , fn ( { field_name_ast , field_asts } , results ) ->
12989 case resolve_field ( context , parent_type , source_value , field_asts ) do
@@ -133,7 +93,7 @@ defmodule GraphQL.Execution.Executor do
13393 end
13494 end
13595
136- @ spec execute_fields_serially ( context , atom , map , any ) :: any
96+ @ spec execute_fields_serially ( ExecutionContext . t , atom , map , any ) :: any
13797 defp execute_fields_serially ( context , parent_type , source_value , fields ) do
13898 # call execute_fields because no async operations yet
13999 execute_fields ( context , parent_type , source_value , fields )
@@ -188,7 +148,7 @@ defmodule GraphQL.Execution.Executor do
188148
189149 defp complete_value ( _ , _ , _ , _ , nil ) , do: nil
190150
191- @ spec complete_value ( context , % ObjectType { } , GraphQL.Document . t , any , map ) :: map
151+ @ spec complete_value ( ExecutionContext . t , % ObjectType { } , GraphQL.Document . t , any , map ) :: map
192152 defp complete_value ( context , % ObjectType { } = return_type , field_asts , _info , result ) do
193153 sub_field_asts = collect_sub_fields ( context , return_type , field_asts )
194154 execute_fields ( context , return_type , result , sub_field_asts . fields )
@@ -198,20 +158,20 @@ defmodule GraphQL.Execution.Executor do
198158 complete_value ( context , % NonNull { ofType: apply ( inner_type , :type , [ ] ) } , field_asts , info , result )
199159 end
200160
201- @ spec complete_value ( context , % NonNull { } , GraphQL.Document . t , any , any ) :: map
161+ @ spec complete_value ( ExecutionContext . t , % NonNull { } , GraphQL.Document . t , any , any ) :: map
202162 defp complete_value ( context , % NonNull { ofType: inner_type } , field_asts , info , result ) do
203163 # TODO: Null Checking
204164 complete_value ( context , inner_type , field_asts , info , result )
205165 end
206166
207- @ spec complete_value ( context , % Interface { } , GraphQL.Document . t , any , any ) :: map
167+ @ spec complete_value ( ExecutionContext . t , % Interface { } , GraphQL.Document . t , any , any ) :: map
208168 defp complete_value ( context , % Interface { } = return_type , field_asts , info , result ) do
209169 runtime_type = AbstractType . get_object_type ( return_type , result , info . schema )
210170 sub_field_asts = collect_sub_fields ( context , runtime_type , field_asts )
211171 execute_fields ( context , runtime_type , result , sub_field_asts . fields )
212172 end
213173
214- @ spec complete_value ( context , % Union { } , GraphQL.Document . t , any , any ) :: map
174+ @ spec complete_value ( ExecutionContext . t , % Union { } , GraphQL.Document . t , any , any ) :: map
215175 defp complete_value ( context , % Union { } = return_type , field_asts , info , result ) do
216176 runtime_type = AbstractType . get_object_type ( return_type , result , info . schema )
217177 sub_field_asts = collect_sub_fields ( context , runtime_type , field_asts )
@@ -222,7 +182,7 @@ defmodule GraphQL.Execution.Executor do
222182 complete_value ( context , % List { ofType: apply ( list_type , :type , [ ] ) } , field_asts , info , result )
223183 end
224184
225- @ spec complete_value ( context , % List { } , GraphQL.Document . t , any , any ) :: map
185+ @ spec complete_value ( ExecutionContext . t , % List { } , GraphQL.Document . t , any , any ) :: map
226186 defp complete_value ( context , % List { ofType: list_type } , field_asts , info , result ) do
227187 Enum . map result , fn ( item ) ->
228188 complete_value_catching_error ( context , list_type , field_asts , info , item )
0 commit comments