mysql2 0.4.2 → 0.4.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +77 -51
- data/ext/mysql2/client.c +242 -51
- data/ext/mysql2/client.h +2 -12
- data/ext/mysql2/extconf.rb +26 -2
- data/ext/mysql2/mysql2_ext.h +0 -4
- data/ext/mysql2/result.c +40 -22
- data/ext/mysql2/result.h +3 -2
- data/ext/mysql2/statement.c +133 -32
- data/lib/mysql2/client.rb +19 -6
- data/lib/mysql2/version.rb +1 -1
- data/spec/configuration.yml.example +0 -6
- data/spec/em/em_spec.rb +1 -0
- data/spec/mysql2/client_spec.rb +211 -111
- data/spec/mysql2/error_spec.rb +4 -6
- data/spec/mysql2/result_spec.rb +71 -36
- data/spec/mysql2/statement_spec.rb +144 -52
- data/spec/spec_helper.rb +73 -59
- data/spec/ssl/gen_certs.sh +1 -1
- data/support/5072E1F5.asc +432 -0
- metadata +12 -11
data/spec/mysql2/result_spec.rb
CHANGED
@@ -22,6 +22,10 @@ RSpec.describe Mysql2::Result do
|
|
22
22
|
expect(@result).to respond_to(:each)
|
23
23
|
end
|
24
24
|
|
25
|
+
it "should respond to #free" do
|
26
|
+
expect(@result).to respond_to(:free)
|
27
|
+
end
|
28
|
+
|
25
29
|
it "should raise a Mysql2::Error exception upon a bad query" do
|
26
30
|
expect {
|
27
31
|
@client.query "bad sql"
|
@@ -78,6 +82,11 @@ RSpec.describe Mysql2::Result do
|
|
78
82
|
expect(result.first.object_id).not_to eql(result.first.object_id)
|
79
83
|
end
|
80
84
|
|
85
|
+
it "should be able to iterate a second time even if cache_rows is disabled" do
|
86
|
+
result = @client.query "SELECT 1 UNION SELECT 2", :cache_rows => false
|
87
|
+
expect(result.to_a).to eql(result.to_a)
|
88
|
+
end
|
89
|
+
|
81
90
|
it "should yield different value for #first if streaming" do
|
82
91
|
result = @client.query "SELECT 1 UNION SELECT 2", :stream => true, :cache_rows => false
|
83
92
|
expect(result.first).not_to eql(result.first)
|
@@ -144,18 +153,16 @@ RSpec.describe Mysql2::Result do
|
|
144
153
|
end
|
145
154
|
|
146
155
|
it "should raise an exception if streaming ended due to a timeout" do
|
147
|
-
|
148
|
-
client = Mysql2::Client.new DatabaseCredentials['root']
|
149
|
-
client.query "CREATE TEMPORARY TABLE streamingTest (val BINARY(255)) ENGINE=MEMORY"
|
156
|
+
@client.query "CREATE TEMPORARY TABLE streamingTest (val BINARY(255)) ENGINE=MEMORY"
|
150
157
|
|
151
158
|
# Insert enough records to force the result set into multiple reads
|
152
159
|
# (the BINARY type is used simply because it forces full width results)
|
153
160
|
10000.times do |i|
|
154
|
-
client.query "INSERT INTO streamingTest (val) VALUES ('Foo #{i}')"
|
161
|
+
@client.query "INSERT INTO streamingTest (val) VALUES ('Foo #{i}')"
|
155
162
|
end
|
156
163
|
|
157
|
-
client.query "SET net_write_timeout = 1"
|
158
|
-
res = client.query "SELECT * FROM streamingTest", :stream => true, :cache_rows => false
|
164
|
+
@client.query "SET net_write_timeout = 1"
|
165
|
+
res = @client.query "SELECT * FROM streamingTest", :stream => true, :cache_rows => false
|
159
166
|
|
160
167
|
expect {
|
161
168
|
res.each_with_index do |_, i|
|
@@ -201,36 +208,43 @@ RSpec.describe Mysql2::Result do
|
|
201
208
|
expect(@test_result['tiny_int_test']).to eql(1)
|
202
209
|
end
|
203
210
|
|
204
|
-
|
205
|
-
|
206
|
-
id1
|
207
|
-
@client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (0)'
|
208
|
-
|
209
|
-
|
210
|
-
id3 = @client.last_id
|
211
|
+
context "cast booleans for TINYINT if :cast_booleans is enabled" do
|
212
|
+
# rubocop:disable Style/Semicolon
|
213
|
+
let(:id1) { @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES ( 1)'; @client.last_id }
|
214
|
+
let(:id2) { @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES ( 0)'; @client.last_id }
|
215
|
+
let(:id3) { @client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (-1)'; @client.last_id }
|
216
|
+
# rubocop:enable Style/Semicolon
|
211
217
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
expect(result1.first['bool_cast_test']).to be true
|
216
|
-
expect(result2.first['bool_cast_test']).to be false
|
217
|
-
expect(result3.first['bool_cast_test']).to be true
|
218
|
+
after do
|
219
|
+
@client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2},#{id3})"
|
220
|
+
end
|
218
221
|
|
219
|
-
|
222
|
+
it "should return TrueClass or FalseClass for a TINYINT value if :cast_booleans is enabled" do
|
223
|
+
result1 = @client.query "SELECT bool_cast_test FROM mysql2_test WHERE id = #{id1} LIMIT 1", :cast_booleans => true
|
224
|
+
result2 = @client.query "SELECT bool_cast_test FROM mysql2_test WHERE id = #{id2} LIMIT 1", :cast_booleans => true
|
225
|
+
result3 = @client.query "SELECT bool_cast_test FROM mysql2_test WHERE id = #{id3} LIMIT 1", :cast_booleans => true
|
226
|
+
expect(result1.first['bool_cast_test']).to be true
|
227
|
+
expect(result2.first['bool_cast_test']).to be false
|
228
|
+
expect(result3.first['bool_cast_test']).to be true
|
229
|
+
end
|
220
230
|
end
|
221
231
|
|
222
|
-
|
223
|
-
|
224
|
-
id1
|
225
|
-
@client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (0)'
|
226
|
-
|
232
|
+
context "cast booleans for BIT(1) if :cast_booleans is enabled" do
|
233
|
+
# rubocop:disable Style/Semicolon
|
234
|
+
let(:id1) { @client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (1)'; @client.last_id }
|
235
|
+
let(:id2) { @client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (0)'; @client.last_id }
|
236
|
+
# rubocop:enable Style/Semicolon
|
227
237
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
expect(result2.first['single_bit_test']).to be false
|
238
|
+
after do
|
239
|
+
@client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2})"
|
240
|
+
end
|
232
241
|
|
233
|
-
|
242
|
+
it "should return TrueClass or FalseClass for a BIT(1) value if :cast_booleans is enabled" do
|
243
|
+
result1 = @client.query "SELECT single_bit_test FROM mysql2_test WHERE id = #{id1}", :cast_booleans => true
|
244
|
+
result2 = @client.query "SELECT single_bit_test FROM mysql2_test WHERE id = #{id2}", :cast_booleans => true
|
245
|
+
expect(result1.first['single_bit_test']).to be true
|
246
|
+
expect(result2.first['single_bit_test']).to be false
|
247
|
+
end
|
234
248
|
end
|
235
249
|
|
236
250
|
it "should return Fixnum for a SMALLINT value" do
|
@@ -278,6 +292,30 @@ RSpec.describe Mysql2::Result do
|
|
278
292
|
expect(@test_result['date_time_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2010-04-04 11:44:00')
|
279
293
|
end
|
280
294
|
|
295
|
+
it "should return Time values with microseconds" do
|
296
|
+
now = Time.now
|
297
|
+
if RUBY_VERSION =~ /1.8/ || @client.server_info[:id] / 100 < 506
|
298
|
+
result = @client.query("SELECT CAST('#{now.strftime('%F %T %z')}' AS DATETIME) AS a")
|
299
|
+
expect(result.first['a'].strftime('%F %T %z')).to eql(now.strftime('%F %T %z'))
|
300
|
+
else
|
301
|
+
result = @client.query("SELECT CAST('#{now.strftime('%F %T.%6N %z')}' AS DATETIME(6)) AS a")
|
302
|
+
# microseconds is 6 digits after the decimal, but only test on 5 significant figures
|
303
|
+
expect(result.first['a'].strftime('%F %T.%5N %z')).to eql(now.strftime('%F %T.%5N %z'))
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
it "should return DateTime values with microseconds" do
|
308
|
+
now = DateTime.now
|
309
|
+
if RUBY_VERSION =~ /1.8/ || @client.server_info[:id] / 100 < 506
|
310
|
+
result = @client.query("SELECT CAST('#{now.strftime('%F %T %z')}' AS DATETIME) AS a")
|
311
|
+
expect(result.first['a'].strftime('%F %T %z')).to eql(now.strftime('%F %T %z'))
|
312
|
+
else
|
313
|
+
result = @client.query("SELECT CAST('#{now.strftime('%F %T.%6N %z')}' AS DATETIME(6)) AS a")
|
314
|
+
# microseconds is 6 digits after the decimal, but only test on 5 significant figures
|
315
|
+
expect(result.first['a'].strftime('%F %T.%5N %z')).to eql(now.strftime('%F %T.%5N %z'))
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
281
319
|
if 1.size == 4 # 32bit
|
282
320
|
klass = if RUBY_VERSION =~ /1.8/
|
283
321
|
DateTime
|
@@ -358,10 +396,9 @@ RSpec.describe Mysql2::Result do
|
|
358
396
|
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
359
397
|
expect(result['enum_test'].encoding).to eql(Encoding::UTF_8)
|
360
398
|
|
361
|
-
client2 =
|
399
|
+
client2 = new_client(:encoding => 'ascii')
|
362
400
|
result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
363
401
|
expect(result['enum_test'].encoding).to eql(Encoding::ASCII)
|
364
|
-
client2.close
|
365
402
|
end
|
366
403
|
end
|
367
404
|
|
@@ -391,10 +428,9 @@ RSpec.describe Mysql2::Result do
|
|
391
428
|
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
392
429
|
expect(result['set_test'].encoding).to eql(Encoding::UTF_8)
|
393
430
|
|
394
|
-
client2 =
|
431
|
+
client2 = new_client(:encoding => 'ascii')
|
395
432
|
result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
396
433
|
expect(result['set_test'].encoding).to eql(Encoding::ASCII)
|
397
|
-
client2.close
|
398
434
|
end
|
399
435
|
end
|
400
436
|
|
@@ -485,10 +521,9 @@ RSpec.describe Mysql2::Result do
|
|
485
521
|
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
486
522
|
expect(result[field].encoding).to eql(Encoding::UTF_8)
|
487
523
|
|
488
|
-
client2 =
|
524
|
+
client2 = new_client(:encoding => 'ascii')
|
489
525
|
result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
490
526
|
expect(result[field].encoding).to eql(Encoding::ASCII)
|
491
|
-
client2.close
|
492
527
|
end
|
493
528
|
end
|
494
529
|
|
@@ -3,14 +3,16 @@ require './spec/spec_helper.rb'
|
|
3
3
|
|
4
4
|
RSpec.describe Mysql2::Statement do
|
5
5
|
before :each do
|
6
|
-
@client =
|
6
|
+
@client = new_client(:encoding => "utf8")
|
7
|
+
end
|
8
|
+
|
9
|
+
def stmt_count
|
10
|
+
@client.query("SHOW STATUS LIKE 'Prepared_stmt_count'").first['Value'].to_i
|
7
11
|
end
|
8
12
|
|
9
13
|
it "should create a statement" do
|
10
14
|
statement = nil
|
11
|
-
expect { statement = @client.prepare 'SELECT 1' }.to change
|
12
|
-
@client.query("SHOW STATUS LIKE 'Prepared_stmt_count'").first['Value'].to_i
|
13
|
-
}.by(1)
|
15
|
+
expect { statement = @client.prepare 'SELECT 1' }.to change(&method(:stmt_count)).by(1)
|
14
16
|
expect(statement).to be_an_instance_of(Mysql2::Statement)
|
15
17
|
end
|
16
18
|
|
@@ -59,6 +61,32 @@ RSpec.describe Mysql2::Statement do
|
|
59
61
|
expect(rows).to eq([{ "1" => 1 }])
|
60
62
|
end
|
61
63
|
|
64
|
+
it "should handle booleans" do
|
65
|
+
stmt = @client.prepare('SELECT ? AS `true`, ? AS `false`')
|
66
|
+
result = stmt.execute(true, false)
|
67
|
+
expect(result.to_a).to eq(['true' => 1, 'false' => 0])
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should handle bignum but in int64_t" do
|
71
|
+
stmt = @client.prepare('SELECT ? AS max, ? AS min')
|
72
|
+
int64_max = (1 << 63) - 1
|
73
|
+
int64_min = -(1 << 63)
|
74
|
+
result = stmt.execute(int64_max, int64_min)
|
75
|
+
expect(result.to_a).to eq(['max' => int64_max, 'min' => int64_min])
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should handle bignum but beyond int64_t" do
|
79
|
+
stmt = @client.prepare('SELECT ? AS max1, ? AS max2, ? AS max3, ? AS min1, ? AS min2, ? AS min3')
|
80
|
+
int64_max1 = (1 << 63)
|
81
|
+
int64_max2 = (1 << 64) - 1
|
82
|
+
int64_max3 = 1 << 64
|
83
|
+
int64_min1 = -(1 << 63) - 1
|
84
|
+
int64_min2 = -(1 << 64) + 1
|
85
|
+
int64_min3 = -0xC000000000000000
|
86
|
+
result = stmt.execute(int64_max1, int64_max2, int64_max3, int64_min1, int64_min2, int64_min3)
|
87
|
+
expect(result.to_a).to eq(['max1' => int64_max1, 'max2' => int64_max2, 'max3' => int64_max3, 'min1' => int64_min1, 'min2' => int64_min2, 'min3' => int64_min3])
|
88
|
+
end
|
89
|
+
|
62
90
|
it "should keep its result after other query" do
|
63
91
|
@client.query 'USE test'
|
64
92
|
@client.query 'CREATE TABLE IF NOT EXISTS mysql2_stmt_q(a int)'
|
@@ -108,6 +136,37 @@ RSpec.describe Mysql2::Statement do
|
|
108
136
|
expect(result.first.first[1]).to be_an_instance_of(Time)
|
109
137
|
end
|
110
138
|
|
139
|
+
it "should prepare Date values" do
|
140
|
+
now = Date.today
|
141
|
+
statement = @client.prepare('SELECT ? AS a')
|
142
|
+
result = statement.execute(now)
|
143
|
+
expect(result.first['a'].to_s).to eql(now.strftime('%F'))
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should prepare Time values with microseconds" do
|
147
|
+
now = Time.now
|
148
|
+
statement = @client.prepare('SELECT ? AS a')
|
149
|
+
result = statement.execute(now)
|
150
|
+
if RUBY_VERSION =~ /1.8/
|
151
|
+
expect(result.first['a'].strftime('%F %T %z')).to eql(now.strftime('%F %T %z'))
|
152
|
+
else
|
153
|
+
# microseconds is six digits after the decimal, but only test on 5 significant figures
|
154
|
+
expect(result.first['a'].strftime('%F %T.%5N %z')).to eql(now.strftime('%F %T.%5N %z'))
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should prepare DateTime values with microseconds" do
|
159
|
+
now = DateTime.now
|
160
|
+
statement = @client.prepare('SELECT ? AS a')
|
161
|
+
result = statement.execute(now)
|
162
|
+
if RUBY_VERSION =~ /1.8/
|
163
|
+
expect(result.first['a'].strftime('%F %T %z')).to eql(now.strftime('%F %T %z'))
|
164
|
+
else
|
165
|
+
# microseconds is six digits after the decimal, but only test on 5 significant figures
|
166
|
+
expect(result.first['a'].strftime('%F %T.%5N %z')).to eql(now.strftime('%F %T.%5N %z'))
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
111
170
|
it "should tell us about the fields" do
|
112
171
|
statement = @client.prepare 'SELECT 1 as foo, 2'
|
113
172
|
statement.execute
|
@@ -117,6 +176,32 @@ RSpec.describe Mysql2::Statement do
|
|
117
176
|
expect(list[1]).to eq('2')
|
118
177
|
end
|
119
178
|
|
179
|
+
it "should handle as a decimal binding a BigDecimal" do
|
180
|
+
stmt = @client.prepare('SELECT ? AS decimal_test')
|
181
|
+
test_result = stmt.execute(BigDecimal.new("123.45")).first
|
182
|
+
expect(test_result['decimal_test']).to be_an_instance_of(BigDecimal)
|
183
|
+
expect(test_result['decimal_test']).to eql(123.45)
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should update a DECIMAL value passing a BigDecimal" do
|
187
|
+
@client.query 'USE test'
|
188
|
+
@client.query 'DROP TABLE IF EXISTS mysql2_stmt_decimal_test'
|
189
|
+
@client.query 'CREATE TABLE mysql2_stmt_decimal_test (decimal_test DECIMAL(10,3))'
|
190
|
+
|
191
|
+
@client.prepare("INSERT INTO mysql2_stmt_decimal_test VALUES (?)").execute(BigDecimal.new("123.45"))
|
192
|
+
|
193
|
+
test_result = @client.query("SELECT * FROM mysql2_stmt_decimal_test").first
|
194
|
+
expect(test_result['decimal_test']).to eql(123.45)
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should warn but still work if cache_rows is set to false" do
|
198
|
+
@client.query_options.merge!(:cache_rows => false)
|
199
|
+
statement = @client.prepare 'SELECT 1'
|
200
|
+
result = nil
|
201
|
+
expect { result = statement.execute.to_a }.to output(/:cache_rows is forced for prepared statements/).to_stderr
|
202
|
+
expect(result.length).to eq(1)
|
203
|
+
end
|
204
|
+
|
120
205
|
context "utf8_db" do
|
121
206
|
before(:each) do
|
122
207
|
@client.query("DROP DATABASE IF EXISTS test_mysql2_stmt_utf8")
|
@@ -249,18 +334,19 @@ RSpec.describe Mysql2::Statement do
|
|
249
334
|
end
|
250
335
|
|
251
336
|
context "#fields" do
|
252
|
-
before(:each) do
|
253
|
-
@client.query "USE test"
|
254
|
-
@test_result = @client.prepare("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").execute
|
255
|
-
end
|
256
|
-
|
257
337
|
it "method should exist" do
|
258
|
-
|
338
|
+
stmt = @client.prepare("SELECT 1")
|
339
|
+
expect(stmt).to respond_to(:fields)
|
259
340
|
end
|
260
341
|
|
261
342
|
it "should return an array of field names in proper order" do
|
262
|
-
|
263
|
-
expect(
|
343
|
+
stmt = @client.prepare("SELECT 'a', 'b', 'c'")
|
344
|
+
expect(stmt.fields).to eql(%w(a b c))
|
345
|
+
end
|
346
|
+
|
347
|
+
it "should return nil for statement with no result fields" do
|
348
|
+
stmt = @client.prepare("INSERT INTO mysql2_test () VALUES ()")
|
349
|
+
expect(stmt.fields).to eql(nil)
|
264
350
|
end
|
265
351
|
end
|
266
352
|
|
@@ -290,36 +376,47 @@ RSpec.describe Mysql2::Statement do
|
|
290
376
|
expect(@test_result['tiny_int_test']).to eql(1)
|
291
377
|
end
|
292
378
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
id2
|
298
|
-
|
299
|
-
|
379
|
+
context "cast booleans for TINYINT if :cast_booleans is enabled" do
|
380
|
+
# rubocop:disable Style/Semicolon
|
381
|
+
let(:client) { new_client(:cast_booleans => true) }
|
382
|
+
let(:id1) { client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES ( 1)'; client.last_id }
|
383
|
+
let(:id2) { client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES ( 0)'; client.last_id }
|
384
|
+
let(:id3) { client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (-1)'; client.last_id }
|
385
|
+
# rubocop:enable Style/Semicolon
|
300
386
|
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
expect(result1.first['bool_cast_test']).to be true
|
305
|
-
expect(result2.first['bool_cast_test']).to be false
|
306
|
-
expect(result3.first['bool_cast_test']).to be true
|
387
|
+
after do
|
388
|
+
client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2},#{id3})"
|
389
|
+
end
|
307
390
|
|
308
|
-
|
391
|
+
it "should return TrueClass or FalseClass for a TINYINT value if :cast_booleans is enabled" do
|
392
|
+
query = client.prepare 'SELECT bool_cast_test FROM mysql2_test WHERE id = ?'
|
393
|
+
result1 = query.execute id1
|
394
|
+
result2 = query.execute id2
|
395
|
+
result3 = query.execute id3
|
396
|
+
expect(result1.first['bool_cast_test']).to be true
|
397
|
+
expect(result2.first['bool_cast_test']).to be false
|
398
|
+
expect(result3.first['bool_cast_test']).to be true
|
399
|
+
end
|
309
400
|
end
|
310
401
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
id2
|
402
|
+
context "cast booleans for BIT(1) if :cast_booleans is enabled" do
|
403
|
+
# rubocop:disable Style/Semicolon
|
404
|
+
let(:client) { new_client(:cast_booleans => true) }
|
405
|
+
let(:id1) { client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (1)'; client.last_id }
|
406
|
+
let(:id2) { client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (0)'; client.last_id }
|
407
|
+
# rubocop:enable Style/Semicolon
|
316
408
|
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
expect(result2.first['single_bit_test']).to be false
|
409
|
+
after do
|
410
|
+
client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2})"
|
411
|
+
end
|
321
412
|
|
322
|
-
|
413
|
+
it "should return TrueClass or FalseClass for a BIT(1) value if :cast_booleans is enabled" do
|
414
|
+
query = client.prepare 'SELECT single_bit_test FROM mysql2_test WHERE id = ?'
|
415
|
+
result1 = query.execute id1
|
416
|
+
result2 = query.execute id2
|
417
|
+
expect(result1.first['single_bit_test']).to be true
|
418
|
+
expect(result2.first['single_bit_test']).to be false
|
419
|
+
end
|
323
420
|
end
|
324
421
|
|
325
422
|
it "should return Fixnum for a SMALLINT value" do
|
@@ -376,39 +473,39 @@ RSpec.describe Mysql2::Statement do
|
|
376
473
|
|
377
474
|
it "should return DateTime when timestamp is < 1901-12-13 20:45:52" do
|
378
475
|
# 1901-12-13T20:45:52 is the min for 32bit Ruby 1.8
|
379
|
-
r = @client.
|
476
|
+
r = @client.prepare("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test").execute
|
380
477
|
expect(r.first['test']).to be_an_instance_of(klass)
|
381
478
|
end
|
382
479
|
|
383
480
|
it "should return DateTime when timestamp is > 2038-01-19T03:14:07" do
|
384
481
|
# 2038-01-19T03:14:07 is the max for 32bit Ruby 1.8
|
385
|
-
r = @client.
|
482
|
+
r = @client.prepare("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test").execute
|
386
483
|
expect(r.first['test']).to be_an_instance_of(klass)
|
387
484
|
end
|
388
485
|
elsif 1.size == 8 # 64bit
|
389
486
|
if RUBY_VERSION =~ /1.8/
|
390
487
|
it "should return Time when timestamp is > 0138-12-31 11:59:59" do
|
391
|
-
r = @client.
|
488
|
+
r = @client.prepare("SELECT CAST('0139-1-1 00:00:00' AS DATETIME) as test").execute
|
392
489
|
expect(r.first['test']).to be_an_instance_of(Time)
|
393
490
|
end
|
394
491
|
|
395
492
|
it "should return DateTime when timestamp is < 0139-1-1T00:00:00" do
|
396
|
-
r = @client.
|
493
|
+
r = @client.prepare("SELECT CAST('0138-12-31 11:59:59' AS DATETIME) as test").execute
|
397
494
|
expect(r.first['test']).to be_an_instance_of(DateTime)
|
398
495
|
end
|
399
496
|
|
400
497
|
it "should return Time when timestamp is > 2038-01-19T03:14:07" do
|
401
|
-
r = @client.
|
498
|
+
r = @client.prepare("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test").execute
|
402
499
|
expect(r.first['test']).to be_an_instance_of(Time)
|
403
500
|
end
|
404
501
|
else
|
405
502
|
it "should return Time when timestamp is < 1901-12-13 20:45:52" do
|
406
|
-
r = @client.
|
503
|
+
r = @client.prepare("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test").execute
|
407
504
|
expect(r.first['test']).to be_an_instance_of(Time)
|
408
505
|
end
|
409
506
|
|
410
507
|
it "should return Time when timestamp is > 2038-01-19T03:14:07" do
|
411
|
-
r = @client.
|
508
|
+
r = @client.prepare("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test").execute
|
412
509
|
expect(r.first['test']).to be_an_instance_of(Time)
|
413
510
|
end
|
414
511
|
end
|
@@ -447,10 +544,9 @@ RSpec.describe Mysql2::Statement do
|
|
447
544
|
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
448
545
|
expect(result['enum_test'].encoding).to eql(Encoding::UTF_8)
|
449
546
|
|
450
|
-
client2 =
|
547
|
+
client2 = new_client(:encoding => 'ascii')
|
451
548
|
result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
452
549
|
expect(result['enum_test'].encoding).to eql(Encoding::US_ASCII)
|
453
|
-
client2.close
|
454
550
|
end
|
455
551
|
end
|
456
552
|
|
@@ -480,10 +576,9 @@ RSpec.describe Mysql2::Statement do
|
|
480
576
|
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
481
577
|
expect(result['set_test'].encoding).to eql(Encoding::UTF_8)
|
482
578
|
|
483
|
-
client2 =
|
579
|
+
client2 = new_client(:encoding => 'ascii')
|
484
580
|
result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
485
581
|
expect(result['set_test'].encoding).to eql(Encoding::US_ASCII)
|
486
|
-
client2.close
|
487
582
|
end
|
488
583
|
end
|
489
584
|
|
@@ -574,10 +669,9 @@ RSpec.describe Mysql2::Statement do
|
|
574
669
|
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
575
670
|
expect(result[field].encoding).to eql(Encoding::UTF_8)
|
576
671
|
|
577
|
-
client2 =
|
672
|
+
client2 = new_client(:encoding => 'ascii')
|
578
673
|
result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
579
674
|
expect(result[field].encoding).to eql(Encoding::US_ASCII)
|
580
|
-
client2.close
|
581
675
|
end
|
582
676
|
end
|
583
677
|
|
@@ -670,9 +764,7 @@ RSpec.describe Mysql2::Statement do
|
|
670
764
|
context 'close' do
|
671
765
|
it 'should free server resources' do
|
672
766
|
stmt = @client.prepare 'SELECT 1'
|
673
|
-
expect { stmt.close }.to change
|
674
|
-
@client.query("SHOW STATUS LIKE 'Prepared_stmt_count'").first['Value'].to_i
|
675
|
-
}.by(-1)
|
767
|
+
expect { stmt.close }.to change(&method(:stmt_count)).by(-1)
|
676
768
|
end
|
677
769
|
|
678
770
|
it 'should raise an error on subsequent execution' do
|
data/spec/spec_helper.rb
CHANGED
@@ -23,72 +23,86 @@ RSpec.configure do |config|
|
|
23
23
|
$VERBOSE = old_verbose
|
24
24
|
end
|
25
25
|
|
26
|
+
def new_client(option_overrides = {})
|
27
|
+
client = Mysql2::Client.new(DatabaseCredentials['root'].merge(option_overrides))
|
28
|
+
@clients ||= []
|
29
|
+
@clients << client
|
30
|
+
return client unless block_given?
|
31
|
+
begin
|
32
|
+
yield client
|
33
|
+
ensure
|
34
|
+
client.close
|
35
|
+
@clients.delete(client)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
26
39
|
config.before :each do
|
27
|
-
@client =
|
40
|
+
@client = new_client
|
28
41
|
end
|
29
42
|
|
30
43
|
config.after :each do
|
31
|
-
@
|
44
|
+
@clients.each(&:close)
|
32
45
|
end
|
33
46
|
|
34
47
|
config.before(:all) do
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
48
|
+
new_client do |client|
|
49
|
+
client.query %[
|
50
|
+
CREATE TABLE IF NOT EXISTS mysql2_test (
|
51
|
+
id MEDIUMINT NOT NULL AUTO_INCREMENT,
|
52
|
+
null_test VARCHAR(10),
|
53
|
+
bit_test BIT(64),
|
54
|
+
single_bit_test BIT(1),
|
55
|
+
tiny_int_test TINYINT,
|
56
|
+
bool_cast_test TINYINT(1),
|
57
|
+
small_int_test SMALLINT,
|
58
|
+
medium_int_test MEDIUMINT,
|
59
|
+
int_test INT,
|
60
|
+
big_int_test BIGINT,
|
61
|
+
float_test FLOAT(10,3),
|
62
|
+
float_zero_test FLOAT(10,3),
|
63
|
+
double_test DOUBLE(10,3),
|
64
|
+
decimal_test DECIMAL(10,3),
|
65
|
+
decimal_zero_test DECIMAL(10,3),
|
66
|
+
date_test DATE,
|
67
|
+
date_time_test DATETIME,
|
68
|
+
timestamp_test TIMESTAMP,
|
69
|
+
time_test TIME,
|
70
|
+
year_test YEAR(4),
|
71
|
+
char_test CHAR(10),
|
72
|
+
varchar_test VARCHAR(10),
|
73
|
+
binary_test BINARY(10),
|
74
|
+
varbinary_test VARBINARY(10),
|
75
|
+
tiny_blob_test TINYBLOB,
|
76
|
+
tiny_text_test TINYTEXT,
|
77
|
+
blob_test BLOB,
|
78
|
+
text_test TEXT,
|
79
|
+
medium_blob_test MEDIUMBLOB,
|
80
|
+
medium_text_test MEDIUMTEXT,
|
81
|
+
long_blob_test LONGBLOB,
|
82
|
+
long_text_test LONGTEXT,
|
83
|
+
enum_test ENUM('val1', 'val2'),
|
84
|
+
set_test SET('val1', 'val2'),
|
85
|
+
PRIMARY KEY (id)
|
86
|
+
)
|
87
|
+
]
|
88
|
+
client.query "DELETE FROM mysql2_test;"
|
89
|
+
client.query %[
|
90
|
+
INSERT INTO mysql2_test (
|
91
|
+
null_test, bit_test, single_bit_test, tiny_int_test, bool_cast_test, small_int_test, medium_int_test, int_test, big_int_test,
|
92
|
+
float_test, float_zero_test, double_test, decimal_test, decimal_zero_test, date_test, date_time_test, timestamp_test, time_test,
|
93
|
+
year_test, char_test, varchar_test, binary_test, varbinary_test, tiny_blob_test,
|
94
|
+
tiny_text_test, blob_test, text_test, medium_blob_test, medium_text_test,
|
95
|
+
long_blob_test, long_text_test, enum_test, set_test
|
96
|
+
)
|
84
97
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
98
|
+
VALUES (
|
99
|
+
NULL, b'101', b'1', 1, 1, 10, 10, 10, 10,
|
100
|
+
10.3, 0, 10.3, 10.3, 0, '2010-4-4', '2010-4-4 11:44:00', '2010-4-4 11:44:00', '11:44:00',
|
101
|
+
2009, "test", "test", "test", "test", "test",
|
102
|
+
"test", "test", "test", "test", "test",
|
103
|
+
"test", "test", 'val1', 'val1,val2'
|
104
|
+
)
|
105
|
+
]
|
106
|
+
end
|
93
107
|
end
|
94
108
|
end
|