serega 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +319 -141
  3. data/VERSION +1 -1
  4. data/lib/serega/attribute.rb +37 -105
  5. data/lib/serega/attribute_normalizer.rb +176 -0
  6. data/lib/serega/config.rb +26 -9
  7. data/lib/serega/object_serializer.rb +11 -10
  8. data/lib/serega/plan.rb +128 -0
  9. data/lib/serega/plan_point.rb +94 -0
  10. data/lib/serega/plugins/batch/batch.rb +187 -41
  11. data/lib/serega/plugins/batch/lib/loader.rb +4 -4
  12. data/lib/serega/plugins/batch/lib/loaders.rb +3 -3
  13. data/lib/serega/plugins/batch/lib/plugins_extensions/activerecord_preloads.rb +2 -2
  14. data/lib/serega/plugins/batch/lib/plugins_extensions/formatters.rb +19 -1
  15. data/lib/serega/plugins/batch/lib/plugins_extensions/preloads.rb +6 -4
  16. data/lib/serega/plugins/batch/lib/validations/check_opt_batch.rb +9 -5
  17. data/lib/serega/plugins/formatters/formatters.rb +28 -31
  18. data/lib/serega/plugins/if/if.rb +24 -6
  19. data/lib/serega/plugins/preloads/lib/format_user_preloads.rb +11 -13
  20. data/lib/serega/plugins/preloads/lib/main_preload_path.rb +2 -2
  21. data/lib/serega/plugins/preloads/lib/preloads_constructor.rb +21 -15
  22. data/lib/serega/plugins/preloads/preloads.rb +72 -40
  23. data/lib/serega/plugins/presenter/presenter.rb +0 -9
  24. data/lib/serega/plugins/string_modifiers/parse_string_modifiers.rb +11 -1
  25. data/lib/serega/plugins.rb +3 -3
  26. data/lib/serega/utils/enum_deep_dup.rb +18 -18
  27. data/lib/serega/utils/enum_deep_freeze.rb +35 -0
  28. data/lib/serega/utils/to_hash.rb +17 -9
  29. data/lib/serega.rb +22 -15
  30. metadata +6 -6
  31. data/lib/serega/map.rb +0 -91
  32. data/lib/serega/map_point.rb +0 -66
  33. data/lib/serega/plugins/batch/lib/batch_option_model.rb +0 -73
  34. 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
@@ -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