@@ -574,13 +574,12 @@ end
574
574
--- Nothing returned, but after necessary count of invokes `state.objs` will
575
575
--- hold list of resulting objects.
576
576
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 )
581
581
end
582
582
583
- local model = opts .model
584
583
local limit = opts .limit
585
584
local filter = opts .filter
586
585
local do_filter = opts .do_filter
@@ -597,15 +596,15 @@ local function process_tuple(state, tuple, opts)
597
596
-- skip all items before pivot (the item pointed by offset)
598
597
local obj = nil
599
598
if not state .pivot_found and pivot_filter then
600
- obj = maybe_unflatten (model , tuple , obj )
599
+ obj = maybe_unflatten (tuple , obj , opts )
601
600
local match = utils .is_subtable (obj , pivot_filter )
602
601
if not match then return true end
603
602
state .pivot_found = true
604
603
return true -- skip pivot item too
605
604
end
606
605
607
606
-- convert tuple -> object, then filter out or continue
608
- obj = maybe_unflatten (model , tuple , obj )
607
+ obj = maybe_unflatten (tuple , obj , opts )
609
608
local match = utils .is_subtable (obj , filter )
610
609
if do_filter then
611
610
if not match then return true end
@@ -698,13 +697,13 @@ local function select_internal(self, collection_name, from, filter, args, extra)
698
697
index_name , collection_name ))
699
698
end
700
699
701
- -- lookup compiled schema for unflattening (model)
700
+ -- lookup functions for unflattening
702
701
local schema_name = collection .schema_name
703
702
assert (type (schema_name ) == ' string' ,
704
703
' 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 (
708
707
collection_name ))
709
708
710
709
-- read-write variables for process_tuple
@@ -717,13 +716,15 @@ local function select_internal(self, collection_name, from, filter, args, extra)
717
716
718
717
-- read only process_tuple options
719
718
local select_opts = {
720
- model = model ,
721
719
limit = args .limit ,
722
720
filter = filter ,
723
721
do_filter = not full_match ,
724
722
pivot_filter = nil , -- filled later if needed
725
723
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 ,
727
728
}
728
729
729
730
if index == nil then
@@ -803,6 +804,9 @@ local function validate_funcs(funcs)
803
804
assert (type (funcs .get_primary_index ) == ' function' ,
804
805
' funcs.get_primary_index must be a function, got ' ..
805
806
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 ))
806
810
end
807
811
808
812
--- Create a new data accessor.
@@ -818,10 +822,10 @@ end
818
822
--- value is 10,000)_
819
823
---
820
824
--- @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
825
829
---
826
830
--- For examples of `opts.schemas` and `opts.collections` consider the
827
831
--- @{tarantool_graphql.new} function description.
@@ -885,6 +889,19 @@ function accessor_general.new(opts, funcs)
885
889
validate_collections (collections , schemas , indexes )
886
890
local index_cache = build_index_cache (indexes , collections )
887
891
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
+
888
905
validate_funcs (funcs )
889
906
890
907
return setmetatable ({
@@ -893,6 +910,7 @@ function accessor_general.new(opts, funcs)
893
910
service_fields = service_fields ,
894
911
indexes = indexes ,
895
912
models = models ,
913
+ default_unflatten_tuple = default_unflatten_tuple ,
896
914
index_cache = index_cache ,
897
915
funcs = funcs ,
898
916
settings = {
0 commit comments