mysql2 0.4.3 → 0.4.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -82,6 +82,11 @@ RSpec.describe Mysql2::Result do
82
82
  expect(result.first.object_id).not_to eql(result.first.object_id)
83
83
  end
84
84
 
85
+ it "should be able to iterate a second time even if cache_rows is disabled" do
86
+ result = @client.query "SELECT 1 UNION SELECT 2", :cache_rows => false
87
+ expect(result.to_a).to eql(result.to_a)
88
+ end
89
+
85
90
  it "should yield different value for #first if streaming" do
86
91
  result = @client.query "SELECT 1 UNION SELECT 2", :stream => true, :cache_rows => false
87
92
  expect(result.first).not_to eql(result.first)
@@ -148,18 +153,16 @@ RSpec.describe Mysql2::Result do
148
153
  end
149
154
 
150
155
  it "should raise an exception if streaming ended due to a timeout" do
151
- # Create an extra client instance, since we're going to time it out
152
- client = Mysql2::Client.new DatabaseCredentials['root']
153
- client.query "CREATE TEMPORARY TABLE streamingTest (val BINARY(255)) ENGINE=MEMORY"
156
+ @client.query "CREATE TEMPORARY TABLE streamingTest (val BINARY(255)) ENGINE=MEMORY"
154
157
 
155
158
  # Insert enough records to force the result set into multiple reads
156
159
  # (the BINARY type is used simply because it forces full width results)
157
160
  10000.times do |i|
158
- client.query "INSERT INTO streamingTest (val) VALUES ('Foo #{i}')"
161
+ @client.query "INSERT INTO streamingTest (val) VALUES ('Foo #{i}')"
159
162
  end
160
163
 
161
- client.query "SET net_write_timeout = 1"
162
- res = client.query "SELECT * FROM streamingTest", :stream => true, :cache_rows => false
164
+ @client.query "SET net_write_timeout = 1"
165
+ res = @client.query "SELECT * FROM streamingTest", :stream => true, :cache_rows => false
163
166
 
164
167
  expect {
165
168
  res.each_with_index do |_, i|
@@ -205,36 +208,43 @@ RSpec.describe Mysql2::Result do
205
208
  expect(@test_result['tiny_int_test']).to eql(1)
206
209
  end
207
210
 
208
- it "should return TrueClass or FalseClass for a TINYINT value if :cast_booleans is enabled" do
209
- @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (1)'
210
- id1 = @client.last_id
211
- @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (0)'
212
- id2 = @client.last_id
213
- @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (-1)'
214
- id3 = @client.last_id
211
+ context "cast booleans for TINYINT if :cast_booleans is enabled" do
212
+ # rubocop:disable Style/Semicolon
213
+ let(:id1) { @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES ( 1)'; @client.last_id }
214
+ let(:id2) { @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES ( 0)'; @client.last_id }
215
+ let(:id3) { @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (-1)'; @client.last_id }
216
+ # rubocop:enable Style/Semicolon
215
217
 
216
- result1 = @client.query 'SELECT bool_cast_test FROM mysql2_test WHERE bool_cast_test = 1 LIMIT 1', :cast_booleans => true
217
- result2 = @client.query 'SELECT bool_cast_test FROM mysql2_test WHERE bool_cast_test = 0 LIMIT 1', :cast_booleans => true
218
- result3 = @client.query 'SELECT bool_cast_test FROM mysql2_test WHERE bool_cast_test = -1 LIMIT 1', :cast_booleans => true
219
- expect(result1.first['bool_cast_test']).to be true
220
- expect(result2.first['bool_cast_test']).to be false
221
- expect(result3.first['bool_cast_test']).to be true
218
+ after do
219
+ @client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2},#{id3})"
220
+ end
222
221
 
223
- @client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2},#{id3})"
222
+ it "should return TrueClass or FalseClass for a TINYINT value if :cast_booleans is enabled" do
223
+ result1 = @client.query "SELECT bool_cast_test FROM mysql2_test WHERE id = #{id1} LIMIT 1", :cast_booleans => true
224
+ result2 = @client.query "SELECT bool_cast_test FROM mysql2_test WHERE id = #{id2} LIMIT 1", :cast_booleans => true
225
+ result3 = @client.query "SELECT bool_cast_test FROM mysql2_test WHERE id = #{id3} LIMIT 1", :cast_booleans => true
226
+ expect(result1.first['bool_cast_test']).to be true
227
+ expect(result2.first['bool_cast_test']).to be false
228
+ expect(result3.first['bool_cast_test']).to be true
229
+ end
224
230
  end
225
231
 
226
- it "should return TrueClass or FalseClass for a BIT(1) value if :cast_booleans is enabled" do
227
- @client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (1)'
228
- id1 = @client.last_id
229
- @client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (0)'
230
- id2 = @client.last_id
232
+ context "cast booleans for BIT(1) if :cast_booleans is enabled" do
233
+ # rubocop:disable Style/Semicolon
234
+ let(:id1) { @client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (1)'; @client.last_id }
235
+ let(:id2) { @client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (0)'; @client.last_id }
236
+ # rubocop:enable Style/Semicolon
231
237
 
232
- result1 = @client.query "SELECT single_bit_test FROM mysql2_test WHERE id = #{id1}", :cast_booleans => true
233
- result2 = @client.query "SELECT single_bit_test FROM mysql2_test WHERE id = #{id2}", :cast_booleans => true
234
- expect(result1.first['single_bit_test']).to be true
235
- expect(result2.first['single_bit_test']).to be false
238
+ after do
239
+ @client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2})"
240
+ end
236
241
 
237
- @client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2})"
242
+ it "should return TrueClass or FalseClass for a BIT(1) value if :cast_booleans is enabled" do
243
+ result1 = @client.query "SELECT single_bit_test FROM mysql2_test WHERE id = #{id1}", :cast_booleans => true
244
+ result2 = @client.query "SELECT single_bit_test FROM mysql2_test WHERE id = #{id2}", :cast_booleans => true
245
+ expect(result1.first['single_bit_test']).to be true
246
+ expect(result2.first['single_bit_test']).to be false
247
+ end
238
248
  end
239
249
 
240
250
  it "should return Fixnum for a SMALLINT value" do
@@ -282,6 +292,30 @@ RSpec.describe Mysql2::Result do
282
292
  expect(@test_result['date_time_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2010-04-04 11:44:00')
283
293
  end
284
294
 
295
+ it "should return Time values with microseconds" do
296
+ now = Time.now
297
+ if RUBY_VERSION =~ /1.8/ || @client.server_info[:id] / 100 < 506
298
+ result = @client.query("SELECT CAST('#{now.strftime('%F %T %z')}' AS DATETIME) AS a")
299
+ expect(result.first['a'].strftime('%F %T %z')).to eql(now.strftime('%F %T %z'))
300
+ else
301
+ result = @client.query("SELECT CAST('#{now.strftime('%F %T.%6N %z')}' AS DATETIME(6)) AS a")
302
+ # microseconds is 6 digits after the decimal, but only test on 5 significant figures
303
+ expect(result.first['a'].strftime('%F %T.%5N %z')).to eql(now.strftime('%F %T.%5N %z'))
304
+ end
305
+ end
306
+
307
+ it "should return DateTime values with microseconds" do
308
+ now = DateTime.now
309
+ if RUBY_VERSION =~ /1.8/ || @client.server_info[:id] / 100 < 506
310
+ result = @client.query("SELECT CAST('#{now.strftime('%F %T %z')}' AS DATETIME) AS a")
311
+ expect(result.first['a'].strftime('%F %T %z')).to eql(now.strftime('%F %T %z'))
312
+ else
313
+ result = @client.query("SELECT CAST('#{now.strftime('%F %T.%6N %z')}' AS DATETIME(6)) AS a")
314
+ # microseconds is 6 digits after the decimal, but only test on 5 significant figures
315
+ expect(result.first['a'].strftime('%F %T.%5N %z')).to eql(now.strftime('%F %T.%5N %z'))
316
+ end
317
+ end
318
+
285
319
  if 1.size == 4 # 32bit
286
320
  klass = if RUBY_VERSION =~ /1.8/
287
321
  DateTime
@@ -362,10 +396,9 @@ RSpec.describe Mysql2::Result do
362
396
  result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
363
397
  expect(result['enum_test'].encoding).to eql(Encoding::UTF_8)
364
398
 
365
- client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
399
+ client2 = new_client(:encoding => 'ascii')
366
400
  result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
367
401
  expect(result['enum_test'].encoding).to eql(Encoding::ASCII)
368
- client2.close
369
402
  end
370
403
  end
371
404
 
@@ -395,10 +428,9 @@ RSpec.describe Mysql2::Result do
395
428
  result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
396
429
  expect(result['set_test'].encoding).to eql(Encoding::UTF_8)
397
430
 
398
- client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
431
+ client2 = new_client(:encoding => 'ascii')
399
432
  result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
400
433
  expect(result['set_test'].encoding).to eql(Encoding::ASCII)
401
- client2.close
402
434
  end
403
435
  end
404
436
 
@@ -489,10 +521,9 @@ RSpec.describe Mysql2::Result do
489
521
  result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
490
522
  expect(result[field].encoding).to eql(Encoding::UTF_8)
491
523
 
492
- client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
524
+ client2 = new_client(:encoding => 'ascii')
493
525
  result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
494
526
  expect(result[field].encoding).to eql(Encoding::ASCII)
495
- client2.close
496
527
  end
497
528
  end
498
529
 
@@ -3,14 +3,16 @@ require './spec/spec_helper.rb'
3
3
 
4
4
  RSpec.describe Mysql2::Statement do
5
5
  before :each do
6
- @client = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => "utf8"))
6
+ @client = new_client(:encoding => "utf8")
7
+ end
8
+
9
+ def stmt_count
10
+ @client.query("SHOW STATUS LIKE 'Prepared_stmt_count'").first['Value'].to_i
7
11
  end
8
12
 
9
13
  it "should create a statement" do
10
14
  statement = nil
11
- expect { statement = @client.prepare 'SELECT 1' }.to change {
12
- @client.query("SHOW STATUS LIKE 'Prepared_stmt_count'").first['Value'].to_i
13
- }.by(1)
15
+ expect { statement = @client.prepare 'SELECT 1' }.to change(&method(:stmt_count)).by(1)
14
16
  expect(statement).to be_an_instance_of(Mysql2::Statement)
15
17
  end
16
18
 
@@ -59,6 +61,32 @@ RSpec.describe Mysql2::Statement do
59
61
  expect(rows).to eq([{ "1" => 1 }])
60
62
  end
61
63
 
64
+ it "should handle booleans" do
65
+ stmt = @client.prepare('SELECT ? AS `true`, ? AS `false`')
66
+ result = stmt.execute(true, false)
67
+ expect(result.to_a).to eq(['true' => 1, 'false' => 0])
68
+ end
69
+
70
+ it "should handle bignum but in int64_t" do
71
+ stmt = @client.prepare('SELECT ? AS max, ? AS min')
72
+ int64_max = (1 << 63) - 1
73
+ int64_min = -(1 << 63)
74
+ result = stmt.execute(int64_max, int64_min)
75
+ expect(result.to_a).to eq(['max' => int64_max, 'min' => int64_min])
76
+ end
77
+
78
+ it "should handle bignum but beyond int64_t" do
79
+ stmt = @client.prepare('SELECT ? AS max1, ? AS max2, ? AS max3, ? AS min1, ? AS min2, ? AS min3')
80
+ int64_max1 = (1 << 63)
81
+ int64_max2 = (1 << 64) - 1
82
+ int64_max3 = 1 << 64
83
+ int64_min1 = -(1 << 63) - 1
84
+ int64_min2 = -(1 << 64) + 1
85
+ int64_min3 = -0xC000000000000000
86
+ result = stmt.execute(int64_max1, int64_max2, int64_max3, int64_min1, int64_min2, int64_min3)
87
+ expect(result.to_a).to eq(['max1' => int64_max1, 'max2' => int64_max2, 'max3' => int64_max3, 'min1' => int64_min1, 'min2' => int64_min2, 'min3' => int64_min3])
88
+ end
89
+
62
90
  it "should keep its result after other query" do
63
91
  @client.query 'USE test'
64
92
  @client.query 'CREATE TABLE IF NOT EXISTS mysql2_stmt_q(a int)'
@@ -108,6 +136,37 @@ RSpec.describe Mysql2::Statement do
108
136
  expect(result.first.first[1]).to be_an_instance_of(Time)
109
137
  end
110
138
 
139
+ it "should prepare Date values" do
140
+ now = Date.today
141
+ statement = @client.prepare('SELECT ? AS a')
142
+ result = statement.execute(now)
143
+ expect(result.first['a'].to_s).to eql(now.strftime('%F'))
144
+ end
145
+
146
+ it "should prepare Time values with microseconds" do
147
+ now = Time.now
148
+ statement = @client.prepare('SELECT ? AS a')
149
+ result = statement.execute(now)
150
+ if RUBY_VERSION =~ /1.8/
151
+ expect(result.first['a'].strftime('%F %T %z')).to eql(now.strftime('%F %T %z'))
152
+ else
153
+ # microseconds is six digits after the decimal, but only test on 5 significant figures
154
+ expect(result.first['a'].strftime('%F %T.%5N %z')).to eql(now.strftime('%F %T.%5N %z'))
155
+ end
156
+ end
157
+
158
+ it "should prepare DateTime values with microseconds" do
159
+ now = DateTime.now
160
+ statement = @client.prepare('SELECT ? AS a')
161
+ result = statement.execute(now)
162
+ if RUBY_VERSION =~ /1.8/
163
+ expect(result.first['a'].strftime('%F %T %z')).to eql(now.strftime('%F %T %z'))
164
+ else
165
+ # microseconds is six digits after the decimal, but only test on 5 significant figures
166
+ expect(result.first['a'].strftime('%F %T.%5N %z')).to eql(now.strftime('%F %T.%5N %z'))
167
+ end
168
+ end
169
+
111
170
  it "should tell us about the fields" do
112
171
  statement = @client.prepare 'SELECT 1 as foo, 2'
113
172
  statement.execute
@@ -117,6 +176,13 @@ RSpec.describe Mysql2::Statement do
117
176
  expect(list[1]).to eq('2')
118
177
  end
119
178
 
179
+ it "should handle as a decimal binding a BigDecimal" do
180
+ stmt = @client.prepare('SELECT ? AS decimal_test')
181
+ test_result = stmt.execute(BigDecimal.new("123.45")).first
182
+ expect(test_result['decimal_test']).to be_an_instance_of(BigDecimal)
183
+ expect(test_result['decimal_test']).to eql(123.45)
184
+ end
185
+
120
186
  it "should update a DECIMAL value passing a BigDecimal" do
121
187
  @client.query 'USE test'
122
188
  @client.query 'DROP TABLE IF EXISTS mysql2_stmt_decimal_test'
@@ -128,6 +194,14 @@ RSpec.describe Mysql2::Statement do
128
194
  expect(test_result['decimal_test']).to eql(123.45)
129
195
  end
130
196
 
197
+ it "should warn but still work if cache_rows is set to false" do
198
+ @client.query_options.merge!(:cache_rows => false)
199
+ statement = @client.prepare 'SELECT 1'
200
+ result = nil
201
+ expect { result = statement.execute.to_a }.to output(/:cache_rows is forced for prepared statements/).to_stderr
202
+ expect(result.length).to eq(1)
203
+ end
204
+
131
205
  context "utf8_db" do
132
206
  before(:each) do
133
207
  @client.query("DROP DATABASE IF EXISTS test_mysql2_stmt_utf8")
@@ -260,18 +334,19 @@ RSpec.describe Mysql2::Statement do
260
334
  end
261
335
 
262
336
  context "#fields" do
263
- before(:each) do
264
- @client.query "USE test"
265
- @test_result = @client.prepare("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").execute
266
- end
267
-
268
337
  it "method should exist" do
269
- expect(@test_result).to respond_to(:fields)
338
+ stmt = @client.prepare("SELECT 1")
339
+ expect(stmt).to respond_to(:fields)
270
340
  end
271
341
 
272
342
  it "should return an array of field names in proper order" do
273
- result = @client.prepare("SELECT 'a', 'b', 'c'").execute
274
- expect(result.fields).to eql(%w(a b c))
343
+ stmt = @client.prepare("SELECT 'a', 'b', 'c'")
344
+ expect(stmt.fields).to eql(%w(a b c))
345
+ end
346
+
347
+ it "should return nil for statement with no result fields" do
348
+ stmt = @client.prepare("INSERT INTO mysql2_test () VALUES ()")
349
+ expect(stmt.fields).to eql(nil)
275
350
  end
276
351
  end
277
352
 
@@ -301,36 +376,47 @@ RSpec.describe Mysql2::Statement do
301
376
  expect(@test_result['tiny_int_test']).to eql(1)
302
377
  end
303
378
 
304
- it "should return TrueClass or FalseClass for a TINYINT value if :cast_booleans is enabled" do
305
- @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (1)'
306
- id1 = @client.last_id
307
- @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (0)'
308
- id2 = @client.last_id
309
- @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (-1)'
310
- id3 = @client.last_id
379
+ context "cast booleans for TINYINT if :cast_booleans is enabled" do
380
+ # rubocop:disable Style/Semicolon
381
+ let(:client) { new_client(:cast_booleans => true) }
382
+ let(:id1) { client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES ( 1)'; client.last_id }
383
+ let(:id2) { client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES ( 0)'; client.last_id }
384
+ let(:id3) { client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (-1)'; client.last_id }
385
+ # rubocop:enable Style/Semicolon
311
386
 
312
- result1 = @client.query 'SELECT bool_cast_test FROM mysql2_test WHERE bool_cast_test = 1 LIMIT 1', :cast_booleans => true
313
- result2 = @client.query 'SELECT bool_cast_test FROM mysql2_test WHERE bool_cast_test = 0 LIMIT 1', :cast_booleans => true
314
- result3 = @client.query 'SELECT bool_cast_test FROM mysql2_test WHERE bool_cast_test = -1 LIMIT 1', :cast_booleans => true
315
- expect(result1.first['bool_cast_test']).to be true
316
- expect(result2.first['bool_cast_test']).to be false
317
- expect(result3.first['bool_cast_test']).to be true
387
+ after do
388
+ client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2},#{id3})"
389
+ end
318
390
 
319
- @client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2},#{id3})"
391
+ it "should return TrueClass or FalseClass for a TINYINT value if :cast_booleans is enabled" do
392
+ query = client.prepare 'SELECT bool_cast_test FROM mysql2_test WHERE id = ?'
393
+ result1 = query.execute id1
394
+ result2 = query.execute id2
395
+ result3 = query.execute id3
396
+ expect(result1.first['bool_cast_test']).to be true
397
+ expect(result2.first['bool_cast_test']).to be false
398
+ expect(result3.first['bool_cast_test']).to be true
399
+ end
320
400
  end
321
401
 
322
- it "should return TrueClass or FalseClass for a BIT(1) value if :cast_booleans is enabled" do
323
- @client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (1)'
324
- id1 = @client.last_id
325
- @client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (0)'
326
- id2 = @client.last_id
402
+ context "cast booleans for BIT(1) if :cast_booleans is enabled" do
403
+ # rubocop:disable Style/Semicolon
404
+ let(:client) { new_client(:cast_booleans => true) }
405
+ let(:id1) { client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (1)'; client.last_id }
406
+ let(:id2) { client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (0)'; client.last_id }
407
+ # rubocop:enable Style/Semicolon
327
408
 
328
- result1 = @client.query "SELECT single_bit_test FROM mysql2_test WHERE id = #{id1}", :cast_booleans => true
329
- result2 = @client.query "SELECT single_bit_test FROM mysql2_test WHERE id = #{id2}", :cast_booleans => true
330
- expect(result1.first['single_bit_test']).to be true
331
- expect(result2.first['single_bit_test']).to be false
409
+ after do
410
+ client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2})"
411
+ end
332
412
 
333
- @client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2})"
413
+ it "should return TrueClass or FalseClass for a BIT(1) value if :cast_booleans is enabled" do
414
+ query = client.prepare 'SELECT single_bit_test FROM mysql2_test WHERE id = ?'
415
+ result1 = query.execute id1
416
+ result2 = query.execute id2
417
+ expect(result1.first['single_bit_test']).to be true
418
+ expect(result2.first['single_bit_test']).to be false
419
+ end
334
420
  end
335
421
 
336
422
  it "should return Fixnum for a SMALLINT value" do
@@ -387,39 +473,39 @@ RSpec.describe Mysql2::Statement do
387
473
 
388
474
  it "should return DateTime when timestamp is < 1901-12-13 20:45:52" do
389
475
  # 1901-12-13T20:45:52 is the min for 32bit Ruby 1.8
390
- r = @client.query("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test")
476
+ r = @client.prepare("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test").execute
391
477
  expect(r.first['test']).to be_an_instance_of(klass)
392
478
  end
393
479
 
394
480
  it "should return DateTime when timestamp is > 2038-01-19T03:14:07" do
395
481
  # 2038-01-19T03:14:07 is the max for 32bit Ruby 1.8
396
- r = @client.query("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test")
482
+ r = @client.prepare("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test").execute
397
483
  expect(r.first['test']).to be_an_instance_of(klass)
398
484
  end
399
485
  elsif 1.size == 8 # 64bit
400
486
  if RUBY_VERSION =~ /1.8/
401
487
  it "should return Time when timestamp is > 0138-12-31 11:59:59" do
402
- r = @client.query("SELECT CAST('0139-1-1 00:00:00' AS DATETIME) as test")
488
+ r = @client.prepare("SELECT CAST('0139-1-1 00:00:00' AS DATETIME) as test").execute
403
489
  expect(r.first['test']).to be_an_instance_of(Time)
404
490
  end
405
491
 
406
492
  it "should return DateTime when timestamp is < 0139-1-1T00:00:00" do
407
- r = @client.query("SELECT CAST('0138-12-31 11:59:59' AS DATETIME) as test")
493
+ r = @client.prepare("SELECT CAST('0138-12-31 11:59:59' AS DATETIME) as test").execute
408
494
  expect(r.first['test']).to be_an_instance_of(DateTime)
409
495
  end
410
496
 
411
497
  it "should return Time when timestamp is > 2038-01-19T03:14:07" do
412
- r = @client.query("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test")
498
+ r = @client.prepare("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test").execute
413
499
  expect(r.first['test']).to be_an_instance_of(Time)
414
500
  end
415
501
  else
416
502
  it "should return Time when timestamp is < 1901-12-13 20:45:52" do
417
- r = @client.query("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test")
503
+ r = @client.prepare("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test").execute
418
504
  expect(r.first['test']).to be_an_instance_of(Time)
419
505
  end
420
506
 
421
507
  it "should return Time when timestamp is > 2038-01-19T03:14:07" do
422
- r = @client.query("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test")
508
+ r = @client.prepare("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test").execute
423
509
  expect(r.first['test']).to be_an_instance_of(Time)
424
510
  end
425
511
  end
@@ -458,10 +544,9 @@ RSpec.describe Mysql2::Statement do
458
544
  result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
459
545
  expect(result['enum_test'].encoding).to eql(Encoding::UTF_8)
460
546
 
461
- client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
547
+ client2 = new_client(:encoding => 'ascii')
462
548
  result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
463
549
  expect(result['enum_test'].encoding).to eql(Encoding::US_ASCII)
464
- client2.close
465
550
  end
466
551
  end
467
552
 
@@ -491,10 +576,9 @@ RSpec.describe Mysql2::Statement do
491
576
  result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
492
577
  expect(result['set_test'].encoding).to eql(Encoding::UTF_8)
493
578
 
494
- client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
579
+ client2 = new_client(:encoding => 'ascii')
495
580
  result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
496
581
  expect(result['set_test'].encoding).to eql(Encoding::US_ASCII)
497
- client2.close
498
582
  end
499
583
  end
500
584
 
@@ -585,10 +669,9 @@ RSpec.describe Mysql2::Statement do
585
669
  result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
586
670
  expect(result[field].encoding).to eql(Encoding::UTF_8)
587
671
 
588
- client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
672
+ client2 = new_client(:encoding => 'ascii')
589
673
  result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
590
674
  expect(result[field].encoding).to eql(Encoding::US_ASCII)
591
- client2.close
592
675
  end
593
676
  end
594
677
 
@@ -681,9 +764,7 @@ RSpec.describe Mysql2::Statement do
681
764
  context 'close' do
682
765
  it 'should free server resources' do
683
766
  stmt = @client.prepare 'SELECT 1'
684
- expect { stmt.close }.to change {
685
- @client.query("SHOW STATUS LIKE 'Prepared_stmt_count'").first['Value'].to_i
686
- }.by(-1)
767
+ expect { stmt.close }.to change(&method(:stmt_count)).by(-1)
687
768
  end
688
769
 
689
770
  it 'should raise an error on subsequent execution' do
data/spec/spec_helper.rb CHANGED
@@ -23,72 +23,86 @@ RSpec.configure do |config|
23
23
  $VERBOSE = old_verbose
24
24
  end
25
25
 
26
+ def new_client(option_overrides = {})
27
+ client = Mysql2::Client.new(DatabaseCredentials['root'].merge(option_overrides))
28
+ @clients ||= []
29
+ @clients << client
30
+ return client unless block_given?
31
+ begin
32
+ yield client
33
+ ensure
34
+ client.close
35
+ @clients.delete(client)
36
+ end
37
+ end
38
+
26
39
  config.before :each do
27
- @client = Mysql2::Client.new DatabaseCredentials['root']
40
+ @client = new_client
28
41
  end
29
42
 
30
43
  config.after :each do
31
- @client.close
44
+ @clients.each(&:close)
32
45
  end
33
46
 
34
47
  config.before(:all) do
35
- client = Mysql2::Client.new DatabaseCredentials['root']
36
- client.query %[
37
- CREATE TABLE IF NOT EXISTS mysql2_test (
38
- id MEDIUMINT NOT NULL AUTO_INCREMENT,
39
- null_test VARCHAR(10),
40
- bit_test BIT(64),
41
- single_bit_test BIT(1),
42
- tiny_int_test TINYINT,
43
- bool_cast_test TINYINT(1),
44
- small_int_test SMALLINT,
45
- medium_int_test MEDIUMINT,
46
- int_test INT,
47
- big_int_test BIGINT,
48
- float_test FLOAT(10,3),
49
- float_zero_test FLOAT(10,3),
50
- double_test DOUBLE(10,3),
51
- decimal_test DECIMAL(10,3),
52
- decimal_zero_test DECIMAL(10,3),
53
- date_test DATE,
54
- date_time_test DATETIME,
55
- timestamp_test TIMESTAMP,
56
- time_test TIME,
57
- year_test YEAR(4),
58
- char_test CHAR(10),
59
- varchar_test VARCHAR(10),
60
- binary_test BINARY(10),
61
- varbinary_test VARBINARY(10),
62
- tiny_blob_test TINYBLOB,
63
- tiny_text_test TINYTEXT,
64
- blob_test BLOB,
65
- text_test TEXT,
66
- medium_blob_test MEDIUMBLOB,
67
- medium_text_test MEDIUMTEXT,
68
- long_blob_test LONGBLOB,
69
- long_text_test LONGTEXT,
70
- enum_test ENUM('val1', 'val2'),
71
- set_test SET('val1', 'val2'),
72
- PRIMARY KEY (id)
73
- )
74
- ]
75
- client.query "DELETE FROM mysql2_test;"
76
- client.query %[
77
- INSERT INTO mysql2_test (
78
- null_test, bit_test, single_bit_test, tiny_int_test, bool_cast_test, small_int_test, medium_int_test, int_test, big_int_test,
79
- float_test, float_zero_test, double_test, decimal_test, decimal_zero_test, date_test, date_time_test, timestamp_test, time_test,
80
- year_test, char_test, varchar_test, binary_test, varbinary_test, tiny_blob_test,
81
- tiny_text_test, blob_test, text_test, medium_blob_test, medium_text_test,
82
- long_blob_test, long_text_test, enum_test, set_test
83
- )
48
+ new_client do |client|
49
+ client.query %[
50
+ CREATE TABLE IF NOT EXISTS mysql2_test (
51
+ id MEDIUMINT NOT NULL AUTO_INCREMENT,
52
+ null_test VARCHAR(10),
53
+ bit_test BIT(64),
54
+ single_bit_test BIT(1),
55
+ tiny_int_test TINYINT,
56
+ bool_cast_test TINYINT(1),
57
+ small_int_test SMALLINT,
58
+ medium_int_test MEDIUMINT,
59
+ int_test INT,
60
+ big_int_test BIGINT,
61
+ float_test FLOAT(10,3),
62
+ float_zero_test FLOAT(10,3),
63
+ double_test DOUBLE(10,3),
64
+ decimal_test DECIMAL(10,3),
65
+ decimal_zero_test DECIMAL(10,3),
66
+ date_test DATE,
67
+ date_time_test DATETIME,
68
+ timestamp_test TIMESTAMP,
69
+ time_test TIME,
70
+ year_test YEAR(4),
71
+ char_test CHAR(10),
72
+ varchar_test VARCHAR(10),
73
+ binary_test BINARY(10),
74
+ varbinary_test VARBINARY(10),
75
+ tiny_blob_test TINYBLOB,
76
+ tiny_text_test TINYTEXT,
77
+ blob_test BLOB,
78
+ text_test TEXT,
79
+ medium_blob_test MEDIUMBLOB,
80
+ medium_text_test MEDIUMTEXT,
81
+ long_blob_test LONGBLOB,
82
+ long_text_test LONGTEXT,
83
+ enum_test ENUM('val1', 'val2'),
84
+ set_test SET('val1', 'val2'),
85
+ PRIMARY KEY (id)
86
+ )
87
+ ]
88
+ client.query "DELETE FROM mysql2_test;"
89
+ client.query %[
90
+ INSERT INTO mysql2_test (
91
+ null_test, bit_test, single_bit_test, tiny_int_test, bool_cast_test, small_int_test, medium_int_test, int_test, big_int_test,
92
+ float_test, float_zero_test, double_test, decimal_test, decimal_zero_test, date_test, date_time_test, timestamp_test, time_test,
93
+ year_test, char_test, varchar_test, binary_test, varbinary_test, tiny_blob_test,
94
+ tiny_text_test, blob_test, text_test, medium_blob_test, medium_text_test,
95
+ long_blob_test, long_text_test, enum_test, set_test
96
+ )
84
97
 
85
- VALUES (
86
- NULL, b'101', b'1', 1, 1, 10, 10, 10, 10,
87
- 10.3, 0, 10.3, 10.3, 0, '2010-4-4', '2010-4-4 11:44:00', '2010-4-4 11:44:00', '11:44:00',
88
- 2009, "test", "test", "test", "test", "test",
89
- "test", "test", "test", "test", "test",
90
- "test", "test", 'val1', 'val1,val2'
91
- )
92
- ]
98
+ VALUES (
99
+ NULL, b'101', b'1', 1, 1, 10, 10, 10, 10,
100
+ 10.3, 0, 10.3, 10.3, 0, '2010-4-4', '2010-4-4 11:44:00', '2010-4-4 11:44:00', '11:44:00',
101
+ 2009, "test", "test", "test", "test", "test",
102
+ "test", "test", "test", "test", "test",
103
+ "test", "test", 'val1', 'val1,val2'
104
+ )
105
+ ]
106
+ end
93
107
  end
94
108
  end
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
- set -eu
3
+ set -eux
4
4
 
5
5
  echo "
6
6
  [ ca ]