query_diet 0.1.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/.gitignore +5 -0
- data/.idea/encodings.xml +5 -0
- data/.idea/misc.xml +25 -0
- data/.idea/modules.xml +9 -0
- data/.idea/query_diet.iml +25 -0
- data/.idea/vcs.xml +8 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +34 -0
- data/Rakefile +37 -0
- data/VERSION +1 -0
- data/lib/query_diet/action_controller_ext.rb +15 -0
- data/lib/query_diet/active_record_ext.rb +11 -0
- data/lib/query_diet/logger.rb +41 -0
- data/lib/query_diet/widget.rb +58 -0
- data/lib/query_diet.rb +5 -0
- data/query_diet.gemspec +93 -0
- data/spec/app_root/app/controllers/application_controller.rb +2 -0
- data/spec/app_root/app/controllers/query_diet_controller.rb +21 -0
- data/spec/app_root/app/models/movie.rb +3 -0
- data/spec/app_root/app/views/layouts/screen.html.erb +6 -0
- data/spec/app_root/app/views/query_diet/no_query.html.erb +3 -0
- data/spec/app_root/app/views/query_diet/two_queries.html.erb +3 -0
- data/spec/app_root/config/boot.rb +114 -0
- data/spec/app_root/config/database.yml +21 -0
- data/spec/app_root/config/environment.rb +14 -0
- data/spec/app_root/config/environments/in_memory.rb +0 -0
- data/spec/app_root/config/environments/mysql.rb +0 -0
- data/spec/app_root/config/environments/postgresql.rb +0 -0
- data/spec/app_root/config/environments/sqlite.rb +0 -0
- data/spec/app_root/config/environments/sqlite3.rb +0 -0
- data/spec/app_root/config/routes.rb +4 -0
- data/spec/app_root/db/migrate/001_create_movies.rb +14 -0
- data/spec/app_root/lib/console_with_fixtures.rb +4 -0
- data/spec/app_root/log/.gitignore +1 -0
- data/spec/app_root/script/console +7 -0
- data/spec/controllers/query_diet_controller_spec.rb +43 -0
- data/spec/logger_spec.rb +29 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/support/rcov.opts +2 -0
- data/spec/support/spec.opts +4 -0
- metadata +116 -0
data/.idea/encodings.xml
ADDED
data/.idea/misc.xml
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="DependencyValidationManager">
|
|
4
|
+
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
|
|
5
|
+
</component>
|
|
6
|
+
<component name="ProjectDetails">
|
|
7
|
+
<option name="projectName" value="query_diet" />
|
|
8
|
+
</component>
|
|
9
|
+
<component name="ProjectRootManager" version="2" project-jdk-name="Ruby SDK 1.8.7 (/usr/bin/ruby)" project-jdk-type="RUBY_SDK" />
|
|
10
|
+
<component name="SvnConfiguration">
|
|
11
|
+
<option name="USER" value="" />
|
|
12
|
+
<option name="PASSWORD" value="" />
|
|
13
|
+
<option name="LAST_MERGED_REVISION" />
|
|
14
|
+
<option name="UPDATE_RUN_STATUS" value="false" />
|
|
15
|
+
<option name="MERGE_DRY_RUN" value="false" />
|
|
16
|
+
<option name="MERGE_DIFF_USE_ANCESTRY" value="true" />
|
|
17
|
+
<option name="UPDATE_LOCK_ON_DEMAND" value="false" />
|
|
18
|
+
<option name="IGNORE_SPACES_IN_MERGE" value="false" />
|
|
19
|
+
<option name="DETECT_NESTED_COPIES" value="false" />
|
|
20
|
+
<option name="IGNORE_SPACES_IN_ANNOTATE" value="true" />
|
|
21
|
+
<option name="SHOW_MERGE_SOURCES_IN_ANNOTATE" value="true" />
|
|
22
|
+
<myIsUseDefaultProxy>false</myIsUseDefaultProxy>
|
|
23
|
+
</component>
|
|
24
|
+
</project>
|
|
25
|
+
|
data/.idea/modules.xml
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="ProjectModuleManager">
|
|
4
|
+
<modules>
|
|
5
|
+
<module fileurl="file://$PROJECT_DIR$/.idea/query_diet.iml" filepath="$PROJECT_DIR$/.idea/query_diet.iml" />
|
|
6
|
+
</modules>
|
|
7
|
+
</component>
|
|
8
|
+
</project>
|
|
9
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="RUBY_MODULE" version="4">
|
|
3
|
+
<component name="GemRequirementsHolder" version="2">
|
|
4
|
+
<requirement>
|
|
5
|
+
<requirement>
|
|
6
|
+
<dependency name="rails" version="0" bound="GREATER_OR_EQUAL" git="false" />
|
|
7
|
+
</requirement>
|
|
8
|
+
<source from="spec/app_root/config/boot.rb" />
|
|
9
|
+
</requirement>
|
|
10
|
+
</component>
|
|
11
|
+
<component name="NewModuleRootManager">
|
|
12
|
+
<content url="file://$MODULE_DIR$" />
|
|
13
|
+
<orderEntry type="inheritedJdk" />
|
|
14
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
15
|
+
<orderEntry type="library" scope="PROVIDED" name="[gem] rails (v2.3.5, /usr/lib/ruby/gems/1.8/gems/rails-2.3.5)" level="application" />
|
|
16
|
+
<orderEntry type="library" scope="PROVIDED" name="[gem] activerecord (v2.3.5, /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5)" level="application" />
|
|
17
|
+
<orderEntry type="library" scope="PROVIDED" name="[gem] rack (v1.0.1, /usr/lib/ruby/gems/1.8/gems/rack-1.0.1)" level="application" />
|
|
18
|
+
<orderEntry type="library" scope="PROVIDED" name="[gem] rake (v0.8.7, /usr/lib/ruby/gems/1.8/gems/rake-0.8.7)" level="application" />
|
|
19
|
+
<orderEntry type="library" scope="PROVIDED" name="[gem] activesupport (v2.3.5, /usr/lib/ruby/gems/1.8/gems/activesupport-2.3.5)" level="application" />
|
|
20
|
+
<orderEntry type="library" scope="PROVIDED" name="[gem] actionpack (v2.3.5, /usr/lib/ruby/gems/1.8/gems/actionpack-2.3.5)" level="application" />
|
|
21
|
+
<orderEntry type="library" scope="PROVIDED" name="[gem] actionmailer (v2.3.5, /usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.5)" level="application" />
|
|
22
|
+
<orderEntry type="library" scope="PROVIDED" name="[gem] activeresource (v2.3.5, /usr/lib/ruby/gems/1.8/gems/activeresource-2.3.5)" level="application" />
|
|
23
|
+
</component>
|
|
24
|
+
</module>
|
|
25
|
+
|
data/.idea/vcs.xml
ADDED
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2009 Henning Koch
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
= query_diet
|
|
2
|
+
|
|
3
|
+
query_diet counts the number of database queries for the last request and *subtly* displays it in the upper right corner of your screen.
|
|
4
|
+
The display turns red if too many queries are run, or if they take too long.
|
|
5
|
+
This is useful to prevent {N + 1 queries}[http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations] from creeping into your code.
|
|
6
|
+
|
|
7
|
+
== Installation
|
|
8
|
+
|
|
9
|
+
Install the gem with
|
|
10
|
+
sudo gem install query_diet
|
|
11
|
+
|
|
12
|
+
There is no further setup necessary after you add the <tt>query_diet</tt> dependency to your Rails application.
|
|
13
|
+
|
|
14
|
+
We recommend you only use the gem with the development environment.
|
|
15
|
+
|
|
16
|
+
== Changing warning thresholds
|
|
17
|
+
|
|
18
|
+
You can define when the counter turns into a red warning. The default threshold is 8 queries and 5000 miliseconds.
|
|
19
|
+
To change the default, add the following to <tt>config/initializers/query_diet.rb</tt>:
|
|
20
|
+
|
|
21
|
+
if defined?(QueryDiet)
|
|
22
|
+
QueryDiet::Logger.bad_count = 8
|
|
23
|
+
QueryDiet::Logger.bad_time = 5000
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
== Rails 3 compatibility
|
|
27
|
+
|
|
28
|
+
We cannot guarantee Rails 3 compatibility at this point, but we will upgrade the gem when Rails 3 is released.
|
|
29
|
+
|
|
30
|
+
=== Credits
|
|
31
|
+
|
|
32
|
+
Henning Koch
|
|
33
|
+
|
|
34
|
+
{www.makandra.de}[http://www.makandra.de/]
|
data/Rakefile
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require 'rake'
|
|
2
|
+
# require 'rake/testtask'
|
|
3
|
+
require 'rake/rdoctask'
|
|
4
|
+
require 'spec/rake/spectask'
|
|
5
|
+
|
|
6
|
+
desc 'Default: Run all specs.'
|
|
7
|
+
task :default => :spec
|
|
8
|
+
|
|
9
|
+
desc "Run all specs"
|
|
10
|
+
Spec::Rake::SpecTask.new() do |t|
|
|
11
|
+
t.spec_opts = ['--options', "\"spec/support/spec.opts\""]
|
|
12
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
desc 'Generate documentation for the query_diet gem.'
|
|
16
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
18
|
+
rdoc.title = 'query_diet'
|
|
19
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
|
20
|
+
rdoc.rdoc_files.include('README')
|
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
begin
|
|
25
|
+
require 'jeweler'
|
|
26
|
+
Jeweler::Tasks.new do |gemspec|
|
|
27
|
+
gemspec.name = "query_diet"
|
|
28
|
+
gemspec.summary = "Rails database query counter that stays out of your way"
|
|
29
|
+
gemspec.email = "github@makandra.de"
|
|
30
|
+
gemspec.homepage = "http://github.com/makandra/query_diet"
|
|
31
|
+
gemspec.description = "Rails database query counter that stays out of your way"
|
|
32
|
+
gemspec.authors = ["Henning Koch"]
|
|
33
|
+
end
|
|
34
|
+
rescue LoadError
|
|
35
|
+
puts "Jeweler not available. Install it with: sudo gem install jeweler"
|
|
36
|
+
end
|
|
37
|
+
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.0
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require_dependency 'application_controller'
|
|
2
|
+
|
|
3
|
+
ApplicationController.class_eval do
|
|
4
|
+
|
|
5
|
+
around_filter :query_diet_logging
|
|
6
|
+
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
def query_diet_logging
|
|
10
|
+
QueryDiet::Logger.reset
|
|
11
|
+
yield
|
|
12
|
+
QueryDiet::Widget.render(response)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module QueryDiet
|
|
2
|
+
class Logger
|
|
3
|
+
class << self
|
|
4
|
+
|
|
5
|
+
attr_accessor :count, :time, :bad_count, :bad_time
|
|
6
|
+
|
|
7
|
+
def reset
|
|
8
|
+
self.count = 0
|
|
9
|
+
self.time = 0
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def log(query, &execution)
|
|
13
|
+
result = nil
|
|
14
|
+
seconds = Benchmark.realtime do
|
|
15
|
+
result = execution.call
|
|
16
|
+
end
|
|
17
|
+
if log_query?(query)
|
|
18
|
+
self.time += (seconds * 1000).to_i
|
|
19
|
+
self.count += 1
|
|
20
|
+
end
|
|
21
|
+
result
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def bad?
|
|
25
|
+
count >= bad_count or time >= bad_time
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def log_query?(query)
|
|
31
|
+
query =~ /^(select|create|update|delete|insert)\b/i
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
reset
|
|
37
|
+
self.bad_count = 8
|
|
38
|
+
self.bad_time = 5000
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module QueryDiet
|
|
2
|
+
class Widget
|
|
3
|
+
class << self
|
|
4
|
+
|
|
5
|
+
def render(response)
|
|
6
|
+
body = response.body
|
|
7
|
+
if response.content_type == "text/html" && position = body.index('</body>')
|
|
8
|
+
body.insert(position, css)
|
|
9
|
+
body.insert(position, html)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def css
|
|
16
|
+
<<-EOF
|
|
17
|
+
<style type="text/css"><!--
|
|
18
|
+
div#query_diet {
|
|
19
|
+
position: absolute;
|
|
20
|
+
top: 0px;
|
|
21
|
+
right: 0px;
|
|
22
|
+
background-color: black;
|
|
23
|
+
color: white;
|
|
24
|
+
z-index: 999;
|
|
25
|
+
padding: 4px 6px;
|
|
26
|
+
font-family; arial, sans-serif;
|
|
27
|
+
font-size: 12px;
|
|
28
|
+
line-height: 12px;
|
|
29
|
+
font-weight: bold;
|
|
30
|
+
cursor: pointer;
|
|
31
|
+
}
|
|
32
|
+
div#query_diet.good {
|
|
33
|
+
xbackground-color: #160;
|
|
34
|
+
filter:alpha(opacity=30);
|
|
35
|
+
-moz-opacity:0.3;
|
|
36
|
+
-khtml-opacity: 0.3;
|
|
37
|
+
opacity: 0.3;
|
|
38
|
+
}
|
|
39
|
+
div#query_diet.bad {
|
|
40
|
+
background-color: red;
|
|
41
|
+
font-size: 16px;
|
|
42
|
+
line-height: 16px;
|
|
43
|
+
}
|
|
44
|
+
--></style>
|
|
45
|
+
EOF
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def html
|
|
49
|
+
<<-EOF
|
|
50
|
+
<div id="query_diet" class="#{QueryDiet::Logger.bad? ? 'bad' : 'good' }" onclick="this.parentNode.removeChild(this);">
|
|
51
|
+
#{QueryDiet::Logger.count} / #{QueryDiet::Logger.time}ms
|
|
52
|
+
</div>
|
|
53
|
+
EOF
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
data/lib/query_diet.rb
ADDED
data/query_diet.gemspec
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Generated by jeweler
|
|
2
|
+
# DO NOT EDIT THIS FILE
|
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
|
4
|
+
# -*- encoding: utf-8 -*-
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |s|
|
|
7
|
+
s.name = %q{query_diet}
|
|
8
|
+
s.version = "0.1.0"
|
|
9
|
+
|
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
|
+
s.authors = ["Henning Koch"]
|
|
12
|
+
s.date = %q{2010-06-23}
|
|
13
|
+
s.description = %q{Rails database query counter that stays out of your way}
|
|
14
|
+
s.email = %q{github@makandra.de}
|
|
15
|
+
s.extra_rdoc_files = [
|
|
16
|
+
"README.rdoc"
|
|
17
|
+
]
|
|
18
|
+
s.files = [
|
|
19
|
+
".gitignore",
|
|
20
|
+
".idea/encodings.xml",
|
|
21
|
+
".idea/misc.xml",
|
|
22
|
+
".idea/modules.xml",
|
|
23
|
+
".idea/query_diet.iml",
|
|
24
|
+
".idea/vcs.xml",
|
|
25
|
+
"MIT-LICENSE",
|
|
26
|
+
"README.rdoc",
|
|
27
|
+
"Rakefile",
|
|
28
|
+
"VERSION",
|
|
29
|
+
"lib/query_diet.rb",
|
|
30
|
+
"lib/query_diet/action_controller_ext.rb",
|
|
31
|
+
"lib/query_diet/active_record_ext.rb",
|
|
32
|
+
"lib/query_diet/logger.rb",
|
|
33
|
+
"lib/query_diet/widget.rb",
|
|
34
|
+
"query_diet.gemspec",
|
|
35
|
+
"spec/app_root/app/controllers/application_controller.rb",
|
|
36
|
+
"spec/app_root/app/controllers/query_diet_controller.rb",
|
|
37
|
+
"spec/app_root/app/models/movie.rb",
|
|
38
|
+
"spec/app_root/app/views/layouts/screen.html.erb",
|
|
39
|
+
"spec/app_root/app/views/query_diet/no_query.html.erb",
|
|
40
|
+
"spec/app_root/app/views/query_diet/two_queries.html.erb",
|
|
41
|
+
"spec/app_root/config/boot.rb",
|
|
42
|
+
"spec/app_root/config/database.yml",
|
|
43
|
+
"spec/app_root/config/environment.rb",
|
|
44
|
+
"spec/app_root/config/environments/in_memory.rb",
|
|
45
|
+
"spec/app_root/config/environments/mysql.rb",
|
|
46
|
+
"spec/app_root/config/environments/postgresql.rb",
|
|
47
|
+
"spec/app_root/config/environments/sqlite.rb",
|
|
48
|
+
"spec/app_root/config/environments/sqlite3.rb",
|
|
49
|
+
"spec/app_root/config/routes.rb",
|
|
50
|
+
"spec/app_root/db/migrate/001_create_movies.rb",
|
|
51
|
+
"spec/app_root/lib/console_with_fixtures.rb",
|
|
52
|
+
"spec/app_root/log/.gitignore",
|
|
53
|
+
"spec/app_root/script/console",
|
|
54
|
+
"spec/controllers/query_diet_controller_spec.rb",
|
|
55
|
+
"spec/logger_spec.rb",
|
|
56
|
+
"spec/spec_helper.rb",
|
|
57
|
+
"spec/support/rcov.opts",
|
|
58
|
+
"spec/support/spec.opts"
|
|
59
|
+
]
|
|
60
|
+
s.homepage = %q{http://github.com/makandra/query_diet}
|
|
61
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
|
62
|
+
s.require_paths = ["lib"]
|
|
63
|
+
s.rubygems_version = %q{1.3.6}
|
|
64
|
+
s.summary = %q{Rails database query counter that stays out of your way}
|
|
65
|
+
s.test_files = [
|
|
66
|
+
"spec/spec_helper.rb",
|
|
67
|
+
"spec/app_root/db/migrate/001_create_movies.rb",
|
|
68
|
+
"spec/app_root/config/boot.rb",
|
|
69
|
+
"spec/app_root/config/environment.rb",
|
|
70
|
+
"spec/app_root/config/routes.rb",
|
|
71
|
+
"spec/app_root/config/environments/in_memory.rb",
|
|
72
|
+
"spec/app_root/config/environments/mysql.rb",
|
|
73
|
+
"spec/app_root/config/environments/postgresql.rb",
|
|
74
|
+
"spec/app_root/config/environments/sqlite.rb",
|
|
75
|
+
"spec/app_root/config/environments/sqlite3.rb",
|
|
76
|
+
"spec/app_root/lib/console_with_fixtures.rb",
|
|
77
|
+
"spec/app_root/app/controllers/application_controller.rb",
|
|
78
|
+
"spec/app_root/app/controllers/query_diet_controller.rb",
|
|
79
|
+
"spec/app_root/app/models/movie.rb",
|
|
80
|
+
"spec/controllers/query_diet_controller_spec.rb",
|
|
81
|
+
"spec/logger_spec.rb"
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
if s.respond_to? :specification_version then
|
|
85
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
86
|
+
s.specification_version = 3
|
|
87
|
+
|
|
88
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
|
89
|
+
else
|
|
90
|
+
end
|
|
91
|
+
else
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
class QueryDietController < ApplicationController
|
|
2
|
+
|
|
3
|
+
layout 'screen'
|
|
4
|
+
|
|
5
|
+
def no_query
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def two_queries
|
|
9
|
+
Movie.create!
|
|
10
|
+
Movie.all
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def no_body_tag
|
|
14
|
+
render :text => "no body tag", :content_type => "text/html"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def yaml
|
|
18
|
+
render :text => { :foo => '<body></body>' }.to_yaml, :content_type => 'text/yaml'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Allow customization of the rails framework path
|
|
2
|
+
RAILS_FRAMEWORK_ROOT = (ENV['RAILS_FRAMEWORK_ROOT'] || "#{File.dirname(__FILE__)}/../../../../../../vendor/rails") unless defined?(RAILS_FRAMEWORK_ROOT)
|
|
3
|
+
|
|
4
|
+
# Don't change this file!
|
|
5
|
+
# Configure your app in config/environment.rb and config/environments/*.rb
|
|
6
|
+
|
|
7
|
+
RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
|
|
8
|
+
|
|
9
|
+
module Rails
|
|
10
|
+
class << self
|
|
11
|
+
def boot!
|
|
12
|
+
unless booted?
|
|
13
|
+
preinitialize
|
|
14
|
+
pick_boot.run
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def booted?
|
|
19
|
+
defined? Rails::Initializer
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def pick_boot
|
|
23
|
+
(vendor_rails? ? VendorBoot : GemBoot).new
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def vendor_rails?
|
|
27
|
+
File.exist?(RAILS_FRAMEWORK_ROOT)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def preinitialize
|
|
31
|
+
load(preinitializer_path) if File.exist?(preinitializer_path)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def preinitializer_path
|
|
35
|
+
"#{RAILS_ROOT}/config/preinitializer.rb"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
class Boot
|
|
40
|
+
def run
|
|
41
|
+
load_initializer
|
|
42
|
+
Rails::Initializer.run(:set_load_path)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
class VendorBoot < Boot
|
|
47
|
+
def load_initializer
|
|
48
|
+
require "#{RAILS_FRAMEWORK_ROOT}/railties/lib/initializer"
|
|
49
|
+
Rails::Initializer.run(:install_gem_spec_stubs)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
class GemBoot < Boot
|
|
54
|
+
def load_initializer
|
|
55
|
+
self.class.load_rubygems
|
|
56
|
+
load_rails_gem
|
|
57
|
+
require 'initializer'
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def load_rails_gem
|
|
61
|
+
if version = self.class.gem_version
|
|
62
|
+
gem 'rails', version
|
|
63
|
+
else
|
|
64
|
+
gem 'rails'
|
|
65
|
+
end
|
|
66
|
+
rescue Gem::LoadError => load_error
|
|
67
|
+
$stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
|
|
68
|
+
exit 1
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
class << self
|
|
72
|
+
def rubygems_version
|
|
73
|
+
Gem::RubyGemsVersion rescue nil
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def gem_version
|
|
77
|
+
if defined? RAILS_GEM_VERSION
|
|
78
|
+
RAILS_GEM_VERSION
|
|
79
|
+
elsif ENV.include?('RAILS_GEM_VERSION')
|
|
80
|
+
ENV['RAILS_GEM_VERSION']
|
|
81
|
+
else
|
|
82
|
+
parse_gem_version(read_environment_rb)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def load_rubygems
|
|
87
|
+
require 'rubygems'
|
|
88
|
+
min_version = '1.1.1'
|
|
89
|
+
unless rubygems_version >= min_version
|
|
90
|
+
$stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
|
|
91
|
+
exit 1
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
rescue LoadError
|
|
95
|
+
$stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
|
|
96
|
+
exit 1
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def parse_gem_version(text)
|
|
100
|
+
$1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
private
|
|
104
|
+
def read_environment_rb
|
|
105
|
+
environment_rb = "#{RAILS_ROOT}/config/environment.rb"
|
|
106
|
+
environment_rb = "#{HELPER_RAILS_ROOT}/config/environment.rb" unless File.exists?(environment_rb)
|
|
107
|
+
File.read(environment_rb)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# All that for this:
|
|
114
|
+
Rails.boot!
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
in_memory:
|
|
2
|
+
adapter: sqlite3
|
|
3
|
+
database: ":memory:"
|
|
4
|
+
verbosity: quiet
|
|
5
|
+
sqlite:
|
|
6
|
+
adapter: sqlite
|
|
7
|
+
dbfile: plugin_test.sqlite.db
|
|
8
|
+
sqlite3:
|
|
9
|
+
adapter: sqlite3
|
|
10
|
+
dbfile: plugin_test.sqlite3.db
|
|
11
|
+
postgresql:
|
|
12
|
+
adapter: postgresql
|
|
13
|
+
username: postgres
|
|
14
|
+
password: postgres
|
|
15
|
+
database: plugin_test
|
|
16
|
+
mysql:
|
|
17
|
+
adapter: mysql
|
|
18
|
+
host: localhost
|
|
19
|
+
username: root
|
|
20
|
+
password:
|
|
21
|
+
database: plugin_test
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'boot')
|
|
2
|
+
|
|
3
|
+
Rails::Initializer.run do |config|
|
|
4
|
+
config.cache_classes = false
|
|
5
|
+
config.whiny_nils = true
|
|
6
|
+
config.action_controller.session = { :key => "_myapp_session", :secret => "gwirofjweroijger8924rt2zfwehfuiwehb1378rifowenfoqwphf23" }
|
|
7
|
+
config.plugin_locators.unshift(
|
|
8
|
+
Class.new(Rails::Plugin::Locator) do
|
|
9
|
+
def plugins
|
|
10
|
+
[Rails::Plugin.new(File.expand_path('.'))]
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
) unless defined?(PluginTestHelper::PluginLocator)
|
|
14
|
+
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# Loads fixtures into the database when running the test app via the console
|
|
2
|
+
(ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(Rails.root, '../fixtures/*.{yml,csv}'))).each do |fixture_file|
|
|
3
|
+
Fixtures.create_fixtures(File.join(Rails.root, '../fixtures'), File.basename(fixture_file, '.*'))
|
|
4
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*.log
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe QueryDietController do
|
|
4
|
+
integrate_views
|
|
5
|
+
|
|
6
|
+
describe 'widget' do
|
|
7
|
+
|
|
8
|
+
it "should be automatically included in a HTML page" do
|
|
9
|
+
get :two_queries
|
|
10
|
+
response.body.should have_tag('div#query_diet')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should not be included in pages that have no body tag" do
|
|
14
|
+
get :no_body_tag
|
|
15
|
+
response.body.should_not have_tag('div#query_diet')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "should not be included in pages that are not text/html" do
|
|
19
|
+
get :yaml
|
|
20
|
+
response.body.should_not have_tag('div#query_diet')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should be highlighted if the request was too intimate with the database" do
|
|
24
|
+
QueryDiet::Logger.stub :bad? => true
|
|
25
|
+
get :no_query
|
|
26
|
+
response.body.should have_tag('div#query_diet.bad')
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should not be highlighted if the request spent little time in the database" do
|
|
30
|
+
QueryDiet::Logger.stub :bad? => false
|
|
31
|
+
get :no_query
|
|
32
|
+
response.body.should have_tag('div#query_diet.good')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should contain the number of requests and the duration spent running queries" do
|
|
36
|
+
QueryDiet::Logger.stub :count => 78, :time => 43500
|
|
37
|
+
get :no_query
|
|
38
|
+
response.body.should have_tag('div#query_diet', :text => "78 / 43500ms")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
data/spec/logger_spec.rb
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe QueryDiet::Logger do
|
|
4
|
+
|
|
5
|
+
before :each do
|
|
6
|
+
QueryDiet::Logger.reset
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe 'count' do
|
|
10
|
+
|
|
11
|
+
it "should return the number of queries since the last reset" do
|
|
12
|
+
Movie.create
|
|
13
|
+
Movie.create
|
|
14
|
+
QueryDiet::Logger.count.should == 2
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe 'time' do
|
|
20
|
+
|
|
21
|
+
it "should return the number of miliseconds spent running database queries since the last reset" do
|
|
22
|
+
Benchmark.should_receive(:realtime).and_return(5)
|
|
23
|
+
Movie.create
|
|
24
|
+
QueryDiet::Logger.time.should == 5000
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
$: << File.join(File.dirname(__FILE__), "/../lib" )
|
|
2
|
+
|
|
3
|
+
# Set the default environment to sqlite3's in_memory database
|
|
4
|
+
ENV['RAILS_ENV'] ||= 'in_memory'
|
|
5
|
+
|
|
6
|
+
# Load the Rails environment and testing framework
|
|
7
|
+
require "#{File.dirname(__FILE__)}/app_root/config/environment"
|
|
8
|
+
require "#{File.dirname(__FILE__)}/../lib/query_diet"
|
|
9
|
+
require 'spec/rails'
|
|
10
|
+
|
|
11
|
+
# Undo changes to RAILS_ENV
|
|
12
|
+
silence_warnings {RAILS_ENV = ENV['RAILS_ENV']}
|
|
13
|
+
|
|
14
|
+
# Run the migrations
|
|
15
|
+
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate")
|
|
16
|
+
|
|
17
|
+
Spec::Runner.configure do |config|
|
|
18
|
+
config.use_transactional_fixtures = true
|
|
19
|
+
config.use_instantiated_fixtures = false
|
|
20
|
+
end
|
|
21
|
+
|
metadata
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: query_diet
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
prerelease: false
|
|
5
|
+
segments:
|
|
6
|
+
- 0
|
|
7
|
+
- 1
|
|
8
|
+
- 0
|
|
9
|
+
version: 0.1.0
|
|
10
|
+
platform: ruby
|
|
11
|
+
authors:
|
|
12
|
+
- Henning Koch
|
|
13
|
+
autorequire:
|
|
14
|
+
bindir: bin
|
|
15
|
+
cert_chain: []
|
|
16
|
+
|
|
17
|
+
date: 2010-06-23 00:00:00 +02:00
|
|
18
|
+
default_executable:
|
|
19
|
+
dependencies: []
|
|
20
|
+
|
|
21
|
+
description: Rails database query counter that stays out of your way
|
|
22
|
+
email: github@makandra.de
|
|
23
|
+
executables: []
|
|
24
|
+
|
|
25
|
+
extensions: []
|
|
26
|
+
|
|
27
|
+
extra_rdoc_files:
|
|
28
|
+
- README.rdoc
|
|
29
|
+
files:
|
|
30
|
+
- .gitignore
|
|
31
|
+
- .idea/encodings.xml
|
|
32
|
+
- .idea/misc.xml
|
|
33
|
+
- .idea/modules.xml
|
|
34
|
+
- .idea/query_diet.iml
|
|
35
|
+
- .idea/vcs.xml
|
|
36
|
+
- MIT-LICENSE
|
|
37
|
+
- README.rdoc
|
|
38
|
+
- Rakefile
|
|
39
|
+
- VERSION
|
|
40
|
+
- lib/query_diet.rb
|
|
41
|
+
- lib/query_diet/action_controller_ext.rb
|
|
42
|
+
- lib/query_diet/active_record_ext.rb
|
|
43
|
+
- lib/query_diet/logger.rb
|
|
44
|
+
- lib/query_diet/widget.rb
|
|
45
|
+
- query_diet.gemspec
|
|
46
|
+
- spec/app_root/app/controllers/application_controller.rb
|
|
47
|
+
- spec/app_root/app/controllers/query_diet_controller.rb
|
|
48
|
+
- spec/app_root/app/models/movie.rb
|
|
49
|
+
- spec/app_root/app/views/layouts/screen.html.erb
|
|
50
|
+
- spec/app_root/app/views/query_diet/no_query.html.erb
|
|
51
|
+
- spec/app_root/app/views/query_diet/two_queries.html.erb
|
|
52
|
+
- spec/app_root/config/boot.rb
|
|
53
|
+
- spec/app_root/config/database.yml
|
|
54
|
+
- spec/app_root/config/environment.rb
|
|
55
|
+
- spec/app_root/config/environments/in_memory.rb
|
|
56
|
+
- spec/app_root/config/environments/mysql.rb
|
|
57
|
+
- spec/app_root/config/environments/postgresql.rb
|
|
58
|
+
- spec/app_root/config/environments/sqlite.rb
|
|
59
|
+
- spec/app_root/config/environments/sqlite3.rb
|
|
60
|
+
- spec/app_root/config/routes.rb
|
|
61
|
+
- spec/app_root/db/migrate/001_create_movies.rb
|
|
62
|
+
- spec/app_root/lib/console_with_fixtures.rb
|
|
63
|
+
- spec/app_root/log/.gitignore
|
|
64
|
+
- spec/app_root/script/console
|
|
65
|
+
- spec/controllers/query_diet_controller_spec.rb
|
|
66
|
+
- spec/logger_spec.rb
|
|
67
|
+
- spec/spec_helper.rb
|
|
68
|
+
- spec/support/rcov.opts
|
|
69
|
+
- spec/support/spec.opts
|
|
70
|
+
has_rdoc: true
|
|
71
|
+
homepage: http://github.com/makandra/query_diet
|
|
72
|
+
licenses: []
|
|
73
|
+
|
|
74
|
+
post_install_message:
|
|
75
|
+
rdoc_options:
|
|
76
|
+
- --charset=UTF-8
|
|
77
|
+
require_paths:
|
|
78
|
+
- lib
|
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
80
|
+
requirements:
|
|
81
|
+
- - ">="
|
|
82
|
+
- !ruby/object:Gem::Version
|
|
83
|
+
segments:
|
|
84
|
+
- 0
|
|
85
|
+
version: "0"
|
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
|
+
requirements:
|
|
88
|
+
- - ">="
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
segments:
|
|
91
|
+
- 0
|
|
92
|
+
version: "0"
|
|
93
|
+
requirements: []
|
|
94
|
+
|
|
95
|
+
rubyforge_project:
|
|
96
|
+
rubygems_version: 1.3.6
|
|
97
|
+
signing_key:
|
|
98
|
+
specification_version: 3
|
|
99
|
+
summary: Rails database query counter that stays out of your way
|
|
100
|
+
test_files:
|
|
101
|
+
- spec/spec_helper.rb
|
|
102
|
+
- spec/app_root/db/migrate/001_create_movies.rb
|
|
103
|
+
- spec/app_root/config/boot.rb
|
|
104
|
+
- spec/app_root/config/environment.rb
|
|
105
|
+
- spec/app_root/config/routes.rb
|
|
106
|
+
- spec/app_root/config/environments/in_memory.rb
|
|
107
|
+
- spec/app_root/config/environments/mysql.rb
|
|
108
|
+
- spec/app_root/config/environments/postgresql.rb
|
|
109
|
+
- spec/app_root/config/environments/sqlite.rb
|
|
110
|
+
- spec/app_root/config/environments/sqlite3.rb
|
|
111
|
+
- spec/app_root/lib/console_with_fixtures.rb
|
|
112
|
+
- spec/app_root/app/controllers/application_controller.rb
|
|
113
|
+
- spec/app_root/app/controllers/query_diet_controller.rb
|
|
114
|
+
- spec/app_root/app/models/movie.rb
|
|
115
|
+
- spec/controllers/query_diet_controller_spec.rb
|
|
116
|
+
- spec/logger_spec.rb
|