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

Commit 9d6cb6f

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

File tree

6 files changed

+359
-18
lines changed

6 files changed

+359
-18
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: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -574,13 +574,12 @@ 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)
578-
local ok, obj = model.unflatten(tuple)
579-
assert(ok, 'cannot unflat tuple: ' .. tostring(obj))
580-
return obj
577+
local function maybe_unflatten(tuple, obj, opts)
578+
if obj ~= nil then return obj end
579+
local default = opts.default_unflatten_tuple
580+
return opts.unflatten_tuple(opts.collection_name, tuple, default)
581581
end
582582

583-
local model = opts.model
584583
local limit = opts.limit
585584
local filter = opts.filter
586585
local do_filter = opts.do_filter
@@ -597,15 +596,15 @@ local function process_tuple(state, tuple, opts)
597596
-- skip all items before pivot (the item pointed by offset)
598597
local obj = nil
599598
if not state.pivot_found and pivot_filter then
600-
obj = maybe_unflatten(model, tuple, obj)
599+
obj = maybe_unflatten(tuple, obj, opts)
601600
local match = utils.is_subtable(obj, pivot_filter)
602601
if not match then return true end
603602
state.pivot_found = true
604603
return true -- skip pivot item too
605604
end
606605

607606
-- convert tuple -> object, then filter out or continue
608-
obj = maybe_unflatten(model, tuple, obj)
607+
obj = maybe_unflatten(tuple, obj, opts)
609608
local match = utils.is_subtable(obj, filter)
610609
if do_filter then
611610
if not match then return true end
@@ -698,13 +697,13 @@ local function select_internal(self, collection_name, from, filter, args, extra)
698697
index_name, collection_name))
699698
end
700699

701-
-- lookup compiled schema for unflattening (model)
700+
-- lookup functions for unflattening
702701
local schema_name = collection.schema_name
703702
assert(type(schema_name) == 'string',
704703
'schema_name must be a string, got ' .. type(schema_name))
705-
local model = self.models[schema_name]
706-
assert(model ~= nil,
707-
('cannot find model for collection "%s"'):format(
704+
local default_unflatten_tuple = self.default_unflatten_tuple[schema_name]
705+
assert(default_unflatten_tuple ~= nil,
706+
('cannot find default_unflatten_tuple for collection "%s"'):format(
708707
collection_name))
709708

710709
-- read-write variables for process_tuple
@@ -717,13 +716,15 @@ local function select_internal(self, collection_name, from, filter, args, extra)
717716

718717
-- read only process_tuple options
719718
local select_opts = {
720-
model = model,
721719
limit = args.limit,
722720
filter = filter,
723721
do_filter = not full_match,
724722
pivot_filter = nil, -- filled later if needed
725723
resulting_object_cnt_max = self.settings.resulting_object_cnt_max,
726-
fetched_object_cnt_max = self.settings.fetched_object_cnt_max
724+
fetched_object_cnt_max = self.settings.fetched_object_cnt_max,
725+
collection_name = collection_name,
726+
unflatten_tuple = self.funcs.unflatten_tuple,
727+
default_unflatten_tuple = default_unflatten_tuple,
727728
}
728729

729730
if index == nil then
@@ -803,6 +804,9 @@ local function validate_funcs(funcs)
803804
assert(type(funcs.get_primary_index) == 'function',
804805
'funcs.get_primary_index must be a function, got ' ..
805806
type(funcs.get_primary_index))
807+
assert(type(funcs.unflatten_tuple) == 'function',
808+
'funcs.unflatten_tuple must be a function, got ' ..
809+
type(funcs.unflatten_tuple))
806810
end
807811

808812
--- Create a new data accessor.
@@ -818,10 +822,10 @@ end
818822
--- value is 10,000)_
819823
---
820824
--- @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
825+
--- `get_primary_index`, `unflatten_tuple`) allows this abstract data accessor
826+
--- behaves in the certain way (say, like space data accessor or shard data
827+
--- accessor); consider the `accessor_space` and the `accessor_shard` modules
828+
--- documentation for this functions description
825829
---
826830
--- For examples of `opts.schemas` and `opts.collections` consider the
827831
--- @{tarantool_graphql.new} function description.
@@ -885,6 +889,19 @@ function accessor_general.new(opts, funcs)
885889
validate_collections(collections, schemas, indexes)
886890
local index_cache = build_index_cache(indexes, collections)
887891

892+
-- create default unflatten functions, that can be called from
893+
-- funcs.unflatten_tuple when an additional pre/postprocessing is not
894+
-- needed
895+
local default_unflatten_tuple = {}
896+
for schema_name, model in pairs(models) do
897+
default_unflatten_tuple[schema_name] =
898+
function(_, tuple)
899+
local ok, obj = model.unflatten(tuple)
900+
assert(ok, 'cannot unflat tuple: ' .. tostring(obj))
901+
return obj
902+
end
903+
end
904+
888905
validate_funcs(funcs)
889906

890907
return setmetatable({
@@ -893,6 +910,7 @@ function accessor_general.new(opts, funcs)
893910
service_fields = service_fields,
894911
indexes = indexes,
895912
models = models,
913+
default_unflatten_tuple = default_unflatten_tuple,
896914
index_cache = index_cache,
897915
funcs = funcs,
898916
settings = {

graphql/accessor_shard.lua

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,26 @@ local function get_primary_index(collection_name)
8080
return get_index(collection_name, 0)
8181
end
8282

83+
--- Convert a tuple to an object.
84+
---
85+
--- @tparam string collection_name
86+
--- @tparam cdata/table tuple
87+
--- @tparam function default unflatten action, call it in the following way:
88+
---
89+
--- ```
90+
--- return default(collection_name, tuple)
91+
--- ```
92+
local function unflatten_tuple(collection_name, tuple, default)
93+
return default(collection_name, tuple)
94+
end
95+
8396
--- Create a new shard data accessor instance.
8497
function accessor_shard.new(opts)
8598
local funcs = {
8699
is_collection_exists = is_collection_exists,
87100
get_index = get_index,
88101
get_primary_index = get_primary_index,
102+
unflatten_tuple = unflatten_tuple,
89103
}
90104
return accessor_general.new(opts, funcs)
91105
end

graphql/accessor_space.lua

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,26 @@ local function get_primary_index(collection_name)
2222
return box.space[collection_name].index[0]
2323
end
2424

25+
--- Convert a tuple to an object.
26+
---
27+
--- @tparam string collection_name
28+
--- @tparam cdata/table tuple
29+
--- @tparam function default unflatten action, call it in the following way:
30+
---
31+
--- ```
32+
--- return default(collection_name, tuple)
33+
--- ```
34+
local function unflatten_tuple(collection_name, tuple, default)
35+
return default(collection_name, tuple)
36+
end
37+
2538
--- Create a new space data accessor instance.
2639
function accessor_space.new(opts)
2740
local funcs = {
2841
is_collection_exists = is_collection_exists,
2942
get_index = get_index,
3043
get_primary_index = get_primary_index,
44+
unflatten_tuple = unflatten_tuple,
3145
}
3246
return accessor_general.new(opts, funcs)
3347
end

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+

0 commit comments

Comments
 (0)