bullet 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,136 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
4
+
5
+ describe Bullet::Detector::Counter do
6
+ def setup_db
7
+ ActiveRecord::Schema.define(:version => 1) do
8
+ create_table :countries do |t|
9
+ t.string :name
10
+ end
11
+
12
+ create_table :cities do |t|
13
+ t.string :name
14
+ t.integer :country_id
15
+ end
16
+ end
17
+ end
18
+
19
+ def teardown_db
20
+ ActiveRecord::Base.connection.tables.each do |table|
21
+ ActiveRecord::Base.connection.drop_table(table)
22
+ end
23
+ end
24
+
25
+ class Country < ActiveRecord::Base
26
+ has_many :cities
27
+ end
28
+
29
+ class City < ActiveRecord::Base
30
+ belongs_to :country
31
+ end
32
+
33
+ before(:all) do
34
+ setup_db
35
+
36
+ country1 = Country.create(:name => 'first')
37
+ country2 = Country.create(:name => 'second')
38
+
39
+ country1.cities.create(:name => 'first')
40
+ country1.cities.create(:name => 'second')
41
+ country2.cities.create(:name => 'third')
42
+ country2.cities.create(:name => 'fourth')
43
+ end
44
+
45
+ after(:all) do
46
+ teardown_db
47
+ end
48
+
49
+ before(:each) do
50
+ Bullet.start_request
51
+ end
52
+
53
+ after(:each) do
54
+ Bullet.end_request
55
+ end
56
+
57
+ it "should need counter cache with all cities" do
58
+ Country.all.each do |country|
59
+ country.cities.size
60
+ end
61
+ Bullet.collected_counter_cache_notifications.should_not be_empty
62
+ end
63
+
64
+ it "should not need coounter cache with only one object" do
65
+ Country.first.cities.size
66
+ Bullet.collected_counter_cache_notifications.should be_empty
67
+ end
68
+
69
+ it "should not need counter cache with part of cities" do
70
+ Country.all.each do |country|
71
+ country.cities.where(:name => 'first').size
72
+ end
73
+ Bullet.collected_counter_cache_notifications.should be_empty
74
+ end
75
+ end
76
+
77
+ describe Bullet::Detector::Counter do
78
+ def setup_db
79
+ ActiveRecord::Schema.define(:version => 1) do
80
+ create_table :people do |t|
81
+ t.string :name
82
+ t.integer :pets_count
83
+ end
84
+
85
+ create_table :pets do |t|
86
+ t.string :name
87
+ t.integer :person_id
88
+ end
89
+ end
90
+ end
91
+
92
+ def teardown_db
93
+ ActiveRecord::Base.connection.tables.each do |table|
94
+ ActiveRecord::Base.connection.drop_table(table)
95
+ end
96
+ end
97
+
98
+ class Person < ActiveRecord::Base
99
+ has_many :pets
100
+ end
101
+
102
+ class Pet < ActiveRecord::Base
103
+ belongs_to :person, :counter_cache => true
104
+ end
105
+
106
+ before(:all) do
107
+ setup_db
108
+
109
+ person1 = Person.create(:name => 'first')
110
+ person2 = Person.create(:name => 'second')
111
+
112
+ person1.pets.create(:name => 'first')
113
+ person1.pets.create(:name => 'second')
114
+ person2.pets.create(:name => 'third')
115
+ person2.pets.create(:name => 'fourth')
116
+ end
117
+
118
+ after(:all) do
119
+ teardown_db
120
+ end
121
+
122
+ before(:each) do
123
+ Bullet.start_request
124
+ end
125
+
126
+ after(:each) do
127
+ Bullet.end_request
128
+ end
129
+
130
+ it "should not need counter cache" do
131
+ Person.all.each do |person|
132
+ person.pets.size
133
+ end
134
+ Bullet.collected_counter_cache_notifications.should be_empty
135
+ end
136
+ end
@@ -0,0 +1,79 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ require 'rspec/autorun'
4
+ require 'rails'
5
+ require 'active_record'
6
+ require 'action_controller'
7
+
8
+ module Rails
9
+ class <<self
10
+ def root
11
+ File.expand_path(__FILE__).split('/')[0..-3].join('/')
12
+ end
13
+ end
14
+ end
15
+
16
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
17
+ require 'bullet'
18
+ Bullet.enable = true
19
+ ActiveRecord::Migration.verbose = false
20
+
21
+ module Bullet
22
+ def self.collected_notifications_of_class( notification_class )
23
+ Bullet.notification_collector.collection.select do |notification|
24
+ notification.is_a? notification_class
25
+ end
26
+ end
27
+
28
+ def self.collected_counter_cache_notifications
29
+ collected_notifications_of_class Bullet::Notification::CounterCache
30
+ end
31
+
32
+ def self.collected_n_plus_one_query_notifications
33
+ collected_notifications_of_class Bullet::Notification::NPlusOneQuery
34
+ end
35
+
36
+ def self.collected_unused_eager_association_notifications
37
+ collected_notifications_of_class Bullet::Notification::UnusedEagerLoading
38
+ end
39
+ end
40
+
41
+ module Bullet
42
+ module Detector
43
+ class Association
44
+ class <<self
45
+ # returns true if all associations are preloaded
46
+ def completely_preloading_associations?
47
+ Bullet.collected_n_plus_one_query_notifications.empty?
48
+ end
49
+
50
+ def has_unused_preload_associations?
51
+ Bullet.collected_unused_eager_association_notifications.present?
52
+ end
53
+
54
+ # returns true if a given object has a specific association
55
+ def creating_object_association_for?(object, association)
56
+ object_associations[object].present? && object_associations[object].include?(association)
57
+ end
58
+
59
+ # returns true if a given class includes the specific unpreloaded association
60
+ def detecting_unpreloaded_association_for?(klass, association)
61
+ for_class_and_assoc = Bullet.collected_n_plus_one_query_notifications.select do |notification|
62
+ notification.base_class == klass and
63
+ notification.associations.include?( association )
64
+ end
65
+ for_class_and_assoc.present?
66
+ end
67
+
68
+ # returns true if the given class includes the specific unused preloaded association
69
+ def unused_preload_associations_for?(klass, association)
70
+ for_class_and_assoc = Bullet.collected_unused_eager_association_notifications.select do |notification|
71
+ notification.base_class == klass and
72
+ notification.associations.include?( association )
73
+ end
74
+ for_class_and_assoc.present?
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,9 @@
1
+ namespace :bullet do
2
+ namespace :log do
3
+ desc "Truncates the bullet log file to zero bytes"
4
+ task :clear do
5
+ f = File.open("log/bullet.log", "w")
6
+ f.close
7
+ end
8
+ end
9
+ end
metadata CHANGED
@@ -1,111 +1,108 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: bullet
3
- version: !ruby/object:Gem::Version
4
- hash: 13
5
- prerelease: false
6
- segments:
7
- - 2
8
- - 0
9
- - 1
10
- version: 2.0.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.1.0
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Richard Huang
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2010-11-19 00:00:00 +08:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
22
- version_requirements: &id001 !ruby/object:Gem::Requirement
12
+ date: 2011-12-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: uniform_notifier
16
+ requirement: &2156581180 !ruby/object:Gem::Requirement
23
17
  none: false
24
- requirements:
18
+ requirements:
25
19
  - - ~>
26
- - !ruby/object:Gem::Version
27
- hash: 23
28
- segments:
29
- - 1
30
- - 0
31
- - 0
20
+ - !ruby/object:Gem::Version
32
21
  version: 1.0.0
33
- requirement: *id001
34
- name: uniform_notifier
35
- prerelease: false
36
22
  type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2156581180
37
25
  description: A rails plugin to kill N+1 queries and unused eager loading.
38
- email:
26
+ email:
39
27
  - flyerhzm@gmail.com
40
28
  executables: []
41
-
42
29
  extensions: []
43
-
44
- extra_rdoc_files:
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .gitignore
33
+ - .rspec
34
+ - .rvmrc
35
+ - .rvmrc.example
36
+ - .watchr
37
+ - Gemfile
38
+ - Gemfile.lock
39
+ - Hacking.textile
45
40
  - MIT-LICENSE
46
41
  - README.textile
47
42
  - README_for_rails2.textile
48
- files:
43
+ - Rakefile
44
+ - bullet.gemspec
45
+ - lib/bullet.rb
49
46
  - lib/bullet/action_controller2.rb
50
47
  - lib/bullet/active_record2.rb
51
48
  - lib/bullet/active_record3.rb
49
+ - lib/bullet/active_record31.rb
50
+ - lib/bullet/detector.rb
52
51
  - lib/bullet/detector/association.rb
53
52
  - lib/bullet/detector/base.rb
54
53
  - lib/bullet/detector/counter.rb
55
54
  - lib/bullet/detector/n_plus_one_query.rb
56
55
  - lib/bullet/detector/unused_eager_association.rb
57
- - lib/bullet/detector.rb
56
+ - lib/bullet/notification.rb
58
57
  - lib/bullet/notification/base.rb
59
58
  - lib/bullet/notification/counter_cache.rb
60
59
  - lib/bullet/notification/n_plus_one_query.rb
61
60
  - lib/bullet/notification/unused_eager_loading.rb
62
- - lib/bullet/notification.rb
63
61
  - lib/bullet/notification_collector.rb
64
62
  - lib/bullet/rack.rb
63
+ - lib/bullet/registry.rb
65
64
  - lib/bullet/registry/association.rb
66
65
  - lib/bullet/registry/base.rb
67
66
  - lib/bullet/registry/object.rb
68
- - lib/bullet/registry.rb
69
67
  - lib/bullet/version.rb
70
- - lib/bullet.rb
71
- - MIT-LICENSE
72
- - README.textile
73
- - README_for_rails2.textile
74
- has_rdoc: true
68
+ - perf/benchmark.rb
69
+ - rails/init.rb
70
+ - spec/bullet/association_for_chris_spec.rb
71
+ - spec/bullet/association_for_peschkaj_spec.rb
72
+ - spec/bullet/association_spec.rb
73
+ - spec/bullet/counter_spec.rb
74
+ - spec/spec_helper.rb
75
+ - tasks/bullet_tasks.rake
75
76
  homepage: http://github.com/flyerhzm/bullet
76
77
  licenses: []
77
-
78
78
  post_install_message:
79
79
  rdoc_options: []
80
-
81
- require_paths:
80
+ require_paths:
82
81
  - lib
83
- required_ruby_version: !ruby/object:Gem::Requirement
82
+ required_ruby_version: !ruby/object:Gem::Requirement
84
83
  none: false
85
- requirements:
86
- - - ">="
87
- - !ruby/object:Gem::Version
88
- hash: 3
89
- segments:
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ segments:
90
89
  - 0
91
- version: "0"
92
- required_rubygems_version: !ruby/object:Gem::Requirement
90
+ hash: -1237939251235315374
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
92
  none: false
94
- requirements:
95
- - - ">="
96
- - !ruby/object:Gem::Version
97
- hash: 23
98
- segments:
99
- - 1
100
- - 3
101
- - 6
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
102
96
  version: 1.3.6
103
97
  requirements: []
104
-
105
98
  rubyforge_project:
106
- rubygems_version: 1.3.7
99
+ rubygems_version: 1.8.10
107
100
  signing_key:
108
101
  specification_version: 3
109
102
  summary: A rails plugin to kill N+1 queries and unused eager loading.
110
- test_files: []
111
-
103
+ test_files:
104
+ - spec/bullet/association_for_chris_spec.rb
105
+ - spec/bullet/association_for_peschkaj_spec.rb
106
+ - spec/bullet/association_spec.rb
107
+ - spec/bullet/counter_spec.rb
108
+ - spec/spec_helper.rb