mysql2 0.4.0-x86-mswin32-60 → 0.4.1-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/examples/eventmachine.rb +1 -1
  3. data/ext/mysql2/client.c +45 -44
  4. data/ext/mysql2/client.h +1 -2
  5. data/ext/mysql2/extconf.rb +59 -37
  6. data/ext/mysql2/infile.c +2 -2
  7. data/ext/mysql2/mysql2_ext.h +4 -6
  8. data/ext/mysql2/mysql_enc_name_to_ruby.h +8 -8
  9. data/ext/mysql2/mysql_enc_to_ruby.h +25 -22
  10. data/ext/mysql2/result.c +4 -16
  11. data/ext/mysql2/result.h +3 -3
  12. data/ext/mysql2/statement.c +79 -42
  13. data/ext/mysql2/statement.h +2 -6
  14. data/lib/mysql2.rb +36 -18
  15. data/lib/mysql2/1.8/mysql2.so +0 -0
  16. data/lib/mysql2/1.9/mysql2.so +0 -0
  17. data/lib/mysql2/2.0/mysql2.so +0 -0
  18. data/lib/mysql2/2.1/mysql2.so +0 -0
  19. data/lib/mysql2/2.2/mysql2.so +0 -0
  20. data/lib/mysql2/client.rb +28 -27
  21. data/lib/mysql2/console.rb +1 -1
  22. data/lib/mysql2/em.rb +5 -6
  23. data/lib/mysql2/error.rb +10 -7
  24. data/lib/mysql2/field.rb +1 -2
  25. data/lib/mysql2/statement.rb +12 -0
  26. data/lib/mysql2/version.rb +1 -1
  27. data/spec/em/em_spec.rb +8 -8
  28. data/spec/mysql2/client_spec.rb +62 -37
  29. data/spec/mysql2/result_spec.rb +48 -48
  30. data/spec/mysql2/statement_spec.rb +143 -57
  31. data/spec/ssl/ca-cert.pem +17 -0
  32. data/spec/ssl/ca-key.pem +27 -0
  33. data/spec/ssl/ca.cnf +22 -0
  34. data/spec/ssl/cert.cnf +22 -0
  35. data/spec/ssl/client-cert.pem +17 -0
  36. data/spec/ssl/client-key.pem +27 -0
  37. data/spec/ssl/client-req.pem +15 -0
  38. data/spec/ssl/gen_certs.sh +48 -0
  39. data/spec/ssl/pkcs8-client-key.pem +28 -0
  40. data/spec/ssl/pkcs8-server-key.pem +28 -0
  41. data/spec/ssl/server-cert.pem +17 -0
  42. data/spec/ssl/server-key.pem +27 -0
  43. data/spec/ssl/server-req.pem +15 -0
  44. data/support/mysql_enc_to_ruby.rb +7 -8
  45. data/support/ruby_enc_to_mysql.rb +1 -1
  46. metadata +28 -2
@@ -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.class).to eql(Hash)
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.class).to eql(Symbol)
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.class).to eql(Array)
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(['a', 'b', 'c'])
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 |row, i|
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 eql("1")
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 eql("10")
180
- expect(result["date_test"]).to eql("2010-04-04")
181
- expect(result["enum_test"]).to eql("val1")
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'].class).to eql(NilClass)
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'].class).to eql(String)
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'].class).to eql(String)
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'].class).to eql(BigDecimal)
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'].class).to eql(Float)
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'].class).to eql(Float)
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'].class).to eql(Time)
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
- unless RUBY_VERSION =~ /1.8/
283
- klass = Time
282
+ klass = if RUBY_VERSION =~ /1.8/
283
+ DateTime
284
284
  else
285
- klass = DateTime
285
+ Time
286
286
  end
287
287
 
288
288
  it "should return DateTime when timestamp is < 1901-12-13 20:45:52" do
289
- # 1901-12-13T20:45:52 is the min for 32bit Ruby 1.8
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'].class).to eql(klass)
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
- # 2038-01-19T03:14:07 is the max for 32bit Ruby 1.8
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'].class).to eql(klass)
297
+ expect(r.first['test']).to be_an_instance_of(klass)
298
298
  end
299
299
  elsif 1.size == 8 # 64bit
300
- unless RUBY_VERSION =~ /1.8/
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'].class).to eql(Time)
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'].class).to eql(DateTime)
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'].class).to eql(Time)
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'].class).to eql(Time)
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'].class).to eql(Time)
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'].class).to eql(Date)
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'].class).to eql(String)
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'].class).to eql(String)
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'].class).to eql(String)
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].class).to eql(String)
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 ['VARBINARY', 'TINYBLOB', 'BLOB', 'MEDIUMBLOB', 'LONGBLOB'].include?(type)
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' }.not_to raise_error
12
- expect(statement).to be_kind_of Mysql2::Statement
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({"a"=>2})
68
- expect(result1.first).to eq({"a"=>1})
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({"a" => 1, "b" => "Hello"})
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({"a" => 2, "b" => "World"})
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 be_kind_of Time
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!({:stream => true, :cache_rows => false, :as => :array})
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.class).to eql(Hash)
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.class).to eql(Symbol)
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.class).to eql(Array)
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(['a', 'b', 'c'])
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'].class).to eql(NilClass)
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'].class).to eql(String)
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'].class).to eql(String)
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'].class).to eql(BigDecimal)
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'].class).to eql(Float)
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'].class).to eql(Float)
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'].class).to eql(Time)
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
- unless RUBY_VERSION =~ /1.8/
371
- klass = Time
371
+ klass = if RUBY_VERSION =~ /1.8/
372
+ DateTime
372
373
  else
373
- klass = DateTime
374
+ Time
374
375
  end
375
376
 
376
377
  it "should return DateTime when timestamp is < 1901-12-13 20:45:52" do
377
- # 1901-12-13T20:45:52 is the min for 32bit Ruby 1.8
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'].class).to eql(klass)
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
- # 2038-01-19T03:14:07 is the max for 32bit Ruby 1.8
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'].class).to eql(klass)
386
+ expect(r.first['test']).to be_an_instance_of(klass)
386
387
  end
387
388
  elsif 1.size == 8 # 64bit
388
- unless RUBY_VERSION =~ /1.8/
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'].class).to eql(Time)
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'].class).to eql(DateTime)
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'].class).to eql(Time)
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'].class).to eql(Time)
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'].class).to eql(Time)
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'].class).to eql(Date)
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'].class).to eql(String)
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'].class).to eql(String)
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'].class).to eql(String)
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].class).to eql(String)
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 ['VARBINARY', 'TINYBLOB', 'BLOB', 'MEDIUMBLOB', 'LONGBLOB'].include?(type)
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