serega 0.10.0 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +319 -141
- data/VERSION +1 -1
- data/lib/serega/attribute.rb +37 -105
- data/lib/serega/attribute_normalizer.rb +176 -0
- data/lib/serega/config.rb +26 -9
- data/lib/serega/object_serializer.rb +11 -10
- data/lib/serega/plan.rb +128 -0
- data/lib/serega/plan_point.rb +94 -0
- data/lib/serega/plugins/batch/batch.rb +187 -41
- data/lib/serega/plugins/batch/lib/loader.rb +4 -4
- data/lib/serega/plugins/batch/lib/loaders.rb +3 -3
- data/lib/serega/plugins/batch/lib/plugins_extensions/activerecord_preloads.rb +2 -2
- data/lib/serega/plugins/batch/lib/plugins_extensions/formatters.rb +19 -1
- data/lib/serega/plugins/batch/lib/plugins_extensions/preloads.rb +6 -4
- data/lib/serega/plugins/batch/lib/validations/check_opt_batch.rb +9 -5
- data/lib/serega/plugins/formatters/formatters.rb +28 -31
- data/lib/serega/plugins/if/if.rb +24 -6
- data/lib/serega/plugins/preloads/lib/format_user_preloads.rb +11 -13
- data/lib/serega/plugins/preloads/lib/main_preload_path.rb +2 -2
- data/lib/serega/plugins/preloads/lib/preloads_constructor.rb +21 -15
- data/lib/serega/plugins/preloads/preloads.rb +72 -40
- data/lib/serega/plugins/presenter/presenter.rb +0 -9
- data/lib/serega/plugins/string_modifiers/parse_string_modifiers.rb +11 -1
- data/lib/serega/plugins.rb +3 -3
- data/lib/serega/utils/enum_deep_dup.rb +18 -18
- data/lib/serega/utils/enum_deep_freeze.rb +35 -0
- data/lib/serega/utils/to_hash.rb +17 -9
- data/lib/serega.rb +22 -15
- metadata +6 -6
- data/lib/serega/map.rb +0 -91
- data/lib/serega/map_point.rb +0 -66
- data/lib/serega/plugins/batch/lib/batch_option_model.rb +0 -73
- data/lib/serega/plugins/preloads/lib/enum_deep_freeze.rb +0 -26
data/lib/serega/map.rb
DELETED
@@ -1,91 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Serega
|
4
|
-
#
|
5
|
-
# Constructs map of attributes that should be serialized.
|
6
|
-
# We will traverse this map to construct serialized response.
|
7
|
-
#
|
8
|
-
class SeregaMap
|
9
|
-
#
|
10
|
-
# SeregaMap class methods
|
11
|
-
#
|
12
|
-
module ClassMethods
|
13
|
-
#
|
14
|
-
# Constructs map of attributes that should be serialized.
|
15
|
-
#
|
16
|
-
# @param opts Serialization parameters
|
17
|
-
# @option opts [Hash] :only The only attributes to serialize
|
18
|
-
# @option opts [Hash] :except Attributes to hide
|
19
|
-
# @option opts [Hash] :with Attributes (usually hidden) to serialize additionally
|
20
|
-
#
|
21
|
-
# @return [Array<Serega::SeregaMapPoint>] map
|
22
|
-
#
|
23
|
-
def call(opts)
|
24
|
-
max_cache_size = serializer_class.config.max_cached_map_per_serializer_count
|
25
|
-
return map_for(opts) if max_cache_size.zero?
|
26
|
-
|
27
|
-
cached_map_for(opts, max_cache_size)
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def map_for(opts)
|
33
|
-
construct_map(serializer_class, **modifiers(opts))
|
34
|
-
end
|
35
|
-
|
36
|
-
def cached_map_for(opts, max_cache_size)
|
37
|
-
@cache ||= {}
|
38
|
-
cache_key = construct_cache_key(opts)
|
39
|
-
|
40
|
-
map = @cache[cache_key] ||= map_for(opts)
|
41
|
-
@cache.shift if @cache.length > max_cache_size
|
42
|
-
map
|
43
|
-
end
|
44
|
-
|
45
|
-
def modifiers(opts)
|
46
|
-
{
|
47
|
-
only: opts[:only] || FROZEN_EMPTY_HASH,
|
48
|
-
except: opts[:except] || FROZEN_EMPTY_HASH,
|
49
|
-
with: opts[:with] || FROZEN_EMPTY_HASH
|
50
|
-
}
|
51
|
-
end
|
52
|
-
|
53
|
-
def construct_map(serializer_class, only:, except:, with:)
|
54
|
-
map = []
|
55
|
-
serializer_class.attributes.each do |name, attribute|
|
56
|
-
next unless attribute.visible?(only: only, except: except, with: with)
|
57
|
-
|
58
|
-
nested_points =
|
59
|
-
if attribute.relation?
|
60
|
-
construct_map(
|
61
|
-
attribute.serializer,
|
62
|
-
only: only[name] || FROZEN_EMPTY_HASH,
|
63
|
-
with: with[name] || FROZEN_EMPTY_HASH,
|
64
|
-
except: except[name] || FROZEN_EMPTY_HASH
|
65
|
-
)
|
66
|
-
end
|
67
|
-
|
68
|
-
map << serializer_class::SeregaMapPoint.new(attribute, nested_points)
|
69
|
-
end
|
70
|
-
map
|
71
|
-
end
|
72
|
-
|
73
|
-
def construct_cache_key(opts, cache_key = nil)
|
74
|
-
return nil if opts.empty?
|
75
|
-
|
76
|
-
cache_key ||= +""
|
77
|
-
|
78
|
-
opts.each do |key, nested_opts|
|
79
|
-
cache_key.insert(-1, SeregaUtils::SymbolName.call(key))
|
80
|
-
cache_key.insert(-1, "-")
|
81
|
-
construct_cache_key(nested_opts, cache_key)
|
82
|
-
end
|
83
|
-
|
84
|
-
cache_key
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
extend ClassMethods
|
89
|
-
extend Serega::SeregaHelpers::SerializerClassHelper
|
90
|
-
end
|
91
|
-
end
|
data/lib/serega/map_point.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Serega
|
4
|
-
#
|
5
|
-
# Combines attribute and nested attributes
|
6
|
-
#
|
7
|
-
class SeregaMapPoint
|
8
|
-
#
|
9
|
-
# SeregaMapPoint instance methods
|
10
|
-
#
|
11
|
-
module InstanceMethods
|
12
|
-
extend Forwardable
|
13
|
-
|
14
|
-
# Shows current attribute
|
15
|
-
# @return [Serega::SeregaAttribute] Current attribute
|
16
|
-
attr_reader :attribute
|
17
|
-
|
18
|
-
# Shows nested points
|
19
|
-
# @return [NilClass, Array<Serega::SeregaMapPoint>] Nested points or nil
|
20
|
-
attr_reader :nested_points
|
21
|
-
|
22
|
-
# @!method name
|
23
|
-
# Attribute `name`
|
24
|
-
# @see Serega::SeregaAttribute::AttributeInstanceMethods#name
|
25
|
-
# @!method value
|
26
|
-
# Attribute `value` block
|
27
|
-
# @see Serega::SeregaAttribute::AttributeInstanceMethods#value
|
28
|
-
# @!method many
|
29
|
-
# Attribute `many` option
|
30
|
-
# @see Serega::SeregaAttribute::AttributeInstanceMethods#many
|
31
|
-
def_delegators :@attribute, :name, :value, :many
|
32
|
-
|
33
|
-
#
|
34
|
-
# Initializes map point
|
35
|
-
#
|
36
|
-
# @param attribute [Serega::SeregaAttribute] Attribute to construct map point
|
37
|
-
# @param nested_points [NilClass, Array<Serega::SeregaMapPoint>] Nested map points for provided attribute
|
38
|
-
#
|
39
|
-
# @return [Serega::SeregaMapPoint] New map point
|
40
|
-
#
|
41
|
-
def initialize(attribute, nested_points)
|
42
|
-
@attribute = attribute
|
43
|
-
@nested_points = nested_points
|
44
|
-
end
|
45
|
-
|
46
|
-
#
|
47
|
-
# Checks if attribute has nested points (is a link to another serializer)
|
48
|
-
#
|
49
|
-
# @return [Boolean] whether attribute has nested points
|
50
|
-
#
|
51
|
-
def has_nested_points?
|
52
|
-
!nested_points.nil?
|
53
|
-
end
|
54
|
-
|
55
|
-
#
|
56
|
-
# @return [Serega::SeregaObjectSerializer] object serializer for nested points
|
57
|
-
#
|
58
|
-
def nested_object_serializer
|
59
|
-
attribute.serializer::SeregaObjectSerializer
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
extend Serega::SeregaHelpers::SerializerClassHelper
|
64
|
-
include InstanceMethods
|
65
|
-
end
|
66
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Serega
|
4
|
-
module SeregaPlugins
|
5
|
-
module Batch
|
6
|
-
#
|
7
|
-
# Combines options and methods needed to load batch for specific attribute
|
8
|
-
#
|
9
|
-
class BatchOptionModel
|
10
|
-
attr_reader :attribute, :opts, :loaders, :many
|
11
|
-
|
12
|
-
#
|
13
|
-
# Initializes BatchOptionModel
|
14
|
-
#
|
15
|
-
# @param map_point [Serega::SeregaMapPoint] Map point for attribute with :batch option
|
16
|
-
# @param loaders [Array] Array of all loaders defined in serialize class
|
17
|
-
# @param many [Boolean] Option :many, defined on attribute
|
18
|
-
#
|
19
|
-
# @return [void]
|
20
|
-
def initialize(attribute)
|
21
|
-
@attribute = attribute
|
22
|
-
@opts = attribute.batch
|
23
|
-
@loaders = attribute.class.serializer_class.config.batch_loaders
|
24
|
-
@many = attribute.many
|
25
|
-
end
|
26
|
-
|
27
|
-
# Returns proc that will be used to batch load registered keys values
|
28
|
-
# @return [#call] batch loader
|
29
|
-
def loader
|
30
|
-
@batch_loader ||= begin
|
31
|
-
loader = opts[:loader]
|
32
|
-
loader = loaders.fetch(loader) if loader.is_a?(Symbol)
|
33
|
-
loader
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
# Returns proc that will be used to find batch_key for current attribute.
|
38
|
-
# @return [Object] key (uid) of batch loaded object
|
39
|
-
def key
|
40
|
-
@batch_key ||= begin
|
41
|
-
key = opts[:key]
|
42
|
-
|
43
|
-
if key.is_a?(Symbol)
|
44
|
-
proc do |object|
|
45
|
-
handle_no_method_error { object.public_send(key) }
|
46
|
-
end
|
47
|
-
else
|
48
|
-
key
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# Returns default value to use if batch loader does not return value for some key
|
54
|
-
# @return [Object] default value for missing key
|
55
|
-
def default_value
|
56
|
-
if opts.key?(:default)
|
57
|
-
opts[:default]
|
58
|
-
elsif many
|
59
|
-
FROZEN_EMPTY_ARRAY
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
private
|
64
|
-
|
65
|
-
def handle_no_method_error
|
66
|
-
yield
|
67
|
-
rescue NoMethodError => error
|
68
|
-
raise error, "NoMethodError when serializing '#{attribute.name}' attribute in #{attribute.class.serializer_class}\n\n#{error.message}", error.backtrace
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Serega
|
4
|
-
module SeregaPlugins
|
5
|
-
module Preloads
|
6
|
-
#
|
7
|
-
# Utility to freeze nested hashes and arrays
|
8
|
-
#
|
9
|
-
class EnumDeepFreeze
|
10
|
-
class << self
|
11
|
-
#
|
12
|
-
# Freezes nested enumerable data
|
13
|
-
#
|
14
|
-
# @param data[Hash, Array] data to freeze
|
15
|
-
#
|
16
|
-
# @return [Hash, Array] same deeply frozen data
|
17
|
-
#
|
18
|
-
def call(data)
|
19
|
-
data.each_entry { |entry| call(entry) } if data.is_a?(Enumerable)
|
20
|
-
data.freeze
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|