mysql2 0.4.2 → 0.4.10
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
- data/README.md +77 -51
- data/ext/mysql2/client.c +242 -51
- data/ext/mysql2/client.h +2 -12
- data/ext/mysql2/extconf.rb +26 -2
- data/ext/mysql2/mysql2_ext.h +0 -4
- data/ext/mysql2/result.c +40 -22
- data/ext/mysql2/result.h +3 -2
- data/ext/mysql2/statement.c +133 -32
- data/lib/mysql2/client.rb +19 -6
- data/lib/mysql2/version.rb +1 -1
- data/spec/configuration.yml.example +0 -6
- data/spec/em/em_spec.rb +1 -0
- data/spec/mysql2/client_spec.rb +211 -111
- data/spec/mysql2/error_spec.rb +4 -6
- data/spec/mysql2/result_spec.rb +71 -36
- data/spec/mysql2/statement_spec.rb +144 -52
- data/spec/spec_helper.rb +73 -59
- data/spec/ssl/gen_certs.sh +1 -1
- data/support/5072E1F5.asc +432 -0
- metadata +12 -11
data/spec/mysql2/client_spec.rb
CHANGED
@@ -7,14 +7,13 @@ RSpec.describe Mysql2::Client do
|
|
7
7
|
|
8
8
|
it "should not raise an exception for valid defaults group" do
|
9
9
|
expect {
|
10
|
-
|
11
|
-
@client = Mysql2::Client.new(opts)
|
10
|
+
new_client(:default_file => cnf_file, :default_group => "test")
|
12
11
|
}.not_to raise_error
|
13
12
|
end
|
14
13
|
|
15
14
|
it "should not raise an exception without default group" do
|
16
15
|
expect {
|
17
|
-
|
16
|
+
new_client(:default_file => cnf_file)
|
18
17
|
}.not_to raise_error
|
19
18
|
end
|
20
19
|
end
|
@@ -23,23 +22,29 @@ RSpec.describe Mysql2::Client do
|
|
23
22
|
expect {
|
24
23
|
# The odd local host IP address forces the mysql client library to
|
25
24
|
# use a TCP socket rather than a domain socket.
|
26
|
-
|
25
|
+
new_client('host' => '127.0.0.2', 'port' => 999999)
|
27
26
|
}.to raise_error(Mysql2::Error)
|
28
27
|
end
|
29
28
|
|
30
29
|
it "should raise an exception on create for invalid encodings" do
|
31
30
|
expect {
|
32
|
-
|
31
|
+
new_client(:encoding => "fake")
|
33
32
|
}.to raise_error(Mysql2::Error)
|
34
33
|
end
|
35
34
|
|
35
|
+
it "should raise an exception on non-string encodings" do
|
36
|
+
expect {
|
37
|
+
new_client(:encoding => :fake)
|
38
|
+
}.to raise_error(TypeError)
|
39
|
+
end
|
40
|
+
|
36
41
|
it "should not raise an exception on create for a valid encoding" do
|
37
42
|
expect {
|
38
|
-
|
43
|
+
new_client(:encoding => "utf8")
|
39
44
|
}.not_to raise_error
|
40
45
|
|
41
46
|
expect {
|
42
|
-
|
47
|
+
new_client(DatabaseCredentials['root'].merge(:encoding => "big5"))
|
43
48
|
}.not_to raise_error
|
44
49
|
end
|
45
50
|
|
@@ -82,7 +87,7 @@ RSpec.describe Mysql2::Client do
|
|
82
87
|
it "should execute init command" do
|
83
88
|
options = DatabaseCredentials['root'].dup
|
84
89
|
options[:init_command] = "SET @something = 'setting_value';"
|
85
|
-
client =
|
90
|
+
client = new_client(options)
|
86
91
|
result = client.query("SELECT @something;")
|
87
92
|
expect(result.first['@something']).to eq('setting_value')
|
88
93
|
end
|
@@ -91,7 +96,7 @@ RSpec.describe Mysql2::Client do
|
|
91
96
|
options = DatabaseCredentials['root'].dup
|
92
97
|
options[:init_command] = "SET @something = 'setting_value';"
|
93
98
|
options[:reconnect] = true
|
94
|
-
client =
|
99
|
+
client = new_client(options)
|
95
100
|
|
96
101
|
result = client.query("SELECT @something;")
|
97
102
|
expect(result.first['@something']).to eq('setting_value')
|
@@ -132,31 +137,23 @@ RSpec.describe Mysql2::Client do
|
|
132
137
|
ssl_client = nil
|
133
138
|
expect {
|
134
139
|
# rubocop:disable Style/TrailingComma
|
135
|
-
ssl_client =
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
:sslverify => true
|
143
|
-
)
|
140
|
+
ssl_client = new_client(
|
141
|
+
'host' => 'mysql2gem.example.com', # must match the certificates
|
142
|
+
:sslkey => '/etc/mysql/client-key.pem',
|
143
|
+
:sslcert => '/etc/mysql/client-cert.pem',
|
144
|
+
:sslca => '/etc/mysql/ca-cert.pem',
|
145
|
+
:sslcipher => 'DHE-RSA-AES256-SHA',
|
146
|
+
:sslverify => true
|
144
147
|
)
|
145
148
|
# rubocop:enable Style/TrailingComma
|
146
149
|
}.not_to raise_error
|
147
150
|
|
148
|
-
results = ssl_client.query(
|
149
|
-
expect(results[
|
150
|
-
expect(results[
|
151
|
-
expect(results[0]['Value']).to be_an_instance_of(String)
|
152
|
-
expect(results[0]['Value']).not_to be_empty
|
153
|
-
|
154
|
-
expect(results[1]['Variable_name']).to eql('Ssl_version')
|
155
|
-
expect(results[1]['Value']).not_to be_nil
|
156
|
-
expect(results[1]['Value']).to be_an_instance_of(String)
|
157
|
-
expect(results[1]['Value']).not_to be_empty
|
151
|
+
results = Hash[ssl_client.query('SHOW STATUS WHERE Variable_name LIKE "Ssl_%"').map { |x| x.values_at('Variable_name', 'Value') }]
|
152
|
+
expect(results['Ssl_cipher']).not_to be_empty
|
153
|
+
expect(results['Ssl_version']).not_to be_empty
|
158
154
|
|
159
|
-
ssl_client.
|
155
|
+
expect(ssl_client.ssl_cipher).not_to be_empty
|
156
|
+
expect(results['Ssl_cipher']).to eql(ssl_client.ssl_cipher)
|
160
157
|
end
|
161
158
|
|
162
159
|
def run_gc
|
@@ -170,60 +167,116 @@ RSpec.describe Mysql2::Client do
|
|
170
167
|
|
171
168
|
it "should terminate connections when calling close" do
|
172
169
|
expect {
|
173
|
-
Mysql2::Client.new(DatabaseCredentials['root'])
|
170
|
+
client = Mysql2::Client.new(DatabaseCredentials['root'])
|
171
|
+
connection_id = client.thread_id
|
172
|
+
client.close
|
173
|
+
|
174
|
+
# mysql_close sends a quit command without waiting for a response
|
175
|
+
# so give the server some time to handle the detect the closed connection
|
176
|
+
closed = false
|
177
|
+
10.times do
|
178
|
+
closed = @client.query("SHOW PROCESSLIST").none? { |row| row['Id'] == connection_id }
|
179
|
+
break if closed
|
180
|
+
sleep(0.1)
|
181
|
+
end
|
182
|
+
expect(closed).to eq(true)
|
174
183
|
}.to_not change {
|
175
|
-
@client.query("SHOW STATUS LIKE '
|
184
|
+
@client.query("SHOW STATUS LIKE 'Aborted_%'").to_a
|
176
185
|
}
|
177
186
|
end
|
178
187
|
|
179
188
|
it "should not leave dangling connections after garbage collection" do
|
180
189
|
run_gc
|
190
|
+
expect {
|
191
|
+
expect {
|
192
|
+
10.times do
|
193
|
+
Mysql2::Client.new(DatabaseCredentials['root']).query('SELECT 1')
|
194
|
+
end
|
195
|
+
}.to change {
|
196
|
+
@client.query("SHOW STATUS LIKE 'Threads_connected'").first['Value'].to_i
|
197
|
+
}.by(10)
|
181
198
|
|
182
|
-
|
183
|
-
|
199
|
+
run_gc
|
200
|
+
}.to_not change {
|
201
|
+
@client.query("SHOW STATUS LIKE 'Aborted_%'").to_a +
|
202
|
+
@client.query("SHOW STATUS LIKE 'Threads_connected'").to_a
|
203
|
+
}
|
204
|
+
end
|
184
205
|
|
185
|
-
|
186
|
-
|
206
|
+
context "#automatic_close" do
|
207
|
+
it "is enabled by default" do
|
208
|
+
expect(new_client.automatic_close?).to be(true)
|
187
209
|
end
|
188
|
-
after_count = client.query("SHOW STATUS LIKE 'Threads_connected'").first['Value'].to_i
|
189
|
-
expect(after_count).to eq(before_count + 10)
|
190
210
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
211
|
+
if RUBY_PLATFORM =~ /mingw|mswin/
|
212
|
+
it "cannot be disabled" do
|
213
|
+
expect do
|
214
|
+
client = new_client(:automatic_close => false)
|
215
|
+
expect(client.automatic_close?).to be(true)
|
216
|
+
end.to output(/always closed by garbage collector/).to_stderr
|
217
|
+
|
218
|
+
expect do
|
219
|
+
client = new_client(:automatic_close => true)
|
220
|
+
expect(client.automatic_close?).to be(true)
|
221
|
+
end.to_not output(/always closed by garbage collector/).to_stderr
|
222
|
+
|
223
|
+
expect do
|
224
|
+
client = new_client(:automatic_close => true)
|
225
|
+
client.automatic_close = false
|
226
|
+
expect(client.automatic_close?).to be(true)
|
227
|
+
end.to output(/always closed by garbage collector/).to_stderr
|
228
|
+
end
|
229
|
+
else
|
230
|
+
it "can be configured" do
|
231
|
+
client = new_client(:automatic_close => false)
|
232
|
+
expect(client.automatic_close?).to be(false)
|
233
|
+
end
|
195
234
|
|
196
|
-
|
197
|
-
|
235
|
+
it "can be assigned" do
|
236
|
+
client = new_client
|
237
|
+
client.automatic_close = false
|
238
|
+
expect(client.automatic_close?).to be(false)
|
198
239
|
|
199
|
-
|
200
|
-
|
240
|
+
client.automatic_close = true
|
241
|
+
expect(client.automatic_close?).to be(true)
|
201
242
|
|
202
|
-
|
203
|
-
|
204
|
-
fork {}
|
243
|
+
client.automatic_close = nil
|
244
|
+
expect(client.automatic_close?).to be(false)
|
205
245
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
246
|
+
client.automatic_close = 9
|
247
|
+
expect(client.automatic_close?).to be(true)
|
248
|
+
end
|
249
|
+
|
250
|
+
it "should not close connections when running in a child process" do
|
251
|
+
run_gc
|
252
|
+
client = Mysql2::Client.new(DatabaseCredentials['root'])
|
253
|
+
client.automatic_close = false
|
254
|
+
|
255
|
+
child = fork do
|
256
|
+
client.query('SELECT 1')
|
257
|
+
client = nil
|
258
|
+
run_gc
|
259
|
+
end
|
211
260
|
|
212
|
-
|
261
|
+
Process.wait(child)
|
213
262
|
|
214
|
-
|
215
|
-
|
216
|
-
|
263
|
+
# this will throw an error if the underlying socket was shutdown by the
|
264
|
+
# child's GC
|
265
|
+
expect { client.query('SELECT 1') }.to_not raise_exception
|
266
|
+
client.close
|
267
|
+
end
|
268
|
+
end
|
217
269
|
end
|
218
270
|
|
219
271
|
it "should be able to connect to database with numeric-only name" do
|
220
|
-
|
221
|
-
@client.query "CREATE DATABASE IF NOT EXISTS `#{
|
222
|
-
@client.query "GRANT ALL ON `#{creds['database']}`.* TO #{creds['username']}@`#{creds['host']}`"
|
272
|
+
database = 1235
|
273
|
+
@client.query "CREATE DATABASE IF NOT EXISTS `#{database}`"
|
223
274
|
|
224
|
-
expect {
|
275
|
+
expect {
|
276
|
+
new_client('database' => database)
|
277
|
+
}.not_to raise_error
|
225
278
|
|
226
|
-
@client.query "DROP DATABASE IF EXISTS `#{
|
279
|
+
@client.query "DROP DATABASE IF EXISTS `#{database}`"
|
227
280
|
end
|
228
281
|
|
229
282
|
it "should respond to #close" do
|
@@ -237,6 +290,25 @@ RSpec.describe Mysql2::Client do
|
|
237
290
|
}.to raise_error(Mysql2::Error)
|
238
291
|
end
|
239
292
|
|
293
|
+
context "#closed?" do
|
294
|
+
it "should return false when connected" do
|
295
|
+
expect(@client.closed?).to eql(false)
|
296
|
+
end
|
297
|
+
|
298
|
+
it "should return true after close" do
|
299
|
+
@client.close
|
300
|
+
expect(@client.closed?).to eql(true)
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
it "should not try to query closed mysql connection" do
|
305
|
+
client = new_client(:reconnect => true)
|
306
|
+
expect(client.close).to be_nil
|
307
|
+
expect {
|
308
|
+
client.query "SELECT 1"
|
309
|
+
}.to raise_error(Mysql2::Error)
|
310
|
+
end
|
311
|
+
|
240
312
|
it "should respond to #query" do
|
241
313
|
expect(@client).to respond_to(:query)
|
242
314
|
end
|
@@ -255,8 +327,8 @@ RSpec.describe Mysql2::Client do
|
|
255
327
|
context "when has a warnings" do
|
256
328
|
it "should > 0" do
|
257
329
|
# "the statement produces extra information that can be viewed by issuing a SHOW WARNINGS"
|
258
|
-
#
|
259
|
-
@client.query(
|
330
|
+
# https://dev.mysql.com/doc/refman/5.7/en/show-warnings.html
|
331
|
+
@client.query('DROP TABLE IF EXISTS test.no_such_table')
|
260
332
|
expect(@client.warning_count).to be > 0
|
261
333
|
end
|
262
334
|
end
|
@@ -293,65 +365,76 @@ RSpec.describe Mysql2::Client do
|
|
293
365
|
|
294
366
|
context ":local_infile" do
|
295
367
|
before(:all) do
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
368
|
+
new_client(:local_infile => true) do |client|
|
369
|
+
local = client.query "SHOW VARIABLES LIKE 'local_infile'"
|
370
|
+
local_enabled = local.any? { |x| x['Value'] == 'ON' }
|
371
|
+
skip("DON'T WORRY, THIS TEST PASSES - but LOCAL INFILE is not enabled in your MySQL daemon.") unless local_enabled
|
372
|
+
|
373
|
+
client.query %[
|
374
|
+
CREATE TABLE IF NOT EXISTS infileTest (
|
375
|
+
id MEDIUMINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
376
|
+
foo VARCHAR(10),
|
377
|
+
bar MEDIUMTEXT
|
378
|
+
)
|
379
|
+
]
|
380
|
+
end
|
308
381
|
end
|
309
382
|
|
310
383
|
after(:all) do
|
311
|
-
|
384
|
+
new_client do |client|
|
385
|
+
client.query "DROP TABLE IF EXISTS infileTest"
|
386
|
+
end
|
312
387
|
end
|
313
388
|
|
314
389
|
it "should raise an error when local_infile is disabled" do
|
315
|
-
client =
|
390
|
+
client = new_client(:local_infile => false)
|
316
391
|
expect {
|
317
392
|
client.query "LOAD DATA LOCAL INFILE 'spec/test_data' INTO TABLE infileTest"
|
318
393
|
}.to raise_error(Mysql2::Error, /command is not allowed/)
|
319
394
|
end
|
320
395
|
|
321
396
|
it "should raise an error when a non-existent file is loaded" do
|
397
|
+
client = new_client(:local_infile => true)
|
322
398
|
expect {
|
323
|
-
|
399
|
+
client.query "LOAD DATA LOCAL INFILE 'this/file/is/not/here' INTO TABLE infileTest"
|
324
400
|
}.to raise_error(Mysql2::Error, 'No such file or directory: this/file/is/not/here')
|
325
401
|
end
|
326
402
|
|
327
403
|
it "should LOAD DATA LOCAL INFILE" do
|
328
|
-
|
329
|
-
|
404
|
+
client = new_client(:local_infile => true)
|
405
|
+
client.query "LOAD DATA LOCAL INFILE 'spec/test_data' INTO TABLE infileTest"
|
406
|
+
info = client.query_info
|
330
407
|
expect(info).to eql(:records => 1, :deleted => 0, :skipped => 0, :warnings => 0)
|
331
408
|
|
332
|
-
result =
|
409
|
+
result = client.query "SELECT * FROM infileTest"
|
333
410
|
expect(result.first).to eql('id' => 1, 'foo' => 'Hello', 'bar' => 'World')
|
334
411
|
end
|
335
412
|
end
|
336
413
|
|
337
414
|
it "should expect connect_timeout to be a positive integer" do
|
338
415
|
expect {
|
339
|
-
|
416
|
+
new_client(:connect_timeout => -1)
|
340
417
|
}.to raise_error(Mysql2::Error)
|
341
418
|
end
|
342
419
|
|
343
420
|
it "should expect read_timeout to be a positive integer" do
|
344
421
|
expect {
|
345
|
-
|
422
|
+
new_client(:read_timeout => -1)
|
346
423
|
}.to raise_error(Mysql2::Error)
|
347
424
|
end
|
348
425
|
|
349
426
|
it "should expect write_timeout to be a positive integer" do
|
350
427
|
expect {
|
351
|
-
|
428
|
+
new_client(:write_timeout => -1)
|
352
429
|
}.to raise_error(Mysql2::Error)
|
353
430
|
end
|
354
431
|
|
432
|
+
it "should allow nil read_timeout" do
|
433
|
+
client = new_client(:read_timeout => nil)
|
434
|
+
|
435
|
+
expect(client.read_timeout).to be_nil
|
436
|
+
end
|
437
|
+
|
355
438
|
context "#query" do
|
356
439
|
it "should let you query again if iterating is finished when streaming" do
|
357
440
|
@client.query("SELECT 1 UNION SELECT 2", :stream => true, :cache_rows => false).each.to_a
|
@@ -417,6 +500,25 @@ RSpec.describe Mysql2::Client do
|
|
417
500
|
}.to raise_error(Mysql2::Error)
|
418
501
|
end
|
419
502
|
|
503
|
+
it "should detect closed connection on query read error" do
|
504
|
+
connection_id = @client.thread_id
|
505
|
+
Thread.new do
|
506
|
+
sleep(0.1)
|
507
|
+
Mysql2::Client.new(DatabaseCredentials['root']).tap do |supervisor|
|
508
|
+
supervisor.query("KILL #{connection_id}")
|
509
|
+
end.close
|
510
|
+
end
|
511
|
+
expect {
|
512
|
+
@client.query("SELECT SLEEP(1)")
|
513
|
+
}.to raise_error(Mysql2::Error, /Lost connection to MySQL server/)
|
514
|
+
|
515
|
+
if RUBY_PLATFORM !~ /mingw|mswin/
|
516
|
+
expect {
|
517
|
+
@client.socket
|
518
|
+
}.to raise_error(Mysql2::Error, 'MySQL client is not connected')
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
420
522
|
if RUBY_PLATFORM !~ /mingw|mswin/
|
421
523
|
it "should not allow another query to be sent without fetching a result first" do
|
422
524
|
@client.query("SELECT 1", :async => true)
|
@@ -433,7 +535,7 @@ RSpec.describe Mysql2::Client do
|
|
433
535
|
end
|
434
536
|
|
435
537
|
it "should timeout if we wait longer than :read_timeout" do
|
436
|
-
client =
|
538
|
+
client = new_client(:read_timeout => 0)
|
437
539
|
expect {
|
438
540
|
client.query('SELECT SLEEP(0.1)')
|
439
541
|
}.to raise_error(Mysql2::Error)
|
@@ -481,15 +583,6 @@ RSpec.describe Mysql2::Client do
|
|
481
583
|
}.to raise_error(Mysql2::Error)
|
482
584
|
end
|
483
585
|
|
484
|
-
it 'should be impervious to connection-corrupting timeouts in #query' do
|
485
|
-
pending('`Thread.handle_interrupt` is not defined') unless Thread.respond_to?(:handle_interrupt)
|
486
|
-
# attempt to break the connection
|
487
|
-
expect { Timeout.timeout(0.1) { @client.query('SELECT SLEEP(0.2)') } }.to raise_error(Timeout::Error)
|
488
|
-
|
489
|
-
# expect the connection to not be broken
|
490
|
-
expect { @client.query('SELECT 1') }.to_not raise_error
|
491
|
-
end
|
492
|
-
|
493
586
|
it 'should be impervious to connection-corrupting timeouts in #execute' do
|
494
587
|
# the statement handle gets corrupted and will segfault the tests if interrupted,
|
495
588
|
# so we can't even use pending on this test, really have to skip it on older Rubies.
|
@@ -507,26 +600,26 @@ RSpec.describe Mysql2::Client do
|
|
507
600
|
context 'when a non-standard exception class is raised' do
|
508
601
|
it "should close the connection when an exception is raised" do
|
509
602
|
expect { Timeout.timeout(0.1, ArgumentError) { @client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
|
510
|
-
expect { @client.query('SELECT 1') }.to raise_error(Mysql2::Error, '
|
603
|
+
expect { @client.query('SELECT 1') }.to raise_error(Mysql2::Error, 'MySQL client is not connected')
|
511
604
|
end
|
512
605
|
|
513
606
|
it "should handle Timeouts without leaving the connection hanging if reconnect is true" do
|
514
|
-
if RUBY_PLATFORM.include?('darwin') &&
|
515
|
-
pending('
|
607
|
+
if RUBY_PLATFORM.include?('darwin') && @client.server_info.fetch(:version).start_with?('5.5')
|
608
|
+
pending('MySQL 5.5 on OSX is afflicted by an unknown bug that breaks this test. See #633 and #634.')
|
516
609
|
end
|
517
610
|
|
518
|
-
client =
|
611
|
+
client = new_client(:reconnect => true)
|
519
612
|
|
520
613
|
expect { Timeout.timeout(0.1, ArgumentError) { client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
|
521
614
|
expect { client.query('SELECT 1') }.to_not raise_error
|
522
615
|
end
|
523
616
|
|
524
617
|
it "should handle Timeouts without leaving the connection hanging if reconnect is set to true after construction" do
|
525
|
-
if RUBY_PLATFORM.include?('darwin') &&
|
526
|
-
pending('
|
618
|
+
if RUBY_PLATFORM.include?('darwin') && @client.server_info.fetch(:version).start_with?('5.5')
|
619
|
+
pending('MySQL 5.5 on OSX is afflicted by an unknown bug that breaks this test. See #633 and #634.')
|
527
620
|
end
|
528
621
|
|
529
|
-
client =
|
622
|
+
client = new_client
|
530
623
|
|
531
624
|
expect { Timeout.timeout(0.1, ArgumentError) { client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
|
532
625
|
expect { client.query('SELECT 1') }.to raise_error(Mysql2::Error)
|
@@ -544,8 +637,9 @@ RSpec.describe Mysql2::Client do
|
|
544
637
|
# Note that each thread opens its own database connection
|
545
638
|
threads = 5.times.map do
|
546
639
|
Thread.new do
|
547
|
-
|
548
|
-
|
640
|
+
new_client do |client|
|
641
|
+
client.query("SELECT SLEEP(#{sleep_time})")
|
642
|
+
end
|
549
643
|
Thread.current.object_id
|
550
644
|
end
|
551
645
|
end
|
@@ -558,10 +652,11 @@ RSpec.describe Mysql2::Client do
|
|
558
652
|
end
|
559
653
|
|
560
654
|
it "evented async queries should be supported" do
|
655
|
+
skip("ruby 1.8 doesn't support IO.for_fd options") if RUBY_VERSION.start_with?("1.8.")
|
561
656
|
# should immediately return nil
|
562
657
|
expect(@client.query("SELECT sleep(0.1)", :async => true)).to eql(nil)
|
563
658
|
|
564
|
-
io_wrapper = IO.for_fd(@client.socket)
|
659
|
+
io_wrapper = IO.for_fd(@client.socket, :autoclose => false)
|
565
660
|
loops = 0
|
566
661
|
loop do
|
567
662
|
if IO.select([io_wrapper], nil, nil, 0.05)
|
@@ -581,7 +676,7 @@ RSpec.describe Mysql2::Client do
|
|
581
676
|
|
582
677
|
context "Multiple results sets" do
|
583
678
|
before(:each) do
|
584
|
-
@multi_client =
|
679
|
+
@multi_client = new_client(:flags => Mysql2::Client::MULTI_STATEMENTS)
|
585
680
|
end
|
586
681
|
|
587
682
|
it "should raise an exception when one of multiple statements fails" do
|
@@ -659,7 +754,7 @@ RSpec.describe Mysql2::Client do
|
|
659
754
|
it "#socket should raise as it's not supported" do
|
660
755
|
expect {
|
661
756
|
@client.socket
|
662
|
-
}.to raise_error(Mysql2::Error)
|
757
|
+
}.to raise_error(Mysql2::Error, /Raw access to the mysql file descriptor isn't supported on Windows/)
|
663
758
|
end
|
664
759
|
end
|
665
760
|
|
@@ -738,7 +833,7 @@ RSpec.describe Mysql2::Client do
|
|
738
833
|
context 'when mysql encoding is not utf8' do
|
739
834
|
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
740
835
|
|
741
|
-
let(:client) {
|
836
|
+
let(:client) { new_client(:encoding => "ujis") }
|
742
837
|
|
743
838
|
it 'should return a internal encoding string if Encoding.default_internal is set' do
|
744
839
|
with_internal_encoding Encoding::UTF_8 do
|
@@ -807,7 +902,7 @@ RSpec.describe Mysql2::Client do
|
|
807
902
|
with_internal_encoding nil do
|
808
903
|
expect(@client.server_info[:version].encoding).to eql(Encoding::UTF_8)
|
809
904
|
|
810
|
-
client2 =
|
905
|
+
client2 = new_client(:encoding => 'ascii')
|
811
906
|
expect(client2.server_info[:version].encoding).to eql(Encoding::ASCII)
|
812
907
|
end
|
813
908
|
end
|
@@ -825,11 +920,11 @@ RSpec.describe Mysql2::Client do
|
|
825
920
|
|
826
921
|
it "should raise a Mysql2::Error exception upon connection failure" do
|
827
922
|
expect {
|
828
|
-
|
923
|
+
new_client(:host => "localhost", :username => 'asdfasdf8d2h', :password => 'asdfasdfw42')
|
829
924
|
}.to raise_error(Mysql2::Error)
|
830
925
|
|
831
926
|
expect {
|
832
|
-
|
927
|
+
new_client(DatabaseCredentials['root'])
|
833
928
|
}.not_to raise_error
|
834
929
|
end
|
835
930
|
|
@@ -931,6 +1026,11 @@ RSpec.describe Mysql2::Client do
|
|
931
1026
|
expect(@client.ping).to eql(false)
|
932
1027
|
end
|
933
1028
|
|
1029
|
+
it "should be able to connect using plaintext password" do
|
1030
|
+
client = new_client(:enable_cleartext_plugin => true)
|
1031
|
+
client.query('SELECT 1')
|
1032
|
+
end
|
1033
|
+
|
934
1034
|
unless RUBY_VERSION =~ /1.8/
|
935
1035
|
it "should respond to #encoding" do
|
936
1036
|
expect(@client).to respond_to(:encoding)
|
data/spec/mysql2/error_spec.rb
CHANGED
@@ -3,11 +3,9 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
RSpec.describe Mysql2::Error do
|
6
|
-
let(:client) { Mysql2::Client.new(DatabaseCredentials['root']) }
|
7
|
-
|
8
6
|
let(:error) do
|
9
7
|
begin
|
10
|
-
client.query("HAHAHA")
|
8
|
+
@client.query("HAHAHA")
|
11
9
|
rescue Mysql2::Error => e
|
12
10
|
error = e
|
13
11
|
end
|
@@ -28,16 +26,16 @@ RSpec.describe Mysql2::Error do
|
|
28
26
|
let(:valid_utf8) { '造字' }
|
29
27
|
let(:error) do
|
30
28
|
begin
|
31
|
-
client.query(valid_utf8)
|
29
|
+
@client.query(valid_utf8)
|
32
30
|
rescue Mysql2::Error => e
|
33
31
|
e
|
34
32
|
end
|
35
33
|
end
|
36
34
|
|
37
|
-
let(:invalid_utf8) { "
|
35
|
+
let(:invalid_utf8) { ["e5c67d1f"].pack('H*').force_encoding(Encoding::UTF_8) }
|
38
36
|
let(:bad_err) do
|
39
37
|
begin
|
40
|
-
client.query(invalid_utf8)
|
38
|
+
@client.query(invalid_utf8)
|
41
39
|
rescue Mysql2::Error => e
|
42
40
|
e
|
43
41
|
end
|