mysql2 0.4.2 → 0.4.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,6 +22,10 @@ RSpec.describe Mysql2::Result do
22
22
  expect(@result).to respond_to(:each)
23
23
  end
24
24
 
25
+ it "should respond to #free" do
26
+ expect(@result).to respond_to(:free)
27
+ end
28
+
25
29
  it "should raise a Mysql2::Error exception upon a bad query" do
26
30
  expect {
27
31
  @client.query "bad sql"
@@ -78,6 +82,11 @@ RSpec.describe Mysql2::Result do
78
82
  expect(result.first.object_id).not_to eql(result.first.object_id)
79
83
  end
80
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
+
81
90
  it "should yield different value for #first if streaming" do
82
91
  result = @client.query "SELECT 1 UNION SELECT 2", :stream => true, :cache_rows => false
83
92
  expect(result.first).not_to eql(result.first)
@@ -144,18 +153,16 @@ RSpec.describe Mysql2::Result do
144
153
  end
145
154
 
146
155
  it "should raise an exception if streaming ended due to a timeout" do
147
- # Create an extra client instance, since we're going to time it out
148
- client = Mysql2::Client.new DatabaseCredentials['root']
149
- client.query "CREATE TEMPORARY TABLE streamingTest (val BINARY(255)) ENGINE=MEMORY"
156
+ @client.query "CREATE TEMPORARY TABLE streamingTest (val BINARY(255)) ENGINE=MEMORY"
150
157
 
151
158
  # Insert enough records to force the result set into multiple reads
152
159
  # (the BINARY type is used simply because it forces full width results)
153
160
  10000.times do |i|
154
- client.query "INSERT INTO streamingTest (val) VALUES ('Foo #{i}')"
161
+ @client.query "INSERT INTO streamingTest (val) VALUES ('Foo #{i}')"
155
162
  end
156
163
 
157
- client.query "SET net_write_timeout = 1"
158
- 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
159
166
 
160
167
  expect {
161
168
  res.each_with_index do |_, i|
@@ -201,36 +208,43 @@ RSpec.describe Mysql2::Result do
201
208
  expect(@test_result['tiny_int_test']).to eql(1)
202
209
  end
203
210
 
204
- it "should return TrueClass or FalseClass for a TINYINT value if :cast_booleans is enabled" do
205
- @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (1)'
206
- id1 = @client.last_id
207
- @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (0)'
208
- id2 = @client.last_id
209
- @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (-1)'
210
- 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
211
217
 
212
- result1 = @client.query 'SELECT bool_cast_test FROM mysql2_test WHERE bool_cast_test = 1 LIMIT 1', :cast_booleans => true
213
- result2 = @client.query 'SELECT bool_cast_test FROM mysql2_test WHERE bool_cast_test = 0 LIMIT 1', :cast_booleans => true
214
- result3 = @client.query 'SELECT bool_cast_test FROM mysql2_test WHERE bool_cast_test = -1 LIMIT 1', :cast_booleans => true
215
- expect(result1.first['bool_cast_test']).to be true
216
- expect(result2.first['bool_cast_test']).to be false
217
- 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
218
221
 
219
- @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
220
230
  end
221
231
 
222
- it "should return TrueClass or FalseClass for a BIT(1) value if :cast_booleans is enabled" do
223
- @client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (1)'
224
- id1 = @client.last_id
225
- @client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (0)'
226
- 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
227
237
 
228
- result1 = @client.query "SELECT single_bit_test FROM mysql2_test WHERE id = #{id1}", :cast_booleans => true
229
- result2 = @client.query "SELECT single_bit_test FROM mysql2_test WHERE id = #{id2}", :cast_booleans => true
230
- expect(result1.first['single_bit_test']).to be true
231
- 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
232
241
 
233
- @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
234
248
  end
235
249
 
236
250
  it "should return Fixnum for a SMALLINT value" do
@@ -278,6 +292,30 @@ RSpec.describe Mysql2::Result do
278
292
  expect(@test_result['date_time_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2010-04-04 11:44:00')
279
293
  end
280
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
+
281
319
  if 1.size == 4 # 32bit
282
320
  klass = if RUBY_VERSION =~ /1.8/
283
321
  DateTime
@@ -358,10 +396,9 @@ RSpec.describe Mysql2::Result do
358
396
  result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
359
397
  expect(result['enum_test'].encoding).to eql(Encoding::UTF_8)
360
398
 
361
- client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
399
+ client2 = new_client(:encoding => 'ascii')
362
400
  result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
363
401
  expect(result['enum_test'].encoding).to eql(Encoding::ASCII)
364
- client2.close
365
402
  end
366
403
  end
367
404
 
@@ -391,10 +428,9 @@ RSpec.describe Mysql2::Result do
391
428
  result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
392
429
  expect(result['set_test'].encoding).to eql(Encoding::UTF_8)
393
430
 
394
- client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
431
+ client2 = new_client(:encoding => 'ascii')
395
432
  result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
396
433
  expect(result['set_test'].encoding).to eql(Encoding::ASCII)
397
- client2.close
398
434
  end
399
435
  end
400
436
 
@@ -485,10 +521,9 @@ RSpec.describe Mysql2::Result do
485
521
  result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
486
522
  expect(result[field].encoding).to eql(Encoding::UTF_8)
487
523
 
488
- client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
524
+ client2 = new_client(:encoding => 'ascii')
489
525
  result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
490
526
  expect(result[field].encoding).to eql(Encoding::ASCII)
491
- client2.close
492
527
  end
493
528
  end
494
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,32 @@ 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
+
186
+ it "should update a DECIMAL value passing a BigDecimal" do
187
+ @client.query 'USE test'
188
+ @client.query 'DROP TABLE IF EXISTS mysql2_stmt_decimal_test'
189
+ @client.query 'CREATE TABLE mysql2_stmt_decimal_test (decimal_test DECIMAL(10,3))'
190
+
191
+ @client.prepare("INSERT INTO mysql2_stmt_decimal_test VALUES (?)").execute(BigDecimal.new("123.45"))
192
+
193
+ test_result = @client.query("SELECT * FROM mysql2_stmt_decimal_test").first
194
+ expect(test_result['decimal_test']).to eql(123.45)
195
+ end
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
+
120
205
  context "utf8_db" do
121
206
  before(:each) do
122
207
  @client.query("DROP DATABASE IF EXISTS test_mysql2_stmt_utf8")
@@ -249,18 +334,19 @@ RSpec.describe Mysql2::Statement do
249
334
  end
250
335
 
251
336
  context "#fields" do
252
- before(:each) do
253
- @client.query "USE test"
254
- @test_result = @client.prepare("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").execute
255
- end
256
-
257
337
  it "method should exist" do
258
- expect(@test_result).to respond_to(:fields)
338
+ stmt = @client.prepare("SELECT 1")
339
+ expect(stmt).to respond_to(:fields)
259
340
  end
260
341
 
261
342
  it "should return an array of field names in proper order" do
262
- result = @client.prepare("SELECT 'a', 'b', 'c'").execute
263
- 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)
264
350
  end
265
351
  end
266
352
 
@@ -290,36 +376,47 @@ RSpec.describe Mysql2::Statement do
290
376
  expect(@test_result['tiny_int_test']).to eql(1)
291
377
  end
292
378
 
293
- it "should return TrueClass or FalseClass for a TINYINT value if :cast_booleans is enabled" do
294
- @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (1)'
295
- id1 = @client.last_id
296
- @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (0)'
297
- id2 = @client.last_id
298
- @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (-1)'
299
- 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
300
386
 
301
- result1 = @client.query 'SELECT bool_cast_test FROM mysql2_test WHERE bool_cast_test = 1 LIMIT 1', :cast_booleans => true
302
- result2 = @client.query 'SELECT bool_cast_test FROM mysql2_test WHERE bool_cast_test = 0 LIMIT 1', :cast_booleans => true
303
- result3 = @client.query 'SELECT bool_cast_test FROM mysql2_test WHERE bool_cast_test = -1 LIMIT 1', :cast_booleans => true
304
- expect(result1.first['bool_cast_test']).to be true
305
- expect(result2.first['bool_cast_test']).to be false
306
- 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
307
390
 
308
- @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
309
400
  end
310
401
 
311
- it "should return TrueClass or FalseClass for a BIT(1) value if :cast_booleans is enabled" do
312
- @client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (1)'
313
- id1 = @client.last_id
314
- @client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (0)'
315
- 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
316
408
 
317
- result1 = @client.query "SELECT single_bit_test FROM mysql2_test WHERE id = #{id1}", :cast_booleans => true
318
- result2 = @client.query "SELECT single_bit_test FROM mysql2_test WHERE id = #{id2}", :cast_booleans => true
319
- expect(result1.first['single_bit_test']).to be true
320
- 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
321
412
 
322
- @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
323
420
  end
324
421
 
325
422
  it "should return Fixnum for a SMALLINT value" do
@@ -376,39 +473,39 @@ RSpec.describe Mysql2::Statement do
376
473
 
377
474
  it "should return DateTime when timestamp is < 1901-12-13 20:45:52" do
378
475
  # 1901-12-13T20:45:52 is the min for 32bit Ruby 1.8
379
- 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
380
477
  expect(r.first['test']).to be_an_instance_of(klass)
381
478
  end
382
479
 
383
480
  it "should return DateTime when timestamp is > 2038-01-19T03:14:07" do
384
481
  # 2038-01-19T03:14:07 is the max for 32bit Ruby 1.8
385
- 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
386
483
  expect(r.first['test']).to be_an_instance_of(klass)
387
484
  end
388
485
  elsif 1.size == 8 # 64bit
389
486
  if RUBY_VERSION =~ /1.8/
390
487
  it "should return Time when timestamp is > 0138-12-31 11:59:59" do
391
- 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
392
489
  expect(r.first['test']).to be_an_instance_of(Time)
393
490
  end
394
491
 
395
492
  it "should return DateTime when timestamp is < 0139-1-1T00:00:00" do
396
- 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
397
494
  expect(r.first['test']).to be_an_instance_of(DateTime)
398
495
  end
399
496
 
400
497
  it "should return Time when timestamp is > 2038-01-19T03:14:07" do
401
- 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
402
499
  expect(r.first['test']).to be_an_instance_of(Time)
403
500
  end
404
501
  else
405
502
  it "should return Time when timestamp is < 1901-12-13 20:45:52" do
406
- 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
407
504
  expect(r.first['test']).to be_an_instance_of(Time)
408
505
  end
409
506
 
410
507
  it "should return Time when timestamp is > 2038-01-19T03:14:07" do
411
- 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
412
509
  expect(r.first['test']).to be_an_instance_of(Time)
413
510
  end
414
511
  end
@@ -447,10 +544,9 @@ RSpec.describe Mysql2::Statement do
447
544
  result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
448
545
  expect(result['enum_test'].encoding).to eql(Encoding::UTF_8)
449
546
 
450
- client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
547
+ client2 = new_client(:encoding => 'ascii')
451
548
  result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
452
549
  expect(result['enum_test'].encoding).to eql(Encoding::US_ASCII)
453
- client2.close
454
550
  end
455
551
  end
456
552
 
@@ -480,10 +576,9 @@ RSpec.describe Mysql2::Statement do
480
576
  result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
481
577
  expect(result['set_test'].encoding).to eql(Encoding::UTF_8)
482
578
 
483
- client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
579
+ client2 = new_client(:encoding => 'ascii')
484
580
  result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
485
581
  expect(result['set_test'].encoding).to eql(Encoding::US_ASCII)
486
- client2.close
487
582
  end
488
583
  end
489
584
 
@@ -574,10 +669,9 @@ RSpec.describe Mysql2::Statement do
574
669
  result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
575
670
  expect(result[field].encoding).to eql(Encoding::UTF_8)
576
671
 
577
- client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
672
+ client2 = new_client(:encoding => 'ascii')
578
673
  result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
579
674
  expect(result[field].encoding).to eql(Encoding::US_ASCII)
580
- client2.close
581
675
  end
582
676
  end
583
677
 
@@ -670,9 +764,7 @@ RSpec.describe Mysql2::Statement do
670
764
  context 'close' do
671
765
  it 'should free server resources' do
672
766
  stmt = @client.prepare 'SELECT 1'
673
- expect { stmt.close }.to change {
674
- @client.query("SHOW STATUS LIKE 'Prepared_stmt_count'").first['Value'].to_i
675
- }.by(-1)
767
+ expect { stmt.close }.to change(&method(:stmt_count)).by(-1)
676
768
  end
677
769
 
678
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 ]