bullet 8.1.3 → 8.3.0

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.
@@ -1,278 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Bullet
4
- module SaveWithBulletSupport
5
- def _create_record(*)
6
- super do
7
- Bullet::Detector::NPlusOneQuery.update_inversed_object(self)
8
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self)
9
- yield(self) if block_given?
10
- end
11
- end
12
- end
13
-
14
- module ActiveRecord
15
- def self.enable
16
- require 'active_record'
17
- ::ActiveRecord::Base.extend(
18
- Module.new do
19
- def find_by_sql(sql, binds = [], preparable: nil, &block)
20
- result = super
21
- if Bullet.start?
22
- if result.is_a? Array
23
- if result.size > 1
24
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
25
- Bullet::Detector::CounterCache.add_possible_objects(result)
26
- elsif result.size == 1
27
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
28
- Bullet::Detector::CounterCache.add_impossible_object(result.first)
29
- end
30
- elsif result.is_a? ::ActiveRecord::Base
31
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
32
- Bullet::Detector::CounterCache.add_impossible_object(result)
33
- end
34
- end
35
- result
36
- end
37
- end
38
- )
39
-
40
- ::ActiveRecord::Base.prepend(SaveWithBulletSupport)
41
-
42
- ::ActiveRecord::Relation.prepend(
43
- Module.new do
44
- # if select a collection of objects, then these objects have possible to cause N+1 query.
45
- # if select only one object, then the only one object has impossible to cause N+1 query.
46
- def records
47
- result = super
48
- if Bullet.start?
49
- if result.first.class.name !~ /^HABTM_/
50
- if result.size > 1
51
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
52
- Bullet::Detector::CounterCache.add_possible_objects(result)
53
- elsif result.size == 1
54
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
55
- Bullet::Detector::CounterCache.add_impossible_object(result.first)
56
- end
57
- end
58
- end
59
- result
60
- end
61
- end
62
- )
63
-
64
- ::ActiveRecord::Associations::Preloader.prepend(
65
- Module.new do
66
- def preloaders_for_one(association, records, scope)
67
- if Bullet.start?
68
- records.compact!
69
- if records.first.class.name !~ /^HABTM_/
70
- records.each { |record| Bullet::Detector::Association.add_object_associations(record, association) }
71
- Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, association)
72
- end
73
- end
74
- super
75
- end
76
- end
77
- )
78
-
79
- ::ActiveRecord::Associations::JoinDependency.prepend(
80
- Module.new do
81
- def instantiate(result_set, &block)
82
- @bullet_eager_loadings = {}
83
- records = super
84
-
85
- if Bullet.start?
86
- @bullet_eager_loadings.each do |_klazz, eager_loadings_hash|
87
- objects = eager_loadings_hash.keys
88
- Bullet::Detector::UnusedEagerLoading.add_eager_loadings(
89
- objects,
90
- eager_loadings_hash[objects.first].to_a
91
- )
92
- end
93
- end
94
- records
95
- end
96
-
97
- def construct(ar_parent, parent, row, rs, seen, model_cache, aliases)
98
- if Bullet.start?
99
- unless ar_parent.nil?
100
- parent.children.each do |node|
101
- key = aliases.column_alias(node, node.primary_key)
102
- id = row[key]
103
- next unless id.nil?
104
-
105
- associations = [node.reflection.name]
106
- if node.reflection.through_reflection?
107
- associations << node.reflection.through_reflection.name
108
- end
109
- associations.each do |association|
110
- Bullet::Detector::Association.add_object_associations(ar_parent, association)
111
- Bullet::Detector::NPlusOneQuery.call_association(ar_parent, association)
112
- @bullet_eager_loadings[ar_parent.class] ||= {}
113
- @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
114
- @bullet_eager_loadings[ar_parent.class][ar_parent] << association
115
- end
116
- end
117
- end
118
- end
119
-
120
- super
121
- end
122
-
123
- # call join associations
124
- def construct_model(record, node, row, model_cache, id, aliases)
125
- result = super
126
-
127
- if Bullet.start?
128
- associations = [node.reflection.name]
129
- if node.reflection.through_reflection?
130
- associations << node.reflection.through_reflection.name
131
- end
132
- associations.each do |association|
133
- Bullet::Detector::Association.add_object_associations(record, association)
134
- Bullet::Detector::NPlusOneQuery.call_association(record, association)
135
- @bullet_eager_loadings[record.class] ||= {}
136
- @bullet_eager_loadings[record.class][record] ||= Set.new
137
- @bullet_eager_loadings[record.class][record] << association
138
- end
139
- end
140
-
141
- result
142
- end
143
- end
144
- )
145
-
146
- ::ActiveRecord::Associations::Association.prepend(
147
- Module.new do
148
- def inversed_from(record)
149
- if Bullet.start?
150
- Bullet::Detector::NPlusOneQuery.add_inversed_object(owner, reflection.name)
151
- end
152
- super
153
- end
154
- end
155
- )
156
-
157
- ::ActiveRecord::Associations::CollectionAssociation.prepend(
158
- Module.new do
159
- def load_target
160
- records = super
161
-
162
- if Bullet.start?
163
- if is_a? ::ActiveRecord::Associations::ThroughAssociation
164
- association = owner.association(reflection.through_reflection.name)
165
- if association.loaded?
166
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
167
- Array.wrap(association.target).each do |through_record|
168
- Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
169
- end
170
-
171
- if reflection.through_reflection != through_reflection
172
- Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
173
- end
174
- end
175
- end
176
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name, inversed: @inversed)
177
- if records.first.class.name !~ /^HABTM_/
178
- if records.size > 1
179
- Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
180
- Bullet::Detector::CounterCache.add_possible_objects(records)
181
- elsif records.size == 1
182
- Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
183
- Bullet::Detector::CounterCache.add_impossible_object(records.first)
184
- end
185
- end
186
- end
187
- records
188
- end
189
-
190
- def empty?
191
- if Bullet.start? && !reflection.has_cached_counter?
192
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
193
- end
194
- super
195
- end
196
-
197
- def include?(object)
198
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name) if Bullet.start?
199
- super
200
- end
201
- end
202
- )
203
-
204
- ::ActiveRecord::Associations::SingularAssociation.prepend(
205
- Module.new do
206
- # call has_one and belongs_to associations
207
- def target
208
- result = super()
209
-
210
- if Bullet.start?
211
- if owner.class.name !~ /^HABTM_/
212
- unless @inversed
213
- if is_a? ::ActiveRecord::Associations::ThroughAssociation
214
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
215
- association = owner.association reflection.through_reflection.name
216
- Array.wrap(association.target).each do |through_record|
217
- Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
218
- end
219
-
220
- if reflection.through_reflection != through_reflection
221
- Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
222
- end
223
- end
224
- end
225
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name, inversed: @inversed)
226
- unless @inversed
227
- if Bullet::Detector::NPlusOneQuery.impossible?(owner)
228
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
229
- else
230
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result) if result
231
- end
232
- end
233
- end
234
- end
235
- result
236
- end
237
- end
238
- )
239
-
240
- ::ActiveRecord::Associations::HasManyAssociation.prepend(
241
- Module.new do
242
- def empty?
243
- if Bullet.start? && !reflection.has_cached_counter?
244
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name, caller_locations)
245
- end
246
- super
247
- end
248
-
249
- def count_records
250
- result = reflection.has_cached_counter?
251
- if Bullet.start? && !result && !is_a?(::ActiveRecord::Associations::ThroughAssociation)
252
- Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
253
- end
254
- super
255
- end
256
- end
257
- )
258
-
259
- ::ActiveRecord::Associations::CollectionProxy.prepend(
260
- Module.new do
261
- def count(column_name = nil)
262
- if Bullet.start? && !proxy_association.is_a?(::ActiveRecord::Associations::ThroughAssociation)
263
- Bullet::Detector::CounterCache.add_counter_cache(
264
- proxy_association.owner,
265
- proxy_association.reflection.name
266
- )
267
- Bullet::Detector::NPlusOneQuery.call_association(
268
- proxy_association.owner,
269
- proxy_association.reflection.name
270
- )
271
- end
272
- super(column_name)
273
- end
274
- end
275
- )
276
- end
277
- end
278
- end
@@ -1,310 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Bullet
4
- module SaveWithBulletSupport
5
- def _create_record(*)
6
- super do
7
- Bullet::Detector::NPlusOneQuery.update_inversed_object(self)
8
- Bullet::Detector::NPlusOneQuery.add_impossible_object(self)
9
- yield(self) if block_given?
10
- end
11
- end
12
- end
13
-
14
- module ActiveRecord
15
- def self.enable
16
- require 'active_record'
17
- ::ActiveRecord::Base.extend(
18
- Module.new do
19
- def find_by_sql(sql, binds = [], preparable: nil, &block)
20
- result = super
21
- if Bullet.start?
22
- if result.is_a? Array
23
- if result.size > 1
24
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
25
- Bullet::Detector::CounterCache.add_possible_objects(result)
26
- elsif result.size == 1
27
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
28
- Bullet::Detector::CounterCache.add_impossible_object(result.first)
29
- end
30
- elsif result.is_a? ::ActiveRecord::Base
31
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result)
32
- Bullet::Detector::CounterCache.add_impossible_object(result)
33
- end
34
- end
35
- result
36
- end
37
- end
38
- )
39
-
40
- ::ActiveRecord::Base.prepend(SaveWithBulletSupport)
41
-
42
- ::ActiveRecord::Relation.prepend(
43
- Module.new do
44
- # if select a collection of objects, then these objects have possible to cause N+1 query.
45
- # if select only one object, then the only one object has impossible to cause N+1 query.
46
- def records
47
- result = super
48
- if Bullet.start?
49
- if result.first.class.name !~ /^HABTM_/
50
- if result.size > 1
51
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result)
52
- Bullet::Detector::CounterCache.add_possible_objects(result)
53
- elsif result.size == 1
54
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)
55
- Bullet::Detector::CounterCache.add_impossible_object(result.first)
56
- end
57
- end
58
- end
59
- result
60
- end
61
- end
62
- )
63
-
64
- ::ActiveRecord::Associations::Preloader.prepend(
65
- Module.new do
66
- def preloaders_for_one(association, records, scope, polymorphic_parent)
67
- if Bullet.start?
68
- records.compact!
69
- if records.first.class.name !~ /^HABTM_/
70
- records.each { |record| Bullet::Detector::Association.add_object_associations(record, association) }
71
- Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, association)
72
- end
73
- end
74
- super
75
- end
76
-
77
- def preloaders_for_reflection(reflection, records, scope)
78
- if Bullet.start?
79
- records.compact!
80
- if records.first.class.name !~ /^HABTM_/
81
- records.each { |record| Bullet::Detector::Association.add_object_associations(record, reflection.name) }
82
- Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, reflection.name)
83
- end
84
- end
85
- super
86
- end
87
- end
88
- )
89
-
90
- ::ActiveRecord::Associations::Preloader::ThroughAssociation.prepend(
91
- Module.new do
92
- def preloaded_records
93
- if Bullet.start? && !defined?(@preloaded_records)
94
- source_preloaders.each do |source_preloader|
95
- reflection_name = source_preloader.send(:reflection).name
96
- source_preloader.send(:owners).each do |owner|
97
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection_name)
98
- end
99
- end
100
- end
101
- super
102
- end
103
- end
104
- )
105
-
106
- ::ActiveRecord::Associations::JoinDependency.prepend(
107
- Module.new do
108
- def instantiate(result_set, strict_loading_value, &block)
109
- @bullet_eager_loadings = {}
110
- records = super
111
-
112
- if Bullet.start?
113
- @bullet_eager_loadings.each do |_klazz, eager_loadings_hash|
114
- objects = eager_loadings_hash.keys
115
- Bullet::Detector::UnusedEagerLoading.add_eager_loadings(
116
- objects,
117
- eager_loadings_hash[objects.first].to_a
118
- )
119
- end
120
- end
121
- records
122
- end
123
-
124
- def construct(ar_parent, parent, row, seen, model_cache, strict_loading_value)
125
- if Bullet.start?
126
- unless ar_parent.nil?
127
- parent.children.each do |node|
128
- key = aliases.column_alias(node, node.primary_key)
129
- id = row[key]
130
- next unless id.nil?
131
-
132
- associations = [node.reflection.name]
133
- if node.reflection.through_reflection?
134
- associations << node.reflection.through_reflection.name
135
- end
136
- associations.each do |association|
137
- Bullet::Detector::Association.add_object_associations(ar_parent, association)
138
- Bullet::Detector::NPlusOneQuery.call_association(ar_parent, association)
139
- @bullet_eager_loadings[ar_parent.class] ||= {}
140
- @bullet_eager_loadings[ar_parent.class][ar_parent] ||= Set.new
141
- @bullet_eager_loadings[ar_parent.class][ar_parent] << association
142
- end
143
- end
144
- end
145
- end
146
-
147
- super
148
- end
149
-
150
- # call join associations
151
- def construct_model(record, node, row, model_cache, id, strict_loading_value)
152
- result = super
153
-
154
- if Bullet.start?
155
- associations = [node.reflection.name]
156
- if node.reflection.through_reflection?
157
- associations << node.reflection.through_reflection.name
158
- end
159
- associations.each do |association|
160
- Bullet::Detector::Association.add_object_associations(record, association)
161
- Bullet::Detector::NPlusOneQuery.call_association(record, association)
162
- @bullet_eager_loadings[record.class] ||= {}
163
- @bullet_eager_loadings[record.class][record] ||= Set.new
164
- @bullet_eager_loadings[record.class][record] << association
165
- end
166
- end
167
-
168
- result
169
- end
170
- end
171
- )
172
-
173
- ::ActiveRecord::Associations::Association.prepend(
174
- Module.new do
175
- def inversed_from(record)
176
- if Bullet.start?
177
- Bullet::Detector::NPlusOneQuery.add_inversed_object(owner, reflection.name)
178
- end
179
- super
180
- end
181
- end
182
- )
183
-
184
- ::ActiveRecord::Associations::CollectionAssociation.prepend(
185
- Module.new do
186
- def load_target
187
- records = super
188
-
189
- if Bullet.start?
190
- if is_a? ::ActiveRecord::Associations::ThroughAssociation
191
- association = owner.association(reflection.through_reflection.name)
192
- if association.loaded?
193
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
194
- Array.wrap(association.target).each do |through_record|
195
- Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
196
- end
197
-
198
- if reflection.through_reflection != through_reflection
199
- Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
200
- end
201
- end
202
- end
203
- if @inversed
204
- Bullet::Detector::Association.add_call_object_associations(owner, reflection.name)
205
- else
206
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name)
207
- end
208
- if records.first.class.name !~ /^HABTM_/
209
- if records.size > 1
210
- Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
211
- Bullet::Detector::CounterCache.add_possible_objects(records)
212
- elsif records.size == 1
213
- Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
214
- Bullet::Detector::CounterCache.add_impossible_object(records.first)
215
- end
216
- end
217
- end
218
- records
219
- end
220
-
221
- def empty?
222
- if Bullet.start? && !reflection.has_cached_counter?
223
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name, caller_locations)
224
- end
225
- super
226
- end
227
-
228
- def include?(object)
229
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name, caller_locations) if Bullet.start?
230
- super
231
- end
232
- end
233
- )
234
-
235
- ::ActiveRecord::Associations::SingularAssociation.prepend(
236
- Module.new do
237
- # call has_one and belongs_to associations
238
- def target
239
- result = super()
240
-
241
- if Bullet.start?
242
- if owner.class.name !~ /^HABTM_/
243
- unless @inversed
244
- if is_a? ::ActiveRecord::Associations::ThroughAssociation
245
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.through_reflection.name)
246
- association = owner.association(reflection.through_reflection.name)
247
- Array.wrap(association.target).each do |through_record|
248
- Bullet::Detector::NPlusOneQuery.call_association(through_record, source_reflection.name)
249
- end
250
-
251
- if reflection.through_reflection != through_reflection
252
- Bullet::Detector::NPlusOneQuery.call_association(owner, through_reflection.name)
253
- end
254
- end
255
- end
256
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name, inversed: @inversed)
257
- unless @inversed
258
- if Bullet::Detector::NPlusOneQuery.impossible?(owner)
259
- Bullet::Detector::NPlusOneQuery.add_impossible_object(result) if result
260
- else
261
- Bullet::Detector::NPlusOneQuery.add_possible_objects(result) if result
262
- end
263
- end
264
- end
265
- end
266
- result
267
- end
268
- end
269
- )
270
-
271
- ::ActiveRecord::Associations::HasManyAssociation.prepend(
272
- Module.new do
273
- def empty?
274
- if Bullet.start? && !reflection.has_cached_counter?
275
- Bullet::Detector::NPlusOneQuery.call_association(owner, reflection.name, caller_locations)
276
- end
277
- super
278
- end
279
-
280
- def count_records
281
- result = reflection.has_cached_counter?
282
- if Bullet.start? && !result && !is_a?(::ActiveRecord::Associations::ThroughAssociation)
283
- Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
284
- end
285
- super
286
- end
287
- end
288
- )
289
-
290
- ::ActiveRecord::Associations::CollectionProxy.prepend(
291
- Module.new do
292
- def count(column_name = nil)
293
- if Bullet.start? && !proxy_association.is_a?(::ActiveRecord::Associations::ThroughAssociation)
294
- Bullet::Detector::CounterCache.add_counter_cache(
295
- proxy_association.owner,
296
- proxy_association.reflection.name
297
- )
298
- Bullet::Detector::NPlusOneQuery.call_association(
299
- proxy_association.owner,
300
- proxy_association.reflection.name,
301
- caller_locations
302
- )
303
- end
304
- super(column_name)
305
- end
306
- end
307
- )
308
- end
309
- end
310
- end