mysql2 0.3.20 → 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/CHANGELOG.md +1 -0
- data/README.md +132 -55
- data/examples/eventmachine.rb +1 -1
- data/examples/threaded.rb +4 -6
- data/ext/mysql2/client.c +323 -140
- data/ext/mysql2/client.h +13 -3
- data/ext/mysql2/extconf.rb +111 -44
- data/ext/mysql2/infile.c +2 -2
- data/ext/mysql2/mysql2_ext.c +1 -0
- data/ext/mysql2/mysql2_ext.h +5 -10
- data/ext/mysql2/mysql_enc_name_to_ruby.h +2 -2
- data/ext/mysql2/mysql_enc_to_ruby.h +25 -22
- data/ext/mysql2/result.c +491 -97
- data/ext/mysql2/result.h +12 -4
- data/ext/mysql2/statement.c +595 -0
- data/ext/mysql2/statement.h +19 -0
- data/lib/mysql2/client.rb +82 -27
- data/lib/mysql2/console.rb +1 -1
- data/lib/mysql2/em.rb +5 -6
- data/lib/mysql2/error.rb +17 -26
- data/lib/mysql2/field.rb +3 -0
- data/lib/mysql2/statement.rb +17 -0
- data/lib/mysql2/version.rb +1 -1
- data/lib/mysql2.rb +38 -18
- data/spec/configuration.yml.example +0 -6
- data/spec/em/em_spec.rb +22 -21
- data/spec/mysql2/client_spec.rb +498 -380
- data/spec/mysql2/error_spec.rb +38 -39
- data/spec/mysql2/result_spec.rb +260 -229
- data/spec/mysql2/statement_spec.rb +776 -0
- data/spec/spec_helper.rb +80 -59
- 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/5072E1F5.asc +432 -0
- data/support/mysql_enc_to_ruby.rb +7 -8
- data/support/ruby_enc_to_mysql.rb +1 -1
- metadata +50 -55
data/spec/mysql2/result_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
|
-
describe Mysql2::Result do
|
4
|
+
RSpec.describe Mysql2::Result do
|
5
5
|
before(:each) do
|
6
6
|
@result = @client.query "SELECT 1"
|
7
7
|
end
|
@@ -15,33 +15,37 @@ describe Mysql2::Result do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
it "should have included Enumerable" do
|
18
|
-
Mysql2::Result.ancestors.include?(Enumerable).
|
18
|
+
expect(Mysql2::Result.ancestors.include?(Enumerable)).to be true
|
19
19
|
end
|
20
20
|
|
21
21
|
it "should respond to #each" do
|
22
|
-
@result.
|
22
|
+
expect(@result).to respond_to(:each)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should respond to #free" do
|
26
|
+
expect(@result).to respond_to(:free)
|
23
27
|
end
|
24
28
|
|
25
29
|
it "should raise a Mysql2::Error exception upon a bad query" do
|
26
|
-
|
30
|
+
expect {
|
27
31
|
@client.query "bad sql"
|
28
|
-
}.
|
32
|
+
}.to raise_error(Mysql2::Error)
|
29
33
|
|
30
|
-
|
34
|
+
expect {
|
31
35
|
@client.query "SELECT 1"
|
32
|
-
}.
|
36
|
+
}.not_to raise_error
|
33
37
|
end
|
34
38
|
|
35
39
|
it "should respond to #count, which is aliased as #size" do
|
36
40
|
r = @client.query "SELECT 1"
|
37
|
-
r.
|
38
|
-
r.
|
41
|
+
expect(r).to respond_to :count
|
42
|
+
expect(r).to respond_to :size
|
39
43
|
end
|
40
44
|
|
41
45
|
it "should be able to return the number of rows in the result set" do
|
42
46
|
r = @client.query "SELECT 1"
|
43
|
-
r.count.
|
44
|
-
r.size.
|
47
|
+
expect(r.count).to eql(1)
|
48
|
+
expect(r.size).to eql(1)
|
45
49
|
end
|
46
50
|
|
47
51
|
context "metadata queries" do
|
@@ -53,39 +57,44 @@ describe Mysql2::Result do
|
|
53
57
|
context "#each" do
|
54
58
|
it "should yield rows as hash's" do
|
55
59
|
@result.each do |row|
|
56
|
-
row.
|
60
|
+
expect(row).to be_an_instance_of(Hash)
|
57
61
|
end
|
58
62
|
end
|
59
63
|
|
60
64
|
it "should yield rows as hash's with symbol keys if :symbolize_keys was set to true" do
|
61
65
|
@result.each(:symbolize_keys => true) do |row|
|
62
|
-
row.keys.first.
|
66
|
+
expect(row.keys.first).to be_an_instance_of(Symbol)
|
63
67
|
end
|
64
68
|
end
|
65
69
|
|
66
70
|
it "should be able to return results as an array" do
|
67
71
|
@result.each(:as => :array) do |row|
|
68
|
-
row.
|
72
|
+
expect(row).to be_an_instance_of(Array)
|
69
73
|
end
|
70
74
|
end
|
71
75
|
|
72
76
|
it "should cache previously yielded results by default" do
|
73
|
-
@result.first.object_id.
|
77
|
+
expect(@result.first.object_id).to eql(@result.first.object_id)
|
74
78
|
end
|
75
79
|
|
76
80
|
it "should not cache previously yielded results if cache_rows is disabled" do
|
77
81
|
result = @client.query "SELECT 1", :cache_rows => false
|
78
|
-
result.first.object_id.
|
82
|
+
expect(result.first.object_id).not_to eql(result.first.object_id)
|
83
|
+
end
|
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)
|
79
88
|
end
|
80
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
|
-
result.first.
|
92
|
+
expect(result.first).not_to eql(result.first)
|
84
93
|
end
|
85
94
|
|
86
95
|
it "should yield the same value for #first if streaming is disabled" do
|
87
96
|
result = @client.query "SELECT 1 UNION SELECT 2", :stream => false
|
88
|
-
result.first.
|
97
|
+
expect(result.first).to eql(result.first)
|
89
98
|
end
|
90
99
|
|
91
100
|
it "should throw an exception if we try to iterate twice when streaming is enabled" do
|
@@ -104,64 +113,63 @@ describe Mysql2::Result do
|
|
104
113
|
end
|
105
114
|
|
106
115
|
it "method should exist" do
|
107
|
-
@test_result.
|
116
|
+
expect(@test_result).to respond_to(:fields)
|
108
117
|
end
|
109
118
|
|
110
119
|
it "should return an array of field names in proper order" do
|
111
120
|
result = @client.query "SELECT 'a', 'b', 'c'"
|
112
|
-
result.fields.
|
121
|
+
expect(result.fields).to eql(%w(a b c))
|
113
122
|
end
|
114
123
|
end
|
115
124
|
|
116
125
|
context "streaming" do
|
117
126
|
it "should maintain a count while streaming" do
|
118
127
|
result = @client.query('SELECT 1', :stream => true, :cache_rows => false)
|
119
|
-
result.count.
|
128
|
+
expect(result.count).to eql(0)
|
120
129
|
result.each.to_a
|
121
|
-
result.count.
|
130
|
+
expect(result.count).to eql(1)
|
122
131
|
end
|
123
132
|
|
124
133
|
it "should retain the count when mixing first and each" do
|
125
134
|
result = @client.query("SELECT 1 UNION SELECT 2", :stream => true, :cache_rows => false)
|
126
|
-
result.count.
|
135
|
+
expect(result.count).to eql(0)
|
127
136
|
result.first
|
128
|
-
result.count.
|
137
|
+
expect(result.count).to eql(1)
|
129
138
|
result.each.to_a
|
130
|
-
result.count.
|
139
|
+
expect(result.count).to eql(2)
|
131
140
|
end
|
132
141
|
|
133
142
|
it "should not yield nil at the end of streaming" do
|
134
143
|
result = @client.query('SELECT * FROM mysql2_test', :stream => true, :cache_rows => false)
|
135
|
-
result.each { |r| r.
|
144
|
+
result.each { |r| expect(r).not_to be_nil }
|
136
145
|
end
|
137
146
|
|
138
147
|
it "#count should be zero for rows after streaming when there were no results" do
|
148
|
+
@client.query "USE test"
|
139
149
|
result = @client.query("SELECT * FROM mysql2_test WHERE null_test IS NOT NULL", :stream => true, :cache_rows => false)
|
140
|
-
result.count.
|
150
|
+
expect(result.count).to eql(0)
|
141
151
|
result.each.to_a
|
142
|
-
result.count.
|
152
|
+
expect(result.count).to eql(0)
|
143
153
|
end
|
144
154
|
|
145
155
|
it "should raise an exception if streaming ended due to a timeout" do
|
146
|
-
|
147
|
-
client = Mysql2::Client.new DatabaseCredentials['root']
|
148
|
-
client.query "CREATE TEMPORARY TABLE streamingTest (val BINARY(255)) ENGINE=MEMORY"
|
156
|
+
@client.query "CREATE TEMPORARY TABLE streamingTest (val BINARY(255)) ENGINE=MEMORY"
|
149
157
|
|
150
158
|
# Insert enough records to force the result set into multiple reads
|
151
159
|
# (the BINARY type is used simply because it forces full width results)
|
152
160
|
10000.times do |i|
|
153
|
-
client.query "INSERT INTO streamingTest (val) VALUES ('Foo #{i}')"
|
161
|
+
@client.query "INSERT INTO streamingTest (val) VALUES ('Foo #{i}')"
|
154
162
|
end
|
155
163
|
|
156
|
-
client.query "SET net_write_timeout = 1"
|
157
|
-
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
|
158
166
|
|
159
|
-
|
160
|
-
res.each_with_index do |
|
167
|
+
expect {
|
168
|
+
res.each_with_index do |_, i|
|
161
169
|
# Exhaust the first result packet then trigger a timeout
|
162
170
|
sleep 2 if i > 0 && i % 1000 == 0
|
163
171
|
end
|
164
|
-
}.
|
172
|
+
}.to raise_error(Mysql2::Error, /Lost connection/)
|
165
173
|
end
|
166
174
|
end
|
167
175
|
|
@@ -172,273 +180,297 @@ describe Mysql2::Result do
|
|
172
180
|
|
173
181
|
it "should return nil values for NULL and strings for everything else when :cast is false" do
|
174
182
|
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
|
175
|
-
result["null_test"].
|
176
|
-
result["tiny_int_test"].
|
177
|
-
result["bool_cast_test"].
|
178
|
-
result["int_test"].
|
179
|
-
result["date_test"].
|
180
|
-
result["enum_test"].
|
183
|
+
expect(result["null_test"]).to be_nil
|
184
|
+
expect(result["tiny_int_test"]).to eql("1")
|
185
|
+
expect(result["bool_cast_test"]).to eql("1")
|
186
|
+
expect(result["int_test"]).to eql("10")
|
187
|
+
expect(result["date_test"]).to eql("2010-04-04")
|
188
|
+
expect(result["enum_test"]).to eql("val1")
|
181
189
|
end
|
182
190
|
|
183
191
|
it "should return nil for a NULL value" do
|
184
|
-
@test_result['null_test'].
|
185
|
-
@test_result['null_test'].
|
192
|
+
expect(@test_result['null_test']).to be_an_instance_of(NilClass)
|
193
|
+
expect(@test_result['null_test']).to eql(nil)
|
186
194
|
end
|
187
195
|
|
188
196
|
it "should return String for a BIT(64) value" do
|
189
|
-
@test_result['bit_test'].
|
190
|
-
@test_result['bit_test'].
|
197
|
+
expect(@test_result['bit_test']).to be_an_instance_of(String)
|
198
|
+
expect(@test_result['bit_test']).to eql("\000\000\000\000\000\000\000\005")
|
191
199
|
end
|
192
200
|
|
193
201
|
it "should return String for a BIT(1) value" do
|
194
|
-
@test_result['single_bit_test'].
|
195
|
-
@test_result['single_bit_test'].
|
202
|
+
expect(@test_result['single_bit_test']).to be_an_instance_of(String)
|
203
|
+
expect(@test_result['single_bit_test']).to eql("\001")
|
196
204
|
end
|
197
205
|
|
198
206
|
it "should return Fixnum for a TINYINT value" do
|
199
|
-
[Fixnum, Bignum].
|
200
|
-
@test_result['tiny_int_test'].
|
207
|
+
expect([Fixnum, Bignum]).to include(@test_result['tiny_int_test'].class)
|
208
|
+
expect(@test_result['tiny_int_test']).to eql(1)
|
201
209
|
end
|
202
210
|
|
203
|
-
|
204
|
-
|
205
|
-
id1
|
206
|
-
@client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (0)'
|
207
|
-
|
208
|
-
|
209
|
-
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
|
210
217
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
result1.first['bool_cast_test'].should be_true
|
215
|
-
result2.first['bool_cast_test'].should be_false
|
216
|
-
result3.first['bool_cast_test'].should be_true
|
218
|
+
after do
|
219
|
+
@client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2},#{id3})"
|
220
|
+
end
|
217
221
|
|
218
|
-
|
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
|
219
230
|
end
|
220
231
|
|
221
|
-
|
222
|
-
|
223
|
-
id1
|
224
|
-
@client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (0)'
|
225
|
-
|
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
|
226
237
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
result2.first['single_bit_test'].should be_false
|
238
|
+
after do
|
239
|
+
@client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2})"
|
240
|
+
end
|
231
241
|
|
232
|
-
|
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
|
233
248
|
end
|
234
249
|
|
235
250
|
it "should return Fixnum for a SMALLINT value" do
|
236
|
-
[Fixnum, Bignum].
|
237
|
-
@test_result['small_int_test'].
|
251
|
+
expect([Fixnum, Bignum]).to include(@test_result['small_int_test'].class)
|
252
|
+
expect(@test_result['small_int_test']).to eql(10)
|
238
253
|
end
|
239
254
|
|
240
255
|
it "should return Fixnum for a MEDIUMINT value" do
|
241
|
-
[Fixnum, Bignum].
|
242
|
-
@test_result['medium_int_test'].
|
256
|
+
expect([Fixnum, Bignum]).to include(@test_result['medium_int_test'].class)
|
257
|
+
expect(@test_result['medium_int_test']).to eql(10)
|
243
258
|
end
|
244
259
|
|
245
260
|
it "should return Fixnum for an INT value" do
|
246
|
-
[Fixnum, Bignum].
|
247
|
-
@test_result['int_test'].
|
261
|
+
expect([Fixnum, Bignum]).to include(@test_result['int_test'].class)
|
262
|
+
expect(@test_result['int_test']).to eql(10)
|
248
263
|
end
|
249
264
|
|
250
265
|
it "should return Fixnum for a BIGINT value" do
|
251
|
-
[Fixnum, Bignum].
|
252
|
-
@test_result['big_int_test'].
|
266
|
+
expect([Fixnum, Bignum]).to include(@test_result['big_int_test'].class)
|
267
|
+
expect(@test_result['big_int_test']).to eql(10)
|
253
268
|
end
|
254
269
|
|
255
270
|
it "should return Fixnum for a YEAR value" do
|
256
|
-
[Fixnum, Bignum].
|
257
|
-
@test_result['year_test'].
|
271
|
+
expect([Fixnum, Bignum]).to include(@test_result['year_test'].class)
|
272
|
+
expect(@test_result['year_test']).to eql(2009)
|
258
273
|
end
|
259
274
|
|
260
275
|
it "should return BigDecimal for a DECIMAL value" do
|
261
|
-
@test_result['decimal_test'].
|
262
|
-
@test_result['decimal_test'].
|
276
|
+
expect(@test_result['decimal_test']).to be_an_instance_of(BigDecimal)
|
277
|
+
expect(@test_result['decimal_test']).to eql(10.3)
|
263
278
|
end
|
264
279
|
|
265
280
|
it "should return Float for a FLOAT value" do
|
266
|
-
@test_result['float_test'].
|
267
|
-
@test_result['float_test'].
|
281
|
+
expect(@test_result['float_test']).to be_an_instance_of(Float)
|
282
|
+
expect(@test_result['float_test']).to eql(10.3)
|
268
283
|
end
|
269
284
|
|
270
285
|
it "should return Float for a DOUBLE value" do
|
271
|
-
@test_result['double_test'].
|
272
|
-
@test_result['double_test'].
|
286
|
+
expect(@test_result['double_test']).to be_an_instance_of(Float)
|
287
|
+
expect(@test_result['double_test']).to eql(10.3)
|
273
288
|
end
|
274
289
|
|
275
290
|
it "should return Time for a DATETIME value when within the supported range" do
|
276
|
-
@test_result['date_time_test'].
|
277
|
-
@test_result['date_time_test'].strftime("%Y-%m-%d %H:%M:%S").
|
291
|
+
expect(@test_result['date_time_test']).to be_an_instance_of(Time)
|
292
|
+
expect(@test_result['date_time_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2010-04-04 11:44:00')
|
293
|
+
end
|
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
|
278
317
|
end
|
279
318
|
|
280
319
|
if 1.size == 4 # 32bit
|
281
|
-
|
282
|
-
|
320
|
+
klass = if RUBY_VERSION =~ /1.8/
|
321
|
+
DateTime
|
283
322
|
else
|
284
|
-
|
323
|
+
Time
|
285
324
|
end
|
286
325
|
|
287
326
|
it "should return DateTime when timestamp is < 1901-12-13 20:45:52" do
|
288
|
-
|
327
|
+
# 1901-12-13T20:45:52 is the min for 32bit Ruby 1.8
|
289
328
|
r = @client.query("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test")
|
290
|
-
r.first['test'].
|
329
|
+
expect(r.first['test']).to be_an_instance_of(klass)
|
291
330
|
end
|
292
331
|
|
293
332
|
it "should return DateTime when timestamp is > 2038-01-19T03:14:07" do
|
294
|
-
|
333
|
+
# 2038-01-19T03:14:07 is the max for 32bit Ruby 1.8
|
295
334
|
r = @client.query("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test")
|
296
|
-
r.first['test'].
|
335
|
+
expect(r.first['test']).to be_an_instance_of(klass)
|
297
336
|
end
|
298
337
|
elsif 1.size == 8 # 64bit
|
299
|
-
|
300
|
-
it "should return Time when timestamp is < 1901-12-13 20:45:52" do
|
301
|
-
r = @client.query("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test")
|
302
|
-
r.first['test'].class.should eql(Time)
|
303
|
-
end
|
304
|
-
|
305
|
-
it "should return Time when timestamp is > 2038-01-19T03:14:07" do
|
306
|
-
r = @client.query("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test")
|
307
|
-
r.first['test'].class.should eql(Time)
|
308
|
-
end
|
309
|
-
else
|
338
|
+
if RUBY_VERSION =~ /1.8/
|
310
339
|
it "should return Time when timestamp is > 0138-12-31 11:59:59" do
|
311
340
|
r = @client.query("SELECT CAST('0139-1-1 00:00:00' AS DATETIME) as test")
|
312
|
-
r.first['test'].
|
341
|
+
expect(r.first['test']).to be_an_instance_of(Time)
|
313
342
|
end
|
314
343
|
|
315
344
|
it "should return DateTime when timestamp is < 0139-1-1T00:00:00" do
|
316
345
|
r = @client.query("SELECT CAST('0138-12-31 11:59:59' AS DATETIME) as test")
|
317
|
-
r.first['test'].
|
346
|
+
expect(r.first['test']).to be_an_instance_of(DateTime)
|
318
347
|
end
|
319
348
|
|
320
349
|
it "should return Time when timestamp is > 2038-01-19T03:14:07" do
|
321
350
|
r = @client.query("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test")
|
322
|
-
r.first['test'].
|
351
|
+
expect(r.first['test']).to be_an_instance_of(Time)
|
352
|
+
end
|
353
|
+
else
|
354
|
+
it "should return Time when timestamp is < 1901-12-13 20:45:52" do
|
355
|
+
r = @client.query("SELECT CAST('1901-12-13 20:45:51' AS DATETIME) as test")
|
356
|
+
expect(r.first['test']).to be_an_instance_of(Time)
|
357
|
+
end
|
358
|
+
|
359
|
+
it "should return Time when timestamp is > 2038-01-19T03:14:07" do
|
360
|
+
r = @client.query("SELECT CAST('2038-01-19 03:14:08' AS DATETIME) as test")
|
361
|
+
expect(r.first['test']).to be_an_instance_of(Time)
|
323
362
|
end
|
324
363
|
end
|
325
364
|
end
|
326
365
|
|
327
366
|
it "should return Time for a TIMESTAMP value when within the supported range" do
|
328
|
-
@test_result['timestamp_test'].
|
329
|
-
@test_result['timestamp_test'].strftime("%Y-%m-%d %H:%M:%S").
|
367
|
+
expect(@test_result['timestamp_test']).to be_an_instance_of(Time)
|
368
|
+
expect(@test_result['timestamp_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2010-04-04 11:44:00')
|
330
369
|
end
|
331
370
|
|
332
371
|
it "should return Time for a TIME value" do
|
333
|
-
@test_result['time_test'].
|
334
|
-
@test_result['time_test'].strftime("%Y-%m-%d %H:%M:%S").
|
372
|
+
expect(@test_result['time_test']).to be_an_instance_of(Time)
|
373
|
+
expect(@test_result['time_test'].strftime("%Y-%m-%d %H:%M:%S")).to eql('2000-01-01 11:44:00')
|
335
374
|
end
|
336
375
|
|
337
376
|
it "should return Date for a DATE value" do
|
338
|
-
@test_result['date_test'].
|
339
|
-
@test_result['date_test'].strftime("%Y-%m-%d").
|
377
|
+
expect(@test_result['date_test']).to be_an_instance_of(Date)
|
378
|
+
expect(@test_result['date_test'].strftime("%Y-%m-%d")).to eql('2010-04-04')
|
340
379
|
end
|
341
380
|
|
342
381
|
it "should return String for an ENUM value" do
|
343
|
-
@test_result['enum_test'].
|
344
|
-
@test_result['enum_test'].
|
382
|
+
expect(@test_result['enum_test']).to be_an_instance_of(String)
|
383
|
+
expect(@test_result['enum_test']).to eql('val1')
|
345
384
|
end
|
346
385
|
|
347
386
|
it "should raise an error given an invalid DATETIME" do
|
348
|
-
|
349
|
-
|
350
|
-
rescue Mysql2::Error => e
|
351
|
-
error = e
|
352
|
-
end
|
353
|
-
|
354
|
-
error.message.should eql("Invalid date in field 'bad_datetime': 1972-00-27 00:00:00")
|
387
|
+
expect { @client.query("SELECT CAST('1972-00-27 00:00:00' AS DATETIME) as bad_datetime").each }.to \
|
388
|
+
raise_error(Mysql2::Error, "Invalid date in field 'bad_datetime': 1972-00-27 00:00:00")
|
355
389
|
end
|
356
390
|
|
357
|
-
|
358
|
-
|
359
|
-
it "should default to the connection's encoding if Encoding.default_internal is nil" do
|
360
|
-
with_internal_encoding nil do
|
361
|
-
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
362
|
-
result['enum_test'].encoding.should eql(Encoding.find('utf-8'))
|
391
|
+
context "string encoding for ENUM values" do
|
392
|
+
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
363
393
|
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
394
|
+
it "should default to the connection's encoding if Encoding.default_internal is nil" do
|
395
|
+
with_internal_encoding nil do
|
396
|
+
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
397
|
+
expect(result['enum_test'].encoding).to eql(Encoding::UTF_8)
|
398
|
+
|
399
|
+
client2 = new_client(:encoding => 'ascii')
|
400
|
+
result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
401
|
+
expect(result['enum_test'].encoding).to eql(Encoding::ASCII)
|
369
402
|
end
|
403
|
+
end
|
370
404
|
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
405
|
+
it "should use Encoding.default_internal" do
|
406
|
+
with_internal_encoding Encoding::UTF_8 do
|
407
|
+
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
408
|
+
expect(result['enum_test'].encoding).to eql(Encoding.default_internal)
|
409
|
+
end
|
376
410
|
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
end
|
411
|
+
with_internal_encoding Encoding::ASCII do
|
412
|
+
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
413
|
+
expect(result['enum_test'].encoding).to eql(Encoding.default_internal)
|
381
414
|
end
|
382
415
|
end
|
383
416
|
end
|
384
417
|
|
385
418
|
it "should return String for a SET value" do
|
386
|
-
@test_result['set_test'].
|
387
|
-
@test_result['set_test'].
|
419
|
+
expect(@test_result['set_test']).to be_an_instance_of(String)
|
420
|
+
expect(@test_result['set_test']).to eql('val1,val2')
|
388
421
|
end
|
389
422
|
|
390
|
-
|
391
|
-
|
392
|
-
it "should default to the connection's encoding if Encoding.default_internal is nil" do
|
393
|
-
with_internal_encoding nil do
|
394
|
-
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
395
|
-
result['set_test'].encoding.should eql(Encoding.find('utf-8'))
|
423
|
+
context "string encoding for SET values" do
|
424
|
+
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
396
425
|
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
426
|
+
it "should default to the connection's encoding if Encoding.default_internal is nil" do
|
427
|
+
with_internal_encoding nil do
|
428
|
+
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
429
|
+
expect(result['set_test'].encoding).to eql(Encoding::UTF_8)
|
430
|
+
|
431
|
+
client2 = new_client(:encoding => 'ascii')
|
432
|
+
result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
433
|
+
expect(result['set_test'].encoding).to eql(Encoding::ASCII)
|
402
434
|
end
|
435
|
+
end
|
403
436
|
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
437
|
+
it "should use Encoding.default_internal" do
|
438
|
+
with_internal_encoding Encoding::UTF_8 do
|
439
|
+
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
440
|
+
expect(result['set_test'].encoding).to eql(Encoding.default_internal)
|
441
|
+
end
|
409
442
|
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
end
|
443
|
+
with_internal_encoding Encoding::ASCII do
|
444
|
+
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
445
|
+
expect(result['set_test'].encoding).to eql(Encoding.default_internal)
|
414
446
|
end
|
415
447
|
end
|
416
448
|
end
|
417
449
|
|
418
450
|
it "should return String for a BINARY value" do
|
419
|
-
@test_result['binary_test'].
|
420
|
-
@test_result['binary_test'].
|
451
|
+
expect(@test_result['binary_test']).to be_an_instance_of(String)
|
452
|
+
expect(@test_result['binary_test']).to eql("test#{"\000" * 6}")
|
421
453
|
end
|
422
454
|
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
455
|
+
context "string encoding for BINARY values" do
|
456
|
+
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
457
|
+
|
458
|
+
it "should default to binary if Encoding.default_internal is nil" do
|
459
|
+
with_internal_encoding nil do
|
460
|
+
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
461
|
+
expect(result['binary_test'].encoding).to eql(Encoding::BINARY)
|
430
462
|
end
|
463
|
+
end
|
431
464
|
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
465
|
+
it "should not use Encoding.default_internal" do
|
466
|
+
with_internal_encoding Encoding::UTF_8 do
|
467
|
+
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
468
|
+
expect(result['binary_test'].encoding).to eql(Encoding::BINARY)
|
469
|
+
end
|
437
470
|
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
end
|
471
|
+
with_internal_encoding Encoding::ASCII do
|
472
|
+
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
473
|
+
expect(result['binary_test'].encoding).to eql(Encoding::BINARY)
|
442
474
|
end
|
443
475
|
end
|
444
476
|
end
|
@@ -454,57 +486,56 @@ describe Mysql2::Result do
|
|
454
486
|
'medium_blob_test' => 'MEDIUMBLOB',
|
455
487
|
'medium_text_test' => 'MEDIUMTEXT',
|
456
488
|
'long_blob_test' => 'LONGBLOB',
|
457
|
-
'long_text_test' => 'LONGTEXT'
|
489
|
+
'long_text_test' => 'LONGTEXT',
|
458
490
|
}.each do |field, type|
|
459
491
|
it "should return a String for #{type}" do
|
460
|
-
@test_result[field].
|
461
|
-
@test_result[field].
|
492
|
+
expect(@test_result[field]).to be_an_instance_of(String)
|
493
|
+
expect(@test_result[field]).to eql("test")
|
462
494
|
end
|
463
495
|
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
496
|
+
context "string encoding for #{type} values" do
|
497
|
+
before { pending('Encoding is undefined') unless defined?(Encoding) }
|
498
|
+
|
499
|
+
if %w(VARBINARY TINYBLOB BLOB MEDIUMBLOB LONGBLOB).include?(type)
|
500
|
+
it "should default to binary if Encoding.default_internal is nil" do
|
501
|
+
with_internal_encoding nil do
|
502
|
+
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
503
|
+
expect(result['binary_test'].encoding).to eql(Encoding::BINARY)
|
472
504
|
end
|
505
|
+
end
|
473
506
|
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
507
|
+
it "should not use Encoding.default_internal" do
|
508
|
+
with_internal_encoding Encoding::UTF_8 do
|
509
|
+
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
510
|
+
expect(result['binary_test'].encoding).to eql(Encoding::BINARY)
|
511
|
+
end
|
479
512
|
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
end
|
513
|
+
with_internal_encoding Encoding::ASCII do
|
514
|
+
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
515
|
+
expect(result['binary_test'].encoding).to eql(Encoding::BINARY)
|
484
516
|
end
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
end
|
517
|
+
end
|
518
|
+
else
|
519
|
+
it "should default to utf-8 if Encoding.default_internal is nil" do
|
520
|
+
with_internal_encoding nil do
|
521
|
+
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
522
|
+
expect(result[field].encoding).to eql(Encoding::UTF_8)
|
523
|
+
|
524
|
+
client2 = new_client(:encoding => 'ascii')
|
525
|
+
result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
526
|
+
expect(result[field].encoding).to eql(Encoding::ASCII)
|
496
527
|
end
|
528
|
+
end
|
497
529
|
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
530
|
+
it "should use Encoding.default_internal" do
|
531
|
+
with_internal_encoding Encoding::UTF_8 do
|
532
|
+
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
533
|
+
expect(result[field].encoding).to eql(Encoding.default_internal)
|
534
|
+
end
|
503
535
|
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
end
|
536
|
+
with_internal_encoding Encoding::ASCII do
|
537
|
+
result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
538
|
+
expect(result[field].encoding).to eql(Encoding.default_internal)
|
508
539
|
end
|
509
540
|
end
|
510
541
|
end
|