mysql2 0.4.6 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +82 -52
- data/examples/eventmachine.rb +0 -2
- data/examples/threaded.rb +2 -4
- data/ext/mysql2/client.c +171 -75
- data/ext/mysql2/client.h +2 -41
- data/ext/mysql2/extconf.rb +30 -23
- data/ext/mysql2/mysql2_ext.c +2 -1
- data/ext/mysql2/mysql2_ext.h +8 -8
- data/ext/mysql2/mysql_enc_to_ruby.h +10 -0
- data/ext/mysql2/result.c +24 -77
- data/ext/mysql2/result.h +2 -3
- data/ext/mysql2/statement.c +101 -73
- data/ext/mysql2/statement.h +0 -2
- data/ext/mysql2/wait_for_single_fd.h +2 -1
- data/lib/mysql2/client.rb +37 -31
- data/lib/mysql2/em.rb +2 -4
- data/lib/mysql2/error.rb +49 -20
- data/lib/mysql2/result.rb +2 -0
- data/lib/mysql2/statement.rb +3 -9
- data/lib/mysql2/version.rb +1 -1
- data/lib/mysql2.rb +14 -15
- data/spec/em/em_spec.rb +6 -6
- data/spec/mysql2/client_spec.rb +300 -215
- data/spec/mysql2/error_spec.rb +3 -9
- data/spec/mysql2/result_spec.rb +124 -158
- data/spec/mysql2/statement_spec.rb +138 -185
- data/spec/spec_helper.rb +79 -61
- data/support/5072E1F5.asc +432 -0
- data/support/mysql_enc_to_ruby.rb +2 -2
- data/support/ruby_enc_to_mysql.rb +5 -5
- metadata +16 -14
@@ -1,12 +1,15 @@
|
|
1
|
-
# encoding: UTF-8
|
2
1
|
require './spec/spec_helper.rb'
|
3
2
|
|
4
3
|
RSpec.describe Mysql2::Statement do
|
5
4
|
before :each do
|
6
|
-
@client =
|
5
|
+
@client = new_client(encoding: "utf8")
|
7
6
|
end
|
8
7
|
|
9
8
|
def stmt_count
|
9
|
+
# Use the performance schema in MySQL 5.7 and above
|
10
|
+
@client.query("SELECT COUNT(1) AS count FROM performance_schema.prepared_statements_instances").first['count'].to_i
|
11
|
+
rescue Mysql2::Error
|
12
|
+
# Fall back to the global prepapred statement counter
|
10
13
|
@client.query("SHOW STATUS LIKE 'Prepared_stmt_count'").first['Value'].to_i
|
11
14
|
end
|
12
15
|
|
@@ -61,6 +64,12 @@ RSpec.describe Mysql2::Statement do
|
|
61
64
|
expect(rows).to eq([{ "1" => 1 }])
|
62
65
|
end
|
63
66
|
|
67
|
+
it "should handle booleans" do
|
68
|
+
stmt = @client.prepare('SELECT ? AS `true`, ? AS `false`')
|
69
|
+
result = stmt.execute(true, false)
|
70
|
+
expect(result.to_a).to eq(['true' => 1, 'false' => 0])
|
71
|
+
end
|
72
|
+
|
64
73
|
it "should handle bignum but in int64_t" do
|
65
74
|
stmt = @client.prepare('SELECT ? AS max, ? AS min')
|
66
75
|
int64_max = (1 << 63) - 1
|
@@ -81,6 +90,20 @@ RSpec.describe Mysql2::Statement do
|
|
81
90
|
expect(result.to_a).to eq(['max1' => int64_max1, 'max2' => int64_max2, 'max3' => int64_max3, 'min1' => int64_min1, 'min2' => int64_min2, 'min3' => int64_min3])
|
82
91
|
end
|
83
92
|
|
93
|
+
it "should accept keyword arguments on statement execute" do
|
94
|
+
stmt = @client.prepare 'SELECT 1 AS a'
|
95
|
+
|
96
|
+
expect(stmt.execute(as: :hash).first).to eq("a" => 1)
|
97
|
+
expect(stmt.execute(as: :array).first).to eq([1])
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should accept bind arguments and keyword arguments on statement execute" do
|
101
|
+
stmt = @client.prepare 'SELECT ? AS a'
|
102
|
+
|
103
|
+
expect(stmt.execute(1, as: :hash).first).to eq("a" => 1)
|
104
|
+
expect(stmt.execute(1, as: :array).first).to eq([1])
|
105
|
+
end
|
106
|
+
|
84
107
|
it "should keep its result after other query" do
|
85
108
|
@client.query 'USE test'
|
86
109
|
@client.query 'CREATE TABLE IF NOT EXISTS mysql2_stmt_q(a int)'
|
@@ -141,22 +164,16 @@ RSpec.describe Mysql2::Statement do
|
|
141
164
|
now = Time.now
|
142
165
|
statement = @client.prepare('SELECT ? AS a')
|
143
166
|
result = statement.execute(now)
|
144
|
-
|
145
|
-
|
146
|
-
else
|
147
|
-
expect(result.first['a'].strftime('%F %T.%6N %z')).to eql(now.strftime('%F %T.%6N %z'))
|
148
|
-
end
|
167
|
+
# microseconds is six digits after the decimal, but only test on 5 significant figures
|
168
|
+
expect(result.first['a'].strftime('%F %T.%5N %z')).to eql(now.strftime('%F %T.%5N %z'))
|
149
169
|
end
|
150
170
|
|
151
171
|
it "should prepare DateTime values with microseconds" do
|
152
172
|
now = DateTime.now
|
153
173
|
statement = @client.prepare('SELECT ? AS a')
|
154
174
|
result = statement.execute(now)
|
155
|
-
|
156
|
-
|
157
|
-
else
|
158
|
-
expect(result.first['a'].strftime('%F %T.%6N %z')).to eql(now.strftime('%F %T.%6N %z'))
|
159
|
-
end
|
175
|
+
# microseconds is six digits after the decimal, but only test on 5 significant figures
|
176
|
+
expect(result.first['a'].strftime('%F %T.%5N %z')).to eql(now.strftime('%F %T.%5N %z'))
|
160
177
|
end
|
161
178
|
|
162
179
|
it "should tell us about the fields" do
|
@@ -170,7 +187,7 @@ RSpec.describe Mysql2::Statement do
|
|
170
187
|
|
171
188
|
it "should handle as a decimal binding a BigDecimal" do
|
172
189
|
stmt = @client.prepare('SELECT ? AS decimal_test')
|
173
|
-
test_result = stmt.execute(BigDecimal
|
190
|
+
test_result = stmt.execute(BigDecimal("123.45")).first
|
174
191
|
expect(test_result['decimal_test']).to be_an_instance_of(BigDecimal)
|
175
192
|
expect(test_result['decimal_test']).to eql(123.45)
|
176
193
|
end
|
@@ -180,17 +197,16 @@ RSpec.describe Mysql2::Statement do
|
|
180
197
|
@client.query 'DROP TABLE IF EXISTS mysql2_stmt_decimal_test'
|
181
198
|
@client.query 'CREATE TABLE mysql2_stmt_decimal_test (decimal_test DECIMAL(10,3))'
|
182
199
|
|
183
|
-
@client.prepare("INSERT INTO mysql2_stmt_decimal_test VALUES (?)").execute(BigDecimal
|
200
|
+
@client.prepare("INSERT INTO mysql2_stmt_decimal_test VALUES (?)").execute(BigDecimal("123.45"))
|
184
201
|
|
185
202
|
test_result = @client.query("SELECT * FROM mysql2_stmt_decimal_test").first
|
186
203
|
expect(test_result['decimal_test']).to eql(123.45)
|
187
204
|
end
|
188
205
|
|
189
206
|
it "should warn but still work if cache_rows is set to false" do
|
190
|
-
@client.query_options.merge!(:cache_rows => false)
|
191
207
|
statement = @client.prepare 'SELECT 1'
|
192
208
|
result = nil
|
193
|
-
expect { result = statement.execute.to_a }.to output(/:cache_rows is forced for prepared statements/).to_stderr
|
209
|
+
expect { result = statement.execute(cache_rows: false).to_a }.to output(/:cache_rows is forced for prepared statements/).to_stderr
|
194
210
|
expect(result.length).to eq(1)
|
195
211
|
end
|
196
212
|
|
@@ -209,7 +225,7 @@ RSpec.describe Mysql2::Statement do
|
|
209
225
|
|
210
226
|
it "should be able to retrieve utf8 field names correctly" do
|
211
227
|
stmt = @client.prepare 'SELECT * FROM `テーブル`'
|
212
|
-
expect(stmt.fields).to eq(%w
|
228
|
+
expect(stmt.fields).to eq(%w[整数 文字列])
|
213
229
|
result = stmt.execute
|
214
230
|
|
215
231
|
expect(result.to_a).to eq([{ "整数" => 1, "文字列" => "イチ" }, { "整数" => 2, "文字列" => "弐" }, { "整数" => 3, "文字列" => "さん" }])
|
@@ -233,16 +249,13 @@ RSpec.describe Mysql2::Statement do
|
|
233
249
|
|
234
250
|
expect(result.to_a).to eq([{ "整数" => 1 }])
|
235
251
|
end
|
236
|
-
end
|
252
|
+
end
|
237
253
|
|
238
254
|
context "streaming result" do
|
239
255
|
it "should be able to stream query result" do
|
240
256
|
n = 1
|
241
257
|
stmt = @client.prepare("SELECT 1 UNION SELECT 2")
|
242
|
-
|
243
|
-
@client.query_options.merge!(:stream => true, :cache_rows => false, :as => :array)
|
244
|
-
|
245
|
-
stmt.execute.each do |r|
|
258
|
+
stmt.execute(stream: true, cache_rows: false, as: :array).each do |r|
|
246
259
|
case n
|
247
260
|
when 1
|
248
261
|
expect(r).to eq([1])
|
@@ -268,23 +281,17 @@ RSpec.describe Mysql2::Statement do
|
|
268
281
|
end
|
269
282
|
|
270
283
|
it "should yield rows as hash's with symbol keys if :symbolize_keys was set to true" do
|
271
|
-
@client.
|
272
|
-
@result = @client.prepare("SELECT 1").execute
|
284
|
+
@result = @client.prepare("SELECT 1").execute(symbolize_keys: true)
|
273
285
|
@result.each do |row|
|
274
286
|
expect(row.keys.first).to be_an_instance_of(Symbol)
|
275
287
|
end
|
276
|
-
@client.query_options[:symbolize_keys] = false
|
277
288
|
end
|
278
289
|
|
279
290
|
it "should be able to return results as an array" do
|
280
|
-
@client.
|
281
|
-
|
282
|
-
@result = @client.prepare("SELECT 1").execute
|
291
|
+
@result = @client.prepare("SELECT 1").execute(as: :array)
|
283
292
|
@result.each do |row|
|
284
293
|
expect(row).to be_an_instance_of(Array)
|
285
294
|
end
|
286
|
-
|
287
|
-
@client.query_options[:as] = :hash
|
288
295
|
end
|
289
296
|
|
290
297
|
it "should cache previously yielded results by default" do
|
@@ -293,222 +300,178 @@ RSpec.describe Mysql2::Statement do
|
|
293
300
|
end
|
294
301
|
|
295
302
|
it "should yield different value for #first if streaming" do
|
296
|
-
@client.
|
297
|
-
@client.query_options[:cache_rows] = false
|
298
|
-
|
299
|
-
result = @client.prepare("SELECT 1 UNION SELECT 2").execute
|
303
|
+
result = @client.prepare("SELECT 1 UNION SELECT 2").execute(stream: true, cache_rows: true)
|
300
304
|
expect(result.first).not_to eql(result.first)
|
301
|
-
|
302
|
-
@client.query_options[:stream] = false
|
303
|
-
@client.query_options[:cache_rows] = true
|
304
305
|
end
|
305
306
|
|
306
307
|
it "should yield the same value for #first if streaming is disabled" do
|
307
|
-
@client.
|
308
|
-
result = @client.prepare("SELECT 1 UNION SELECT 2").execute
|
308
|
+
result = @client.prepare("SELECT 1 UNION SELECT 2").execute(stream: false)
|
309
309
|
expect(result.first).to eql(result.first)
|
310
310
|
end
|
311
311
|
|
312
312
|
it "should throw an exception if we try to iterate twice when streaming is enabled" do
|
313
|
-
@client.
|
314
|
-
|
315
|
-
|
316
|
-
result = @client.prepare("SELECT 1 UNION SELECT 2").execute
|
317
|
-
|
318
|
-
expect {
|
313
|
+
result = @client.prepare("SELECT 1 UNION SELECT 2").execute(stream: true, cache_rows: false)
|
314
|
+
expect do
|
319
315
|
result.each {}
|
320
316
|
result.each {}
|
321
|
-
|
322
|
-
|
323
|
-
@client.query_options[:stream] = false
|
324
|
-
@client.query_options[:cache_rows] = true
|
317
|
+
end.to raise_exception(Mysql2::Error)
|
325
318
|
end
|
326
319
|
end
|
327
320
|
|
328
321
|
context "#fields" do
|
329
|
-
before(:each) do
|
330
|
-
@client.query "USE test"
|
331
|
-
@test_result = @client.prepare("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").execute
|
332
|
-
end
|
333
|
-
|
334
322
|
it "method should exist" do
|
335
|
-
|
323
|
+
stmt = @client.prepare("SELECT 1")
|
324
|
+
expect(stmt).to respond_to(:fields)
|
336
325
|
end
|
337
326
|
|
338
327
|
it "should return an array of field names in proper order" do
|
339
|
-
|
340
|
-
expect(
|
328
|
+
stmt = @client.prepare("SELECT 'a', 'b', 'c'")
|
329
|
+
expect(stmt.fields).to eql(%w[a b c])
|
330
|
+
end
|
331
|
+
|
332
|
+
it "should return nil for statement with no result fields" do
|
333
|
+
stmt = @client.prepare("INSERT INTO mysql2_test () VALUES ()")
|
334
|
+
expect(stmt.fields).to eql(nil)
|
341
335
|
end
|
342
336
|
end
|
343
337
|
|
344
338
|
context "row data type mapping" do
|
345
|
-
|
346
|
-
@client.query "USE test"
|
347
|
-
@test_result = @client.prepare("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").execute.first
|
348
|
-
end
|
339
|
+
let(:test_result) { @client.prepare("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").execute.first }
|
349
340
|
|
350
341
|
it "should return nil for a NULL value" do
|
351
|
-
expect(
|
352
|
-
expect(
|
342
|
+
expect(test_result['null_test']).to be_an_instance_of(NilClass)
|
343
|
+
expect(test_result['null_test']).to eql(nil)
|
353
344
|
end
|
354
345
|
|
355
346
|
it "should return String for a BIT(64) value" do
|
356
|
-
expect(
|
357
|
-
expect(
|
347
|
+
expect(test_result['bit_test']).to be_an_instance_of(String)
|
348
|
+
expect(test_result['bit_test']).to eql("\000\000\000\000\000\000\000\005")
|
358
349
|
end
|
359
350
|
|
360
351
|
it "should return String for a BIT(1) value" do
|
361
|
-
expect(
|
362
|
-
expect(
|
352
|
+
expect(test_result['single_bit_test']).to be_an_instance_of(String)
|
353
|
+
expect(test_result['single_bit_test']).to eql("\001")
|
363
354
|
end
|
364
355
|
|
365
356
|
it "should return Fixnum for a TINYINT value" do
|
366
|
-
expect(
|
367
|
-
expect(
|
357
|
+
expect(num_classes).to include(test_result['tiny_int_test'].class)
|
358
|
+
expect(test_result['tiny_int_test']).to eql(1)
|
368
359
|
end
|
369
360
|
|
370
|
-
|
371
|
-
|
372
|
-
id1
|
373
|
-
@client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (0)'
|
374
|
-
|
375
|
-
|
376
|
-
id3 = @client.last_id
|
361
|
+
context "cast booleans for TINYINT if :cast_booleans is enabled" do
|
362
|
+
# rubocop:disable Style/Semicolon
|
363
|
+
let(:id1) { @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES ( 1)'; @client.last_id }
|
364
|
+
let(:id2) { @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES ( 0)'; @client.last_id }
|
365
|
+
let(:id3) { @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (-1)'; @client.last_id }
|
366
|
+
# rubocop:enable Style/Semicolon
|
377
367
|
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
expect(result1.first['bool_cast_test']).to be true
|
382
|
-
expect(result2.first['bool_cast_test']).to be false
|
383
|
-
expect(result3.first['bool_cast_test']).to be true
|
368
|
+
after do
|
369
|
+
@client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2},#{id3})"
|
370
|
+
end
|
384
371
|
|
385
|
-
|
372
|
+
it "should return TrueClass or FalseClass for a TINYINT value if :cast_booleans is enabled" do
|
373
|
+
query = @client.prepare 'SELECT bool_cast_test FROM mysql2_test WHERE id = ?'
|
374
|
+
result1 = query.execute id1, cast_booleans: true
|
375
|
+
result2 = query.execute id2, cast_booleans: true
|
376
|
+
result3 = query.execute id3, cast_booleans: true
|
377
|
+
expect(result1.first['bool_cast_test']).to be true
|
378
|
+
expect(result2.first['bool_cast_test']).to be false
|
379
|
+
expect(result3.first['bool_cast_test']).to be true
|
380
|
+
end
|
386
381
|
end
|
387
382
|
|
388
|
-
|
389
|
-
|
390
|
-
id1
|
391
|
-
@client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (0)'
|
392
|
-
|
383
|
+
context "cast booleans for BIT(1) if :cast_booleans is enabled" do
|
384
|
+
# rubocop:disable Style/Semicolon
|
385
|
+
let(:id1) { @client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (1)'; @client.last_id }
|
386
|
+
let(:id2) { @client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (0)'; @client.last_id }
|
387
|
+
# rubocop:enable Style/Semicolon
|
393
388
|
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
expect(result2.first['single_bit_test']).to be false
|
389
|
+
after do
|
390
|
+
@client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2})"
|
391
|
+
end
|
398
392
|
|
399
|
-
|
393
|
+
it "should return TrueClass or FalseClass for a BIT(1) value if :cast_booleans is enabled" do
|
394
|
+
query = @client.prepare 'SELECT single_bit_test FROM mysql2_test WHERE id = ?'
|
395
|
+
result1 = query.execute id1, cast_booleans: true
|
396
|
+
result2 = query.execute id2, cast_booleans: true
|
397
|
+
expect(result1.first['single_bit_test']).to be true
|
398
|
+
expect(result2.first['single_bit_test']).to be false
|
399
|
+
end
|
400
400
|
end
|
401
401
|
|
402
402
|
it "should return Fixnum for a SMALLINT value" do
|
403
|
-
expect(
|
404
|
-
expect(
|
403
|
+
expect(num_classes).to include(test_result['small_int_test'].class)
|
404
|
+
expect(test_result['small_int_test']).to eql(10)
|
405
405
|
end
|
406
406
|
|
407
407
|
it "should return Fixnum for a MEDIUMINT value" do
|
408
|
-
expect(
|
409
|
-
expect(
|
408
|
+
expect(num_classes).to include(test_result['medium_int_test'].class)
|
409
|
+
expect(test_result['medium_int_test']).to eql(10)
|
410
410
|
end
|
411
411
|
|
412
412
|
it "should return Fixnum for an INT value" do
|
413
|
-
expect(
|
414
|
-
expect(
|
413
|
+
expect(num_classes).to include(test_result['int_test'].class)
|
414
|
+
expect(test_result['int_test']).to eql(10)
|
415
415
|
end
|
416
416
|
|
417
417
|
it "should return Fixnum for a BIGINT value" do
|
418
|
-
expect(
|
419
|
-
expect(
|
418
|
+
expect(num_classes).to include(test_result['big_int_test'].class)
|
419
|
+
expect(test_result['big_int_test']).to eql(10)
|
420
420
|
end
|
421
421
|
|
422
422
|
it "should return Fixnum for a YEAR value" do
|
423
|
-
expect(
|
424
|
-
expect(
|
423
|
+
expect(num_classes).to include(test_result['year_test'].class)
|
424
|
+
expect(test_result['year_test']).to eql(2009)
|
425
425
|
end
|
426
426
|
|
427
427
|
it "should return BigDecimal for a DECIMAL value" do
|
428
|
-
expect(
|
429
|
-
expect(
|
428
|
+
expect(test_result['decimal_test']).to be_an_instance_of(BigDecimal)
|
429
|
+
expect(test_result['decimal_test']).to eql(10.3)
|
430
430
|
end
|
431
431
|
|
432
432
|
it "should return Float for a FLOAT value" do
|
433
|
-
expect(
|
434
|
-
expect(
|
433
|
+
expect(test_result['float_test']).to be_an_instance_of(Float)
|
434
|
+
expect(test_result['float_test']).to be_within(1e-5).of(10.3)
|
435
435
|
end
|
436
436
|
|
437
437
|
it "should return Float for a DOUBLE value" do
|
438
|
-
expect(
|
439
|
-
expect(
|
438
|
+
expect(test_result['double_test']).to be_an_instance_of(Float)
|
439
|
+
expect(test_result['double_test']).to eql(10.3)
|
440
440
|
end
|
441
441
|
|
442
442
|
it "should return Time for a DATETIME value when within the supported range" do
|
443
|
-
expect(
|
444
|
-
expect(
|
443
|
+
expect(test_result['date_time_test']).to be_an_instance_of(Time)
|
444
|
+
expect(test_result['date_time_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2010-04-04 11:44:00')
|
445
445
|
end
|
446
446
|
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
Time
|
452
|
-
end
|
453
|
-
|
454
|
-
it "should return DateTime when timestamp is < 1901-12-13 20:45:52" do
|
455
|
-
# 1901-12-13T20:45:52 is the min for 32bit Ruby 1.8
|
456
|
-
r = @client.query("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test")
|
457
|
-
expect(r.first['test']).to be_an_instance_of(klass)
|
458
|
-
end
|
459
|
-
|
460
|
-
it "should return DateTime when timestamp is > 2038-01-19T03:14:07" do
|
461
|
-
# 2038-01-19T03:14:07 is the max for 32bit Ruby 1.8
|
462
|
-
r = @client.query("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test")
|
463
|
-
expect(r.first['test']).to be_an_instance_of(klass)
|
464
|
-
end
|
465
|
-
elsif 1.size == 8 # 64bit
|
466
|
-
if RUBY_VERSION =~ /1.8/
|
467
|
-
it "should return Time when timestamp is > 0138-12-31 11:59:59" do
|
468
|
-
r = @client.query("SELECT CAST('0139-1-1 00:00:00' AS DATETIME) as test")
|
469
|
-
expect(r.first['test']).to be_an_instance_of(Time)
|
470
|
-
end
|
471
|
-
|
472
|
-
it "should return DateTime when timestamp is < 0139-1-1T00:00:00" do
|
473
|
-
r = @client.query("SELECT CAST('0138-12-31 11:59:59' AS DATETIME) as test")
|
474
|
-
expect(r.first['test']).to be_an_instance_of(DateTime)
|
475
|
-
end
|
476
|
-
|
477
|
-
it "should return Time when timestamp is > 2038-01-19T03:14:07" do
|
478
|
-
r = @client.query("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test")
|
479
|
-
expect(r.first['test']).to be_an_instance_of(Time)
|
480
|
-
end
|
481
|
-
else
|
482
|
-
it "should return Time when timestamp is < 1901-12-13 20:45:52" do
|
483
|
-
r = @client.query("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test")
|
484
|
-
expect(r.first['test']).to be_an_instance_of(Time)
|
485
|
-
end
|
447
|
+
it "should return Time when timestamp is < 1901-12-13 20:45:52" do
|
448
|
+
r = @client.prepare("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test").execute
|
449
|
+
expect(r.first['test']).to be_an_instance_of(Time)
|
450
|
+
end
|
486
451
|
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
end
|
491
|
-
end
|
452
|
+
it "should return Time when timestamp is > 2038-01-19T03:14:07" do
|
453
|
+
r = @client.prepare("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test").execute
|
454
|
+
expect(r.first['test']).to be_an_instance_of(Time)
|
492
455
|
end
|
493
456
|
|
494
457
|
it "should return Time for a TIMESTAMP value when within the supported range" do
|
495
|
-
expect(
|
496
|
-
expect(
|
458
|
+
expect(test_result['timestamp_test']).to be_an_instance_of(Time)
|
459
|
+
expect(test_result['timestamp_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2010-04-04 11:44:00')
|
497
460
|
end
|
498
461
|
|
499
462
|
it "should return Time for a TIME value" do
|
500
|
-
expect(
|
501
|
-
expect(
|
463
|
+
expect(test_result['time_test']).to be_an_instance_of(Time)
|
464
|
+
expect(test_result['time_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2000-01-01 11:44:00')
|
502
465
|
end
|
503
466
|
|
504
467
|
it "should return Date for a DATE value" do
|
505
|
-
expect(
|
506
|
-
expect(
|
468
|
+
expect(test_result['date_test']).to be_an_instance_of(Date)
|
469
|
+
expect(test_result['date_test'].strftime("%Y-%m-%d")).to eql('2010-04-04')
|
507
470
|
end
|
508
471
|
|
509
472
|
it "should return String for an ENUM value" do
|
510
|
-
expect(
|
511
|
-
expect(
|
473
|
+
expect(test_result['enum_test']).to be_an_instance_of(String)
|
474
|
+
expect(test_result['enum_test']).to eql('val1')
|
512
475
|
end
|
513
476
|
|
514
477
|
it "should raise an error given an invalid DATETIME" do
|
@@ -517,17 +480,14 @@ RSpec.describe Mysql2::Statement do
|
|
517
480
|
end
|
518
481
|
|
519
482
|
context "string encoding for ENUM values" do
|
520
|
-
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
521
|
-
|
522
483
|
it "should default to the connection's encoding if Encoding.default_internal is nil" do
|
523
484
|
with_internal_encoding nil do
|
524
485
|
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
525
486
|
expect(result['enum_test'].encoding).to eql(Encoding::UTF_8)
|
526
487
|
|
527
|
-
client2 =
|
488
|
+
client2 = new_client(encoding: 'ascii')
|
528
489
|
result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
529
490
|
expect(result['enum_test'].encoding).to eql(Encoding::US_ASCII)
|
530
|
-
client2.close
|
531
491
|
end
|
532
492
|
end
|
533
493
|
|
@@ -545,22 +505,19 @@ RSpec.describe Mysql2::Statement do
|
|
545
505
|
end
|
546
506
|
|
547
507
|
it "should return String for a SET value" do
|
548
|
-
expect(
|
549
|
-
expect(
|
508
|
+
expect(test_result['set_test']).to be_an_instance_of(String)
|
509
|
+
expect(test_result['set_test']).to eql('val1,val2')
|
550
510
|
end
|
551
511
|
|
552
512
|
context "string encoding for SET values" do
|
553
|
-
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
554
|
-
|
555
513
|
it "should default to the connection's encoding if Encoding.default_internal is nil" do
|
556
514
|
with_internal_encoding nil do
|
557
515
|
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
558
516
|
expect(result['set_test'].encoding).to eql(Encoding::UTF_8)
|
559
517
|
|
560
|
-
client2 =
|
518
|
+
client2 = new_client(encoding: 'ascii')
|
561
519
|
result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
562
520
|
expect(result['set_test'].encoding).to eql(Encoding::US_ASCII)
|
563
|
-
client2.close
|
564
521
|
end
|
565
522
|
end
|
566
523
|
|
@@ -578,13 +535,11 @@ RSpec.describe Mysql2::Statement do
|
|
578
535
|
end
|
579
536
|
|
580
537
|
it "should return String for a BINARY value" do
|
581
|
-
expect(
|
582
|
-
expect(
|
538
|
+
expect(test_result['binary_test']).to be_an_instance_of(String)
|
539
|
+
expect(test_result['binary_test']).to eql("test#{"\000" * 6}")
|
583
540
|
end
|
584
541
|
|
585
542
|
context "string encoding for BINARY values" do
|
586
|
-
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
587
|
-
|
588
543
|
it "should default to binary if Encoding.default_internal is nil" do
|
589
544
|
with_internal_encoding nil do
|
590
545
|
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
@@ -619,14 +574,12 @@ RSpec.describe Mysql2::Statement do
|
|
619
574
|
'long_text_test' => 'LONGTEXT',
|
620
575
|
}.each do |field, type|
|
621
576
|
it "should return a String for #{type}" do
|
622
|
-
expect(
|
623
|
-
expect(
|
577
|
+
expect(test_result[field]).to be_an_instance_of(String)
|
578
|
+
expect(test_result[field]).to eql("test")
|
624
579
|
end
|
625
580
|
|
626
581
|
context "string encoding for #{type} values" do
|
627
|
-
|
628
|
-
|
629
|
-
if %w(VARBINARY TINYBLOB BLOB MEDIUMBLOB LONGBLOB).include?(type)
|
582
|
+
if %w[VARBINARY TINYBLOB BLOB MEDIUMBLOB LONGBLOB].include?(type)
|
630
583
|
it "should default to binary if Encoding.default_internal is nil" do
|
631
584
|
with_internal_encoding nil do
|
632
585
|
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
@@ -651,10 +604,9 @@ RSpec.describe Mysql2::Statement do
|
|
651
604
|
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
652
605
|
expect(result[field].encoding).to eql(Encoding::UTF_8)
|
653
606
|
|
654
|
-
client2 =
|
607
|
+
client2 = new_client(encoding: 'ascii')
|
655
608
|
result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
656
609
|
expect(result[field].encoding).to eql(Encoding::US_ASCII)
|
657
|
-
client2.close
|
658
610
|
end
|
659
611
|
end
|
660
612
|
|
@@ -714,7 +666,6 @@ RSpec.describe Mysql2::Statement do
|
|
714
666
|
|
715
667
|
it 'should return number of rows affected by an insert' do
|
716
668
|
stmt = @client.prepare 'INSERT INTO lastIdTest (blah) VALUES (?)'
|
717
|
-
expect(stmt.affected_rows).to eq 0
|
718
669
|
stmt.execute 1
|
719
670
|
expect(stmt.affected_rows).to eq 1
|
720
671
|
end
|
@@ -747,7 +698,9 @@ RSpec.describe Mysql2::Statement do
|
|
747
698
|
context 'close' do
|
748
699
|
it 'should free server resources' do
|
749
700
|
stmt = @client.prepare 'SELECT 1'
|
701
|
+
GC.disable
|
750
702
|
expect { stmt.close }.to change(&method(:stmt_count)).by(-1)
|
703
|
+
GC.enable
|
751
704
|
end
|
752
705
|
|
753
706
|
it 'should raise an error on subsequent execution' do
|