mysql2 0.4.4 → 0.5.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
- data/README.md +90 -52
- data/examples/eventmachine.rb +0 -2
- data/examples/threaded.rb +2 -4
- data/ext/mysql2/client.c +260 -76
- data/ext/mysql2/client.h +2 -47
- data/ext/mysql2/extconf.rb +44 -18
- data/ext/mysql2/mysql2_ext.c +2 -1
- data/ext/mysql2/mysql2_ext.h +8 -8
- data/ext/mysql2/result.c +23 -74
- data/ext/mysql2/statement.c +139 -63
- data/ext/mysql2/statement.h +0 -2
- data/ext/mysql2/wait_for_single_fd.h +2 -1
- data/lib/mysql2/client.rb +50 -31
- data/lib/mysql2/em.rb +2 -4
- data/lib/mysql2/error.rb +49 -20
- data/lib/mysql2/result.rb +2 -0
- data/lib/mysql2/statement.rb +3 -9
- data/lib/mysql2/version.rb +1 -1
- data/lib/mysql2.rb +14 -15
- data/spec/configuration.yml.example +0 -6
- data/spec/em/em_spec.rb +6 -6
- data/spec/mysql2/client_spec.rb +318 -237
- data/spec/mysql2/error_spec.rb +4 -10
- data/spec/mysql2/result_spec.rb +124 -158
- data/spec/mysql2/statement_spec.rb +185 -180
- data/spec/spec_helper.rb +79 -61
- data/spec/ssl/gen_certs.sh +1 -1
- data/support/5072E1F5.asc +432 -0
- data/support/mysql_enc_to_ruby.rb +2 -2
- data/support/ruby_enc_to_mysql.rb +5 -5
- metadata +16 -14
data/spec/mysql2/client_spec.rb
CHANGED
@@ -1,47 +1,50 @@
|
|
1
|
-
# encoding: UTF-8
|
2
1
|
require 'spec_helper'
|
3
|
-
require 'stringio'
|
4
2
|
|
5
3
|
RSpec.describe Mysql2::Client do
|
6
4
|
context "using defaults file" do
|
7
5
|
let(:cnf_file) { File.expand_path('../../my.cnf', __FILE__) }
|
8
6
|
|
9
7
|
it "should not raise an exception for valid defaults group" do
|
10
|
-
expect
|
11
|
-
|
12
|
-
|
13
|
-
}.not_to raise_error
|
8
|
+
expect do
|
9
|
+
new_client(default_file: cnf_file, default_group: "test")
|
10
|
+
end.not_to raise_error
|
14
11
|
end
|
15
12
|
|
16
13
|
it "should not raise an exception without default group" do
|
17
|
-
expect
|
18
|
-
|
19
|
-
|
14
|
+
expect do
|
15
|
+
new_client(default_file: cnf_file)
|
16
|
+
end.not_to raise_error
|
20
17
|
end
|
21
18
|
end
|
22
19
|
|
23
|
-
it "should raise
|
24
|
-
expect
|
20
|
+
it "should raise a Mysql::Error::ConnectionError upon connection failure" do
|
21
|
+
expect do
|
25
22
|
# The odd local host IP address forces the mysql client library to
|
26
23
|
# use a TCP socket rather than a domain socket.
|
27
|
-
|
28
|
-
|
24
|
+
new_client('host' => '127.0.0.2', 'port' => 999999)
|
25
|
+
end.to raise_error(Mysql2::Error::ConnectionError)
|
29
26
|
end
|
30
27
|
|
31
28
|
it "should raise an exception on create for invalid encodings" do
|
32
|
-
expect
|
33
|
-
|
34
|
-
|
29
|
+
expect do
|
30
|
+
new_client(encoding: "fake")
|
31
|
+
end.to raise_error(Mysql2::Error)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should raise an exception on non-string encodings" do
|
35
|
+
expect do
|
36
|
+
new_client(encoding: :fake)
|
37
|
+
end.to raise_error(TypeError)
|
35
38
|
end
|
36
39
|
|
37
40
|
it "should not raise an exception on create for a valid encoding" do
|
38
|
-
expect
|
39
|
-
|
40
|
-
|
41
|
+
expect do
|
42
|
+
new_client(encoding: "utf8")
|
43
|
+
end.not_to raise_error
|
41
44
|
|
42
|
-
expect
|
43
|
-
|
44
|
-
|
45
|
+
expect do
|
46
|
+
new_client(DatabaseCredentials['root'].merge(encoding: "big5"))
|
47
|
+
end.not_to raise_error
|
45
48
|
end
|
46
49
|
|
47
50
|
Klient = Class.new(Mysql2::Client) do
|
@@ -53,18 +56,18 @@ RSpec.describe Mysql2::Client do
|
|
53
56
|
end
|
54
57
|
|
55
58
|
it "should accept connect flags and pass them to #connect" do
|
56
|
-
client = Klient.new :
|
59
|
+
client = Klient.new flags: Mysql2::Client::FOUND_ROWS
|
57
60
|
expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to be > 0
|
58
61
|
end
|
59
62
|
|
60
63
|
it "should parse flags array" do
|
61
|
-
client = Klient.new :
|
64
|
+
client = Klient.new flags: %w[FOUND_ROWS -PROTOCOL_41]
|
62
65
|
expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to eql(Mysql2::Client::FOUND_ROWS)
|
63
66
|
expect(client.connect_args.last[6] & Mysql2::Client::PROTOCOL_41).to eql(0)
|
64
67
|
end
|
65
68
|
|
66
69
|
it "should parse flags string" do
|
67
|
-
client = Klient.new :
|
70
|
+
client = Klient.new flags: "FOUND_ROWS -PROTOCOL_41"
|
68
71
|
expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to eql(Mysql2::Client::FOUND_ROWS)
|
69
72
|
expect(client.connect_args.last[6] & Mysql2::Client::PROTOCOL_41).to eql(0)
|
70
73
|
end
|
@@ -76,14 +79,15 @@ RSpec.describe Mysql2::Client do
|
|
76
79
|
Mysql2::Client::LONG_FLAG |
|
77
80
|
Mysql2::Client::TRANSACTIONS |
|
78
81
|
Mysql2::Client::PROTOCOL_41 |
|
79
|
-
Mysql2::Client::SECURE_CONNECTION
|
82
|
+
Mysql2::Client::SECURE_CONNECTION |
|
83
|
+
Mysql2::Client::CONNECT_ATTRS
|
80
84
|
expect(client.connect_args.last[6]).to eql(client_flags)
|
81
85
|
end
|
82
86
|
|
83
87
|
it "should execute init command" do
|
84
88
|
options = DatabaseCredentials['root'].dup
|
85
89
|
options[:init_command] = "SET @something = 'setting_value';"
|
86
|
-
client =
|
90
|
+
client = new_client(options)
|
87
91
|
result = client.query("SELECT @something;")
|
88
92
|
expect(result.first['@something']).to eq('setting_value')
|
89
93
|
end
|
@@ -92,7 +96,7 @@ RSpec.describe Mysql2::Client do
|
|
92
96
|
options = DatabaseCredentials['root'].dup
|
93
97
|
options[:init_command] = "SET @something = 'setting_value';"
|
94
98
|
options[:reconnect] = true
|
95
|
-
client =
|
99
|
+
client = new_client(options)
|
96
100
|
|
97
101
|
result = client.query("SELECT @something;")
|
98
102
|
expect(result.first['@something']).to eq('setting_value')
|
@@ -131,20 +135,16 @@ RSpec.describe Mysql2::Client do
|
|
131
135
|
|
132
136
|
# You may need to adjust the lines below to match your SSL certificate paths
|
133
137
|
ssl_client = nil
|
134
|
-
expect
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
:sslcipher => 'DHE-RSA-AES256-SHA',
|
143
|
-
:sslverify => true
|
144
|
-
)
|
138
|
+
expect do
|
139
|
+
ssl_client = new_client(
|
140
|
+
'host' => 'mysql2gem.example.com', # must match the certificates
|
141
|
+
:sslkey => '/etc/mysql/client-key.pem',
|
142
|
+
:sslcert => '/etc/mysql/client-cert.pem',
|
143
|
+
:sslca => '/etc/mysql/ca-cert.pem',
|
144
|
+
:sslcipher => 'DHE-RSA-AES256-SHA',
|
145
|
+
:sslverify => true,
|
145
146
|
)
|
146
|
-
|
147
|
-
}.not_to raise_error
|
147
|
+
end.not_to raise_error
|
148
148
|
|
149
149
|
results = Hash[ssl_client.query('SHOW STATUS WHERE Variable_name LIKE "Ssl_%"').map { |x| x.values_at('Variable_name', 'Value') }]
|
150
150
|
expect(results['Ssl_cipher']).not_to be_empty
|
@@ -152,8 +152,6 @@ RSpec.describe Mysql2::Client do
|
|
152
152
|
|
153
153
|
expect(ssl_client.ssl_cipher).not_to be_empty
|
154
154
|
expect(results['Ssl_cipher']).to eql(ssl_client.ssl_cipher)
|
155
|
-
|
156
|
-
ssl_client.close
|
157
155
|
end
|
158
156
|
|
159
157
|
def run_gc
|
@@ -166,65 +164,112 @@ RSpec.describe Mysql2::Client do
|
|
166
164
|
end
|
167
165
|
|
168
166
|
it "should terminate connections when calling close" do
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
167
|
+
# rubocop:disable Lint/AmbiguousBlockAssociation
|
168
|
+
expect do
|
169
|
+
client = Mysql2::Client.new(DatabaseCredentials['root'])
|
170
|
+
connection_id = client.thread_id
|
171
|
+
client.close
|
172
|
+
|
173
|
+
# mysql_close sends a quit command without waiting for a response
|
174
|
+
# so give the server some time to handle the detect the closed connection
|
175
|
+
closed = false
|
176
|
+
10.times do
|
177
|
+
closed = @client.query("SHOW PROCESSLIST").none? { |row| row['Id'] == connection_id }
|
178
|
+
break if closed
|
179
|
+
sleep(0.1)
|
180
|
+
end
|
181
|
+
expect(closed).to eq(true)
|
182
|
+
end.to_not change {
|
183
|
+
@client.query("SHOW STATUS LIKE 'Aborted_%'").to_a
|
174
184
|
}
|
185
|
+
# rubocop:enable Lint/AmbiguousBlockAssociation
|
175
186
|
end
|
176
187
|
|
177
188
|
it "should not leave dangling connections after garbage collection" do
|
178
189
|
run_gc
|
179
|
-
|
180
|
-
|
190
|
+
# rubocop:disable Lint/AmbiguousBlockAssociation
|
191
|
+
expect do
|
192
|
+
expect do
|
181
193
|
10.times do
|
182
194
|
Mysql2::Client.new(DatabaseCredentials['root']).query('SELECT 1')
|
183
195
|
end
|
184
|
-
|
196
|
+
end.to change {
|
185
197
|
@client.query("SHOW STATUS LIKE 'Threads_connected'").first['Value'].to_i
|
186
198
|
}.by(10)
|
187
199
|
|
188
200
|
run_gc
|
189
|
-
|
201
|
+
end.to_not change {
|
190
202
|
@client.query("SHOW STATUS LIKE 'Aborted_%'").to_a +
|
191
203
|
@client.query("SHOW STATUS LIKE 'Threads_connected'").to_a
|
192
204
|
}
|
205
|
+
# rubocop:enable Lint/AmbiguousBlockAssociation
|
206
|
+
end
|
207
|
+
|
208
|
+
context "#set_server_option" do
|
209
|
+
let(:client) do
|
210
|
+
new_client.tap do |client|
|
211
|
+
client.set_server_option(Mysql2::Client::OPTION_MULTI_STATEMENTS_ON)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'returns true when multi_statements is enable' do
|
216
|
+
expect(client.set_server_option(Mysql2::Client::OPTION_MULTI_STATEMENTS_ON)).to be true
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'returns true when multi_statements is disable' do
|
220
|
+
expect(client.set_server_option(Mysql2::Client::OPTION_MULTI_STATEMENTS_OFF)).to be true
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'returns false when multi_statements is neither OPTION_MULTI_STATEMENTS_OFF or OPTION_MULTI_STATEMENTS_ON' do
|
224
|
+
expect(client.set_server_option(344)).to be false
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'enables multiple-statement' do
|
228
|
+
client.query("SELECT 1;SELECT 2;")
|
229
|
+
|
230
|
+
expect(client.next_result).to be true
|
231
|
+
expect(client.store_result.first).to eql('2' => 2)
|
232
|
+
expect(client.next_result).to be false
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'disables multiple-statement' do
|
236
|
+
client.set_server_option(Mysql2::Client::OPTION_MULTI_STATEMENTS_OFF)
|
237
|
+
|
238
|
+
expect { client.query("SELECT 1;SELECT 2;") }.to raise_error(Mysql2::Error)
|
239
|
+
end
|
193
240
|
end
|
194
241
|
|
195
242
|
context "#automatic_close" do
|
196
243
|
it "is enabled by default" do
|
197
|
-
|
198
|
-
expect(client.automatic_close?).to be(true)
|
244
|
+
expect(new_client.automatic_close?).to be(true)
|
199
245
|
end
|
200
246
|
|
201
247
|
if RUBY_PLATFORM =~ /mingw|mswin/
|
202
248
|
it "cannot be disabled" do
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
client
|
249
|
+
expect do
|
250
|
+
client = new_client(automatic_close: false)
|
251
|
+
expect(client.automatic_close?).to be(true)
|
252
|
+
end.to output(/always closed by garbage collector/).to_stderr
|
253
|
+
|
254
|
+
expect do
|
255
|
+
client = new_client(automatic_close: true)
|
256
|
+
expect(client.automatic_close?).to be(true)
|
257
|
+
end.to_not output(/always closed by garbage collector/).to_stderr
|
258
|
+
|
259
|
+
expect do
|
260
|
+
client = new_client(automatic_close: true)
|
211
261
|
client.automatic_close = false
|
212
|
-
expect(
|
213
|
-
|
214
|
-
|
215
|
-
expect { client.automatic_close = true }.to_not change { $stderr.string }
|
216
|
-
ensure
|
217
|
-
$stderr = stderr
|
218
|
-
end
|
262
|
+
expect(client.automatic_close?).to be(true)
|
263
|
+
end.to output(/always closed by garbage collector/).to_stderr
|
219
264
|
end
|
220
265
|
else
|
221
266
|
it "can be configured" do
|
222
|
-
client =
|
267
|
+
client = new_client(automatic_close: false)
|
223
268
|
expect(client.automatic_close?).to be(false)
|
224
269
|
end
|
225
270
|
|
226
271
|
it "can be assigned" do
|
227
|
-
client =
|
272
|
+
client = new_client
|
228
273
|
client.automatic_close = false
|
229
274
|
expect(client.automatic_close?).to be(false)
|
230
275
|
|
@@ -243,33 +288,31 @@ RSpec.describe Mysql2::Client do
|
|
243
288
|
client = Mysql2::Client.new(DatabaseCredentials['root'])
|
244
289
|
client.automatic_close = false
|
245
290
|
|
246
|
-
|
247
|
-
# `fork` call hangs forever. WTF?
|
248
|
-
fork {}
|
249
|
-
|
250
|
-
fork do
|
291
|
+
child = fork do
|
251
292
|
client.query('SELECT 1')
|
252
293
|
client = nil
|
253
294
|
run_gc
|
254
295
|
end
|
255
296
|
|
256
|
-
Process.wait
|
297
|
+
Process.wait(child)
|
257
298
|
|
258
299
|
# this will throw an error if the underlying socket was shutdown by the
|
259
300
|
# child's GC
|
260
301
|
expect { client.query('SELECT 1') }.to_not raise_exception
|
302
|
+
client.close
|
261
303
|
end
|
262
304
|
end
|
263
305
|
end
|
264
306
|
|
265
307
|
it "should be able to connect to database with numeric-only name" do
|
266
|
-
|
267
|
-
@client.query "CREATE DATABASE IF NOT EXISTS `#{
|
268
|
-
@client.query "GRANT ALL ON `#{creds['database']}`.* TO #{creds['username']}@`#{creds['host']}`"
|
308
|
+
database = 1235
|
309
|
+
@client.query "CREATE DATABASE IF NOT EXISTS `#{database}`"
|
269
310
|
|
270
|
-
expect
|
311
|
+
expect do
|
312
|
+
new_client('database' => database)
|
313
|
+
end.not_to raise_error
|
271
314
|
|
272
|
-
@client.query "DROP DATABASE IF EXISTS `#{
|
315
|
+
@client.query "DROP DATABASE IF EXISTS `#{database}`"
|
273
316
|
end
|
274
317
|
|
275
318
|
it "should respond to #close" do
|
@@ -278,9 +321,28 @@ RSpec.describe Mysql2::Client do
|
|
278
321
|
|
279
322
|
it "should be able to close properly" do
|
280
323
|
expect(@client.close).to be_nil
|
281
|
-
expect
|
324
|
+
expect do
|
282
325
|
@client.query "SELECT 1"
|
283
|
-
|
326
|
+
end.to raise_error(Mysql2::Error)
|
327
|
+
end
|
328
|
+
|
329
|
+
context "#closed?" do
|
330
|
+
it "should return false when connected" do
|
331
|
+
expect(@client.closed?).to eql(false)
|
332
|
+
end
|
333
|
+
|
334
|
+
it "should return true after close" do
|
335
|
+
@client.close
|
336
|
+
expect(@client.closed?).to eql(true)
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
it "should not try to query closed mysql connection" do
|
341
|
+
client = new_client(reconnect: true)
|
342
|
+
expect(client.close).to be_nil
|
343
|
+
expect do
|
344
|
+
client.query "SELECT 1"
|
345
|
+
end.to raise_error(Mysql2::Error)
|
284
346
|
end
|
285
347
|
|
286
348
|
it "should respond to #query" do
|
@@ -301,8 +363,8 @@ RSpec.describe Mysql2::Client do
|
|
301
363
|
context "when has a warnings" do
|
302
364
|
it "should > 0" do
|
303
365
|
# "the statement produces extra information that can be viewed by issuing a SHOW WARNINGS"
|
304
|
-
#
|
305
|
-
@client.query(
|
366
|
+
# https://dev.mysql.com/doc/refman/5.7/en/show-warnings.html
|
367
|
+
@client.query('DROP TABLE IF EXISTS test.no_such_table')
|
306
368
|
expect(@client.warning_count).to be > 0
|
307
369
|
end
|
308
370
|
end
|
@@ -329,7 +391,7 @@ RSpec.describe Mysql2::Client do
|
|
329
391
|
# # Note that mysql_info() returns a non-NULL value for INSERT ... VALUES only for the multiple-row form of the statement (that is, only if multiple value lists are specified).
|
330
392
|
@client.query("INSERT INTO infoTest (blah) VALUES (1234),(4535)")
|
331
393
|
|
332
|
-
expect(@client.query_info).to eql(:
|
394
|
+
expect(@client.query_info).to eql(records: 2, duplicates: 0, warnings: 0)
|
333
395
|
expect(@client.query_info_string).to eq('Records: 2 Duplicates: 0 Warnings: 0')
|
334
396
|
|
335
397
|
@client.query "DROP TABLE infoTest"
|
@@ -339,99 +401,124 @@ RSpec.describe Mysql2::Client do
|
|
339
401
|
|
340
402
|
context ":local_infile" do
|
341
403
|
before(:all) do
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
404
|
+
new_client(local_infile: true) do |client|
|
405
|
+
local = client.query "SHOW VARIABLES LIKE 'local_infile'"
|
406
|
+
local_enabled = local.any? { |x| x['Value'] == 'ON' }
|
407
|
+
skip("DON'T WORRY, THIS TEST PASSES - but LOCAL INFILE is not enabled in your MySQL daemon.") unless local_enabled
|
408
|
+
|
409
|
+
client.query %[
|
410
|
+
CREATE TABLE IF NOT EXISTS infileTest (
|
411
|
+
id MEDIUMINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
412
|
+
foo VARCHAR(10),
|
413
|
+
bar MEDIUMTEXT
|
414
|
+
)
|
415
|
+
]
|
416
|
+
end
|
354
417
|
end
|
355
418
|
|
356
419
|
after(:all) do
|
357
|
-
|
420
|
+
new_client do |client|
|
421
|
+
client.query "DROP TABLE IF EXISTS infileTest"
|
422
|
+
end
|
358
423
|
end
|
359
424
|
|
360
425
|
it "should raise an error when local_infile is disabled" do
|
361
|
-
client =
|
362
|
-
expect
|
426
|
+
client = new_client(local_infile: false)
|
427
|
+
expect do
|
363
428
|
client.query "LOAD DATA LOCAL INFILE 'spec/test_data' INTO TABLE infileTest"
|
364
|
-
|
429
|
+
end.to raise_error(Mysql2::Error, /command is not allowed/)
|
365
430
|
end
|
366
431
|
|
367
432
|
it "should raise an error when a non-existent file is loaded" do
|
368
|
-
|
369
|
-
|
370
|
-
|
433
|
+
client = new_client(local_infile: true)
|
434
|
+
expect do
|
435
|
+
client.query "LOAD DATA LOCAL INFILE 'this/file/is/not/here' INTO TABLE infileTest"
|
436
|
+
end.to raise_error(Mysql2::Error, 'No such file or directory: this/file/is/not/here')
|
371
437
|
end
|
372
438
|
|
373
439
|
it "should LOAD DATA LOCAL INFILE" do
|
374
|
-
|
375
|
-
|
376
|
-
|
440
|
+
client = new_client(local_infile: true)
|
441
|
+
client.query "LOAD DATA LOCAL INFILE 'spec/test_data' INTO TABLE infileTest"
|
442
|
+
info = client.query_info
|
443
|
+
expect(info).to eql(records: 1, deleted: 0, skipped: 0, warnings: 0)
|
377
444
|
|
378
|
-
result =
|
445
|
+
result = client.query "SELECT * FROM infileTest"
|
379
446
|
expect(result.first).to eql('id' => 1, 'foo' => 'Hello', 'bar' => 'World')
|
380
447
|
end
|
381
448
|
end
|
382
449
|
|
383
450
|
it "should expect connect_timeout to be a positive integer" do
|
384
|
-
expect
|
385
|
-
|
386
|
-
|
451
|
+
expect do
|
452
|
+
new_client(connect_timeout: -1)
|
453
|
+
end.to raise_error(Mysql2::Error)
|
387
454
|
end
|
388
455
|
|
389
456
|
it "should expect read_timeout to be a positive integer" do
|
390
|
-
expect
|
391
|
-
|
392
|
-
|
457
|
+
expect do
|
458
|
+
new_client(read_timeout: -1)
|
459
|
+
end.to raise_error(Mysql2::Error)
|
393
460
|
end
|
394
461
|
|
395
462
|
it "should expect write_timeout to be a positive integer" do
|
396
|
-
expect
|
397
|
-
|
398
|
-
|
463
|
+
expect do
|
464
|
+
new_client(write_timeout: -1)
|
465
|
+
end.to raise_error(Mysql2::Error)
|
399
466
|
end
|
400
467
|
|
401
468
|
it "should allow nil read_timeout" do
|
402
|
-
client =
|
469
|
+
client = new_client(read_timeout: nil)
|
403
470
|
|
404
471
|
expect(client.read_timeout).to be_nil
|
405
472
|
end
|
406
473
|
|
474
|
+
it "should set default program_name in connect_attrs" do
|
475
|
+
client = new_client
|
476
|
+
if Mysql2::Client::CONNECT_ATTRS.zero? || client.server_info[:version].match(/10.[01].\d+-MariaDB/)
|
477
|
+
pending('Both client and server versions must be MySQL 5.6 or MariaDB 10.2 or later.')
|
478
|
+
end
|
479
|
+
result = client.query("SELECT attr_value FROM performance_schema.session_account_connect_attrs WHERE processlist_id = connection_id() AND attr_name = 'program_name'")
|
480
|
+
expect(result.first['attr_value']).to eq($PROGRAM_NAME)
|
481
|
+
end
|
482
|
+
|
483
|
+
it "should set custom connect_attrs" do
|
484
|
+
client = new_client(connect_attrs: { program_name: 'my_program_name', foo: 'fooval', bar: 'barval' })
|
485
|
+
if Mysql2::Client::CONNECT_ATTRS.zero? || client.server_info[:version].match(/10.[01].\d+-MariaDB/)
|
486
|
+
pending('Both client and server versions must be MySQL 5.6 or MariaDB 10.2 or later.')
|
487
|
+
end
|
488
|
+
results = Hash[client.query("SELECT * FROM performance_schema.session_account_connect_attrs WHERE processlist_id = connection_id()").map { |x| x.values_at('ATTR_NAME', 'ATTR_VALUE') }]
|
489
|
+
expect(results['program_name']).to eq('my_program_name')
|
490
|
+
expect(results['foo']).to eq('fooval')
|
491
|
+
expect(results['bar']).to eq('barval')
|
492
|
+
end
|
493
|
+
|
407
494
|
context "#query" do
|
408
495
|
it "should let you query again if iterating is finished when streaming" do
|
409
|
-
@client.query("SELECT 1 UNION SELECT 2", :
|
496
|
+
@client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false).each.to_a
|
410
497
|
|
411
|
-
expect
|
412
|
-
@client.query("SELECT 1 UNION SELECT 2", :
|
413
|
-
|
498
|
+
expect do
|
499
|
+
@client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false)
|
500
|
+
end.to_not raise_error
|
414
501
|
end
|
415
502
|
|
416
503
|
it "should not let you query again if iterating is not finished when streaming" do
|
417
|
-
@client.query("SELECT 1 UNION SELECT 2", :
|
504
|
+
@client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false).first
|
418
505
|
|
419
|
-
expect
|
420
|
-
@client.query("SELECT 1 UNION SELECT 2", :
|
421
|
-
|
506
|
+
expect do
|
507
|
+
@client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false)
|
508
|
+
end.to raise_exception(Mysql2::Error)
|
422
509
|
end
|
423
510
|
|
424
511
|
it "should only accept strings as the query parameter" do
|
425
|
-
expect
|
512
|
+
expect do
|
426
513
|
@client.query ["SELECT 'not right'"]
|
427
|
-
|
514
|
+
end.to raise_error(TypeError)
|
428
515
|
end
|
429
516
|
|
430
517
|
it "should not retain query options set on a query for subsequent queries, but should retain it in the result" do
|
431
|
-
result = @client.query "SELECT 1", :
|
518
|
+
result = @client.query "SELECT 1", something: :else
|
432
519
|
expect(@client.query_options[:something]).to be_nil
|
433
|
-
expect(result.instance_variable_get('@query_options')).to eql(@client.query_options.merge(:
|
434
|
-
expect(@client.instance_variable_get('@current_query_options')).to eql(@client.query_options.merge(:
|
520
|
+
expect(result.instance_variable_get('@query_options')).to eql(@client.query_options.merge(something: :else))
|
521
|
+
expect(@client.instance_variable_get('@current_query_options')).to eql(@client.query_options.merge(something: :else))
|
435
522
|
|
436
523
|
result = @client.query "SELECT 1"
|
437
524
|
expect(result.instance_variable_get('@query_options')).to eql(@client.query_options)
|
@@ -439,7 +526,7 @@ RSpec.describe Mysql2::Client do
|
|
439
526
|
end
|
440
527
|
|
441
528
|
it "should allow changing query options for subsequent queries" do
|
442
|
-
@client.query_options
|
529
|
+
@client.query_options[:something] = :else
|
443
530
|
result = @client.query "SELECT 1"
|
444
531
|
expect(@client.query_options[:something]).to eql(:else)
|
445
532
|
expect(result.instance_variable_get('@query_options')[:something]).to eql(:else)
|
@@ -454,41 +541,60 @@ RSpec.describe Mysql2::Client do
|
|
454
541
|
end
|
455
542
|
|
456
543
|
it "should be able to return results as an array" do
|
457
|
-
expect(@client.query("SELECT 1", :
|
458
|
-
@client.query("SELECT 1").each(:
|
544
|
+
expect(@client.query("SELECT 1", as: :array).first).to be_an_instance_of(Array)
|
545
|
+
@client.query("SELECT 1").each(as: :array)
|
459
546
|
end
|
460
547
|
|
461
548
|
it "should be able to return results with symbolized keys" do
|
462
|
-
expect(@client.query("SELECT 1", :
|
549
|
+
expect(@client.query("SELECT 1", symbolize_keys: true).first.keys[0]).to be_an_instance_of(Symbol)
|
463
550
|
end
|
464
551
|
|
465
552
|
it "should require an open connection" do
|
466
553
|
@client.close
|
467
|
-
expect
|
554
|
+
expect do
|
468
555
|
@client.query "SELECT 1"
|
469
|
-
|
556
|
+
end.to raise_error(Mysql2::Error)
|
557
|
+
end
|
558
|
+
|
559
|
+
it "should detect closed connection on query read error" do
|
560
|
+
connection_id = @client.thread_id
|
561
|
+
Thread.new do
|
562
|
+
sleep(0.1)
|
563
|
+
Mysql2::Client.new(DatabaseCredentials['root']).tap do |supervisor|
|
564
|
+
supervisor.query("KILL #{connection_id}")
|
565
|
+
end.close
|
566
|
+
end
|
567
|
+
expect do
|
568
|
+
@client.query("SELECT SLEEP(1)")
|
569
|
+
end.to raise_error(Mysql2::Error, /Lost connection to MySQL server/)
|
570
|
+
|
571
|
+
if RUBY_PLATFORM !~ /mingw|mswin/
|
572
|
+
expect do
|
573
|
+
@client.socket
|
574
|
+
end.to raise_error(Mysql2::Error, 'MySQL client is not connected')
|
575
|
+
end
|
470
576
|
end
|
471
577
|
|
472
578
|
if RUBY_PLATFORM !~ /mingw|mswin/
|
473
579
|
it "should not allow another query to be sent without fetching a result first" do
|
474
|
-
@client.query("SELECT 1", :
|
475
|
-
expect
|
580
|
+
@client.query("SELECT 1", async: true)
|
581
|
+
expect do
|
476
582
|
@client.query("SELECT 1")
|
477
|
-
|
583
|
+
end.to raise_error(Mysql2::Error)
|
478
584
|
end
|
479
585
|
|
480
586
|
it "should describe the thread holding the active query" do
|
481
|
-
thr = Thread.new { @client.query("SELECT 1", :
|
587
|
+
thr = Thread.new { @client.query("SELECT 1", async: true) }
|
482
588
|
|
483
589
|
thr.join
|
484
590
|
expect { @client.query('SELECT 1') }.to raise_error(Mysql2::Error, Regexp.new(Regexp.escape(thr.inspect)))
|
485
591
|
end
|
486
592
|
|
487
593
|
it "should timeout if we wait longer than :read_timeout" do
|
488
|
-
client =
|
489
|
-
expect
|
594
|
+
client = new_client(read_timeout: 0)
|
595
|
+
expect do
|
490
596
|
client.query('SELECT SLEEP(0.1)')
|
491
|
-
|
597
|
+
end.to raise_error(Mysql2::Error::TimeoutError)
|
492
598
|
end
|
493
599
|
|
494
600
|
# XXX this test is not deterministic (because Unix signal handling is not)
|
@@ -522,31 +628,18 @@ RSpec.describe Mysql2::Client do
|
|
522
628
|
end
|
523
629
|
|
524
630
|
it "#socket should return a Fixnum (file descriptor from C)" do
|
525
|
-
expect(@client.socket).to be_an_instance_of(
|
631
|
+
expect(@client.socket).to be_an_instance_of(0.class)
|
526
632
|
expect(@client.socket).not_to eql(0)
|
527
633
|
end
|
528
634
|
|
529
635
|
it "#socket should require an open connection" do
|
530
636
|
@client.close
|
531
|
-
expect
|
637
|
+
expect do
|
532
638
|
@client.socket
|
533
|
-
|
534
|
-
end
|
535
|
-
|
536
|
-
it 'should be impervious to connection-corrupting timeouts in #query' do
|
537
|
-
pending('`Thread.handle_interrupt` is not defined') unless Thread.respond_to?(:handle_interrupt)
|
538
|
-
# attempt to break the connection
|
539
|
-
expect { Timeout.timeout(0.1) { @client.query('SELECT SLEEP(0.2)') } }.to raise_error(Timeout::Error)
|
540
|
-
|
541
|
-
# expect the connection to not be broken
|
542
|
-
expect { @client.query('SELECT 1') }.to_not raise_error
|
639
|
+
end.to raise_error(Mysql2::Error)
|
543
640
|
end
|
544
641
|
|
545
642
|
it 'should be impervious to connection-corrupting timeouts in #execute' do
|
546
|
-
# the statement handle gets corrupted and will segfault the tests if interrupted,
|
547
|
-
# so we can't even use pending on this test, really have to skip it on older Rubies.
|
548
|
-
skip('`Thread.handle_interrupt` is not defined') unless Thread.respond_to?(:handle_interrupt)
|
549
|
-
|
550
643
|
# attempt to break the connection
|
551
644
|
stmt = @client.prepare('SELECT SLEEP(?)')
|
552
645
|
expect { Timeout.timeout(0.1) { stmt.execute(0.2) } }.to raise_error(Timeout::Error)
|
@@ -559,26 +652,26 @@ RSpec.describe Mysql2::Client do
|
|
559
652
|
context 'when a non-standard exception class is raised' do
|
560
653
|
it "should close the connection when an exception is raised" do
|
561
654
|
expect { Timeout.timeout(0.1, ArgumentError) { @client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
|
562
|
-
expect { @client.query('SELECT 1') }.to raise_error(Mysql2::Error, '
|
655
|
+
expect { @client.query('SELECT 1') }.to raise_error(Mysql2::Error, 'MySQL client is not connected')
|
563
656
|
end
|
564
657
|
|
565
658
|
it "should handle Timeouts without leaving the connection hanging if reconnect is true" do
|
566
|
-
if RUBY_PLATFORM.include?('darwin') &&
|
567
|
-
pending('
|
659
|
+
if RUBY_PLATFORM.include?('darwin') && @client.server_info.fetch(:version).start_with?('5.5')
|
660
|
+
pending('MySQL 5.5 on OSX is afflicted by an unknown bug that breaks this test. See #633 and #634.')
|
568
661
|
end
|
569
662
|
|
570
|
-
client =
|
663
|
+
client = new_client(reconnect: true)
|
571
664
|
|
572
665
|
expect { Timeout.timeout(0.1, ArgumentError) { client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
|
573
666
|
expect { client.query('SELECT 1') }.to_not raise_error
|
574
667
|
end
|
575
668
|
|
576
669
|
it "should handle Timeouts without leaving the connection hanging if reconnect is set to true after construction" do
|
577
|
-
if RUBY_PLATFORM.include?('darwin') &&
|
578
|
-
pending('
|
670
|
+
if RUBY_PLATFORM.include?('darwin') && @client.server_info.fetch(:version).start_with?('5.5')
|
671
|
+
pending('MySQL 5.5 on OSX is afflicted by an unknown bug that breaks this test. See #633 and #634.')
|
579
672
|
end
|
580
673
|
|
581
|
-
client =
|
674
|
+
client = new_client
|
582
675
|
|
583
676
|
expect { Timeout.timeout(0.1, ArgumentError) { client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
|
584
677
|
expect { client.query('SELECT 1') }.to raise_error(Mysql2::Error)
|
@@ -594,10 +687,11 @@ RSpec.describe Mysql2::Client do
|
|
594
687
|
sleep_time = 0.5
|
595
688
|
|
596
689
|
# Note that each thread opens its own database connection
|
597
|
-
threads = 5
|
690
|
+
threads = Array.new(5) do
|
598
691
|
Thread.new do
|
599
|
-
|
600
|
-
|
692
|
+
new_client do |client|
|
693
|
+
client.query("SELECT SLEEP(#{sleep_time})")
|
694
|
+
end
|
601
695
|
Thread.current.object_id
|
602
696
|
end
|
603
697
|
end
|
@@ -611,17 +705,11 @@ RSpec.describe Mysql2::Client do
|
|
611
705
|
|
612
706
|
it "evented async queries should be supported" do
|
613
707
|
# should immediately return nil
|
614
|
-
expect(@client.query("SELECT sleep(0.1)", :
|
708
|
+
expect(@client.query("SELECT sleep(0.1)", async: true)).to eql(nil)
|
615
709
|
|
616
|
-
io_wrapper = IO.for_fd(@client.socket)
|
710
|
+
io_wrapper = IO.for_fd(@client.socket, autoclose: false)
|
617
711
|
loops = 0
|
618
|
-
|
619
|
-
if IO.select([io_wrapper], nil, nil, 0.05)
|
620
|
-
break
|
621
|
-
else
|
622
|
-
loops += 1
|
623
|
-
end
|
624
|
-
end
|
712
|
+
loops += 1 until IO.select([io_wrapper], nil, nil, 0.05)
|
625
713
|
|
626
714
|
# make sure we waited some period of time
|
627
715
|
expect(loops >= 1).to be true
|
@@ -633,15 +721,15 @@ RSpec.describe Mysql2::Client do
|
|
633
721
|
|
634
722
|
context "Multiple results sets" do
|
635
723
|
before(:each) do
|
636
|
-
@multi_client =
|
724
|
+
@multi_client = new_client(flags: Mysql2::Client::MULTI_STATEMENTS)
|
637
725
|
end
|
638
726
|
|
639
727
|
it "should raise an exception when one of multiple statements fails" do
|
640
728
|
result = @multi_client.query("SELECT 1 AS 'set_1'; SELECT * FROM invalid_table_name; SELECT 2 AS 'set_2';")
|
641
729
|
expect(result.first['set_1']).to be(1)
|
642
|
-
expect
|
730
|
+
expect do
|
643
731
|
@multi_client.next_result
|
644
|
-
|
732
|
+
end.to raise_error(Mysql2::Error)
|
645
733
|
expect(@multi_client.next_result).to be false
|
646
734
|
end
|
647
735
|
|
@@ -663,17 +751,17 @@ RSpec.describe Mysql2::Client do
|
|
663
751
|
|
664
752
|
it "will raise on query if there are outstanding results to read" do
|
665
753
|
@multi_client.query("SELECT 1; SELECT 2; SELECT 3")
|
666
|
-
expect
|
754
|
+
expect do
|
667
755
|
@multi_client.query("SELECT 4")
|
668
|
-
|
756
|
+
end.to raise_error(Mysql2::Error)
|
669
757
|
end
|
670
758
|
|
671
759
|
it "#abandon_results! should work" do
|
672
760
|
@multi_client.query("SELECT 1; SELECT 2; SELECT 3")
|
673
761
|
@multi_client.abandon_results!
|
674
|
-
expect
|
762
|
+
expect do
|
675
763
|
@multi_client.query("SELECT 4")
|
676
|
-
|
764
|
+
end.not_to raise_error
|
677
765
|
end
|
678
766
|
|
679
767
|
it "#more_results? should work" do
|
@@ -709,9 +797,9 @@ RSpec.describe Mysql2::Client do
|
|
709
797
|
|
710
798
|
if RUBY_PLATFORM =~ /mingw|mswin/
|
711
799
|
it "#socket should raise as it's not supported" do
|
712
|
-
expect
|
800
|
+
expect do
|
713
801
|
@client.socket
|
714
|
-
|
802
|
+
end.to raise_error(Mysql2::Error, /Raw access to the mysql file descriptor isn't supported on Windows/)
|
715
803
|
end
|
716
804
|
end
|
717
805
|
|
@@ -730,27 +818,25 @@ RSpec.describe Mysql2::Client do
|
|
730
818
|
end
|
731
819
|
|
732
820
|
it "should not overflow the thread stack" do
|
733
|
-
expect
|
821
|
+
expect do
|
734
822
|
Thread.new { Mysql2::Client.escape("'" * 256 * 1024) }.join
|
735
|
-
|
823
|
+
end.not_to raise_error
|
736
824
|
end
|
737
825
|
|
738
826
|
it "should not overflow the process stack" do
|
739
|
-
expect
|
827
|
+
expect do
|
740
828
|
Thread.new { Mysql2::Client.escape("'" * 1024 * 1024 * 4) }.join
|
741
|
-
|
829
|
+
end.not_to raise_error
|
742
830
|
end
|
743
831
|
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
expect(escaped.encoding).to eql(str.encoding)
|
832
|
+
it "should carry over the original string's encoding" do
|
833
|
+
str = "abc'def\"ghi\0jkl%mno"
|
834
|
+
escaped = Mysql2::Client.escape(str)
|
835
|
+
expect(escaped.encoding).to eql(str.encoding)
|
749
836
|
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
end
|
837
|
+
str.encode!('us-ascii')
|
838
|
+
escaped = Mysql2::Client.escape(str)
|
839
|
+
expect(escaped.encoding).to eql(str.encoding)
|
754
840
|
end
|
755
841
|
end
|
756
842
|
|
@@ -769,28 +855,26 @@ RSpec.describe Mysql2::Client do
|
|
769
855
|
end
|
770
856
|
|
771
857
|
it "should not overflow the thread stack" do
|
772
|
-
expect
|
858
|
+
expect do
|
773
859
|
Thread.new { @client.escape("'" * 256 * 1024) }.join
|
774
|
-
|
860
|
+
end.not_to raise_error
|
775
861
|
end
|
776
862
|
|
777
863
|
it "should not overflow the process stack" do
|
778
|
-
expect
|
864
|
+
expect do
|
779
865
|
Thread.new { @client.escape("'" * 1024 * 1024 * 4) }.join
|
780
|
-
|
866
|
+
end.not_to raise_error
|
781
867
|
end
|
782
868
|
|
783
869
|
it "should require an open connection" do
|
784
870
|
@client.close
|
785
|
-
expect
|
871
|
+
expect do
|
786
872
|
@client.escape ""
|
787
|
-
|
873
|
+
end.to raise_error(Mysql2::Error)
|
788
874
|
end
|
789
875
|
|
790
876
|
context 'when mysql encoding is not utf8' do
|
791
|
-
|
792
|
-
|
793
|
-
let(:client) { Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => "ujis")) }
|
877
|
+
let(:client) { new_client(encoding: "ujis") }
|
794
878
|
|
795
879
|
it 'should return a internal encoding string if Encoding.default_internal is set' do
|
796
880
|
with_internal_encoding Encoding::UTF_8 do
|
@@ -809,14 +893,12 @@ RSpec.describe Mysql2::Client do
|
|
809
893
|
info = @client.info
|
810
894
|
expect(info).to be_an_instance_of(Hash)
|
811
895
|
expect(info).to have_key(:id)
|
812
|
-
expect(info[:id]).to be_an_instance_of(
|
896
|
+
expect(info[:id]).to be_an_instance_of(0.class)
|
813
897
|
expect(info).to have_key(:version)
|
814
898
|
expect(info[:version]).to be_an_instance_of(String)
|
815
899
|
end
|
816
900
|
|
817
901
|
context "strings returned by #info" do
|
818
|
-
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
819
|
-
|
820
902
|
it "should be tagged as ascii" do
|
821
903
|
expect(@client.info[:version].encoding).to eql(Encoding::US_ASCII)
|
822
904
|
expect(@client.info[:header_version].encoding).to eql(Encoding::US_ASCII)
|
@@ -824,8 +906,6 @@ RSpec.describe Mysql2::Client do
|
|
824
906
|
end
|
825
907
|
|
826
908
|
context "strings returned by .info" do
|
827
|
-
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
828
|
-
|
829
909
|
it "should be tagged as ascii" do
|
830
910
|
expect(Mysql2::Client.info[:version].encoding).to eql(Encoding::US_ASCII)
|
831
911
|
expect(Mysql2::Client.info[:header_version].encoding).to eql(Encoding::US_ASCII)
|
@@ -840,26 +920,24 @@ RSpec.describe Mysql2::Client do
|
|
840
920
|
server_info = @client.server_info
|
841
921
|
expect(server_info).to be_an_instance_of(Hash)
|
842
922
|
expect(server_info).to have_key(:id)
|
843
|
-
expect(server_info[:id]).to be_an_instance_of(
|
923
|
+
expect(server_info[:id]).to be_an_instance_of(0.class)
|
844
924
|
expect(server_info).to have_key(:version)
|
845
925
|
expect(server_info[:version]).to be_an_instance_of(String)
|
846
926
|
end
|
847
927
|
|
848
928
|
it "#server_info should require an open connection" do
|
849
929
|
@client.close
|
850
|
-
expect
|
930
|
+
expect do
|
851
931
|
@client.server_info
|
852
|
-
|
932
|
+
end.to raise_error(Mysql2::Error)
|
853
933
|
end
|
854
934
|
|
855
935
|
context "strings returned by #server_info" do
|
856
|
-
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
857
|
-
|
858
936
|
it "should default to the connection's encoding if Encoding.default_internal is nil" do
|
859
937
|
with_internal_encoding nil do
|
860
938
|
expect(@client.server_info[:version].encoding).to eql(Encoding::UTF_8)
|
861
939
|
|
862
|
-
client2 =
|
940
|
+
client2 = new_client(encoding: 'ascii')
|
863
941
|
expect(client2.server_info[:version].encoding).to eql(Encoding::ASCII)
|
864
942
|
end
|
865
943
|
end
|
@@ -875,14 +953,14 @@ RSpec.describe Mysql2::Client do
|
|
875
953
|
end
|
876
954
|
end
|
877
955
|
|
878
|
-
it "should raise a Mysql2::Error exception upon connection failure" do
|
879
|
-
expect
|
880
|
-
|
881
|
-
|
956
|
+
it "should raise a Mysql2::Error::ConnectionError exception upon connection failure due to invalid credentials" do
|
957
|
+
expect do
|
958
|
+
new_client(host: 'localhost', username: 'asdfasdf8d2h', password: 'asdfasdfw42')
|
959
|
+
end.to raise_error(Mysql2::Error::ConnectionError)
|
882
960
|
|
883
|
-
expect
|
884
|
-
|
885
|
-
|
961
|
+
expect do
|
962
|
+
new_client(DatabaseCredentials['root'])
|
963
|
+
end.not_to raise_error
|
886
964
|
end
|
887
965
|
|
888
966
|
context 'write operations api' do
|
@@ -931,7 +1009,7 @@ RSpec.describe Mysql2::Client do
|
|
931
1009
|
end
|
932
1010
|
|
933
1011
|
it "#thread_id should be a Fixnum" do
|
934
|
-
expect(@client.thread_id).to be_an_instance_of(
|
1012
|
+
expect(@client.thread_id).to be_an_instance_of(0.class)
|
935
1013
|
end
|
936
1014
|
|
937
1015
|
it "should respond to #ping" do
|
@@ -967,9 +1045,9 @@ RSpec.describe Mysql2::Client do
|
|
967
1045
|
end
|
968
1046
|
|
969
1047
|
it "should raise a Mysql2::Error when the database doesn't exist" do
|
970
|
-
expect
|
1048
|
+
expect do
|
971
1049
|
@client.select_db("nopenothere")
|
972
|
-
|
1050
|
+
end.to raise_error(Mysql2::Error)
|
973
1051
|
end
|
974
1052
|
|
975
1053
|
it "should return the database switched to" do
|
@@ -983,9 +1061,12 @@ RSpec.describe Mysql2::Client do
|
|
983
1061
|
expect(@client.ping).to eql(false)
|
984
1062
|
end
|
985
1063
|
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
1064
|
+
it "should be able to connect using plaintext password" do
|
1065
|
+
client = new_client(enable_cleartext_plugin: true)
|
1066
|
+
client.query('SELECT 1')
|
1067
|
+
end
|
1068
|
+
|
1069
|
+
it "should respond to #encoding" do
|
1070
|
+
expect(@client).to respond_to(:encoding)
|
990
1071
|
end
|
991
1072
|
end
|