Skip to content
This repository was archived by the owner on Apr 14, 2022. It is now read-only.

Commit fb4b75e

Browse files
committed
Split code to modules
Moves are mostly done w/o changes. There are APIs (parameters and return values) that are subject to further refactoring. Removed duplicate code in resolve the function for multihead connections. Part of #166.
1 parent fc32742 commit fb4b75e

15 files changed

+2206
-2142
lines changed

graphql/accessor_general.lua

Lines changed: 19 additions & 274 deletions
Large diffs are not rendered by default.

graphql/avro_helpers.lua

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
--- The module us collection of helpers to simplify avro-schema related tasks.
1+
--- The module is collection of helpers to simplify avro-schema related tasks.
22

33
local json = require('json')
44
local avro_schema = require('avro_schema')
55

6+
local utils = require('graphql.utils')
7+
local check = utils.check
8+
69
local avro_helpers = {}
710

811
--- The function converts avro type to the corresponding nullable type in
@@ -83,4 +86,81 @@ function avro_helpers.major_avro_schema_version()
8386
return model.get_types == nil and 2 or 3
8487
end
8588

89+
function avro_helpers.is_scalar_type(avro_schema_type)
90+
check(avro_schema_type, 'avro_schema_type', 'string')
91+
92+
local scalar_types = {
93+
['int'] = true,
94+
['int*'] = true,
95+
['long'] = true,
96+
['long*'] = true,
97+
['float'] = true,
98+
['float*'] = true,
99+
['double'] = true,
100+
['double*'] = true,
101+
['boolean'] = true,
102+
['boolean*'] = true,
103+
['string'] = true,
104+
['string*'] = true,
105+
['null'] = true,
106+
}
107+
108+
return scalar_types[avro_schema_type] or false
109+
end
110+
111+
function avro_helpers.is_comparable_scalar_type(avro_schema_type)
112+
check(avro_schema_type, 'avro_schema_type', 'string')
113+
114+
local scalar_types = {
115+
['int'] = true,
116+
['int*'] = true,
117+
['long'] = true,
118+
['long*'] = true,
119+
['boolean'] = true,
120+
['boolean*'] = true,
121+
['string'] = true,
122+
['string*'] = true,
123+
['null'] = true,
124+
}
125+
126+
return scalar_types[avro_schema_type] or false
127+
end
128+
129+
function avro_helpers.is_compound_type(avro_schema_type)
130+
check(avro_schema_type, 'avro_schema_type', 'string')
131+
132+
local compound_types = {
133+
['record'] = true,
134+
['record*'] = true,
135+
['array'] = true,
136+
['array*'] = true,
137+
['map'] = true,
138+
['map*'] = true,
139+
}
140+
141+
return compound_types[avro_schema_type] or false
142+
end
143+
144+
function avro_helpers.avro_type(avro_schema, opts)
145+
local opts = opts or {}
146+
local allow_references = opts.allow_references or false
147+
148+
if type(avro_schema) == 'table' then
149+
if utils.is_array(avro_schema) then
150+
return 'union'
151+
elseif avro_helpers.is_compound_type(avro_schema.type) then
152+
return avro_schema.type
153+
elseif allow_references then
154+
return avro_schema
155+
end
156+
elseif type(avro_schema) == 'string' then
157+
if avro_helpers.is_scalar_type(avro_schema) then
158+
return avro_schema
159+
elseif allow_references then
160+
return avro_schema
161+
end
162+
end
163+
error('unrecognized avro-schema type: ' .. json.encode(avro_schema))
164+
end
165+
86166
return avro_helpers

graphql/convert_schema/arguments.lua

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
--- Convert avro-schema fields to GraphQL arguments (scalars and InputObjects).
2+
3+
local json = require('json')
4+
local log = require('log')
5+
local core_types = require('graphql.core.types')
6+
local avro_helpers = require('graphql.avro_helpers')
7+
local core_types_helpers = require('graphql.convert_schema.core_types_helpers')
8+
local scalar_types = require('graphql.convert_schema.scalar_types')
9+
10+
local utils = require('graphql.utils')
11+
local check = utils.check
12+
13+
local arguments = {}
14+
15+
--- Convert each field of an avro-schema to a scalar graphql type or an input
16+
--- object.
17+
---
18+
--- It uses the @{arguments.convert} function to convert each field, then skips
19+
--- fields of record, array and map types and gives the resulting list of
20+
--- converted fields.
21+
---
22+
--- @tparam table fields list of fields of the avro-schema record fields format
23+
---
24+
--- @tparam[opt] table opts optional options:
25+
---
26+
--- * `skip_compound` -- do not add fields of record type to the arguments;
27+
--- default: false.
28+
---
29+
--- * `dont_skip` -- do not skip any fields; default: false.
30+
---
31+
--- @treturn table `args` -- map with type names as keys and graphql types as
32+
--- values
33+
function arguments.convert_record_fields(fields, opts)
34+
assert(type(fields) == 'table',
35+
'fields must be a table, got ' .. type(fields))
36+
37+
local opts = opts or {}
38+
assert(type(opts) == 'table',
39+
'opts must be a table, got ' .. type(opts))
40+
41+
local skip_compound = opts.skip_compound or false
42+
assert(type(skip_compound) == 'boolean',
43+
'skip_compound must be a boolean, got ' .. type(skip_compound))
44+
45+
local dont_skip = opts.dont_skip or false
46+
check(dont_skip, 'dont_skip', 'boolean')
47+
48+
local args = {}
49+
for _, field in ipairs(fields) do
50+
assert(type(field.name) == 'string',
51+
('field.name must be a string, got %s (schema %s)')
52+
:format(type(field.name), json.encode(field)))
53+
-- records, arrays (gql lists), maps and unions can't be arguments, so
54+
-- these graphql types are to be skipped;
55+
-- skip_compound == false is the trick for accessor_general-provided
56+
-- record; we don't expect map, array or union here as well as we don't
57+
-- expect avro-schema reference.
58+
local avro_t = avro_helpers.avro_type(field.type,
59+
{allow_references = true})
60+
local add_field = dont_skip or
61+
avro_helpers.is_comparable_scalar_type(avro_t) or
62+
(not skip_compound and not avro_helpers.is_scalar_type(avro_t))
63+
if add_field then
64+
local ok, gql_class = pcall(arguments.convert, field.type)
65+
-- XXX: we need better avro-schema -> graphql types converter to
66+
-- handle the following cases:
67+
-- * scalar arguments that can be checked for equality (object
68+
-- args): skip any other
69+
-- * pcre / limit / offset (nothing special here I guess)
70+
-- * auxiliary schemas for insert / update: don't skip anything
71+
if ok then
72+
args[field.name] = core_types_helpers.nullable(gql_class)
73+
else
74+
log.warn(('Cannot add argument "%s": %s'):format(
75+
field.name, tostring(gql_class)))
76+
end
77+
end
78+
end
79+
return args
80+
end
81+
82+
--- Convert avro-schema type to GraphQL scalar or InputObject.
83+
---
84+
--- An error will be raised if avro_schema type is 'record'
85+
--- and its' fields have non-scalar types. So triple nesting level is not
86+
--- supported (record with record as a field - ok, record with record which
87+
--- has inside an another level - not ok).
88+
function arguments.convert(avro_schema)
89+
assert(avro_schema ~= nil,
90+
'avro_schema must not be nil')
91+
92+
if avro_helpers.avro_type(avro_schema) == 'record' then
93+
assert(type(avro_schema.name) == 'string',
94+
('avro_schema.name must be a string, got %s (avro_schema %s)')
95+
:format(type(avro_schema.name), json.encode(avro_schema)))
96+
97+
assert(type(avro_schema.fields) == 'table',
98+
('avro_schema.fields must be a table, got %s (avro_schema %s)')
99+
:format(type(avro_schema.fields), json.encode(avro_schema)))
100+
101+
local fields = {}
102+
for _, field in ipairs(avro_schema.fields) do
103+
assert(type(field.name) == 'string',
104+
('field.name must be a string, got %s (schema %s)')
105+
:format(type(field.name), json.encode(field)))
106+
107+
local gql_field_type = scalar_types.convert(field.type,
108+
{raise = true})
109+
110+
fields[field.name] = {
111+
name = field.name,
112+
kind = gql_field_type,
113+
}
114+
end
115+
116+
local res = core_types.nonNull(core_types.inputObject({
117+
name = avro_schema.name,
118+
description = 'generated from avro-schema for ' ..
119+
avro_schema.name,
120+
fields = fields,
121+
}))
122+
123+
return res
124+
else
125+
local res = scalar_types.convert(avro_schema, {raise = false})
126+
if res == nil then
127+
error('unrecognized avro-schema type: ' ..
128+
json.encode(avro_schema))
129+
end
130+
return res
131+
end
132+
end
133+
134+
return arguments
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--- Collection of helpers to work with GraphQL types.
2+
3+
local utils = require('graphql.utils')
4+
local check = utils.check
5+
6+
local core_types_helpers = {}
7+
8+
function core_types_helpers.nullable(gql_class)
9+
check(gql_class, 'gql_class', 'table')
10+
11+
if gql_class.__type ~= 'NonNull' then return gql_class end
12+
13+
assert(gql_class.ofType ~= nil, 'gql_class.ofType must not be nil')
14+
return core_types_helpers.nullable(gql_class.ofType)
15+
end
16+
17+
function core_types_helpers.raw_gql_type(gql_class)
18+
check(gql_class, 'gql_class', 'table')
19+
20+
if gql_class.ofType == nil then return gql_class end
21+
22+
assert(gql_class.ofType ~= nil, 'gql_class.ofType must not be nil')
23+
return core_types_helpers.raw_gql_type(gql_class.ofType)
24+
end
25+
26+
return core_types_helpers

graphql/convert_schema/init.lua

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
local schema = require('graphql.convert_schema.schema')
2+
3+
local convert_schema = {}
4+
5+
convert_schema.convert = schema.convert
6+
7+
return convert_schema

0 commit comments

Comments
 (0)