activerecord-pedantmysql2-adapter 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +15 -2
- data/lib/active_record/connection_adapters/pedant_mysql2_adapter.rb +1 -1
- data/lib/pedant_mysql2.rb +45 -16
- data/lib/pedant_mysql2/version.rb +1 -1
- data/spec/adapter_spec.rb +73 -14
- data/spec/support/database.rb +1 -0
- metadata +25 -3
- metadata.gz.sig +2 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3edf754b2a2095a7149077c7307326fb63e58851
|
4
|
+
data.tar.gz: e65305e4b6c3f8fb0c682cc890ee010b88405b93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0788ea3fa24672a2b31723dab2fc19cb2b768008515be1d978d19cffa7562d8c988a693770219a64f1380b77a434d22650fda77bb5ec25f3ff9dc0caa1b6f9c2
|
7
|
+
data.tar.gz: b2a18d31f2345eab76fc0f8373a721dd43b81b3c116ca120b9eb52c167330f674babd3d3820875b040fc814bb0f6af096401f4c2effc85a651186b2942406e16
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
Binary file
|
data/README.md
CHANGED
@@ -40,10 +40,14 @@ You can report them to your exception tracker:
|
|
40
40
|
or totally silence them:
|
41
41
|
|
42
42
|
```ruby
|
43
|
-
PedantMysql2.
|
43
|
+
PedantMysql2.silence_warnings!
|
44
44
|
```
|
45
45
|
|
46
|
-
|
46
|
+
and to restore it to raising warnings as errors:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
PedantMysql2.raise_warnings!
|
50
|
+
```
|
47
51
|
|
48
52
|
You can easilly whitelist some types of warnings:
|
49
53
|
|
@@ -59,6 +63,15 @@ warnings = PedantMysql2.capture_warnings do
|
|
59
63
|
end
|
60
64
|
```
|
61
65
|
|
66
|
+
## Thread-safe
|
67
|
+
|
68
|
+
This gem is tested to be thread safe with a couple known exceptions.
|
69
|
+
|
70
|
+
`PedantMysql2.ignore` is not thread safe and should only be called during initialization of your app. Changing this within a thread while another is updating it could be problematic.
|
71
|
+
`PedantMysql2.on_warning=` is not thread safe, this should also be called only during initialization.
|
72
|
+
|
73
|
+
If you find any other parts that are not thread-safe, please create an issue or PR.
|
74
|
+
|
62
75
|
## Development
|
63
76
|
|
64
77
|
Setting up the development environment is very straightforward. In order to keep the test
|
@@ -63,7 +63,7 @@ class ActiveRecord::ConnectionAdapters::PedantMysql2Adapter < ActiveRecord::Conn
|
|
63
63
|
result = @connection.query('SHOW WARNINGS')
|
64
64
|
result.each do |level, code, message|
|
65
65
|
warning = MysqlWarning.new(message, code, level, sql)
|
66
|
-
::PedantMysql2.
|
66
|
+
::PedantMysql2.warn(warning)
|
67
67
|
end
|
68
68
|
end
|
69
69
|
end
|
data/lib/pedant_mysql2.rb
CHANGED
@@ -1,34 +1,42 @@
|
|
1
1
|
module PedantMysql2
|
2
2
|
class << self
|
3
|
-
attr_accessor :on_warning
|
4
|
-
|
5
3
|
def capture_warnings
|
6
|
-
|
7
|
-
|
8
|
-
Thread.current[:mysql_warnings] = []
|
9
|
-
self.on_warning = lambda { |warning| Thread.current[:mysql_warnings] << warning }
|
4
|
+
warnings = backup_warnings
|
5
|
+
setup_capture
|
10
6
|
yield
|
11
|
-
|
12
|
-
warnings
|
7
|
+
captured_warnings
|
13
8
|
ensure
|
14
|
-
|
15
|
-
self.on_warning = previous_callback
|
9
|
+
restore_warnings(warnings)
|
16
10
|
end
|
17
11
|
|
18
12
|
def raise_warnings!
|
19
|
-
self.on_warning =
|
13
|
+
self.on_warning = nil
|
20
14
|
end
|
21
15
|
|
22
16
|
def silence_warnings!
|
23
|
-
self.on_warning =
|
17
|
+
self.on_warning = lambda{ |warning| }
|
24
18
|
end
|
25
19
|
|
26
20
|
def ignore(*matchers)
|
27
21
|
self.whitelist.concat(matchers.flatten)
|
28
22
|
end
|
29
23
|
|
30
|
-
def
|
31
|
-
|
24
|
+
def warn(warning)
|
25
|
+
return if ignored?(warning)
|
26
|
+
|
27
|
+
if on_warning
|
28
|
+
on_warning.call(warning)
|
29
|
+
else
|
30
|
+
raise warning
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def on_warning
|
35
|
+
Thread.current[:__pedant_mysql2_on_warning] || @_on_warning
|
36
|
+
end
|
37
|
+
|
38
|
+
def on_warning=(new_proc)
|
39
|
+
@_on_warning = new_proc
|
32
40
|
end
|
33
41
|
|
34
42
|
protected
|
@@ -37,8 +45,29 @@ module PedantMysql2
|
|
37
45
|
@whitelist ||= []
|
38
46
|
end
|
39
47
|
|
40
|
-
|
48
|
+
def ignored?(warning)
|
49
|
+
whitelist.any? { |matcher| matcher =~ warning.message }
|
50
|
+
end
|
51
|
+
|
52
|
+
def setup_capture
|
53
|
+
Thread.current[:__pedant_mysql2_warnings] = []
|
54
|
+
self.thread_on_warning = lambda { |warning| Thread.current[:__pedant_mysql2_warnings] << warning }
|
55
|
+
end
|
56
|
+
|
57
|
+
def captured_warnings
|
58
|
+
Thread.current[:__pedant_mysql2_warnings]
|
59
|
+
end
|
41
60
|
|
42
|
-
|
61
|
+
def backup_warnings
|
62
|
+
[captured_warnings, Thread.current[:__pedant_mysql2_on_warning]]
|
63
|
+
end
|
64
|
+
|
65
|
+
def restore_warnings(warnings)
|
66
|
+
Thread.current[:__pedant_mysql2_warnings], self.thread_on_warning = *warnings
|
67
|
+
end
|
43
68
|
|
69
|
+
def thread_on_warning=(new_proc)
|
70
|
+
Thread.current[:__pedant_mysql2_on_warning] = new_proc
|
71
|
+
end
|
72
|
+
end
|
44
73
|
end
|
data/spec/adapter_spec.rb
CHANGED
@@ -19,39 +19,56 @@ describe PedantMysql2 do
|
|
19
19
|
PedantMysql2.on_warning = @original_callback
|
20
20
|
end
|
21
21
|
|
22
|
+
def execute_with_warning
|
23
|
+
ActiveRecord::Base.connection.execute('SELECT 1 + "foo"')
|
24
|
+
end
|
25
|
+
|
26
|
+
def wait_for(thread)
|
27
|
+
sleep 0.1 until thread.stop?
|
28
|
+
end
|
29
|
+
|
30
|
+
# Used by the thread-safe testing
|
31
|
+
def method_missing(method_name,*args)
|
32
|
+
if PedantMysql2.respond_to?(method_name, true)
|
33
|
+
PedantMysql2.send(method_name,*args)
|
34
|
+
else
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
22
39
|
it 'raises warnings by default' do
|
23
40
|
expect {
|
24
|
-
|
41
|
+
execute_with_warning
|
25
42
|
}.to raise_error(MysqlWarning, "Truncated incorrect DOUBLE value: 'foo'")
|
26
43
|
end
|
27
44
|
|
28
45
|
it 'can have a whitelist of warnings' do
|
29
46
|
PedantMysql2.ignore(/Truncated incorrect DOUBLE value/i)
|
30
47
|
expect {
|
31
|
-
|
48
|
+
execute_with_warning
|
32
49
|
}.to_not raise_error
|
33
50
|
end
|
34
51
|
|
35
52
|
it 'do not change the returned value' do
|
36
53
|
PedantMysql2.silence_warnings!
|
37
|
-
result =
|
54
|
+
result = execute_with_warning
|
38
55
|
expect(result.to_a).to be == [[1.0]]
|
39
56
|
end
|
40
57
|
|
41
58
|
it 'do not change the returned value of exec_update' do
|
42
|
-
result = connection.update('UPDATE comment SET id = 1 LIMIT 1')
|
59
|
+
result = connection.update('UPDATE comment SET id = 1 ORDER BY id LIMIT 1')
|
43
60
|
expect(result).to be_zero
|
44
61
|
end
|
45
62
|
|
46
63
|
it 'do not change the returned value of exec_delete' do
|
47
|
-
result = connection.delete('DELETE FROM comment LIMIT 1')
|
64
|
+
result = connection.delete('DELETE FROM comment ORDER BY id LIMIT 1')
|
48
65
|
expect(result).to be_zero
|
49
66
|
end
|
50
67
|
|
51
68
|
it 'can easily be raised' do
|
52
69
|
PedantMysql2.on_warning = lambda { |warning| raise warning }
|
53
70
|
expect {
|
54
|
-
|
71
|
+
execute_with_warning
|
55
72
|
}.to raise_error(MysqlWarning)
|
56
73
|
end
|
57
74
|
|
@@ -59,22 +76,64 @@ describe PedantMysql2 do
|
|
59
76
|
warnings = nil
|
60
77
|
expect {
|
61
78
|
warnings = PedantMysql2.capture_warnings do
|
62
|
-
|
79
|
+
execute_with_warning
|
63
80
|
end
|
64
81
|
}.to_not raise_error
|
65
|
-
|
82
|
+
|
66
83
|
expect(warnings.size).to be == 1
|
67
84
|
expect(warnings.first).to be_a MysqlWarning
|
68
85
|
expect(warnings.first.message).to be == "Truncated incorrect DOUBLE value: 'foo'"
|
69
86
|
end
|
70
87
|
|
71
88
|
it 'restores the old value that was stored in the thread_local capture_warnings' do
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
89
|
+
warnings1 = nil
|
90
|
+
warnings2 = nil
|
91
|
+
|
92
|
+
warnings1 = PedantMysql2.capture_warnings do
|
93
|
+
execute_with_warning
|
94
|
+
warnings2 = PedantMysql2.capture_warnings do
|
95
|
+
execute_with_warning
|
96
|
+
execute_with_warning
|
97
|
+
end
|
76
98
|
end
|
77
|
-
|
99
|
+
|
100
|
+
expect(warnings1.size).to be == 1
|
101
|
+
expect(warnings2.size).to be == 2
|
102
|
+
expect(warnings2).to_not include(warnings1)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should be thread-safe to capture_warnings (when class instance variables were used this did not pass)' do
|
106
|
+
thread = Thread.new do
|
107
|
+
warnings = backup_warnings
|
108
|
+
Thread.stop
|
109
|
+
setup_capture
|
110
|
+
Thread.stop
|
111
|
+
execute_with_warning
|
112
|
+
expect(captured_warnings.size).to be == 1
|
113
|
+
restore_warnings(warnings)
|
114
|
+
end
|
115
|
+
|
116
|
+
wait_for(thread)
|
117
|
+
warnings = backup_warnings
|
118
|
+
thread.run
|
119
|
+
wait_for(thread)
|
120
|
+
setup_capture
|
121
|
+
execute_with_warning
|
122
|
+
expect(captured_warnings.size).to be == 1
|
123
|
+
restore_warnings(warnings)
|
124
|
+
thread.run
|
125
|
+
thread.join
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should inherit on_warning from parent thread' do
|
129
|
+
PedantMysql2.silence_warnings!
|
130
|
+
thread = Thread.new do
|
131
|
+
expect {
|
132
|
+
execute_with_warning
|
133
|
+
}.to_not raise_error
|
134
|
+
end
|
135
|
+
|
136
|
+
thread.join
|
78
137
|
end
|
79
138
|
|
80
139
|
describe MysqlWarning do
|
@@ -82,7 +141,7 @@ describe PedantMysql2 do
|
|
82
141
|
subject do
|
83
142
|
begin
|
84
143
|
PedantMysql2.on_warning = lambda { |warning| raise warning }
|
85
|
-
|
144
|
+
execute_with_warning
|
86
145
|
rescue MysqlWarning => exception
|
87
146
|
exception
|
88
147
|
end
|
data/spec/support/database.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,36 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-pedantmysql2-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean Boussier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
|
-
cert_chain:
|
11
|
-
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MQ8wDQYDVQQDDAZhZG1p
|
14
|
+
bnMxFzAVBgoJkiaJk/IsZAEZFgdzaG9waWZ5MRMwEQYKCZImiZPyLGQBGRYDY29t
|
15
|
+
MB4XDTE0MDUxNTIwMzM0OFoXDTE1MDUxNTIwMzM0OFowPzEPMA0GA1UEAwwGYWRt
|
16
|
+
aW5zMRcwFQYKCZImiZPyLGQBGRYHc2hvcGlmeTETMBEGCgmSJomT8ixkARkWA2Nv
|
17
|
+
bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL0/81O3e1vh5smcwp2G
|
18
|
+
MpLQ6q0kejQLa65bPYPxdzWA1SYOKyGfw+yR9LdFzsuKpwWzKq6zX35lj1IckWS4
|
19
|
+
bNBEQzxmufUxU0XPM02haFB8fOfDJzdXsWte9Ge4IFwahwn68gpMqN+BvxL+KMYz
|
20
|
+
Iut9YmN44d4LZdsENEIO5vmybuG2vYDz7R56qB0PA+Q2P2CdhymsBad2DQs69FBo
|
21
|
+
uico9V6VMYYctL9lCYdzu9IXrOYNTt88suKIVzzAlHOKeN0Ng5qdztFoTR8sfxDr
|
22
|
+
Ydg3KHl5n47wlpgd8R0f/4b5gGxW+v9pyJCgQnLlRu7DedVSvv7+GMtj3g9r3nhJ
|
23
|
+
KqECAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFI/o
|
24
|
+
maf34HXbUOQsdoLHacEKQgunMB0GA1UdEQQWMBSBEmFkbWluc0BzaG9waWZ5LmNv
|
25
|
+
bTAdBgNVHRIEFjAUgRJhZG1pbnNAc2hvcGlmeS5jb20wDQYJKoZIhvcNAQEFBQAD
|
26
|
+
ggEBADkK9aj5T0HPExsov4EoMWFnO+G7RQ28C30VAfKxnL2UxG6i4XMHVs6Xi94h
|
27
|
+
qXFw1ec9Y2eDUqaolT3bviOk9BB197+A8Vz/k7MC6ci2NE+yDDB7HAC8zU6LAx8Y
|
28
|
+
Iqvw7B/PSZ/pz4bUVFlTATif4mi1vO3lidRkdHRtM7UePSn2rUpOi0gtXBP3bLu5
|
29
|
+
YjHJN7wx5cugMEyroKITG5gL0Nxtu21qtOlHX4Hc4KdE2JqzCPOsS4zsZGhgwhPs
|
30
|
+
fl3hbtVFTqbOlwL9vy1fudXcolIE/ZTcxQ+er07ZFZdKCXayR9PPs64heamfn0fp
|
31
|
+
TConQSX2BnZdhIEYW+cKzEC/bLc=
|
32
|
+
-----END CERTIFICATE-----
|
33
|
+
date: 2015-03-30 00:00:00.000000000 Z
|
12
34
|
dependencies:
|
13
35
|
- !ruby/object:Gem::Dependency
|
14
36
|
name: activerecord
|
metadata.gz.sig
ADDED