@@ -56,38 +56,62 @@ 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
+ [' null' ] = true ,
78
+ }
79
+
80
+ return scalar_types [avro_schema_type ] or false
81
+ end
82
+
83
+ local function is_compound_type (avro_schema_type )
84
+ check (avro_schema_type , ' avro_schema_type' , ' string' )
85
+
86
+ local compound_types = {
87
+ [' record' ] = true ,
88
+ [' record*' ] = true ,
89
+ [' array' ] = true ,
90
+ [' array*' ] = true ,
91
+ [' map' ] = true ,
92
+ [' map*' ] = true ,
93
+ }
94
+
95
+ return compound_types [avro_schema_type ] or false
96
+ end
97
+
98
+ local function avro_type (avro_schema , opts )
99
+ local opts = opts or {}
100
+ local allow_references = opts .allow_references or false
101
+
60
102
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*'
65
- elseif utils .is_array (avro_schema ) then
103
+ if utils .is_array (avro_schema ) then
66
104
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*'
105
+ elseif is_compound_type (avro_schema .type ) then
106
+ return avro_schema .type
107
+ elseif allow_references then
108
+ return avro_schema
75
109
end
76
110
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*'
89
- elseif avro_schema == ' null' then
90
- return ' null'
111
+ if is_scalar_type (avro_schema ) then
112
+ return avro_schema
113
+ elseif allow_references then
114
+ return avro_schema
91
115
end
92
116
end
93
117
error (' unrecognized avro-schema type: ' .. json .encode (avro_schema ))
@@ -247,17 +271,14 @@ local function convert_record_fields_to_args(fields, opts)
247
271
assert (type (field .name ) == ' string' ,
248
272
(' field.name must be a string, got %s (schema %s)' )
249
273
:format (type (field .name ), json .encode (field )))
250
-
251
- -- records, arrays (gql lists) and maps can't be arguments, so these
252
- -- graphql types are to be skipped
253
- local avro_t = avro_type (field .type )
254
- if not skip_compound or (
255
- avro_t ~= ' record' and avro_t ~= ' record*' and
256
- avro_t ~= ' array' and avro_t ~= ' array*' and
257
- avro_t ~= ' map' and avro_t ~= ' map*' and
258
- avro_t ~= ' union' ) then
259
-
260
- local gql_class = gql_argument_type (field .type , field .name )
274
+ -- records, arrays (gql lists), maps and unions can't be arguments, so
275
+ -- these graphql types are to be skipped;
276
+ -- skip_compound == false is the trick for accessor_general-provided
277
+ -- record; we don't expect map, array or union here as well as we don't
278
+ -- expect avro-schema reference.
279
+ local avro_t = avro_type (field .type , {allow_references = true })
280
+ if not skip_compound or is_scalar_type (avro_t ) then
281
+ local gql_class = gql_argument_type (field .type )
261
282
args [field .name ] = nullable (gql_class )
262
283
end
263
284
end
@@ -925,7 +946,7 @@ gql_type = function(state, avro_schema, collection, collection_name, field_name)
925
946
' state.accessor.list_args must not be nil' )
926
947
927
948
-- type of the top element in the avro-schema
928
- local avro_t = avro_type (avro_schema )
949
+ local avro_t = avro_type (avro_schema , { allow_references = true } )
929
950
930
951
if avro_t == ' record' or avro_t == ' record*' then
931
952
assert (type (avro_schema .name ) == ' string' ,
@@ -949,6 +970,8 @@ gql_type = function(state, avro_schema, collection, collection_name, field_name)
949
970
avro_schema .name ,
950
971
fields = fields ,
951
972
})
973
+ state .declarations [avro_schema .name ] = types .nonNull (res )
974
+ state .declarations [avro_schema .name .. ' *' ] = res
952
975
return avro_t == ' record' and types .nonNull (res ) or res
953
976
elseif avro_t == ' enum' then
954
977
error (' enums not implemented yet' ) -- XXX
@@ -980,6 +1003,12 @@ gql_type = function(state, avro_schema, collection, collection_name, field_name)
980
1003
elseif avro_t == ' union' then
981
1004
return create_gql_union (state , avro_schema , field_name )
982
1005
else
1006
+ if type (avro_schema ) == ' string' then
1007
+ if state .declarations [avro_schema ] ~= nil then
1008
+ return state .declarations [avro_schema ]
1009
+ end
1010
+ end
1011
+
983
1012
local res = convert_scalar_type (avro_schema , {raise = false })
984
1013
if res == nil then
985
1014
error (' unrecognized avro-schema type: ' ..
@@ -1119,6 +1148,9 @@ local function parse_cfg(cfg)
1119
1148
state .list_arguments = utils .gen_booking_table ({})
1120
1149
state .all_arguments = utils .gen_booking_table ({})
1121
1150
1151
+ -- map from avro-schema names to graphql types
1152
+ state .declarations = {}
1153
+
1122
1154
local accessor = cfg .accessor
1123
1155
assert (accessor ~= nil , ' cfg.accessor must not be nil' )
1124
1156
assert (accessor .select ~= nil , ' cfg.accessor.select must not be nil' )
0 commit comments