agoo 2.5.7 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of agoo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +38 -0
- data/ext/agoo/agoo.c +11 -2
- data/ext/agoo/bind.c +15 -20
- data/ext/agoo/con.c +32 -25
- data/ext/agoo/debug.c +225 -162
- data/ext/agoo/debug.h +31 -51
- data/ext/agoo/doc.c +278 -5
- data/ext/agoo/doc.h +6 -1
- data/ext/agoo/err.c +1 -0
- data/ext/agoo/err.h +1 -0
- data/ext/agoo/error_stream.c +3 -6
- data/ext/agoo/gqlcobj.c +12 -0
- data/ext/agoo/gqlcobj.h +25 -0
- data/ext/agoo/gqleval.c +520 -0
- data/ext/agoo/gqleval.h +49 -0
- data/ext/agoo/gqlintro.c +1237 -97
- data/ext/agoo/gqlintro.h +8 -0
- data/ext/agoo/gqljson.c +460 -0
- data/ext/agoo/gqljson.h +15 -0
- data/ext/agoo/gqlvalue.c +679 -136
- data/ext/agoo/gqlvalue.h +29 -7
- data/ext/agoo/graphql.c +841 -362
- data/ext/agoo/graphql.h +180 -90
- data/ext/agoo/hook.c +8 -16
- data/ext/agoo/http.c +3 -4
- data/ext/agoo/log.c +22 -25
- data/ext/agoo/log.h +1 -0
- data/ext/agoo/page.c +24 -40
- data/ext/agoo/pub.c +23 -21
- data/ext/agoo/queue.c +2 -4
- data/ext/agoo/ready.c +9 -9
- data/ext/agoo/req.c +80 -5
- data/ext/agoo/req.h +2 -0
- data/ext/agoo/res.c +1 -3
- data/ext/agoo/rgraphql.c +753 -0
- data/ext/agoo/rresponse.c +9 -15
- data/ext/agoo/rserver.c +18 -17
- data/ext/agoo/sdl.c +1264 -120
- data/ext/agoo/sdl.h +8 -1
- data/ext/agoo/sectime.c +136 -0
- data/ext/agoo/sectime.h +19 -0
- data/ext/agoo/server.c +1 -3
- data/ext/agoo/subject.c +2 -4
- data/ext/agoo/text.c +124 -18
- data/ext/agoo/text.h +5 -1
- data/ext/agoo/upgraded.c +2 -4
- data/lib/agoo/version.rb +1 -1
- data/test/base_handler_test.rb +43 -40
- data/test/bind_test.rb +49 -48
- data/test/graphql_test.rb +1019 -0
- data/test/hijack_test.rb +1 -1
- data/test/rack_handler_test.rb +40 -34
- data/test/static_test.rb +33 -32
- metadata +17 -6
data/ext/agoo/gqleval.h
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
// Copyright (c) 2018, Peter Ohler, All rights reserved.
|
2
|
+
|
3
|
+
#ifndef AGOO_GQLEVAL_H
|
4
|
+
#define AGOO_GQLEVAL_H
|
5
|
+
|
6
|
+
#include <stdbool.h>
|
7
|
+
|
8
|
+
#include "err.h"
|
9
|
+
|
10
|
+
// Used for references to implemenation entities.
|
11
|
+
typedef void* gqlRef;
|
12
|
+
|
13
|
+
typedef struct _gqlKeyVal {
|
14
|
+
const char *key;
|
15
|
+
struct _gqlValue *value;
|
16
|
+
} *gqlKeyVal;
|
17
|
+
|
18
|
+
struct _gqlDoc;
|
19
|
+
struct _gqlField;
|
20
|
+
struct _gqlSel;
|
21
|
+
struct _gqlType;
|
22
|
+
struct _gqlValue;
|
23
|
+
|
24
|
+
// Resolve field on a target to a child reference.
|
25
|
+
typedef int (*gqlResolveFunc)(agooErr err,
|
26
|
+
struct _gqlDoc *doc,
|
27
|
+
gqlRef target,
|
28
|
+
struct _gqlField *field,
|
29
|
+
struct _gqlSel *sel,
|
30
|
+
struct _gqlValue *result,
|
31
|
+
int depth);
|
32
|
+
|
33
|
+
// Determine the type of a reference. Return NULL if can't be determined.
|
34
|
+
typedef struct _gqlType* (*gqlTypeFunc)(gqlRef ref);
|
35
|
+
|
36
|
+
|
37
|
+
extern struct _gqlValue* gql_doc_eval(agooErr err, struct _gqlDoc *doc);
|
38
|
+
extern struct _gqlValue* gql_get_arg_value(gqlKeyVal args, const char *key);
|
39
|
+
extern int gql_eval_sels(agooErr err, struct _gqlDoc *doc, gqlRef ref, struct _gqlField *field, struct _gqlSel *sels, struct _gqlValue *result, int depth);
|
40
|
+
extern int gql_set_typename(agooErr err, struct _gqlType *type, const char *key, struct _gqlValue *result);
|
41
|
+
|
42
|
+
extern gqlRef gql_root;
|
43
|
+
extern gqlResolveFunc gql_resolve_func;
|
44
|
+
extern gqlTypeFunc gql_type_func;
|
45
|
+
extern gqlRef (*gql_root_op)(const char *op);
|
46
|
+
|
47
|
+
extern struct _gqlValue* (*gql_doc_eval_func)(agooErr err, struct _gqlDoc *doc);
|
48
|
+
|
49
|
+
#endif // AGOO_GQLEVAL_H
|
data/ext/agoo/gqlintro.c
CHANGED
@@ -1,21 +1,15 @@
|
|
1
1
|
// Copyright (c) 2018, Peter Ohler, All rights reserved.
|
2
2
|
|
3
|
+
#include <stdio.h>
|
3
4
|
#include <stdlib.h>
|
4
5
|
#include <string.h>
|
5
6
|
|
7
|
+
#include "debug.h"
|
8
|
+
#include "gqlcobj.h"
|
6
9
|
#include "gqlintro.h"
|
7
10
|
#include "gqlvalue.h"
|
8
11
|
#include "graphql.h"
|
9
12
|
|
10
|
-
static gqlType schema_type;
|
11
|
-
static gqlType type_type;
|
12
|
-
static gqlType type_kind_type;
|
13
|
-
static gqlType field_type;
|
14
|
-
static gqlType input_value_type;
|
15
|
-
static gqlType enum_value_type;
|
16
|
-
static gqlType directive_type;
|
17
|
-
static gqlType directive_location_type;
|
18
|
-
|
19
13
|
// type __Schema {
|
20
14
|
// types: [__Type!]!
|
21
15
|
// queryType: __Type!
|
@@ -23,33 +17,30 @@ static gqlType directive_location_type;
|
|
23
17
|
// subscriptionType: __Type
|
24
18
|
// directives: [__Directive!]!
|
25
19
|
// }
|
26
|
-
static gqlRef
|
27
|
-
schema_types_resolve(gqlRef target, const char *fieldName, gqlKeyVal *args) {
|
28
|
-
// TBD
|
29
|
-
return NULL;
|
30
|
-
}
|
31
|
-
|
32
|
-
static gqlRef
|
33
|
-
schema_query_type_resolve(gqlRef target, const char *fieldName, gqlKeyVal *args) {
|
34
|
-
// TBD return schema_type.query.type
|
35
|
-
// lookup "schema" type
|
36
|
-
// get query field
|
37
|
-
// get return type of field
|
38
|
-
return NULL;
|
39
|
-
}
|
40
|
-
|
41
20
|
static int
|
42
21
|
create_schema_type(agooErr err) {
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
22
|
+
gqlType type;
|
23
|
+
gqlType type_type;
|
24
|
+
gqlType type_list;
|
25
|
+
gqlType dir_type;
|
26
|
+
gqlType dir_list;
|
27
|
+
|
28
|
+
if (NULL == (type = gql_type_create(err, "__Schema", NULL, 0, NULL)) ||
|
29
|
+
|
30
|
+
NULL == (type_type = gql_assure_type(err, "__Type")) ||
|
31
|
+
NULL == (type_list = gql_assure_list(err, type_type, true)) ||
|
32
|
+
NULL == (dir_type = gql_assure_type(err, "__Directive")) ||
|
33
|
+
NULL == (dir_list = gql_assure_list(err, dir_type, true)) ||
|
34
|
+
|
35
|
+
NULL == gql_type_field(err, type, "types", type_list, NULL, NULL, 0, true) ||
|
36
|
+
NULL == gql_type_field(err, type, "queryType", type_type, NULL, NULL, 0, true) ||
|
37
|
+
NULL == gql_type_field(err, type, "mutationType", type_type, NULL, NULL, 0, false) ||
|
38
|
+
NULL == gql_type_field(err, type, "subscriptionType", type_type, NULL, NULL, 0, false) ||
|
39
|
+
NULL == gql_type_field(err, type, "directives", dir_list, NULL, NULL, 0, true)) {
|
49
40
|
|
50
41
|
return err->code;
|
51
42
|
}
|
52
|
-
|
43
|
+
type->core = true;
|
53
44
|
|
54
45
|
return AGOO_ERR_OK;
|
55
46
|
}
|
@@ -67,29 +58,49 @@ create_schema_type(agooErr err) {
|
|
67
58
|
// }
|
68
59
|
static int
|
69
60
|
create_type_type(agooErr err) {
|
61
|
+
gqlType type;
|
70
62
|
gqlField fields = NULL;
|
71
63
|
gqlField enum_values = NULL;
|
72
64
|
gqlValue dv;
|
65
|
+
gqlType kind_type;
|
66
|
+
gqlType type_list;
|
67
|
+
gqlType field_type;
|
68
|
+
gqlType field_list;
|
69
|
+
gqlType enum_type;
|
70
|
+
gqlType enum_list;
|
71
|
+
gqlType input_type;
|
72
|
+
gqlType input_list;
|
73
73
|
|
74
|
-
if (NULL == (
|
75
|
-
|
76
|
-
NULL ==
|
77
|
-
NULL ==
|
78
|
-
NULL == (
|
79
|
-
NULL ==
|
80
|
-
NULL ==
|
81
|
-
NULL == (
|
82
|
-
NULL ==
|
83
|
-
NULL ==
|
74
|
+
if (NULL == (type = gql_type_create(err, "__Type", NULL, 0, NULL)) ||
|
75
|
+
|
76
|
+
NULL == (type_list = gql_assure_list(err, type, true)) ||
|
77
|
+
NULL == (field_type = gql_assure_type(err, "__Field")) ||
|
78
|
+
NULL == (field_list = gql_assure_list(err, field_type, true)) ||
|
79
|
+
NULL == (kind_type = gql_assure_type(err, "__TypeKind")) ||
|
80
|
+
NULL == (enum_type = gql_assure_type(err, "__EnumValue")) ||
|
81
|
+
NULL == (enum_list = gql_assure_list(err, enum_type, true)) ||
|
82
|
+
NULL == (input_type = gql_assure_type(err, "__InputValue")) ||
|
83
|
+
NULL == (input_list = gql_assure_list(err, input_type, true)) ||
|
84
|
+
|
85
|
+
NULL == gql_type_field(err, type, "kind", kind_type, NULL, NULL, 0, true) ||
|
86
|
+
NULL == gql_type_field(err, type, "name", &gql_string_type, NULL, NULL, 0, false) ||
|
87
|
+
NULL == gql_type_field(err, type, "description", &gql_string_type, NULL, NULL, 0, false) ||
|
88
|
+
NULL == (fields = gql_type_field(err, type, "fields", field_list, NULL, NULL, 0, false)) ||
|
89
|
+
NULL == gql_type_field(err, type, "interfaces", type_list, NULL, NULL, 0, false) ||
|
90
|
+
NULL == gql_type_field(err, type, "possibleTypes", type_list, NULL, NULL, 0, false) ||
|
91
|
+
NULL == (enum_values = gql_type_field(err, type, "enumValues", enum_list, NULL, NULL, 0, false)) ||
|
92
|
+
NULL == gql_type_field(err, type, "inputFields", input_list, NULL, NULL, 0, false) ||
|
93
|
+
NULL == gql_type_field(err, type, "ofType", type, NULL, NULL, 0, false)) {
|
84
94
|
|
85
95
|
return err->code;
|
86
96
|
}
|
87
|
-
|
97
|
+
type->core = true;
|
88
98
|
|
89
99
|
if (NULL == (dv = gql_bool_create(err, false)) ||
|
90
|
-
|
100
|
+
|
101
|
+
NULL == gql_field_arg(err, fields, "includeDeprecated", &gql_bool_type, NULL, 0, dv, false) ||
|
91
102
|
NULL == (dv = gql_bool_create(err, false)) ||
|
92
|
-
NULL == gql_field_arg(err, enum_values, "includeDeprecated", &gql_bool_type, NULL, dv, false)) {
|
103
|
+
NULL == gql_field_arg(err, enum_values, "includeDeprecated", &gql_bool_type, NULL, 0, dv, false)) {
|
93
104
|
|
94
105
|
return err->code;
|
95
106
|
}
|
@@ -110,11 +121,15 @@ create_type_kind_type(agooErr err) {
|
|
110
121
|
NULL
|
111
122
|
};
|
112
123
|
const char **cp;
|
113
|
-
|
114
|
-
|
115
|
-
|
124
|
+
gqlType type;
|
125
|
+
|
126
|
+
if (NULL == (type = gql_enum_create(err, "__TypeKind", NULL, 0))) {
|
127
|
+
return err->code;
|
128
|
+
}
|
129
|
+
type->core = true;
|
130
|
+
|
116
131
|
for (cp = choices; NULL != *cp; cp++) {
|
117
|
-
if (
|
132
|
+
if (NULL == gql_enum_append(err, type, *cp, 0, NULL, 0)) {
|
118
133
|
return err->code;
|
119
134
|
}
|
120
135
|
}
|
@@ -131,17 +146,27 @@ create_type_kind_type(agooErr err) {
|
|
131
146
|
// }
|
132
147
|
static int
|
133
148
|
create_field_type(agooErr err) {
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
149
|
+
gqlType type;
|
150
|
+
gqlType type_type;
|
151
|
+
gqlType input_type;
|
152
|
+
gqlType input_list;
|
153
|
+
|
154
|
+
if (NULL == (type = gql_type_create(err, "__Field", NULL, 0, NULL)) ||
|
155
|
+
|
156
|
+
NULL == (type_type = gql_assure_type(err, "__Type")) ||
|
157
|
+
NULL == (input_type = gql_assure_type(err, "__InputValue")) ||
|
158
|
+
NULL == (input_list = gql_assure_list(err, input_type, true)) ||
|
159
|
+
|
160
|
+
NULL == gql_type_field(err, type, "name", &gql_string_type, NULL, NULL, 0, true) ||
|
161
|
+
NULL == gql_type_field(err, type, "description", &gql_string_type, NULL, NULL, 0, false) ||
|
162
|
+
NULL == gql_type_field(err, type, "args", input_list, NULL, NULL, 0, true) ||
|
163
|
+
NULL == gql_type_field(err, type, "type", type_type, NULL, NULL, 0, true) ||
|
164
|
+
NULL == gql_type_field(err, type, "isDeprecated", &gql_bool_type, NULL, NULL, 0, true) ||
|
165
|
+
NULL == gql_type_field(err, type, "reason", &gql_string_type, NULL, NULL, 0, false)) {
|
141
166
|
|
142
167
|
return err->code;
|
143
168
|
}
|
144
|
-
|
169
|
+
type->core = true;
|
145
170
|
|
146
171
|
return AGOO_ERR_OK;
|
147
172
|
}
|
@@ -154,15 +179,21 @@ create_field_type(agooErr err) {
|
|
154
179
|
// }
|
155
180
|
static int
|
156
181
|
create_input_type(agooErr err) {
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
182
|
+
gqlType type;
|
183
|
+
gqlType type_type;
|
184
|
+
|
185
|
+
if (NULL == (type = gql_type_create(err, "__InputValue", NULL, 0, NULL)) ||
|
186
|
+
|
187
|
+
NULL == (type_type = gql_assure_type(err, "__Type")) ||
|
188
|
+
|
189
|
+
NULL == gql_type_field(err, type, "name", &gql_string_type, NULL, NULL, 0, true) ||
|
190
|
+
NULL == gql_type_field(err, type, "description", &gql_string_type, NULL, NULL, 0, false) ||
|
191
|
+
NULL == gql_type_field(err, type, "type", type_type, NULL, NULL, 0, true) ||
|
192
|
+
NULL == gql_type_field(err, type, "defaultValue", &gql_string_type, NULL, NULL, 0, false)) {
|
162
193
|
|
163
194
|
return err->code;
|
164
195
|
}
|
165
|
-
|
196
|
+
type->core = true;
|
166
197
|
|
167
198
|
return AGOO_ERR_OK;
|
168
199
|
}
|
@@ -175,15 +206,17 @@ create_input_type(agooErr err) {
|
|
175
206
|
// }
|
176
207
|
static int
|
177
208
|
create_enum_type(agooErr err) {
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
NULL == gql_type_field(err,
|
182
|
-
NULL == gql_type_field(err,
|
209
|
+
gqlType type;
|
210
|
+
|
211
|
+
if (NULL == (type = gql_type_create(err, "__EnumValue", NULL, 0, NULL)) ||
|
212
|
+
NULL == gql_type_field(err, type, "name", &gql_string_type, NULL, NULL, 0, true) ||
|
213
|
+
NULL == gql_type_field(err, type, "description", &gql_string_type, NULL, NULL, 0, false) ||
|
214
|
+
NULL == gql_type_field(err, type, "isDeprecated", &gql_bool_type, NULL, NULL, 0, true) ||
|
215
|
+
NULL == gql_type_field(err, type, "deprecationReason", &gql_string_type, NULL, NULL, 0, false)) {
|
183
216
|
|
184
217
|
return err->code;
|
185
218
|
}
|
186
|
-
|
219
|
+
type->core = true;
|
187
220
|
|
188
221
|
return AGOO_ERR_OK;
|
189
222
|
}
|
@@ -196,15 +229,27 @@ create_enum_type(agooErr err) {
|
|
196
229
|
// }
|
197
230
|
static int
|
198
231
|
create_directive_type(agooErr err) {
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
232
|
+
gqlType type;
|
233
|
+
gqlType input_type;
|
234
|
+
gqlType input_list;
|
235
|
+
gqlType loc_type;
|
236
|
+
gqlType loc_list;
|
237
|
+
|
238
|
+
if (NULL == (type = gql_type_create(err, "__Directive", NULL, 0, NULL)) ||
|
239
|
+
|
240
|
+
NULL == (input_type = gql_assure_type(err, "__InputValue")) ||
|
241
|
+
NULL == (input_list = gql_assure_list(err, input_type, true)) ||
|
242
|
+
NULL == (loc_type = gql_assure_type(err, "__DirectiveLocation")) ||
|
243
|
+
NULL == (loc_list = gql_assure_list(err, loc_type, true)) ||
|
244
|
+
|
245
|
+
NULL == gql_type_field(err, type, "name", &gql_string_type, NULL, NULL, 0, true) ||
|
246
|
+
NULL == gql_type_field(err, type, "description", &gql_string_type, NULL, NULL, 0, false) ||
|
247
|
+
NULL == gql_type_field(err, type, "locations", loc_list, NULL, NULL, 0, true) ||
|
248
|
+
NULL == gql_type_field(err, type, "args", input_list, NULL, NULL, 0, true)) {
|
204
249
|
|
205
250
|
return err->code;
|
206
251
|
}
|
207
|
-
|
252
|
+
type->core = true;
|
208
253
|
|
209
254
|
return AGOO_ERR_OK;
|
210
255
|
}
|
@@ -232,11 +277,14 @@ create_directive_location_type(agooErr err) {
|
|
232
277
|
"INPUT_FIELD_DEFINITION",
|
233
278
|
NULL };
|
234
279
|
const char **cp;
|
280
|
+
gqlType type;
|
235
281
|
|
236
|
-
|
237
|
-
|
282
|
+
if (NULL == (type = gql_enum_create(err, "__DirectiveLocation", NULL, 0))) {
|
283
|
+
return err->code;
|
284
|
+
}
|
285
|
+
type->core = true;
|
238
286
|
for (cp = choices; NULL != *cp; cp++) {
|
239
|
-
if (
|
287
|
+
if (NULL == gql_enum_append(err, type, *cp, 0, NULL, 0)) {
|
240
288
|
return err->code;
|
241
289
|
}
|
242
290
|
}
|
@@ -245,15 +293,16 @@ create_directive_location_type(agooErr err) {
|
|
245
293
|
|
246
294
|
static int
|
247
295
|
create_dir_skip(agooErr err) {
|
248
|
-
gqlDir dir = gql_directive_create(err, "skip", NULL,
|
296
|
+
gqlDir dir = gql_directive_create(err, "skip", NULL, 0);
|
249
297
|
|
250
298
|
if (NULL == dir) {
|
251
299
|
return err->code;
|
252
300
|
}
|
301
|
+
dir->core = true;
|
253
302
|
if (AGOO_ERR_OK != gql_directive_on(err, dir, "FIELD", -1) ||
|
254
303
|
AGOO_ERR_OK != gql_directive_on(err, dir, "FRAGMENT_SPREAD", -1) ||
|
255
304
|
AGOO_ERR_OK != gql_directive_on(err, dir, "INLINE_FRAGMENT", -1) ||
|
256
|
-
NULL == gql_dir_arg(err, dir, "if",
|
305
|
+
NULL == gql_dir_arg(err, dir, "if", &gql_bool_type, NULL, -1, NULL, true)) {
|
257
306
|
|
258
307
|
return err->code;
|
259
308
|
}
|
@@ -262,15 +311,16 @@ create_dir_skip(agooErr err) {
|
|
262
311
|
|
263
312
|
static int
|
264
313
|
create_dir_include(agooErr err) {
|
265
|
-
gqlDir dir = gql_directive_create(err, "include", NULL,
|
314
|
+
gqlDir dir = gql_directive_create(err, "include", NULL, 0);
|
266
315
|
|
267
316
|
if (NULL == dir) {
|
268
317
|
return err->code;
|
269
318
|
}
|
319
|
+
dir->core = true;
|
270
320
|
if (AGOO_ERR_OK != gql_directive_on(err, dir, "FIELD", -1) ||
|
271
321
|
AGOO_ERR_OK != gql_directive_on(err, dir, "FRAGMENT_SPREAD", -1) ||
|
272
322
|
AGOO_ERR_OK != gql_directive_on(err, dir, "INLINE_FRAGMENT", -1) ||
|
273
|
-
NULL == gql_dir_arg(err, dir, "if",
|
323
|
+
NULL == gql_dir_arg(err, dir, "if", &gql_bool_type, NULL, 0, NULL, true)) {
|
274
324
|
|
275
325
|
return err->code;
|
276
326
|
}
|
@@ -279,16 +329,17 @@ create_dir_include(agooErr err) {
|
|
279
329
|
|
280
330
|
static int
|
281
331
|
create_dir_deprecated(agooErr err) {
|
282
|
-
gqlDir dir = gql_directive_create(err, "deprecated", NULL,
|
332
|
+
gqlDir dir = gql_directive_create(err, "deprecated", NULL, 0);
|
283
333
|
gqlValue dv;
|
284
334
|
|
285
335
|
if (NULL == dir) {
|
286
336
|
return err->code;
|
287
337
|
}
|
338
|
+
dir->core = true;
|
288
339
|
if (AGOO_ERR_OK != gql_directive_on(err, dir, "FIELD_DEFINITION", -1) ||
|
289
340
|
AGOO_ERR_OK != gql_directive_on(err, dir, "ENUM_VALUE", -1) ||
|
290
341
|
NULL == (dv = gql_string_create(err, "No longer supported", -1)) ||
|
291
|
-
NULL == gql_dir_arg(err, dir, "reason",
|
342
|
+
NULL == gql_dir_arg(err, dir, "reason", &gql_string_type, NULL, -1, dv, false)) {
|
292
343
|
|
293
344
|
return err->code;
|
294
345
|
}
|
@@ -297,8 +348,6 @@ create_dir_deprecated(agooErr err) {
|
|
297
348
|
|
298
349
|
int
|
299
350
|
gql_intro_init(agooErr err) {
|
300
|
-
gqlField f;
|
301
|
-
|
302
351
|
if (AGOO_ERR_OK != create_type_kind_type(err) ||
|
303
352
|
AGOO_ERR_OK != create_input_type(err) ||
|
304
353
|
AGOO_ERR_OK != create_type_type(err) ||
|
@@ -313,21 +362,1112 @@ gql_intro_init(agooErr err) {
|
|
313
362
|
|
314
363
|
return err->code;
|
315
364
|
}
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
365
|
+
return AGOO_ERR_OK;
|
366
|
+
}
|
367
|
+
|
368
|
+
// introspection handlers /////////////////////////////////////////////////////////////////////
|
369
|
+
|
370
|
+
static struct _gqlCclass type_class;
|
371
|
+
|
372
|
+
static gqlValue
|
373
|
+
extract_arg(agooErr err, gqlField field, gqlSel sel, const char *key) {
|
374
|
+
if (NULL != sel->args) {
|
375
|
+
gqlSelArg sa;
|
376
|
+
gqlValue v = NULL;
|
377
|
+
|
378
|
+
for (sa = sel->args; NULL != sa; sa = sa->next) {
|
379
|
+
if (0 != strcmp(sa->name, key)) {
|
380
|
+
continue;
|
381
|
+
}
|
382
|
+
if (NULL != sa->var) {
|
383
|
+
v = sa->var->value;
|
384
|
+
} else {
|
385
|
+
v = sa->value;
|
386
|
+
}
|
387
|
+
if (NULL != field) {
|
388
|
+
gqlArg fa;
|
389
|
+
|
390
|
+
for (fa = field->args; NULL != fa; fa = fa->next) {
|
391
|
+
if (0 == strcmp(sa->name, fa->name)) {
|
392
|
+
if (v->type != fa->type && GQL_SCALAR_VAR != v->type->scalar_kind) {
|
393
|
+
if (AGOO_ERR_OK != gql_value_convert(err, v, fa->type)) {
|
394
|
+
return NULL;
|
395
|
+
}
|
396
|
+
}
|
397
|
+
break;
|
398
|
+
}
|
399
|
+
}
|
400
|
+
}
|
401
|
+
}
|
402
|
+
return v;
|
403
|
+
}
|
404
|
+
return NULL;
|
405
|
+
}
|
406
|
+
|
407
|
+
static bool
|
408
|
+
is_deprecated(gqlDirUse use) {
|
409
|
+
for (; NULL != use; use = use->next) {
|
410
|
+
if (0 == strcmp("deprecated", use->dir->name)) {
|
411
|
+
return true;
|
412
|
+
}
|
413
|
+
}
|
414
|
+
return false;
|
415
|
+
}
|
416
|
+
|
417
|
+
static const char*
|
418
|
+
deprecation_reason(gqlDirUse use) {
|
419
|
+
const char *reason = NULL;
|
420
|
+
|
421
|
+
for (; NULL != use; use = use->next) {
|
422
|
+
if (0 == strcmp("deprecated", use->dir->name)) {
|
423
|
+
gqlLink a;
|
424
|
+
|
425
|
+
for (a = use->args; NULL != a; a = a->next) {
|
426
|
+
if (0 == strcmp("reason", a->key)) {
|
427
|
+
reason = gql_string_get(a->value);
|
428
|
+
break;
|
429
|
+
}
|
430
|
+
}
|
431
|
+
}
|
432
|
+
}
|
433
|
+
return reason;
|
434
|
+
}
|
435
|
+
|
436
|
+
// InputValue
|
437
|
+
// name: String!
|
438
|
+
static int
|
439
|
+
input_value_name(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
440
|
+
const char *key = sel->name;
|
441
|
+
|
442
|
+
if (NULL != sel->alias) {
|
443
|
+
key = sel->alias;
|
444
|
+
}
|
445
|
+
return gql_object_set(err, result, key, gql_string_create(err, ((gqlArg)obj->ptr)->name, -1));
|
446
|
+
}
|
447
|
+
|
448
|
+
// description: String
|
449
|
+
static int
|
450
|
+
input_value_description(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
451
|
+
const char *key = sel->name;
|
452
|
+
const char *s = ((gqlArg)obj->ptr)->desc;
|
453
|
+
gqlValue desc;
|
454
|
+
|
455
|
+
if (NULL != sel->alias) {
|
456
|
+
key = sel->alias;
|
457
|
+
}
|
458
|
+
if (NULL == s) {
|
459
|
+
desc = gql_null_create(err);
|
460
|
+
} else {
|
461
|
+
desc = gql_string_create(err, s, -1);
|
462
|
+
}
|
463
|
+
return gql_object_set(err, result, key, desc);
|
464
|
+
}
|
465
|
+
|
466
|
+
// type: __Type!
|
467
|
+
static int
|
468
|
+
input_value_type(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
469
|
+
gqlArg a = (gqlArg)obj->ptr;
|
470
|
+
const char *key = sel->name;
|
471
|
+
struct _gqlCobj child = { .clas = &type_class };
|
472
|
+
gqlValue co;
|
473
|
+
|
474
|
+
if (NULL != sel->alias) {
|
475
|
+
key = sel->alias;
|
476
|
+
}
|
477
|
+
if (NULL == a || NULL == a->type) {
|
478
|
+
return gql_object_set(err, result, key, gql_null_create(err));
|
479
|
+
}
|
480
|
+
if (NULL == (co = gql_object_create(err)) ||
|
481
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, co)) {
|
482
|
+
return err->code;
|
483
|
+
}
|
484
|
+
child.ptr = (void*)a->type;
|
485
|
+
|
486
|
+
return gql_eval_sels(err, doc, (gqlRef)&child, field, sel->sels, co, depth + 1);
|
487
|
+
}
|
488
|
+
|
489
|
+
// defaultValue: String
|
490
|
+
static int
|
491
|
+
input_value_default_value(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
492
|
+
gqlArg a = (gqlArg)obj->ptr;
|
493
|
+
const char *key = sel->name;
|
494
|
+
gqlValue dv = a->default_value;
|
495
|
+
|
496
|
+
if (NULL != sel->alias) {
|
497
|
+
key = sel->alias;
|
498
|
+
}
|
499
|
+
if (NULL == dv) {
|
500
|
+
return gql_object_set(err, result, key, gql_null_create(err));
|
501
|
+
}
|
502
|
+
if (NULL == (dv = gql_value_dup(err, dv))) {
|
503
|
+
return err->code;
|
504
|
+
}
|
505
|
+
if (AGOO_ERR_OK != gql_value_convert(err, dv, &gql_string_type)) {
|
506
|
+
return err->code;
|
507
|
+
}
|
508
|
+
return gql_object_set(err, result, key, dv);
|
509
|
+
}
|
510
|
+
|
511
|
+
static struct _gqlCmethod input_value_methods[] = {
|
512
|
+
{ .key = "name", .func = input_value_name },
|
513
|
+
{ .key = "description", .func = input_value_description },
|
514
|
+
{ .key = "type", .func = input_value_type },
|
515
|
+
{ .key = "defaultValue", .func = input_value_default_value },
|
516
|
+
{ .key = NULL, .func = NULL },
|
517
|
+
};
|
518
|
+
|
519
|
+
static struct _gqlCclass input_value_class = {
|
520
|
+
.name = "__InputValue",
|
521
|
+
.methods = input_value_methods,
|
522
|
+
};
|
523
|
+
|
524
|
+
// __Field
|
525
|
+
// name: String!
|
526
|
+
static int
|
527
|
+
field_name(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
528
|
+
const char *key = sel->name;
|
529
|
+
|
530
|
+
if (NULL != sel->alias) {
|
531
|
+
key = sel->alias;
|
532
|
+
}
|
533
|
+
return gql_object_set(err, result, key, gql_string_create(err, ((gqlField)obj->ptr)->name, -1));
|
534
|
+
}
|
535
|
+
|
536
|
+
// description: String
|
537
|
+
static int
|
538
|
+
field_description(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
539
|
+
const char *key = sel->name;
|
540
|
+
const char *s = ((gqlField)obj->ptr)->desc;
|
541
|
+
gqlValue desc;
|
542
|
+
|
543
|
+
if (NULL != sel->alias) {
|
544
|
+
key = sel->alias;
|
545
|
+
}
|
546
|
+
if (NULL == s) {
|
547
|
+
desc = gql_null_create(err);
|
548
|
+
} else {
|
549
|
+
desc = gql_string_create(err, s, -1);
|
550
|
+
}
|
551
|
+
return gql_object_set(err, result, key, desc);
|
552
|
+
}
|
553
|
+
|
554
|
+
// args: [__InputValue!]!
|
555
|
+
static int
|
556
|
+
field_args(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
557
|
+
gqlField f = (gqlField)obj->ptr;
|
558
|
+
const char *key = sel->name;
|
559
|
+
gqlArg a;
|
560
|
+
gqlValue list = gql_list_create(err, NULL);
|
561
|
+
gqlValue co;
|
562
|
+
struct _gqlField cf;
|
563
|
+
struct _gqlCobj child = { .clas = &input_value_class };
|
564
|
+
int d2 = depth + 1;
|
565
|
+
|
566
|
+
if (NULL != sel->alias) {
|
567
|
+
key = sel->alias;
|
568
|
+
}
|
569
|
+
if (NULL == list ||
|
570
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
571
|
+
return err->code;
|
572
|
+
}
|
573
|
+
memset(&cf, 0, sizeof(cf));
|
574
|
+
cf.type = sel->type->base;
|
575
|
+
|
576
|
+
for (a = f->args; NULL != a; a = a->next) {
|
577
|
+
if (NULL == (co = gql_object_create(err)) ||
|
578
|
+
AGOO_ERR_OK != gql_list_append(err, list, co)) {
|
579
|
+
return err->code;
|
580
|
+
}
|
581
|
+
child.ptr = a;
|
582
|
+
if (AGOO_ERR_OK != gql_eval_sels(err, doc, (gqlRef)&child, &cf, sel->sels, co, d2)) {
|
583
|
+
return err->code;
|
584
|
+
}
|
585
|
+
}
|
586
|
+
return AGOO_ERR_OK;
|
587
|
+
}
|
588
|
+
|
589
|
+
// type: __Type!
|
590
|
+
static int
|
591
|
+
field_type(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
592
|
+
gqlField f = (gqlField)obj->ptr;
|
593
|
+
const char *key = sel->name;
|
594
|
+
struct _gqlCobj child = { .clas = &type_class };
|
595
|
+
gqlValue co;
|
596
|
+
|
597
|
+
if (NULL != sel->alias) {
|
598
|
+
key = sel->alias;
|
599
|
+
}
|
600
|
+
if (NULL == f || NULL == f->type) {
|
601
|
+
co = gql_null_create(err);
|
602
|
+
|
603
|
+
return gql_object_set(err, result, key, co);
|
604
|
+
}
|
605
|
+
if (NULL == (co = gql_object_create(err)) ||
|
606
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, co)) {
|
607
|
+
return err->code;
|
608
|
+
}
|
609
|
+
child.ptr = (void*)f->type;
|
610
|
+
|
611
|
+
return gql_eval_sels(err, doc, (gqlRef)&child, field, sel->sels, co, depth + 1);
|
612
|
+
}
|
613
|
+
|
614
|
+
// isDeprecated: Boolean!
|
615
|
+
static int
|
616
|
+
field_is_deprecated(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
617
|
+
const char *key = sel->name;
|
618
|
+
|
619
|
+
if (NULL != sel->alias) {
|
620
|
+
key = sel->alias;
|
621
|
+
}
|
622
|
+
return gql_object_set(err, result, key, gql_bool_create(err, is_deprecated(((gqlField)obj->ptr)->dir)));
|
623
|
+
}
|
624
|
+
|
625
|
+
// deprecationReason: String
|
626
|
+
static int
|
627
|
+
field_deprecation_reason(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
628
|
+
const char *reason = deprecation_reason(((gqlField)obj->ptr)->dir);
|
629
|
+
const char *key = sel->name;
|
630
|
+
gqlValue rv;
|
631
|
+
|
632
|
+
if (NULL != sel->alias) {
|
633
|
+
key = sel->alias;
|
634
|
+
}
|
635
|
+
if (NULL == reason) {
|
636
|
+
rv = gql_null_create(err);
|
637
|
+
} else {
|
638
|
+
rv = gql_string_create(err, reason, -1);
|
639
|
+
}
|
640
|
+
return gql_object_set(err, result, key, rv);
|
641
|
+
}
|
642
|
+
|
643
|
+
static struct _gqlCmethod field_methods[] = {
|
644
|
+
{ .key = "name", .func = field_name },
|
645
|
+
{ .key = "description", .func = field_description },
|
646
|
+
{ .key = "args", .func = field_args },
|
647
|
+
{ .key = "type", .func = field_type },
|
648
|
+
{ .key = "isDeprecated", .func = field_is_deprecated },
|
649
|
+
{ .key = "deprecationReason", .func = field_deprecation_reason },
|
650
|
+
{ .key = NULL, .func = NULL },
|
651
|
+
};
|
652
|
+
|
653
|
+
static struct _gqlCclass field_class = {
|
654
|
+
.name = "__Field",
|
655
|
+
.methods = field_methods,
|
656
|
+
};
|
657
|
+
|
658
|
+
// EnumValue
|
659
|
+
// name: String!
|
660
|
+
static int
|
661
|
+
enum_value_name(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
662
|
+
const char *key = sel->name;
|
663
|
+
|
664
|
+
if (NULL != sel->alias) {
|
665
|
+
key = sel->alias;
|
666
|
+
}
|
667
|
+
return gql_object_set(err, result, key, gql_string_create(err, ((gqlEnumVal)obj->ptr)->value, -1));
|
668
|
+
}
|
669
|
+
|
670
|
+
// description: String
|
671
|
+
static int
|
672
|
+
enum_value_description(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
673
|
+
const char *key = sel->name;
|
674
|
+
const char *s = ((gqlEnumVal)obj->ptr)->desc;
|
675
|
+
gqlValue desc;
|
676
|
+
|
677
|
+
if (NULL != sel->alias) {
|
678
|
+
key = sel->alias;
|
679
|
+
}
|
680
|
+
if (NULL == s) {
|
681
|
+
desc = gql_null_create(err);
|
682
|
+
} else {
|
683
|
+
desc = gql_string_create(err, s, -1);
|
684
|
+
}
|
685
|
+
return gql_object_set(err, result, key, desc);
|
686
|
+
}
|
687
|
+
|
688
|
+
static int
|
689
|
+
enum_value_is_deprecated(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
690
|
+
const char *key = sel->name;
|
691
|
+
|
692
|
+
if (NULL != sel->alias) {
|
693
|
+
key = sel->alias;
|
694
|
+
}
|
695
|
+
return gql_object_set(err, result, key, gql_bool_create(err, is_deprecated(((gqlEnumVal)obj->ptr)->dir)));
|
696
|
+
}
|
697
|
+
|
698
|
+
static int
|
699
|
+
enum_value_deprecation_reason(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
700
|
+
const char *reason = deprecation_reason(((gqlEnumVal)obj->ptr)->dir);
|
701
|
+
const char *key = sel->name;
|
702
|
+
gqlValue rv;
|
703
|
+
|
704
|
+
if (NULL != sel->alias) {
|
705
|
+
key = sel->alias;
|
706
|
+
}
|
707
|
+
if (NULL == reason) {
|
708
|
+
rv = gql_null_create(err);
|
709
|
+
} else {
|
710
|
+
rv = gql_string_create(err, reason, -1);
|
711
|
+
}
|
712
|
+
return gql_object_set(err, result, key, rv);
|
713
|
+
}
|
714
|
+
|
715
|
+
static struct _gqlCmethod enum_value_methods[] = {
|
716
|
+
{ .key = "name", .func = enum_value_name },
|
717
|
+
{ .key = "description", .func = enum_value_description },
|
718
|
+
{ .key = "isDeprecated", .func = enum_value_is_deprecated },
|
719
|
+
{ .key = "deprecationReason", .func = enum_value_deprecation_reason },
|
720
|
+
{ .key = NULL, .func = NULL },
|
721
|
+
};
|
722
|
+
|
723
|
+
static struct _gqlCclass enum_value_class = {
|
724
|
+
.name = "__EnumValue",
|
725
|
+
.methods = enum_value_methods,
|
726
|
+
};
|
727
|
+
|
728
|
+
// __Directive
|
729
|
+
// name: String!
|
730
|
+
static int
|
731
|
+
directive_name(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
732
|
+
const char *key = sel->name;
|
733
|
+
|
734
|
+
if (NULL != sel->alias) {
|
735
|
+
key = sel->alias;
|
736
|
+
}
|
737
|
+
return gql_object_set(err, result, key, gql_string_create(err, ((gqlDir)obj->ptr)->name, -1));
|
738
|
+
}
|
739
|
+
|
740
|
+
// description: String
|
741
|
+
static int
|
742
|
+
directive_description(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
743
|
+
const char *key = sel->name;
|
744
|
+
const char *s = ((gqlDir)obj->ptr)->desc;
|
745
|
+
gqlValue desc;
|
746
|
+
|
747
|
+
if (NULL != sel->alias) {
|
748
|
+
key = sel->alias;
|
749
|
+
}
|
750
|
+
if (NULL == s) {
|
751
|
+
desc = gql_null_create(err);
|
752
|
+
} else {
|
753
|
+
desc = gql_string_create(err, s, -1);
|
754
|
+
}
|
755
|
+
return gql_object_set(err, result, key, desc);
|
756
|
+
}
|
757
|
+
|
758
|
+
// locations: [__DirectiveLocation!]!
|
759
|
+
static int
|
760
|
+
directive_locations(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
761
|
+
gqlDir d = (gqlDir)obj->ptr;
|
762
|
+
const char *key = sel->name;
|
763
|
+
gqlStrLink locs = d->locs;
|
764
|
+
gqlValue list = gql_list_create(err, NULL);
|
765
|
+
gqlValue c;
|
766
|
+
|
767
|
+
if (NULL != sel->alias) {
|
768
|
+
key = sel->alias;
|
769
|
+
}
|
770
|
+
if (NULL == list ||
|
771
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
772
|
+
return err->code;
|
773
|
+
}
|
774
|
+
for (; NULL != locs; locs = locs->next) {
|
775
|
+
if (NULL == (c = gql_string_create(err, locs->str, -1)) ||
|
776
|
+
AGOO_ERR_OK != gql_list_append(err, list, c)) {
|
777
|
+
return err->code;
|
322
778
|
}
|
323
779
|
}
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
780
|
+
return AGOO_ERR_OK;
|
781
|
+
}
|
782
|
+
|
783
|
+
static int
|
784
|
+
directive_args(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
785
|
+
gqlDir d = (gqlDir)obj->ptr;
|
786
|
+
const char *key = sel->name;
|
787
|
+
gqlArg a;
|
788
|
+
gqlValue list = gql_list_create(err, NULL);
|
789
|
+
gqlValue co;
|
790
|
+
struct _gqlField cf;
|
791
|
+
struct _gqlCobj child = { .clas = &input_value_class };
|
792
|
+
int d2 = depth + 1;
|
793
|
+
|
794
|
+
if (NULL != sel->alias) {
|
795
|
+
key = sel->alias;
|
796
|
+
}
|
797
|
+
if (NULL == list ||
|
798
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
799
|
+
return err->code;
|
800
|
+
}
|
801
|
+
memset(&cf, 0, sizeof(cf));
|
802
|
+
cf.type = sel->type->base;
|
803
|
+
|
804
|
+
for (a = d->args; NULL != a; a = a->next) {
|
805
|
+
if (NULL == (co = gql_object_create(err)) ||
|
806
|
+
AGOO_ERR_OK != gql_list_append(err, list, co)) {
|
807
|
+
return err->code;
|
808
|
+
}
|
809
|
+
child.ptr = a;
|
810
|
+
if (AGOO_ERR_OK != gql_eval_sels(err, doc, (gqlRef)&child, &cf, sel->sels, co, d2)) {
|
811
|
+
return err->code;
|
330
812
|
}
|
331
813
|
}
|
332
814
|
return AGOO_ERR_OK;
|
333
815
|
}
|
816
|
+
|
817
|
+
static struct _gqlCmethod directive_methods[] = {
|
818
|
+
{ .key = "name", .func = directive_name },
|
819
|
+
{ .key = "description", .func = directive_description },
|
820
|
+
{ .key = "locations", .func = directive_locations },
|
821
|
+
{ .key = "args", .func = directive_args },
|
822
|
+
{ .key = NULL, .func = NULL },
|
823
|
+
};
|
824
|
+
|
825
|
+
static struct _gqlCclass directive_class = {
|
826
|
+
.name = "__Directive",
|
827
|
+
.methods = directive_methods,
|
828
|
+
};
|
829
|
+
|
830
|
+
// __Type
|
831
|
+
// kind: __TypeKind!
|
832
|
+
static int
|
833
|
+
type_kind(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
834
|
+
const char *kind = NULL;
|
835
|
+
const char *key = sel->name;
|
836
|
+
|
837
|
+
switch (((gqlType)obj->ptr)->kind) {
|
838
|
+
case GQL_OBJECT: kind = "OBJECT"; break;
|
839
|
+
case GQL_INPUT: kind = "INPUT_OBJECT"; break;
|
840
|
+
case GQL_UNION: kind = "UNION"; break;
|
841
|
+
case GQL_INTERFACE: kind = "INTERFACE"; break;
|
842
|
+
case GQL_ENUM: kind = "ENUM"; break;
|
843
|
+
case GQL_SCALAR: kind = "SCALAR"; break;
|
844
|
+
case GQL_LIST: kind = "LIST"; break;
|
845
|
+
default:
|
846
|
+
return agoo_err_set(err, AGOO_ERR_ARG, "__Type kind field not valid. %s:%d", __FILE__, __LINE__);
|
847
|
+
}
|
848
|
+
if (NULL != sel->alias) {
|
849
|
+
key = sel->alias;
|
850
|
+
}
|
851
|
+
return gql_object_set(err, result, key, gql_token_create(err, kind, -1, gql_type_get("__TypeKind")));
|
852
|
+
}
|
853
|
+
|
854
|
+
// name: String
|
855
|
+
static int
|
856
|
+
type_name(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
857
|
+
const char *key = sel->name;
|
858
|
+
|
859
|
+
if (NULL != sel->alias) {
|
860
|
+
key = sel->alias;
|
861
|
+
}
|
862
|
+
return gql_object_set(err, result, key, gql_string_create(err, ((gqlType)obj->ptr)->name, -1));
|
863
|
+
}
|
864
|
+
|
865
|
+
// description: String
|
866
|
+
static int
|
867
|
+
type_description(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
868
|
+
gqlType type = (gqlType)obj->ptr;
|
869
|
+
const char *key = sel->name;
|
870
|
+
gqlValue desc;
|
871
|
+
|
872
|
+
if (NULL != sel->alias) {
|
873
|
+
key = sel->alias;
|
874
|
+
}
|
875
|
+
if (NULL == type->desc) {
|
876
|
+
desc = gql_null_create(err);
|
877
|
+
} else {
|
878
|
+
desc = gql_string_create(err, type->desc, -1);
|
879
|
+
}
|
880
|
+
return gql_object_set(err, result, key, desc);
|
881
|
+
}
|
882
|
+
|
883
|
+
// OBJECT and INTERFACE only
|
884
|
+
// fields(includeDeprecated: Boolean = false): [__Field!]
|
885
|
+
static int
|
886
|
+
type_fields(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
887
|
+
gqlType type = (gqlType)obj->ptr;
|
888
|
+
const char *key = sel->name;
|
889
|
+
gqlField f;
|
890
|
+
gqlValue list = gql_list_create(err, NULL);
|
891
|
+
gqlValue co;
|
892
|
+
struct _gqlField cf;
|
893
|
+
struct _gqlCobj child = { .clas = &field_class };
|
894
|
+
int d2 = depth + 1;
|
895
|
+
gqlValue a = extract_arg(err, field, sel, "includeDeprecated");
|
896
|
+
bool inc_dep = false;
|
897
|
+
|
898
|
+
if (GQL_OBJECT != type->kind && GQL_INTERFACE != type->kind) {
|
899
|
+
if (NULL == (co = gql_null_create(err)) ||
|
900
|
+
AGOO_ERR_OK != gql_list_append(err, list, co)) {
|
901
|
+
return err->code;
|
902
|
+
}
|
903
|
+
return AGOO_ERR_OK;
|
904
|
+
}
|
905
|
+
if (NULL != a && GQL_SCALAR_BOOL == a->type->scalar_kind && a->b) {
|
906
|
+
inc_dep = true;
|
907
|
+
}
|
908
|
+
if (NULL != sel->alias) {
|
909
|
+
key = sel->alias;
|
910
|
+
}
|
911
|
+
if (NULL == list ||
|
912
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
913
|
+
return err->code;
|
914
|
+
}
|
915
|
+
memset(&cf, 0, sizeof(cf));
|
916
|
+
cf.type = sel->type->base;
|
917
|
+
for (f = type->fields; NULL != f; f = f->next) {
|
918
|
+
if (!inc_dep && is_deprecated(f->dir)) {
|
919
|
+
continue;
|
920
|
+
}
|
921
|
+
if (NULL == (co = gql_object_create(err)) ||
|
922
|
+
AGOO_ERR_OK != gql_list_append(err, list, co)) {
|
923
|
+
return err->code;
|
924
|
+
}
|
925
|
+
child.ptr = f;
|
926
|
+
if (AGOO_ERR_OK != gql_eval_sels(err, doc, (gqlRef)&child, &cf, sel->sels, co, d2)) {
|
927
|
+
return err->code;
|
928
|
+
}
|
929
|
+
}
|
930
|
+
return AGOO_ERR_OK;
|
931
|
+
}
|
932
|
+
|
933
|
+
// OBJECT only
|
934
|
+
// interfaces: [__Type!]
|
935
|
+
static int
|
936
|
+
type_interfaces(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
937
|
+
gqlType type = (gqlType)obj->ptr;
|
938
|
+
const char *key = sel->name;
|
939
|
+
gqlTypeLink tl;
|
940
|
+
gqlValue list = gql_list_create(err, NULL);
|
941
|
+
gqlValue co;
|
942
|
+
struct _gqlField cf;
|
943
|
+
struct _gqlCobj child = { .clas = &type_class };
|
944
|
+
int d2 = depth + 1;
|
945
|
+
|
946
|
+
if (GQL_OBJECT != type->kind) {
|
947
|
+
if (NULL == (co = gql_null_create(err)) ||
|
948
|
+
AGOO_ERR_OK != gql_list_append(err, list, co)) {
|
949
|
+
return err->code;
|
950
|
+
}
|
951
|
+
return AGOO_ERR_OK;
|
952
|
+
}
|
953
|
+
if (NULL != sel->alias) {
|
954
|
+
key = sel->alias;
|
955
|
+
}
|
956
|
+
if (NULL == list ||
|
957
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
958
|
+
return err->code;
|
959
|
+
}
|
960
|
+
memset(&cf, 0, sizeof(cf));
|
961
|
+
cf.type = sel->type->base;
|
962
|
+
for (tl = type->interfaces; NULL != tl; tl = tl->next) {
|
963
|
+
if (NULL == (co = gql_object_create(err)) ||
|
964
|
+
AGOO_ERR_OK != gql_list_append(err, list, co)) {
|
965
|
+
return err->code;
|
966
|
+
}
|
967
|
+
child.ptr = tl->type;
|
968
|
+
if (AGOO_ERR_OK != gql_eval_sels(err, doc, (gqlRef)&child, &cf, sel->sels, co, d2)) {
|
969
|
+
return err->code;
|
970
|
+
}
|
971
|
+
}
|
972
|
+
return AGOO_ERR_OK;
|
973
|
+
}
|
974
|
+
|
975
|
+
// INTERFACE and UNION only
|
976
|
+
// possibleTypes: [__Type!]
|
977
|
+
static bool
|
978
|
+
has_interface(gqlType type, gqlType interface) {
|
979
|
+
gqlTypeLink tl;
|
980
|
+
|
981
|
+
for (tl = type->interfaces; NULL != tl; tl = tl->next) {
|
982
|
+
if (tl->type == type) {
|
983
|
+
return true;
|
984
|
+
}
|
985
|
+
}
|
986
|
+
return false;
|
987
|
+
}
|
988
|
+
|
989
|
+
typedef struct _posCtx {
|
990
|
+
agooErr err;
|
991
|
+
gqlDoc doc;
|
992
|
+
gqlSel sel;
|
993
|
+
int depth;
|
994
|
+
gqlValue list;
|
995
|
+
gqlType interface;
|
996
|
+
gqlCobj child;
|
997
|
+
gqlField cf;
|
998
|
+
} *PosCtx;
|
999
|
+
|
1000
|
+
static void
|
1001
|
+
possible_cb(gqlType type, void *ctx) {
|
1002
|
+
PosCtx pc = (PosCtx)ctx;
|
1003
|
+
|
1004
|
+
if (AGOO_ERR_OK != pc->err->code) {
|
1005
|
+
return;
|
1006
|
+
}
|
1007
|
+
if (GQL_LIST != type->kind && has_interface(type, pc->interface)) {
|
1008
|
+
gqlValue co;
|
1009
|
+
|
1010
|
+
if (NULL == (co = gql_object_create(pc->err)) ||
|
1011
|
+
AGOO_ERR_OK != gql_list_append(pc->err, pc->list, co)) {
|
1012
|
+
return;
|
1013
|
+
}
|
1014
|
+
pc->child->ptr = type;
|
1015
|
+
gql_eval_sels(pc->err, pc->doc, (gqlRef)pc->child, pc->cf, pc->sel->sels, co, pc->depth);
|
1016
|
+
}
|
1017
|
+
}
|
1018
|
+
|
1019
|
+
static int
|
1020
|
+
type_possible_types(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
1021
|
+
gqlType type = (gqlType)obj->ptr;
|
1022
|
+
const char *key = sel->name;
|
1023
|
+
gqlTypeLink tl;
|
1024
|
+
gqlValue list = gql_list_create(err, NULL);
|
1025
|
+
gqlValue co;
|
1026
|
+
struct _gqlField cf;
|
1027
|
+
struct _gqlCobj child = { .clas = &type_class };
|
1028
|
+
int d2 = depth + 1;
|
1029
|
+
|
1030
|
+
if (NULL != sel->alias) {
|
1031
|
+
key = sel->alias;
|
1032
|
+
}
|
1033
|
+
if (NULL == list ||
|
1034
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
1035
|
+
return err->code;
|
1036
|
+
}
|
1037
|
+
memset(&cf, 0, sizeof(cf));
|
1038
|
+
cf.type = sel->type->base;
|
1039
|
+
|
1040
|
+
switch (type->kind) {
|
1041
|
+
case GQL_INTERFACE: {
|
1042
|
+
struct _posCtx pc = {
|
1043
|
+
.err = err,
|
1044
|
+
.doc = doc,
|
1045
|
+
.sel = sel,
|
1046
|
+
.depth = depth + 1,
|
1047
|
+
.list = list,
|
1048
|
+
.interface = type,
|
1049
|
+
.child = &child,
|
1050
|
+
.cf = &cf,
|
1051
|
+
};
|
1052
|
+
|
1053
|
+
gql_type_iterate(possible_cb, &pc);
|
1054
|
+
break;
|
1055
|
+
}
|
1056
|
+
case GQL_UNION:
|
1057
|
+
for (tl = type->types; NULL != tl; tl = tl->next) {
|
1058
|
+
if (NULL == (co = gql_object_create(err)) ||
|
1059
|
+
AGOO_ERR_OK != gql_list_append(err, list, co)) {
|
1060
|
+
return err->code;
|
1061
|
+
}
|
1062
|
+
child.ptr = tl->type;
|
1063
|
+
if (AGOO_ERR_OK != gql_eval_sels(err, doc, (gqlRef)&child, &cf, sel->sels, co, d2)) {
|
1064
|
+
return err->code;
|
1065
|
+
}
|
1066
|
+
}
|
1067
|
+
break;
|
1068
|
+
default:
|
1069
|
+
if (NULL == (co = gql_null_create(err)) ||
|
1070
|
+
AGOO_ERR_OK != gql_list_append(err, list, co)) {
|
1071
|
+
return err->code;
|
1072
|
+
}
|
1073
|
+
}
|
1074
|
+
return AGOO_ERR_OK;
|
1075
|
+
}
|
1076
|
+
|
1077
|
+
// ENUM only
|
1078
|
+
// enumValues(includeDeprecated: Boolean = false): [__EnumValue!]
|
1079
|
+
static int
|
1080
|
+
type_enum_values(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
1081
|
+
gqlType type = (gqlType)obj->ptr;
|
1082
|
+
const char *key = sel->name;
|
1083
|
+
gqlEnumVal c;
|
1084
|
+
gqlValue list = gql_list_create(err, NULL);
|
1085
|
+
gqlValue co;
|
1086
|
+
struct _gqlField cf;
|
1087
|
+
struct _gqlCobj child = { .clas = &enum_value_class };
|
1088
|
+
int d2 = depth + 1;
|
1089
|
+
gqlValue a = extract_arg(err, field, sel, "includeDeprecated");
|
1090
|
+
bool inc_dep = false;
|
1091
|
+
|
1092
|
+
if (GQL_ENUM != type->kind) {
|
1093
|
+
if (NULL == (co = gql_null_create(err)) ||
|
1094
|
+
AGOO_ERR_OK != gql_list_append(err, list, co)) {
|
1095
|
+
return err->code;
|
1096
|
+
}
|
1097
|
+
return AGOO_ERR_OK;
|
1098
|
+
}
|
1099
|
+
if (NULL != a && GQL_SCALAR_BOOL == a->type->scalar_kind && a->b) {
|
1100
|
+
inc_dep = true;
|
1101
|
+
}
|
1102
|
+
if (NULL != sel->alias) {
|
1103
|
+
key = sel->alias;
|
1104
|
+
}
|
1105
|
+
if (NULL == list ||
|
1106
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
1107
|
+
return err->code;
|
1108
|
+
}
|
1109
|
+
memset(&cf, 0, sizeof(cf));
|
1110
|
+
cf.type = sel->type->base;
|
1111
|
+
for (c = type->choices; NULL != c; c = c->next) {
|
1112
|
+
if (!inc_dep && is_deprecated(c->dir)) {
|
1113
|
+
continue;
|
1114
|
+
}
|
1115
|
+
if (NULL == (co = gql_object_create(err)) ||
|
1116
|
+
AGOO_ERR_OK != gql_list_append(err, list, co)) {
|
1117
|
+
return err->code;
|
1118
|
+
}
|
1119
|
+
child.ptr = c;
|
1120
|
+
if (AGOO_ERR_OK != gql_eval_sels(err, doc, (gqlRef)&child, &cf, sel->sels, co, d2)) {
|
1121
|
+
return err->code;
|
1122
|
+
}
|
1123
|
+
}
|
1124
|
+
return AGOO_ERR_OK;
|
1125
|
+
}
|
1126
|
+
|
1127
|
+
// INPUT_OBJECT only
|
1128
|
+
// inputFields: [__InputValue!]
|
1129
|
+
static int
|
1130
|
+
type_input_fields(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
1131
|
+
gqlType type = (gqlType)obj->ptr;
|
1132
|
+
const char *key = sel->name;
|
1133
|
+
gqlArg a;
|
1134
|
+
gqlValue list = gql_list_create(err, NULL);
|
1135
|
+
gqlValue co;
|
1136
|
+
struct _gqlField cf;
|
1137
|
+
struct _gqlCobj child = { .clas = &input_value_class };
|
1138
|
+
int d2 = depth + 1;
|
1139
|
+
|
1140
|
+
if (GQL_INPUT != type->kind) {
|
1141
|
+
if (NULL == (co = gql_null_create(err)) ||
|
1142
|
+
AGOO_ERR_OK != gql_list_append(err, list, co)) {
|
1143
|
+
return err->code;
|
1144
|
+
}
|
1145
|
+
return AGOO_ERR_OK;
|
1146
|
+
}
|
1147
|
+
if (NULL != sel->alias) {
|
1148
|
+
key = sel->alias;
|
1149
|
+
}
|
1150
|
+
if (NULL == list ||
|
1151
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
1152
|
+
return err->code;
|
1153
|
+
}
|
1154
|
+
memset(&cf, 0, sizeof(cf));
|
1155
|
+
cf.type = sel->type->base;
|
1156
|
+
|
1157
|
+
for (a = type->args; NULL != a; a = a->next) {
|
1158
|
+
if (NULL == (co = gql_object_create(err)) ||
|
1159
|
+
AGOO_ERR_OK != gql_list_append(err, list, co)) {
|
1160
|
+
return err->code;
|
1161
|
+
}
|
1162
|
+
child.ptr = a;
|
1163
|
+
if (AGOO_ERR_OK != gql_eval_sels(err, doc, (gqlRef)&child, &cf, sel->sels, co, d2)) {
|
1164
|
+
return err->code;
|
1165
|
+
}
|
1166
|
+
}
|
1167
|
+
return AGOO_ERR_OK;
|
1168
|
+
}
|
1169
|
+
|
1170
|
+
// NON_NULL and LIST only
|
1171
|
+
// ofType: __Type
|
1172
|
+
static int
|
1173
|
+
type_of_type(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
1174
|
+
gqlType type = (gqlType)obj->ptr;
|
1175
|
+
const char *key = sel->name;
|
1176
|
+
struct _gqlCobj child = { .clas = &type_class };
|
1177
|
+
gqlValue co;
|
1178
|
+
|
1179
|
+
if (NULL != sel->alias) {
|
1180
|
+
key = sel->alias;
|
1181
|
+
}
|
1182
|
+
if (NULL == type || NULL == type->base || (GQL_LIST != type->kind && GQL_NON_NULL != type->kind)) {
|
1183
|
+
co = gql_null_create(err);
|
1184
|
+
|
1185
|
+
return gql_object_set(err, result, key, co);
|
1186
|
+
}
|
1187
|
+
if (NULL == (co = gql_object_create(err)) ||
|
1188
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, co)) {
|
1189
|
+
return err->code;
|
1190
|
+
}
|
1191
|
+
child.ptr = (void*)type->base;
|
1192
|
+
|
1193
|
+
return gql_eval_sels(err, doc, (gqlRef)&child, field, sel->sels, co, depth + 1);
|
1194
|
+
}
|
1195
|
+
|
1196
|
+
static struct _gqlCmethod type_methods[] = {
|
1197
|
+
{ .key = "kind", .func = type_kind },
|
1198
|
+
{ .key = "name", .func = type_name },
|
1199
|
+
{ .key = "description", .func = type_description },
|
1200
|
+
{ .key = "fields", .func = type_fields },
|
1201
|
+
{ .key = "interfaces", .func = type_interfaces },
|
1202
|
+
{ .key = "possibleTypes", .func = type_possible_types },
|
1203
|
+
{ .key = "enumValues", .func = type_enum_values },
|
1204
|
+
{ .key = "inputFields", .func = type_input_fields },
|
1205
|
+
{ .key = "ofType", .func = type_of_type },
|
1206
|
+
{ .key = NULL, .func = NULL },
|
1207
|
+
};
|
1208
|
+
|
1209
|
+
// __Type
|
1210
|
+
static struct _gqlCclass type_class = {
|
1211
|
+
.name = "__Type",
|
1212
|
+
.methods = type_methods,
|
1213
|
+
};
|
1214
|
+
|
1215
|
+
// __Schema
|
1216
|
+
typedef struct _schemaCbCtx {
|
1217
|
+
agooErr err;
|
1218
|
+
gqlDoc doc;
|
1219
|
+
gqlSel sel;
|
1220
|
+
int depth;
|
1221
|
+
gqlValue list;
|
1222
|
+
} *SchemaCbCtx;
|
1223
|
+
|
1224
|
+
static void
|
1225
|
+
schema_types_cb(gqlType type, void *ctx) {
|
1226
|
+
SchemaCbCtx scc = (SchemaCbCtx)ctx;
|
1227
|
+
gqlValue co;
|
1228
|
+
struct _gqlCobj child = { .clas = &type_class, .ptr = (void*)type };
|
1229
|
+
struct _gqlField cf;
|
1230
|
+
|
1231
|
+
if (AGOO_ERR_OK != scc->err->code || GQL_LIST == type->kind) {
|
1232
|
+
return;
|
1233
|
+
}
|
1234
|
+
memset(&cf, 0, sizeof(cf));
|
1235
|
+
cf.type = scc->sel->type->base;
|
1236
|
+
|
1237
|
+
if (NULL == (co = gql_object_create(scc->err)) ||
|
1238
|
+
AGOO_ERR_OK != gql_list_append(scc->err, scc->list, co)) {
|
1239
|
+
return;
|
1240
|
+
}
|
1241
|
+
gql_eval_sels(scc->err, scc->doc, (gqlRef)&child, &cf, scc->sel->sels, co, scc->depth);
|
1242
|
+
}
|
1243
|
+
|
1244
|
+
// types: [__Type!]!
|
1245
|
+
static int
|
1246
|
+
schema_types(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
1247
|
+
const char *key = sel->name;
|
1248
|
+
gqlValue list = gql_list_create(err, NULL);
|
1249
|
+
struct _schemaCbCtx scc = {
|
1250
|
+
.err = err,
|
1251
|
+
.doc = doc,
|
1252
|
+
.sel = sel,
|
1253
|
+
.depth = depth + 1,
|
1254
|
+
.list = list,
|
1255
|
+
};
|
1256
|
+
|
1257
|
+
if (NULL != sel->alias) {
|
1258
|
+
key = sel->alias;
|
1259
|
+
}
|
1260
|
+
if (NULL == list ||
|
1261
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
1262
|
+
return err->code;
|
1263
|
+
}
|
1264
|
+
gql_type_iterate(schema_types_cb, &scc);
|
1265
|
+
|
1266
|
+
return err->code;
|
1267
|
+
}
|
1268
|
+
|
1269
|
+
static int
|
1270
|
+
schema_op_type(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth, const char *op) {
|
1271
|
+
const char *key = sel->name;
|
1272
|
+
struct _gqlCobj child = { .clas = &type_class };
|
1273
|
+
gqlValue co;
|
1274
|
+
gqlType type;
|
1275
|
+
|
1276
|
+
if (NULL != sel->alias) {
|
1277
|
+
key = sel->alias;
|
1278
|
+
}
|
1279
|
+
if (NULL == (type = gql_type_func(gql_root_op(op)))) {
|
1280
|
+
if (NULL == (co = gql_null_create(err)) ||
|
1281
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, co)) {
|
1282
|
+
return err->code;
|
1283
|
+
}
|
1284
|
+
return AGOO_ERR_OK;
|
1285
|
+
}
|
1286
|
+
if (NULL == (co = gql_object_create(err)) ||
|
1287
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, co)) {
|
1288
|
+
return err->code;
|
1289
|
+
}
|
1290
|
+
child.ptr = (void*)type;
|
1291
|
+
|
1292
|
+
return gql_eval_sels(err, doc, (gqlRef)&child, field, sel->sels, co, depth + 1);
|
1293
|
+
}
|
1294
|
+
|
1295
|
+
// queryType: __Type!
|
1296
|
+
static int
|
1297
|
+
schema_query_type(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
1298
|
+
return schema_op_type(err, doc, obj, field, sel, result, depth, "query");
|
1299
|
+
}
|
1300
|
+
|
1301
|
+
// mutationType: __Type
|
1302
|
+
static int
|
1303
|
+
schema_mutation_type(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
1304
|
+
return schema_op_type(err, doc, obj, field, sel, result, depth, "mutation");
|
1305
|
+
}
|
1306
|
+
|
1307
|
+
// subscriptionType: __Type
|
1308
|
+
static int
|
1309
|
+
schema_subscription_type(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
1310
|
+
return schema_op_type(err, doc, obj, field, sel, result, depth, "subscription");
|
1311
|
+
}
|
1312
|
+
|
1313
|
+
// directives: [__Directive!]!
|
1314
|
+
static int
|
1315
|
+
schema_directives(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
1316
|
+
const char *key = sel->name;
|
1317
|
+
gqlValue list = gql_list_create(err, NULL);
|
1318
|
+
gqlValue co;
|
1319
|
+
struct _gqlField cf;
|
1320
|
+
struct _gqlCobj child = { .clas = &directive_class };
|
1321
|
+
int d2 = depth + 1;
|
1322
|
+
gqlDir d = gql_directives;
|
1323
|
+
|
1324
|
+
if (NULL != sel->alias) {
|
1325
|
+
key = sel->alias;
|
1326
|
+
}
|
1327
|
+
if (NULL == list ||
|
1328
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
1329
|
+
return err->code;
|
1330
|
+
}
|
1331
|
+
memset(&cf, 0, sizeof(cf));
|
1332
|
+
cf.type = sel->type->base;
|
1333
|
+
|
1334
|
+
for (d = gql_directives; NULL != d; d = d->next) {
|
1335
|
+
if (NULL == (co = gql_object_create(err)) ||
|
1336
|
+
AGOO_ERR_OK != gql_list_append(err, list, co)) {
|
1337
|
+
return err->code;
|
1338
|
+
}
|
1339
|
+
child.ptr = d;
|
1340
|
+
if (AGOO_ERR_OK != gql_eval_sels(err, doc, (gqlRef)&child, &cf, sel->sels, co, d2)) {
|
1341
|
+
return err->code;
|
1342
|
+
}
|
1343
|
+
}
|
1344
|
+
return AGOO_ERR_OK;
|
1345
|
+
}
|
1346
|
+
|
1347
|
+
static struct _gqlCmethod schema_methods[] = {
|
1348
|
+
{ .key = "types", .func = schema_types },
|
1349
|
+
{ .key = "queryType", .func = schema_query_type },
|
1350
|
+
{ .key = "mutationType", .func = schema_mutation_type },
|
1351
|
+
{ .key = "subscriptionType", .func = schema_subscription_type },
|
1352
|
+
{ .key = "directives", .func = schema_directives },
|
1353
|
+
{ .key = NULL, .func = NULL },
|
1354
|
+
};
|
1355
|
+
|
1356
|
+
static struct _gqlCclass schema_class = {
|
1357
|
+
.name = "__Schema",
|
1358
|
+
.methods = schema_methods,
|
1359
|
+
};
|
1360
|
+
|
1361
|
+
static int
|
1362
|
+
root_schema(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
1363
|
+
struct _gqlCobj child = { .clas = &schema_class, .ptr = NULL };
|
1364
|
+
gqlValue co;
|
1365
|
+
const char *key = sel->name;
|
1366
|
+
|
1367
|
+
if (NULL != sel->alias) {
|
1368
|
+
key = sel->alias;
|
1369
|
+
}
|
1370
|
+
if (NULL == (co = gql_object_create(err)) ||
|
1371
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, co)) {
|
1372
|
+
return err->code;
|
1373
|
+
}
|
1374
|
+
return gql_eval_sels(err, doc, (gqlRef)&child, field, sel->sels, co, depth + 1);
|
1375
|
+
}
|
1376
|
+
|
1377
|
+
static int
|
1378
|
+
root_type(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
1379
|
+
gqlValue na = extract_arg(err, field, sel, "name");
|
1380
|
+
const char *name = NULL;
|
1381
|
+
const char *key = sel->name;
|
1382
|
+
int d2 = depth + 1;
|
1383
|
+
gqlType type;
|
1384
|
+
gqlValue co;
|
1385
|
+
struct _gqlCobj child = { .clas = &type_class };
|
1386
|
+
|
1387
|
+
if (NULL != na) {
|
1388
|
+
name = gql_string_get(na);
|
1389
|
+
}
|
1390
|
+
if (NULL == name) {
|
1391
|
+
return agoo_err_set(err, AGOO_ERR_ARG, "%s field requires a name argument. %s:%d", sel->name, __FILE__, __LINE__);
|
1392
|
+
}
|
1393
|
+
if (NULL == (type = gql_type_get(name))) {
|
1394
|
+
return agoo_err_set(err, AGOO_ERR_ARG, "%s is not a defined type. %s:%d", name, __FILE__, __LINE__);
|
1395
|
+
}
|
1396
|
+
if (NULL != sel->alias) {
|
1397
|
+
key = sel->alias;
|
1398
|
+
}
|
1399
|
+
if (NULL == (co = gql_object_create(err)) ||
|
1400
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, co)) {
|
1401
|
+
return err->code;
|
1402
|
+
}
|
1403
|
+
child.ptr = type;
|
1404
|
+
if (AGOO_ERR_OK != gql_eval_sels(err, doc, (gqlRef)&child, field, sel->sels, co, d2)) {
|
1405
|
+
return err->code;
|
1406
|
+
}
|
1407
|
+
return AGOO_ERR_OK;
|
1408
|
+
}
|
1409
|
+
|
1410
|
+
static struct _gqlCmethod root_methods[] = {
|
1411
|
+
{ .key = "__type", .func = root_type },
|
1412
|
+
{ .key = "__schema", .func = root_schema },
|
1413
|
+
{ .key = NULL, .func = NULL },
|
1414
|
+
};
|
1415
|
+
|
1416
|
+
static struct _gqlCclass root_class = {
|
1417
|
+
.name = "__Query",
|
1418
|
+
.methods = root_methods,
|
1419
|
+
};
|
1420
|
+
|
1421
|
+
static gqlType
|
1422
|
+
ref_type(gqlRef ref) {
|
1423
|
+
gqlCobj obj = (gqlCobj)ref;
|
1424
|
+
|
1425
|
+
if (NULL != obj && NULL != obj->clas) {
|
1426
|
+
return gql_type_get(obj->clas->name);
|
1427
|
+
}
|
1428
|
+
return NULL;
|
1429
|
+
}
|
1430
|
+
|
1431
|
+
static int
|
1432
|
+
resolve(agooErr err, gqlDoc doc, gqlRef target, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
1433
|
+
gqlCobj obj = (gqlCobj)target;
|
1434
|
+
gqlCmethod method;
|
1435
|
+
|
1436
|
+
for (method = obj->clas->methods; NULL != method->key; method++) {
|
1437
|
+
if (0 == strcmp(method->key, sel->name)) {
|
1438
|
+
return method->func(err, doc, obj, field, sel, result, depth);
|
1439
|
+
}
|
1440
|
+
}
|
1441
|
+
return agoo_err_set(err, AGOO_ERR_EVAL, "%s is not a field on %s.", sel->name, obj->clas->name);
|
1442
|
+
}
|
1443
|
+
|
1444
|
+
int
|
1445
|
+
gql_intro_eval(agooErr err, gqlDoc doc, gqlSel sel, gqlValue result, int depth) {
|
1446
|
+
struct _gqlField field;
|
1447
|
+
struct _gqlCobj obj;
|
1448
|
+
|
1449
|
+
if (0 == strcmp("__type", sel->name)) {
|
1450
|
+
if (1 < depth) {
|
1451
|
+
return agoo_err_set(err, AGOO_ERR_EVAL, "__type can only be called from a query root.");
|
1452
|
+
}
|
1453
|
+
obj.clas = &root_class;
|
1454
|
+
obj.ptr = NULL;
|
1455
|
+
} else if (0 == strcmp("__schema", sel->name)) {
|
1456
|
+
if (1 < depth) {
|
1457
|
+
return agoo_err_set(err, AGOO_ERR_EVAL, "__scheme can only be called from a query root.");
|
1458
|
+
}
|
1459
|
+
obj.clas = &root_class;
|
1460
|
+
obj.ptr = NULL;
|
1461
|
+
} else {
|
1462
|
+
return agoo_err_set(err, AGOO_ERR_EVAL, "%s can only be called from the query root.", sel->name);
|
1463
|
+
}
|
1464
|
+
memset(&field, 0, sizeof(field));
|
1465
|
+
field.name = sel->name;
|
1466
|
+
field.type = sel->type;
|
1467
|
+
|
1468
|
+
doc->funcs.resolve = resolve;
|
1469
|
+
doc->funcs.type = ref_type;
|
1470
|
+
|
1471
|
+
return resolve(err, doc, &obj, &field, sel, result, depth);
|
1472
|
+
}
|
1473
|
+
|