mysql2 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/examples/eventmachine.rb +1 -1
- data/ext/mysql2/client.c +45 -44
- data/ext/mysql2/client.h +1 -2
- data/ext/mysql2/extconf.rb +59 -37
- data/ext/mysql2/infile.c +2 -2
- data/ext/mysql2/mysql2_ext.h +4 -6
- data/ext/mysql2/mysql_enc_name_to_ruby.h +8 -8
- data/ext/mysql2/mysql_enc_to_ruby.h +25 -22
- data/ext/mysql2/result.c +4 -16
- data/ext/mysql2/result.h +3 -3
- data/ext/mysql2/statement.c +79 -42
- data/ext/mysql2/statement.h +2 -6
- data/lib/mysql2.rb +36 -18
- data/lib/mysql2/client.rb +28 -27
- data/lib/mysql2/console.rb +1 -1
- data/lib/mysql2/em.rb +5 -6
- data/lib/mysql2/error.rb +10 -7
- data/lib/mysql2/field.rb +1 -2
- data/lib/mysql2/statement.rb +12 -0
- data/lib/mysql2/version.rb +1 -1
- data/spec/em/em_spec.rb +8 -8
- data/spec/mysql2/client_spec.rb +62 -37
- data/spec/mysql2/result_spec.rb +48 -48
- data/spec/mysql2/statement_spec.rb +143 -57
- data/spec/ssl/ca-cert.pem +17 -0
- data/spec/ssl/ca-key.pem +27 -0
- data/spec/ssl/ca.cnf +22 -0
- data/spec/ssl/cert.cnf +22 -0
- data/spec/ssl/client-cert.pem +17 -0
- data/spec/ssl/client-key.pem +27 -0
- data/spec/ssl/client-req.pem +15 -0
- data/spec/ssl/gen_certs.sh +48 -0
- data/spec/ssl/pkcs8-client-key.pem +28 -0
- data/spec/ssl/pkcs8-server-key.pem +28 -0
- data/spec/ssl/server-cert.pem +17 -0
- data/spec/ssl/server-key.pem +27 -0
- data/spec/ssl/server-req.pem +15 -0
- data/support/mysql_enc_to_ruby.rb +7 -8
- data/support/ruby_enc_to_mysql.rb +1 -1
- metadata +28 -2
data/spec/mysql2/result_spec.rb
CHANGED
@@ -53,19 +53,19 @@ RSpec.describe Mysql2::Result do
|
|
53
53
|
context "#each" do
|
54
54
|
it "should yield rows as hash's" do
|
55
55
|
@result.each do |row|
|
56
|
-
expect(row
|
56
|
+
expect(row).to be_an_instance_of(Hash)
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
60
|
it "should yield rows as hash's with symbol keys if :symbolize_keys was set to true" do
|
61
61
|
@result.each(:symbolize_keys => true) do |row|
|
62
|
-
expect(row.keys.first
|
62
|
+
expect(row.keys.first).to be_an_instance_of(Symbol)
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
66
|
it "should be able to return results as an array" do
|
67
67
|
@result.each(:as => :array) do |row|
|
68
|
-
expect(row
|
68
|
+
expect(row).to be_an_instance_of(Array)
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
@@ -109,7 +109,7 @@ RSpec.describe Mysql2::Result do
|
|
109
109
|
|
110
110
|
it "should return an array of field names in proper order" do
|
111
111
|
result = @client.query "SELECT 'a', 'b', 'c'"
|
112
|
-
expect(result.fields).to eql(
|
112
|
+
expect(result.fields).to eql(%w(a b c))
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
@@ -132,7 +132,7 @@ RSpec.describe Mysql2::Result do
|
|
132
132
|
|
133
133
|
it "should not yield nil at the end of streaming" do
|
134
134
|
result = @client.query('SELECT * FROM mysql2_test', :stream => true, :cache_rows => false)
|
135
|
-
result.each { |r| expect(r).not_to be_nil}
|
135
|
+
result.each { |r| expect(r).not_to be_nil }
|
136
136
|
end
|
137
137
|
|
138
138
|
it "#count should be zero for rows after streaming when there were no results" do
|
@@ -158,7 +158,7 @@ RSpec.describe Mysql2::Result do
|
|
158
158
|
res = client.query "SELECT * FROM streamingTest", :stream => true, :cache_rows => false
|
159
159
|
|
160
160
|
expect {
|
161
|
-
res.each_with_index do |
|
161
|
+
res.each_with_index do |_, i|
|
162
162
|
# Exhaust the first result packet then trigger a timeout
|
163
163
|
sleep 2 if i > 0 && i % 1000 == 0
|
164
164
|
end
|
@@ -174,25 +174,25 @@ RSpec.describe Mysql2::Result do
|
|
174
174
|
it "should return nil values for NULL and strings for everything else when :cast is false" do
|
175
175
|
result = @client.query('SELECT null_test, tiny_int_test, bool_cast_test, int_test, date_test, enum_test FROM mysql2_test WHERE bool_cast_test = 1 LIMIT 1', :cast => false).first
|
176
176
|
expect(result["null_test"]).to be_nil
|
177
|
-
expect(result["tiny_int_test"]).to
|
177
|
+
expect(result["tiny_int_test"]).to eql("1")
|
178
178
|
expect(result["bool_cast_test"]).to eql("1")
|
179
|
-
expect(result["int_test"]).to
|
180
|
-
expect(result["date_test"]).to
|
181
|
-
expect(result["enum_test"]).to
|
179
|
+
expect(result["int_test"]).to eql("10")
|
180
|
+
expect(result["date_test"]).to eql("2010-04-04")
|
181
|
+
expect(result["enum_test"]).to eql("val1")
|
182
182
|
end
|
183
183
|
|
184
184
|
it "should return nil for a NULL value" do
|
185
|
-
expect(@test_result['null_test']
|
185
|
+
expect(@test_result['null_test']).to be_an_instance_of(NilClass)
|
186
186
|
expect(@test_result['null_test']).to eql(nil)
|
187
187
|
end
|
188
188
|
|
189
189
|
it "should return String for a BIT(64) value" do
|
190
|
-
expect(@test_result['bit_test']
|
190
|
+
expect(@test_result['bit_test']).to be_an_instance_of(String)
|
191
191
|
expect(@test_result['bit_test']).to eql("\000\000\000\000\000\000\000\005")
|
192
192
|
end
|
193
193
|
|
194
194
|
it "should return String for a BIT(1) value" do
|
195
|
-
expect(@test_result['single_bit_test']
|
195
|
+
expect(@test_result['single_bit_test']).to be_an_instance_of(String)
|
196
196
|
expect(@test_result['single_bit_test']).to eql("\001")
|
197
197
|
end
|
198
198
|
|
@@ -259,89 +259,89 @@ RSpec.describe Mysql2::Result do
|
|
259
259
|
end
|
260
260
|
|
261
261
|
it "should return BigDecimal for a DECIMAL value" do
|
262
|
-
expect(@test_result['decimal_test']
|
262
|
+
expect(@test_result['decimal_test']).to be_an_instance_of(BigDecimal)
|
263
263
|
expect(@test_result['decimal_test']).to eql(10.3)
|
264
264
|
end
|
265
265
|
|
266
266
|
it "should return Float for a FLOAT value" do
|
267
|
-
expect(@test_result['float_test']
|
267
|
+
expect(@test_result['float_test']).to be_an_instance_of(Float)
|
268
268
|
expect(@test_result['float_test']).to eql(10.3)
|
269
269
|
end
|
270
270
|
|
271
271
|
it "should return Float for a DOUBLE value" do
|
272
|
-
expect(@test_result['double_test']
|
272
|
+
expect(@test_result['double_test']).to be_an_instance_of(Float)
|
273
273
|
expect(@test_result['double_test']).to eql(10.3)
|
274
274
|
end
|
275
275
|
|
276
276
|
it "should return Time for a DATETIME value when within the supported range" do
|
277
|
-
expect(@test_result['date_time_test']
|
277
|
+
expect(@test_result['date_time_test']).to be_an_instance_of(Time)
|
278
278
|
expect(@test_result['date_time_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2010-04-04 11:44:00')
|
279
279
|
end
|
280
280
|
|
281
281
|
if 1.size == 4 # 32bit
|
282
|
-
|
283
|
-
|
282
|
+
klass = if RUBY_VERSION =~ /1.8/
|
283
|
+
DateTime
|
284
284
|
else
|
285
|
-
|
285
|
+
Time
|
286
286
|
end
|
287
287
|
|
288
288
|
it "should return DateTime when timestamp is < 1901-12-13 20:45:52" do
|
289
|
-
|
289
|
+
# 1901-12-13T20:45:52 is the min for 32bit Ruby 1.8
|
290
290
|
r = @client.query("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test")
|
291
|
-
expect(r.first['test']
|
291
|
+
expect(r.first['test']).to be_an_instance_of(klass)
|
292
292
|
end
|
293
293
|
|
294
294
|
it "should return DateTime when timestamp is > 2038-01-19T03:14:07" do
|
295
|
-
|
295
|
+
# 2038-01-19T03:14:07 is the max for 32bit Ruby 1.8
|
296
296
|
r = @client.query("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test")
|
297
|
-
expect(r.first['test']
|
297
|
+
expect(r.first['test']).to be_an_instance_of(klass)
|
298
298
|
end
|
299
299
|
elsif 1.size == 8 # 64bit
|
300
|
-
|
301
|
-
it "should return Time when timestamp is < 1901-12-13 20:45:52" do
|
302
|
-
r = @client.query("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test")
|
303
|
-
expect(r.first['test'].class).to eql(Time)
|
304
|
-
end
|
305
|
-
|
306
|
-
it "should return Time when timestamp is > 2038-01-19T03:14:07" do
|
307
|
-
r = @client.query("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test")
|
308
|
-
expect(r.first['test'].class).to eql(Time)
|
309
|
-
end
|
310
|
-
else
|
300
|
+
if RUBY_VERSION =~ /1.8/
|
311
301
|
it "should return Time when timestamp is > 0138-12-31 11:59:59" do
|
312
302
|
r = @client.query("SELECT CAST('0139-1-1 00:00:00' AS DATETIME) as test")
|
313
|
-
expect(r.first['test']
|
303
|
+
expect(r.first['test']).to be_an_instance_of(Time)
|
314
304
|
end
|
315
305
|
|
316
306
|
it "should return DateTime when timestamp is < 0139-1-1T00:00:00" do
|
317
307
|
r = @client.query("SELECT CAST('0138-12-31 11:59:59' AS DATETIME) as test")
|
318
|
-
expect(r.first['test']
|
308
|
+
expect(r.first['test']).to be_an_instance_of(DateTime)
|
309
|
+
end
|
310
|
+
|
311
|
+
it "should return Time when timestamp is > 2038-01-19T03:14:07" do
|
312
|
+
r = @client.query("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test")
|
313
|
+
expect(r.first['test']).to be_an_instance_of(Time)
|
314
|
+
end
|
315
|
+
else
|
316
|
+
it "should return Time when timestamp is < 1901-12-13 20:45:52" do
|
317
|
+
r = @client.query("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test")
|
318
|
+
expect(r.first['test']).to be_an_instance_of(Time)
|
319
319
|
end
|
320
320
|
|
321
321
|
it "should return Time when timestamp is > 2038-01-19T03:14:07" do
|
322
322
|
r = @client.query("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test")
|
323
|
-
expect(r.first['test']
|
323
|
+
expect(r.first['test']).to be_an_instance_of(Time)
|
324
324
|
end
|
325
325
|
end
|
326
326
|
end
|
327
327
|
|
328
328
|
it "should return Time for a TIMESTAMP value when within the supported range" do
|
329
|
-
expect(@test_result['timestamp_test']
|
329
|
+
expect(@test_result['timestamp_test']).to be_an_instance_of(Time)
|
330
330
|
expect(@test_result['timestamp_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2010-04-04 11:44:00')
|
331
331
|
end
|
332
332
|
|
333
333
|
it "should return Time for a TIME value" do
|
334
|
-
expect(@test_result['time_test']
|
334
|
+
expect(@test_result['time_test']).to be_an_instance_of(Time)
|
335
335
|
expect(@test_result['time_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2000-01-01 11:44:00')
|
336
336
|
end
|
337
337
|
|
338
338
|
it "should return Date for a DATE value" do
|
339
|
-
expect(@test_result['date_test']
|
339
|
+
expect(@test_result['date_test']).to be_an_instance_of(Date)
|
340
340
|
expect(@test_result['date_test'].strftime("%Y-%m-%d")).to eql('2010-04-04')
|
341
341
|
end
|
342
342
|
|
343
343
|
it "should return String for an ENUM value" do
|
344
|
-
expect(@test_result['enum_test']
|
344
|
+
expect(@test_result['enum_test']).to be_an_instance_of(String)
|
345
345
|
expect(@test_result['enum_test']).to eql('val1')
|
346
346
|
end
|
347
347
|
|
@@ -379,7 +379,7 @@ RSpec.describe Mysql2::Result do
|
|
379
379
|
end
|
380
380
|
|
381
381
|
it "should return String for a SET value" do
|
382
|
-
expect(@test_result['set_test']
|
382
|
+
expect(@test_result['set_test']).to be_an_instance_of(String)
|
383
383
|
expect(@test_result['set_test']).to eql('val1,val2')
|
384
384
|
end
|
385
385
|
|
@@ -412,8 +412,8 @@ RSpec.describe Mysql2::Result do
|
|
412
412
|
end
|
413
413
|
|
414
414
|
it "should return String for a BINARY value" do
|
415
|
-
expect(@test_result['binary_test']
|
416
|
-
expect(@test_result['binary_test']).to eql("test#{"\000"*6}")
|
415
|
+
expect(@test_result['binary_test']).to be_an_instance_of(String)
|
416
|
+
expect(@test_result['binary_test']).to eql("test#{"\000" * 6}")
|
417
417
|
end
|
418
418
|
|
419
419
|
context "string encoding for BINARY values" do
|
@@ -450,17 +450,17 @@ RSpec.describe Mysql2::Result do
|
|
450
450
|
'medium_blob_test' => 'MEDIUMBLOB',
|
451
451
|
'medium_text_test' => 'MEDIUMTEXT',
|
452
452
|
'long_blob_test' => 'LONGBLOB',
|
453
|
-
'long_text_test' => 'LONGTEXT'
|
453
|
+
'long_text_test' => 'LONGTEXT',
|
454
454
|
}.each do |field, type|
|
455
455
|
it "should return a String for #{type}" do
|
456
|
-
expect(@test_result[field]
|
456
|
+
expect(@test_result[field]).to be_an_instance_of(String)
|
457
457
|
expect(@test_result[field]).to eql("test")
|
458
458
|
end
|
459
459
|
|
460
460
|
context "string encoding for #{type} values" do
|
461
461
|
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
462
462
|
|
463
|
-
if
|
463
|
+
if %w(VARBINARY TINYBLOB BLOB MEDIUMBLOB LONGBLOB).include?(type)
|
464
464
|
it "should default to binary if Encoding.default_internal is nil" do
|
465
465
|
with_internal_encoding nil do
|
466
466
|
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
@@ -8,8 +8,10 @@ RSpec.describe Mysql2::Statement do
|
|
8
8
|
|
9
9
|
it "should create a statement" do
|
10
10
|
statement = nil
|
11
|
-
expect { statement = @client.prepare 'SELECT 1' }.
|
12
|
-
|
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).to be_an_instance_of(Mysql2::Statement)
|
13
15
|
end
|
14
16
|
|
15
17
|
it "should raise an exception when server disconnects" do
|
@@ -53,8 +55,8 @@ RSpec.describe Mysql2::Statement do
|
|
53
55
|
statement = @client.prepare 'SELECT 1'
|
54
56
|
result = statement.execute
|
55
57
|
rows = []
|
56
|
-
result.each {|r| rows << r}
|
57
|
-
expect(rows).to eq([{"1"=>1}])
|
58
|
+
result.each { |r| rows << r }
|
59
|
+
expect(rows).to eq([{ "1" => 1 }])
|
58
60
|
end
|
59
61
|
|
60
62
|
it "should keep its result after other query" do
|
@@ -64,8 +66,8 @@ RSpec.describe Mysql2::Statement do
|
|
64
66
|
stmt = @client.prepare('SELECT a FROM mysql2_stmt_q WHERE a = ?')
|
65
67
|
result1 = stmt.execute(1)
|
66
68
|
result2 = stmt.execute(2)
|
67
|
-
expect(result2.first).to eq(
|
68
|
-
expect(result1.first).to eq(
|
69
|
+
expect(result2.first).to eq("a" => 2)
|
70
|
+
expect(result1.first).to eq("a" => 1)
|
69
71
|
@client.query 'DROP TABLE IF EXISTS mysql2_stmt_q'
|
70
72
|
end
|
71
73
|
|
@@ -91,11 +93,11 @@ RSpec.describe Mysql2::Statement do
|
|
91
93
|
@client.query 'INSERT INTO mysql2_stmt_q (a, b) VALUES (1, "Hello"), (2, "World")'
|
92
94
|
statement = @client.prepare 'SELECT * FROM mysql2_stmt_q WHERE a < ?'
|
93
95
|
results = statement.execute(2)
|
94
|
-
expect(results.first).to eq(
|
96
|
+
expect(results.first).to eq("a" => 1, "b" => "Hello")
|
95
97
|
|
96
98
|
statement = @client.prepare 'SELECT * FROM mysql2_stmt_q WHERE b LIKE ?'
|
97
99
|
results = statement.execute('%orld')
|
98
|
-
expect(results.first).to eq(
|
100
|
+
expect(results.first).to eq("a" => 2, "b" => "World")
|
99
101
|
|
100
102
|
@client.query 'DROP TABLE IF EXISTS mysql2_stmt_q'
|
101
103
|
end
|
@@ -103,7 +105,7 @@ RSpec.describe Mysql2::Statement do
|
|
103
105
|
it "should select dates" do
|
104
106
|
statement = @client.prepare 'SELECT NOW()'
|
105
107
|
result = statement.execute
|
106
|
-
expect(result.first.first[1]).to
|
108
|
+
expect(result.first.first[1]).to be_an_instance_of(Time)
|
107
109
|
end
|
108
110
|
|
109
111
|
it "should tell us about the fields" do
|
@@ -130,10 +132,10 @@ RSpec.describe Mysql2::Statement do
|
|
130
132
|
|
131
133
|
it "should be able to retrieve utf8 field names correctly" do
|
132
134
|
stmt = @client.prepare 'SELECT * FROM `テーブル`'
|
133
|
-
expect(stmt.fields).to eq(
|
135
|
+
expect(stmt.fields).to eq(%w(整数 文字列))
|
134
136
|
result = stmt.execute
|
135
137
|
|
136
|
-
expect(result.to_a).to eq([{"整数"=>1, "文字列"=>"イチ"}, {"整数"=>2, "文字列"=>"弐"}, {"整数"=>3, "文字列"=>"さん"}])
|
138
|
+
expect(result.to_a).to eq([{ "整数" => 1, "文字列" => "イチ" }, { "整数" => 2, "文字列" => "弐" }, { "整数" => 3, "文字列" => "さん" }])
|
137
139
|
end
|
138
140
|
|
139
141
|
it "should be able to retrieve utf8 param query correctly" do
|
@@ -142,7 +144,7 @@ RSpec.describe Mysql2::Statement do
|
|
142
144
|
|
143
145
|
result = stmt.execute 'イチ'
|
144
146
|
|
145
|
-
expect(result.to_a).to eq([{"整数"=>1}])
|
147
|
+
expect(result.to_a).to eq([{ "整数" => 1 }])
|
146
148
|
end
|
147
149
|
|
148
150
|
it "should be able to retrieve query with param in different encoding correctly" do
|
@@ -152,9 +154,8 @@ RSpec.describe Mysql2::Statement do
|
|
152
154
|
param = 'イチ'.encode("EUC-JP")
|
153
155
|
result = stmt.execute param
|
154
156
|
|
155
|
-
expect(result.to_a).to eq([{"整数"=>1}])
|
157
|
+
expect(result.to_a).to eq([{ "整数" => 1 }])
|
156
158
|
end
|
157
|
-
|
158
159
|
end if defined? Encoding
|
159
160
|
|
160
161
|
context "streaming result" do
|
@@ -162,7 +163,7 @@ RSpec.describe Mysql2::Statement do
|
|
162
163
|
n = 1
|
163
164
|
stmt = @client.prepare("SELECT 1 UNION SELECT 2")
|
164
165
|
|
165
|
-
@client.query_options.merge!(
|
166
|
+
@client.query_options.merge!(:stream => true, :cache_rows => false, :as => :array)
|
166
167
|
|
167
168
|
stmt.execute.each do |r|
|
168
169
|
case n
|
@@ -185,7 +186,7 @@ RSpec.describe Mysql2::Statement do
|
|
185
186
|
it "should yield rows as hash's" do
|
186
187
|
@result = @client.prepare("SELECT 1").execute
|
187
188
|
@result.each do |row|
|
188
|
-
expect(row
|
189
|
+
expect(row).to be_an_instance_of(Hash)
|
189
190
|
end
|
190
191
|
end
|
191
192
|
|
@@ -193,7 +194,7 @@ RSpec.describe Mysql2::Statement do
|
|
193
194
|
@client.query_options[:symbolize_keys] = true
|
194
195
|
@result = @client.prepare("SELECT 1").execute
|
195
196
|
@result.each do |row|
|
196
|
-
expect(row.keys.first
|
197
|
+
expect(row.keys.first).to be_an_instance_of(Symbol)
|
197
198
|
end
|
198
199
|
@client.query_options[:symbolize_keys] = false
|
199
200
|
end
|
@@ -203,7 +204,7 @@ RSpec.describe Mysql2::Statement do
|
|
203
204
|
|
204
205
|
@result = @client.prepare("SELECT 1").execute
|
205
206
|
@result.each do |row|
|
206
|
-
expect(row
|
207
|
+
expect(row).to be_an_instance_of(Array)
|
207
208
|
end
|
208
209
|
|
209
210
|
@client.query_options[:as] = :hash
|
@@ -259,7 +260,7 @@ RSpec.describe Mysql2::Statement do
|
|
259
260
|
|
260
261
|
it "should return an array of field names in proper order" do
|
261
262
|
result = @client.prepare("SELECT 'a', 'b', 'c'").execute
|
262
|
-
expect(result.fields).to eql(
|
263
|
+
expect(result.fields).to eql(%w(a b c))
|
263
264
|
end
|
264
265
|
end
|
265
266
|
|
@@ -270,17 +271,17 @@ RSpec.describe Mysql2::Statement do
|
|
270
271
|
end
|
271
272
|
|
272
273
|
it "should return nil for a NULL value" do
|
273
|
-
expect(@test_result['null_test']
|
274
|
+
expect(@test_result['null_test']).to be_an_instance_of(NilClass)
|
274
275
|
expect(@test_result['null_test']).to eql(nil)
|
275
276
|
end
|
276
277
|
|
277
278
|
it "should return String for a BIT(64) value" do
|
278
|
-
expect(@test_result['bit_test']
|
279
|
+
expect(@test_result['bit_test']).to be_an_instance_of(String)
|
279
280
|
expect(@test_result['bit_test']).to eql("\000\000\000\000\000\000\000\005")
|
280
281
|
end
|
281
282
|
|
282
283
|
it "should return String for a BIT(1) value" do
|
283
|
-
expect(@test_result['single_bit_test']
|
284
|
+
expect(@test_result['single_bit_test']).to be_an_instance_of(String)
|
284
285
|
expect(@test_result['single_bit_test']).to eql("\001")
|
285
286
|
end
|
286
287
|
|
@@ -347,89 +348,89 @@ RSpec.describe Mysql2::Statement do
|
|
347
348
|
end
|
348
349
|
|
349
350
|
it "should return BigDecimal for a DECIMAL value" do
|
350
|
-
expect(@test_result['decimal_test']
|
351
|
+
expect(@test_result['decimal_test']).to be_an_instance_of(BigDecimal)
|
351
352
|
expect(@test_result['decimal_test']).to eql(10.3)
|
352
353
|
end
|
353
354
|
|
354
355
|
it "should return Float for a FLOAT value" do
|
355
|
-
expect(@test_result['float_test']
|
356
|
+
expect(@test_result['float_test']).to be_an_instance_of(Float)
|
356
357
|
expect(@test_result['float_test']).to be_within(1e-5).of(10.3)
|
357
358
|
end
|
358
359
|
|
359
360
|
it "should return Float for a DOUBLE value" do
|
360
|
-
expect(@test_result['double_test']
|
361
|
+
expect(@test_result['double_test']).to be_an_instance_of(Float)
|
361
362
|
expect(@test_result['double_test']).to eql(10.3)
|
362
363
|
end
|
363
364
|
|
364
365
|
it "should return Time for a DATETIME value when within the supported range" do
|
365
|
-
expect(@test_result['date_time_test']
|
366
|
+
expect(@test_result['date_time_test']).to be_an_instance_of(Time)
|
366
367
|
expect(@test_result['date_time_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2010-04-04 11:44:00')
|
367
368
|
end
|
368
369
|
|
369
370
|
if 1.size == 4 # 32bit
|
370
|
-
|
371
|
-
|
371
|
+
klass = if RUBY_VERSION =~ /1.8/
|
372
|
+
DateTime
|
372
373
|
else
|
373
|
-
|
374
|
+
Time
|
374
375
|
end
|
375
376
|
|
376
377
|
it "should return DateTime when timestamp is < 1901-12-13 20:45:52" do
|
377
|
-
|
378
|
+
# 1901-12-13T20:45:52 is the min for 32bit Ruby 1.8
|
378
379
|
r = @client.query("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test")
|
379
|
-
expect(r.first['test']
|
380
|
+
expect(r.first['test']).to be_an_instance_of(klass)
|
380
381
|
end
|
381
382
|
|
382
383
|
it "should return DateTime when timestamp is > 2038-01-19T03:14:07" do
|
383
|
-
|
384
|
+
# 2038-01-19T03:14:07 is the max for 32bit Ruby 1.8
|
384
385
|
r = @client.query("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test")
|
385
|
-
expect(r.first['test']
|
386
|
+
expect(r.first['test']).to be_an_instance_of(klass)
|
386
387
|
end
|
387
388
|
elsif 1.size == 8 # 64bit
|
388
|
-
|
389
|
-
it "should return Time when timestamp is < 1901-12-13 20:45:52" do
|
390
|
-
r = @client.query("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test")
|
391
|
-
expect(r.first['test'].class).to eql(Time)
|
392
|
-
end
|
393
|
-
|
394
|
-
it "should return Time when timestamp is > 2038-01-19T03:14:07" do
|
395
|
-
r = @client.query("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test")
|
396
|
-
expect(r.first['test'].class).to eql(Time)
|
397
|
-
end
|
398
|
-
else
|
389
|
+
if RUBY_VERSION =~ /1.8/
|
399
390
|
it "should return Time when timestamp is > 0138-12-31 11:59:59" do
|
400
391
|
r = @client.query("SELECT CAST('0139-1-1 00:00:00' AS DATETIME) as test")
|
401
|
-
expect(r.first['test']
|
392
|
+
expect(r.first['test']).to be_an_instance_of(Time)
|
402
393
|
end
|
403
394
|
|
404
395
|
it "should return DateTime when timestamp is < 0139-1-1T00:00:00" do
|
405
396
|
r = @client.query("SELECT CAST('0138-12-31 11:59:59' AS DATETIME) as test")
|
406
|
-
expect(r.first['test']
|
397
|
+
expect(r.first['test']).to be_an_instance_of(DateTime)
|
398
|
+
end
|
399
|
+
|
400
|
+
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")
|
402
|
+
expect(r.first['test']).to be_an_instance_of(Time)
|
403
|
+
end
|
404
|
+
else
|
405
|
+
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")
|
407
|
+
expect(r.first['test']).to be_an_instance_of(Time)
|
407
408
|
end
|
408
409
|
|
409
410
|
it "should return Time when timestamp is > 2038-01-19T03:14:07" do
|
410
411
|
r = @client.query("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test")
|
411
|
-
expect(r.first['test']
|
412
|
+
expect(r.first['test']).to be_an_instance_of(Time)
|
412
413
|
end
|
413
414
|
end
|
414
415
|
end
|
415
416
|
|
416
417
|
it "should return Time for a TIMESTAMP value when within the supported range" do
|
417
|
-
expect(@test_result['timestamp_test']
|
418
|
+
expect(@test_result['timestamp_test']).to be_an_instance_of(Time)
|
418
419
|
expect(@test_result['timestamp_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2010-04-04 11:44:00')
|
419
420
|
end
|
420
421
|
|
421
422
|
it "should return Time for a TIME value" do
|
422
|
-
expect(@test_result['time_test']
|
423
|
+
expect(@test_result['time_test']).to be_an_instance_of(Time)
|
423
424
|
expect(@test_result['time_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2000-01-01 11:44:00')
|
424
425
|
end
|
425
426
|
|
426
427
|
it "should return Date for a DATE value" do
|
427
|
-
expect(@test_result['date_test']
|
428
|
+
expect(@test_result['date_test']).to be_an_instance_of(Date)
|
428
429
|
expect(@test_result['date_test'].strftime("%Y-%m-%d")).to eql('2010-04-04')
|
429
430
|
end
|
430
431
|
|
431
432
|
it "should return String for an ENUM value" do
|
432
|
-
expect(@test_result['enum_test']
|
433
|
+
expect(@test_result['enum_test']).to be_an_instance_of(String)
|
433
434
|
expect(@test_result['enum_test']).to eql('val1')
|
434
435
|
end
|
435
436
|
|
@@ -467,7 +468,7 @@ RSpec.describe Mysql2::Statement do
|
|
467
468
|
end
|
468
469
|
|
469
470
|
it "should return String for a SET value" do
|
470
|
-
expect(@test_result['set_test']
|
471
|
+
expect(@test_result['set_test']).to be_an_instance_of(String)
|
471
472
|
expect(@test_result['set_test']).to eql('val1,val2')
|
472
473
|
end
|
473
474
|
|
@@ -500,8 +501,8 @@ RSpec.describe Mysql2::Statement do
|
|
500
501
|
end
|
501
502
|
|
502
503
|
it "should return String for a BINARY value" do
|
503
|
-
expect(@test_result['binary_test']
|
504
|
-
expect(@test_result['binary_test']).to eql("test#{"\000"*6}")
|
504
|
+
expect(@test_result['binary_test']).to be_an_instance_of(String)
|
505
|
+
expect(@test_result['binary_test']).to eql("test#{"\000" * 6}")
|
505
506
|
end
|
506
507
|
|
507
508
|
context "string encoding for BINARY values" do
|
@@ -538,17 +539,17 @@ RSpec.describe Mysql2::Statement do
|
|
538
539
|
'medium_blob_test' => 'MEDIUMBLOB',
|
539
540
|
'medium_text_test' => 'MEDIUMTEXT',
|
540
541
|
'long_blob_test' => 'LONGBLOB',
|
541
|
-
'long_text_test' => 'LONGTEXT'
|
542
|
+
'long_text_test' => 'LONGTEXT',
|
542
543
|
}.each do |field, type|
|
543
544
|
it "should return a String for #{type}" do
|
544
|
-
expect(@test_result[field]
|
545
|
+
expect(@test_result[field]).to be_an_instance_of(String)
|
545
546
|
expect(@test_result[field]).to eql("test")
|
546
547
|
end
|
547
548
|
|
548
549
|
context "string encoding for #{type} values" do
|
549
550
|
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
550
551
|
|
551
|
-
if
|
552
|
+
if %w(VARBINARY TINYBLOB BLOB MEDIUMBLOB LONGBLOB).include?(type)
|
552
553
|
it "should default to binary if Encoding.default_internal is nil" do
|
553
554
|
with_internal_encoding nil do
|
554
555
|
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
@@ -595,4 +596,89 @@ RSpec.describe Mysql2::Statement do
|
|
595
596
|
end
|
596
597
|
end
|
597
598
|
end
|
599
|
+
|
600
|
+
context 'last_id' do
|
601
|
+
before(:each) do
|
602
|
+
@client.query 'USE test'
|
603
|
+
@client.query 'CREATE TABLE IF NOT EXISTS lastIdTest (`id` BIGINT NOT NULL AUTO_INCREMENT, blah INT(11), PRIMARY KEY (`id`))'
|
604
|
+
end
|
605
|
+
|
606
|
+
after(:each) do
|
607
|
+
@client.query 'DROP TABLE lastIdTest'
|
608
|
+
end
|
609
|
+
|
610
|
+
it 'should return last insert id' do
|
611
|
+
stmt = @client.prepare 'INSERT INTO lastIdTest (blah) VALUES (?)'
|
612
|
+
expect(stmt.last_id).to eq 0
|
613
|
+
stmt.execute 1
|
614
|
+
expect(stmt.last_id).to eq 1
|
615
|
+
end
|
616
|
+
|
617
|
+
it 'should handle bigint ids' do
|
618
|
+
stmt = @client.prepare 'INSERT INTO lastIdTest (id, blah) VALUES (?, ?)'
|
619
|
+
stmt.execute 5000000000, 5000
|
620
|
+
expect(stmt.last_id).to eql(5000000000)
|
621
|
+
|
622
|
+
stmt = @client.prepare 'INSERT INTO lastIdTest (blah) VALUES (?)'
|
623
|
+
stmt.execute 5001
|
624
|
+
expect(stmt.last_id).to eql(5000000001)
|
625
|
+
end
|
626
|
+
end
|
627
|
+
|
628
|
+
context 'affected_rows' do
|
629
|
+
before :each do
|
630
|
+
@client.query 'USE test'
|
631
|
+
@client.query 'CREATE TABLE IF NOT EXISTS lastIdTest (`id` BIGINT NOT NULL AUTO_INCREMENT, blah INT(11), PRIMARY KEY (`id`))'
|
632
|
+
end
|
633
|
+
|
634
|
+
after :each do
|
635
|
+
@client.query 'DROP TABLE lastIdTest'
|
636
|
+
end
|
637
|
+
|
638
|
+
it 'should return number of rows affected by an insert' do
|
639
|
+
stmt = @client.prepare 'INSERT INTO lastIdTest (blah) VALUES (?)'
|
640
|
+
expect(stmt.affected_rows).to eq 0
|
641
|
+
stmt.execute 1
|
642
|
+
expect(stmt.affected_rows).to eq 1
|
643
|
+
end
|
644
|
+
|
645
|
+
it 'should return number of rows affected by an update' do
|
646
|
+
stmt = @client.prepare 'INSERT INTO lastIdTest (blah) VALUES (?)'
|
647
|
+
stmt.execute 1
|
648
|
+
expect(stmt.affected_rows).to eq 1
|
649
|
+
stmt.execute 2
|
650
|
+
expect(stmt.affected_rows).to eq 1
|
651
|
+
|
652
|
+
stmt = @client.prepare 'UPDATE lastIdTest SET blah=? WHERE blah=?'
|
653
|
+
stmt.execute 0, 1
|
654
|
+
expect(stmt.affected_rows).to eq 1
|
655
|
+
end
|
656
|
+
|
657
|
+
it 'should return number of rows affected by a delete' do
|
658
|
+
stmt = @client.prepare 'INSERT INTO lastIdTest (blah) VALUES (?)'
|
659
|
+
stmt.execute 1
|
660
|
+
expect(stmt.affected_rows).to eq 1
|
661
|
+
stmt.execute 2
|
662
|
+
expect(stmt.affected_rows).to eq 1
|
663
|
+
|
664
|
+
stmt = @client.prepare 'DELETE FROM lastIdTest WHERE blah=?'
|
665
|
+
stmt.execute 1
|
666
|
+
expect(stmt.affected_rows).to eq 1
|
667
|
+
end
|
668
|
+
end
|
669
|
+
|
670
|
+
context 'close' do
|
671
|
+
it 'should free server resources' do
|
672
|
+
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)
|
676
|
+
end
|
677
|
+
|
678
|
+
it 'should raise an error on subsequent execution' do
|
679
|
+
stmt = @client.prepare 'SELECT 1'
|
680
|
+
stmt.close
|
681
|
+
expect { stmt.execute }.to raise_error(Mysql2::Error, /Invalid statement handle/)
|
682
|
+
end
|
683
|
+
end
|
598
684
|
end
|