ree_lib 1.0.49 → 1.0.50

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +4 -3
  3. data/lib/ree_lib/Packages.schema.json +4 -0
  4. data/lib/ree_lib/packages/ree_actions/spec/ree_actions/dsl_spec.rb +17 -10
  5. data/lib/ree_lib/packages/ree_dao/Package.schema.json +10 -0
  6. data/lib/ree_lib/packages/ree_dao/package/ree_dao/aggregate_dsl.rb +26 -0
  7. data/lib/ree_lib/packages/ree_dao/package/ree_dao/association.rb +311 -0
  8. data/lib/ree_lib/packages/ree_dao/package/ree_dao/associations.rb +148 -0
  9. data/lib/ree_lib/packages/ree_dao/package/ree_dao/beans/dao_cache.rb +40 -19
  10. data/lib/ree_lib/packages/ree_dao/package/ree_dao/contract/dao_dataset_contract.rb +15 -0
  11. data/lib/ree_lib/packages/ree_dao/package/ree_dao/contract/entity_contract.rb +15 -0
  12. data/lib/ree_lib/packages/ree_dao/package/ree_dao/dataset_extensions.rb +4 -0
  13. data/lib/ree_lib/packages/ree_dao/package/ree_dao/dsl.rb +1 -1
  14. data/lib/ree_lib/packages/ree_dao/package/ree_dao/functions/build_pg_connection.rb +1 -0
  15. data/lib/ree_lib/packages/ree_dao/package/ree_dao/functions/build_sqlite_connection.rb +1 -0
  16. data/lib/ree_lib/packages/ree_dao/package/ree_dao/functions/drop_cache.rb +1 -1
  17. data/lib/ree_lib/packages/ree_dao/package/ree_dao/functions/init_cache.rb +1 -1
  18. data/lib/ree_lib/packages/ree_dao/package/ree_dao/functions/load_agg.rb +63 -0
  19. data/lib/ree_lib/packages/ree_dao/package/ree_dao/thread_parents.rb +40 -0
  20. data/lib/ree_lib/packages/ree_dao/package/ree_dao.rb +9 -0
  21. data/lib/ree_lib/packages/ree_dao/schemas/ree_dao/functions/build_pg_connection.schema.json +1 -1
  22. data/lib/ree_lib/packages/ree_dao/schemas/ree_dao/functions/build_sqlite_connection.schema.json +1 -1
  23. data/lib/ree_lib/packages/ree_dao/schemas/ree_dao/functions/load_agg.schema.json +43 -0
  24. data/lib/ree_lib/packages/ree_dao/spec/ree_dao/functions/load_agg/load_agg_benchmark_spec.rb +414 -0
  25. data/lib/ree_lib/packages/ree_dao/spec/ree_dao/functions/load_agg/load_agg_spec.rb +605 -0
  26. data/lib/ree_lib/packages/ree_dao/spec/ree_dao/functions/load_agg/ree_dao_load_agg_test.rb +524 -0
  27. data/lib/ree_lib/packages/ree_logger/package/ree_logger/multi_logger.rb +19 -10
  28. data/lib/ree_lib/packages/ree_logger/spec/ree_logger/multi_logger_spec.rb +10 -0
  29. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper_factory_proxy.rb +6 -3
  30. data/lib/ree_lib/packages/ree_std/.gitignore +0 -0
  31. data/lib/ree_lib/packages/ree_std/.rspec +2 -0
  32. data/lib/ree_lib/packages/ree_std/Package.schema.json +24 -0
  33. data/lib/ree_lib/packages/ree_std/bin/console +5 -0
  34. data/lib/ree_lib/packages/ree_std/package/ree_std/functions/retry_on_fail.rb +46 -0
  35. data/lib/ree_lib/packages/ree_std/package/ree_std/retry.rb +67 -0
  36. data/lib/ree_lib/packages/ree_std/package/ree_std.rb +6 -0
  37. data/lib/ree_lib/packages/ree_std/schemas/ree_std/functions/retry_on_fail.schema.json +38 -0
  38. data/lib/ree_lib/packages/ree_std/spec/package_schema_spec.rb +14 -0
  39. data/lib/ree_lib/packages/ree_std/spec/ree_std/functions/retry_on_fail_spec.rb +97 -0
  40. data/lib/ree_lib/packages/ree_std/spec/spec_helper.rb +3 -0
  41. data/lib/ree_lib/packages/ree_swagger/package/ree_swagger/functions/build_request_body_schema.rb +5 -0
  42. data/lib/ree_lib/packages/ree_swagger/package/ree_swagger/functions/build_serializer_schema.rb +5 -0
  43. data/lib/ree_lib/packages/ree_swagger/spec/functions/build_endpoint_schema_spec.rb +4 -2
  44. data/lib/ree_lib/packages/ree_swagger/spec/functions/build_request_body_spec.rb +4 -2
  45. data/lib/ree_lib/version.rb +1 -1
  46. metadata +38 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c09a8508f0d27f47f70238fbd1dad1c5627c6082f575d703c509a831c67385f
4
- data.tar.gz: 297458d5b314777ce81af4d077e97fdcddc7985bf947ff0e33d7d07635a68718
3
+ metadata.gz: 4a53010ba7fdd43f86e011e0ee3f90675bb71e1b7f0c66d127736918ec89f6f0
4
+ data.tar.gz: 739eeb996f5ebfff231c613b5a6fd13022a4e91c5fa05716902dbd37d32f4d26
5
5
  SHA512:
6
- metadata.gz: 7804922d52fc7d3d6b203d58cfbfa63b0d87df69655537edc85b70b01d1e4bba88ed73459bad71e0c1f10ebd6d5ffcbb6d5c86c231b0c817038ed5cb6eba48a3
7
- data.tar.gz: ecd43b3975300c865644f617d7235f7d7868b945c9ca5a8f61e8bd2e939faa0214283d66aa883ad85bcba9ce365cfacd723a020eda31027991c74a4919e992b5
6
+ metadata.gz: f3a66d7108179a12e92fc5b36eb1adaaff37a733760f02e8867bcd949b9507b966161c4cb245da9d308de3d6066d8e6990ebd81b7a0d76a3e52e6fca02b75fd3
7
+ data.tar.gz: 5008628b066547548f69f3690d14e3103756b01573d3be8eb001450538c76a88c4adf3ebfec0ae36b5b47c13af9f598264d11a50c3a54f8eca0f3a630039563c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ree_lib (1.0.49)
4
+ ree_lib (1.0.50)
5
5
  binding_of_caller (~> 1.0.0)
6
6
  i18n (~> 1.12.0)
7
7
  loofah (~> 2.18.0)
@@ -28,6 +28,8 @@ GEM
28
28
  crass (1.0.6)
29
29
  debug_inspector (1.1.0)
30
30
  diff-lcs (1.5.0)
31
+ faker (3.2.0)
32
+ i18n (>= 1.8.11, < 2)
31
33
  hashdiff (1.0.1)
32
34
  highline (2.0.3)
33
35
  i18n (1.12.0)
@@ -36,8 +38,6 @@ GEM
36
38
  crass (~> 1.0.2)
37
39
  nokogiri (>= 1.5.9)
38
40
  msgpack (1.6.0)
39
- nokogiri (1.15.2-x86_64-darwin)
40
- racc (~> 1.4)
41
41
  nokogiri (1.15.2-x86_64-linux)
42
42
  racc (~> 1.4)
43
43
  oj (3.13.23)
@@ -87,6 +87,7 @@ PLATFORMS
87
87
 
88
88
  DEPENDENCIES
89
89
  bootsnap
90
+ faker (~> 3.2)
90
91
  pg (~> 1.4.1)
91
92
  rack-test
92
93
  rake (~> 13.0)
@@ -78,6 +78,10 @@
78
78
  "name": "ree_routes",
79
79
  "schema": "packages/ree_routes/Package.schema.json"
80
80
  },
81
+ {
82
+ "name": "ree_std",
83
+ "schema": "packages/ree_std/Package.schema.json"
84
+ },
81
85
  {
82
86
  "name": "ree_string",
83
87
  "schema": "packages/ree_string/Package.schema.json"
@@ -150,23 +150,30 @@ RSpec.describe ReeActions::DSL, type: [:autoclean] do
150
150
  user = ReeActionsTest::User.new(name: 'John', age: 30)
151
151
  users_dao.put(user)
152
152
 
153
- thr = Thread.new {
154
- user2 = ReeActionsTest::User.new(name: 'Alex', age: 33)
155
- users_dao.put(user2)
156
- }
153
+ Thread.new do
154
+ users_dao.put(ReeActionsTest::User.new(name: 'Alex', age: 33))
155
+ end.join
157
156
 
158
- thr.join
157
+ Thread.new do
158
+ users_dao.put(ReeActionsTest::User.new(name: 'David', age: 21))
159
+
160
+ Thread.new do
161
+ users_dao.put(ReeActionsTest::User.new(name: 'Sam', age: 19))
162
+ end.join
163
+ end.join
159
164
 
160
- $thread_group_cache = ReeDao::DaoCache.new.instance_variable_get(:@thread_groups)
161
- .dig(Thread.current.group.object_id, :users)
165
+ $thread_cache = ReeDao::DaoCache.new.instance_variable_get(:@threads)
166
+ .dig(Thread.current.object_id, :users)
162
167
 
163
168
  attrs[:user_id]
164
169
  end
165
170
  end
166
171
  end
167
172
 
168
- ReeActionsTest::TestAction3.new.call('user_access', {user_id: 1})
169
- expect($thread_group_cache.keys.count).to_not eq(0)
170
- expect($thread_group_cache.keys.count).to eq(2)
173
+ Thread.new do
174
+ ReeActionsTest::TestAction3.new.call('user_access', {user_id: 1})
175
+ end.join
176
+ expect($thread_cache.keys.count).to_not eq(0)
177
+ expect($thread_cache.keys.count).to eq(4)
171
178
  }
172
179
  end
@@ -16,6 +16,9 @@
16
16
  {
17
17
  "name": "ree_enum"
18
18
  },
19
+ {
20
+ "name": "ree_hash"
21
+ },
19
22
  {
20
23
  "name": "ree_mapper"
21
24
  },
@@ -93,6 +96,13 @@
93
96
  "fn"
94
97
  ]
95
98
  },
99
+ {
100
+ "name": "load_agg",
101
+ "schema": "packages/ree_dao/schemas/ree_dao/functions/load_agg.schema.json",
102
+ "tags": [
103
+ "fn"
104
+ ]
105
+ },
96
106
  {
97
107
  "name": "one_to_many",
98
108
  "schema": "packages/ree_dao/schemas/ree_dao/functions/one_to_many.schema.json",
@@ -0,0 +1,26 @@
1
+ module ReeDao
2
+ module AggregateDSL
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ def self.extended(base)
8
+ base.extend(ClassMethods)
9
+ end
10
+
11
+ module ClassMethods
12
+ def aggregate(name, &proc)
13
+ dsl = Ree::ObjectDsl.new(
14
+ Ree.container.packages_facade, name, self, :fn
15
+ )
16
+
17
+ dsl.instance_exec(&proc) if block_given?
18
+ dsl.tags(["aggregate"])
19
+ dsl.freeze(false)
20
+ dsl.object.set_as_compiled(false)
21
+
22
+ Ree.container.compile(dsl.package, name)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,311 @@
1
+ module ReeDao
2
+ class Association
3
+ include Ree::LinkDSL
4
+
5
+ link :demodulize, from: :ree_string
6
+ link :group_by, from: :ree_array
7
+ link :index_by, from: :ree_array
8
+ link :underscore, from: :ree_string
9
+
10
+ attr_reader :parent, :list, :global_opts
11
+
12
+ contract(ReeDao::Associations, Array, Ksplat[RestKeys => Any] => Any)
13
+ def initialize(parent, list, **global_opts)
14
+ @parent = parent
15
+ @list = list
16
+ @global_opts = global_opts
17
+ end
18
+
19
+ contract(
20
+ Or[:belongs_to, :has_one, :has_many, :field],
21
+ Symbol,
22
+ Ksplat[RestKeys => Any],
23
+ Optblock => Array
24
+ )
25
+ def load(assoc_type, assoc_name, **opts, &block)
26
+ load_association(assoc_type, assoc_name, **opts, &block)
27
+ end
28
+
29
+ contract(
30
+ Or[:belongs_to, :has_one, :has_many, :field],
31
+ Symbol,
32
+ Ksplat[RestKeys => Any],
33
+ Optblock => Nilor[Array]
34
+ )
35
+ def load_association(assoc_type, assoc_name, **opts, &block)
36
+ assoc_index = load_association_by_type(
37
+ assoc_type,
38
+ assoc_name,
39
+ **opts
40
+ )
41
+
42
+ process_block(assoc_index, opts[:autoload_children] ||= false, &block) if block_given?
43
+
44
+ list
45
+ end
46
+
47
+ contract(
48
+ Or[:belongs_to, :has_one, :has_many, :field],
49
+ Symbol,
50
+ Ksplat[RestKeys => Any] => Any
51
+ )
52
+ def load_association_by_type(type, assoc_name, **opts)
53
+ case type
54
+ when :belongs_to
55
+ one_to_one(
56
+ assoc_name,
57
+ list,
58
+ scope: opts[:scope],
59
+ foreign_key: opts[:foreign_key],
60
+ setter: opts[:setter],
61
+ reverse: false
62
+ )
63
+ when :has_one
64
+ one_to_one(
65
+ assoc_name,
66
+ list,
67
+ scope: opts[:scope],
68
+ foreign_key: opts[:foreign_key],
69
+ setter: opts[:setter],
70
+ reverse: true
71
+ )
72
+ when :has_many
73
+ one_to_many(
74
+ assoc_name,
75
+ list,
76
+ scope: opts[:scope],
77
+ foreign_key: opts[:foreign_key],
78
+ setter: opts[:setter]
79
+ )
80
+ else
81
+ one_to_many(
82
+ assoc_name,
83
+ list,
84
+ scope: opts[:scope],
85
+ foreign_key: opts[:foreign_key],
86
+ setter: opts[:setter],
87
+ skip_dao: true
88
+ )
89
+ end
90
+ end
91
+
92
+ contract(Hash, Bool, Block => Any)
93
+ def process_block(assoc, autoload_children, &block)
94
+ assoc_list = assoc.values.flatten
95
+
96
+ if ReeDao::Associations.sync_mode?
97
+ ReeDao::Associations.new(
98
+ parent.agg_caller,
99
+ assoc_list,
100
+ parent.local_vars,
101
+ autoload_children,
102
+ **global_opts
103
+ ).instance_exec(assoc_list, &block)
104
+ else
105
+ ReeDao::Associations.new(
106
+ parent.agg_caller,
107
+ assoc_list,
108
+ parent.local_vars,
109
+ autoload_children,
110
+ **global_opts
111
+ ).instance_exec(assoc_list, &block).map(&:join)
112
+ end
113
+ end
114
+
115
+ contract(
116
+ Symbol,
117
+ Array,
118
+ Kwargs[
119
+ foreign_key: Nilor[Symbol],
120
+ scope: Nilor[Sequel::Dataset],
121
+ setter: Nilor[Or[Symbol, Proc]],
122
+ reverse: Bool
123
+ ] => Hash
124
+ )
125
+ def one_to_one(
126
+ assoc_name,
127
+ list,
128
+ scope: nil,
129
+ foreign_key: nil,
130
+ setter: nil,
131
+ reverse: true
132
+ )
133
+ return {} if list.empty?
134
+
135
+ assoc_dao = find_dao(assoc_name, parent, scope)
136
+
137
+ if reverse
138
+ if !foreign_key
139
+ name = underscore(demodulize(list.first.class.name))
140
+ foreign_key = "#{name}_id".to_sym
141
+ end
142
+
143
+ root_ids = list.map(&:id).uniq
144
+ else
145
+ if !foreign_key
146
+ dto_class = assoc_dao
147
+ .opts[:schema_mapper]
148
+ .dto(:db_load)
149
+
150
+ name = underscore(demodulize(dto_class.name))
151
+
152
+ root_ids = list.map(&:"#{"#{name}_id".to_sym}").uniq
153
+ foreign_key = :id
154
+ else
155
+ root_ids = list.map(&:"#{foreign_key}")
156
+ foreign_key = :id
157
+ end
158
+ end
159
+
160
+ default_scope = assoc_dao&.where(foreign_key => root_ids)
161
+
162
+ items = add_scopes(default_scope, scope, global_opts[assoc_name])
163
+
164
+ assoc = index_by(items) { _1.send(foreign_key) }
165
+
166
+ populate_association(
167
+ list,
168
+ assoc,
169
+ assoc_name,
170
+ setter: setter,
171
+ reverse: reverse
172
+ )
173
+
174
+ assoc
175
+ end
176
+
177
+ contract(
178
+ Symbol,
179
+ Array,
180
+ Kwargs[
181
+ foreign_key: Nilor[Symbol],
182
+ scope: Nilor[Sequel::Dataset],
183
+ setter: Nilor[Or[Symbol, Proc]],
184
+ skip_dao: Bool
185
+ ] => Hash
186
+ )
187
+ def one_to_many(
188
+ assoc_name,
189
+ list,
190
+ foreign_key: nil,
191
+ scope: nil,
192
+ setter: nil,
193
+ skip_dao: false
194
+ )
195
+ return {} if list.empty?
196
+
197
+ assoc_dao = nil
198
+ assoc_dao = find_dao(assoc_name, parent, scope) if !skip_dao
199
+
200
+ foreign_key ||= "#{underscore(demodulize(list.first.class.name))}_id".to_sym
201
+
202
+ root_ids = list.map(&:id)
203
+
204
+ default_scope = assoc_dao&.where(foreign_key => root_ids)
205
+
206
+ items = add_scopes(default_scope, scope, global_opts[assoc_name])
207
+
208
+ assoc = group_by(items) { _1.send(foreign_key) }
209
+
210
+ populate_association(
211
+ list,
212
+ assoc,
213
+ assoc_name,
214
+ setter: setter
215
+ )
216
+
217
+ assoc
218
+ end
219
+
220
+ contract(
221
+ Array,
222
+ Hash,
223
+ Symbol,
224
+ Kwargs[
225
+ reverse: Nilor[Bool],
226
+ setter: Nilor[Or[Symbol, Proc]]
227
+ ] => Any
228
+ )
229
+ def populate_association(
230
+ list,
231
+ association_index,
232
+ assoc_name,
233
+ reverse: nil,
234
+ setter: nil
235
+ )
236
+ assoc_setter = if setter
237
+ setter
238
+ else
239
+ "set_#{assoc_name}"
240
+ end
241
+
242
+ list.each do |item|
243
+ if setter && setter.is_a?(Proc)
244
+ self.instance_exec(item, association_index, &assoc_setter)
245
+ else
246
+ key = if reverse.nil?
247
+ :id
248
+ else
249
+ reverse ? :id : "#{assoc_name}_id"
250
+ end
251
+ value = association_index[item.send(key)]
252
+ next if value.nil?
253
+
254
+ item.send(assoc_setter, value)
255
+ end
256
+ end
257
+ end
258
+
259
+ contract(Nilor[Sequel::Dataset], Nilor[Sequel::Dataset], Nilor[Proc] => Array)
260
+ def add_scopes(default_scope, scope, named_scope)
261
+ if default_scope && !scope
262
+ res = default_scope
263
+ end
264
+
265
+ if default_scope && scope
266
+ if scope == []
267
+ res = default_scope
268
+ else
269
+ res = merge_scopes(default_scope, scope)
270
+ end
271
+ end
272
+
273
+ if !default_scope && scope
274
+ return [] if scope.empty?
275
+
276
+ res = scope
277
+ end
278
+
279
+ if named_scope
280
+ res = named_scope.call(res)
281
+ end
282
+
283
+ res.all
284
+ end
285
+
286
+ def merge_scopes(s1, s2)
287
+ if s2.opts[:where]
288
+ s1 = s1.where(s2.opts[:where])
289
+ end
290
+
291
+ if s2.opts[:order]
292
+ s1 = s1.order(*s2.opts[:order])
293
+ end
294
+
295
+ s1
296
+ end
297
+
298
+ def find_dao(assoc_name, parent, scope)
299
+ dao_from_name = parent.instance_variable_get("@#{assoc_name}") || parent.instance_variable_get("@#{assoc_name}s")
300
+ return dao_from_name if dao_from_name
301
+
302
+ raise ArgumentError, "can't find DAO for :#{assoc_name}, provide correct scope or association name" if scope.nil?
303
+
304
+ table_name = scope.first_source_table
305
+ dao_from_scope = parent.instance_variable_get("@#{table_name}")
306
+ return dao_from_scope if dao_from_scope
307
+
308
+ raise ArgumentError, "can't find DAO for :#{assoc_name}, provide correct scope or association name"
309
+ end
310
+ end
311
+ end
@@ -0,0 +1,148 @@
1
+ module ReeDao
2
+ class Associations
3
+ include Ree::LinkDSL
4
+
5
+ attr_reader :agg_caller, :list, :local_vars, :only, :except, :autoload_children, :global_opts
6
+
7
+ def initialize(agg_caller, list, local_vars, autoload_children = false, **opts)
8
+ @agg_caller = agg_caller
9
+ @list = list
10
+ @local_vars = local_vars
11
+ @threads = [] if !self.class.sync_mode?
12
+ @global_opts = opts
13
+ @only = opts[:only] if opts[:only]
14
+ @except = opts[:except] if opts[:except]
15
+ @autoload_children = autoload_children
16
+
17
+ raise ArgumentError.new("you can't use both :only and :except arguments at the same time") if @only && @except
18
+
19
+ local_vars.each do |k, v|
20
+ instance_variable_set(k, v)
21
+
22
+ self.class.define_method k.to_s.gsub('@', '') do
23
+ v
24
+ end
25
+ end
26
+ end
27
+
28
+ def self.sync_mode?
29
+ ReeDao.load_sync_associations_enabled?
30
+ end
31
+
32
+ contract(
33
+ Symbol,
34
+ Ksplat[
35
+ scope?: Sequel::Dataset,
36
+ setter?: Or[Symbol, Proc],
37
+ foreign_key?: Symbol,
38
+ autoload_children?: Bool
39
+ ],
40
+ Optblock => Any
41
+ )
42
+ def belongs_to(assoc_name, **opts, &block)
43
+ association(__method__, assoc_name, **opts, &block)
44
+ end
45
+
46
+ contract(
47
+ Symbol,
48
+ Ksplat[
49
+ scope?: Sequel::Dataset,
50
+ setter?: Or[Symbol, Proc],
51
+ foreign_key?: Symbol,
52
+ autoload_children?: Bool
53
+ ],
54
+ Optblock => Any
55
+ )
56
+ def has_one(assoc_name, **opts, &block)
57
+ association(__method__, assoc_name, **opts, &block)
58
+ end
59
+
60
+ contract(
61
+ Symbol,
62
+ Ksplat[
63
+ scope?: Sequel::Dataset,
64
+ setter?: Or[Symbol, Proc],
65
+ foreign_key?: Symbol,
66
+ autoload_children?: Bool
67
+ ],
68
+ Optblock => Any
69
+ )
70
+ def has_many(assoc_name, **opts, &block)
71
+ association(__method__, assoc_name, **opts, &block)
72
+ end
73
+
74
+ contract(
75
+ Symbol,
76
+ Ksplat[
77
+ scope?: Sequel::Dataset,
78
+ setter?: Or[Symbol, Proc],
79
+ foreign_key?: Symbol,
80
+ autoload_children?: Bool
81
+ ],
82
+ Optblock => Any
83
+ )
84
+ def field(assoc_name, **opts, &block)
85
+ association(__method__, assoc_name, **opts, &block)
86
+ end
87
+
88
+ private
89
+
90
+ contract(
91
+ Or[
92
+ :belongs_to,
93
+ :has_one,
94
+ :has_many,
95
+ :field
96
+ ],
97
+ Symbol,
98
+ Ksplat[
99
+ scope?: Sequel::Dataset,
100
+ setter?: Or[Symbol, Proc],
101
+ foreign_key?: Symbol,
102
+ autoload_children?: Bool
103
+ ],
104
+ Optblock => Any
105
+ )
106
+ def association(assoc_type, assoc_name, **assoc_opts, &block)
107
+ if self.class.sync_mode?
108
+ return if association_is_not_included?(assoc_name)
109
+
110
+ association = Association.new(self, list, **global_opts)
111
+ association.load(assoc_type, assoc_name, **assoc_opts, &block)
112
+ else
113
+ return @threads if association_is_not_included?(assoc_name)
114
+
115
+ @threads << Thread.new do
116
+ association = Association.new(self, list, **global_opts)
117
+ association.load(assoc_type, assoc_name, **assoc_opts, &block)
118
+ end
119
+ end
120
+ end
121
+
122
+ contract(Symbol => Bool)
123
+ def association_is_not_included?(assoc_name)
124
+ return false if !only && !except
125
+
126
+ if only
127
+ return false if only && only.include?(assoc_name)
128
+
129
+ if only && !only.include?(assoc_name)
130
+ return false if autoload_children
131
+ return true
132
+ end
133
+ end
134
+
135
+ if except
136
+ return true if except && except.include?(assoc_name)
137
+ return false if except && !except.include?(assoc_name)
138
+ end
139
+ end
140
+
141
+ contract(Symbol, SplatOf[Any], Optblock => Any)
142
+ def method_missing(method, *args, &block)
143
+ return super if !agg_caller.private_methods(false).include?(method)
144
+
145
+ agg_caller.send(method, *args, &block)
146
+ end
147
+ end
148
+ end
@@ -9,48 +9,69 @@ class ReeDao::DaoCache
9
9
  end
10
10
 
11
11
  def setup
12
- @thread_groups = {}
12
+ @threads = {}
13
13
  end
14
14
 
15
- def add_thread_group_cache(thread_group)
16
- @thread_groups[thread_group.object_id] ||= {}
15
+ def add_thread_cache(thread)
16
+ @threads[get_thread_object_id(thread)] ||= {}
17
17
  end
18
18
 
19
- def drop_thread_group_cache(thread_group)
20
- @thread_groups.delete(thread_group.object_id)
19
+ def drop_thread_cache(thread)
20
+ @threads.delete(get_thread_object_id(thread))
21
21
  end
22
22
 
23
23
  def get(table_name, primary_key)
24
- add_thread_group_cache(current_thread_group)
24
+ add_thread_cache(current_thread)
25
25
  add_table_name(table_name)
26
26
 
27
- @thread_groups[current_thread_group.object_id][table_name][primary_key]
27
+ @threads[current_thread_object_id][table_name][primary_key]
28
28
  end
29
29
 
30
30
  def set(table_name, primary_key, data)
31
- add_thread_group_cache(current_thread_group)
31
+ add_thread_cache(current_thread)
32
32
  add_table_name(table_name)
33
33
  add_primary_key(table_name, primary_key)
34
34
 
35
- @thread_groups[current_thread_group.object_id][table_name][primary_key] = deep_dup(data)
35
+ @threads[current_thread_object_id][table_name][primary_key] = deep_dup(data)
36
36
  end
37
37
 
38
- def drop_table_cache(table_name)
39
- add_thread_group_cache(current_thread_group)
40
- @thread_groups[current_thread_group.object_id].delete(table_name)
38
+ private
39
+
40
+ def get_thread_object_id(thread)
41
+ thread.parent == Thread.main ? thread.object_id : get_parent_thread(thread)
41
42
  end
42
43
 
43
- private
44
+ def get_parent_thread(thread)
45
+ return thread.object_id if thread.parent == Thread.main || thread == Thread.main
46
+
47
+ get_parent_thread(thread.parent)
48
+ end
44
49
 
45
- def current_thread_group
46
- Thread.current.group
50
+ def current_thread
51
+ Thread.current
47
52
  end
48
53
 
49
- def add_table_name(thread_group = Thread.current.group, table_name)
50
- @thread_groups[thread_group.object_id][table_name] ||= {}
54
+ def current_thread_object_id
55
+ get_thread_object_id(current_thread)
51
56
  end
52
57
 
53
- def add_primary_key(thread_group = Thread.current.group, table_name, primary_key)
54
- @thread_groups[thread_group.object_id][table_name][primary_key] ||= {}
58
+ def add_table_name(table_name)
59
+ if !@threads[current_thread_object_id]
60
+ @threads[current_thread_object_id] ||= {}
61
+ end
62
+
63
+ @threads[current_thread_object_id][table_name] ||= {}
64
+ end
65
+
66
+ def add_primary_key(table_name, primary_key)
67
+ if !@threads[current_thread_object_id]
68
+ @threads[current_thread_object_id] ||= {}
69
+ end
70
+
71
+ if !@threads[current_thread_object_id][table_name]
72
+ @threads[current_thread_object_id][table_name] ||= {}
73
+ end
74
+
75
+ @threads[current_thread_object_id][table_name][primary_key] ||= {}
55
76
  end
56
77
  end