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

Commit 310d378

Browse files
committed
WIP: support of nesting a record into a record
* Fixes #46. * Fixes #49.
1 parent a4be6ee commit 310d378

File tree

6 files changed

+263
-14
lines changed

6 files changed

+263
-14
lines changed

graphql/tarantool_graphql.lua

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -149,27 +149,30 @@ local function gql_argument_type(state, avro_schema)
149149
end
150150
end
151151

152-
local function convert_record_fields_to_args(state, fields)
152+
local function convert_record_fields_to_args(state, fields, skip_compound)
153+
-- XXX: wrap into opts and and assert on skip_compound
153154
local args = {}
154155
for _, field in ipairs(fields) do
155156
assert(type(field.name) == 'string',
156157
('field.name must be a string, got %s (schema %s)')
157158
:format(type(field.name), json.encode(field)))
158-
local gql_class = gql_argument_type(state, field.type)
159-
args[field.name] = nullable(gql_class)
159+
if not skip_compound or avro_type(field.type) ~= 'record' then
160+
local gql_class = gql_argument_type(state, field.type)
161+
args[field.name] = nullable(gql_class)
162+
end
160163
end
161164
return args
162165
end
163166

164-
--- Convert each field of an avro-schema to a graphql type and corresponding
165-
--- argument for an upper graphql type.
167+
--- Convert each field of an avro-schema to a graphql type
166168
---
167169
--- @tparam table state for read state.accessor and previously filled
168170
--- state.types
169171
--- @tparam table fields fields part from an avro-schema
172+
---
173+
--- @treturn table res XXX
170174
local function convert_record_fields(state, fields)
171175
local res = {}
172-
local object_args = {}
173176
for _, field in ipairs(fields) do
174177
assert(type(field.name) == 'string',
175178
('field.name must be a string, got %s (schema %s)')
@@ -178,9 +181,8 @@ local function convert_record_fields(state, fields)
178181
name = field.name,
179182
kind = gql_type(state, field.type),
180183
}
181-
object_args[field.name] = nullable(res[field.name].kind)
182184
end
183-
return res, object_args
185+
return res
184186
end
185187

186188
--- The function recursively converts passed avro-schema to a graphql type.
@@ -228,7 +230,7 @@ gql_type = function(state, avro_schema, collection, collection_name)
228230
('avro_schema.fields must be a table, got %s (avro_schema %s)')
229231
:format(type(avro_schema.fields), json.encode(avro_schema)))
230232

231-
local fields, _ = convert_record_fields(state, avro_schema.fields)
233+
local fields = convert_record_fields(state, avro_schema.fields)
232234

233235
for _, c in ipairs((collection or {}).connections or {}) do
234236
assert(type(c.type) == 'string',
@@ -371,8 +373,8 @@ local function parse_cfg(cfg)
371373
schema.name))
372374
state.types[name] = gql_type(state, schema, collection, name)
373375

374-
local _, object_args = convert_record_fields(state,
375-
schema.fields)
376+
local object_args = convert_record_fields_to_args(state,
377+
schema.fields, true) -- [[skip_compound = true ]] --
376378
local list_args = convert_record_fields_to_args(
377379
state, accessor:list_args(name))
378380
local args = utils.merge_tables(object_args, list_args)

test/common/lua/multirunner.lua

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
local net_box = require('net.box')
33
local shard = require('shard')
44

5+
local initialized = false
6+
57
local function instance_uri(instance_id)
68
local socket_dir = require('fio').cwd()
79
local uri = ('%s/shard%s.sock'):format(socket_dir, instance_id)
@@ -12,9 +14,10 @@ local function init_shard(test_run, servers, config)
1214
local shard = require('shard')
1315
local suite = "common"
1416
test_run:create_cluster(servers, suite)
15-
box.once('init_shard_module', function()
17+
if not initialized then
1618
shard.init(config)
17-
end)
19+
initialized = true
20+
end
1821
shard.wait_connection()
1922
end
2023

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
-- Nested record inside a record
2+
-- https://github.com/tarantool/graphql/issues/46
3+
-- https://github.com/tarantool/graphql/issues/49
4+
5+
local json = require('json')
6+
local yaml = require('yaml')
7+
local utils = require('graphql.utils')
8+
9+
local testdata = {}
10+
11+
testdata.meta = {
12+
schemas = json.decode([[{
13+
"user": {
14+
"type": "record",
15+
"name": "user",
16+
"fields": [
17+
{"name": "uid", "type": "long"},
18+
{"name": "p1", "type": "string"},
19+
{"name": "p2", "type": "string"},
20+
{
21+
"name": "nested",
22+
"type": {
23+
"type": "record",
24+
"name": "nested",
25+
"fields": [
26+
{"name": "x", "type": "long"},
27+
{"name": "y", "type": "long"}
28+
]
29+
}
30+
}
31+
]
32+
}
33+
}]]),
34+
collections = json.decode([[{
35+
"user": {
36+
"schema_name": "user",
37+
"connections": []
38+
}
39+
}]]),
40+
service_fields = {
41+
user = {},
42+
},
43+
indexes = {
44+
user = {
45+
uid = {
46+
service_fields = {},
47+
fields = {'uid'},
48+
index_type = 'tree',
49+
unique = true,
50+
primary = true,
51+
},
52+
},
53+
}
54+
}
55+
56+
57+
function testdata.init_spaces()
58+
-- user fields
59+
local UID_FN = 1
60+
61+
box.schema.create_space('user')
62+
box.space.user:create_index('uid', {
63+
type = 'tree', unique = true, parts = {UID_FN, 'unsigned'}})
64+
end
65+
66+
function testdata.drop_spaces()
67+
box.space.user:drop()
68+
end
69+
70+
function testdata.fill_test_data(virtbox)
71+
for i = 1, 15 do
72+
local uid = i
73+
local p1 = 'p1 ' .. tostring(i)
74+
local p2 = 'p2 ' .. tostring(i)
75+
local x = 1000 + i
76+
local y = 2000 + i
77+
virtbox.user:replace({uid, p1, p2, x, y})
78+
end
79+
end
80+
81+
function testdata.run_queries(gql_wrapper)
82+
local query = [[
83+
query getUserByUid($uid: Long) {
84+
user(uid: $uid) {
85+
uid
86+
p1
87+
p2
88+
nested {
89+
x
90+
y
91+
}
92+
}
93+
}
94+
]]
95+
96+
local gql_query = gql_wrapper:compile(query)
97+
local variables = {uid = 5}
98+
local result = utils.show_trace(function()
99+
return gql_query:execute(variables)
100+
end)
101+
102+
return 'RUN {{{\n' ..
103+
(('QUERY\n%s'):format(query:rstrip())) .. '\n' ..
104+
(('VARIABLES\n%s'):format(yaml.encode(variables))) .. '\n' ..
105+
(('RESULT\n%s'):format(yaml.encode(result))) .. '\n' ..
106+
'}}}'
107+
end
108+
109+
return testdata

test/common/nested_record.result

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
Shard 2x2
2+
RUN {{{
3+
QUERY
4+
query getUserByUid($uid: Long) {
5+
user(uid: $uid) {
6+
uid
7+
p1
8+
p2
9+
nested {
10+
x
11+
y
12+
}
13+
}
14+
}
15+
VARIABLES
16+
---
17+
uid: 5
18+
...
19+
20+
RESULT
21+
---
22+
user:
23+
- p2: p2 5
24+
p1: p1 5
25+
uid: 5
26+
nested:
27+
y: 2005
28+
x: 1005
29+
...
30+
31+
}}}
32+
Shard 4x1
33+
RUN {{{
34+
QUERY
35+
query getUserByUid($uid: Long) {
36+
user(uid: $uid) {
37+
uid
38+
p1
39+
p2
40+
nested {
41+
x
42+
y
43+
}
44+
}
45+
}
46+
VARIABLES
47+
---
48+
uid: 5
49+
...
50+
51+
RESULT
52+
---
53+
user:
54+
- p2: p2 5
55+
p1: p1 5
56+
uid: 5
57+
nested:
58+
y: 2005
59+
x: 1005
60+
...
61+
62+
}}}
63+
Local (box)
64+
RUN {{{
65+
QUERY
66+
query getUserByUid($uid: Long) {
67+
user(uid: $uid) {
68+
uid
69+
p1
70+
p2
71+
nested {
72+
x
73+
y
74+
}
75+
}
76+
}
77+
VARIABLES
78+
---
79+
uid: 5
80+
...
81+
82+
RESULT
83+
---
84+
user:
85+
- p2: p2 5
86+
p1: p1 5
87+
uid: 5
88+
nested:
89+
y: 2005
90+
x: 1005
91+
...
92+
93+
}}}

test/common/nested_record.test.lua

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/usr/bin/env tarantool
2+
3+
local fio = require('fio')
4+
local multirunner = require('multirunner')
5+
local testdata = require('test_data_nested_record')
6+
local test_run = require('test_run').new()
7+
local graphql = require('graphql')
8+
9+
box.cfg({})
10+
11+
-- require in-repo version of graphql/ sources despite current working directory
12+
package.path = fio.abspath(debug.getinfo(1).source:match("@?(.*/)")
13+
:gsub('/./', '/'):gsub('/+$', '')) .. '/../../?.lua' .. ';' .. package.path
14+
15+
local function run(setup_name, shard)
16+
print(setup_name)
17+
18+
local accessor_class = shard and graphql.accessor_shard or
19+
graphql.accessor_space
20+
local virtbox = shard or box.space
21+
22+
local accessor = accessor_class.new({
23+
schemas = testdata.meta.schemas,
24+
collections = testdata.meta.collections,
25+
service_fields = testdata.meta.service_fields,
26+
indexes = testdata.meta.indexes,
27+
})
28+
29+
local gql_wrapper = graphql.new({
30+
schemas = testdata.meta.schemas,
31+
collections = testdata.meta.collections,
32+
accessor = accessor,
33+
})
34+
35+
testdata.fill_test_data(virtbox)
36+
print(testdata.run_queries(gql_wrapper))
37+
end
38+
39+
multirunner.run(test_run, testdata.init_spaces, testdata.drop_spaces, run)
40+
41+
os.exit()

test/common/suite.ini

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[default]
22
core = app
33
description = tests different setups simultaneously
4-
lua_libs = lua/multirunner.lua lua/test_data_user_order.lua
4+
lua_libs = lua/multirunner.lua lua/test_data_user_order.lua \
5+
lua/test_data_nested_record.lua

0 commit comments

Comments
 (0)