mysql2 0.5.2-x64-mingw32 → 0.5.3-x64-mingw32

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +44 -28
  3. data/ext/mysql2/client.c +25 -8
  4. data/ext/mysql2/extconf.rb +1 -1
  5. data/ext/mysql2/mysql_enc_name_to_ruby.h +60 -56
  6. data/ext/mysql2/mysql_enc_to_ruby.h +56 -5
  7. data/ext/mysql2/result.c +17 -11
  8. data/ext/mysql2/statement.c +4 -2
  9. data/lib/mysql2.rb +6 -3
  10. data/lib/mysql2/2.2/mysql2.so +0 -0
  11. data/lib/mysql2/2.3/mysql2.so +0 -0
  12. data/lib/mysql2/2.4/mysql2.so +0 -0
  13. data/lib/mysql2/2.5/mysql2.so +0 -0
  14. data/lib/mysql2/2.6/mysql2.so +0 -0
  15. data/lib/mysql2/client.rb +1 -1
  16. data/lib/mysql2/error.rb +3 -3
  17. data/lib/mysql2/version.rb +1 -1
  18. data/support/5072E1F5.asc +5 -5
  19. data/support/mysql_enc_to_ruby.rb +6 -1
  20. data/support/ruby_enc_to_mysql.rb +2 -0
  21. metadata +7 -58
  22. data/examples/eventmachine.rb +0 -19
  23. data/examples/threaded.rb +0 -16
  24. data/lib/mysql2/2.0/mysql2.so +0 -0
  25. data/lib/mysql2/2.1/mysql2.so +0 -0
  26. data/spec/configuration.yml.example +0 -11
  27. data/spec/em/em_spec.rb +0 -135
  28. data/spec/my.cnf.example +0 -9
  29. data/spec/mysql2/client_spec.rb +0 -1072
  30. data/spec/mysql2/error_spec.rb +0 -78
  31. data/spec/mysql2/result_spec.rb +0 -485
  32. data/spec/mysql2/statement_spec.rb +0 -712
  33. data/spec/rcov.opts +0 -3
  34. data/spec/spec_helper.rb +0 -112
  35. data/spec/ssl/ca-cert.pem +0 -17
  36. data/spec/ssl/ca-key.pem +0 -27
  37. data/spec/ssl/ca.cnf +0 -22
  38. data/spec/ssl/cert.cnf +0 -22
  39. data/spec/ssl/client-cert.pem +0 -17
  40. data/spec/ssl/client-key.pem +0 -27
  41. data/spec/ssl/client-req.pem +0 -15
  42. data/spec/ssl/gen_certs.sh +0 -48
  43. data/spec/ssl/pkcs8-client-key.pem +0 -28
  44. data/spec/ssl/pkcs8-server-key.pem +0 -28
  45. data/spec/ssl/server-cert.pem +0 -17
  46. data/spec/ssl/server-key.pem +0 -27
  47. data/spec/ssl/server-req.pem +0 -15
  48. data/spec/test_data +0 -1
@@ -1,19 +0,0 @@
1
- $LOAD_PATH.unshift 'lib'
2
-
3
- require 'rubygems'
4
- require 'eventmachine'
5
- require 'mysql2/em'
6
-
7
- EM.run do
8
- client1 = Mysql2::EM::Client.new
9
- defer1 = client1.query "SELECT sleep(3) as first_query"
10
- defer1.callback do |result|
11
- puts "Result: #{result.to_a.inspect}"
12
- end
13
-
14
- client2 = Mysql2::EM::Client.new
15
- defer2 = client2.query "SELECT sleep(1) second_query"
16
- defer2.callback do |result|
17
- puts "Result: #{result.to_a.inspect}"
18
- end
19
- end
@@ -1,16 +0,0 @@
1
- $LOAD_PATH.unshift 'lib'
2
- require 'mysql2'
3
- require 'timeout'
4
-
5
- # Should never exceed worst case 3.5 secs across all 20 threads
6
- Timeout.timeout(3.5) do
7
- Array.new(20) do
8
- Thread.new do
9
- overhead = rand(3)
10
- puts ">> thread #{Thread.current.object_id} query, #{overhead} sec overhead"
11
- # 3 second overhead per query
12
- Mysql2::Client.new(host: "localhost", username: "root").query("SELECT sleep(#{overhead}) as result")
13
- puts "<< thread #{Thread.current.object_id} result, #{overhead} sec overhead"
14
- end
15
- end.each(&:join)
16
- end
Binary file
Binary file
@@ -1,11 +0,0 @@
1
- root:
2
- host: localhost
3
- username: root
4
- password:
5
- database: test
6
-
7
- user:
8
- host: localhost
9
- username: LOCALUSERNAME
10
- password:
11
- database: mysql2_test
@@ -1,135 +0,0 @@
1
- require 'spec_helper'
2
- begin
3
- require 'eventmachine'
4
- require 'mysql2/em'
5
-
6
- RSpec.describe Mysql2::EM::Client do
7
- it "should support async queries" do
8
- results = []
9
- EM.run do
10
- client1 = Mysql2::EM::Client.new DatabaseCredentials['root']
11
- defer1 = client1.query "SELECT sleep(0.1) as first_query"
12
- defer1.callback do |result|
13
- results << result.first
14
- client1.close
15
- EM.stop_event_loop
16
- end
17
-
18
- client2 = Mysql2::EM::Client.new DatabaseCredentials['root']
19
- defer2 = client2.query "SELECT sleep(0.025) second_query"
20
- defer2.callback do |result|
21
- results << result.first
22
- client2.close
23
- end
24
- end
25
-
26
- expect(results[0].keys).to include("second_query")
27
- expect(results[1].keys).to include("first_query")
28
- end
29
-
30
- it "should support queries in callbacks" do
31
- results = []
32
- EM.run do
33
- client = Mysql2::EM::Client.new DatabaseCredentials['root']
34
- defer1 = client.query "SELECT sleep(0.025) as first_query"
35
- defer1.callback do |result|
36
- results << result.first
37
- defer2 = client.query "SELECT sleep(0.025) as second_query"
38
- defer2.callback do |r|
39
- results << r.first
40
- client.close
41
- EM.stop_event_loop
42
- end
43
- end
44
- end
45
-
46
- expect(results[0].keys).to include("first_query")
47
- expect(results[1].keys).to include("second_query")
48
- end
49
-
50
- it "should not swallow exceptions raised in callbacks" do
51
- expect do
52
- EM.run do
53
- client = Mysql2::EM::Client.new DatabaseCredentials['root']
54
- defer = client.query "SELECT sleep(0.1) as first_query"
55
- defer.callback do
56
- client.close
57
- raise 'some error'
58
- end
59
- defer.errback do
60
- # This _shouldn't_ be run, but it needed to prevent the specs from
61
- # freezing if this test fails.
62
- EM.stop_event_loop
63
- end
64
- end
65
- end.to raise_error('some error')
66
- end
67
-
68
- context 'when an exception is raised by the client' do
69
- let(:client) { Mysql2::EM::Client.new DatabaseCredentials['root'] }
70
- let(:error) { StandardError.new('some error') }
71
- before { allow(client).to receive(:async_result).and_raise(error) }
72
- after { client.close }
73
-
74
- it "should swallow exceptions raised in by the client" do
75
- errors = []
76
- EM.run do
77
- defer = client.query "SELECT sleep(0.1) as first_query"
78
- defer.callback do
79
- # This _shouldn't_ be run, but it is needed to prevent the specs from
80
- # freezing if this test fails.
81
- EM.stop_event_loop
82
- end
83
- defer.errback do |err|
84
- errors << err
85
- EM.stop_event_loop
86
- end
87
- end
88
- expect(errors).to eq([error])
89
- end
90
-
91
- it "should fail the deferrable" do
92
- callbacks_run = []
93
- EM.run do
94
- defer = client.query "SELECT sleep(0.025) as first_query"
95
- EM.add_timer(0.1) do
96
- defer.callback do
97
- callbacks_run << :callback
98
- # This _shouldn't_ be run, but it is needed to prevent the specs from
99
- # freezing if this test fails.
100
- EM.stop_event_loop
101
- end
102
- defer.errback do
103
- callbacks_run << :errback
104
- EM.stop_event_loop
105
- end
106
- end
107
- end
108
- expect(callbacks_run).to eq([:errback])
109
- end
110
- end
111
-
112
- it "should not raise error when closing client with no query running" do
113
- callbacks_run = []
114
- EM.run do
115
- client = Mysql2::EM::Client.new DatabaseCredentials['root']
116
- defer = client.query("select sleep(0.025)")
117
- defer.callback do
118
- callbacks_run << :callback
119
- end
120
- defer.errback do
121
- callbacks_run << :errback
122
- end
123
- EM.add_timer(0.1) do
124
- expect(callbacks_run).to eq([:callback])
125
- expect do
126
- client.close
127
- end.not_to raise_error
128
- EM.stop_event_loop
129
- end
130
- end
131
- end
132
- end
133
- rescue LoadError
134
- puts "EventMachine not installed, skipping the specs that use it"
135
- end
@@ -1,9 +0,0 @@
1
- [root]
2
- host=localhost
3
- user=LOCALUSERNAME
4
- password=
5
-
6
- [client]
7
- host=localhost
8
- user=LOCALUSERNAME
9
- password=
@@ -1,1072 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe Mysql2::Client do
4
- context "using defaults file" do
5
- let(:cnf_file) { File.expand_path('../../my.cnf', __FILE__) }
6
-
7
- it "should not raise an exception for valid defaults group" do
8
- expect do
9
- new_client(default_file: cnf_file, default_group: "test")
10
- end.not_to raise_error
11
- end
12
-
13
- it "should not raise an exception without default group" do
14
- expect do
15
- new_client(default_file: cnf_file)
16
- end.not_to raise_error
17
- end
18
- end
19
-
20
- it "should raise a Mysql::Error::ConnectionError upon connection failure" do
21
- expect do
22
- # The odd local host IP address forces the mysql client library to
23
- # use a TCP socket rather than a domain socket.
24
- new_client('host' => '127.0.0.2', 'port' => 999999)
25
- end.to raise_error(Mysql2::Error::ConnectionError)
26
- end
27
-
28
- it "should raise an exception on create for invalid encodings" do
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)
38
- end
39
-
40
- it "should not raise an exception on create for a valid encoding" do
41
- expect do
42
- new_client(encoding: "utf8")
43
- end.not_to raise_error
44
-
45
- expect do
46
- new_client(DatabaseCredentials['root'].merge(encoding: "big5"))
47
- end.not_to raise_error
48
- end
49
-
50
- Klient = Class.new(Mysql2::Client) do
51
- attr_reader :connect_args
52
- def connect(*args)
53
- @connect_args ||= []
54
- @connect_args << args
55
- end
56
- end
57
-
58
- it "should accept connect flags and pass them to #connect" do
59
- client = Klient.new flags: Mysql2::Client::FOUND_ROWS
60
- expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to be > 0
61
- end
62
-
63
- it "should parse flags array" do
64
- client = Klient.new flags: %w[FOUND_ROWS -PROTOCOL_41]
65
- expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to eql(Mysql2::Client::FOUND_ROWS)
66
- expect(client.connect_args.last[6] & Mysql2::Client::PROTOCOL_41).to eql(0)
67
- end
68
-
69
- it "should parse flags string" do
70
- client = Klient.new flags: "FOUND_ROWS -PROTOCOL_41"
71
- expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to eql(Mysql2::Client::FOUND_ROWS)
72
- expect(client.connect_args.last[6] & Mysql2::Client::PROTOCOL_41).to eql(0)
73
- end
74
-
75
- it "should default flags to (REMEMBER_OPTIONS, LONG_PASSWORD, LONG_FLAG, TRANSACTIONS, PROTOCOL_41, SECURE_CONNECTION)" do
76
- client = Klient.new
77
- client_flags = Mysql2::Client::REMEMBER_OPTIONS |
78
- Mysql2::Client::LONG_PASSWORD |
79
- Mysql2::Client::LONG_FLAG |
80
- Mysql2::Client::TRANSACTIONS |
81
- Mysql2::Client::PROTOCOL_41 |
82
- Mysql2::Client::SECURE_CONNECTION |
83
- Mysql2::Client::CONNECT_ATTRS
84
- expect(client.connect_args.last[6]).to eql(client_flags)
85
- end
86
-
87
- it "should execute init command" do
88
- options = DatabaseCredentials['root'].dup
89
- options[:init_command] = "SET @something = 'setting_value';"
90
- client = new_client(options)
91
- result = client.query("SELECT @something;")
92
- expect(result.first['@something']).to eq('setting_value')
93
- end
94
-
95
- it "should send init_command after reconnect" do
96
- options = DatabaseCredentials['root'].dup
97
- options[:init_command] = "SET @something = 'setting_value';"
98
- options[:reconnect] = true
99
- client = new_client(options)
100
-
101
- result = client.query("SELECT @something;")
102
- expect(result.first['@something']).to eq('setting_value')
103
-
104
- # get the current connection id
105
- result = client.query("SELECT CONNECTION_ID()")
106
- first_conn_id = result.first['CONNECTION_ID()']
107
-
108
- # break the current connection
109
- expect { client.query("KILL #{first_conn_id}") }.to raise_error(Mysql2::Error)
110
-
111
- client.ping # reconnect now
112
-
113
- # get the new connection id
114
- result = client.query("SELECT CONNECTION_ID()")
115
- second_conn_id = result.first['CONNECTION_ID()']
116
-
117
- # confirm reconnect by checking the new connection id
118
- expect(first_conn_id).not_to eq(second_conn_id)
119
-
120
- # At last, check that the init command executed
121
- result = client.query("SELECT @something;")
122
- expect(result.first['@something']).to eq('setting_value')
123
- end
124
-
125
- it "should have a global default_query_options hash" do
126
- expect(Mysql2::Client).to respond_to(:default_query_options)
127
- end
128
-
129
- it "should be able to connect via SSL options" do
130
- ssl = @client.query "SHOW VARIABLES LIKE 'have_ssl'"
131
- ssl_uncompiled = ssl.any? { |x| x['Value'] == 'OFF' }
132
- pending("DON'T WORRY, THIS TEST PASSES - but SSL is not compiled into your MySQL daemon.") if ssl_uncompiled
133
- ssl_disabled = ssl.any? { |x| x['Value'] == 'DISABLED' }
134
- pending("DON'T WORRY, THIS TEST PASSES - but SSL is not enabled in your MySQL daemon.") if ssl_disabled
135
-
136
- # You may need to adjust the lines below to match your SSL certificate paths
137
- ssl_client = nil
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,
146
- )
147
- end.not_to raise_error
148
-
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
152
-
153
- expect(ssl_client.ssl_cipher).not_to be_empty
154
- expect(results['Ssl_cipher']).to eql(ssl_client.ssl_cipher)
155
- end
156
-
157
- def run_gc
158
- if defined?(Rubinius)
159
- GC.run(true)
160
- else
161
- GC.start
162
- end
163
- sleep(0.5)
164
- end
165
-
166
- it "should terminate connections when calling close" do
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
184
- }
185
- # rubocop:enable Lint/AmbiguousBlockAssociation
186
- end
187
-
188
- it "should not leave dangling connections after garbage collection" do
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)
199
-
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
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
240
- end
241
-
242
- context "#automatic_close" do
243
- it "is enabled by default" do
244
- expect(new_client.automatic_close?).to be(true)
245
- end
246
-
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
296
-
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
305
- end
306
-
307
- it "should be able to connect to database with numeric-only name" do
308
- database = 1235
309
- @client.query "CREATE DATABASE IF NOT EXISTS `#{database}`"
310
-
311
- expect do
312
- new_client('database' => database)
313
- end.not_to raise_error
314
-
315
- @client.query "DROP DATABASE IF EXISTS `#{database}`"
316
- end
317
-
318
- it "should respond to #close" do
319
- expect(@client).to respond_to(:close)
320
- end
321
-
322
- it "should be able to close properly" do
323
- expect(@client.close).to be_nil
324
- expect do
325
- @client.query "SELECT 1"
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)
346
- end
347
-
348
- it "should respond to #query" do
349
- expect(@client).to respond_to(:query)
350
- end
351
-
352
- it "should respond to #warning_count" do
353
- expect(@client).to respond_to(:warning_count)
354
- end
355
-
356
- context "#warning_count" do
357
- context "when no warnings" do
358
- it "should 0" do
359
- @client.query('select 1')
360
- expect(@client.warning_count).to eq(0)
361
- end
362
- end
363
- context "when has a warnings" do
364
- it "should > 0" do
365
- # "the statement produces extra information that can be viewed by issuing a SHOW WARNINGS"
366
- # https://dev.mysql.com/doc/refman/5.7/en/show-warnings.html
367
- @client.query('DROP TABLE IF EXISTS test.no_such_table')
368
- expect(@client.warning_count).to be > 0
369
- end
370
- end
371
- end
372
-
373
- it "should respond to #query_info" do
374
- expect(@client).to respond_to(:query_info)
375
- end
376
-
377
- context "#query_info" do
378
- context "when no info present" do
379
- it "should 0" do
380
- @client.query('select 1')
381
- expect(@client.query_info).to be_empty
382
- expect(@client.query_info_string).to be_nil
383
- end
384
- end
385
- context "when has some info" do
386
- it "should retrieve it" do
387
- @client.query "USE test"
388
- @client.query "CREATE TABLE IF NOT EXISTS infoTest (`id` int(11) NOT NULL AUTO_INCREMENT, blah INT(11), PRIMARY KEY (`id`))"
389
-
390
- # http://dev.mysql.com/doc/refman/5.0/en/mysql-info.html says
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).
392
- @client.query("INSERT INTO infoTest (blah) VALUES (1234),(4535)")
393
-
394
- expect(@client.query_info).to eql(records: 2, duplicates: 0, warnings: 0)
395
- expect(@client.query_info_string).to eq('Records: 2 Duplicates: 0 Warnings: 0')
396
-
397
- @client.query "DROP TABLE infoTest"
398
- end
399
- end
400
- end
401
-
402
- context ":local_infile" do
403
- before(:all) do
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
417
- end
418
-
419
- after(:all) do
420
- new_client do |client|
421
- client.query "DROP TABLE IF EXISTS infileTest"
422
- end
423
- end
424
-
425
- it "should raise an error when local_infile is disabled" do
426
- client = new_client(local_infile: false)
427
- expect do
428
- client.query "LOAD DATA LOCAL INFILE 'spec/test_data' INTO TABLE infileTest"
429
- end.to raise_error(Mysql2::Error, /command is not allowed/)
430
- end
431
-
432
- it "should raise an error when a non-existent file is loaded" do
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')
437
- end
438
-
439
- it "should LOAD DATA LOCAL INFILE" do
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)
444
-
445
- result = client.query "SELECT * FROM infileTest"
446
- expect(result.first).to eql('id' => 1, 'foo' => 'Hello', 'bar' => 'World')
447
- end
448
- end
449
-
450
- it "should expect connect_timeout to be a positive integer" do
451
- expect do
452
- new_client(connect_timeout: -1)
453
- end.to raise_error(Mysql2::Error)
454
- end
455
-
456
- it "should expect read_timeout to be a positive integer" do
457
- expect do
458
- new_client(read_timeout: -1)
459
- end.to raise_error(Mysql2::Error)
460
- end
461
-
462
- it "should expect write_timeout to be a positive integer" do
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')
492
- end
493
-
494
- context "#query" do
495
- it "should let you query again if iterating is finished when streaming" do
496
- @client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false).each.to_a
497
-
498
- expect do
499
- @client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false)
500
- end.to_not raise_error
501
- end
502
-
503
- it "should not let you query again if iterating is not finished when streaming" do
504
- @client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false).first
505
-
506
- expect do
507
- @client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false)
508
- end.to raise_exception(Mysql2::Error)
509
- end
510
-
511
- it "should only accept strings as the query parameter" do
512
- expect do
513
- @client.query ["SELECT 'not right'"]
514
- end.to raise_error(TypeError)
515
- end
516
-
517
- it "should not retain query options set on a query for subsequent queries, but should retain it in the result" do
518
- result = @client.query "SELECT 1", something: :else
519
- expect(@client.query_options[:something]).to be_nil
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))
522
-
523
- result = @client.query "SELECT 1"
524
- expect(result.instance_variable_get('@query_options')).to eql(@client.query_options)
525
- expect(@client.instance_variable_get('@current_query_options')).to eql(@client.query_options)
526
- end
527
-
528
- it "should allow changing query options for subsequent queries" do
529
- @client.query_options[:something] = :else
530
- result = @client.query "SELECT 1"
531
- expect(@client.query_options[:something]).to eql(:else)
532
- expect(result.instance_variable_get('@query_options')[:something]).to eql(:else)
533
-
534
- # Clean up after this test
535
- @client.query_options.delete(:something)
536
- expect(@client.query_options[:something]).to be_nil
537
- end
538
-
539
- it "should return results as a hash by default" do
540
- expect(@client.query("SELECT 1").first).to be_an_instance_of(Hash)
541
- end
542
-
543
- it "should be able to return results as an array" do
544
- expect(@client.query("SELECT 1", as: :array).first).to be_an_instance_of(Array)
545
- @client.query("SELECT 1").each(as: :array)
546
- end
547
-
548
- it "should be able to return results with symbolized keys" do
549
- expect(@client.query("SELECT 1", symbolize_keys: true).first.keys[0]).to be_an_instance_of(Symbol)
550
- end
551
-
552
- it "should require an open connection" do
553
- @client.close
554
- expect do
555
- @client.query "SELECT 1"
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
576
- end
577
-
578
- if RUBY_PLATFORM !~ /mingw|mswin/
579
- it "should not allow another query to be sent without fetching a result first" do
580
- @client.query("SELECT 1", async: true)
581
- expect do
582
- @client.query("SELECT 1")
583
- end.to raise_error(Mysql2::Error)
584
- end
585
-
586
- it "should describe the thread holding the active query" do
587
- thr = Thread.new { @client.query("SELECT 1", async: true) }
588
-
589
- thr.join
590
- expect { @client.query('SELECT 1') }.to raise_error(Mysql2::Error, Regexp.new(Regexp.escape(thr.inspect)))
591
- end
592
-
593
- it "should timeout if we wait longer than :read_timeout" do
594
- client = new_client(read_timeout: 0)
595
- expect do
596
- client.query('SELECT SLEEP(0.1)')
597
- end.to raise_error(Mysql2::Error::TimeoutError)
598
- end
599
-
600
- # XXX this test is not deterministic (because Unix signal handling is not)
601
- # and may fail on a loaded system
602
- it "should run signal handlers while waiting for a response" do
603
- kill_time = 0.1
604
- query_time = 2 * kill_time
605
-
606
- mark = {}
607
-
608
- begin
609
- trap(:USR1) { mark.store(:USR1, Time.now) }
610
- pid = fork do
611
- sleep kill_time # wait for client query to start
612
- Process.kill(:USR1, Process.ppid)
613
- sleep # wait for explicit kill to prevent GC disconnect
614
- end
615
- mark.store(:QUERY_START, Time.now)
616
- @client.query("SELECT SLEEP(#{query_time})")
617
- mark.store(:QUERY_END, Time.now)
618
- ensure
619
- Process.kill(:TERM, pid)
620
- Process.waitpid2(pid)
621
- trap(:USR1, 'DEFAULT')
622
- end
623
-
624
- # the query ran uninterrupted
625
- expect(mark.fetch(:QUERY_END) - mark.fetch(:QUERY_START)).to be_within(0.02).of(query_time)
626
- # signals fired while the query was running
627
- expect(mark.fetch(:USR1)).to be_between(mark.fetch(:QUERY_START), mark.fetch(:QUERY_END))
628
- end
629
-
630
- it "#socket should return a Fixnum (file descriptor from C)" do
631
- expect(@client.socket).to be_an_instance_of(0.class)
632
- expect(@client.socket).not_to eql(0)
633
- end
634
-
635
- it "#socket should require an open connection" do
636
- @client.close
637
- expect do
638
- @client.socket
639
- end.to raise_error(Mysql2::Error)
640
- end
641
-
642
- it 'should be impervious to connection-corrupting timeouts in #execute' do
643
- # attempt to break the connection
644
- stmt = @client.prepare('SELECT SLEEP(?)')
645
- expect { Timeout.timeout(0.1) { stmt.execute(0.2) } }.to raise_error(Timeout::Error)
646
- stmt.close
647
-
648
- # expect the connection to not be broken
649
- expect { @client.query('SELECT 1') }.to_not raise_error
650
- end
651
-
652
- context 'when a non-standard exception class is raised' do
653
- it "should close the connection when an exception is raised" do
654
- expect { Timeout.timeout(0.1, ArgumentError) { @client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
655
- expect { @client.query('SELECT 1') }.to raise_error(Mysql2::Error, 'MySQL client is not connected')
656
- end
657
-
658
- it "should handle Timeouts without leaving the connection hanging if reconnect is true" do
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.')
661
- end
662
-
663
- client = new_client(reconnect: true)
664
-
665
- expect { Timeout.timeout(0.1, ArgumentError) { client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
666
- expect { client.query('SELECT 1') }.to_not raise_error
667
- end
668
-
669
- it "should handle Timeouts without leaving the connection hanging if reconnect is set to true after construction" do
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.')
672
- end
673
-
674
- client = new_client
675
-
676
- expect { Timeout.timeout(0.1, ArgumentError) { client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
677
- expect { client.query('SELECT 1') }.to raise_error(Mysql2::Error)
678
-
679
- client.reconnect = true
680
-
681
- expect { Timeout.timeout(0.1, ArgumentError) { client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
682
- expect { client.query('SELECT 1') }.to_not raise_error
683
- end
684
- end
685
-
686
- it "threaded queries should be supported" do
687
- sleep_time = 0.5
688
-
689
- # Note that each thread opens its own database connection
690
- threads = Array.new(5) do
691
- Thread.new do
692
- new_client do |client|
693
- client.query("SELECT SLEEP(#{sleep_time})")
694
- end
695
- Thread.current.object_id
696
- end
697
- end
698
-
699
- # This timeout demonstrates that the threads are sleeping concurrently:
700
- # In the serial case, the timeout would fire and the test would fail
701
- values = Timeout.timeout(sleep_time * 1.1) { threads.map(&:value) }
702
-
703
- expect(values).to match_array(threads.map(&:object_id))
704
- end
705
-
706
- it "evented async queries should be supported" do
707
- # should immediately return nil
708
- expect(@client.query("SELECT sleep(0.1)", async: true)).to eql(nil)
709
-
710
- io_wrapper = IO.for_fd(@client.socket, autoclose: false)
711
- loops = 0
712
- loops += 1 until IO.select([io_wrapper], nil, nil, 0.05)
713
-
714
- # make sure we waited some period of time
715
- expect(loops >= 1).to be true
716
-
717
- result = @client.async_result
718
- expect(result).to be_an_instance_of(Mysql2::Result)
719
- end
720
- end
721
-
722
- context "Multiple results sets" do
723
- before(:each) do
724
- @multi_client = new_client(flags: Mysql2::Client::MULTI_STATEMENTS)
725
- end
726
-
727
- it "should raise an exception when one of multiple statements fails" do
728
- result = @multi_client.query("SELECT 1 AS 'set_1'; SELECT * FROM invalid_table_name; SELECT 2 AS 'set_2';")
729
- expect(result.first['set_1']).to be(1)
730
- expect do
731
- @multi_client.next_result
732
- end.to raise_error(Mysql2::Error)
733
- expect(@multi_client.next_result).to be false
734
- end
735
-
736
- it "returns multiple result sets" do
737
- expect(@multi_client.query("SELECT 1 AS 'set_1'; SELECT 2 AS 'set_2'").first).to eql('set_1' => 1)
738
-
739
- expect(@multi_client.next_result).to be true
740
- expect(@multi_client.store_result.first).to eql('set_2' => 2)
741
-
742
- expect(@multi_client.next_result).to be false
743
- end
744
-
745
- it "does not interfere with other statements" do
746
- @multi_client.query("SELECT 1 AS 'set_1'; SELECT 2 AS 'set_2'")
747
- @multi_client.store_result while @multi_client.next_result
748
-
749
- expect(@multi_client.query("SELECT 3 AS 'next'").first).to eq('next' => 3)
750
- end
751
-
752
- it "will raise on query if there are outstanding results to read" do
753
- @multi_client.query("SELECT 1; SELECT 2; SELECT 3")
754
- expect do
755
- @multi_client.query("SELECT 4")
756
- end.to raise_error(Mysql2::Error)
757
- end
758
-
759
- it "#abandon_results! should work" do
760
- @multi_client.query("SELECT 1; SELECT 2; SELECT 3")
761
- @multi_client.abandon_results!
762
- expect do
763
- @multi_client.query("SELECT 4")
764
- end.not_to raise_error
765
- end
766
-
767
- it "#more_results? should work" do
768
- @multi_client.query("SELECT 1 AS 'set_1'; SELECT 2 AS 'set_2'")
769
- expect(@multi_client.more_results?).to be true
770
-
771
- @multi_client.next_result
772
- @multi_client.store_result
773
-
774
- expect(@multi_client.more_results?).to be false
775
- end
776
-
777
- it "#more_results? should work with stored procedures" do
778
- @multi_client.query("DROP PROCEDURE IF EXISTS test_proc")
779
- @multi_client.query("CREATE PROCEDURE test_proc() BEGIN SELECT 1 AS 'set_1'; SELECT 2 AS 'set_2'; END")
780
- expect(@multi_client.query("CALL test_proc()").first).to eql('set_1' => 1)
781
- expect(@multi_client.more_results?).to be true
782
-
783
- @multi_client.next_result
784
- expect(@multi_client.store_result.first).to eql('set_2' => 2)
785
-
786
- @multi_client.next_result
787
- expect(@multi_client.store_result).to be_nil # this is the result from CALL itself
788
-
789
- expect(@multi_client.more_results?).to be false
790
- end
791
- end
792
- end
793
-
794
- it "should respond to #socket" do
795
- expect(@client).to respond_to(:socket)
796
- end
797
-
798
- if RUBY_PLATFORM =~ /mingw|mswin/
799
- it "#socket should raise as it's not supported" do
800
- expect do
801
- @client.socket
802
- end.to raise_error(Mysql2::Error, /Raw access to the mysql file descriptor isn't supported on Windows/)
803
- end
804
- end
805
-
806
- it "should respond to escape" do
807
- expect(Mysql2::Client).to respond_to(:escape)
808
- end
809
-
810
- context "escape" do
811
- it "should return a new SQL-escape version of the passed string" do
812
- expect(Mysql2::Client.escape("abc'def\"ghi\0jkl%mno")).to eql("abc\\'def\\\"ghi\\0jkl%mno")
813
- end
814
-
815
- it "should return the passed string if nothing was escaped" do
816
- str = "plain"
817
- expect(Mysql2::Client.escape(str).object_id).to eql(str.object_id)
818
- end
819
-
820
- it "should not overflow the thread stack" do
821
- expect do
822
- Thread.new { Mysql2::Client.escape("'" * 256 * 1024) }.join
823
- end.not_to raise_error
824
- end
825
-
826
- it "should not overflow the process stack" do
827
- expect do
828
- Thread.new { Mysql2::Client.escape("'" * 1024 * 1024 * 4) }.join
829
- end.not_to raise_error
830
- end
831
-
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)
836
-
837
- str.encode!('us-ascii')
838
- escaped = Mysql2::Client.escape(str)
839
- expect(escaped.encoding).to eql(str.encoding)
840
- end
841
- end
842
-
843
- it "should respond to #escape" do
844
- expect(@client).to respond_to(:escape)
845
- end
846
-
847
- context "#escape" do
848
- it "should return a new SQL-escape version of the passed string" do
849
- expect(@client.escape("abc'def\"ghi\0jkl%mno")).to eql("abc\\'def\\\"ghi\\0jkl%mno")
850
- end
851
-
852
- it "should return the passed string if nothing was escaped" do
853
- str = "plain"
854
- expect(@client.escape(str).object_id).to eql(str.object_id)
855
- end
856
-
857
- it "should not overflow the thread stack" do
858
- expect do
859
- Thread.new { @client.escape("'" * 256 * 1024) }.join
860
- end.not_to raise_error
861
- end
862
-
863
- it "should not overflow the process stack" do
864
- expect do
865
- Thread.new { @client.escape("'" * 1024 * 1024 * 4) }.join
866
- end.not_to raise_error
867
- end
868
-
869
- it "should require an open connection" do
870
- @client.close
871
- expect do
872
- @client.escape ""
873
- end.to raise_error(Mysql2::Error)
874
- end
875
-
876
- context 'when mysql encoding is not utf8' do
877
- let(:client) { new_client(encoding: "ujis") }
878
-
879
- it 'should return a internal encoding string if Encoding.default_internal is set' do
880
- with_internal_encoding Encoding::UTF_8 do
881
- expect(client.escape("\u{30C6}\u{30B9}\u{30C8}")).to eq "\u{30C6}\u{30B9}\u{30C8}"
882
- expect(client.escape("\u{30C6}'\u{30B9}\"\u{30C8}")).to eq "\u{30C6}\\'\u{30B9}\\\"\u{30C8}"
883
- end
884
- end
885
- end
886
- end
887
-
888
- it "should respond to #info" do
889
- expect(@client).to respond_to(:info)
890
- end
891
-
892
- it "#info should return a hash containing the client version ID and String" do
893
- info = @client.info
894
- expect(info).to be_an_instance_of(Hash)
895
- expect(info).to have_key(:id)
896
- expect(info[:id]).to be_an_instance_of(0.class)
897
- expect(info).to have_key(:version)
898
- expect(info[:version]).to be_an_instance_of(String)
899
- end
900
-
901
- context "strings returned by #info" do
902
- it "should be tagged as ascii" do
903
- expect(@client.info[:version].encoding).to eql(Encoding::US_ASCII)
904
- expect(@client.info[:header_version].encoding).to eql(Encoding::US_ASCII)
905
- end
906
- end
907
-
908
- context "strings returned by .info" do
909
- it "should be tagged as ascii" do
910
- expect(Mysql2::Client.info[:version].encoding).to eql(Encoding::US_ASCII)
911
- expect(Mysql2::Client.info[:header_version].encoding).to eql(Encoding::US_ASCII)
912
- end
913
- end
914
-
915
- it "should respond to #server_info" do
916
- expect(@client).to respond_to(:server_info)
917
- end
918
-
919
- it "#server_info should return a hash containing the client version ID and String" do
920
- server_info = @client.server_info
921
- expect(server_info).to be_an_instance_of(Hash)
922
- expect(server_info).to have_key(:id)
923
- expect(server_info[:id]).to be_an_instance_of(0.class)
924
- expect(server_info).to have_key(:version)
925
- expect(server_info[:version]).to be_an_instance_of(String)
926
- end
927
-
928
- it "#server_info should require an open connection" do
929
- @client.close
930
- expect do
931
- @client.server_info
932
- end.to raise_error(Mysql2::Error)
933
- end
934
-
935
- context "strings returned by #server_info" do
936
- it "should default to the connection's encoding if Encoding.default_internal is nil" do
937
- with_internal_encoding nil do
938
- expect(@client.server_info[:version].encoding).to eql(Encoding::UTF_8)
939
-
940
- client2 = new_client(encoding: 'ascii')
941
- expect(client2.server_info[:version].encoding).to eql(Encoding::ASCII)
942
- end
943
- end
944
-
945
- it "should use Encoding.default_internal" do
946
- with_internal_encoding Encoding::UTF_8 do
947
- expect(@client.server_info[:version].encoding).to eql(Encoding.default_internal)
948
- end
949
-
950
- with_internal_encoding Encoding::ASCII do
951
- expect(@client.server_info[:version].encoding).to eql(Encoding.default_internal)
952
- end
953
- end
954
- end
955
-
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)
960
-
961
- expect do
962
- new_client(DatabaseCredentials['root'])
963
- end.not_to raise_error
964
- end
965
-
966
- context 'write operations api' do
967
- before(:each) do
968
- @client.query "USE test"
969
- @client.query "CREATE TABLE IF NOT EXISTS lastIdTest (`id` BIGINT NOT NULL AUTO_INCREMENT, blah INT(11), PRIMARY KEY (`id`))"
970
- end
971
-
972
- after(:each) do
973
- @client.query "DROP TABLE lastIdTest"
974
- end
975
-
976
- it "should respond to #last_id" do
977
- expect(@client).to respond_to(:last_id)
978
- end
979
-
980
- it "#last_id should return a Fixnum, the from the last INSERT/UPDATE" do
981
- expect(@client.last_id).to eql(0)
982
- @client.query "INSERT INTO lastIdTest (blah) VALUES (1234)"
983
- expect(@client.last_id).to eql(1)
984
- end
985
-
986
- it "should respond to #last_id" do
987
- expect(@client).to respond_to(:last_id)
988
- end
989
-
990
- it "#last_id should return a Fixnum, the from the last INSERT/UPDATE" do
991
- @client.query "INSERT INTO lastIdTest (blah) VALUES (1234)"
992
- expect(@client.affected_rows).to eql(1)
993
- @client.query "UPDATE lastIdTest SET blah=4321 WHERE id=1"
994
- expect(@client.affected_rows).to eql(1)
995
- end
996
-
997
- it "#last_id should handle BIGINT auto-increment ids above 32 bits" do
998
- # The id column type must be BIGINT. Surprise: INT(x) is limited to 32-bits for all values of x.
999
- # Insert a row with a given ID, this should raise the auto-increment state
1000
- @client.query "INSERT INTO lastIdTest (id, blah) VALUES (5000000000, 5000)"
1001
- expect(@client.last_id).to eql(5000000000)
1002
- @client.query "INSERT INTO lastIdTest (blah) VALUES (5001)"
1003
- expect(@client.last_id).to eql(5000000001)
1004
- end
1005
- end
1006
-
1007
- it "should respond to #thread_id" do
1008
- expect(@client).to respond_to(:thread_id)
1009
- end
1010
-
1011
- it "#thread_id should be a Fixnum" do
1012
- expect(@client.thread_id).to be_an_instance_of(0.class)
1013
- end
1014
-
1015
- it "should respond to #ping" do
1016
- expect(@client).to respond_to(:ping)
1017
- end
1018
-
1019
- context "select_db" do
1020
- before(:each) do
1021
- 2.times do |i|
1022
- @client.query("CREATE DATABASE test_selectdb_#{i}")
1023
- @client.query("USE test_selectdb_#{i}")
1024
- @client.query("CREATE TABLE test#{i} (`id` int NOT NULL PRIMARY KEY)")
1025
- end
1026
- end
1027
-
1028
- after(:each) do
1029
- 2.times do |i|
1030
- @client.query("DROP DATABASE test_selectdb_#{i}")
1031
- end
1032
- end
1033
-
1034
- it "should respond to #select_db" do
1035
- expect(@client).to respond_to(:select_db)
1036
- end
1037
-
1038
- it "should switch databases" do
1039
- @client.select_db("test_selectdb_0")
1040
- expect(@client.query("SHOW TABLES").first.values.first).to eql("test0")
1041
- @client.select_db("test_selectdb_1")
1042
- expect(@client.query("SHOW TABLES").first.values.first).to eql("test1")
1043
- @client.select_db("test_selectdb_0")
1044
- expect(@client.query("SHOW TABLES").first.values.first).to eql("test0")
1045
- end
1046
-
1047
- it "should raise a Mysql2::Error when the database doesn't exist" do
1048
- expect do
1049
- @client.select_db("nopenothere")
1050
- end.to raise_error(Mysql2::Error)
1051
- end
1052
-
1053
- it "should return the database switched to" do
1054
- expect(@client.select_db("test_selectdb_1")).to eq("test_selectdb_1")
1055
- end
1056
- end
1057
-
1058
- it "#thread_id should return a boolean" do
1059
- expect(@client.ping).to eql(true)
1060
- @client.close
1061
- expect(@client.ping).to eql(false)
1062
- end
1063
-
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)
1071
- end
1072
- end