prosopite 1.0.0 → 1.0.4

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
  SHA256:
3
- metadata.gz: 3df6a0299972911e48ea44330995864e2cd2191ec66c199296ba324a5fa8e639
4
- data.tar.gz: 4f9ee347a8cf52fd742ee66586c7e4b601c8436a4bcabe1b1afdef5e09293f44
3
+ metadata.gz: 66728f096f4aafd32cf868f6b24ce88daae9d282b21d2c8b95ed0b732a299d2c
4
+ data.tar.gz: 4259b7a737bc367742efc158d425a57c1e24c435991f3ad4bd57dbd7a6c195d4
5
5
  SHA512:
6
- metadata.gz: 668bc7e58bcabd77231adc831054d56ca572e1e9857f87736d1fd06048c1eeaac9c0c0ab970c6ed6f8ce70670ae51277c3c4f56012d0ec61240c0e728c1f3795
7
- data.tar.gz: '0341920f4f1beddc2b9c46553f9284724ecddfe50f30579a7cc9627c93fdf2d3c714bb57fd453dd7a4783a86951b9dd2cb0a79e721189bce3b89eda0c119c8bf'
6
+ metadata.gz: 3fc7f6c647ebfcbce614c0ef7c51a2e9a69b6da7090d889e65dd535891c93a33b07e4228f2d877951a26a06f8bd53687567bf86fed2b77f9558b84a0c24eaa4f
7
+ data.tar.gz: 139a0047ea3aed0f99a0900bf8c2bf235d5fe1723563859c85bd887daae96a8d65c2b21e5f9ad350384de6424c2ef8a3f7ea1df9d66d8bfb33af2009133f0eb4
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- prosopite (0.2.1)
4
+ prosopite (1.0.3)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -127,11 +127,12 @@ Prosopite auto-detection can be enabled on all controllers:
127
127
  ```ruby
128
128
  class ApplicationController < ActionController::Base
129
129
  unless Rails.env.production?
130
- before_action do
130
+ around_action :n_plus_one_detection
131
+
132
+ def n_plus_one_detection
131
133
  Prosopite.scan
132
- end
133
-
134
- after_action do
134
+ yield
135
+ ensure
135
136
  Prosopite.finish
136
137
  end
137
138
  end
@@ -194,6 +195,31 @@ Prosopite.scan
194
195
  Prosopite.finish
195
196
  ```
196
197
 
198
+ or
199
+
200
+ ```ruby
201
+ Prosopite.scan do
202
+ <code to scan>
203
+ end
204
+ ```
205
+
206
+ ## Pausing and resuming scans
207
+
208
+ Scans can be paused:
209
+
210
+ ```ruby
211
+ Prosopite.scan
212
+ # <code to scan>
213
+ Prosopite.pause
214
+ # <code that has n+1s>
215
+ Prosopite.resume
216
+ # <code to scan>
217
+ Prosopite.finish
218
+ ```
219
+
220
+ An example of when you might use this is if you are [testing Active Jobs inline](https://guides.rubyonrails.org/testing.html#testing-jobs),
221
+ and don't want to run Prosopite on background job code, just foreground app code. In that case you could write an [Active Job callback](https://edgeguides.rubyonrails.org/active_job_basics.html#callbacks) that pauses the scan while the job is running.
222
+
197
223
  ## Contributing
198
224
 
199
225
  Bug reports and pull requests are welcome on GitHub at https://github.com/charkost/prosopite.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Prosopite
4
- VERSION = "1.0.0"
4
+ VERSION = "1.0.4"
5
5
  end
data/lib/prosopite.rb CHANGED
@@ -1,5 +1,7 @@
1
1
 
2
2
  module Prosopite
3
+ DEFAULT_ALLOW_LIST = %w(active_record/associations/preloader active_record/validations/uniqueness)
4
+
3
5
  class NPlusOneQueriesError < StandardError; end
4
6
  class << self
5
7
  attr_writer :raise,
@@ -21,12 +23,29 @@ module Prosopite
21
23
  @allow_list ||= []
22
24
 
23
25
  tc[:prosopite_scan] = true
26
+
27
+ if block_given?
28
+ begin
29
+ yield
30
+ finish
31
+ ensure
32
+ tc[:prosopite_scan] = false
33
+ end
34
+ end
24
35
  end
25
36
 
26
37
  def tc
27
38
  Thread.current
28
39
  end
29
40
 
41
+ def pause
42
+ tc[:prosopite_scan] = false
43
+ end
44
+
45
+ def resume
46
+ tc[:prosopite_scan] = true
47
+ end
48
+
30
49
  def scan?
31
50
  tc[:prosopite_scan]
32
51
  end
@@ -53,14 +72,14 @@ module Prosopite
53
72
  end
54
73
  end
55
74
 
75
+ next unless fingerprints.uniq.size == 1
76
+
56
77
  kaller = tc[:prosopite_query_caller][location_key]
57
78
 
58
- if fingerprints.uniq.size == 1 && !kaller.any? { |f| @allow_list.any? { |s| f.include?(s) } }
79
+ is_allowed = kaller.any? { |f| @allow_list.concat(DEFAULT_ALLOW_LIST).any? { |s| f.include?(s) } }
80
+ unless is_allowed
59
81
  queries = tc[:prosopite_query_holder][location_key]
60
-
61
- unless kaller.any? { |f| f.include?('active_record/validations/uniqueness') }
62
- tc[:prosopite_notifications][queries] = kaller
63
- end
82
+ tc[:prosopite_notifications][queries] = kaller
64
83
  end
65
84
  end
66
85
  end
@@ -105,7 +124,7 @@ module Prosopite
105
124
 
106
125
  query.gsub!(/\btrue\b|\bfalse\b/i, "?")
107
126
 
108
- query.gsub!(/[0-9+-][0-9a-f.xb+-]*/, "?")
127
+ query.gsub!(/[0-9+-][0-9a-f.x+-]*/, "?")
109
128
  query.gsub!(/[xb.+-]\?/, "?")
110
129
 
111
130
  query.strip!
@@ -166,9 +185,9 @@ module Prosopite
166
185
  return if @subscribed
167
186
 
168
187
  ActiveSupport::Notifications.subscribe 'sql.active_record' do |_, _, _, _, data|
169
- sql = data[:sql]
188
+ sql, name = data[:sql], data[:name]
170
189
 
171
- if scan? && sql.include?('SELECT') && data[:cached].nil?
190
+ if scan? && name != "SCHEMA" && sql.include?('SELECT') && data[:cached].nil?
172
191
  location_key = Digest::SHA1.hexdigest(caller.join)
173
192
 
174
193
  tc[:prosopite_query_counter][location_key] += 1
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prosopite
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mpampis Kostas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-17 00:00:00.000000000 Z
11
+ date: 2021-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry