marginalia 1.6.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bda214f48d77afb13f9c9182a550272d4e654c4f
4
- data.tar.gz: 5d199a1edd3a808254824a2bb45e22deca536e22
3
+ metadata.gz: da6b70d12c22d141f4283d2e99b5550afaf8da14
4
+ data.tar.gz: fb2a34d6aee5b051fc9611ba792f4c14a50b2e9b
5
5
  SHA512:
6
- metadata.gz: 7f7ee0ed6593d2a639c31787a559a86db0367b63ed79dde39966a4264904bbbd77d822e01be212ae40e7a573330281cb75489fc08e577c28e4d059712bcd2a86
7
- data.tar.gz: 4963089d9d9609fd5dbdae17c36e6ed001cea24b81550febdf0826fc3fe13d574f34c8bb51a1ffc6b270e30ba68dd6c14b3d693cec8fcc6bfa4370d8fdee144a
6
+ metadata.gz: af483022b150c72a218aa51dadb6db0865272cd81faa53db211b1b08e81a0b18b560908e92f553e93eb8b0d47029bd927f6fe6e61c811ab11e9d4b63339bed9d
7
+ data.tar.gz: e688057959cfd654dc027f03b1a8720ad21c90113d5478d18ed6897d5e4ab0a21297e703cfca85275e5d4495bce0e354acd9612f97f395cad6b1c70cdb39c8fa
@@ -1,18 +1,16 @@
1
1
  language: ruby
2
+ sudo: false
2
3
 
3
4
  rvm:
4
- - 2.3.1
5
- - 2.4.4
6
- - 2.5.1
7
-
8
- sudo: false
5
+ - 2.2
6
+ - 2.3
7
+ - 2.4
9
8
 
10
- script: bundle exec rake db:reset test:all
9
+ script: "bundle exec rake db:reset test:all"
11
10
 
12
- env:
13
- - "RAILS_VERSION=4.2.0"
14
- - "RAILS_VERSION=5.0.6"
15
- - "RAILS_VERSION=5.1.5"
16
- - "RAILS_VERSION=4.2.0 TEST_RAILS_API=true"
17
- - "RAILS_VERSION=5.0.6 TEST_RAILS_API=true"
18
- - "RAILS_VERSION=5.1.5 TEST_RAILS_API=true"
11
+ gemfile:
12
+ - gemfiles/4.2.gemfile
13
+ - gemfiles/4.2.api.gemfile
14
+ - gemfiles/5.0.gemfile
15
+ - gemfiles/5.1.gemfile
16
+ - gemfiles/5.2.gemfile
data/Gemfile CHANGED
@@ -10,7 +10,7 @@ else
10
10
  gem 'mysql2', '>= 0.3.13', '< 0.5'
11
11
  end
12
12
  gem 'pg', '~> 0.15'
13
- gem 'sqlite3'
13
+ gem 'sqlite3', '~> 1.3.6'
14
14
 
15
15
  rails = case version
16
16
  when "master"
@@ -24,3 +24,7 @@ gem "rails", rails
24
24
  if ENV["TEST_RAILS_API"] == "true"
25
25
  gem "rails-api", "~> 0.2.1"
26
26
  end
27
+
28
+ if RUBY_VERSION.start_with?('2.3')
29
+ gem 'mysql'
30
+ end
data/README.md CHANGED
@@ -100,6 +100,27 @@ With ActiveRecord >= 3.2.19:
100
100
 
101
101
  Pull requests for other included comment components are welcome.
102
102
 
103
+ ## Inline query annotations
104
+
105
+ In addition to the request or job-level component-based annotations,
106
+ Marginalia may be used to add inline annotations to specific queries using a
107
+ block-based API.
108
+
109
+ For example, the following code:
110
+
111
+ Marginalia.with_annotation("foo") do
112
+ Account.where(queenbee_id: 1234567890).first
113
+ end
114
+
115
+ will issue this query:
116
+
117
+ Account Load (0.3ms) SELECT `accounts`.* FROM `accounts`
118
+ WHERE `accounts`.`queenbee_id` = 1234567890
119
+ LIMIT 1
120
+ /*application:BCX,controller:project_imports,action:show*/ /*foo*/
121
+
122
+ Nesting `with_annotation` blocks will concatenate the comment strings.
123
+
103
124
  ## Contributing
104
125
 
105
126
  Start by bundling and creating the test database:
@@ -0,0 +1,9 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "mysql2", "~> 0.3.13"
4
+ gem "pg", "~> 0.15"
5
+ gem "sqlite3", "~> 1.3.6"
6
+ gem "rails", "= 4.2.11.1"
7
+ gem "rails-api", "~> 0.2.1"
8
+
9
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "mysql2", "~> 0.3.13"
4
+ gem "pg", "~> 0.15"
5
+ gem "sqlite3", "~> 1.3.6"
6
+ gem "rails", "= 4.2.11.1"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "mysql2", "~> 0.3.13"
4
+ gem "pg", "~> 0.15"
5
+ gem "sqlite3", "~> 1.3.6"
6
+ gem "rails", "= 5.0.7.2"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "mysql2", "~> 0.3.13"
4
+ gem "pg", "~> 0.15"
5
+ gem "sqlite3", "~> 1.3.6"
6
+ gem "rails", "= 5.1.6.2"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "mysql2", "~> 0.4.10"
4
+ gem "pg", "~> 0.15"
5
+ gem "sqlite3", "~> 1.3.6"
6
+ gem "rails", "= 5.2.2.1"
7
+
8
+ gemspec :path => "../"
@@ -1,5 +1,6 @@
1
1
  require 'marginalia/railtie'
2
2
  require 'marginalia/comment'
3
+ require 'marginalia/sidekiq_instrumentation'
3
4
 
4
5
  module Marginalia
5
6
  mattr_accessor :application_name
@@ -48,10 +49,13 @@ module Marginalia
48
49
  Marginalia::Comment.update_adapter!(self)
49
50
  comment = Marginalia::Comment.construct_comment
50
51
  if comment.present? && !sql.include?(comment)
51
- "#{sql} /*#{comment}*/"
52
- else
53
- sql
52
+ sql = "#{sql} /*#{comment}*/"
54
53
  end
54
+ inline_comment = Marginalia::Comment.construct_inline_comment
55
+ if inline_comment.present?
56
+ sql = "#{sql} /*#{inline_comment}*/"
57
+ end
58
+ sql
55
59
  end
56
60
 
57
61
  def execute_with_marginalia(sql, name = nil)
@@ -100,4 +104,11 @@ module Marginalia
100
104
  Marginalia::Comment.clear!
101
105
  end
102
106
  end
107
+
108
+ def self.with_annotation(comment, &block)
109
+ Marginalia::Comment.inline_annotations.push(comment)
110
+ block.call if block.present?
111
+ ensure
112
+ Marginalia::Comment.inline_annotations.pop
113
+ end
103
114
  end
@@ -30,6 +30,11 @@ module Marginalia
30
30
  ret
31
31
  end
32
32
 
33
+ def self.construct_inline_comment
34
+ return nil if inline_annotations.none?
35
+ escape_sql_comment(inline_annotations.join)
36
+ end
37
+
33
38
  def self.escape_sql_comment(str)
34
39
  while str.include?('/*') || str.include?('*/')
35
40
  str = str.gsub('/*', '').gsub('*/', '')
@@ -96,6 +101,10 @@ module Marginalia
96
101
  marginalia_controller.action_name if marginalia_controller.respond_to? :action_name
97
102
  end
98
103
 
104
+ def self.sidekiq_job
105
+ marginalia_job["class"] if marginalia_job
106
+ end
107
+
99
108
  def self.line
100
109
  Marginalia::Comment.lines_to_ignore ||= /\.rvm|gem|vendor\/|marginalia|rbenv/
101
110
  last_line = caller.detect do |line|
@@ -154,6 +163,10 @@ module Marginalia
154
163
  marginalia_adapter.pool.spec.config
155
164
  end
156
165
  end
166
+
167
+ def self.inline_annotations
168
+ Thread.current[:marginalia_inline_annotations] ||= []
169
+ end
157
170
  end
158
171
 
159
172
  end
@@ -0,0 +1,25 @@
1
+ module Marginalia
2
+
3
+ # Alternative to ActiveJob Instrumentation for Sidekiq.
4
+ # Apt for Instrumenting Sidekiq with Rails version < 4.2.
5
+ module SidekiqInstrumentation
6
+
7
+ class Middleware
8
+ def call(worker, msg, queue)
9
+ Marginalia::Comment.update_job! msg
10
+ yield
11
+ ensure
12
+ Marginalia::Comment.clear_job!
13
+ end
14
+ end
15
+
16
+ def self.enable!
17
+ Sidekiq.configure_server do |config|
18
+ config.server_middleware do |chain|
19
+ chain.add Marginalia::SidekiqInstrumentation::Middleware
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ end
@@ -8,7 +8,7 @@ Gem::Specification.new do |gem|
8
8
  gem.test_files = `git ls-files -- {test}/*`.split("\n")
9
9
  gem.name = "marginalia"
10
10
  gem.require_paths = ["lib"]
11
- gem.version = "1.6.0"
11
+ gem.version = "1.7.0"
12
12
  gem.license = "MIT"
13
13
 
14
14
  gem.add_runtime_dependency "actionpack", ">= 2.3"
@@ -19,8 +19,7 @@ Gem::Specification.new do |gem|
19
19
  gem.add_development_dependency "sqlite3"
20
20
  gem.add_development_dependency "minitest"
21
21
  gem.add_development_dependency "mocha"
22
+ gem.add_development_dependency "sidekiq"
22
23
 
23
24
  gem.summary = gem.description = %q{Attach comments to your ActiveRecord queries.}
24
-
25
- gem.extensions = ["ext/mkrf_conf.rb"]
26
25
  end
@@ -23,6 +23,8 @@ require 'logger'
23
23
  require 'pp'
24
24
  require 'active_record'
25
25
  require 'action_controller'
26
+ require 'sidekiq'
27
+ require 'sidekiq/testing'
26
28
 
27
29
  if request_id_available?
28
30
  require 'action_dispatch/middleware/request_id'
@@ -87,6 +89,13 @@ if active_job_available?
87
89
  end
88
90
  end
89
91
 
92
+ class PostsSidekiqJob
93
+ include Sidekiq::Worker
94
+ def perform
95
+ Post.first
96
+ end
97
+ end
98
+
90
99
  if using_rails_api?
91
100
  class PostsApiController < ActionController::API
92
101
  def driver_only
@@ -275,6 +284,23 @@ class MarginaliaTest < MiniTest::Test
275
284
  end
276
285
  end
277
286
 
287
+ def test_sidekiq_job
288
+ Marginalia::Comment.components = [:sidekiq_job]
289
+ Marginalia::SidekiqInstrumentation.enable!
290
+
291
+ # Test harness does not run Sidekiq middlewares by default so include testing middleware.
292
+ Sidekiq::Testing.server_middleware do |chain|
293
+ chain.add Marginalia::SidekiqInstrumentation::Middleware
294
+ end
295
+
296
+ Sidekiq::Testing.fake!
297
+ PostsSidekiqJob.perform_async
298
+ PostsSidekiqJob.drain
299
+ assert_match %{sidekiq_job:PostsSidekiqJob}, @queries.first
300
+ Post.first
301
+ refute_match %{sidekiq_job:PostsSidekiqJob}, @queries.last
302
+ end
303
+
278
304
  def test_good_comment
279
305
  assert_equal Marginalia::Comment.escape_sql_comment('app:foo'), 'app:foo'
280
306
  end
@@ -284,6 +310,37 @@ class MarginaliaTest < MiniTest::Test
284
310
  assert_equal Marginalia::Comment.escape_sql_comment('**//; DROP TABLE USERS;/*'), '; DROP TABLE USERS;'
285
311
  end
286
312
 
313
+ def test_inline_annotations
314
+ Marginalia.with_annotation("foo") do
315
+ Post.first
316
+ end
317
+ Post.first
318
+ assert_match %r{/\*foo\*/$}, @queries.first
319
+ refute_match %r{/\*foo\*/$}, @queries.last
320
+ # Assert we're not adding an empty comment, either
321
+ refute_match %r{/\*\s*\*/$}, @queries.last
322
+ end
323
+
324
+ def test_nested_inline_annotations
325
+ Marginalia.with_annotation("foo") do
326
+ Marginalia.with_annotation("bar") do
327
+ Post.first
328
+ end
329
+ end
330
+ assert_match %r{/\*foobar\*/$}, @queries.first
331
+ end
332
+
333
+ def test_bad_inline_annotations
334
+ Marginalia.with_annotation("*/; DROP TABLE USERS;/*") do
335
+ Post.first
336
+ end
337
+ Marginalia.with_annotation("**//; DROP TABLE USERS;//**") do
338
+ Post.first
339
+ end
340
+ assert_match %r{/\*; DROP TABLE USERS;\*/$}, @queries.first
341
+ assert_match %r{/\*; DROP TABLE USERS;\*/$}, @queries.last
342
+ end
343
+
287
344
  def teardown
288
345
  Marginalia.application_name = nil
289
346
  Marginalia::Comment.lines_to_ignore = nil
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marginalia
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Noah Lorang
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2018-09-24 00:00:00.000000000 Z
13
+ date: 2019-03-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: actionpack
@@ -124,13 +124,26 @@ dependencies:
124
124
  - - ">="
125
125
  - !ruby/object:Gem::Version
126
126
  version: '0'
127
+ - !ruby/object:Gem::Dependency
128
+ name: sidekiq
129
+ requirement: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
127
141
  description: Attach comments to your ActiveRecord queries.
128
142
  email:
129
143
  - noah@37signals.com
130
144
  - arthurnn@github.com
131
145
  executables: []
132
- extensions:
133
- - ext/mkrf_conf.rb
146
+ extensions: []
134
147
  extra_rdoc_files: []
135
148
  files:
136
149
  - ".gitignore"
@@ -140,11 +153,16 @@ files:
140
153
  - LICENSE
141
154
  - README.md
142
155
  - Rakefile
143
- - ext/mkrf_conf.rb
156
+ - gemfiles/4.2.api.gemfile
157
+ - gemfiles/4.2.gemfile
158
+ - gemfiles/5.0.gemfile
159
+ - gemfiles/5.1.gemfile
160
+ - gemfiles/5.2.gemfile
144
161
  - init.rb
145
162
  - lib/marginalia.rb
146
163
  - lib/marginalia/comment.rb
147
164
  - lib/marginalia/railtie.rb
165
+ - lib/marginalia/sidekiq_instrumentation.rb
148
166
  - marginalia.gemspec
149
167
  - test/query_comments_test.rb
150
168
  homepage: https://github.com/basecamp/marginalia
@@ -1,21 +0,0 @@
1
- require 'rubygems'
2
- require 'rubygems/command.rb'
3
- require 'rubygems/dependency_installer.rb'
4
-
5
- begin
6
- Gem::Command.build_args = ARGV
7
- rescue NoMethodError
8
- end
9
-
10
- installer = Gem::DependencyInstaller.new
11
- begin
12
- if RUBY_VERSION < "2.4"
13
- installer.install "mysql", ">=0"
14
- end
15
- rescue
16
- exit(1)
17
- end
18
-
19
- f = File.open(File.join(File.dirname(__FILE__), "Rakefile"), "w")
20
- f.write("task :default\n")
21
- f.close