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
581
- end
582
-
583
- local model = opts .model
584
577
local limit = opts .limit
585
578
local filter = opts .filter
586
579
local do_filter = opts .do_filter
@@ -594,18 +587,19 @@ local function process_tuple(state, tuple, opts)
594
587
' (`fetched_object_cnt_max` in accessor)' ):format (
595
588
qstats .fetched_object_cnt , fetched_object_cnt_max ))
596
589
590
+ -- convert tuple -> object
591
+ local obj = opts .unflatten_tuple (opts .collection_name , tuple ,
592
+ opts .default_unflatten_tuple )
593
+
597
594
-- skip all items before pivot (the item pointed by offset)
598
- local obj = nil
599
595
if not state .pivot_found and pivot_filter then
600
- obj = maybe_unflatten (model , tuple , obj )
601
596
local match = utils .is_subtable (obj , pivot_filter )
602
597
if not match then return true end
603
598
state .pivot_found = true
604
599
return true -- skip pivot item too
605
600
end
606
601
607
- -- convert tuple -> object, then filter out or continue
608
- obj = maybe_unflatten (model , tuple , obj )
602
+ -- filter out non-matching objects
609
603
local match = utils .is_subtable (obj , filter )
610
604
if do_filter then
611
605
if not match then return true end
@@ -698,13 +692,13 @@ local function select_internal(self, collection_name, from, filter, args, extra)
698
692
index_name , collection_name ))
699
693
end
700
694
701
- -- lookup compiled schema for unflattening (model)
695
+ -- lookup functions for unflattening
702
696
local schema_name = collection .schema_name
703
697
assert (type (schema_name ) == ' string' ,
704
698
' 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 (
699
+ local default_unflatten_tuple = self .default_unflatten_tuple [schema_name ]
700
+ assert (default_unflatten_tuple ~= nil ,
701
+ (' cannot find default_unflatten_tuple for collection "%s"' ):format (
708
702
collection_name ))
709
703
710
704
-- read-write variables for process_tuple
@@ -717,13 +711,15 @@ local function select_internal(self, collection_name, from, filter, args, extra)
717
711
718
712
-- read only process_tuple options
719
713
local select_opts = {
720
- model = model ,
721
714
limit = args .limit ,
722
715
filter = filter ,
723
716
do_filter = not full_match ,
724
717
pivot_filter = nil , -- filled later if needed
725
718
resulting_object_cnt_max = self .settings .resulting_object_cnt_max ,
726
- fetched_object_cnt_max = self .settings .fetched_object_cnt_max
719
+ fetched_object_cnt_max = self .settings .fetched_object_cnt_max ,
720
+ collection_name = collection_name ,
721
+ unflatten_tuple = self .funcs .unflatten_tuple ,
722
+ default_unflatten_tuple = default_unflatten_tuple ,
727
723
}
728
724
729
725
if index == nil then
@@ -803,6 +799,9 @@ local function validate_funcs(funcs)
803
799
assert (type (funcs .get_primary_index ) == ' function' ,
804
800
' funcs.get_primary_index must be a function, got ' ..
805
801
type (funcs .get_primary_index ))
802
+ assert (type (funcs .unflatten_tuple ) == ' function' ,
803
+ ' funcs.unflatten_tuple must be a function, got ' ..
804
+ type (funcs .unflatten_tuple ))
806
805
end
807
806
808
807
--- Create a new data accessor.
@@ -818,10 +817,10 @@ end
818
817
--- value is 10,000)_
819
818
---
820
819
--- @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
820
+ --- `get_primary_index`, `unflatten_tuple` ) allows this abstract data accessor
821
+ --- behaves in the certain way (say, like space data accessor or shard data
822
+ --- accessor); consider the `accessor_space` and the `accessor_shard` modules
823
+ --- documentation for this functions description
825
824
---
826
825
--- For examples of `opts.schemas` and `opts.collections` consider the
827
826
--- @{tarantool_graphql.new} function description.
@@ -885,6 +884,19 @@ function accessor_general.new(opts, funcs)
885
884
validate_collections (collections , schemas , indexes )
886
885
local index_cache = build_index_cache (indexes , collections )
887
886
887
+ -- create default unflatten functions, that can be called from
888
+ -- funcs.unflatten_tuple when an additional pre/postprocessing is not
889
+ -- needed
890
+ local default_unflatten_tuple = {}
891
+ for schema_name , model in pairs (models ) do
892
+ default_unflatten_tuple [schema_name ] =
893
+ function (_ , tuple )
894
+ local ok , obj = model .unflatten (tuple )
895
+ assert (ok , ' cannot unflat tuple: ' .. tostring (obj ))
896
+ return obj
897
+ end
898
+ end
899
+
888
900
validate_funcs (funcs )
889
901
890
902
return setmetatable ({
@@ -893,6 +905,7 @@ function accessor_general.new(opts, funcs)
893
905
service_fields = service_fields ,
894
906
indexes = indexes ,
895
907
models = models ,
908
+ default_unflatten_tuple = default_unflatten_tuple ,
896
909
index_cache = index_cache ,
897
910
funcs = funcs ,
898
911
settings = {
0 commit comments