@@ -30,6 +30,14 @@ local function avro_type(avro_schema)
30
30
return ' record*'
31
31
elseif utils .is_array (avro_schema ) then
32
32
return ' union'
33
+ elseif avro_schema .type == ' array' then
34
+ return ' array'
35
+ elseif avro_schema .type == ' array*' then
36
+ return ' array*'
37
+ elseif avro_schema .type == ' map' then
38
+ return ' map'
39
+ elseif avro_schema .type == ' map*' then
40
+ return ' map*'
33
41
end
34
42
elseif type (avro_schema ) == ' string' then
35
43
if avro_schema == ' int' then
105
113
106
114
--- Non-recursive version of the @{gql_type} function that returns
107
115
--- InputObject instead of Object.
116
+ --- An error will be raised in case of fields that are not scalar types
117
+ --- as there are no sense in non scalar arguments
108
118
local function gql_argument_type (state , avro_schema )
109
119
assert (type (state ) == ' table' ,
110
120
' state must be a table, got ' .. type (state ))
@@ -115,17 +125,23 @@ local function gql_argument_type(state, avro_schema)
115
125
assert (type (avro_schema .name ) == ' string' ,
116
126
(' avro_schema.name must be a string, got %s (avro_schema %s)' )
117
127
:format (type (avro_schema .name ), json .encode (avro_schema )))
128
+
118
129
assert (type (avro_schema .fields ) == ' table' ,
119
130
(' avro_schema.fields must be a table, got %s (avro_schema %s)' )
120
131
:format (type (avro_schema .fields ), json .encode (avro_schema )))
121
132
133
+ --- @tfixme iteration over null table
134
+ --- maybe avro.scheme was meant?
122
135
local fields = {}
123
- for _ , field in ipairs (fields ) do
136
+ for _ , field in ipairs (avro_schema .fields ) do
137
+
124
138
assert (type (field .name ) == ' string' ,
125
139
(' field.name must be a string, got %s (schema %s)' )
126
140
:format (type (field .name ), json .encode (field )))
141
+
127
142
local gql_field_type = convert_scalar_type (
128
143
field .type , {raise = true })
144
+
129
145
fields [field .name ] = {
130
146
name = field .name ,
131
147
kind = types .nonNull (gql_field_type ),
@@ -140,6 +156,8 @@ local function gql_argument_type(state, avro_schema)
140
156
}))
141
157
142
158
return res
159
+ --- elseif avro_type(avro_schema) == 'array' then
160
+
143
161
else
144
162
local res = convert_scalar_type (avro_schema , {raise = false })
145
163
if res == nil then
@@ -149,31 +167,38 @@ local function gql_argument_type(state, avro_schema)
149
167
end
150
168
end
151
169
170
+
171
+ --- Returns table of record's arguments
172
+ --- all arguments are nullable
152
173
local function convert_record_fields_to_args (state , fields )
153
174
local args = {}
154
175
for _ , field in ipairs (fields ) do
176
+
155
177
assert (type (field .name ) == ' string' ,
156
178
(' field.name must be a string, got %s (schema %s)' )
157
179
:format (type (field .name ), json .encode (field )))
180
+
158
181
local gql_class = gql_argument_type (state , field .type )
159
182
args [field .name ] = nullable (gql_class )
160
183
end
161
184
return args
162
185
end
163
186
164
- --- Convert each field of an avro-schema to a graphql type and corresponding
165
- --- argument for an upper graphql type.
187
+ --- Recursively convert each field of an avro-schema to a graphql type and
188
+ --- corresponding argument for an upper graphql type.
166
189
---
167
190
--- @tparam table state for read state.accessor and previously filled
168
191
--- state.types
169
192
--- @tparam table fields fields part from an avro-schema
170
193
local function convert_record_fields (state , fields )
171
194
local res = {}
172
195
local object_args = {}
196
+
173
197
for _ , field in ipairs (fields ) do
174
198
assert (type (field .name ) == ' string' ,
175
199
(' field.name must be a string, got %s (schema %s)' )
176
200
:format (type (field .name ), json .encode (field )))
201
+
177
202
res [field .name ] = {
178
203
name = field .name ,
179
204
kind = gql_type (state , field .type ),
186
211
--- The function recursively converts passed avro-schema to a graphql type.
187
212
---
188
213
--- @tparam table state for read state.accessor and previously filled
189
- --- state.types
214
+ --- state.types (state.types are gql types)
190
215
--- @tparam table avro_schema input avro-schema
191
216
--- @tparam [opt] table collection table with schema_name, connections fields
192
217
--- described a collection (e.g. tarantool's spaces)
@@ -230,6 +255,7 @@ gql_type = function(state, avro_schema, collection, collection_name)
230
255
231
256
local fields , _ = convert_record_fields (state , avro_schema .fields )
232
257
258
+ -- if collection param is passed
233
259
for _ , c in ipairs ((collection or {}).connections or {}) do
234
260
assert (type (c .type ) == ' string' ,
235
261
' connection.type must be a string, got ' .. type (c .type ))
@@ -333,9 +359,12 @@ gql_type = function(state, avro_schema, collection, collection_name)
333
359
error (' unrecognized avro-schema type: ' .. json .encode (avro_schema ))
334
360
end
335
361
return res
362
+
336
363
end
364
+
337
365
end
338
366
367
+
339
368
local function parse_cfg (cfg )
340
369
local state = {}
341
370
state .types = utils .gen_booking_table ({})
@@ -356,32 +385,37 @@ local function parse_cfg(cfg)
356
385
357
386
local fields = {}
358
387
359
- for name , collection in pairs (state .collections ) do
360
- collection .name = name
388
+ for collection_name , collection in pairs (state .collections ) do
389
+ collection .name = collection_name
361
390
assert (collection .schema_name ~= nil ,
362
391
' collection.schema_name must not be nil' )
392
+
363
393
local schema = cfg .schemas [collection .schema_name ]
364
394
assert (schema ~= nil , (' cfg.schemas[%s] must not be nil' ):format (
365
395
tostring (collection .schema_name )))
366
396
assert (schema .name == nil or schema .name == collection .schema_name ,
367
397
(' top-level schema name does not match the name in ' ..
368
398
' the schema itself: "%s" vs "%s"' ):format (collection .schema_name ,
369
399
schema .name ))
370
- state .types [name ] = gql_type (state , schema , collection , name )
371
400
401
+ -- recursively converts all avro types into gql types in the given schema
402
+ state .types [collection_name ] = gql_type (state , schema , collection , collection_name )
403
+
404
+ -- prepare arguments
372
405
local _ , object_args = convert_record_fields (state ,
373
406
schema .fields )
374
407
local list_args = convert_record_fields_to_args (
375
- state , accessor :list_args (name ))
408
+ state , accessor :list_args (collection_name ))
376
409
local args = utils .merge_tables (object_args , list_args )
377
- state .object_arguments [name ] = object_args
378
- state .list_arguments [name ] = list_args
379
- state .all_arguments [name ] = args
410
+
411
+ state .object_arguments [collection_name ] = object_args
412
+ state .list_arguments [collection_name ] = list_args
413
+ state .all_arguments [collection_name ] = args
380
414
381
415
-- create entry points from collection names
382
- fields [name ] = {
383
- kind = types .nonNull (types .list (state .types [name ])),
384
- arguments = state .all_arguments [name ],
416
+ fields [collection_name ] = {
417
+ kind = types .nonNull (types .list (state .types [collection_name ])),
418
+ arguments = state .all_arguments [collection_name ],
385
419
resolve = function (rootValue , args_instance , info )
386
420
local object_args_instance = {} -- passed to 'filter'
387
421
local list_args_instance = {} -- passed to 'args'
@@ -397,7 +431,7 @@ local function parse_cfg(cfg)
397
431
end
398
432
end
399
433
local from = nil
400
- return accessor :select (rootValue , name , from ,
434
+ return accessor :select (rootValue , collection_name , from ,
401
435
object_args_instance , list_args_instance )
402
436
end ,
403
437
}
@@ -414,7 +448,7 @@ local function parse_cfg(cfg)
414
448
return state
415
449
end
416
450
417
- --- The function checks if given query has an appropriate type
451
+ --- The function checks if given query has an appropriate type 'query'
418
452
--- (mutations are not supported yet)
419
453
local function assert_gql_query_ast (func_name , ast )
420
454
assert (# ast .definitions == 1 ,
@@ -427,6 +461,7 @@ local function assert_gql_query_ast(func_name, ast)
427
461
type (operation_name ))
428
462
end
429
463
464
+ --- The function just makes some assertions and then call graphql-lua execute
430
465
local function gql_execute (qstate , variables )
431
466
assert (qstate .state )
432
467
local state = qstate .state
446
481
447
482
--- The function parses a raw query string, validate the resulting query
448
483
--- and return it ready for execution
484
+ --- @tparam table state current state of graphql-lib, including
485
+ --- schemas, collections and accessor
486
+ --- @tparam string query raw query string
449
487
local function gql_compile (state , query )
450
488
assert (type (state ) == ' table' and type (query ) == ' string' ,
451
489
' use :validate(...) instead of .validate(...)' )
@@ -462,6 +500,7 @@ local function gql_compile(state, query)
462
500
ast = ast ,
463
501
operation_name = operation_name ,
464
502
}
503
+
465
504
local gql_query = setmetatable (qstate , {
466
505
__index = {
467
506
execute = gql_execute ,
0 commit comments