mysql2 0.4.4 → 0.5.0
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 +90 -52
- data/examples/eventmachine.rb +0 -2
- data/examples/threaded.rb +2 -4
- data/ext/mysql2/client.c +260 -76
- data/ext/mysql2/client.h +2 -47
- data/ext/mysql2/extconf.rb +44 -18
- data/ext/mysql2/mysql2_ext.c +2 -1
- data/ext/mysql2/mysql2_ext.h +8 -8
- data/ext/mysql2/result.c +23 -74
- data/ext/mysql2/statement.c +139 -63
- data/ext/mysql2/statement.h +0 -2
- data/ext/mysql2/wait_for_single_fd.h +2 -1
- data/lib/mysql2/client.rb +50 -31
- data/lib/mysql2/em.rb +2 -4
- data/lib/mysql2/error.rb +49 -20
- data/lib/mysql2/result.rb +2 -0
- data/lib/mysql2/statement.rb +3 -9
- data/lib/mysql2/version.rb +1 -1
- data/lib/mysql2.rb +14 -15
- data/spec/configuration.yml.example +0 -6
- data/spec/em/em_spec.rb +6 -6
- data/spec/mysql2/client_spec.rb +318 -237
- data/spec/mysql2/error_spec.rb +4 -10
- data/spec/mysql2/result_spec.rb +124 -158
- data/spec/mysql2/statement_spec.rb +185 -180
- data/spec/spec_helper.rb +79 -61
- data/spec/ssl/gen_certs.sh +1 -1
- data/support/5072E1F5.asc +432 -0
- data/support/mysql_enc_to_ruby.rb +2 -2
- data/support/ruby_enc_to_mysql.rb +5 -5
- metadata +16 -14
@@ -1,16 +1,17 @@
|
|
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")
|
6
|
+
end
|
7
|
+
|
8
|
+
def stmt_count
|
9
|
+
@client.query("SHOW STATUS LIKE 'Prepared_stmt_count'").first['Value'].to_i
|
7
10
|
end
|
8
11
|
|
9
12
|
it "should create a statement" do
|
10
13
|
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)
|
14
|
+
expect { statement = @client.prepare 'SELECT 1' }.to change(&method(:stmt_count)).by(1)
|
14
15
|
expect(statement).to be_an_instance_of(Mysql2::Statement)
|
15
16
|
end
|
16
17
|
|
@@ -59,6 +60,46 @@ RSpec.describe Mysql2::Statement do
|
|
59
60
|
expect(rows).to eq([{ "1" => 1 }])
|
60
61
|
end
|
61
62
|
|
63
|
+
it "should handle booleans" do
|
64
|
+
stmt = @client.prepare('SELECT ? AS `true`, ? AS `false`')
|
65
|
+
result = stmt.execute(true, false)
|
66
|
+
expect(result.to_a).to eq(['true' => 1, 'false' => 0])
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should handle bignum but in int64_t" do
|
70
|
+
stmt = @client.prepare('SELECT ? AS max, ? AS min')
|
71
|
+
int64_max = (1 << 63) - 1
|
72
|
+
int64_min = -(1 << 63)
|
73
|
+
result = stmt.execute(int64_max, int64_min)
|
74
|
+
expect(result.to_a).to eq(['max' => int64_max, 'min' => int64_min])
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should handle bignum but beyond int64_t" do
|
78
|
+
stmt = @client.prepare('SELECT ? AS max1, ? AS max2, ? AS max3, ? AS min1, ? AS min2, ? AS min3')
|
79
|
+
int64_max1 = (1 << 63)
|
80
|
+
int64_max2 = (1 << 64) - 1
|
81
|
+
int64_max3 = 1 << 64
|
82
|
+
int64_min1 = -(1 << 63) - 1
|
83
|
+
int64_min2 = -(1 << 64) + 1
|
84
|
+
int64_min3 = -0xC000000000000000
|
85
|
+
result = stmt.execute(int64_max1, int64_max2, int64_max3, int64_min1, int64_min2, int64_min3)
|
86
|
+
expect(result.to_a).to eq(['max1' => int64_max1, 'max2' => int64_max2, 'max3' => int64_max3, 'min1' => int64_min1, 'min2' => int64_min2, 'min3' => int64_min3])
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should accept keyword arguments on statement execute" do
|
90
|
+
stmt = @client.prepare 'SELECT 1 AS a'
|
91
|
+
|
92
|
+
expect(stmt.execute(as: :hash).first).to eq("a" => 1)
|
93
|
+
expect(stmt.execute(as: :array).first).to eq([1])
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should accept bind arguments and keyword arguments on statement execute" do
|
97
|
+
stmt = @client.prepare 'SELECT ? AS a'
|
98
|
+
|
99
|
+
expect(stmt.execute(1, as: :hash).first).to eq("a" => 1)
|
100
|
+
expect(stmt.execute(1, as: :array).first).to eq([1])
|
101
|
+
end
|
102
|
+
|
62
103
|
it "should keep its result after other query" do
|
63
104
|
@client.query 'USE test'
|
64
105
|
@client.query 'CREATE TABLE IF NOT EXISTS mysql2_stmt_q(a int)'
|
@@ -108,6 +149,29 @@ RSpec.describe Mysql2::Statement do
|
|
108
149
|
expect(result.first.first[1]).to be_an_instance_of(Time)
|
109
150
|
end
|
110
151
|
|
152
|
+
it "should prepare Date values" do
|
153
|
+
now = Date.today
|
154
|
+
statement = @client.prepare('SELECT ? AS a')
|
155
|
+
result = statement.execute(now)
|
156
|
+
expect(result.first['a'].to_s).to eql(now.strftime('%F'))
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should prepare Time values with microseconds" do
|
160
|
+
now = Time.now
|
161
|
+
statement = @client.prepare('SELECT ? AS a')
|
162
|
+
result = statement.execute(now)
|
163
|
+
# microseconds is six digits after the decimal, but only test on 5 significant figures
|
164
|
+
expect(result.first['a'].strftime('%F %T.%5N %z')).to eql(now.strftime('%F %T.%5N %z'))
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should prepare DateTime values with microseconds" do
|
168
|
+
now = DateTime.now
|
169
|
+
statement = @client.prepare('SELECT ? AS a')
|
170
|
+
result = statement.execute(now)
|
171
|
+
# microseconds is six digits after the decimal, but only test on 5 significant figures
|
172
|
+
expect(result.first['a'].strftime('%F %T.%5N %z')).to eql(now.strftime('%F %T.%5N %z'))
|
173
|
+
end
|
174
|
+
|
111
175
|
it "should tell us about the fields" do
|
112
176
|
statement = @client.prepare 'SELECT 1 as foo, 2'
|
113
177
|
statement.execute
|
@@ -117,22 +181,28 @@ RSpec.describe Mysql2::Statement do
|
|
117
181
|
expect(list[1]).to eq('2')
|
118
182
|
end
|
119
183
|
|
184
|
+
it "should handle as a decimal binding a BigDecimal" do
|
185
|
+
stmt = @client.prepare('SELECT ? AS decimal_test')
|
186
|
+
test_result = stmt.execute(BigDecimal("123.45")).first
|
187
|
+
expect(test_result['decimal_test']).to be_an_instance_of(BigDecimal)
|
188
|
+
expect(test_result['decimal_test']).to eql(123.45)
|
189
|
+
end
|
190
|
+
|
120
191
|
it "should update a DECIMAL value passing a BigDecimal" do
|
121
192
|
@client.query 'USE test'
|
122
193
|
@client.query 'DROP TABLE IF EXISTS mysql2_stmt_decimal_test'
|
123
194
|
@client.query 'CREATE TABLE mysql2_stmt_decimal_test (decimal_test DECIMAL(10,3))'
|
124
195
|
|
125
|
-
@client.prepare("INSERT INTO mysql2_stmt_decimal_test VALUES (?)").execute(BigDecimal
|
196
|
+
@client.prepare("INSERT INTO mysql2_stmt_decimal_test VALUES (?)").execute(BigDecimal("123.45"))
|
126
197
|
|
127
198
|
test_result = @client.query("SELECT * FROM mysql2_stmt_decimal_test").first
|
128
199
|
expect(test_result['decimal_test']).to eql(123.45)
|
129
200
|
end
|
130
201
|
|
131
202
|
it "should warn but still work if cache_rows is set to false" do
|
132
|
-
@client.query_options.merge!(:cache_rows => false)
|
133
203
|
statement = @client.prepare 'SELECT 1'
|
134
204
|
result = nil
|
135
|
-
expect { result = statement.execute.to_a }.to output(/:cache_rows is forced for prepared statements/).to_stderr
|
205
|
+
expect { result = statement.execute(cache_rows: false).to_a }.to output(/:cache_rows is forced for prepared statements/).to_stderr
|
136
206
|
expect(result.length).to eq(1)
|
137
207
|
end
|
138
208
|
|
@@ -151,7 +221,7 @@ RSpec.describe Mysql2::Statement do
|
|
151
221
|
|
152
222
|
it "should be able to retrieve utf8 field names correctly" do
|
153
223
|
stmt = @client.prepare 'SELECT * FROM `テーブル`'
|
154
|
-
expect(stmt.fields).to eq(%w
|
224
|
+
expect(stmt.fields).to eq(%w[整数 文字列])
|
155
225
|
result = stmt.execute
|
156
226
|
|
157
227
|
expect(result.to_a).to eq([{ "整数" => 1, "文字列" => "イチ" }, { "整数" => 2, "文字列" => "弐" }, { "整数" => 3, "文字列" => "さん" }])
|
@@ -175,16 +245,13 @@ RSpec.describe Mysql2::Statement do
|
|
175
245
|
|
176
246
|
expect(result.to_a).to eq([{ "整数" => 1 }])
|
177
247
|
end
|
178
|
-
end
|
248
|
+
end
|
179
249
|
|
180
250
|
context "streaming result" do
|
181
251
|
it "should be able to stream query result" do
|
182
252
|
n = 1
|
183
253
|
stmt = @client.prepare("SELECT 1 UNION SELECT 2")
|
184
|
-
|
185
|
-
@client.query_options.merge!(:stream => true, :cache_rows => false, :as => :array)
|
186
|
-
|
187
|
-
stmt.execute.each do |r|
|
254
|
+
stmt.execute(stream: true, cache_rows: false, as: :array).each do |r|
|
188
255
|
case n
|
189
256
|
when 1
|
190
257
|
expect(r).to eq([1])
|
@@ -210,23 +277,17 @@ RSpec.describe Mysql2::Statement do
|
|
210
277
|
end
|
211
278
|
|
212
279
|
it "should yield rows as hash's with symbol keys if :symbolize_keys was set to true" do
|
213
|
-
@client.
|
214
|
-
@result = @client.prepare("SELECT 1").execute
|
280
|
+
@result = @client.prepare("SELECT 1").execute(symbolize_keys: true)
|
215
281
|
@result.each do |row|
|
216
282
|
expect(row.keys.first).to be_an_instance_of(Symbol)
|
217
283
|
end
|
218
|
-
@client.query_options[:symbolize_keys] = false
|
219
284
|
end
|
220
285
|
|
221
286
|
it "should be able to return results as an array" do
|
222
|
-
@client.
|
223
|
-
|
224
|
-
@result = @client.prepare("SELECT 1").execute
|
287
|
+
@result = @client.prepare("SELECT 1").execute(as: :array)
|
225
288
|
@result.each do |row|
|
226
289
|
expect(row).to be_an_instance_of(Array)
|
227
290
|
end
|
228
|
-
|
229
|
-
@client.query_options[:as] = :hash
|
230
291
|
end
|
231
292
|
|
232
293
|
it "should cache previously yielded results by default" do
|
@@ -235,222 +296,178 @@ RSpec.describe Mysql2::Statement do
|
|
235
296
|
end
|
236
297
|
|
237
298
|
it "should yield different value for #first if streaming" do
|
238
|
-
@client.
|
239
|
-
@client.query_options[:cache_rows] = false
|
240
|
-
|
241
|
-
result = @client.prepare("SELECT 1 UNION SELECT 2").execute
|
299
|
+
result = @client.prepare("SELECT 1 UNION SELECT 2").execute(stream: true, cache_rows: true)
|
242
300
|
expect(result.first).not_to eql(result.first)
|
243
|
-
|
244
|
-
@client.query_options[:stream] = false
|
245
|
-
@client.query_options[:cache_rows] = true
|
246
301
|
end
|
247
302
|
|
248
303
|
it "should yield the same value for #first if streaming is disabled" do
|
249
|
-
@client.
|
250
|
-
result = @client.prepare("SELECT 1 UNION SELECT 2").execute
|
304
|
+
result = @client.prepare("SELECT 1 UNION SELECT 2").execute(stream: false)
|
251
305
|
expect(result.first).to eql(result.first)
|
252
306
|
end
|
253
307
|
|
254
308
|
it "should throw an exception if we try to iterate twice when streaming is enabled" do
|
255
|
-
@client.
|
256
|
-
|
257
|
-
|
258
|
-
result = @client.prepare("SELECT 1 UNION SELECT 2").execute
|
259
|
-
|
260
|
-
expect {
|
309
|
+
result = @client.prepare("SELECT 1 UNION SELECT 2").execute(stream: true, cache_rows: false)
|
310
|
+
expect do
|
261
311
|
result.each {}
|
262
312
|
result.each {}
|
263
|
-
|
264
|
-
|
265
|
-
@client.query_options[:stream] = false
|
266
|
-
@client.query_options[:cache_rows] = true
|
313
|
+
end.to raise_exception(Mysql2::Error)
|
267
314
|
end
|
268
315
|
end
|
269
316
|
|
270
317
|
context "#fields" do
|
271
|
-
before(:each) do
|
272
|
-
@client.query "USE test"
|
273
|
-
@test_result = @client.prepare("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").execute
|
274
|
-
end
|
275
|
-
|
276
318
|
it "method should exist" do
|
277
|
-
|
319
|
+
stmt = @client.prepare("SELECT 1")
|
320
|
+
expect(stmt).to respond_to(:fields)
|
278
321
|
end
|
279
322
|
|
280
323
|
it "should return an array of field names in proper order" do
|
281
|
-
|
282
|
-
expect(
|
324
|
+
stmt = @client.prepare("SELECT 'a', 'b', 'c'")
|
325
|
+
expect(stmt.fields).to eql(%w[a b c])
|
326
|
+
end
|
327
|
+
|
328
|
+
it "should return nil for statement with no result fields" do
|
329
|
+
stmt = @client.prepare("INSERT INTO mysql2_test () VALUES ()")
|
330
|
+
expect(stmt.fields).to eql(nil)
|
283
331
|
end
|
284
332
|
end
|
285
333
|
|
286
334
|
context "row data type mapping" do
|
287
|
-
|
288
|
-
@client.query "USE test"
|
289
|
-
@test_result = @client.prepare("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").execute.first
|
290
|
-
end
|
335
|
+
let(:test_result) { @client.prepare("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").execute.first }
|
291
336
|
|
292
337
|
it "should return nil for a NULL value" do
|
293
|
-
expect(
|
294
|
-
expect(
|
338
|
+
expect(test_result['null_test']).to be_an_instance_of(NilClass)
|
339
|
+
expect(test_result['null_test']).to eql(nil)
|
295
340
|
end
|
296
341
|
|
297
342
|
it "should return String for a BIT(64) value" do
|
298
|
-
expect(
|
299
|
-
expect(
|
343
|
+
expect(test_result['bit_test']).to be_an_instance_of(String)
|
344
|
+
expect(test_result['bit_test']).to eql("\000\000\000\000\000\000\000\005")
|
300
345
|
end
|
301
346
|
|
302
347
|
it "should return String for a BIT(1) value" do
|
303
|
-
expect(
|
304
|
-
expect(
|
348
|
+
expect(test_result['single_bit_test']).to be_an_instance_of(String)
|
349
|
+
expect(test_result['single_bit_test']).to eql("\001")
|
305
350
|
end
|
306
351
|
|
307
352
|
it "should return Fixnum for a TINYINT value" do
|
308
|
-
expect(
|
309
|
-
expect(
|
353
|
+
expect(num_classes).to include(test_result['tiny_int_test'].class)
|
354
|
+
expect(test_result['tiny_int_test']).to eql(1)
|
310
355
|
end
|
311
356
|
|
312
|
-
|
313
|
-
|
314
|
-
id1
|
315
|
-
@client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (0)'
|
316
|
-
|
317
|
-
|
318
|
-
id3 = @client.last_id
|
357
|
+
context "cast booleans for TINYINT if :cast_booleans is enabled" do
|
358
|
+
# rubocop:disable Style/Semicolon
|
359
|
+
let(:id1) { @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES ( 1)'; @client.last_id }
|
360
|
+
let(:id2) { @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES ( 0)'; @client.last_id }
|
361
|
+
let(:id3) { @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (-1)'; @client.last_id }
|
362
|
+
# rubocop:enable Style/Semicolon
|
319
363
|
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
expect(result1.first['bool_cast_test']).to be true
|
324
|
-
expect(result2.first['bool_cast_test']).to be false
|
325
|
-
expect(result3.first['bool_cast_test']).to be true
|
364
|
+
after do
|
365
|
+
@client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2},#{id3})"
|
366
|
+
end
|
326
367
|
|
327
|
-
|
368
|
+
it "should return TrueClass or FalseClass for a TINYINT value if :cast_booleans is enabled" do
|
369
|
+
query = @client.prepare 'SELECT bool_cast_test FROM mysql2_test WHERE id = ?'
|
370
|
+
result1 = query.execute id1, cast_booleans: true
|
371
|
+
result2 = query.execute id2, cast_booleans: true
|
372
|
+
result3 = query.execute id3, cast_booleans: true
|
373
|
+
expect(result1.first['bool_cast_test']).to be true
|
374
|
+
expect(result2.first['bool_cast_test']).to be false
|
375
|
+
expect(result3.first['bool_cast_test']).to be true
|
376
|
+
end
|
328
377
|
end
|
329
378
|
|
330
|
-
|
331
|
-
|
332
|
-
id1
|
333
|
-
@client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (0)'
|
334
|
-
|
379
|
+
context "cast booleans for BIT(1) if :cast_booleans is enabled" do
|
380
|
+
# rubocop:disable Style/Semicolon
|
381
|
+
let(:id1) { @client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (1)'; @client.last_id }
|
382
|
+
let(:id2) { @client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (0)'; @client.last_id }
|
383
|
+
# rubocop:enable Style/Semicolon
|
335
384
|
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
expect(result2.first['single_bit_test']).to be false
|
385
|
+
after do
|
386
|
+
@client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2})"
|
387
|
+
end
|
340
388
|
|
341
|
-
|
389
|
+
it "should return TrueClass or FalseClass for a BIT(1) value if :cast_booleans is enabled" do
|
390
|
+
query = @client.prepare 'SELECT single_bit_test FROM mysql2_test WHERE id = ?'
|
391
|
+
result1 = query.execute id1, cast_booleans: true
|
392
|
+
result2 = query.execute id2, cast_booleans: true
|
393
|
+
expect(result1.first['single_bit_test']).to be true
|
394
|
+
expect(result2.first['single_bit_test']).to be false
|
395
|
+
end
|
342
396
|
end
|
343
397
|
|
344
398
|
it "should return Fixnum for a SMALLINT value" do
|
345
|
-
expect(
|
346
|
-
expect(
|
399
|
+
expect(num_classes).to include(test_result['small_int_test'].class)
|
400
|
+
expect(test_result['small_int_test']).to eql(10)
|
347
401
|
end
|
348
402
|
|
349
403
|
it "should return Fixnum for a MEDIUMINT value" do
|
350
|
-
expect(
|
351
|
-
expect(
|
404
|
+
expect(num_classes).to include(test_result['medium_int_test'].class)
|
405
|
+
expect(test_result['medium_int_test']).to eql(10)
|
352
406
|
end
|
353
407
|
|
354
408
|
it "should return Fixnum for an INT value" do
|
355
|
-
expect(
|
356
|
-
expect(
|
409
|
+
expect(num_classes).to include(test_result['int_test'].class)
|
410
|
+
expect(test_result['int_test']).to eql(10)
|
357
411
|
end
|
358
412
|
|
359
413
|
it "should return Fixnum for a BIGINT value" do
|
360
|
-
expect(
|
361
|
-
expect(
|
414
|
+
expect(num_classes).to include(test_result['big_int_test'].class)
|
415
|
+
expect(test_result['big_int_test']).to eql(10)
|
362
416
|
end
|
363
417
|
|
364
418
|
it "should return Fixnum for a YEAR value" do
|
365
|
-
expect(
|
366
|
-
expect(
|
419
|
+
expect(num_classes).to include(test_result['year_test'].class)
|
420
|
+
expect(test_result['year_test']).to eql(2009)
|
367
421
|
end
|
368
422
|
|
369
423
|
it "should return BigDecimal for a DECIMAL value" do
|
370
|
-
expect(
|
371
|
-
expect(
|
424
|
+
expect(test_result['decimal_test']).to be_an_instance_of(BigDecimal)
|
425
|
+
expect(test_result['decimal_test']).to eql(10.3)
|
372
426
|
end
|
373
427
|
|
374
428
|
it "should return Float for a FLOAT value" do
|
375
|
-
expect(
|
376
|
-
expect(
|
429
|
+
expect(test_result['float_test']).to be_an_instance_of(Float)
|
430
|
+
expect(test_result['float_test']).to be_within(1e-5).of(10.3)
|
377
431
|
end
|
378
432
|
|
379
433
|
it "should return Float for a DOUBLE value" do
|
380
|
-
expect(
|
381
|
-
expect(
|
434
|
+
expect(test_result['double_test']).to be_an_instance_of(Float)
|
435
|
+
expect(test_result['double_test']).to eql(10.3)
|
382
436
|
end
|
383
437
|
|
384
438
|
it "should return Time for a DATETIME value when within the supported range" do
|
385
|
-
expect(
|
386
|
-
expect(
|
439
|
+
expect(test_result['date_time_test']).to be_an_instance_of(Time)
|
440
|
+
expect(test_result['date_time_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2010-04-04 11:44:00')
|
387
441
|
end
|
388
442
|
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
Time
|
394
|
-
end
|
395
|
-
|
396
|
-
it "should return DateTime when timestamp is < 1901-12-13 20:45:52" do
|
397
|
-
# 1901-12-13T20:45:52 is the min for 32bit Ruby 1.8
|
398
|
-
r = @client.query("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test")
|
399
|
-
expect(r.first['test']).to be_an_instance_of(klass)
|
400
|
-
end
|
401
|
-
|
402
|
-
it "should return DateTime when timestamp is > 2038-01-19T03:14:07" do
|
403
|
-
# 2038-01-19T03:14:07 is the max for 32bit Ruby 1.8
|
404
|
-
r = @client.query("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test")
|
405
|
-
expect(r.first['test']).to be_an_instance_of(klass)
|
406
|
-
end
|
407
|
-
elsif 1.size == 8 # 64bit
|
408
|
-
if RUBY_VERSION =~ /1.8/
|
409
|
-
it "should return Time when timestamp is > 0138-12-31 11:59:59" do
|
410
|
-
r = @client.query("SELECT CAST('0139-1-1 00:00:00' AS DATETIME) as test")
|
411
|
-
expect(r.first['test']).to be_an_instance_of(Time)
|
412
|
-
end
|
413
|
-
|
414
|
-
it "should return DateTime when timestamp is < 0139-1-1T00:00:00" do
|
415
|
-
r = @client.query("SELECT CAST('0138-12-31 11:59:59' AS DATETIME) as test")
|
416
|
-
expect(r.first['test']).to be_an_instance_of(DateTime)
|
417
|
-
end
|
418
|
-
|
419
|
-
it "should return Time when timestamp is > 2038-01-19T03:14:07" do
|
420
|
-
r = @client.query("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test")
|
421
|
-
expect(r.first['test']).to be_an_instance_of(Time)
|
422
|
-
end
|
423
|
-
else
|
424
|
-
it "should return Time when timestamp is < 1901-12-13 20:45:52" do
|
425
|
-
r = @client.query("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test")
|
426
|
-
expect(r.first['test']).to be_an_instance_of(Time)
|
427
|
-
end
|
443
|
+
it "should return Time when timestamp is < 1901-12-13 20:45:52" do
|
444
|
+
r = @client.prepare("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test").execute
|
445
|
+
expect(r.first['test']).to be_an_instance_of(Time)
|
446
|
+
end
|
428
447
|
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
end
|
433
|
-
end
|
448
|
+
it "should return Time when timestamp is > 2038-01-19T03:14:07" do
|
449
|
+
r = @client.prepare("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test").execute
|
450
|
+
expect(r.first['test']).to be_an_instance_of(Time)
|
434
451
|
end
|
435
452
|
|
436
453
|
it "should return Time for a TIMESTAMP value when within the supported range" do
|
437
|
-
expect(
|
438
|
-
expect(
|
454
|
+
expect(test_result['timestamp_test']).to be_an_instance_of(Time)
|
455
|
+
expect(test_result['timestamp_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2010-04-04 11:44:00')
|
439
456
|
end
|
440
457
|
|
441
458
|
it "should return Time for a TIME value" do
|
442
|
-
expect(
|
443
|
-
expect(
|
459
|
+
expect(test_result['time_test']).to be_an_instance_of(Time)
|
460
|
+
expect(test_result['time_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2000-01-01 11:44:00')
|
444
461
|
end
|
445
462
|
|
446
463
|
it "should return Date for a DATE value" do
|
447
|
-
expect(
|
448
|
-
expect(
|
464
|
+
expect(test_result['date_test']).to be_an_instance_of(Date)
|
465
|
+
expect(test_result['date_test'].strftime("%Y-%m-%d")).to eql('2010-04-04')
|
449
466
|
end
|
450
467
|
|
451
468
|
it "should return String for an ENUM value" do
|
452
|
-
expect(
|
453
|
-
expect(
|
469
|
+
expect(test_result['enum_test']).to be_an_instance_of(String)
|
470
|
+
expect(test_result['enum_test']).to eql('val1')
|
454
471
|
end
|
455
472
|
|
456
473
|
it "should raise an error given an invalid DATETIME" do
|
@@ -459,17 +476,14 @@ RSpec.describe Mysql2::Statement do
|
|
459
476
|
end
|
460
477
|
|
461
478
|
context "string encoding for ENUM values" do
|
462
|
-
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
463
|
-
|
464
479
|
it "should default to the connection's encoding if Encoding.default_internal is nil" do
|
465
480
|
with_internal_encoding nil do
|
466
481
|
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
467
482
|
expect(result['enum_test'].encoding).to eql(Encoding::UTF_8)
|
468
483
|
|
469
|
-
client2 =
|
484
|
+
client2 = new_client(encoding: 'ascii')
|
470
485
|
result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
471
486
|
expect(result['enum_test'].encoding).to eql(Encoding::US_ASCII)
|
472
|
-
client2.close
|
473
487
|
end
|
474
488
|
end
|
475
489
|
|
@@ -487,22 +501,19 @@ RSpec.describe Mysql2::Statement do
|
|
487
501
|
end
|
488
502
|
|
489
503
|
it "should return String for a SET value" do
|
490
|
-
expect(
|
491
|
-
expect(
|
504
|
+
expect(test_result['set_test']).to be_an_instance_of(String)
|
505
|
+
expect(test_result['set_test']).to eql('val1,val2')
|
492
506
|
end
|
493
507
|
|
494
508
|
context "string encoding for SET values" do
|
495
|
-
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
496
|
-
|
497
509
|
it "should default to the connection's encoding if Encoding.default_internal is nil" do
|
498
510
|
with_internal_encoding nil do
|
499
511
|
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
500
512
|
expect(result['set_test'].encoding).to eql(Encoding::UTF_8)
|
501
513
|
|
502
|
-
client2 =
|
514
|
+
client2 = new_client(encoding: 'ascii')
|
503
515
|
result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
504
516
|
expect(result['set_test'].encoding).to eql(Encoding::US_ASCII)
|
505
|
-
client2.close
|
506
517
|
end
|
507
518
|
end
|
508
519
|
|
@@ -520,13 +531,11 @@ RSpec.describe Mysql2::Statement do
|
|
520
531
|
end
|
521
532
|
|
522
533
|
it "should return String for a BINARY value" do
|
523
|
-
expect(
|
524
|
-
expect(
|
534
|
+
expect(test_result['binary_test']).to be_an_instance_of(String)
|
535
|
+
expect(test_result['binary_test']).to eql("test#{"\000" * 6}")
|
525
536
|
end
|
526
537
|
|
527
538
|
context "string encoding for BINARY values" do
|
528
|
-
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
529
|
-
|
530
539
|
it "should default to binary if Encoding.default_internal is nil" do
|
531
540
|
with_internal_encoding nil do
|
532
541
|
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
@@ -561,14 +570,12 @@ RSpec.describe Mysql2::Statement do
|
|
561
570
|
'long_text_test' => 'LONGTEXT',
|
562
571
|
}.each do |field, type|
|
563
572
|
it "should return a String for #{type}" do
|
564
|
-
expect(
|
565
|
-
expect(
|
573
|
+
expect(test_result[field]).to be_an_instance_of(String)
|
574
|
+
expect(test_result[field]).to eql("test")
|
566
575
|
end
|
567
576
|
|
568
577
|
context "string encoding for #{type} values" do
|
569
|
-
|
570
|
-
|
571
|
-
if %w(VARBINARY TINYBLOB BLOB MEDIUMBLOB LONGBLOB).include?(type)
|
578
|
+
if %w[VARBINARY TINYBLOB BLOB MEDIUMBLOB LONGBLOB].include?(type)
|
572
579
|
it "should default to binary if Encoding.default_internal is nil" do
|
573
580
|
with_internal_encoding nil do
|
574
581
|
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
@@ -593,10 +600,9 @@ RSpec.describe Mysql2::Statement do
|
|
593
600
|
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
594
601
|
expect(result[field].encoding).to eql(Encoding::UTF_8)
|
595
602
|
|
596
|
-
client2 =
|
603
|
+
client2 = new_client(encoding: 'ascii')
|
597
604
|
result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
598
605
|
expect(result[field].encoding).to eql(Encoding::US_ASCII)
|
599
|
-
client2.close
|
600
606
|
end
|
601
607
|
end
|
602
608
|
|
@@ -656,7 +662,6 @@ RSpec.describe Mysql2::Statement do
|
|
656
662
|
|
657
663
|
it 'should return number of rows affected by an insert' do
|
658
664
|
stmt = @client.prepare 'INSERT INTO lastIdTest (blah) VALUES (?)'
|
659
|
-
expect(stmt.affected_rows).to eq 0
|
660
665
|
stmt.execute 1
|
661
666
|
expect(stmt.affected_rows).to eq 1
|
662
667
|
end
|
@@ -689,9 +694,9 @@ RSpec.describe Mysql2::Statement do
|
|
689
694
|
context 'close' do
|
690
695
|
it 'should free server resources' do
|
691
696
|
stmt = @client.prepare 'SELECT 1'
|
692
|
-
|
693
|
-
|
694
|
-
|
697
|
+
GC.disable
|
698
|
+
expect { stmt.close }.to change(&method(:stmt_count)).by(-1)
|
699
|
+
GC.enable
|
695
700
|
end
|
696
701
|
|
697
702
|
it 'should raise an error on subsequent execution' do
|