ree_lib 1.0.55 → 1.0.57
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/Gemfile.lock +1 -1
- data/lib/ree_lib/packages/ree_dao/package/ree_dao/association.rb +19 -70
- data/lib/ree_lib/packages/ree_dao/package/ree_dao/associations.rb +56 -56
- data/lib/ree_lib/packages/ree_dao/package/ree_dao/functions/load_agg.rb +11 -3
- data/lib/ree_lib/packages/ree_dao/schemas/ree_dao/functions/load_agg.schema.json +6 -6
- data/lib/ree_lib/packages/ree_dao/spec/ree_dao/functions/load_agg/load_agg_spec.rb +161 -19
- data/lib/ree_lib/packages/ree_dao/spec/ree_dao/functions/load_agg/ree_dao_load_agg_test.rb +19 -0
- data/lib/ree_lib/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 84ad4225d13e31575c1799fd4c7a4b480a1e7ae6b9709834447a733a3a260367
|
|
4
|
+
data.tar.gz: ba98679b88ac6ad2cec30fcd0280c01638220fdd0a7488f8f33c7ead0dd2de7d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ccbda33bb5233fc869f470993a93ec1770471e6fdce354a49455bf15c487731b06384bb776ed762c172e75428d77a071fc4483087cdbd2de8ef780729ccae3ac
|
|
7
|
+
data.tar.gz: d24649974cf1ca2f05c0bece050a7aa91450244cc065f972acacef6f7d966ee52f285c458cf9925d76693b14862d9ebfe77d42142dbb1bea24c3277a26b5a887
|
data/Gemfile.lock
CHANGED
|
@@ -26,8 +26,12 @@ module ReeDao
|
|
|
26
26
|
load_association(assoc_type, assoc_name, **opts, &block)
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
+
def handle_field(assoc_name, proc)
|
|
30
|
+
proc.call
|
|
31
|
+
end
|
|
32
|
+
|
|
29
33
|
contract(
|
|
30
|
-
Or[:belongs_to, :has_one, :has_many
|
|
34
|
+
Or[:belongs_to, :has_one, :has_many],
|
|
31
35
|
Symbol,
|
|
32
36
|
Ksplat[RestKeys => Any],
|
|
33
37
|
Optblock => Nilor[Array]
|
|
@@ -87,8 +91,7 @@ module ReeDao
|
|
|
87
91
|
scope: opts[:scope],
|
|
88
92
|
primary_key: opts[:primary_key],
|
|
89
93
|
foreign_key: opts[:foreign_key],
|
|
90
|
-
setter: opts[:setter]
|
|
91
|
-
skip_dao: true
|
|
94
|
+
setter: opts[:setter]
|
|
92
95
|
)
|
|
93
96
|
end
|
|
94
97
|
end
|
|
@@ -112,7 +115,7 @@ module ReeDao
|
|
|
112
115
|
parent.local_vars,
|
|
113
116
|
autoload_children,
|
|
114
117
|
**global_opts
|
|
115
|
-
).instance_exec(assoc_list, &block).map(&:join)
|
|
118
|
+
).instance_exec(assoc_list, &block)[:association_threads].map(&:join)
|
|
116
119
|
end
|
|
117
120
|
end
|
|
118
121
|
|
|
@@ -127,20 +130,11 @@ module ReeDao
|
|
|
127
130
|
reverse: Bool
|
|
128
131
|
] => Or[Hash, Array]
|
|
129
132
|
)
|
|
130
|
-
def one_to_one(
|
|
131
|
-
assoc_name,
|
|
132
|
-
list,
|
|
133
|
-
scope: nil,
|
|
134
|
-
primary_key: :id,
|
|
135
|
-
foreign_key: nil,
|
|
136
|
-
setter: nil,
|
|
137
|
-
reverse: true
|
|
138
|
-
)
|
|
133
|
+
def one_to_one(assoc_name, list, scope: nil, primary_key: :id, foreign_key: nil, setter: nil, reverse: true)
|
|
139
134
|
return {} if list.empty?
|
|
140
135
|
|
|
141
136
|
primary_key ||= :id
|
|
142
137
|
|
|
143
|
-
# TODO: refactor
|
|
144
138
|
if scope.is_a?(Array)
|
|
145
139
|
items = scope
|
|
146
140
|
else
|
|
@@ -169,7 +163,9 @@ module ReeDao
|
|
|
169
163
|
end
|
|
170
164
|
end
|
|
171
165
|
|
|
172
|
-
default_scope =
|
|
166
|
+
default_scope = if !scope
|
|
167
|
+
assoc_dao&.where(foreign_key => root_ids)
|
|
168
|
+
end
|
|
173
169
|
|
|
174
170
|
items = add_scopes(default_scope, scope, global_opts[assoc_name])
|
|
175
171
|
end
|
|
@@ -199,35 +195,27 @@ module ReeDao
|
|
|
199
195
|
foreign_key: Nilor[Symbol],
|
|
200
196
|
primary_key: Nilor[Symbol],
|
|
201
197
|
scope: Nilor[Sequel::Dataset, Array],
|
|
202
|
-
setter: Nilor[Or[Symbol, Proc]]
|
|
203
|
-
skip_dao: Bool
|
|
198
|
+
setter: Nilor[Or[Symbol, Proc]]
|
|
204
199
|
] => Or[Hash, Array]
|
|
205
200
|
)
|
|
206
|
-
def one_to_many(
|
|
207
|
-
assoc_name,
|
|
208
|
-
list,
|
|
209
|
-
primary_key: nil,
|
|
210
|
-
foreign_key: nil,
|
|
211
|
-
scope: nil,
|
|
212
|
-
setter: nil,
|
|
213
|
-
skip_dao: false
|
|
214
|
-
)
|
|
201
|
+
def one_to_many(assoc_name, list, primary_key: nil, foreign_key: nil, scope: nil, setter: nil)
|
|
215
202
|
return {} if list.empty?
|
|
216
203
|
|
|
217
204
|
primary_key ||= :id
|
|
218
205
|
|
|
219
|
-
# TODO: refactor
|
|
220
206
|
if scope.is_a?(Array)
|
|
221
207
|
items = scope
|
|
222
208
|
else
|
|
223
209
|
assoc_dao = nil
|
|
224
|
-
assoc_dao = find_dao(assoc_name, parent, scope)
|
|
210
|
+
assoc_dao = find_dao(assoc_name, parent, scope)
|
|
225
211
|
|
|
226
212
|
foreign_key ||= "#{underscore(demodulize(list.first.class.name))}_id".to_sym
|
|
227
213
|
|
|
228
214
|
root_ids = list.map(&:"#{primary_key}")
|
|
229
215
|
|
|
230
|
-
default_scope =
|
|
216
|
+
default_scope = if !scope
|
|
217
|
+
assoc_dao&.where(foreign_key => root_ids)
|
|
218
|
+
end
|
|
231
219
|
|
|
232
220
|
items = add_scopes(default_scope, scope, global_opts[assoc_name])
|
|
233
221
|
end
|
|
@@ -259,14 +247,7 @@ module ReeDao
|
|
|
259
247
|
setter: Nilor[Or[Symbol, Proc]]
|
|
260
248
|
] => Any
|
|
261
249
|
)
|
|
262
|
-
def populate_association(
|
|
263
|
-
list,
|
|
264
|
-
association_index,
|
|
265
|
-
assoc_name,
|
|
266
|
-
primary_key: nil,
|
|
267
|
-
reverse: nil,
|
|
268
|
-
setter: nil
|
|
269
|
-
)
|
|
250
|
+
def populate_association(list, association_index, assoc_name, primary_key: nil, reverse: nil, setter: nil)
|
|
270
251
|
assoc_setter = if setter
|
|
271
252
|
setter
|
|
272
253
|
else
|
|
@@ -296,23 +277,7 @@ module ReeDao
|
|
|
296
277
|
|
|
297
278
|
contract(Nilor[Sequel::Dataset], Nilor[Sequel::Dataset], Nilor[Proc] => Array)
|
|
298
279
|
def add_scopes(default_scope, scope, named_scope)
|
|
299
|
-
|
|
300
|
-
res = default_scope
|
|
301
|
-
end
|
|
302
|
-
|
|
303
|
-
if default_scope && scope
|
|
304
|
-
if scope == []
|
|
305
|
-
res = default_scope
|
|
306
|
-
else
|
|
307
|
-
res = merge_scopes(default_scope, scope)
|
|
308
|
-
end
|
|
309
|
-
end
|
|
310
|
-
|
|
311
|
-
if !default_scope && scope
|
|
312
|
-
return [] if scope.empty?
|
|
313
|
-
|
|
314
|
-
res = scope
|
|
315
|
-
end
|
|
280
|
+
res = scope || default_scope
|
|
316
281
|
|
|
317
282
|
if named_scope
|
|
318
283
|
res = named_scope.call(res)
|
|
@@ -321,22 +286,6 @@ module ReeDao
|
|
|
321
286
|
res.all
|
|
322
287
|
end
|
|
323
288
|
|
|
324
|
-
def merge_scopes(s1, s2)
|
|
325
|
-
if s2.opts[:where]
|
|
326
|
-
s1 = s1.where(s2.opts[:where])
|
|
327
|
-
end
|
|
328
|
-
|
|
329
|
-
if s2.opts[:order]
|
|
330
|
-
s1 = s1.order(*s2.opts[:order])
|
|
331
|
-
end
|
|
332
|
-
|
|
333
|
-
if s1.opts[:schema_mapper] != s2.opts[:schema_mapper]
|
|
334
|
-
s1 = s1.with_mapper(s2.opts[:schema_mapper])
|
|
335
|
-
end
|
|
336
|
-
|
|
337
|
-
s1
|
|
338
|
-
end
|
|
339
|
-
|
|
340
289
|
def find_dao(assoc_name, parent, scope)
|
|
341
290
|
dao_from_name = parent.instance_variable_get("@#{assoc_name}") || parent.instance_variable_get("@#{assoc_name}s")
|
|
342
291
|
return dao_from_name if dao_from_name
|
|
@@ -8,14 +8,19 @@ module ReeDao
|
|
|
8
8
|
@agg_caller = agg_caller
|
|
9
9
|
@list = list
|
|
10
10
|
@local_vars = local_vars
|
|
11
|
-
@
|
|
12
|
-
@global_opts = opts
|
|
11
|
+
@global_opts = opts || {}
|
|
13
12
|
@only = opts[:only] if opts[:only]
|
|
14
13
|
@except = opts[:except] if opts[:except]
|
|
15
14
|
@autoload_children = autoload_children
|
|
16
15
|
|
|
17
16
|
raise ArgumentError.new("you can't use both :only and :except arguments at the same time") if @only && @except
|
|
18
17
|
|
|
18
|
+
|
|
19
|
+
if !self.class.sync_mode?
|
|
20
|
+
@assoc_threads = []
|
|
21
|
+
@field_threads = []
|
|
22
|
+
end
|
|
23
|
+
|
|
19
24
|
local_vars.each do |k, v|
|
|
20
25
|
instance_variable_set(k, v)
|
|
21
26
|
|
|
@@ -31,62 +36,34 @@ module ReeDao
|
|
|
31
36
|
|
|
32
37
|
contract(
|
|
33
38
|
Symbol,
|
|
34
|
-
|
|
35
|
-
scope?: Or[Sequel::Dataset, Array],
|
|
36
|
-
setter?: Or[Symbol, Proc],
|
|
37
|
-
primary_key?: Symbol,
|
|
38
|
-
foreign_key?: Symbol,
|
|
39
|
-
autoload_children?: Bool
|
|
40
|
-
],
|
|
39
|
+
Nilor[Proc, Sequel::Dataset],
|
|
41
40
|
Optblock => Any
|
|
42
41
|
)
|
|
43
|
-
def belongs_to(assoc_name,
|
|
44
|
-
association(__method__, assoc_name,
|
|
42
|
+
def belongs_to(assoc_name, opts = nil, &block)
|
|
43
|
+
association(__method__, assoc_name, opts, &block)
|
|
45
44
|
end
|
|
46
45
|
|
|
47
46
|
contract(
|
|
48
47
|
Symbol,
|
|
49
|
-
|
|
50
|
-
scope?: Or[Sequel::Dataset, Array],
|
|
51
|
-
setter?: Or[Symbol, Proc],
|
|
52
|
-
primary_key?: Symbol,
|
|
53
|
-
foreign_key?: Symbol,
|
|
54
|
-
autoload_children?: Bool
|
|
55
|
-
],
|
|
48
|
+
Nilor[Proc, Sequel::Dataset],
|
|
56
49
|
Optblock => Any
|
|
57
50
|
)
|
|
58
|
-
def has_one(assoc_name,
|
|
59
|
-
association(__method__, assoc_name,
|
|
51
|
+
def has_one(assoc_name, opts = nil, &block)
|
|
52
|
+
association(__method__, assoc_name, opts, &block)
|
|
60
53
|
end
|
|
61
54
|
|
|
62
55
|
contract(
|
|
63
56
|
Symbol,
|
|
64
|
-
|
|
65
|
-
scope?: Or[Sequel::Dataset, Array],
|
|
66
|
-
setter?: Or[Symbol, Proc],
|
|
67
|
-
primary_key?: Symbol,
|
|
68
|
-
foreign_key?: Symbol,
|
|
69
|
-
autoload_children?: Bool
|
|
70
|
-
],
|
|
57
|
+
Nilor[Proc, Sequel::Dataset],
|
|
71
58
|
Optblock => Any
|
|
72
59
|
)
|
|
73
|
-
def has_many(assoc_name,
|
|
74
|
-
association(__method__, assoc_name,
|
|
60
|
+
def has_many(assoc_name, opts = nil, &block)
|
|
61
|
+
association(__method__, assoc_name, opts, &block)
|
|
75
62
|
end
|
|
76
63
|
|
|
77
|
-
contract(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
scope?: Or[Sequel::Dataset, Array],
|
|
81
|
-
setter?: Or[Symbol, Proc],
|
|
82
|
-
primary_key?: Symbol,
|
|
83
|
-
foreign_key?: Symbol,
|
|
84
|
-
autoload_children?: Bool
|
|
85
|
-
],
|
|
86
|
-
Optblock => Any
|
|
87
|
-
)
|
|
88
|
-
def field(assoc_name, **opts, &block)
|
|
89
|
-
association(__method__, assoc_name, **opts, &block)
|
|
64
|
+
contract(Symbol, Proc => Any)
|
|
65
|
+
def field(assoc_name, proc)
|
|
66
|
+
association(__method__, assoc_name, proc)
|
|
90
67
|
end
|
|
91
68
|
|
|
92
69
|
private
|
|
@@ -99,27 +76,40 @@ module ReeDao
|
|
|
99
76
|
:field
|
|
100
77
|
],
|
|
101
78
|
Symbol,
|
|
102
|
-
|
|
103
|
-
scope?: Or[Sequel::Dataset, Array],
|
|
104
|
-
setter?: Or[Symbol, Proc],
|
|
105
|
-
primary_key?: Symbol,
|
|
106
|
-
foreign_key?: Symbol,
|
|
107
|
-
autoload_children?: Bool
|
|
108
|
-
],
|
|
79
|
+
Nilor[Proc, Sequel::Dataset],
|
|
109
80
|
Optblock => Any
|
|
110
81
|
)
|
|
111
|
-
def association(assoc_type, assoc_name,
|
|
82
|
+
def association(assoc_type, assoc_name, opts, &block)
|
|
112
83
|
if self.class.sync_mode?
|
|
113
84
|
return if association_is_not_included?(assoc_name) || list.empty?
|
|
114
|
-
|
|
85
|
+
|
|
115
86
|
association = Association.new(self, list, **global_opts)
|
|
116
|
-
|
|
87
|
+
if assoc_type == :field
|
|
88
|
+
association.handle_field(assoc_name, opts)
|
|
89
|
+
else
|
|
90
|
+
association.load(assoc_type, assoc_name, **get_assoc_opts(opts), &block)
|
|
91
|
+
end
|
|
117
92
|
else
|
|
118
|
-
|
|
93
|
+
if association_is_not_included?(assoc_name) || list.empty?
|
|
94
|
+
return { association_threads: @assoc_threads, field_threads: @field_threads }
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
association = Association.new(self, list, **global_opts)
|
|
119
98
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
99
|
+
if assoc_type == :field
|
|
100
|
+
{
|
|
101
|
+
association_threads: @assoc_threads,
|
|
102
|
+
field_threads: @field_threads << Thread.new do
|
|
103
|
+
association.handle_field(assoc_name, opts)
|
|
104
|
+
end
|
|
105
|
+
}
|
|
106
|
+
else
|
|
107
|
+
{
|
|
108
|
+
association_threads: @assoc_threads << Thread.new do
|
|
109
|
+
association.load(assoc_type, assoc_name, **get_assoc_opts(opts), &block)
|
|
110
|
+
end,
|
|
111
|
+
field_threads: @field_threads
|
|
112
|
+
}
|
|
123
113
|
end
|
|
124
114
|
end
|
|
125
115
|
end
|
|
@@ -149,5 +139,15 @@ module ReeDao
|
|
|
149
139
|
|
|
150
140
|
agg_caller.send(method, *args, &block)
|
|
151
141
|
end
|
|
142
|
+
|
|
143
|
+
def get_assoc_opts(opts)
|
|
144
|
+
if opts.is_a?(Proc)
|
|
145
|
+
opts.call
|
|
146
|
+
elsif opts.is_a?(Sequel::Dataset)
|
|
147
|
+
{ scope: opts }
|
|
148
|
+
else
|
|
149
|
+
{}
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
152
|
end
|
|
153
153
|
end
|
|
@@ -10,16 +10,17 @@ class ReeDao::LoadAgg
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
contract(
|
|
13
|
-
Or[Sequel::Dataset, ArrayOf[Integer], ArrayOf[EntityContract], Integer],
|
|
14
13
|
Nilor[DaoDatasetContract],
|
|
14
|
+
Or[Sequel::Dataset, ArrayOf[Integer], ArrayOf[EntityContract], Integer],
|
|
15
15
|
Ksplat[
|
|
16
16
|
only?: ArrayOf[Symbol],
|
|
17
17
|
except?: ArrayOf[Symbol],
|
|
18
|
+
to_dto?: Proc,
|
|
18
19
|
RestKeys => Any
|
|
19
20
|
],
|
|
20
21
|
Optblock => ArrayOf[Any]
|
|
21
22
|
)
|
|
22
|
-
def call(
|
|
23
|
+
def call(dao = nil, ids_or_scope, **opts, &block)
|
|
23
24
|
scope = if ids_or_scope.is_a?(Array) && ids_or_scope.any? { _1.is_a?(Integer) }
|
|
24
25
|
raise ArgumentError.new("Dao should be provided") if dao.nil?
|
|
25
26
|
return [] if ids_or_scope.empty?
|
|
@@ -35,6 +36,12 @@ class ReeDao::LoadAgg
|
|
|
35
36
|
|
|
36
37
|
list = scope.is_a?(Sequel::Dataset) ? scope.all : scope
|
|
37
38
|
|
|
39
|
+
if opts[:to_dto]
|
|
40
|
+
list = list.map do |item|
|
|
41
|
+
list = opts[:to_dto].call(item)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
38
45
|
load_associations(list, **opts, &block) if block_given?
|
|
39
46
|
|
|
40
47
|
if ids_or_scope.is_a?(Array)
|
|
@@ -61,7 +68,8 @@ class ReeDao::LoadAgg
|
|
|
61
68
|
if ReeDao.load_sync_associations_enabled?
|
|
62
69
|
associations
|
|
63
70
|
else
|
|
64
|
-
associations.map(&:join)
|
|
71
|
+
associations[:association_threads].map(&:join)
|
|
72
|
+
associations[:field_threads].map(&:join)
|
|
65
73
|
end
|
|
66
74
|
end
|
|
67
75
|
end
|
|
@@ -14,20 +14,20 @@
|
|
|
14
14
|
],
|
|
15
15
|
"return": "ArrayOf[Any]",
|
|
16
16
|
"args": [
|
|
17
|
-
{
|
|
18
|
-
"arg": "ids_or_scope",
|
|
19
|
-
"arg_type": "req",
|
|
20
|
-
"type": "Or[Sequel::Dataset, ArrayOf[Integer], ArrayOf[PackageName::Entity], Integer]"
|
|
21
|
-
},
|
|
22
17
|
{
|
|
23
18
|
"arg": "dao",
|
|
24
19
|
"arg_type": "opt",
|
|
25
20
|
"type": "Nilor[PackageName::DaoName::Dao: \"SELECT * FROM `table`\"]"
|
|
26
21
|
},
|
|
22
|
+
{
|
|
23
|
+
"arg": "ids_or_scope",
|
|
24
|
+
"arg_type": "req",
|
|
25
|
+
"type": "Or[Sequel::Dataset, ArrayOf[Integer], ArrayOf[PackageName::Entity], Integer]"
|
|
26
|
+
},
|
|
27
27
|
{
|
|
28
28
|
"arg": "opts",
|
|
29
29
|
"arg_type": "keyrest",
|
|
30
|
-
"type": "Ksplat[:only? => ArrayOf[Symbol], :except? => ArrayOf[Symbol], \"RestKeys\" => Any]"
|
|
30
|
+
"type": "Ksplat[:only? => ArrayOf[Symbol], :except? => ArrayOf[Symbol], :to_dto? => Proc, \"RestKeys\" => Any]"
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
33
|
"arg": "block",
|
|
@@ -99,19 +99,67 @@ RSpec.describe :load_agg do
|
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
def call(ids_or_scope, **opts)
|
|
102
|
-
load_agg(
|
|
102
|
+
load_agg(users, ids_or_scope, **opts) do |users_list|
|
|
103
103
|
belongs_to :organization
|
|
104
|
-
has_many :books do
|
|
104
|
+
has_many :books do |books_list|
|
|
105
105
|
has_one :author
|
|
106
106
|
has_many :chapters
|
|
107
107
|
|
|
108
|
-
has_many :reviews do
|
|
108
|
+
has_many :reviews do |reviews_list|
|
|
109
109
|
has_one :review_author
|
|
110
|
+
|
|
111
|
+
field :review_calculatetable_field, -> { some_method(reviews_list) }
|
|
110
112
|
end
|
|
113
|
+
|
|
114
|
+
field :book_calculatetable_field, -> { change_book_titles(books_list) }
|
|
111
115
|
end
|
|
112
116
|
|
|
113
|
-
has_one :passport,
|
|
114
|
-
has_one :custom_field,
|
|
117
|
+
has_one :passport, -> { passport_opts }
|
|
118
|
+
has_one :custom_field, -> { custom_field_opts }
|
|
119
|
+
|
|
120
|
+
field :user_calculatetable_field, -> { some_method(users_list) }
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
private
|
|
125
|
+
|
|
126
|
+
def change_book_titles(books_list)
|
|
127
|
+
books_list.each do |book|
|
|
128
|
+
book.title = "#{book.title.upcase} changed"
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def some_method(list)
|
|
133
|
+
puts list.map(&:id)
|
|
134
|
+
puts list.map { _1.class.name }
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def passport_opts
|
|
138
|
+
{
|
|
139
|
+
foreign_key: :user_id,
|
|
140
|
+
scope: user_passports
|
|
141
|
+
}
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def custom_field_opts
|
|
145
|
+
{
|
|
146
|
+
scope: books.where(title: "1984")
|
|
147
|
+
}
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
class ReeDaoLoadAggTest::UsersAggWithDto
|
|
152
|
+
include ReeDao::AggregateDSL
|
|
153
|
+
|
|
154
|
+
aggregate :users_agg_with_dto do
|
|
155
|
+
link :users, from: :ree_dao_load_agg_test
|
|
156
|
+
link :organizations, from: :ree_dao_load_agg_test
|
|
157
|
+
link :load_agg, from: :ree_dao
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def call(ids_or_scope, **opts)
|
|
161
|
+
load_agg(users, ids_or_scope, **opts) do
|
|
162
|
+
belongs_to :organization
|
|
115
163
|
end
|
|
116
164
|
end
|
|
117
165
|
end
|
|
@@ -130,9 +178,9 @@ RSpec.describe :load_agg do
|
|
|
130
178
|
end
|
|
131
179
|
|
|
132
180
|
def call(ids_or_scope, **opts)
|
|
133
|
-
load_agg(
|
|
181
|
+
load_agg(users, ids_or_scope, **opts) do
|
|
134
182
|
belongs_to :organization
|
|
135
|
-
has_many :books,
|
|
183
|
+
has_many :books, -> { books_opts } do
|
|
136
184
|
has_one :author
|
|
137
185
|
has_many :chapters
|
|
138
186
|
|
|
@@ -142,6 +190,12 @@ RSpec.describe :load_agg do
|
|
|
142
190
|
end
|
|
143
191
|
end
|
|
144
192
|
end
|
|
193
|
+
|
|
194
|
+
private
|
|
195
|
+
|
|
196
|
+
def books_opts
|
|
197
|
+
{ autoload_children: true }
|
|
198
|
+
end
|
|
145
199
|
end
|
|
146
200
|
|
|
147
201
|
class ReeDaoLoadAggTest::UsersAggAutoloadReviewsChildren
|
|
@@ -158,18 +212,24 @@ RSpec.describe :load_agg do
|
|
|
158
212
|
end
|
|
159
213
|
|
|
160
214
|
def call(ids_or_scope, **opts)
|
|
161
|
-
load_agg(
|
|
215
|
+
load_agg(users, ids_or_scope, **opts) do
|
|
162
216
|
belongs_to :organization
|
|
163
217
|
has_many :books do
|
|
164
218
|
has_one :author
|
|
165
219
|
has_many :chapters
|
|
166
220
|
|
|
167
|
-
has_many :reviews, autoload_children: true do
|
|
221
|
+
has_many :reviews, -> { { autoload_children: true } } do
|
|
168
222
|
has_one :review_author
|
|
169
223
|
end
|
|
170
224
|
end
|
|
171
225
|
end
|
|
172
226
|
end
|
|
227
|
+
|
|
228
|
+
private
|
|
229
|
+
|
|
230
|
+
def reviews_opts
|
|
231
|
+
{ autoload_children: true }
|
|
232
|
+
end
|
|
173
233
|
end
|
|
174
234
|
|
|
175
235
|
class ReeDaoLoadAggTest::UsersAggBlockTest
|
|
@@ -183,13 +243,21 @@ RSpec.describe :load_agg do
|
|
|
183
243
|
end
|
|
184
244
|
|
|
185
245
|
def call(ids_or_scope, **opts)
|
|
186
|
-
load_agg(
|
|
246
|
+
load_agg(users, ids_or_scope, **opts) do
|
|
187
247
|
belongs_to :organization
|
|
188
|
-
has_many :books,
|
|
248
|
+
has_many :books, -> { books_opts }
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
private
|
|
253
|
+
|
|
254
|
+
def books_opts
|
|
255
|
+
{
|
|
256
|
+
setter: -> (item, items_index) {
|
|
189
257
|
b = items_index[item.id].each { |b| b.title = "Changed" }
|
|
190
258
|
item.set_books(b)
|
|
191
259
|
}
|
|
192
|
-
|
|
260
|
+
}
|
|
193
261
|
end
|
|
194
262
|
end
|
|
195
263
|
|
|
@@ -204,22 +272,42 @@ RSpec.describe :load_agg do
|
|
|
204
272
|
end
|
|
205
273
|
|
|
206
274
|
def call(ids_or_scope, **opts)
|
|
207
|
-
load_agg(
|
|
275
|
+
load_agg(users, ids_or_scope, **opts) do |agg_list|
|
|
208
276
|
some_id = agg_list.first.id
|
|
209
277
|
title = "1984"
|
|
210
|
-
belongs_to :organization
|
|
278
|
+
belongs_to :organization, organizations.by_name("Corp")
|
|
211
279
|
|
|
212
|
-
has_many :books,
|
|
280
|
+
has_many :books, -> { books_opts(title) }
|
|
213
281
|
end
|
|
214
282
|
end
|
|
215
283
|
|
|
216
284
|
private
|
|
217
285
|
|
|
286
|
+
def books_opts(title)
|
|
287
|
+
{ scope: books_scope(title) }
|
|
288
|
+
end
|
|
289
|
+
|
|
218
290
|
def books_scope(title)
|
|
219
291
|
books.where(title: title)
|
|
220
292
|
end
|
|
221
293
|
end
|
|
222
294
|
|
|
295
|
+
class ReeDaoLoadAggTest::UsersAggOnlyDataset
|
|
296
|
+
include ReeDao::AggregateDSL
|
|
297
|
+
|
|
298
|
+
aggregate :users_agg_only_dataset do
|
|
299
|
+
link :users, from: :ree_dao_load_agg_test
|
|
300
|
+
link :books, from: :ree_dao_load_agg_test
|
|
301
|
+
link :load_agg, from: :ree_dao
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def call(ids_or_scope, **opts)
|
|
305
|
+
load_agg(users, ids_or_scope, **opts) do
|
|
306
|
+
has_many :books, books.where(title: "1408")
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
|
|
223
311
|
class ReeDaoLoadAggTest::UsersAggWithoutDao
|
|
224
312
|
include ReeDao::AggregateDSL
|
|
225
313
|
|
|
@@ -231,7 +319,7 @@ RSpec.describe :load_agg do
|
|
|
231
319
|
end
|
|
232
320
|
|
|
233
321
|
def call(ids_or_scope, **opts)
|
|
234
|
-
load_agg(
|
|
322
|
+
load_agg(users, ids_or_scope, **opts) do
|
|
235
323
|
has_many :something
|
|
236
324
|
end
|
|
237
325
|
end
|
|
@@ -243,6 +331,8 @@ RSpec.describe :load_agg do
|
|
|
243
331
|
let(:users_agg_autoload_books_children) { ReeDaoLoadAggTest::UsersAggAutoloadBooksChildren.new }
|
|
244
332
|
let(:users_agg_autoload_reviews_children) { ReeDaoLoadAggTest::UsersAggAutoloadReviewsChildren.new }
|
|
245
333
|
let(:users_agg_without_dao) { ReeDaoLoadAggTest::UsersAggWithoutDao.new }
|
|
334
|
+
let(:users_agg_with_dto) { ReeDaoLoadAggTest::UsersAggWithDto.new }
|
|
335
|
+
let(:users_agg_only_dataset) { ReeDaoLoadAggTest::UsersAggOnlyDataset.new }
|
|
246
336
|
let(:organizations) { ReeDaoLoadAggTest::Organizations.new }
|
|
247
337
|
let(:users) { ReeDaoLoadAggTest::Users.new }
|
|
248
338
|
let(:user_passports) { ReeDaoLoadAggTest::UserPassports.new }
|
|
@@ -267,6 +357,57 @@ RSpec.describe :load_agg do
|
|
|
267
357
|
}.to raise_error(ArgumentError)
|
|
268
358
|
}
|
|
269
359
|
|
|
360
|
+
it {
|
|
361
|
+
organizations.delete_all
|
|
362
|
+
users.delete_all
|
|
363
|
+
|
|
364
|
+
organization = ReeDaoLoadAggTest::Organization.new(name: "Test Org")
|
|
365
|
+
organizations.put(organization)
|
|
366
|
+
|
|
367
|
+
user_1 = ReeDaoLoadAggTest::User.new(name: "John", age: 33, organization_id: organization.id)
|
|
368
|
+
user_2 = ReeDaoLoadAggTest::User.new(name: "Sam", age: 21, organization_id: organization.id)
|
|
369
|
+
users.put(user_1)
|
|
370
|
+
users.put(user_2)
|
|
371
|
+
|
|
372
|
+
res = users_agg_with_dto.call(
|
|
373
|
+
users.all,
|
|
374
|
+
to_dto: -> (user) {
|
|
375
|
+
ReeDaoLoadAggTest::UserDto.new(
|
|
376
|
+
id: user.id,
|
|
377
|
+
name: user.name,
|
|
378
|
+
organization_id: user.organization_id,
|
|
379
|
+
full_name: user.name
|
|
380
|
+
)
|
|
381
|
+
}
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
expect(res.first.class).to eq(ReeDaoLoadAggTest::UserDto)
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
it {
|
|
388
|
+
organizations.delete_all
|
|
389
|
+
users.delete_all
|
|
390
|
+
|
|
391
|
+
org = ReeDaoLoadAggTest::Organization.new(name: "Test Org")
|
|
392
|
+
organizations.put(org)
|
|
393
|
+
|
|
394
|
+
user = ReeDaoLoadAggTest::User.new(name: "John", age: 33, organization_id: org.id)
|
|
395
|
+
users.put(user)
|
|
396
|
+
|
|
397
|
+
book_1 = ReeDaoLoadAggTest::Book.new(user_id: user.id, title: "1984")
|
|
398
|
+
book_2 = ReeDaoLoadAggTest::Book.new(user_id: user.id, title: "1408")
|
|
399
|
+
book_3 = ReeDaoLoadAggTest::Book.new(user_id: user.id, title: "1408")
|
|
400
|
+
|
|
401
|
+
books.put(book_1)
|
|
402
|
+
books.put(book_2)
|
|
403
|
+
books.put(book_3)
|
|
404
|
+
|
|
405
|
+
res = users_agg_only_dataset.call(users.where(name: "John"))
|
|
406
|
+
|
|
407
|
+
user = res[0]
|
|
408
|
+
expect(user.books.map(&:title).uniq).to eq(["1408"])
|
|
409
|
+
}
|
|
410
|
+
|
|
270
411
|
it {
|
|
271
412
|
organizations.delete_all
|
|
272
413
|
users.delete_all
|
|
@@ -317,6 +458,7 @@ RSpec.describe :load_agg do
|
|
|
317
458
|
expect(res_user.passport).to eq(passport_1)
|
|
318
459
|
expect(res_user.passport.info).to eq("some info")
|
|
319
460
|
expect(res_user.books.count).to eq(2)
|
|
461
|
+
expect(res_user.books.map(&:title)).to eq(["1984 changed", "1408 changed"])
|
|
320
462
|
expect(res_user.books[0].author.name).to eq("George Orwell")
|
|
321
463
|
expect(res_user.books[0].chapters.map(&:title)).to eq(["beginning"])
|
|
322
464
|
expect(res_user.books[0].reviews[0].review_author.name).to eq("John Review")
|
|
@@ -595,7 +737,7 @@ RSpec.describe :load_agg do
|
|
|
595
737
|
|
|
596
738
|
ids = [user_1, user_2].map(&:id)
|
|
597
739
|
|
|
598
|
-
res = load_agg(
|
|
740
|
+
res = load_agg(users, ids)
|
|
599
741
|
expect(res.count).to eq(2)
|
|
600
742
|
}
|
|
601
743
|
|
|
@@ -609,7 +751,7 @@ RSpec.describe :load_agg do
|
|
|
609
751
|
user_1 = ReeDaoLoadAggTest::User.new(name: "John", age: 33, organization_id: organization.id)
|
|
610
752
|
users.put(user_1)
|
|
611
753
|
|
|
612
|
-
res = load_agg(user_1.id
|
|
754
|
+
res = load_agg(users, user_1.id)
|
|
613
755
|
expect(res.count).to eq(1)
|
|
614
756
|
}
|
|
615
757
|
|
|
@@ -625,7 +767,7 @@ RSpec.describe :load_agg do
|
|
|
625
767
|
users.put(user_1)
|
|
626
768
|
users.put(user_2)
|
|
627
769
|
|
|
628
|
-
res = load_agg(users.where(organization_id: organization.id)
|
|
770
|
+
res = load_agg(users, users.where(organization_id: organization.id))
|
|
629
771
|
expect(res.count).to eq(2)
|
|
630
772
|
}
|
|
631
773
|
end
|
|
@@ -134,6 +134,25 @@ class ReeDaoLoadAggTest::User
|
|
|
134
134
|
attr_accessor :name, :age, :organization_id
|
|
135
135
|
end
|
|
136
136
|
|
|
137
|
+
class ReeDaoLoadAggTest::UserDto
|
|
138
|
+
include ReeDto::EntityDSL
|
|
139
|
+
|
|
140
|
+
properties(
|
|
141
|
+
id: Integer,
|
|
142
|
+
organization_id: Integer,
|
|
143
|
+
name: String,
|
|
144
|
+
full_name: String,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
def set_organization(org)
|
|
148
|
+
@organization = org; nil
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def organization
|
|
152
|
+
@organization
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
137
156
|
class ReeDaoLoadAggTest::Organization
|
|
138
157
|
include ReeDto::EntityDSL
|
|
139
158
|
|
data/lib/ree_lib/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ree_lib
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.57
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ruslan Gatiyatov
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-07-
|
|
11
|
+
date: 2023-07-31 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: ree
|