n1_loader 1.7.0 → 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -1
- data/lib/n1_loader/active_record/associations_preloader_v5.rb +4 -4
- data/lib/n1_loader/active_record/associations_preloader_v6.rb +4 -4
- data/lib/n1_loader/active_record/associations_preloader_v7.rb +4 -4
- data/lib/n1_loader/ar_lazy_preload/loadable.rb +5 -14
- data/lib/n1_loader/ar_lazy_preload.rb +1 -1
- data/lib/n1_loader/core/loadable.rb +16 -59
- data/lib/n1_loader/core/loader.rb +8 -5
- data/lib/n1_loader/core/loader_builder.rb +16 -0
- data/lib/n1_loader/core/preloader.rb +5 -8
- data/lib/n1_loader/version.rb +1 -1
- data/lib/n1_loader.rb +1 -1
- metadata +3 -3
- data/lib/n1_loader/core/name.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 61980f2b94429810da38a914db9e3779385a86cf0fbe95773311b19a2551c5a3
|
4
|
+
data.tar.gz: 8817ef5434d16ba5eb13deec0a78110fae07b9def1256e6b1d163deb02ed5a05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b78afcfdc23c584456a3e5daef5c8f18f102bafffffbb06640275afdd9ee2e65368384d29d2dd77f0a5c991a4c281d808086bc1648da38a304eac743b3265fcd
|
7
|
+
data.tar.gz: 26795d6614b90f868a6aaec760180e0270a4726c5ce0e1f88fc04b97cfc751a8627a8d94efc27d2443d82cc145207759b595afe3383a4f8a38cacc8af75d4b3f
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,12 @@
|
|
1
|
-
## [1.
|
1
|
+
## [1.7.2] - 2023/08/04
|
2
|
+
|
3
|
+
- Refactor core that ended up with speed boost.
|
4
|
+
|
5
|
+
## [1.7.1] - 2023/07/30
|
6
|
+
|
7
|
+
- Fix interface discrepancy for `N1LoaderReflection`. Thanks [Denis Talakevich](https://github.com/senid231) for suggesting it!
|
8
|
+
|
9
|
+
## [1.7.0] - 2023/07/30
|
2
10
|
|
3
11
|
Extend the flexibility of loading data comparison. Thanks [Nazar Matus](https://github.com/FunkyloverOne) for suggesting it!
|
4
12
|
|
@@ -4,7 +4,7 @@ module N1Loader
|
|
4
4
|
module ActiveRecord
|
5
5
|
module Associations
|
6
6
|
module Preloader # :nodoc:
|
7
|
-
N1LoaderReflection = Struct.new(:
|
7
|
+
N1LoaderReflection = Struct.new(:name, :loader) do
|
8
8
|
def options
|
9
9
|
{}
|
10
10
|
end
|
@@ -12,7 +12,7 @@ module N1Loader
|
|
12
12
|
|
13
13
|
def preloaders_for_one(association, records, scope)
|
14
14
|
grouped_records(association, records).flat_map do |reflection, klasses|
|
15
|
-
next N1Loader::Preloader.new(records).preload(reflection.
|
15
|
+
next N1Loader::Preloader.new(records).preload(reflection.name) if reflection.is_a?(N1LoaderReflection)
|
16
16
|
|
17
17
|
klasses.map do |rhs_klass, rs|
|
18
18
|
loader = preloader_for(reflection, rs).new(rhs_klass, rs, reflection, scope)
|
@@ -24,11 +24,11 @@ module N1Loader
|
|
24
24
|
|
25
25
|
def grouped_records(association, records)
|
26
26
|
n1_load_records, records = records.partition do |record|
|
27
|
-
record.class.respond_to?(:
|
27
|
+
record.class.respond_to?(:n1_loaders) && record.class.n1_loaders.key?(association)
|
28
28
|
end
|
29
29
|
|
30
30
|
hash = n1_load_records.group_by do |record|
|
31
|
-
N1LoaderReflection.new(association, record.class.
|
31
|
+
N1LoaderReflection.new(association, record.class.n1_loaders[association])
|
32
32
|
end
|
33
33
|
|
34
34
|
hash.merge(super)
|
@@ -4,7 +4,7 @@ module N1Loader
|
|
4
4
|
module ActiveRecord
|
5
5
|
module Associations
|
6
6
|
module Preloader # :nodoc:
|
7
|
-
N1LoaderReflection = Struct.new(:
|
7
|
+
N1LoaderReflection = Struct.new(:name, :loader) do
|
8
8
|
def options
|
9
9
|
{}
|
10
10
|
end
|
@@ -13,16 +13,16 @@ module N1Loader
|
|
13
13
|
def preloaders_for_reflection(reflection, records, scope)
|
14
14
|
return super unless reflection.is_a?(N1LoaderReflection)
|
15
15
|
|
16
|
-
N1Loader::Preloader.new(records).preload(reflection.
|
16
|
+
N1Loader::Preloader.new(records).preload(reflection.name)
|
17
17
|
end
|
18
18
|
|
19
19
|
def grouped_records(association, records, polymorphic_parent)
|
20
20
|
n1_load_records, records = records.partition do |record|
|
21
|
-
record.class.respond_to?(:
|
21
|
+
record.class.respond_to?(:n1_loaders) && record.class.n1_loaders[association]
|
22
22
|
end
|
23
23
|
|
24
24
|
hash = n1_load_records.group_by do |record|
|
25
|
-
N1LoaderReflection.new(association, record.class.
|
25
|
+
N1LoaderReflection.new(association, record.class.n1_loaders[association])
|
26
26
|
end
|
27
27
|
|
28
28
|
hash.merge(super)
|
@@ -4,7 +4,7 @@ module N1Loader
|
|
4
4
|
module ActiveRecord
|
5
5
|
module Associations
|
6
6
|
module Preloader # :nodoc:
|
7
|
-
N1LoaderReflection = Struct.new(:
|
7
|
+
N1LoaderReflection = Struct.new(:name, :loader) do
|
8
8
|
def options
|
9
9
|
{}
|
10
10
|
end
|
@@ -13,16 +13,16 @@ module N1Loader
|
|
13
13
|
def preloaders_for_reflection(reflection, records)
|
14
14
|
return super unless reflection.is_a?(N1LoaderReflection)
|
15
15
|
|
16
|
-
N1Loader::Preloader.new(records).preload(reflection.
|
16
|
+
N1Loader::Preloader.new(records).preload(reflection.name)
|
17
17
|
end
|
18
18
|
|
19
19
|
def grouped_records # rubocop:disable Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/AbcSize
|
20
20
|
n1_load_records, records = source_records.partition do |record|
|
21
|
-
record.class.respond_to?(:
|
21
|
+
record.class.respond_to?(:n1_loaders) && record.class.n1_loaders[association]
|
22
22
|
end
|
23
23
|
|
24
24
|
h = n1_load_records.group_by do |record|
|
25
|
-
N1LoaderReflection.new(association, record.class.
|
25
|
+
N1LoaderReflection.new(association, record.class.n1_loaders[association])
|
26
26
|
end
|
27
27
|
|
28
28
|
polymorphic_parent = !root? && parent.polymorphic?
|
@@ -2,22 +2,13 @@
|
|
2
2
|
|
3
3
|
module N1Loader
|
4
4
|
module ArLazyPreload
|
5
|
-
module Loadable
|
6
|
-
|
7
|
-
|
8
|
-
name, loader_name, loader_variable_name = super
|
5
|
+
module Loadable # :nodoc:
|
6
|
+
def n1_loader(name)
|
7
|
+
return n1_loaders[name] if n1_loaders[name]
|
9
8
|
|
10
|
-
|
11
|
-
loader = instance_variable_get(loader_variable_name)
|
12
|
-
return loader if loader
|
9
|
+
ContextAdapter.new(lazy_preload_context).try_preload_lazily(name) if respond_to?(:lazy_preload_context)
|
13
10
|
|
14
|
-
|
15
|
-
return instance_variable_get(loader_variable_name)
|
16
|
-
end
|
17
|
-
|
18
|
-
send("#{loader_name}_reload")
|
19
|
-
end
|
20
|
-
end
|
11
|
+
super
|
21
12
|
end
|
22
13
|
end
|
23
14
|
end
|
@@ -17,7 +17,7 @@ require_relative "ar_lazy_preload/loader_patch"
|
|
17
17
|
require_relative "ar_lazy_preload/loader"
|
18
18
|
require_relative "ar_lazy_preload/context"
|
19
19
|
|
20
|
-
N1Loader::Loadable
|
20
|
+
N1Loader::Loadable.prepend(N1Loader::ArLazyPreload::Loadable)
|
21
21
|
N1Loader::Preloader.prepend(N1Loader::ArLazyPreload::PreloaderPatch)
|
22
22
|
N1Loader::Loader.prepend(N1Loader::ArLazyPreload::LoaderPatch)
|
23
23
|
N1Loader::LoaderCollection.prepend(N1Loader::ArLazyPreload::LoaderCollectionPatch)
|
@@ -7,14 +7,14 @@ module N1Loader
|
|
7
7
|
# include N1Loader::Loadable
|
8
8
|
#
|
9
9
|
# # with inline loader
|
10
|
-
#
|
10
|
+
# n1_optimized :something do
|
11
11
|
# def perform(elements)
|
12
12
|
# elements.each { |element| fulfill(element, element.calculate_something) }
|
13
13
|
# end
|
14
14
|
# end
|
15
15
|
#
|
16
16
|
# # with custom loader
|
17
|
-
#
|
17
|
+
# n1_optimized :something, MyLoader
|
18
18
|
# end
|
19
19
|
#
|
20
20
|
# # custom loader
|
@@ -24,23 +24,21 @@ module N1Loader
|
|
24
24
|
# end
|
25
25
|
# end
|
26
26
|
module Loadable
|
27
|
-
|
27
|
+
def n1_loaders
|
28
|
+
@n1_loaders ||= {}
|
29
|
+
end
|
28
30
|
|
29
31
|
def n1_loader(name)
|
30
|
-
name
|
31
|
-
|
32
|
-
send("#{name}_loader")
|
32
|
+
n1_loaders[name]
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
36
|
-
name =
|
37
|
-
|
38
|
-
send("#{name}_loader=", loader_collection)
|
35
|
+
def n1_loader_reload(name)
|
36
|
+
n1_loaders[name] = LoaderCollection.new(self.class.n1_loaders[name], [self])
|
39
37
|
end
|
40
38
|
|
41
39
|
def n1_clear_cache
|
42
|
-
self.class.n1_loaders.
|
43
|
-
|
40
|
+
self.class.n1_loaders.each_key do |name|
|
41
|
+
n1_loaders[name] = nil
|
44
42
|
end
|
45
43
|
end
|
46
44
|
|
@@ -49,61 +47,20 @@ module N1Loader
|
|
49
47
|
end
|
50
48
|
|
51
49
|
module ClassMethods # :nodoc:
|
52
|
-
include Name
|
53
|
-
|
54
|
-
def n1_loader(name)
|
55
|
-
name = n1_loader_name(name)
|
56
|
-
|
57
|
-
send("#{name}_loader")
|
58
|
-
end
|
59
|
-
|
60
|
-
def n1_loader_defined?(name)
|
61
|
-
name = n1_loader_name(name)
|
62
|
-
|
63
|
-
respond_to?("#{name}_loader")
|
64
|
-
end
|
65
|
-
|
66
50
|
def n1_loaders
|
67
|
-
@n1_loaders ||= superclass.respond_to?(:n1_loaders) ? superclass.n1_loaders.dup :
|
51
|
+
@n1_loaders ||= superclass.respond_to?(:n1_loaders) ? superclass.n1_loaders.dup : {}
|
68
52
|
end
|
69
53
|
|
70
|
-
def n1_optimized(name, loader = nil, &block)
|
71
|
-
loader ||=
|
72
|
-
if block.arity == 1
|
73
|
-
define_method(:perform, &block)
|
74
|
-
else
|
75
|
-
class_eval(&block)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
loader_name = "#{n1_loader_name(name)}_loader"
|
79
|
-
loader_variable_name = "@#{loader_name}"
|
80
|
-
|
81
|
-
n1_loaders << name
|
82
|
-
|
83
|
-
define_singleton_method(loader_name) do
|
84
|
-
loader
|
85
|
-
end
|
86
|
-
|
87
|
-
define_method("#{loader_name}_reload") do
|
88
|
-
instance_variable_set(loader_variable_name,
|
89
|
-
N1Loader::LoaderCollection.new(self.class.send(loader_name), [self]))
|
90
|
-
end
|
54
|
+
def n1_optimized(name, loader = nil, &block)
|
55
|
+
loader ||= LoaderBuilder.build(&block)
|
91
56
|
|
92
|
-
|
93
|
-
instance_variable_set(loader_variable_name, loader_collection_instance)
|
94
|
-
end
|
95
|
-
|
96
|
-
define_method(loader_name) do
|
97
|
-
instance_variable_get(loader_variable_name) || send("#{loader_name}_reload")
|
98
|
-
end
|
57
|
+
n1_loaders[name] = loader
|
99
58
|
|
100
59
|
define_method(name) do |reload: false, **args|
|
101
|
-
|
60
|
+
n1_loader_reload(name) if reload || n1_loader(name).nil?
|
102
61
|
|
103
|
-
|
62
|
+
n1_loader(name).with(**args).for(self)
|
104
63
|
end
|
105
|
-
|
106
|
-
[name, loader_name, loader_variable_name]
|
107
64
|
end
|
108
65
|
end
|
109
66
|
end
|
@@ -62,11 +62,10 @@ module N1Loader
|
|
62
62
|
|
63
63
|
attr_reader :elements, :args
|
64
64
|
|
65
|
-
def check_missing_arguments!
|
65
|
+
def check_missing_arguments!
|
66
66
|
return unless (arguments = self.class.arguments)
|
67
67
|
|
68
|
-
required_arguments = arguments
|
69
|
-
.map { |argument| argument[:name] }
|
68
|
+
required_arguments = required_arguments(arguments)
|
70
69
|
|
71
70
|
return if required_arguments.all? { |argument| args.key?(argument) }
|
72
71
|
|
@@ -74,8 +73,12 @@ module N1Loader
|
|
74
73
|
|
75
74
|
list = missing_arguments.map { |argument| ":#{argument}" }.join(", ")
|
76
75
|
|
77
|
-
raise MissingArgument,
|
78
|
-
|
76
|
+
raise MissingArgument, "Loader requires [#{list}] arguments but they are missing"
|
77
|
+
end
|
78
|
+
|
79
|
+
def required_arguments(args)
|
80
|
+
args.reject { |argument| argument[:optional] }
|
81
|
+
.map { |argument| argument[:name] }
|
79
82
|
end
|
80
83
|
|
81
84
|
def check_arguments!
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module N1Loader
|
4
|
+
# The class builds {N1Loader::Loader}
|
5
|
+
class LoaderBuilder
|
6
|
+
def self.build(&block)
|
7
|
+
Class.new(N1Loader::Loader) do
|
8
|
+
if block.arity == 1
|
9
|
+
define_method(:perform, &block)
|
10
|
+
else
|
11
|
+
class_eval(&block)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -18,22 +18,19 @@ module N1Loader
|
|
18
18
|
keys.flatten(1).flat_map do |key|
|
19
19
|
elements
|
20
20
|
.group_by { |element| loader_class(element, key) }
|
21
|
-
.
|
22
|
-
|
23
|
-
|
21
|
+
.select { |loader_class, _| loader_class }
|
22
|
+
.map do |(loader_class, grouped_elements)|
|
24
23
|
loader_collection = N1Loader::LoaderCollection.new(loader_class, grouped_elements)
|
25
|
-
grouped_elements.each { |grouped_element| grouped_element.
|
24
|
+
grouped_elements.each { |grouped_element| grouped_element.n1_loaders[key] = loader_collection }
|
26
25
|
loader_collection
|
27
|
-
end
|
26
|
+
end
|
28
27
|
end
|
29
28
|
end
|
30
29
|
|
31
30
|
private
|
32
31
|
|
33
32
|
def loader_class(element, key)
|
34
|
-
element.class.respond_to?(:
|
35
|
-
element.class.n1_loader_defined?(key) &&
|
36
|
-
element.class.n1_loader(key)
|
33
|
+
element.class.respond_to?(:n1_loaders) && element.class.n1_loaders[key]
|
37
34
|
end
|
38
35
|
end
|
39
36
|
end
|
data/lib/n1_loader/version.rb
CHANGED
data/lib/n1_loader.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative "n1_loader/version"
|
4
4
|
|
5
|
-
require_relative "n1_loader/core/
|
5
|
+
require_relative "n1_loader/core/loader_builder"
|
6
6
|
require_relative "n1_loader/core/loader"
|
7
7
|
require_relative "n1_loader/core/loader_collection"
|
8
8
|
require_relative "n1_loader/core/loadable"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: n1_loader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.7.
|
4
|
+
version: 1.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evgeniy Demin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-08-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -195,8 +195,8 @@ files:
|
|
195
195
|
- lib/n1_loader/ar_lazy_preload/preloader_patch.rb
|
196
196
|
- lib/n1_loader/core/loadable.rb
|
197
197
|
- lib/n1_loader/core/loader.rb
|
198
|
+
- lib/n1_loader/core/loader_builder.rb
|
198
199
|
- lib/n1_loader/core/loader_collection.rb
|
199
|
-
- lib/n1_loader/core/name.rb
|
200
200
|
- lib/n1_loader/core/preloader.rb
|
201
201
|
- lib/n1_loader/version.rb
|
202
202
|
- n1_loader.gemspec
|
data/lib/n1_loader/core/name.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module N1Loader
|
4
|
-
# Add support of question mark names
|
5
|
-
module Name
|
6
|
-
def n1_loader_name(name)
|
7
|
-
to_sym = name.is_a?(Symbol)
|
8
|
-
|
9
|
-
converted = name.to_s.gsub("?", "_question_mark")
|
10
|
-
|
11
|
-
to_sym ? converted.to_sym : converted
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|