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 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