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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +30 -4
- data/lib/prosopite/version.rb +1 -1
- data/lib/prosopite.rb +27 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 66728f096f4aafd32cf868f6b24ce88daae9d282b21d2c8b95ed0b732a299d2c
|
4
|
+
data.tar.gz: 4259b7a737bc367742efc158d425a57c1e24c435991f3ad4bd57dbd7a6c195d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3fc7f6c647ebfcbce614c0ef7c51a2e9a69b6da7090d889e65dd535891c93a33b07e4228f2d877951a26a06f8bd53687567bf86fed2b77f9558b84a0c24eaa4f
|
7
|
+
data.tar.gz: 139a0047ea3aed0f99a0900bf8c2bf235d5fe1723563859c85bd887daae96a8d65c2b21e5f9ad350384de6424c2ef8a3f7ea1df9d66d8bfb33af2009133f0eb4
|
data/Gemfile.lock
CHANGED
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
|
-
|
130
|
+
around_action :n_plus_one_detection
|
131
|
+
|
132
|
+
def n_plus_one_detection
|
131
133
|
Prosopite.scan
|
132
|
-
|
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.
|
data/lib/prosopite/version.rb
CHANGED
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
|
-
|
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.
|
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.
|
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-
|
11
|
+
date: 2021-12-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry
|