mysql2 0.4.2 → 0.5.2
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 +103 -59
- data/examples/eventmachine.rb +0 -2
- data/examples/threaded.rb +2 -4
- data/ext/mysql2/client.c +334 -94
- data/ext/mysql2/client.h +3 -51
- data/ext/mysql2/extconf.rb +45 -18
- data/ext/mysql2/mysql2_ext.c +2 -1
- data/ext/mysql2/mysql2_ext.h +8 -8
- data/ext/mysql2/mysql_enc_to_ruby.h +10 -0
- data/ext/mysql2/result.c +53 -94
- data/ext/mysql2/statement.c +191 -83
- 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 +372 -239
- data/spec/mysql2/error_spec.rb +4 -10
- data/spec/mysql2/result_spec.rb +132 -157
- data/spec/mysql2/statement_spec.rb +205 -177
- 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,4 +1,3 @@
|
|
1
|
-
# encoding: UTF-8
|
2
1
|
require 'spec_helper'
|
3
2
|
|
4
3
|
RSpec.describe Mysql2::Client do
|
@@ -6,41 +5,46 @@ RSpec.describe Mysql2::Client do
|
|
6
5
|
let(:cnf_file) { File.expand_path('../../my.cnf', __FILE__) }
|
7
6
|
|
8
7
|
it "should not raise an exception for valid defaults group" do
|
9
|
-
expect
|
10
|
-
|
11
|
-
|
12
|
-
}.not_to raise_error
|
8
|
+
expect do
|
9
|
+
new_client(default_file: cnf_file, default_group: "test")
|
10
|
+
end.not_to raise_error
|
13
11
|
end
|
14
12
|
|
15
13
|
it "should not raise an exception without default group" do
|
16
|
-
expect
|
17
|
-
|
18
|
-
|
14
|
+
expect do
|
15
|
+
new_client(default_file: cnf_file)
|
16
|
+
end.not_to raise_error
|
19
17
|
end
|
20
18
|
end
|
21
19
|
|
22
|
-
it "should raise
|
23
|
-
expect
|
20
|
+
it "should raise a Mysql::Error::ConnectionError upon connection failure" do
|
21
|
+
expect do
|
24
22
|
# The odd local host IP address forces the mysql client library to
|
25
23
|
# use a TCP socket rather than a domain socket.
|
26
|
-
|
27
|
-
|
24
|
+
new_client('host' => '127.0.0.2', 'port' => 999999)
|
25
|
+
end.to raise_error(Mysql2::Error::ConnectionError)
|
28
26
|
end
|
29
27
|
|
30
28
|
it "should raise an exception on create for invalid encodings" do
|
31
|
-
expect
|
32
|
-
|
33
|
-
|
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)
|
34
38
|
end
|
35
39
|
|
36
40
|
it "should not raise an exception on create for a valid encoding" do
|
37
|
-
expect
|
38
|
-
|
39
|
-
|
41
|
+
expect do
|
42
|
+
new_client(encoding: "utf8")
|
43
|
+
end.not_to raise_error
|
40
44
|
|
41
|
-
expect
|
42
|
-
|
43
|
-
|
45
|
+
expect do
|
46
|
+
new_client(DatabaseCredentials['root'].merge(encoding: "big5"))
|
47
|
+
end.not_to raise_error
|
44
48
|
end
|
45
49
|
|
46
50
|
Klient = Class.new(Mysql2::Client) do
|
@@ -52,18 +56,18 @@ RSpec.describe Mysql2::Client do
|
|
52
56
|
end
|
53
57
|
|
54
58
|
it "should accept connect flags and pass them to #connect" do
|
55
|
-
client = Klient.new :
|
59
|
+
client = Klient.new flags: Mysql2::Client::FOUND_ROWS
|
56
60
|
expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to be > 0
|
57
61
|
end
|
58
62
|
|
59
63
|
it "should parse flags array" do
|
60
|
-
client = Klient.new :
|
64
|
+
client = Klient.new flags: %w[FOUND_ROWS -PROTOCOL_41]
|
61
65
|
expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to eql(Mysql2::Client::FOUND_ROWS)
|
62
66
|
expect(client.connect_args.last[6] & Mysql2::Client::PROTOCOL_41).to eql(0)
|
63
67
|
end
|
64
68
|
|
65
69
|
it "should parse flags string" do
|
66
|
-
client = Klient.new :
|
70
|
+
client = Klient.new flags: "FOUND_ROWS -PROTOCOL_41"
|
67
71
|
expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to eql(Mysql2::Client::FOUND_ROWS)
|
68
72
|
expect(client.connect_args.last[6] & Mysql2::Client::PROTOCOL_41).to eql(0)
|
69
73
|
end
|
@@ -75,14 +79,15 @@ RSpec.describe Mysql2::Client do
|
|
75
79
|
Mysql2::Client::LONG_FLAG |
|
76
80
|
Mysql2::Client::TRANSACTIONS |
|
77
81
|
Mysql2::Client::PROTOCOL_41 |
|
78
|
-
Mysql2::Client::SECURE_CONNECTION
|
82
|
+
Mysql2::Client::SECURE_CONNECTION |
|
83
|
+
Mysql2::Client::CONNECT_ATTRS
|
79
84
|
expect(client.connect_args.last[6]).to eql(client_flags)
|
80
85
|
end
|
81
86
|
|
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')
|
@@ -130,33 +135,23 @@ RSpec.describe Mysql2::Client do
|
|
130
135
|
|
131
136
|
# You may need to adjust the lines below to match your SSL certificate paths
|
132
137
|
ssl_client = nil
|
133
|
-
expect
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
:sslcipher => 'DHE-RSA-AES256-SHA',
|
142
|
-
:sslverify => true
|
143
|
-
)
|
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,
|
144
146
|
)
|
145
|
-
|
146
|
-
}.not_to raise_error
|
147
|
-
|
148
|
-
results = ssl_client.query("SHOW STATUS WHERE Variable_name = \"Ssl_version\" OR Variable_name = \"Ssl_cipher\"").to_a
|
149
|
-
expect(results[0]['Variable_name']).to eql('Ssl_cipher')
|
150
|
-
expect(results[0]['Value']).not_to be_nil
|
151
|
-
expect(results[0]['Value']).to be_an_instance_of(String)
|
152
|
-
expect(results[0]['Value']).not_to be_empty
|
147
|
+
end.not_to raise_error
|
153
148
|
|
154
|
-
|
155
|
-
expect(results[
|
156
|
-
expect(results[
|
157
|
-
expect(results[1]['Value']).not_to be_empty
|
149
|
+
results = Hash[ssl_client.query('SHOW STATUS WHERE Variable_name LIKE "Ssl_%"').map { |x| x.values_at('Variable_name', 'Value') }]
|
150
|
+
expect(results['Ssl_cipher']).not_to be_empty
|
151
|
+
expect(results['Ssl_version']).not_to be_empty
|
158
152
|
|
159
|
-
ssl_client.
|
153
|
+
expect(ssl_client.ssl_cipher).not_to be_empty
|
154
|
+
expect(results['Ssl_cipher']).to eql(ssl_client.ssl_cipher)
|
160
155
|
end
|
161
156
|
|
162
157
|
def run_gc
|
@@ -169,61 +164,155 @@ RSpec.describe Mysql2::Client do
|
|
169
164
|
end
|
170
165
|
|
171
166
|
it "should terminate connections when calling close" do
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
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
|
176
184
|
}
|
185
|
+
# rubocop:enable Lint/AmbiguousBlockAssociation
|
177
186
|
end
|
178
187
|
|
179
188
|
it "should not leave dangling connections after garbage collection" do
|
180
189
|
run_gc
|
190
|
+
# rubocop:disable Lint/AmbiguousBlockAssociation
|
191
|
+
expect do
|
192
|
+
expect do
|
193
|
+
10.times do
|
194
|
+
Mysql2::Client.new(DatabaseCredentials['root']).query('SELECT 1')
|
195
|
+
end
|
196
|
+
end.to change {
|
197
|
+
@client.query("SHOW STATUS LIKE 'Threads_connected'").first['Value'].to_i
|
198
|
+
}.by(10)
|
181
199
|
|
182
|
-
|
183
|
-
|
200
|
+
run_gc
|
201
|
+
end.to_not change {
|
202
|
+
@client.query("SHOW STATUS LIKE 'Aborted_%'").to_a +
|
203
|
+
@client.query("SHOW STATUS LIKE 'Threads_connected'").to_a
|
204
|
+
}
|
205
|
+
# rubocop:enable Lint/AmbiguousBlockAssociation
|
206
|
+
end
|
184
207
|
|
185
|
-
|
186
|
-
|
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
|
187
213
|
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
214
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
end
|
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
|
195
218
|
|
196
|
-
|
197
|
-
|
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
|
198
222
|
|
199
|
-
|
200
|
-
|
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
|
201
226
|
|
202
|
-
|
203
|
-
|
204
|
-
fork {}
|
227
|
+
it 'enables multiple-statement' do
|
228
|
+
client.query("SELECT 1;SELECT 2;")
|
205
229
|
|
206
|
-
|
207
|
-
client.
|
208
|
-
client
|
209
|
-
|
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
|
240
|
+
end
|
241
|
+
|
242
|
+
context "#automatic_close" do
|
243
|
+
it "is enabled by default" do
|
244
|
+
expect(new_client.automatic_close?).to be(true)
|
210
245
|
end
|
211
246
|
|
212
|
-
|
247
|
+
if RUBY_PLATFORM =~ /mingw|mswin/
|
248
|
+
it "cannot be disabled" do
|
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)
|
261
|
+
client.automatic_close = false
|
262
|
+
expect(client.automatic_close?).to be(true)
|
263
|
+
end.to output(/always closed by garbage collector/).to_stderr
|
264
|
+
end
|
265
|
+
else
|
266
|
+
it "can be configured" do
|
267
|
+
client = new_client(automatic_close: false)
|
268
|
+
expect(client.automatic_close?).to be(false)
|
269
|
+
end
|
270
|
+
|
271
|
+
it "can be assigned" do
|
272
|
+
client = new_client
|
273
|
+
client.automatic_close = false
|
274
|
+
expect(client.automatic_close?).to be(false)
|
275
|
+
|
276
|
+
client.automatic_close = true
|
277
|
+
expect(client.automatic_close?).to be(true)
|
278
|
+
|
279
|
+
client.automatic_close = nil
|
280
|
+
expect(client.automatic_close?).to be(false)
|
281
|
+
|
282
|
+
client.automatic_close = 9
|
283
|
+
expect(client.automatic_close?).to be(true)
|
284
|
+
end
|
285
|
+
|
286
|
+
it "should not close connections when running in a child process" do
|
287
|
+
run_gc
|
288
|
+
client = Mysql2::Client.new(DatabaseCredentials['root'])
|
289
|
+
client.automatic_close = false
|
290
|
+
|
291
|
+
child = fork do
|
292
|
+
client.query('SELECT 1')
|
293
|
+
client = nil
|
294
|
+
run_gc
|
295
|
+
end
|
213
296
|
|
214
|
-
|
215
|
-
|
216
|
-
|
297
|
+
Process.wait(child)
|
298
|
+
|
299
|
+
# this will throw an error if the underlying socket was shutdown by the
|
300
|
+
# child's GC
|
301
|
+
expect { client.query('SELECT 1') }.to_not raise_exception
|
302
|
+
client.close
|
303
|
+
end
|
304
|
+
end
|
217
305
|
end
|
218
306
|
|
219
307
|
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']}`"
|
308
|
+
database = 1235
|
309
|
+
@client.query "CREATE DATABASE IF NOT EXISTS `#{database}`"
|
223
310
|
|
224
|
-
expect
|
311
|
+
expect do
|
312
|
+
new_client('database' => database)
|
313
|
+
end.not_to raise_error
|
225
314
|
|
226
|
-
@client.query "DROP DATABASE IF EXISTS `#{
|
315
|
+
@client.query "DROP DATABASE IF EXISTS `#{database}`"
|
227
316
|
end
|
228
317
|
|
229
318
|
it "should respond to #close" do
|
@@ -232,9 +321,28 @@ RSpec.describe Mysql2::Client do
|
|
232
321
|
|
233
322
|
it "should be able to close properly" do
|
234
323
|
expect(@client.close).to be_nil
|
235
|
-
expect
|
324
|
+
expect do
|
236
325
|
@client.query "SELECT 1"
|
237
|
-
|
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)
|
238
346
|
end
|
239
347
|
|
240
348
|
it "should respond to #query" do
|
@@ -255,8 +363,8 @@ RSpec.describe Mysql2::Client do
|
|
255
363
|
context "when has a warnings" do
|
256
364
|
it "should > 0" do
|
257
365
|
# "the statement produces extra information that can be viewed by issuing a SHOW WARNINGS"
|
258
|
-
#
|
259
|
-
@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')
|
260
368
|
expect(@client.warning_count).to be > 0
|
261
369
|
end
|
262
370
|
end
|
@@ -283,7 +391,7 @@ RSpec.describe Mysql2::Client do
|
|
283
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).
|
284
392
|
@client.query("INSERT INTO infoTest (blah) VALUES (1234),(4535)")
|
285
393
|
|
286
|
-
expect(@client.query_info).to eql(:
|
394
|
+
expect(@client.query_info).to eql(records: 2, duplicates: 0, warnings: 0)
|
287
395
|
expect(@client.query_info_string).to eq('Records: 2 Duplicates: 0 Warnings: 0')
|
288
396
|
|
289
397
|
@client.query "DROP TABLE infoTest"
|
@@ -293,93 +401,124 @@ RSpec.describe Mysql2::Client do
|
|
293
401
|
|
294
402
|
context ":local_infile" do
|
295
403
|
before(:all) do
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
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
|
308
417
|
end
|
309
418
|
|
310
419
|
after(:all) do
|
311
|
-
|
420
|
+
new_client do |client|
|
421
|
+
client.query "DROP TABLE IF EXISTS infileTest"
|
422
|
+
end
|
312
423
|
end
|
313
424
|
|
314
425
|
it "should raise an error when local_infile is disabled" do
|
315
|
-
client =
|
316
|
-
expect
|
426
|
+
client = new_client(local_infile: false)
|
427
|
+
expect do
|
317
428
|
client.query "LOAD DATA LOCAL INFILE 'spec/test_data' INTO TABLE infileTest"
|
318
|
-
|
429
|
+
end.to raise_error(Mysql2::Error, /command is not allowed/)
|
319
430
|
end
|
320
431
|
|
321
432
|
it "should raise an error when a non-existent file is loaded" do
|
322
|
-
|
323
|
-
|
324
|
-
|
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')
|
325
437
|
end
|
326
438
|
|
327
439
|
it "should LOAD DATA LOCAL INFILE" do
|
328
|
-
|
329
|
-
|
330
|
-
|
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)
|
331
444
|
|
332
|
-
result =
|
445
|
+
result = client.query "SELECT * FROM infileTest"
|
333
446
|
expect(result.first).to eql('id' => 1, 'foo' => 'Hello', 'bar' => 'World')
|
334
447
|
end
|
335
448
|
end
|
336
449
|
|
337
450
|
it "should expect connect_timeout to be a positive integer" do
|
338
|
-
expect
|
339
|
-
|
340
|
-
|
451
|
+
expect do
|
452
|
+
new_client(connect_timeout: -1)
|
453
|
+
end.to raise_error(Mysql2::Error)
|
341
454
|
end
|
342
455
|
|
343
456
|
it "should expect read_timeout to be a positive integer" do
|
344
|
-
expect
|
345
|
-
|
346
|
-
|
457
|
+
expect do
|
458
|
+
new_client(read_timeout: -1)
|
459
|
+
end.to raise_error(Mysql2::Error)
|
347
460
|
end
|
348
461
|
|
349
462
|
it "should expect write_timeout to be a positive integer" do
|
350
|
-
expect
|
351
|
-
|
352
|
-
|
463
|
+
expect do
|
464
|
+
new_client(write_timeout: -1)
|
465
|
+
end.to raise_error(Mysql2::Error)
|
466
|
+
end
|
467
|
+
|
468
|
+
it "should allow nil read_timeout" do
|
469
|
+
client = new_client(read_timeout: nil)
|
470
|
+
|
471
|
+
expect(client.read_timeout).to be_nil
|
472
|
+
end
|
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')
|
353
492
|
end
|
354
493
|
|
355
494
|
context "#query" do
|
356
495
|
it "should let you query again if iterating is finished when streaming" do
|
357
|
-
@client.query("SELECT 1 UNION SELECT 2", :
|
496
|
+
@client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false).each.to_a
|
358
497
|
|
359
|
-
expect
|
360
|
-
@client.query("SELECT 1 UNION SELECT 2", :
|
361
|
-
|
498
|
+
expect do
|
499
|
+
@client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false)
|
500
|
+
end.to_not raise_error
|
362
501
|
end
|
363
502
|
|
364
503
|
it "should not let you query again if iterating is not finished when streaming" do
|
365
|
-
@client.query("SELECT 1 UNION SELECT 2", :
|
504
|
+
@client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false).first
|
366
505
|
|
367
|
-
expect
|
368
|
-
@client.query("SELECT 1 UNION SELECT 2", :
|
369
|
-
|
506
|
+
expect do
|
507
|
+
@client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false)
|
508
|
+
end.to raise_exception(Mysql2::Error)
|
370
509
|
end
|
371
510
|
|
372
511
|
it "should only accept strings as the query parameter" do
|
373
|
-
expect
|
512
|
+
expect do
|
374
513
|
@client.query ["SELECT 'not right'"]
|
375
|
-
|
514
|
+
end.to raise_error(TypeError)
|
376
515
|
end
|
377
516
|
|
378
517
|
it "should not retain query options set on a query for subsequent queries, but should retain it in the result" do
|
379
|
-
result = @client.query "SELECT 1", :
|
518
|
+
result = @client.query "SELECT 1", something: :else
|
380
519
|
expect(@client.query_options[:something]).to be_nil
|
381
|
-
expect(result.instance_variable_get('@query_options')).to eql(@client.query_options.merge(:
|
382
|
-
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))
|
383
522
|
|
384
523
|
result = @client.query "SELECT 1"
|
385
524
|
expect(result.instance_variable_get('@query_options')).to eql(@client.query_options)
|
@@ -387,7 +526,7 @@ RSpec.describe Mysql2::Client do
|
|
387
526
|
end
|
388
527
|
|
389
528
|
it "should allow changing query options for subsequent queries" do
|
390
|
-
@client.query_options
|
529
|
+
@client.query_options[:something] = :else
|
391
530
|
result = @client.query "SELECT 1"
|
392
531
|
expect(@client.query_options[:something]).to eql(:else)
|
393
532
|
expect(result.instance_variable_get('@query_options')[:something]).to eql(:else)
|
@@ -402,41 +541,60 @@ RSpec.describe Mysql2::Client do
|
|
402
541
|
end
|
403
542
|
|
404
543
|
it "should be able to return results as an array" do
|
405
|
-
expect(@client.query("SELECT 1", :
|
406
|
-
@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)
|
407
546
|
end
|
408
547
|
|
409
548
|
it "should be able to return results with symbolized keys" do
|
410
|
-
expect(@client.query("SELECT 1", :
|
549
|
+
expect(@client.query("SELECT 1", symbolize_keys: true).first.keys[0]).to be_an_instance_of(Symbol)
|
411
550
|
end
|
412
551
|
|
413
552
|
it "should require an open connection" do
|
414
553
|
@client.close
|
415
|
-
expect
|
554
|
+
expect do
|
416
555
|
@client.query "SELECT 1"
|
417
|
-
|
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
|
418
576
|
end
|
419
577
|
|
420
578
|
if RUBY_PLATFORM !~ /mingw|mswin/
|
421
579
|
it "should not allow another query to be sent without fetching a result first" do
|
422
|
-
@client.query("SELECT 1", :
|
423
|
-
expect
|
580
|
+
@client.query("SELECT 1", async: true)
|
581
|
+
expect do
|
424
582
|
@client.query("SELECT 1")
|
425
|
-
|
583
|
+
end.to raise_error(Mysql2::Error)
|
426
584
|
end
|
427
585
|
|
428
586
|
it "should describe the thread holding the active query" do
|
429
|
-
thr = Thread.new { @client.query("SELECT 1", :
|
587
|
+
thr = Thread.new { @client.query("SELECT 1", async: true) }
|
430
588
|
|
431
589
|
thr.join
|
432
590
|
expect { @client.query('SELECT 1') }.to raise_error(Mysql2::Error, Regexp.new(Regexp.escape(thr.inspect)))
|
433
591
|
end
|
434
592
|
|
435
593
|
it "should timeout if we wait longer than :read_timeout" do
|
436
|
-
client =
|
437
|
-
expect
|
594
|
+
client = new_client(read_timeout: 0)
|
595
|
+
expect do
|
438
596
|
client.query('SELECT SLEEP(0.1)')
|
439
|
-
|
597
|
+
end.to raise_error(Mysql2::Error::TimeoutError)
|
440
598
|
end
|
441
599
|
|
442
600
|
# XXX this test is not deterministic (because Unix signal handling is not)
|
@@ -470,31 +628,18 @@ RSpec.describe Mysql2::Client do
|
|
470
628
|
end
|
471
629
|
|
472
630
|
it "#socket should return a Fixnum (file descriptor from C)" do
|
473
|
-
expect(@client.socket).to be_an_instance_of(
|
631
|
+
expect(@client.socket).to be_an_instance_of(0.class)
|
474
632
|
expect(@client.socket).not_to eql(0)
|
475
633
|
end
|
476
634
|
|
477
635
|
it "#socket should require an open connection" do
|
478
636
|
@client.close
|
479
|
-
expect
|
637
|
+
expect do
|
480
638
|
@client.socket
|
481
|
-
|
482
|
-
end
|
483
|
-
|
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
|
639
|
+
end.to raise_error(Mysql2::Error)
|
491
640
|
end
|
492
641
|
|
493
642
|
it 'should be impervious to connection-corrupting timeouts in #execute' do
|
494
|
-
# the statement handle gets corrupted and will segfault the tests if interrupted,
|
495
|
-
# so we can't even use pending on this test, really have to skip it on older Rubies.
|
496
|
-
skip('`Thread.handle_interrupt` is not defined') unless Thread.respond_to?(:handle_interrupt)
|
497
|
-
|
498
643
|
# attempt to break the connection
|
499
644
|
stmt = @client.prepare('SELECT SLEEP(?)')
|
500
645
|
expect { Timeout.timeout(0.1) { stmt.execute(0.2) } }.to raise_error(Timeout::Error)
|
@@ -507,26 +652,26 @@ RSpec.describe Mysql2::Client do
|
|
507
652
|
context 'when a non-standard exception class is raised' do
|
508
653
|
it "should close the connection when an exception is raised" do
|
509
654
|
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, '
|
655
|
+
expect { @client.query('SELECT 1') }.to raise_error(Mysql2::Error, 'MySQL client is not connected')
|
511
656
|
end
|
512
657
|
|
513
658
|
it "should handle Timeouts without leaving the connection hanging if reconnect is true" do
|
514
|
-
if RUBY_PLATFORM.include?('darwin') &&
|
515
|
-
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.')
|
516
661
|
end
|
517
662
|
|
518
|
-
client =
|
663
|
+
client = new_client(reconnect: true)
|
519
664
|
|
520
665
|
expect { Timeout.timeout(0.1, ArgumentError) { client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
|
521
666
|
expect { client.query('SELECT 1') }.to_not raise_error
|
522
667
|
end
|
523
668
|
|
524
669
|
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('
|
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.')
|
527
672
|
end
|
528
673
|
|
529
|
-
client =
|
674
|
+
client = new_client
|
530
675
|
|
531
676
|
expect { Timeout.timeout(0.1, ArgumentError) { client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
|
532
677
|
expect { client.query('SELECT 1') }.to raise_error(Mysql2::Error)
|
@@ -542,10 +687,11 @@ RSpec.describe Mysql2::Client do
|
|
542
687
|
sleep_time = 0.5
|
543
688
|
|
544
689
|
# Note that each thread opens its own database connection
|
545
|
-
threads = 5
|
690
|
+
threads = Array.new(5) do
|
546
691
|
Thread.new do
|
547
|
-
|
548
|
-
|
692
|
+
new_client do |client|
|
693
|
+
client.query("SELECT SLEEP(#{sleep_time})")
|
694
|
+
end
|
549
695
|
Thread.current.object_id
|
550
696
|
end
|
551
697
|
end
|
@@ -559,17 +705,11 @@ RSpec.describe Mysql2::Client do
|
|
559
705
|
|
560
706
|
it "evented async queries should be supported" do
|
561
707
|
# should immediately return nil
|
562
|
-
expect(@client.query("SELECT sleep(0.1)", :
|
708
|
+
expect(@client.query("SELECT sleep(0.1)", async: true)).to eql(nil)
|
563
709
|
|
564
|
-
io_wrapper = IO.for_fd(@client.socket)
|
710
|
+
io_wrapper = IO.for_fd(@client.socket, autoclose: false)
|
565
711
|
loops = 0
|
566
|
-
|
567
|
-
if IO.select([io_wrapper], nil, nil, 0.05)
|
568
|
-
break
|
569
|
-
else
|
570
|
-
loops += 1
|
571
|
-
end
|
572
|
-
end
|
712
|
+
loops += 1 until IO.select([io_wrapper], nil, nil, 0.05)
|
573
713
|
|
574
714
|
# make sure we waited some period of time
|
575
715
|
expect(loops >= 1).to be true
|
@@ -581,15 +721,15 @@ RSpec.describe Mysql2::Client do
|
|
581
721
|
|
582
722
|
context "Multiple results sets" do
|
583
723
|
before(:each) do
|
584
|
-
@multi_client =
|
724
|
+
@multi_client = new_client(flags: Mysql2::Client::MULTI_STATEMENTS)
|
585
725
|
end
|
586
726
|
|
587
727
|
it "should raise an exception when one of multiple statements fails" do
|
588
728
|
result = @multi_client.query("SELECT 1 AS 'set_1'; SELECT * FROM invalid_table_name; SELECT 2 AS 'set_2';")
|
589
729
|
expect(result.first['set_1']).to be(1)
|
590
|
-
expect
|
730
|
+
expect do
|
591
731
|
@multi_client.next_result
|
592
|
-
|
732
|
+
end.to raise_error(Mysql2::Error)
|
593
733
|
expect(@multi_client.next_result).to be false
|
594
734
|
end
|
595
735
|
|
@@ -611,17 +751,17 @@ RSpec.describe Mysql2::Client do
|
|
611
751
|
|
612
752
|
it "will raise on query if there are outstanding results to read" do
|
613
753
|
@multi_client.query("SELECT 1; SELECT 2; SELECT 3")
|
614
|
-
expect
|
754
|
+
expect do
|
615
755
|
@multi_client.query("SELECT 4")
|
616
|
-
|
756
|
+
end.to raise_error(Mysql2::Error)
|
617
757
|
end
|
618
758
|
|
619
759
|
it "#abandon_results! should work" do
|
620
760
|
@multi_client.query("SELECT 1; SELECT 2; SELECT 3")
|
621
761
|
@multi_client.abandon_results!
|
622
|
-
expect
|
762
|
+
expect do
|
623
763
|
@multi_client.query("SELECT 4")
|
624
|
-
|
764
|
+
end.not_to raise_error
|
625
765
|
end
|
626
766
|
|
627
767
|
it "#more_results? should work" do
|
@@ -657,9 +797,9 @@ RSpec.describe Mysql2::Client do
|
|
657
797
|
|
658
798
|
if RUBY_PLATFORM =~ /mingw|mswin/
|
659
799
|
it "#socket should raise as it's not supported" do
|
660
|
-
expect
|
800
|
+
expect do
|
661
801
|
@client.socket
|
662
|
-
|
802
|
+
end.to raise_error(Mysql2::Error, /Raw access to the mysql file descriptor isn't supported on Windows/)
|
663
803
|
end
|
664
804
|
end
|
665
805
|
|
@@ -678,27 +818,25 @@ RSpec.describe Mysql2::Client do
|
|
678
818
|
end
|
679
819
|
|
680
820
|
it "should not overflow the thread stack" do
|
681
|
-
expect
|
821
|
+
expect do
|
682
822
|
Thread.new { Mysql2::Client.escape("'" * 256 * 1024) }.join
|
683
|
-
|
823
|
+
end.not_to raise_error
|
684
824
|
end
|
685
825
|
|
686
826
|
it "should not overflow the process stack" do
|
687
|
-
expect
|
827
|
+
expect do
|
688
828
|
Thread.new { Mysql2::Client.escape("'" * 1024 * 1024 * 4) }.join
|
689
|
-
|
829
|
+
end.not_to raise_error
|
690
830
|
end
|
691
831
|
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
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)
|
697
836
|
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
end
|
837
|
+
str.encode!('us-ascii')
|
838
|
+
escaped = Mysql2::Client.escape(str)
|
839
|
+
expect(escaped.encoding).to eql(str.encoding)
|
702
840
|
end
|
703
841
|
end
|
704
842
|
|
@@ -717,28 +855,26 @@ RSpec.describe Mysql2::Client do
|
|
717
855
|
end
|
718
856
|
|
719
857
|
it "should not overflow the thread stack" do
|
720
|
-
expect
|
858
|
+
expect do
|
721
859
|
Thread.new { @client.escape("'" * 256 * 1024) }.join
|
722
|
-
|
860
|
+
end.not_to raise_error
|
723
861
|
end
|
724
862
|
|
725
863
|
it "should not overflow the process stack" do
|
726
|
-
expect
|
864
|
+
expect do
|
727
865
|
Thread.new { @client.escape("'" * 1024 * 1024 * 4) }.join
|
728
|
-
|
866
|
+
end.not_to raise_error
|
729
867
|
end
|
730
868
|
|
731
869
|
it "should require an open connection" do
|
732
870
|
@client.close
|
733
|
-
expect
|
871
|
+
expect do
|
734
872
|
@client.escape ""
|
735
|
-
|
873
|
+
end.to raise_error(Mysql2::Error)
|
736
874
|
end
|
737
875
|
|
738
876
|
context 'when mysql encoding is not utf8' do
|
739
|
-
|
740
|
-
|
741
|
-
let(:client) { Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => "ujis")) }
|
877
|
+
let(:client) { new_client(encoding: "ujis") }
|
742
878
|
|
743
879
|
it 'should return a internal encoding string if Encoding.default_internal is set' do
|
744
880
|
with_internal_encoding Encoding::UTF_8 do
|
@@ -757,14 +893,12 @@ RSpec.describe Mysql2::Client do
|
|
757
893
|
info = @client.info
|
758
894
|
expect(info).to be_an_instance_of(Hash)
|
759
895
|
expect(info).to have_key(:id)
|
760
|
-
expect(info[:id]).to be_an_instance_of(
|
896
|
+
expect(info[:id]).to be_an_instance_of(0.class)
|
761
897
|
expect(info).to have_key(:version)
|
762
898
|
expect(info[:version]).to be_an_instance_of(String)
|
763
899
|
end
|
764
900
|
|
765
901
|
context "strings returned by #info" do
|
766
|
-
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
767
|
-
|
768
902
|
it "should be tagged as ascii" do
|
769
903
|
expect(@client.info[:version].encoding).to eql(Encoding::US_ASCII)
|
770
904
|
expect(@client.info[:header_version].encoding).to eql(Encoding::US_ASCII)
|
@@ -772,8 +906,6 @@ RSpec.describe Mysql2::Client do
|
|
772
906
|
end
|
773
907
|
|
774
908
|
context "strings returned by .info" do
|
775
|
-
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
776
|
-
|
777
909
|
it "should be tagged as ascii" do
|
778
910
|
expect(Mysql2::Client.info[:version].encoding).to eql(Encoding::US_ASCII)
|
779
911
|
expect(Mysql2::Client.info[:header_version].encoding).to eql(Encoding::US_ASCII)
|
@@ -788,26 +920,24 @@ RSpec.describe Mysql2::Client do
|
|
788
920
|
server_info = @client.server_info
|
789
921
|
expect(server_info).to be_an_instance_of(Hash)
|
790
922
|
expect(server_info).to have_key(:id)
|
791
|
-
expect(server_info[:id]).to be_an_instance_of(
|
923
|
+
expect(server_info[:id]).to be_an_instance_of(0.class)
|
792
924
|
expect(server_info).to have_key(:version)
|
793
925
|
expect(server_info[:version]).to be_an_instance_of(String)
|
794
926
|
end
|
795
927
|
|
796
928
|
it "#server_info should require an open connection" do
|
797
929
|
@client.close
|
798
|
-
expect
|
930
|
+
expect do
|
799
931
|
@client.server_info
|
800
|
-
|
932
|
+
end.to raise_error(Mysql2::Error)
|
801
933
|
end
|
802
934
|
|
803
935
|
context "strings returned by #server_info" do
|
804
|
-
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
805
|
-
|
806
936
|
it "should default to the connection's encoding if Encoding.default_internal is nil" do
|
807
937
|
with_internal_encoding nil do
|
808
938
|
expect(@client.server_info[:version].encoding).to eql(Encoding::UTF_8)
|
809
939
|
|
810
|
-
client2 =
|
940
|
+
client2 = new_client(encoding: 'ascii')
|
811
941
|
expect(client2.server_info[:version].encoding).to eql(Encoding::ASCII)
|
812
942
|
end
|
813
943
|
end
|
@@ -823,14 +953,14 @@ RSpec.describe Mysql2::Client do
|
|
823
953
|
end
|
824
954
|
end
|
825
955
|
|
826
|
-
it "should raise a Mysql2::Error exception upon connection failure" do
|
827
|
-
expect
|
828
|
-
|
829
|
-
|
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)
|
830
960
|
|
831
|
-
expect
|
832
|
-
|
833
|
-
|
961
|
+
expect do
|
962
|
+
new_client(DatabaseCredentials['root'])
|
963
|
+
end.not_to raise_error
|
834
964
|
end
|
835
965
|
|
836
966
|
context 'write operations api' do
|
@@ -879,7 +1009,7 @@ RSpec.describe Mysql2::Client do
|
|
879
1009
|
end
|
880
1010
|
|
881
1011
|
it "#thread_id should be a Fixnum" do
|
882
|
-
expect(@client.thread_id).to be_an_instance_of(
|
1012
|
+
expect(@client.thread_id).to be_an_instance_of(0.class)
|
883
1013
|
end
|
884
1014
|
|
885
1015
|
it "should respond to #ping" do
|
@@ -915,9 +1045,9 @@ RSpec.describe Mysql2::Client do
|
|
915
1045
|
end
|
916
1046
|
|
917
1047
|
it "should raise a Mysql2::Error when the database doesn't exist" do
|
918
|
-
expect
|
1048
|
+
expect do
|
919
1049
|
@client.select_db("nopenothere")
|
920
|
-
|
1050
|
+
end.to raise_error(Mysql2::Error)
|
921
1051
|
end
|
922
1052
|
|
923
1053
|
it "should return the database switched to" do
|
@@ -931,9 +1061,12 @@ RSpec.describe Mysql2::Client do
|
|
931
1061
|
expect(@client.ping).to eql(false)
|
932
1062
|
end
|
933
1063
|
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
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)
|
938
1071
|
end
|
939
1072
|
end
|