query_diet 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/.gitignore +5 -0
  2. data/.idea/encodings.xml +5 -0
  3. data/.idea/misc.xml +25 -0
  4. data/.idea/modules.xml +9 -0
  5. data/.idea/query_diet.iml +25 -0
  6. data/.idea/vcs.xml +8 -0
  7. data/MIT-LICENSE +20 -0
  8. data/README.rdoc +34 -0
  9. data/Rakefile +37 -0
  10. data/VERSION +1 -0
  11. data/lib/query_diet/action_controller_ext.rb +15 -0
  12. data/lib/query_diet/active_record_ext.rb +11 -0
  13. data/lib/query_diet/logger.rb +41 -0
  14. data/lib/query_diet/widget.rb +58 -0
  15. data/lib/query_diet.rb +5 -0
  16. data/query_diet.gemspec +93 -0
  17. data/spec/app_root/app/controllers/application_controller.rb +2 -0
  18. data/spec/app_root/app/controllers/query_diet_controller.rb +21 -0
  19. data/spec/app_root/app/models/movie.rb +3 -0
  20. data/spec/app_root/app/views/layouts/screen.html.erb +6 -0
  21. data/spec/app_root/app/views/query_diet/no_query.html.erb +3 -0
  22. data/spec/app_root/app/views/query_diet/two_queries.html.erb +3 -0
  23. data/spec/app_root/config/boot.rb +114 -0
  24. data/spec/app_root/config/database.yml +21 -0
  25. data/spec/app_root/config/environment.rb +14 -0
  26. data/spec/app_root/config/environments/in_memory.rb +0 -0
  27. data/spec/app_root/config/environments/mysql.rb +0 -0
  28. data/spec/app_root/config/environments/postgresql.rb +0 -0
  29. data/spec/app_root/config/environments/sqlite.rb +0 -0
  30. data/spec/app_root/config/environments/sqlite3.rb +0 -0
  31. data/spec/app_root/config/routes.rb +4 -0
  32. data/spec/app_root/db/migrate/001_create_movies.rb +14 -0
  33. data/spec/app_root/lib/console_with_fixtures.rb +4 -0
  34. data/spec/app_root/log/.gitignore +1 -0
  35. data/spec/app_root/script/console +7 -0
  36. data/spec/controllers/query_diet_controller_spec.rb +43 -0
  37. data/spec/logger_spec.rb +29 -0
  38. data/spec/spec_helper.rb +21 -0
  39. data/spec/support/rcov.opts +2 -0
  40. data/spec/support/spec.opts +4 -0
  41. metadata +116 -0
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ doc
2
+ pkg
3
+ *.gem
4
+ .idea
5
+
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
4
+ </project>
5
+
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
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="" vcs="" />
5
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
6
+ </component>
7
+ </project>
8
+
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,11 @@
1
+ ActiveRecord::Base.connection.class.class_eval do
2
+
3
+ def execute_with_query_diet(query, name = nil)
4
+ QueryDiet::Logger.log(query) do
5
+ execute_without_query_diet(query, name)
6
+ end
7
+ end
8
+
9
+ alias_method_chain :execute, :query_diet
10
+
11
+ 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
@@ -0,0 +1,5 @@
1
+ require 'query_diet/logger'
2
+ require 'query_diet/widget'
3
+ require 'query_diet/active_record_ext'
4
+ require 'query_diet/action_controller_ext'
5
+
@@ -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,2 @@
1
+ class ApplicationController < ActionController::Base
2
+ 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,3 @@
1
+ class Movie < ActiveRecord::Base
2
+
3
+ end
@@ -0,0 +1,6 @@
1
+ <html>
2
+ <body>
3
+ <h1>Title</h1>
4
+ <%= yield %>
5
+ </body>
6
+ </html>
@@ -0,0 +1,3 @@
1
+ <p>
2
+ No query.
3
+ </p>
@@ -0,0 +1,3 @@
1
+ <p>
2
+ Two queries.
3
+ </p>
@@ -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
+ ActionController::Routing::Routes.draw do |map|
2
+ map.connect ':controller/:action/:id'
3
+ map.connect ':controller/:action/:id.:format'
4
+ end
@@ -0,0 +1,14 @@
1
+ class CreateMovies < ActiveRecord::Migration
2
+
3
+ def self.up
4
+ create_table :movies do |t|
5
+ t.string :title
6
+ t.integer :year
7
+ end
8
+ end
9
+
10
+ def self.down
11
+ drop_table :movies
12
+ end
13
+
14
+ end
@@ -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,7 @@
1
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
2
+ libs = " -r irb/completion"
3
+ libs << " -r test/test_helper"
4
+ libs << " -r console_app"
5
+ libs << " -r console_with_helpers"
6
+ libs << " -r console_with_fixtures"
7
+ exec "#{irb} #{libs} --simple-prompt"
@@ -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
@@ -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
@@ -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
+
@@ -0,0 +1,2 @@
1
+ --exclude "spec/*,gems/*"
2
+ --rails
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --format progress
3
+ --loadby mtime
4
+ --reverse
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