bullet 4.9.0 → 4.10.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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -1
  3. data/.travis.yml +1 -1
  4. data/CHANGELOG.md +7 -0
  5. data/Gemfile +1 -3
  6. data/Gemfile.mongoid +2 -3
  7. data/Gemfile.mongoid-2.4 +0 -3
  8. data/Gemfile.mongoid-2.5 +0 -3
  9. data/Gemfile.mongoid-2.6 +0 -3
  10. data/Gemfile.mongoid-2.7 +0 -3
  11. data/Gemfile.mongoid-2.8 +0 -3
  12. data/Gemfile.mongoid-3.0 +0 -3
  13. data/Gemfile.mongoid-3.1 +0 -3
  14. data/Gemfile.mongoid-4.0 +19 -0
  15. data/Gemfile.rails-3.0 +0 -2
  16. data/Gemfile.rails-3.1 +1 -3
  17. data/Gemfile.rails-3.2 +1 -3
  18. data/Gemfile.rails-4.0 +1 -3
  19. data/Gemfile.rails-4.1 +1 -3
  20. data/README.md +19 -2
  21. data/bullet.gemspec +4 -2
  22. data/lib/bullet.rb +39 -10
  23. data/lib/bullet/active_record3.rb +20 -2
  24. data/lib/bullet/active_record3x.rb +20 -2
  25. data/lib/bullet/active_record4.rb +20 -2
  26. data/lib/bullet/active_record41.rb +20 -2
  27. data/lib/bullet/detector/association.rb +14 -25
  28. data/lib/bullet/detector/base.rb +0 -6
  29. data/lib/bullet/detector/counter_cache.rb +10 -12
  30. data/lib/bullet/detector/n_plus_one_query.rb +12 -8
  31. data/lib/bullet/detector/unused_eager_loading.rb +5 -1
  32. data/lib/bullet/mongoid3x.rb +5 -4
  33. data/lib/bullet/mongoid4x.rb +5 -4
  34. data/lib/bullet/version.rb +1 -1
  35. data/spec/bullet/detector/association_spec.rb +0 -19
  36. data/spec/bullet/detector/base_spec.rb +0 -6
  37. data/spec/bullet/detector/counter_cache_spec.rb +0 -8
  38. data/spec/bullet/detector/n_plus_one_query_spec.rb +0 -6
  39. data/spec/bullet/detector/unused_eager_loading_spec.rb +0 -7
  40. data/spec/bullet/rack_spec.rb +1 -7
  41. data/spec/bullet/registry/object_spec.rb +0 -1
  42. data/spec/bullet_spec.rb +41 -0
  43. data/spec/integration/active_record3/association_spec.rb +18 -75
  44. data/spec/integration/active_record4/association_spec.rb +16 -75
  45. data/spec/integration/counter_cache_spec.rb +1 -1
  46. data/spec/integration/mongoid/association_spec.rb +0 -10
  47. data/spec/spec_helper.rb +17 -0
  48. data/spec/support/mongo_seed.rb +1 -1
  49. data/test.sh +1 -0
  50. metadata +7 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f5d5793126ed37cd4f560144b157258999c0b318
4
- data.tar.gz: 56e7d6b4a5d4a2fda7bcc9707523e4863159aa83
3
+ metadata.gz: e3badf3b077a980eaa5aff1923f4e73d702f5b91
4
+ data.tar.gz: f62fd9855dca76718f1abd484052e8b9ec841088
5
5
  SHA512:
6
- metadata.gz: 817982d863e94c8fb85379b07006536e83c4ea97e0b92a9f7cc4a1444dcba2f4743202a25a9a6f68b9be2cad20985bd6fb5c0a45a4015a93e782ac4eaaa95da9
7
- data.tar.gz: 14311a13bfd4b6bcd88f2f72271b3e39a681ee19c13d42aeba4318a7826e4e927792479b75f6d07357725699dd6d0a0d7b6c2545e3f37ed4d24fb86766d10b20
6
+ metadata.gz: cd79339a18313dd651739d819f59d33ceee240ec595ff53a49b27133010d8a83e9274292907ccd99bd9b894b7d975c54e4a65b49f0907b08f0b70a4a994dc9e1
7
+ data.tar.gz: 3dbb60cf0426b5cfb0d1fc5ac1bed620d139aafbf798eae0a7ebe94915a8b17fcc0a745b587313007a2922826f0b396f4be290dc353832f0c5e2618bedb29c50
data/.rspec CHANGED
@@ -1,2 +1,2 @@
1
1
  --colour
2
- --format nested
2
+ --format progress
@@ -1,6 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.1
3
+ - 2.1.2
4
4
  gemfile:
5
5
  - Gemfile.rails-4.1
6
6
  - Gemfile.rails-4.0
@@ -1,5 +1,12 @@
1
1
  # Next Release
2
2
 
3
+ ## 4.9.0 (04/30/2014)
4
+
5
+ * Add Bullet.stacktrace_includes option
6
+ * Applied keyword argument fixes on Ruby 2.2.0
7
+ * Add bugsnag notifier
8
+ * Support rails 4.1.0
9
+
3
10
  ## 4.8.0 (02/16/2014)
4
11
 
5
12
  * Support rails 4.1.0.beta1
data/Gemfile CHANGED
@@ -5,8 +5,6 @@ gemspec
5
5
  gem 'rails', github: 'rails/rails'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mysql2', platforms: [:ruby]
9
- gem 'activerecord-jdbcmysql-adapter', platforms: [:jruby]
10
8
  gem 'activerecord-import'
11
9
 
12
10
  gem "rspec"
@@ -18,4 +16,4 @@ gem 'coveralls', require: false
18
16
  platforms :rbx do
19
17
  gem 'rubysl', '~> 2.0'
20
18
  gem 'rubinius-developer_tools'
21
- end
19
+ end
@@ -3,9 +3,8 @@ source "https://rubygems.org"
3
3
  gemspec
4
4
 
5
5
  gem 'rails'
6
- gem 'sqlite3'
7
- gem 'mysql2'
8
- gem 'activerecord-import'
6
+ gem 'sqlite3', platforms: [:ruby]
7
+ gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
9
8
  gem 'mongoid', github: 'mongoid/mongoid'
10
9
 
11
10
  gem "rspec"
@@ -5,9 +5,6 @@ gemspec
5
5
  gem 'rails', '~> 3.2.16'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mysql2', platforms: [:ruby]
9
- gem 'activerecord-jdbcmysql-adapter', platforms: [:jruby]
10
- gem 'activerecord-import'
11
8
  gem 'mongoid', '~> 2.4.12'
12
9
 
13
10
  gem "rspec"
@@ -5,9 +5,6 @@ gemspec
5
5
  gem 'rails', '~> 3.2.16'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mysql2', platforms: [:ruby]
9
- gem 'activerecord-jdbcmysql-adapter', platforms: [:jruby]
10
- gem 'activerecord-import'
11
8
  gem 'mongoid', '~> 2.5.2'
12
9
 
13
10
  gem "rspec"
@@ -5,9 +5,6 @@ gemspec
5
5
  gem 'rails', '~> 3.2.16'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mysql2', platforms: [:ruby]
9
- gem 'activerecord-jdbcmysql-adapter', platforms: [:jruby]
10
- gem 'activerecord-import'
11
8
  gem 'mongoid', '~> 2.6.0'
12
9
 
13
10
  gem "rspec"
@@ -5,9 +5,6 @@ gemspec
5
5
  gem 'rails', '~> 3.2.16'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mysql2', platforms: [:ruby]
9
- gem 'activerecord-jdbcmysql-adapter', platforms: [:jruby]
10
- gem 'activerecord-import'
11
8
  gem 'mongoid', '~> 2.7.1'
12
9
 
13
10
  gem "rspec"
@@ -5,9 +5,6 @@ gemspec
5
5
  gem 'rails', '~> 3.2'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mysql2', platforms: [:ruby]
9
- gem 'activerecord-jdbcmysql-adapter', platforms: [:jruby]
10
- gem 'activerecord-import'
11
8
  gem 'mongoid', '~> 2.8'
12
9
 
13
10
  gem "rspec"
@@ -5,9 +5,6 @@ gemspec
5
5
  gem 'rails', '~> 3.2.16'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mysql2', platforms: [:ruby]
9
- gem 'activerecord-jdbcmysql-adapter', platforms: [:jruby]
10
- gem 'activerecord-import'
11
8
  gem 'mongoid', '~> 3.0.23'
12
9
 
13
10
  gem "rspec"
@@ -5,9 +5,6 @@ gemspec
5
5
  gem 'rails', '~> 3.2.16'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mysql2', platforms: [:ruby]
9
- gem 'activerecord-jdbcmysql-adapter', platforms: [:jruby]
10
- gem 'activerecord-import'
11
8
  gem 'mongoid', '~> 3.1.6'
12
9
 
13
10
  gem "rspec"
@@ -0,0 +1,19 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem 'rails', '~> 4.0.5'
6
+ gem 'sqlite3', platforms: [:ruby]
7
+ gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
+ gem 'mongoid', '~> 4.0.0.beta2'
9
+
10
+ gem "rspec"
11
+ gem "guard"
12
+ gem "guard-rspec"
13
+
14
+ gem 'coveralls', require: false
15
+
16
+ platforms :rbx do
17
+ gem 'rubysl', '~> 2.0'
18
+ gem 'rubinius-developer_tools'
19
+ end
@@ -5,8 +5,6 @@ gemspec
5
5
  gem 'rails', '~> 3.0.20'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mysql2', platforms: [:ruby]
9
- gem 'activerecord-jdbcmysql-adapter', platforms: [:jruby]
10
8
  gem 'activerecord-import'
11
9
 
12
10
  gem "rspec"
@@ -5,8 +5,6 @@ gemspec
5
5
  gem 'rails', '~> 3.1.12'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mysql2', platforms: [:ruby]
9
- gem 'activerecord-jdbcmysql-adapter', platforms: [:jruby]
10
8
  gem 'activerecord-import'
11
9
 
12
10
  gem "rspec"
@@ -18,4 +16,4 @@ gem 'coveralls', require: false
18
16
  platforms :rbx do
19
17
  gem 'rubysl', '~> 2.0'
20
18
  gem 'rubinius-developer_tools'
21
- end
19
+ end
@@ -2,11 +2,9 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'rails', '~> 3.2.17'
5
+ gem 'rails', '~> 3.2.18'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mysql2', platforms: [:ruby]
9
- gem 'activerecord-jdbcmysql-adapter', platforms: [:jruby]
10
8
  gem 'activerecord-import'
11
9
 
12
10
  gem "rspec"
@@ -2,11 +2,9 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'rails', '~> 4.0.4'
5
+ gem 'rails', '~> 4.0.5'
6
6
  gem 'sqlite3', platforms: [:ruby]
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mysql2', platforms: [:ruby]
9
- gem 'activerecord-jdbcmysql-adapter', platforms: [:jruby]
10
8
  gem 'activerecord-import'
11
9
 
12
10
  gem "rspec"
@@ -2,11 +2,9 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'rails', '~> 4.1.0'
5
+ gem 'rails', '~> 4.1.1'
6
6
  gem 'sqlite3'
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
8
- gem 'mysql2'
9
- gem 'activerecord-jdbcmysql-adapter', platforms: [:jruby]
10
8
  gem 'activerecord-import'
11
9
 
12
10
  gem "rspec"
data/README.md CHANGED
@@ -151,6 +151,18 @@ end
151
151
  warnings = Bullet.warnings
152
152
  ```
153
153
 
154
+ ### Work with sinatra
155
+
156
+ Configure and use bullet rack
157
+
158
+ ```ruby
159
+ configure :development do
160
+ Bullet.enable = true
161
+ Bullet.bullet_logger = true
162
+ use Bullet::Rack
163
+ end
164
+ ```
165
+
154
166
  ### Run in tests
155
167
 
156
168
  First you need to enable bullet in test environment.
@@ -168,16 +180,21 @@ Then wrap each test in bullet api.
168
180
 
169
181
  ```ruby
170
182
  # spec/spec_helper.rb
171
- before(:each) do
183
+ config.before(:each) do
172
184
  Bullet.start_request if Bullet.enable?
173
185
  end
174
186
 
175
- after(:each) do
187
+ config.after(:each) do
176
188
  Bullet.perform_out_of_channel_notifications if Bullet.enable? && Bullet.notification?
177
189
  Bullet.end_request if Bullet.enable?
178
190
  end
179
191
  ```
180
192
 
193
+ ## Debug Mode
194
+
195
+ Bullet outputs some details info, to enable debug mode, set DEBUG=true
196
+ env.
197
+
181
198
  ## Contributors
182
199
 
183
200
  [https://github.com/flyerhzm/bullet/contributors](https://github.com/flyerhzm/bullet/contributors)
@@ -13,10 +13,12 @@ Gem::Specification.new do |s|
13
13
  s.summary = "help to kill N+1 queries and unused eager loading."
14
14
  s.description = "help to kill N+1 queries and unused eager loading."
15
15
 
16
+ s.license = 'MIT'
17
+
16
18
  s.required_rubygems_version = ">= 1.3.6"
17
19
 
18
- s.add_dependency "activesupport"
19
- s.add_dependency "uniform_notifier", "~> 1.6.0"
20
+ s.add_runtime_dependency "activesupport"
21
+ s.add_runtime_dependency "uniform_notifier", "~> 1.6.0"
20
22
 
21
23
  s.files = `git ls-files`.split("\n")
22
24
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -27,7 +27,7 @@ module Bullet
27
27
  class << self
28
28
  attr_writer :enable, :n_plus_one_query_enable, :unused_eager_loading_enable, :counter_cache_enable, :stacktrace_includes
29
29
  attr_reader :notification_collector, :whitelist
30
- attr_accessor :add_footer
30
+ attr_accessor :add_footer, :orm_pathches_applied
31
31
 
32
32
  delegate :alert=, :console=, :growl=, :rails_logger=, :xmpp=, :airbrake=, :bugsnag=, :to => UniformNotifier
33
33
 
@@ -43,8 +43,11 @@ module Bullet
43
43
  @enable = @n_plus_one_query_enable = @unused_eager_loading_enable = @counter_cache_enable = enable
44
44
  if enable?
45
45
  reset_whitelist
46
- Bullet::Mongoid.enable if mongoid?
47
- Bullet::ActiveRecord.enable if active_record?
46
+ unless orm_pathches_applied
47
+ self.orm_pathches_applied = true
48
+ Bullet::Mongoid.enable if mongoid?
49
+ Bullet::ActiveRecord.enable if active_record?
50
+ end
48
51
  end
49
52
  end
50
53
 
@@ -83,27 +86,53 @@ module Bullet
83
86
 
84
87
  def bullet_logger=(active)
85
88
  if active
86
- bullet_log_file = File.open("#{rails? ? Rails.root.to_s : Dir.pwd}/log/bullet.log", 'a+')
89
+ require 'fileutils'
90
+ root_path = "#{rails? ? Rails.root.to_s : Dir.pwd}"
91
+ FileUtils.mkdir_p(root_path + '/log')
92
+ bullet_log_file = File.open("#{root_path}/log/bullet.log", 'a+')
87
93
  bullet_log_file.sync = true
88
94
  UniformNotifier.customized_logger = bullet_log_file
89
95
  end
90
96
  end
91
97
 
98
+ def debug(title, message)
99
+ puts "[Bullet][#{title}] #{message}" if ENV['DEBUG'] == 'true'
100
+ end
101
+
92
102
  def start_request
93
- notification_collector.reset
94
- DETECTORS.each { |bullet| bullet.start_request }
103
+ Thread.current[:bullet_start] = true
104
+ Thread.current[:bullet_notification_collector] = Bullet::NotificationCollector.new
105
+
106
+ Thread.current[:bullet_object_associations] = Bullet::Registry::Base.new
107
+ Thread.current[:bullet_call_object_associations] = Bullet::Registry::Base.new
108
+ Thread.current[:bullet_possible_objects] = Bullet::Registry::Object.new
109
+ Thread.current[:bullet_impossible_objects] = Bullet::Registry::Object.new
110
+ Thread.current[:bullet_eager_loadings] = Bullet::Registry::Association.new
111
+
112
+ Thread.current[:bullet_counter_possible_objects] ||= Bullet::Registry::Object.new
113
+ Thread.current[:bullet_counter_impossible_objects] ||= Bullet::Registry::Object.new
95
114
  end
96
115
 
97
116
  def end_request
98
- DETECTORS.each { |bullet| bullet.end_request }
117
+ Thread.current[:bullet_start] = nil
118
+ Thread.current[:bullet_notification_collector] = nil
119
+
120
+ Thread.current[:bullet_object_associations] = nil
121
+ Thread.current[:bullet_possible_objects] = nil
122
+ Thread.current[:bullet_impossible_objects] = nil
123
+ Thread.current[:bullet_call_object_associations] = nil
124
+ Thread.current[:bullet_eager_loadings] = nil
125
+
126
+ Thread.current[:bullet_counter_possible_objects] = nil
127
+ Thread.current[:bullet_counter_impossible_objects] = nil
99
128
  end
100
129
 
101
- def clear
102
- DETECTORS.each { |bullet| bullet.clear }
130
+ def start?
131
+ Thread.current[:bullet_start]
103
132
  end
104
133
 
105
134
  def notification_collector
106
- @notification_collector ||= Bullet::NotificationCollector.new
135
+ Thread.current[:bullet_notification_collector]
107
136
  end
108
137
 
109
138
  def notification?
@@ -42,7 +42,6 @@ module Bullet
42
42
  associations = (@eager_load_values + @includes_values).uniq
43
43
  records.each do |record|
44
44
  Bullet::Detector::Association.add_object_associations(record, associations)
45
- Bullet::Detector::NPlusOneQuery.call_association(record, associations)
46
45
  end
47
46
  Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
48
47
  records
@@ -50,13 +49,32 @@ module Bullet
50
49
  end
51
50
 
52
51
  ::ActiveRecord::Associations::ClassMethods::JoinDependency.class_eval do
52
+ alias_method :origin_instantiate, :instantiate
53
53
  alias_method :origin_construct_association, :construct_association
54
+
55
+ def instantiate(rows)
56
+ @bullet_eager_loadings = {}
57
+ records = origin_instantiate(rows)
58
+
59
+ @bullet_eager_loadings.each do |klazz, eager_loadings_hash|
60
+ objects = eager_loadings_hash.keys
61
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(objects, eager_loadings_hash[objects.first].to_a)
62
+ end
63
+ records
64
+ end
65
+
54
66
  # call join associations
55
67
  def construct_association(record, join, row)
68
+ result = origin_construct_association(record, join, row)
69
+
56
70
  associations = join.reflection.name
57
71
  Bullet::Detector::Association.add_object_associations(record, associations)
58
72
  Bullet::Detector::NPlusOneQuery.call_association(record, associations)
59
- origin_construct_association(record, join, row)
73
+ @bullet_eager_loadings[record.class] ||= {}
74
+ @bullet_eager_loadings[record.class][record] ||= Set.new
75
+ @bullet_eager_loadings[record.class][record] << associations
76
+
77
+ result
60
78
  end
61
79
  end
62
80
 
@@ -42,7 +42,6 @@ module Bullet
42
42
  associations = (eager_load_values + includes_values).uniq
43
43
  records.each do |record|
44
44
  Bullet::Detector::Association.add_object_associations(record, associations)
45
- Bullet::Detector::NPlusOneQuery.call_association(record, associations)
46
45
  end
47
46
  Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records, associations)
48
47
  records
@@ -50,13 +49,32 @@ module Bullet
50
49
  end
51
50
 
52
51
  ::ActiveRecord::Associations::JoinDependency.class_eval do
52
+ alias_method :origin_instantiate, :instantiate
53
53
  alias_method :origin_construct_association, :construct_association
54
+
55
+ def instantiate(rows)
56
+ @bullet_eager_loadings = {}
57
+ records = origin_instantiate(rows)
58
+
59
+ @bullet_eager_loadings.each do |klazz, eager_loadings_hash|
60
+ objects = eager_loadings_hash.keys
61
+ Bullet::Detector::UnusedEagerLoading.add_eager_loadings(objects, eager_loadings_hash[objects.first].to_a)
62
+ end
63
+ records
64
+ end
65
+
54
66
  # call join associations
55
67
  def construct_association(record, join, row)
68
+ result = origin_construct_association(record, join, row)
69
+
56
70
  associations = join.reflection.name
57
71
  Bullet::Detector::Association.add_object_associations(record, associations)
58
72
  Bullet::Detector::NPlusOneQuery.call_association(record, associations)
59
- origin_construct_association(record, join, row)
73
+ @bullet_eager_loadings[record.class] ||= {}
74
+ @bullet_eager_loadings[record.class][record] ||= Set.new
75
+ @bullet_eager_loadings[record.class][record] << associations
76
+
77
+ result
60
78
  end
61
79
  end
62
80