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

Commit 7ae1d74

Browse files
committed
Allow to use custom unflattener
Closes #52 (moves responsibility to an user of the library).
1 parent a4be6ee commit 7ae1d74

File tree

4 files changed

+317
-9
lines changed

4 files changed

+317
-9
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ default:
44
.PHONY: lint
55
lint:
66
luacheck graphql/*.lua test/local/*.lua test/testdata/*.lua \
7-
test/common/*test.lua test/common/lua/*.lua \
7+
test/common/*.test.lua test/common/lua/*.lua \
88
--no-redefined --no-unused-args
99

1010
.PHONY: test

graphql/accessor_general.lua

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,13 @@ end
574574
--- Nothing returned, but after necessary count of invokes `state.objs` will
575575
--- hold list of resulting objects.
576576
local function process_tuple(state, tuple, opts)
577-
local function maybe_unflatten(model, tuple, obj)
577+
local function maybe_unflatten(model, tuple, obj, opts)
578+
if obj ~= nil then
579+
return obj
580+
end
581+
if opts.unflatten_tuple ~= nil then
582+
return opts.unflatten_tuple(opts.collection_name, tuple)
583+
end
578584
local ok, obj = model.unflatten(tuple)
579585
assert(ok, 'cannot unflat tuple: ' .. tostring(obj))
580586
return obj
@@ -597,15 +603,15 @@ local function process_tuple(state, tuple, opts)
597603
-- skip all items before pivot (the item pointed by offset)
598604
local obj = nil
599605
if not state.pivot_found and pivot_filter then
600-
obj = maybe_unflatten(model, tuple, obj)
606+
obj = maybe_unflatten(model, tuple, obj, opts)
601607
local match = utils.is_subtable(obj, pivot_filter)
602608
if not match then return true end
603609
state.pivot_found = true
604610
return true -- skip pivot item too
605611
end
606612

607613
-- convert tuple -> object, then filter out or continue
608-
obj = maybe_unflatten(model, tuple, obj)
614+
obj = maybe_unflatten(model, tuple, obj, opts)
609615
local match = utils.is_subtable(obj, filter)
610616
if do_filter then
611617
if not match then return true end
@@ -723,7 +729,9 @@ local function select_internal(self, collection_name, from, filter, args, extra)
723729
do_filter = not full_match,
724730
pivot_filter = nil, -- filled later if needed
725731
resulting_object_cnt_max = self.settings.resulting_object_cnt_max,
726-
fetched_object_cnt_max = self.settings.fetched_object_cnt_max
732+
fetched_object_cnt_max = self.settings.fetched_object_cnt_max,
733+
collection_name = collection_name,
734+
unflatten_tuple = self.funcs.unflatten_tuple,
727735
}
728736

729737
if index == nil then
@@ -803,6 +811,11 @@ local function validate_funcs(funcs)
803811
assert(type(funcs.get_primary_index) == 'function',
804812
'funcs.get_primary_index must be a function, got ' ..
805813
type(funcs.get_primary_index))
814+
if funcs.unflatten_tuple ~= nil then
815+
assert(type(funcs.unflatten_tuple) == 'function',
816+
'funcs.unflatten_tuple must be a function, got ' ..
817+
type(funcs.unflatten_tuple))
818+
end
806819
end
807820

808821
--- Create a new data accessor.
@@ -818,10 +831,10 @@ end
818831
--- value is 10,000)_
819832
---
820833
--- @tparam table funcs set of functions (`is_collection_exists`, `get_index`,
821-
--- `get_primary_index`) allows this abstract data accessor behaves in the
822-
--- certain way (say, like space data accessor or shard data accessor);
823-
--- consider the `accessor_space` and the `accessor_shard` modules documentation
824-
--- for this functions description
834+
--- `get_primary_index`, `unflatten_tuple`) allows this abstract data accessor
835+
--- behaves in the certain way (say, like space data accessor or shard data
836+
--- accessor); consider the `accessor_space` and the `accessor_shard` modules
837+
--- documentation for this functions description
825838
---
826839
--- For examples of `opts.schemas` and `opts.collections` consider the
827840
--- @{tarantool_graphql.new} function description.

test/local/unflatten_tuple.result

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
RESULT
2+
---
3+
order_collection:
4+
- order_id: order_id_1
5+
description: first order of Ivan$
6+
user_connection:
7+
user_id: user_id_1
8+
last_name: Ivanov$
9+
first_name: Ivan$
10+
...
11+
12+
RESULT
13+
---
14+
user_collection:
15+
- user_id: user_id_1
16+
last_name: Ivanov$
17+
first_name: Ivan$
18+
order_connection:
19+
- order_id: order_id_1
20+
description: first order of Ivan$
21+
- order_id: order_id_2
22+
description: second order of Ivan$
23+
...
24+
25+
RESULT
26+
---
27+
user_collection:
28+
- user_id: user_id_42
29+
last_name: last name 42$
30+
first_name: first name 42$
31+
order_connection:
32+
- order_id: order_id_1574
33+
description: order of user 42$
34+
- order_id: order_id_1575
35+
description: order of user 42$
36+
- order_id: order_id_1576
37+
description: order of user 42$
38+
- order_id: order_id_1577
39+
description: order of user 42$
40+
- order_id: order_id_1578
41+
description: order of user 42$
42+
- order_id: order_id_1579
43+
description: order of user 42$
44+
- order_id: order_id_1580
45+
description: order of user 42$
46+
- order_id: order_id_1581
47+
description: order of user 42$
48+
- order_id: order_id_1582
49+
description: order of user 42$
50+
- order_id: order_id_1583
51+
description: order of user 42$
52+
...
53+
54+
RESULT
55+
---
56+
user_collection:
57+
- user_id: user_id_42
58+
last_name: last name 42$
59+
first_name: first name 42$
60+
order_connection:
61+
- order_id: order_id_1602
62+
description: order of user 42$
63+
- order_id: order_id_1603
64+
description: order of user 42$
65+
...
66+
67+
RESULT
68+
---
69+
user_collection: []
70+
...
71+
72+
RESULT
73+
---
74+
user_collection:
75+
- user_id: user_id_42
76+
last_name: last name 42$
77+
first_name: first name 42$
78+
order_connection:
79+
- order_id: order_id_1564
80+
description: order of user 42$
81+
- order_id: order_id_1565
82+
description: order of user 42$
83+
- order_id: order_id_1566
84+
description: order of user 42$
85+
- order_id: order_id_1567
86+
description: order of user 42$
87+
- order_id: order_id_1568
88+
description: order of user 42$
89+
- order_id: order_id_1569
90+
description: order of user 42$
91+
- order_id: order_id_1570
92+
description: order of user 42$
93+
- order_id: order_id_1571
94+
description: order of user 42$
95+
- order_id: order_id_1572
96+
description: order of user 42$
97+
- order_id: order_id_1573
98+
description: order of user 42$
99+
- order_id: order_id_1574
100+
description: order of user 42$
101+
- order_id: order_id_1575
102+
description: order of user 42$
103+
- order_id: order_id_1576
104+
description: order of user 42$
105+
- order_id: order_id_1577
106+
description: order of user 42$
107+
- order_id: order_id_1578
108+
description: order of user 42$
109+
- order_id: order_id_1579
110+
description: order of user 42$
111+
- order_id: order_id_1580
112+
description: order of user 42$
113+
- order_id: order_id_1581
114+
description: order of user 42$
115+
- order_id: order_id_1582
116+
description: order of user 42$
117+
- order_id: order_id_1583
118+
description: order of user 42$
119+
- order_id: order_id_1584
120+
description: order of user 42$
121+
- order_id: order_id_1585
122+
description: order of user 42$
123+
- order_id: order_id_1586
124+
description: order of user 42$
125+
- order_id: order_id_1587
126+
description: order of user 42$
127+
- order_id: order_id_1588
128+
description: order of user 42$
129+
- order_id: order_id_1589
130+
description: order of user 42$
131+
- order_id: order_id_1590
132+
description: order of user 42$
133+
- order_id: order_id_1591
134+
description: order of user 42$
135+
- order_id: order_id_1592
136+
description: order of user 42$
137+
- order_id: order_id_1593
138+
description: order of user 42$
139+
- order_id: order_id_1594
140+
description: order of user 42$
141+
- order_id: order_id_1595
142+
description: order of user 42$
143+
- order_id: order_id_1596
144+
description: order of user 42$
145+
- order_id: order_id_1597
146+
description: order of user 42$
147+
- order_id: order_id_1598
148+
description: order of user 42$
149+
- order_id: order_id_1599
150+
description: order of user 42$
151+
- order_id: order_id_1600
152+
description: order of user 42$
153+
- order_id: order_id_1601
154+
description: order of user 42$
155+
- order_id: order_id_1602
156+
description: order of user 42$
157+
- order_id: order_id_1603
158+
description: order of user 42$
159+
...
160+
161+
RESULT
162+
---
163+
user_collection:
164+
- user_id: user_id_54
165+
last_name: last name 54$
166+
first_name: first name 54$
167+
- user_id: user_id_55
168+
last_name: last name 55$
169+
first_name: first name 55$
170+
- user_id: user_id_56
171+
last_name: last name 56$
172+
first_name: first name 56$
173+
- user_id: user_id_57
174+
last_name: last name 57$
175+
first_name: first name 57$
176+
- user_id: user_id_58
177+
last_name: last name 58$
178+
first_name: first name 58$
179+
- user_id: user_id_59
180+
last_name: last name 59$
181+
first_name: first name 59$
182+
- user_id: user_id_6
183+
last_name: last name 6$
184+
first_name: first name 6$
185+
- user_id: user_id_60
186+
last_name: last name 60$
187+
first_name: first name 60$
188+
- user_id: user_id_61
189+
last_name: last name 61$
190+
first_name: first name 61$
191+
- user_id: user_id_62
192+
last_name: last name 62$
193+
first_name: first name 62$
194+
...
195+
196+
RESULT
197+
---
198+
user_collection: []
199+
...
200+
201+
RESULT
202+
---
203+
user_collection: []
204+
...
205+
206+
RESULT
207+
---
208+
order_collection: []
209+
...
210+

test/local/unflatten_tuple.test.lua

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/usr/bin/env tarantool
2+
3+
local fio = require('fio')
4+
5+
-- require in-repo version of graphql/ sources despite current working directory
6+
package.path = fio.abspath(debug.getinfo(1).source:match("@?(.*/)")
7+
:gsub('/./', '/'):gsub('/+$', '')) .. '/../../?.lua' .. ';' ..
8+
package.path
9+
10+
local avro = require('avro_schema')
11+
local graphql = require('graphql')
12+
local testdata = require('test.testdata.common_testdata')
13+
14+
-- init box, upload test data and acquire metadata
15+
-- -----------------------------------------------
16+
17+
-- init box and data schema
18+
box.cfg{background = false}
19+
testdata.init_spaces()
20+
21+
-- upload test data
22+
testdata.fill_test_data()
23+
24+
-- acquire metadata
25+
local metadata = testdata.get_test_metadata()
26+
local schemas = metadata.schemas
27+
local collections = metadata.collections
28+
local service_fields = metadata.service_fields
29+
local indexes = metadata.indexes
30+
31+
-- build accessor and graphql schemas
32+
-- ----------------------------------
33+
34+
local accessor = graphql.accessor_space.new({
35+
schemas = schemas,
36+
collections = collections,
37+
service_fields = service_fields,
38+
indexes = indexes,
39+
})
40+
41+
local ok, handle = avro.create(schemas.user)
42+
assert(ok, 'avro schema create: ' .. tostring(handle))
43+
local ok, model = avro.compile({handle, service_fields = {'int'}})
44+
assert(ok, 'avro schema compile: ' .. tostring(model))
45+
local user_model = model
46+
47+
local ok, handle = avro.create(schemas.order)
48+
assert(ok, 'avro schema create: ' .. tostring(handle))
49+
local ok, model = avro.compile({handle})
50+
assert(ok, 'avro schema compile: ' .. tostring(model))
51+
local order_model = model
52+
53+
accessor.funcs.unflatten_tuple = function(collection_name, tuple)
54+
if collection_name == 'user_collection' then
55+
local ok, obj = user_model.unflatten(tuple)
56+
assert(ok, 'unflatten: ' .. tostring(obj))
57+
obj.first_name = obj.first_name .. '$'
58+
obj.last_name = obj.last_name .. '$'
59+
return obj
60+
elseif collection_name == 'order_collection' then
61+
local ok, obj = order_model.unflatten(tuple)
62+
assert(ok, 'unflatten: ' .. tostring(obj))
63+
obj.description = obj.description .. '$'
64+
return obj
65+
end
66+
error('unexpected collection_name: ' .. tostring(collection_name))
67+
end
68+
69+
local gql_wrapper = graphql.new({
70+
schemas = schemas,
71+
collections = collections,
72+
accessor = accessor,
73+
})
74+
75+
-- run queries
76+
-- -----------
77+
78+
testdata.run_queries(gql_wrapper)
79+
80+
-- clean up
81+
-- --------
82+
83+
testdata.drop_spaces()
84+
85+
os.exit()

0 commit comments

Comments
 (0)