activerecord-pedantmysql2-adapter 1.0.1 → 1.1.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: 37c3b963b0b4bb1c8128ec4b745fce6915796f65
4
- data.tar.gz: d26e7b34382ec8108830e5145f5a4376c413a9c4
3
+ metadata.gz: 3edf754b2a2095a7149077c7307326fb63e58851
4
+ data.tar.gz: e65305e4b6c3f8fb0c682cc890ee010b88405b93
5
5
  SHA512:
6
- metadata.gz: a61634eb872f51c607c5dc2f50904fac8057522b88e94809f1094a068e704642b71868ef7d86b5c990b3a39212a4781b19ae34f1bb81daba96a70c7a45c9e800
7
- data.tar.gz: 543e8afda7636bc01fdd9a72aeb588365bf9b2cbd68fbd5377fdbb4b45c872fcdf9c9c3d7c6003fcfbeae045850a1080362aae0430466e105805175c8b1b4b8d
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.on_warning = lambda { |*| }
43
+ PedantMysql2.silence_warnings!
44
44
  ```
45
45
 
46
- Or whatever else behaviour you want (logging).
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.on_warning.call(warning) unless PedantMysql2.ignored?(warning)
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
- previous_callback = on_warning
7
- previous_warnings = Thread.current[:mysql_warnings]
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
- warnings = Thread.current[:mysql_warnings]
12
- warnings
7
+ captured_warnings
13
8
  ensure
14
- Thread.current[:mysql_warnings] = previous_warnings
15
- self.on_warning = previous_callback
9
+ restore_warnings(warnings)
16
10
  end
17
11
 
18
12
  def raise_warnings!
19
- self.on_warning = lambda{ |warning| raise warning }
13
+ self.on_warning = nil
20
14
  end
21
15
 
22
16
  def silence_warnings!
23
- self.on_warning = nil
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 ignored?(warning)
31
- on_warning.nil? || whitelist.any? { |matcher| matcher =~ warning.message }
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
- end
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
- raise_warnings!
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
@@ -1,3 +1,3 @@
1
1
  module PedantMysql2
2
- VERSION = '1.0.1'
2
+ VERSION = '1.1.0'
3
3
  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
- connection.execute('SELECT 1 + "foo"')
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
- connection.execute('SELECT 1 + "foo"')
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 = connection.execute('SELECT 1 + "foo"')
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
- connection.execute('SELECT 1 + "foo"')
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
- connection.execute('SELECT 1 + "foo"')
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
- Thread.current[:mysql_warnings] = 'abracadabra'
73
- PedantMysql2.capture_warnings do
74
- expect(Thread.current[:mysql_warnings]).to be_an Array
75
- connection.execute('SELECT 1 + "foo"')
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
- expect(Thread.current[:mysql_warnings]).to be == 'abracadabra'
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
- connection.execute('SELECT 1 + "foo"')
144
+ execute_with_warning
86
145
  rescue MysqlWarning => exception
87
146
  exception
88
147
  end
@@ -5,6 +5,7 @@ ActiveRecord::Base.configurations = {
5
5
  username: 'travis',
6
6
  encoding: 'utf8',
7
7
  strict: false,
8
+ pool: 5,
8
9
  },
9
10
  }
10
11
  ActiveRecord::Base.establish_connection(:test)
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.1
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
- date: 2014-12-19 00:00:00.000000000 Z
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
@@ -0,0 +1,2 @@
1
+ ��9AB{ż��3�s΂a�\NC�DxHAh�8B������(��b��¢`���V�X�/AvD�3�������??��
2
+ ��g�Xl��Ags�?w�֓�*�����uɥX��px`����c6�M�6���ƞ#N��\S֋��x����Û=:l��D����]m����$-�W<����t��.:hoX�JҠlGu r�c .�2_������qq D��b���"ЛSV��i �̜$��W�Cd�O�Y�K�.��M}�Nw�e