instructure-marginalia 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ tmp
4
+ marginalia_test
data/.rbenv-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.3-p0
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ script: bundle exec rake db:reset test:all
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,67 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ marginalia (1.1.0)
5
+ actionpack (>= 2.3, < 3.3)
6
+ activerecord (>= 2.3, < 3.3)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actionpack (3.1.3)
12
+ activemodel (= 3.1.3)
13
+ activesupport (= 3.1.3)
14
+ builder (~> 3.0.0)
15
+ erubis (~> 2.7.0)
16
+ i18n (~> 0.6)
17
+ rack (~> 1.3.5)
18
+ rack-cache (~> 1.1)
19
+ rack-mount (~> 0.8.2)
20
+ rack-test (~> 0.6.1)
21
+ sprockets (~> 2.0.3)
22
+ activemodel (3.1.3)
23
+ activesupport (= 3.1.3)
24
+ builder (~> 3.0.0)
25
+ i18n (~> 0.6)
26
+ activerecord (3.1.3)
27
+ activemodel (= 3.1.3)
28
+ activesupport (= 3.1.3)
29
+ arel (~> 2.2.1)
30
+ tzinfo (~> 0.3.29)
31
+ activesupport (3.1.3)
32
+ multi_json (~> 1.0)
33
+ arel (2.2.1)
34
+ builder (3.0.0)
35
+ erubis (2.7.0)
36
+ hike (1.2.1)
37
+ i18n (0.6.0)
38
+ multi_json (1.1.0)
39
+ mysql (2.8.1)
40
+ mysql2 (0.3.11)
41
+ pg (0.13.2)
42
+ rack (1.3.6)
43
+ rack-cache (1.1)
44
+ rack (>= 0.4)
45
+ rack-mount (0.8.3)
46
+ rack (>= 1.0.0)
47
+ rack-test (0.6.1)
48
+ rack (>= 1.0)
49
+ rake (0.9.2.2)
50
+ sprockets (2.0.3)
51
+ hike (~> 1.2)
52
+ rack (~> 1.0)
53
+ tilt (~> 1.1, != 1.3.0)
54
+ sqlite3 (1.3.6)
55
+ tilt (1.3.3)
56
+ tzinfo (0.3.32)
57
+
58
+ PLATFORMS
59
+ ruby
60
+
61
+ DEPENDENCIES
62
+ marginalia!
63
+ mysql
64
+ mysql2
65
+ pg
66
+ rake
67
+ sqlite3
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ # Copyright (c) 2012 37signals, LLC
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.md ADDED
@@ -0,0 +1,112 @@
1
+ # marginalia [![Build Status](https://secure.travis-ci.org/37signals/marginalia.png?branch=master)](http://travis-ci.org/37signals/marginalia)
2
+
3
+ Attach comments to your ActiveRecord queries. By default, it adds the application, controller, and action names as a
4
+ comment at the end of each query.
5
+
6
+ This helps when searching log files for queries, and seeing where slow queries came from.
7
+
8
+ For example, once enabled, your logs will look like:
9
+
10
+ Account Load (0.3ms) SELECT `accounts`.* FROM `accounts`
11
+ WHERE `accounts`.`queenbee_id` = 1234567890
12
+ LIMIT 1
13
+ /*application:BCX,controller:project_imports,action:show*/
14
+
15
+ You can also use these query comments along with a tool like [pt-query-digest](http://www.percona.com/doc/percona-toolkit/2.1/pt-query-digest.html#query-reviews)
16
+ to automate identification of controllers and actions that are hotspots forslow queries.
17
+
18
+ This gem was created at 37signals. You can read more about how we use it [on
19
+ our blog](http://37signals.com/svn/posts/3130-tech-note-mysql-query-comments-in-rails).
20
+
21
+ This has been tested and used in production with both the mysql and mysql2 gems,
22
+ tested on Rails 2.3.5 through 3.2-stable. It has also been tested for sqlite3 and postgres.
23
+
24
+ Patches are welcome for other database adapters.
25
+
26
+ **The preferred way to get support is to send an email to
27
+ marginalia@librelist.com. Github issues
28
+ and pull requests will be checked occassionally, but email is the
29
+ fastest way to get help.**
30
+
31
+ ## Installation
32
+
33
+ ### For Rails 3.x:
34
+
35
+ # Gemfile
36
+ gem 'marginalia'
37
+
38
+ #config/application.rb
39
+ require 'marginalia/railtie'
40
+
41
+
42
+ ### For Rails 2.x:
43
+
44
+ If using cached externals, add to your `config/externals.yml` file.
45
+
46
+ Or, if your prefer using `config.gem`, you can use:
47
+
48
+ config.gem 'marginalia'
49
+
50
+ Finally, if bundled, you'll need to manually run the initialization step in an
51
+ initializer, e.g.:
52
+
53
+ # Gemfile
54
+ gem 'marginalia', :require => false
55
+
56
+ #config/initializers/marginalia.rb
57
+ require 'marginalia'
58
+ Marginalia::Railtie.insert
59
+
60
+ ### Customization
61
+ Optionally, you can set the application name shown in the log like so in an initializer (e.g. `config/initializers/marginalia.rb`):
62
+
63
+ Marginalia.application_name = "BCX"
64
+
65
+ For Rails 3 applications, the name will default to your Rails application name.
66
+ For Rails 2 applications, "rails" is used as the default application name.
67
+
68
+ You can also configure the components of the comment that will be appended,
69
+ by setting `Marginalia::Comment.components`. By default, this is set to:
70
+
71
+ Marginalia::Comment.components = [:application, :controller, :action]
72
+
73
+ Which results in a comment of
74
+ `application:#{application_name},controller:#{controller.name},action:#{action_name}`.
75
+
76
+ You can re-order or remove these components. You can also add additional
77
+ comment components of your desire by defining new module methods for
78
+ `Marginalia::Comment` which return a string. For example:
79
+
80
+ module Marginalia
81
+ module Comment
82
+ def self.mycommentcomponent
83
+ "TEST"
84
+ end
85
+ end
86
+ end
87
+
88
+ Marginalia::Comment.components = [:application, :mycommentcomponent]
89
+
90
+ Which will result in a comment like
91
+ `application:#{application_name},mycommentcomponent:TEST`
92
+ The calling controller is available to these methods via `@controller`.
93
+
94
+ Marginalia ships with `:application`, `:controller`, and `:action` enabled by
95
+ default. In addition, implementation is provided for:
96
+ * `:line` (for file and line number calling query). :line supports
97
+ a configuration by setting a regexp in `Marginalia::Comment.lines_to_ignore`
98
+ to exclude parts of the stacktrace from inclusion in the line comment.
99
+
100
+ Pull requests for other included comment components are welcome.
101
+
102
+ ## Contributing
103
+
104
+ Start by bundling and creating the test database:
105
+
106
+ bundle
107
+ rake db:create
108
+
109
+ Then, running `rake` will run the tests on both the `mysql` and `mysql2` adapters:
110
+
111
+ rake
112
+
data/Rakefile ADDED
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ task :default => ['test:all']
5
+
6
+ namespace :test do
7
+ desc "test all drivers"
8
+ task :all => [:mysql, :mysql2, :postgresql, :sqlite]
9
+
10
+ desc "test mysql driver"
11
+ task :mysql do
12
+ sh "DRIVER=mysql ruby -Ilib -Itest test/*_test.rb"
13
+ end
14
+
15
+ desc "test mysql2 driver"
16
+ task :mysql2 do
17
+ sh "DRIVER=mysql2 ruby -Ilib -Itest test/*_test.rb"
18
+ end
19
+
20
+ desc "test PostgreSQL driver"
21
+ task :postgresql do
22
+ sh "DRIVER=postgresql DB_USERNAME=postgres ruby -Ilib -Itest test/*_test.rb"
23
+ end
24
+
25
+ desc "test sqlite3 driver"
26
+ task :sqlite do
27
+ sh "DRIVER=sqlite3 ruby -Ilib -Itest test/*_test.rb"
28
+ end
29
+ end
30
+
31
+ namespace :db do
32
+
33
+ desc "reset all databases"
34
+ task :reset => [:"mysql:reset", :"postgresql:reset"]
35
+
36
+ namespace :mysql do
37
+ desc "reset MySQL database"
38
+ task :reset => [:drop, :create]
39
+
40
+ desc "create MySQL database"
41
+ task :create do
42
+ sh 'mysql -u root -e "create database marginalia_test;"'
43
+ end
44
+
45
+ desc "drop MySQL database"
46
+ task :drop do
47
+ sh 'mysql -u root -e "drop database if exists marginalia_test;"'
48
+ end
49
+ end
50
+
51
+ namespace :postgresql do
52
+ desc "reset PostgreSQL database"
53
+ task :reset => [:drop, :create]
54
+
55
+ desc "create PostgreSQL database"
56
+ task :create do
57
+ sh 'createdb -U postgres marginalia_test'
58
+ end
59
+
60
+ desc "drop PostgreSQL database"
61
+ task :drop do
62
+ sh 'psql -d postgres -U postgres -c "DROP DATABASE IF EXISTS marginalia_test"'
63
+ end
64
+ end
65
+
66
+ end
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'marginalia/railtie'
2
+ Marginalia::Railtie.insert
data/lib/marginalia.rb ADDED
@@ -0,0 +1,41 @@
1
+ require 'marginalia/railtie'
2
+ require 'marginalia/comment'
3
+
4
+ module Marginalia
5
+ mattr_accessor :application_name
6
+
7
+ module ActiveRecordInstrumentation
8
+ def self.included(instrumented_class)
9
+ Marginalia::Comment.components = [:application, :controller, :action]
10
+ instrumented_class.class_eval do
11
+ if method_defined? :execute
12
+ alias_method :execute_without_marginalia, :execute
13
+ alias_method :execute, :execute_with_marginalia
14
+ end
15
+
16
+ if method_defined? :exec_query
17
+ alias_method :exec_query_without_marginalia, :exec_query
18
+ alias_method :exec_query, :exec_query_with_marginalia
19
+ end
20
+ end
21
+ end
22
+
23
+ def annotate_sql(sql)
24
+ comment = Marginalia::Comment.construct_comment
25
+ if comment.present? && !sql.match(comment)
26
+ "#{sql} /*#{comment}*/"
27
+ else
28
+ sql
29
+ end
30
+ end
31
+
32
+ def execute_with_marginalia(sql, name = nil)
33
+ execute_without_marginalia(annotate_sql(sql), name)
34
+ end
35
+
36
+ def exec_query_with_marginalia(sql, name = 'SQL', binds = [])
37
+ exec_query_without_marginalia(annotate_sql(sql), name, binds)
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,76 @@
1
+ require 'socket'
2
+
3
+ module Marginalia
4
+ module Comment
5
+ mattr_accessor :components, :lines_to_ignore
6
+
7
+ def self.update!(controller = nil)
8
+ @controller = controller
9
+ end
10
+
11
+ def self.construct_comment
12
+ ret = ''
13
+ self.components.each do |c|
14
+ component_value = self.send(c)
15
+ if component_value.present?
16
+ ret << ',' if ret.present?
17
+ ret << c.to_s << ':' << component_value.to_s
18
+ end
19
+ end
20
+ ret
21
+ end
22
+
23
+ def self.clear!
24
+ @controller = nil
25
+ end
26
+
27
+ private
28
+ def self.application
29
+ if defined? Rails.application
30
+ Marginalia.application_name ||= Rails.application.class.name.split("::").first
31
+ else
32
+ Marginalia.application_name ||= "rails"
33
+ end
34
+
35
+ Marginalia.application_name
36
+ end
37
+
38
+ def self.controller
39
+ @controller.controller_name if @controller.respond_to? :controller_name
40
+ end
41
+
42
+ def self.action
43
+ @controller.action_name if @controller.respond_to? :action_name
44
+ end
45
+
46
+ def self.line
47
+ Marginalia::Comment.lines_to_ignore ||= /\.rvm|gem|vendor|marginalia|rbenv/
48
+ last_line = caller.detect do |line|
49
+ line !~ Marginalia::Comment.lines_to_ignore
50
+ end
51
+ if last_line
52
+ root = if defined?(Rails) && Rails.respond_to?(:root)
53
+ Rails.root.to_s
54
+ elsif defined?(RAILS_ROOT)
55
+ RAILS_ROOT
56
+ else
57
+ ""
58
+ end
59
+ if last_line.starts_with? root
60
+ last_line = last_line[root.length..-1]
61
+ end
62
+ last_line
63
+ end
64
+ end
65
+
66
+ def self.hostname
67
+ @cached_hostname ||= Socket.gethostname
68
+ end
69
+
70
+ def self.pid
71
+ Process.pid
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,73 @@
1
+ require 'marginalia'
2
+
3
+ module Marginalia
4
+ if defined? Rails::Railtie
5
+ require 'rails/railtie'
6
+
7
+ class Railtie < Rails::Railtie
8
+ initializer 'marginalia.insert' do
9
+ ActiveSupport.on_load :active_record do
10
+ Marginalia::Railtie.insert_into_active_record
11
+ end
12
+
13
+ ActiveSupport.on_load :action_controller do
14
+ Marginalia::Railtie.insert_into_action_controller
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ class Railtie
21
+ def self.insert
22
+ insert_into_active_record
23
+ insert_into_action_controller
24
+ end
25
+
26
+ def self.insert_into_action_controller
27
+ ActionController::Base.class_eval do
28
+ def record_query_comment
29
+ Marginalia::Comment.update!(self)
30
+ yield
31
+ ensure
32
+ Marginalia::Comment.clear!
33
+ end
34
+ around_filter :record_query_comment
35
+ end
36
+ end
37
+
38
+ def self.insert_into_active_record
39
+ if defined? ActiveRecord::ConnectionAdapters::Mysql2Adapter
40
+ if ActiveRecord::Base.connection.is_a?(ActiveRecord::ConnectionAdapters::Mysql2Adapter)
41
+ ActiveRecord::ConnectionAdapters::Mysql2Adapter.module_eval do
42
+ include Marginalia::ActiveRecordInstrumentation
43
+ end
44
+ end
45
+ end
46
+
47
+ if defined? ActiveRecord::ConnectionAdapters::MysqlAdapter
48
+ if ActiveRecord::Base.connection.is_a?(ActiveRecord::ConnectionAdapters::MysqlAdapter)
49
+ ActiveRecord::ConnectionAdapters::MysqlAdapter.module_eval do
50
+ include Marginalia::ActiveRecordInstrumentation
51
+ end
52
+ end
53
+ end
54
+
55
+ # SQL queries made through PostgreSQLAdapter#exec_delete will not be annotated.
56
+ if defined? ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
57
+ if ActiveRecord::Base.connection.is_a?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
58
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.module_eval do
59
+ include Marginalia::ActiveRecordInstrumentation
60
+ end
61
+ end
62
+ end
63
+
64
+ if defined? ActiveRecord::ConnectionAdapters::SQLiteAdapter
65
+ if ActiveRecord::Base.connection.is_a?(ActiveRecord::ConnectionAdapters::SQLiteAdapter)
66
+ ActiveRecord::ConnectionAdapters::SQLiteAdapter.module_eval do
67
+ include Marginalia::ActiveRecordInstrumentation
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,22 @@
1
+ Gem::Specification.new do |gem|
2
+ gem.authors = ["Noah Lorang", "Nick Quaranto", "Taylor Weibley"]
3
+ gem.email = ["noah@37signals.com"]
4
+ gem.homepage = "https://github.com/37signals/marginalia"
5
+
6
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
7
+ gem.files = `git ls-files`.split("\n")
8
+ gem.test_files = `git ls-files -- {test}/*`.split("\n")
9
+ gem.name = "instructure-marginalia"
10
+ gem.require_paths = ["lib"]
11
+ gem.version = "1.1.3"
12
+
13
+ gem.add_runtime_dependency "actionpack", ">= 2.3", "< 3.3"
14
+ gem.add_runtime_dependency "activerecord", ">= 2.3", "< 3.3"
15
+ gem.add_development_dependency "rake"
16
+ gem.add_development_dependency "mysql"
17
+ gem.add_development_dependency "mysql2"
18
+ gem.add_development_dependency "pg"
19
+ gem.add_development_dependency "sqlite3"
20
+
21
+ gem.summary = description = %q{Attach comments to your ActiveRecord queries.}
22
+ end
@@ -0,0 +1,99 @@
1
+ require 'test/unit'
2
+ require 'logger'
3
+ require 'pp'
4
+ require 'active_record'
5
+ require 'action_controller'
6
+ require 'marginalia'
7
+ RAILS_ROOT = File.expand_path(File.dirname(__FILE__))
8
+
9
+ ActiveRecord::Base.establish_connection({
10
+ :adapter => ENV["DRIVER"] || "mysql",
11
+ :host => "localhost",
12
+ :username => ENV["DB_USERNAME"] || "root",
13
+ :database => "marginalia_test"
14
+ })
15
+
16
+ class Post < ActiveRecord::Base
17
+ end
18
+
19
+ class PostsController < ActionController::Base
20
+ def driver_only
21
+ ActiveRecord::Base.connection.execute "select id from posts"
22
+ render :nothing => true
23
+ end
24
+ end
25
+
26
+ unless Post.table_exists?
27
+ ActiveRecord::Schema.define do
28
+ create_table "posts", :force => true do |t|
29
+ end
30
+ end
31
+ end
32
+
33
+ Marginalia::Railtie.insert
34
+
35
+ class MarginaliaTest < Test::Unit::TestCase
36
+ def setup
37
+ @queries = []
38
+ ActiveSupport::Notifications.subscribe "sql.active_record" do |*args|
39
+ @queries << args.last[:sql]
40
+ end
41
+ @env = Rack::MockRequest.env_for('/')
42
+ end
43
+
44
+ def test_query_commenting_on_mysql_driver_with_no_action
45
+ ActiveRecord::Base.connection.execute "select id from posts"
46
+ assert_match %r{select id from posts /\*application:rails\*/$}, @queries.first
47
+ end
48
+
49
+ def test_query_commenting_on_mysql_driver_with_action
50
+ PostsController.action(:driver_only).call(@env)
51
+ assert_match %r{select id from posts /\*application:rails,controller:posts,action:driver_only\*/$}, @queries.first
52
+ end
53
+
54
+ def test_configuring_application
55
+ Marginalia.application_name = "customapp"
56
+ PostsController.action(:driver_only).call(@env)
57
+
58
+ assert_match %r{/\*application:customapp,controller:posts,action:driver_only\*/$}, @queries.first
59
+ end
60
+
61
+ def test_configuring_query_components
62
+ Marginalia::Comment.components = [:controller]
63
+ PostsController.action(:driver_only).call(@env)
64
+
65
+ assert_match %r{/\*controller:posts\*/$}, @queries.first
66
+ end
67
+
68
+ def test_last_line_component
69
+ Marginalia::Comment.components = [:line]
70
+ PostsController.action(:driver_only).call(@env)
71
+
72
+ # Because "lines_to_ignore" by default includes "marginalia" and "gem", the
73
+ # extracted line line will be from the line in this file that actually
74
+ # triggers the query.
75
+ assert_match %r{/\*line:test/query_comments_test.rb:[0-9]+:in `driver_only'\*/$}, @queries.first
76
+ end
77
+
78
+ def test_last_line_component_with_lines_to_ignore
79
+ Marginalia::Comment.lines_to_ignore = /foo bar/
80
+ Marginalia::Comment.components = [:line]
81
+ PostsController.action(:driver_only).call(@env)
82
+ # Because "lines_to_ignore" does not include "marginalia", the extracted
83
+ # line will be from marginalia/comment.rb.
84
+ assert_match %r{/\*line:.*lib/marginalia/comment.rb:[0-9]+}, @queries.first
85
+ end
86
+
87
+ def test_hostname_and_pid
88
+ Marginalia::Comment.components = [:hostname, :pid]
89
+ PostsController.action(:driver_only).call(@env)
90
+ assert_match %r{/\*hostname:#{Socket.gethostname},pid:#{Process.pid}\*/$}, @queries.first
91
+
92
+ end
93
+
94
+ def teardown
95
+ Marginalia.application_name = nil
96
+ Marginalia::Comment.components = [:application, :controller, :action]
97
+ ActiveSupport::Notifications.unsubscribe "sql.active_record"
98
+ end
99
+ end
metadata ADDED
@@ -0,0 +1,185 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: instructure-marginalia
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Noah Lorang
9
+ - Nick Quaranto
10
+ - Taylor Weibley
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2013-04-08 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: actionpack
18
+ requirement: !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ! '>='
22
+ - !ruby/object:Gem::Version
23
+ version: '2.3'
24
+ - - <
25
+ - !ruby/object:Gem::Version
26
+ version: '3.3'
27
+ type: :runtime
28
+ prerelease: false
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ! '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '2.3'
35
+ - - <
36
+ - !ruby/object:Gem::Version
37
+ version: '3.3'
38
+ - !ruby/object:Gem::Dependency
39
+ name: activerecord
40
+ requirement: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '2.3'
46
+ - - <
47
+ - !ruby/object:Gem::Version
48
+ version: '3.3'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '2.3'
57
+ - - <
58
+ - !ruby/object:Gem::Version
59
+ version: '3.3'
60
+ - !ruby/object:Gem::Dependency
61
+ name: rake
62
+ requirement: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ - !ruby/object:Gem::Dependency
77
+ name: mysql
78
+ requirement: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ type: :development
85
+ prerelease: false
86
+ version_requirements: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ - !ruby/object:Gem::Dependency
93
+ name: mysql2
94
+ requirement: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ type: :development
101
+ prerelease: false
102
+ version_requirements: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ - !ruby/object:Gem::Dependency
109
+ name: pg
110
+ requirement: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ! '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ type: :development
117
+ prerelease: false
118
+ version_requirements: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ! '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ - !ruby/object:Gem::Dependency
125
+ name: sqlite3
126
+ requirement: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ none: false
136
+ requirements:
137
+ - - ! '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ description:
141
+ email:
142
+ - noah@37signals.com
143
+ executables: []
144
+ extensions: []
145
+ extra_rdoc_files: []
146
+ files:
147
+ - .gitignore
148
+ - .rbenv-version
149
+ - .travis.yml
150
+ - Gemfile
151
+ - Gemfile.lock
152
+ - LICENSE
153
+ - README.md
154
+ - Rakefile
155
+ - init.rb
156
+ - lib/marginalia.rb
157
+ - lib/marginalia/comment.rb
158
+ - lib/marginalia/railtie.rb
159
+ - marginalia.gemspec
160
+ - test/query_comments_test.rb
161
+ homepage: https://github.com/37signals/marginalia
162
+ licenses: []
163
+ post_install_message:
164
+ rdoc_options: []
165
+ require_paths:
166
+ - lib
167
+ required_ruby_version: !ruby/object:Gem::Requirement
168
+ none: false
169
+ requirements:
170
+ - - ! '>='
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ required_rubygems_version: !ruby/object:Gem::Requirement
174
+ none: false
175
+ requirements:
176
+ - - ! '>='
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ requirements: []
180
+ rubyforge_project:
181
+ rubygems_version: 1.8.23
182
+ signing_key:
183
+ specification_version: 3
184
+ summary: Attach comments to your ActiveRecord queries.
185
+ test_files: []