@@ -251,16 +251,11 @@ local function convert_record_fields(state, fields)
251
251
return res
252
252
end
253
253
254
- -- @todo where to put new format description?
255
-
256
- --- The function converts passed simple connection to a field of GraphQL type
257
- --- There are two types on connections: simple and union
258
-
254
+ --- The function converts passed simple connection to a field of GraphQL type.
259
255
---
260
- --- @tparam table state for read state.accessor and previously filled
261
- --- state.types (state.types are gql types)
256
+ --- @tparam table state for for collection types
262
257
--- @tparam table c simple connection to create field on
263
- --- @tparam table collection_name name of the collection which have given
258
+ --- @tparam table collection_name name of the collection which has given
264
259
--- connection
265
260
local convert_simple_connection = function (state , c , collection_name )
266
261
assert (type (c .destination_collection ) == ' string' ,
@@ -292,9 +287,6 @@ local convert_simple_connection = function(state, c, collection_name)
292
287
kind = destination_type ,
293
288
arguments = c_args ,
294
289
resolve = function (parent , args_instance , info )
295
- -- print('print from 295 - resolve of simple connection')
296
- -- print('parent - resolve result from parent type')
297
- -- require('pl.pretty').dump(parent)
298
290
local destination_args_names = {}
299
291
local destination_args_values = {}
300
292
@@ -354,14 +346,19 @@ local convert_simple_connection = function(state, c, collection_name)
354
346
return field
355
347
end
356
348
349
+ --- The function converts passed union connection to a field of GraphQL type.
350
+ --- It builds connections between union collection and destination collections
351
+ --- (destination collections are 'types' of a 'Union' in GraphQL).
352
+ ---
353
+ --- @tparam table state for collection types
354
+ --- @tparam table c union connection to create field on
355
+ --- @tparam table collection_name name of the collection which has given
356
+ --- connection
357
357
local convert_union_connection = function (state , c , collection_name )
358
358
local union_types = {}
359
359
local collection_to_arguments = {}
360
360
local collection_to_list_arguments = {}
361
- -- map from determinant objects to use in resolveType
362
- -- not to use like determinant[determinant_value] = ...
363
- -- use like for k, v in pairs() ...
364
- -- {{hero_type = 'human', number_of_legs = '2'} = 'human_collection', {
361
+
365
362
local determinant_keys = utils .get_keys (c .variants [1 ].determinant )
366
363
local determinant_to_variant = {}
367
364
@@ -397,23 +394,21 @@ local convert_union_connection = function(state, c, collection_name)
397
394
collection_to_list_arguments [v .destination_collection ] = v_list_args
398
395
end
399
396
400
- -- should return graphQL type (collection in our terms)
401
- local function resolveType (result )
402
- -- @todo fix this as it will work only for human-starship union
403
- if utils .do_have_keys (result , {' name' }) then
404
- return state .types [' human_collection' ]
405
- end
406
-
407
- if utils .do_have_keys (result , {' model' }) then
408
- return state .types [' starship_collection' ]
397
+ local resolveType = function (result )
398
+ for _ , v in pairs (c .variants ) do
399
+ local dest_collection = state .types [v .destination_collection ]
400
+ if utils .do_have_keys (result , utils .get_keys (dest_collection .fields )) then
401
+ return dest_collection
402
+ end
409
403
end
410
404
end
411
405
412
- local function resolve_variant (parent )
406
+ local resolve_variant = function (parent )
413
407
assert (utils .do_have_keys (parent , determinant_keys ),
414
- (' Parent object of union object doesn\' t have determinant fields' ..
415
- ' which are nessesary to determine which resolving variant should' ..
416
- ' be used. Union parent object:\n "%s"\n Determinant keys:\n "%s"' ):
408
+ (' Parent object of union object doesn\' t have determinant ' ..
409
+ ' fields which are nessesary to determine which resolving ' ..
410
+ ' variant should be used. Union parent object:\n "%s"\n ' ..
411
+ ' Determinant keys:\n "%s"' ):
417
412
format (yaml .encode (parent ), yaml .encode (determinant_keys )))
418
413
419
414
local resulting_variant
@@ -439,10 +434,10 @@ local convert_union_connection = function(state, c, collection_name)
439
434
440
435
local field = {
441
436
name = c .name ,
442
- kind = types .union ({name = c .name , types = union_types , resolveType = resolveType }),
437
+ kind = types .union ({name = c .name , types = union_types ,
438
+ resolveType = resolveType }),
443
439
arguments = nil ,
444
440
resolve = function (parent , args_instance , info )
445
- -- variant for this destination
446
441
local v = resolve_variant (parent )
447
442
local destination_collection = state .types [v .destination_collection ]
448
443
local destination_args_names = {}
@@ -503,9 +498,9 @@ local convert_union_connection = function(state, c, collection_name)
503
498
return objs
504
499
end
505
500
end
506
- }
501
+ }
507
502
return field
508
- end
503
+ end
509
504
510
505
--- The function converts passed connection to a field of GraphQL type
511
506
---
@@ -516,11 +511,11 @@ local convert_union_connection = function(state, c, collection_name)
516
511
--- connection
517
512
local convert_connection_to_field = function (state , connection , collection_name )
518
513
assert (type (connection .type ) == ' string' ,
519
- ' connection.type must be a string, got ' .. type (connection .type ))
514
+ ' connection.type must be a string, got ' .. type (connection .type ))
520
515
assert (connection .type == ' 1:1' or connection .type == ' 1:N' ,
521
- ' connection.type must be 1:1 or 1:N, got ' .. connection .type )
516
+ ' connection.type must be 1:1 or 1:N, got ' .. connection .type )
522
517
assert (type (connection .name ) == ' string' ,
523
- ' connection.name must be a string, got ' .. type (connection .name ))
518
+ ' connection.name must be a string, got ' .. type (connection .name ))
524
519
assert (connection .destination_collection or connection .variants ,
525
520
' connection must either destination_collection or variatns field' )
526
521
@@ -682,7 +677,6 @@ local function parse_cfg(cfg)
682
677
{skip_compound = true })
683
678
local list_args = convert_record_fields_to_args (
684
679
accessor :list_args (collection_name ))
685
-
686
680
local args = utils .merge_tables (object_args , list_args )
687
681
688
682
state .object_arguments [collection_name ] = object_args
@@ -712,10 +706,8 @@ local function parse_cfg(cfg)
712
706
local extra = {
713
707
qcontext = info .qcontext
714
708
}
715
-
716
-
717
709
return accessor :select (rootValue , collection_name , from ,
718
- object_args_instance , list_args_instance , extra )
710
+ object_args_instance , list_args_instance , extra )
719
711
end ,
720
712
}
721
713
end
@@ -779,16 +771,6 @@ local function gql_compile(state, query)
779
771
local ast = parse (query )
780
772
assert_gql_query_ast (' gql_compile' , ast )
781
773
local operation_name = ast .definitions [1 ].name .value
782
- --
783
- -- print('print from gql_compile - state.schema')
784
- -- require('pl.pretty').dump(state.schema)
785
- --
786
- -- print('ast')
787
- -- require('pl.pretty').dump(ast)
788
-
789
-
790
- -- @todo add custom validation for schemas with unions
791
- -- or change insides of validate to process unions the custom way
792
774
validate (state .schema , ast )
793
775
794
776
local qstate = {
825
807
--- schema_name = 'schema_name_foo',
826
808
--- connections = { // the optional field
827
809
--- {
828
- --- name = 'connection_name_bar',
810
+ --- type = '1:1' or '1:N',
811
+ --- name = 'simple_connection_name',
829
812
--- destination_collection = 'collection_baz',
830
813
--- parts = {
831
814
--- {
838
821
--- -- ignored in the graphql
839
822
--- -- part
840
823
--- },
841
- --- ...
824
+ --- {
825
+ --- name = 'union_connection_name',
826
+ --- type = '1:1' or '1:N',
827
+ --- variants = {
828
+ --- {
829
+ --- see variant format below
830
+ --- },
831
+ --- ...
832
+ --- }
833
+ --- },
834
+ --- ...
842
835
--- },
843
836
--- },
844
837
--- ...
872
865
--- }
873
866
--- }),
874
867
--- })
868
+ ---
869
+ --- variant format
870
+ --- {
871
+ --- Source collection must have all fields that are keys in determinant
872
+ --- table. Based on the values of these fields right destination collection
873
+ --- is determined.
874
+ --- determinant = {field_or_source: 'destination_1_value', ...},
875
+ --- destination_collection = 'collection_name',
876
+ --- parts = {
877
+ --- {
878
+ --- source_field = 'field_name_source',
879
+ --- destination_field = 'field_name_destination'
880
+ --- }
881
+ --- },
882
+ --- index_name = 'index_name'
883
+ --- }
875
884
function tarantool_graphql .new (cfg )
876
885
local state = parse_cfg (cfg )
877
886
return setmetatable (state , {
0 commit comments