@@ -56,36 +56,61 @@ local default_instance
56
56
-- forward declarations
57
57
local gql_type
58
58
59
- local function avro_type (avro_schema )
59
+ local function is_scalar_type (avro_schema_type )
60
+ check (avro_schema_type , ' avro_schema_type' , ' string' )
61
+
62
+ local scalar_types = {
63
+ [' int' ] = true ,
64
+ [' int*' ] = true ,
65
+ [' long' ] = true ,
66
+ [' long*' ] = true ,
67
+ --[[
68
+ ['float'] = true,
69
+ ['float*'] = true,
70
+ ['double'] = true,
71
+ ['double*'] = true,
72
+ ['boolean'] = true,
73
+ ['boolean*'] = true,
74
+ ]] --
75
+ [' string' ] = true ,
76
+ [' string*' ] = true ,
77
+ }
78
+
79
+ return scalar_types [avro_schema_type ] or false
80
+ end
81
+
82
+ local function is_compound_type (avro_schema_type )
83
+ check (avro_schema_type , ' avro_schema_type' , ' string' )
84
+
85
+ local compound_types = {
86
+ [' record' ] = true ,
87
+ [' record*' ] = true ,
88
+ [' array' ] = true ,
89
+ [' array*' ] = true ,
90
+ [' map' ] = true ,
91
+ [' map*' ] = true ,
92
+ }
93
+
94
+ return compound_types [avro_schema_type ] or false
95
+ end
96
+
97
+ local function avro_type (avro_schema , opts )
98
+ local opts = opts or {}
99
+ local allow_references = opts .allow_references or false
100
+
60
101
if type (avro_schema ) == ' table' then
61
- if avro_schema .type == ' record' then
62
- return ' record'
63
- elseif avro_schema .type == ' record*' then
64
- return ' record*'
102
+ if is_compound_type (avro_schema .type ) then
103
+ return avro_schema .type
65
104
elseif utils .is_array (avro_schema ) then
66
105
return ' union'
67
- elseif avro_schema .type == ' array' then
68
- return ' array'
69
- elseif avro_schema .type == ' array*' then
70
- return ' array*'
71
- elseif avro_schema .type == ' map' then
72
- return ' map'
73
- elseif avro_schema .type == ' map*' then
74
- return ' map*'
106
+ elseif allow_references then
107
+ return avro_schema
75
108
end
76
109
elseif type (avro_schema ) == ' string' then
77
- if avro_schema == ' int' then
78
- return ' int'
79
- elseif avro_schema == ' int*' then
80
- return ' int*'
81
- elseif avro_schema == ' long' then
82
- return ' long'
83
- elseif avro_schema == ' long*' then
84
- return ' long*'
85
- elseif avro_schema == ' string' then
86
- return ' string'
87
- elseif avro_schema == ' string*' then
88
- return ' string*'
110
+ if is_scalar_type (avro_schema ) then
111
+ return avro_schema
112
+ elseif allow_references then
113
+ return avro_schema
89
114
end
90
115
end
91
116
error (' unrecognized avro-schema type: ' .. json .encode (avro_schema ))
@@ -245,14 +270,13 @@ local function convert_record_fields_to_args(fields, opts)
245
270
assert (type (field .name ) == ' string' ,
246
271
(' field.name must be a string, got %s (schema %s)' )
247
272
:format (type (field .name ), json .encode (field )))
248
-
249
- -- records, arrays (gql lists) and maps can't be arguments, so these
250
- -- graphql types are to be skipped
251
- local avro_t = avro_type (field .type )
252
- if not skip_compound or (
253
- avro_t ~= ' record' and avro_t ~= ' record*' and
254
- avro_t ~= ' array' and avro_t ~= ' array*' and
255
- avro_t ~= ' map' and avro_t ~= ' map*' ) then
273
+ -- records, arrays (gql lists), maps and unions can't be arguments, so
274
+ -- these graphql types are to be skipped;
275
+ -- skip_compound == false is the trick for accessor_general-provided
276
+ -- record; we don't expect map, array or union here as well as we don't
277
+ -- expect avro-schema reference.
278
+ local avro_t = avro_type (field .type , {allow_references = true })
279
+ if not skip_compound or is_scalar_type (avro_t ) then
256
280
local gql_class = gql_argument_type (field .type )
257
281
args [field .name ] = nullable (gql_class )
258
282
end
@@ -711,7 +735,7 @@ gql_type = function(state, avro_schema, collection, collection_name)
711
735
' state.accessor.list_args must not be nil' )
712
736
713
737
-- type of the top element in the avro-schema
714
- local avro_t = avro_type (avro_schema )
738
+ local avro_t = avro_type (avro_schema , { allow_references = true } )
715
739
716
740
if avro_t == ' record' or avro_t == ' record*' then
717
741
assert (type (avro_schema .name ) == ' string' ,
@@ -735,6 +759,8 @@ gql_type = function(state, avro_schema, collection, collection_name)
735
759
avro_schema .name ,
736
760
fields = fields ,
737
761
})
762
+ state .declarations [avro_schema .name ] = types .nonNull (res )
763
+ state .declarations [avro_schema .name .. ' *' ] = res
738
764
return avro_t == ' record' and types .nonNull (res ) or res
739
765
elseif avro_t == ' enum' then
740
766
error (' enums not implemented yet' ) -- XXX
@@ -764,6 +790,14 @@ gql_type = function(state, avro_schema, collection, collection_name)
764
790
local gql_map = types_map
765
791
return avro_t == ' map' and types .nonNull (gql_map ) or gql_map
766
792
else
793
+ require (' log' ).info (' aaaa: ' .. json .encode (avro_schema ))
794
+ -- XXX: prevent name clash using namespaces
795
+ if type (avro_schema ) == ' string' then
796
+ if state .declarations [avro_schema ] ~= nil then
797
+ return state .declarations [avro_schema ]
798
+ end
799
+ end
800
+
767
801
local res = convert_scalar_type (avro_schema , {raise = false })
768
802
if res == nil then
769
803
error (' unrecognized avro-schema type: ' ..
@@ -903,6 +937,9 @@ local function parse_cfg(cfg)
903
937
state .list_arguments = utils .gen_booking_table ({})
904
938
state .all_arguments = utils .gen_booking_table ({})
905
939
940
+ -- map from avro-schema names to graphql types
941
+ state .declarations = {}
942
+
906
943
local accessor = cfg .accessor
907
944
assert (accessor ~= nil , ' cfg.accessor must not be nil' )
908
945
assert (accessor .select ~= nil , ' cfg.accessor.select must not be nil' )
0 commit comments