flyerhzm-bullet 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/bullet.gemspec +4 -4
- data/lib/bullet/association.rb +112 -53
- metadata +4 -5
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.1.0
|
data/bullet.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bullet}
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Richard Huang"]
|
12
|
-
s.date = %q{2009-08-
|
12
|
+
s.date = %q{2009-08-27}
|
13
13
|
s.description = %q{This plugin is aimed to give you some performance suggestion about ActiveRecord usage, what should use but not use, such as eager loading, counter cache and so on, what should not use but use, such as unused eager loading. Now it provides you the suggestion of eager loading and unused eager loading. The others are todo, next may be couter cache.}
|
14
14
|
s.email = %q{flyerhzm@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -38,8 +38,8 @@ Gem::Specification.new do |s|
|
|
38
38
|
s.rubygems_version = %q{1.3.5}
|
39
39
|
s.summary = %q{A plugin to kill N+1 queries and unused eager loading}
|
40
40
|
s.test_files = [
|
41
|
-
"spec/
|
42
|
-
"spec/
|
41
|
+
"spec/bullet_association_spec.rb",
|
42
|
+
"spec/spec_helper.rb"
|
43
43
|
]
|
44
44
|
|
45
45
|
if s.respond_to? :specification_version then
|
data/lib/bullet/association.rb
CHANGED
@@ -7,13 +7,6 @@ module Bullet
|
|
7
7
|
|
8
8
|
def start_request
|
9
9
|
# puts "start request"
|
10
|
-
@@object_associations ||= {}
|
11
|
-
@@call_object_associations ||= {}
|
12
|
-
@@unpreload_associations ||= {}
|
13
|
-
@@unused_preload_associations ||= {}
|
14
|
-
@@callers ||= []
|
15
|
-
@@possible_objects ||= {}
|
16
|
-
@@impossible_objects ||= {}
|
17
10
|
end
|
18
11
|
|
19
12
|
def end_request
|
@@ -38,16 +31,12 @@ module Bullet
|
|
38
31
|
end
|
39
32
|
|
40
33
|
def check_unused_preload_associations
|
41
|
-
|
42
|
-
call_association =
|
34
|
+
object_associations.each do |object, association|
|
35
|
+
call_association = call_object_associations[object] || []
|
43
36
|
association.uniq! unless association.flatten!.nil?
|
44
37
|
call_association.uniq! unless call_association.flatten!.nil?
|
45
|
-
|
46
|
-
unless (association - call_association).empty?
|
47
|
-
@@unused_preload_associations[klazz] ||= []
|
48
|
-
@@unused_preload_associations[klazz] << (association - call_association)
|
49
|
-
@@unused_preload_associations[klazz].flatten!.uniq!
|
50
|
-
end
|
38
|
+
|
39
|
+
add_unused_preload_associations(object.class, association - call_association) unless (association - call_association).empty?
|
51
40
|
end
|
52
41
|
end
|
53
42
|
|
@@ -57,11 +46,11 @@ module Bullet
|
|
57
46
|
end
|
58
47
|
|
59
48
|
def has_unused_preload_associations?
|
60
|
-
|
49
|
+
!unused_preload_associations.empty?
|
61
50
|
end
|
62
51
|
|
63
52
|
def has_unpreload_associations?
|
64
|
-
|
53
|
+
!unpreload_associations.empty?
|
65
54
|
end
|
66
55
|
|
67
56
|
def bad_associations_alert
|
@@ -69,24 +58,37 @@ module Bullet
|
|
69
58
|
if @@alert
|
70
59
|
str = "<script type='text/javascript'>"
|
71
60
|
str << "alert('The request has unused preload assocations as follows:\\n"
|
72
|
-
str << (has_unused_preload_associations? ?
|
61
|
+
str << (has_unused_preload_associations? ? bad_associations_str(unused_preload_associations) : "None")
|
73
62
|
str << "\\nThe request has N+1 queries as follows:\\n"
|
74
|
-
str << (has_unpreload_associations? ?
|
63
|
+
str << (has_unpreload_associations? ? bad_associations_str(unpreload_associations) : "None")
|
75
64
|
str << "')"
|
76
65
|
str << "</script>\n"
|
77
66
|
end
|
78
67
|
str
|
79
68
|
end
|
69
|
+
|
70
|
+
def bad_associations_str(bad_associations)
|
71
|
+
puts bad_associations.inspect
|
72
|
+
bad_associations.to_a.collect{|klazz, associations| klazz_associations_str(klazz, associations)}.join('\\n')
|
73
|
+
end
|
74
|
+
|
75
|
+
def klazz_associations_str(klazz, associations)
|
76
|
+
"model: #{klazz} => associations: [#{associations.join(', ')}]"
|
77
|
+
end
|
78
|
+
|
79
|
+
def associations_str(associations)
|
80
|
+
":include => #{associations.map{|a| a.to_sym unless a.is_a? Hash}.inspect}"
|
81
|
+
end
|
80
82
|
|
81
83
|
def log_bad_associations(path)
|
82
84
|
if @@logger
|
83
|
-
|
84
|
-
@@logger.info "Unused preload associations: PATH_INFO: #{path};
|
85
|
+
unused_preload_associations.each do |klazz, associations|
|
86
|
+
@@logger.info "Unused preload associations: PATH_INFO: #{path}; " + klazz_associations_str(klazz, associations) + "\n Remove from your finder: " + associations_str(associations)
|
85
87
|
end
|
86
|
-
|
87
|
-
@@logger.info "N+1 Query: PATH_INFO: #{path};
|
88
|
+
unpreload_associations.each do |klazz, associations|
|
89
|
+
@@logger.info "N+1 Query: PATH_INFO: #{path}; " + klazz_associations_str(klazz, associations) + "\n Add to your finder: " + associations_str(associations)
|
88
90
|
end
|
89
|
-
|
91
|
+
callers.each do |c|
|
90
92
|
@@logger.info "N+1 Query: method call stack: \n" + c.join("\n")
|
91
93
|
end
|
92
94
|
@@logger_file.flush
|
@@ -94,56 +96,113 @@ module Bullet
|
|
94
96
|
end
|
95
97
|
|
96
98
|
def has_klazz_association(klazz)
|
97
|
-
|
99
|
+
!klazz_associations[klazz].nil? and klazz_associations.keys.include?(klazz)
|
98
100
|
end
|
99
101
|
|
100
102
|
def define_association(klazz, associations)
|
101
103
|
# puts "define association, #{klazz} => #{associations}"
|
102
|
-
|
103
|
-
@@klazz_associations[klazz] ||= []
|
104
|
-
@@klazz_associations[klazz] << associations
|
104
|
+
add_klazz_associations(klazz, associations)
|
105
105
|
end
|
106
106
|
|
107
|
-
def
|
108
|
-
# puts "
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
107
|
+
def call_association(object, associations)
|
108
|
+
# puts "call association, #{object} => #{associations}"
|
109
|
+
if unpreload_associations?(object, associations)
|
110
|
+
add_unpreload_associations(object.class, associations)
|
111
|
+
add_call_object_associations(object, associations)
|
112
|
+
caller_in_project
|
113
|
+
end
|
113
114
|
end
|
114
115
|
|
115
|
-
def
|
116
|
-
# puts "add impossible object, #{object}"
|
116
|
+
def unpreload_associations?(object, associations)
|
117
117
|
klazz = object.class
|
118
|
-
|
119
|
-
|
118
|
+
(!possible_objects[klazz].nil? and possible_objects[klazz].include?(object)) and
|
119
|
+
(impossible_objects[klazz].nil? or !impossible_objects[klazz].include?(object)) and
|
120
|
+
(object_associations[object].nil? or !object_associations[object].include?(associations))
|
121
|
+
end
|
122
|
+
|
123
|
+
def add_unpreload_associations(klazz, associations)
|
124
|
+
# puts "add unpreload associations, #{klazz} => #{associations.inspect}"
|
125
|
+
unpreload_associations[klazz] ||= []
|
126
|
+
unpreload_associations[klazz] << associations
|
127
|
+
unpreload_associations[klazz].uniq!
|
128
|
+
end
|
129
|
+
|
130
|
+
def add_unused_preload_associations(klazz, associations)
|
131
|
+
# puts "add unused preload associations, #{object} => #{associations.inspect}"
|
132
|
+
unused_preload_associations[klazz] ||= []
|
133
|
+
unused_preload_associations[klazz] << associations
|
134
|
+
unused_preload_associations[klazz].flatten!.uniq!
|
120
135
|
end
|
121
136
|
|
122
137
|
def add_association(object, associations)
|
123
|
-
# puts "add
|
124
|
-
|
125
|
-
|
138
|
+
# puts "add associations, #{object} => #{associations.inspect}"
|
139
|
+
object_associations[object] ||= []
|
140
|
+
object_associations[object] << associations
|
126
141
|
end
|
127
142
|
|
128
|
-
def
|
129
|
-
# puts "call
|
143
|
+
def add_call_object_associations(object, associations)
|
144
|
+
# puts "add call object associations, #{object} => #{associations.inspect}"
|
145
|
+
call_object_associations[object] ||= []
|
146
|
+
call_object_associations[object] << associations
|
147
|
+
end
|
148
|
+
|
149
|
+
def add_possible_objects(objects)
|
150
|
+
# puts "add possible objects, #{objects.inspect}"
|
151
|
+
klazz= objects.first.class
|
152
|
+
possible_objects[klazz] ||= []
|
153
|
+
possible_objects[klazz] << objects
|
154
|
+
possible_objects[klazz].flatten!.uniq!
|
155
|
+
end
|
156
|
+
|
157
|
+
def add_impossible_object(object)
|
158
|
+
# puts "add impossible object, #{object}"
|
130
159
|
klazz = object.class
|
160
|
+
impossible_objects[klazz] ||= []
|
161
|
+
impossible_objects[klazz] << object
|
162
|
+
end
|
163
|
+
|
164
|
+
def add_klazz_associations(klazz, associations)
|
165
|
+
# puts "define associations, #{klazz} => #{associations.inspect}"
|
166
|
+
klazz_associations[klazz] ||= []
|
167
|
+
klazz_associations[klazz] << associations
|
168
|
+
end
|
169
|
+
|
170
|
+
def unpreload_associations
|
171
|
+
@@unpreload_associations ||= {}
|
172
|
+
end
|
173
|
+
|
174
|
+
def unused_preload_associations
|
175
|
+
@@unused_preload_associations ||= {}
|
176
|
+
end
|
177
|
+
|
178
|
+
def object_associations
|
179
|
+
@@object_associations ||= {}
|
180
|
+
end
|
181
|
+
|
182
|
+
def call_object_associations
|
183
|
+
@@call_object_associations ||= {}
|
184
|
+
end
|
185
|
+
|
186
|
+
def possible_objects
|
131
187
|
@@possible_objects ||= {}
|
188
|
+
end
|
189
|
+
|
190
|
+
def impossible_objects
|
132
191
|
@@impossible_objects ||= {}
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
@@call_object_associations[object] ||= []
|
138
|
-
@@call_object_associations[object] << associations
|
139
|
-
caller_in_project
|
140
|
-
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def klazz_associations
|
195
|
+
@@klazz_associations ||= {}
|
141
196
|
end
|
142
197
|
|
143
198
|
VENDOR_ROOT = File.join(RAILS_ROOT, 'vendor')
|
144
199
|
def caller_in_project
|
145
|
-
|
146
|
-
|
200
|
+
callers << caller.select {|c| c =~ /#{RAILS_ROOT}/}.reject {|c| c =~ /#{VENDOR_ROOT}/}
|
201
|
+
callers.uniq!
|
202
|
+
end
|
203
|
+
|
204
|
+
def callers
|
205
|
+
@@callers ||= []
|
147
206
|
end
|
148
207
|
end
|
149
208
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flyerhzm-bullet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Huang
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-08-
|
12
|
+
date: 2009-08-27 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -39,7 +39,6 @@ files:
|
|
39
39
|
- tasks/bullet_tasks.rake
|
40
40
|
has_rdoc: false
|
41
41
|
homepage: http://www.huangzhimin.com/projects/4-bullet
|
42
|
-
licenses:
|
43
42
|
post_install_message:
|
44
43
|
rdoc_options:
|
45
44
|
- --charset=UTF-8
|
@@ -60,10 +59,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
59
|
requirements: []
|
61
60
|
|
62
61
|
rubyforge_project:
|
63
|
-
rubygems_version: 1.
|
62
|
+
rubygems_version: 1.2.0
|
64
63
|
signing_key:
|
65
64
|
specification_version: 3
|
66
65
|
summary: A plugin to kill N+1 queries and unused eager loading
|
67
66
|
test_files:
|
68
|
-
- spec/spec_helper.rb
|
69
67
|
- spec/bullet_association_spec.rb
|
68
|
+
- spec/spec_helper.rb
|