@@ -57,53 +57,142 @@ def initialize(query:, lazies_at_depth:)
57
57
end
58
58
59
59
def final_result
60
- @response && @response . graphql_result_data
60
+ @response . respond_to? ( :graphql_result_data ) ? @response . graphql_result_data : @response
61
61
end
62
62
63
63
def inspect
64
64
"#<#{ self . class . name } response=#{ @response . inspect } >"
65
65
end
66
66
67
- # This _begins_ the execution. Some deferred work
68
- # might be stored up in lazies.
69
67
# @return [void]
70
68
def run_eager
71
- root_operation = query . selected_operation
72
- root_op_type = root_operation . operation_type || "query"
73
- root_type = schema . root_type_for_operation ( root_op_type )
74
- runtime_object = root_type . wrap ( query . root_value , context )
75
- runtime_object = schema . sync_lazy ( runtime_object )
76
- is_eager = root_op_type == "mutation"
77
- @response = GraphQLResultHash . new ( nil , root_type , runtime_object , nil , false , root_operation . selections , is_eager , root_operation , nil , nil )
78
- st = get_current_runtime_state
79
- st . current_result = @response
80
-
81
- if runtime_object . nil?
82
- # Root .authorized? returned false.
83
- @response = nil
69
+ root_type = query . root_type
70
+ case query
71
+ when GraphQL ::Query
72
+ ast_node = query . selected_operation
73
+ selections = ast_node . selections
74
+ object = query . root_value
75
+ is_eager = ast_node . operation_type == "mutation"
76
+ base_path = nil
77
+ when GraphQL ::Query ::Partial
78
+ ast_node = query . ast_nodes . first
79
+ selections = query . ast_nodes . map ( &:selections ) . inject ( &:+ )
80
+ object = query . object
81
+ is_eager = false
82
+ base_path = query . path
84
83
else
85
- call_method_on_directives ( :resolve , runtime_object , root_operation . directives ) do # execute query level directives
86
- each_gathered_selections ( @response ) do |selections , is_selection_array , ordered_result_keys |
87
- @response . ordered_result_keys ||= ordered_result_keys
88
- if is_selection_array
89
- selection_response = GraphQLResultHash . new ( nil , root_type , runtime_object , nil , false , selections , is_eager , root_operation , nil , nil )
90
- selection_response . ordered_result_keys = ordered_result_keys
91
- final_response = @response
92
- else
93
- selection_response = @response
94
- final_response = nil
95
- end
84
+ raise ArgumentError , "Unexpected Runnable, can't execute: #{ query . class } (#{ query . inspect } )"
85
+ end
86
+ object = schema . sync_lazy ( object ) # TODO test query partial with lazy root object
87
+ runtime_state = get_current_runtime_state
88
+ case root_type . kind . name
89
+ when "OBJECT"
90
+ object_proxy = root_type . wrap ( object , context )
91
+ object_proxy = schema . sync_lazy ( object_proxy )
92
+ if object_proxy . nil?
93
+ @response = nil
94
+ else
95
+ @response = GraphQLResultHash . new ( nil , root_type , object_proxy , nil , false , selections , is_eager , ast_node , nil , nil )
96
+ @response . base_path = base_path
97
+ runtime_state . current_result = @response
98
+ call_method_on_directives ( :resolve , object , ast_node . directives ) do
99
+ each_gathered_selections ( @response ) do |selections , is_selection_array , ordered_result_keys |
100
+ @response . ordered_result_keys ||= ordered_result_keys
101
+ if is_selection_array
102
+ selection_response = GraphQLResultHash . new ( nil , root_type , object_proxy , nil , false , selections , is_eager , ast_node , nil , nil )
103
+ selection_response . ordered_result_keys = ordered_result_keys
104
+ final_response = @response
105
+ else
106
+ selection_response = @response
107
+ final_response = nil
108
+ end
96
109
97
- @dataloader . append_job {
98
- evaluate_selections (
99
- selections ,
100
- selection_response ,
101
- final_response ,
102
- nil ,
110
+ @dataloader . append_job {
111
+ evaluate_selections (
112
+ selections ,
113
+ selection_response ,
114
+ final_response ,
115
+ nil ,
116
+ )
117
+ }
118
+ end
119
+ end
120
+ end
121
+ when "LIST"
122
+ inner_type = root_type . unwrap
123
+ case inner_type . kind . name
124
+ when "SCALAR" , "ENUM"
125
+ result_name = ast_node . alias || ast_node . name
126
+ owner_type = query . field_definition . owner
127
+ selection_result = GraphQLResultHash . new ( nil , owner_type , nil , nil , false , EmptyObjects ::EMPTY_ARRAY , false , ast_node , nil , nil )
128
+ selection_result . base_path = base_path
129
+ selection_result . ordered_result_keys = [ result_name ]
130
+ runtime_state = get_current_runtime_state
131
+ runtime_state . current_result = selection_result
132
+ runtime_state . current_result_name = result_name
133
+ field_defn = query . field_definition
134
+ continue_value = continue_value ( object , field_defn , false , ast_node , result_name , selection_result )
135
+ if HALT != continue_value
136
+ continue_field ( continue_value , owner_type , field_defn , root_type , ast_node , nil , false , nil , nil , result_name , selection_result , false , runtime_state ) # rubocop:disable Metrics/ParameterLists
137
+ end
138
+ @response = selection_result [ result_name ]
139
+ else
140
+ @response = GraphQLResultArray . new ( nil , root_type , nil , nil , false , selections , false , ast_node , nil , nil )
141
+ @response . base_path = base_path
142
+ idx = nil
143
+ object . each do |inner_value |
144
+ idx ||= 0
145
+ this_idx = idx
146
+ idx += 1
147
+ @dataloader . append_job do
148
+ runtime_state . current_result_name = this_idx
149
+ runtime_state . current_result = @response
150
+ continue_field (
151
+ inner_value , root_type , nil , inner_type , nil , @response . graphql_selections , false , object_proxy ,
152
+ nil , this_idx , @response , false , runtime_state
103
153
)
104
- }
154
+ end
155
+ end
156
+ end
157
+ when "SCALAR" , "ENUM"
158
+ result_name = ast_node . alias || ast_node . name
159
+ owner_type = query . field_definition . owner
160
+ selection_result = GraphQLResultHash . new ( nil , query . parent_type , nil , nil , false , EmptyObjects ::EMPTY_ARRAY , false , ast_node , nil , nil )
161
+ selection_result . ordered_result_keys = [ result_name ]
162
+ selection_result . base_path = base_path
163
+ runtime_state = get_current_runtime_state
164
+ runtime_state . current_result = selection_result
165
+ runtime_state . current_result_name = result_name
166
+ field_defn = query . field_definition
167
+ continue_value = continue_value ( object , field_defn , false , ast_node , result_name , selection_result )
168
+ if HALT != continue_value
169
+ continue_field ( continue_value , owner_type , field_defn , query . root_type , ast_node , nil , false , nil , nil , result_name , selection_result , false , runtime_state ) # rubocop:disable Metrics/ParameterLists
170
+ end
171
+ @response = selection_result [ result_name ]
172
+ when "UNION" , "INTERFACE"
173
+ resolved_type , _resolved_obj = resolve_type ( root_type , object )
174
+ resolved_type = schema . sync_lazy ( resolved_type )
175
+ object_proxy = resolved_type . wrap ( object , context )
176
+ object_proxy = schema . sync_lazy ( object_proxy )
177
+ @response = GraphQLResultHash . new ( nil , resolved_type , object_proxy , nil , false , selections , false , query . ast_nodes . first , nil , nil )
178
+ @response . base_path = base_path
179
+ each_gathered_selections ( @response ) do |selections , is_selection_array , ordered_result_keys |
180
+ @response . ordered_result_keys ||= ordered_result_keys
181
+ if is_selection_array == true
182
+ raise "This isn't supported yet"
105
183
end
184
+
185
+ @dataloader . append_job {
186
+ evaluate_selections (
187
+ selections ,
188
+ @response ,
189
+ nil ,
190
+ runtime_state ,
191
+ )
192
+ }
106
193
end
194
+ else
195
+ raise "Invariant: unsupported type kind for partial execution: #{ root_type . kind . inspect } (#{ root_type } )"
107
196
end
108
197
nil
109
198
end
0 commit comments