bullet 1.6.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.
- data/MIT-LICENSE +20 -0
- data/README.textile +381 -0
- data/Rakefile +33 -0
- data/VERSION +1 -0
- data/bullet.gemspec +59 -0
- data/lib/bullet.rb +77 -0
- data/lib/bullet/action_controller.rb +16 -0
- data/lib/bullet/active_record.rb +105 -0
- data/lib/bullet/association.rb +267 -0
- data/lib/bullet/counter.rb +101 -0
- data/lib/bullet/logger.rb +9 -0
- data/lib/bullet/notification.rb +83 -0
- data/lib/bulletware.rb +42 -0
- data/rails/init.rb +1 -0
- data/spec/bullet_association_spec.rb +1044 -0
- data/spec/bullet_counter_spec.rb +136 -0
- data/spec/spec.opts +8 -0
- data/spec/spec_helper.rb +50 -0
- data/tasks/bullet_tasks.rake +9 -0
- metadata +75 -0
@@ -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::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::Counter.start_request
|
51
|
+
end
|
52
|
+
|
53
|
+
after(:each) do
|
54
|
+
Bullet::Counter.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::Counter.should be_need_counter_caches
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should not need coounter cache with only one object" do
|
65
|
+
Country.first.cities.size
|
66
|
+
Bullet::Counter.should_not be_need_counter_caches
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should not need counter cache with part of cities" do
|
70
|
+
Country.all.each do |country|
|
71
|
+
country.cities(:conditions => ["name = ?", 'first']).size
|
72
|
+
end
|
73
|
+
Bullet::Counter.should_not be_need_counter_caches
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe Bullet::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::Counter.start_request
|
124
|
+
end
|
125
|
+
|
126
|
+
after(:each) do
|
127
|
+
Bullet::Counter.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::Counter.should_not be_need_counter_caches
|
135
|
+
end
|
136
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec/autorun'
|
3
|
+
require 'active_record'
|
4
|
+
require 'action_controller'
|
5
|
+
|
6
|
+
RAILS_ROOT = File.expand_path(__FILE__).split('/')[0..-3].join('/') unless defined? RAILS_ROOT
|
7
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/bullet/notification'))
|
8
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/bullet/logger'))
|
9
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/bullet/active_record'))
|
10
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/bullet/action_controller'))
|
11
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/bullet/association'))
|
12
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/bullet/counter'))
|
13
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/bullet'))
|
14
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/bulletware'))
|
15
|
+
Bullet.enable = true
|
16
|
+
|
17
|
+
module BulletTestHelper
|
18
|
+
def silence_logger(&block)
|
19
|
+
orig_stdout = $stdout
|
20
|
+
$stdout = StringIO.new
|
21
|
+
block.call
|
22
|
+
$stdout = orig_stdout
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Bullet
|
27
|
+
class Association
|
28
|
+
class <<self
|
29
|
+
# returns true if all associations are preloaded
|
30
|
+
def completely_preloading_associations?
|
31
|
+
!has_unpreload_associations?
|
32
|
+
end
|
33
|
+
|
34
|
+
# returns true if a given object has a specific association
|
35
|
+
def creating_object_association_for?(object, association)
|
36
|
+
object_associations[object].present? && object_associations[object].include?(association)
|
37
|
+
end
|
38
|
+
|
39
|
+
# returns true if a given class includes the specific unpreloaded association
|
40
|
+
def detecting_unpreloaded_association_for?(klazz, association)
|
41
|
+
unpreload_associations[klazz].present? && unpreload_associations[klazz].include?(association)
|
42
|
+
end
|
43
|
+
|
44
|
+
# returns true if the given class includes the specific unused preloaded association
|
45
|
+
def unused_preload_associations_for?(klazz, association)
|
46
|
+
unused_preload_associations[klazz].present? && unused_preload_associations[klazz].include?(association)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bullet
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.6.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Richard Huang
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-08 00:00:00 +08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: The Bullet plugin is designed to help you increase your application's performance by reducing the number of queries it makes. It will watch your queries while you develop your application and notify you when you should add eager loading (N+1 queries) or when you're using eager loading that isn't necessary.
|
17
|
+
email: flyerhzm@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.textile
|
24
|
+
files:
|
25
|
+
- MIT-LICENSE
|
26
|
+
- README.textile
|
27
|
+
- Rakefile
|
28
|
+
- VERSION
|
29
|
+
- bullet.gemspec
|
30
|
+
- lib/bullet.rb
|
31
|
+
- lib/bullet/action_controller.rb
|
32
|
+
- lib/bullet/active_record.rb
|
33
|
+
- lib/bullet/association.rb
|
34
|
+
- lib/bullet/counter.rb
|
35
|
+
- lib/bullet/logger.rb
|
36
|
+
- lib/bullet/notification.rb
|
37
|
+
- lib/bulletware.rb
|
38
|
+
- rails/init.rb
|
39
|
+
- spec/bullet_association_spec.rb
|
40
|
+
- spec/bullet_counter_spec.rb
|
41
|
+
- spec/spec.opts
|
42
|
+
- spec/spec_helper.rb
|
43
|
+
- tasks/bullet_tasks.rake
|
44
|
+
has_rdoc: true
|
45
|
+
homepage: http://github.com/flyerhzm/bullet
|
46
|
+
licenses: []
|
47
|
+
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options:
|
50
|
+
- --charset=UTF-8
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: "0"
|
64
|
+
version:
|
65
|
+
requirements: []
|
66
|
+
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 1.3.5
|
69
|
+
signing_key:
|
70
|
+
specification_version: 3
|
71
|
+
summary: A plugin to kill N+1 queries and unused eager loading
|
72
|
+
test_files:
|
73
|
+
- spec/bullet_counter_spec.rb
|
74
|
+
- spec/spec_helper.rb
|
75
|
+
- spec/bullet_association_spec.rb
|