ruby-mysql-ext 2.9.7

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.
@@ -0,0 +1,118 @@
1
+ # coding: binary
2
+ describe Mysql::Packet do
3
+ def self._(s)
4
+ s.unpack('H*').first
5
+ end
6
+ subject{Mysql::Packet.new(data)}
7
+ describe '#lcb' do
8
+ [
9
+ ["\xfb", nil],
10
+ ["\xfc\x01\x02", 0x0201],
11
+ ["\xfd\x01\x02\x03", 0x030201],
12
+ ["\xfe\x01\x02\x03\x04\x05\x06\x07\x08", 0x0807060504030201],
13
+ ["\x01", 0x01],
14
+ ].each do |data, result|
15
+ context "for '#{_ data}'" do
16
+ let(:data){data}
17
+ it{subject.lcb.should == result}
18
+ end
19
+ end
20
+ end
21
+
22
+ describe '#lcs' do
23
+ [
24
+ ["\x03\x41\x42\x43", 'ABC'],
25
+ ["\x01", ''],
26
+ ["", nil],
27
+ ].each do |data, result|
28
+ context "for '#{_ data}'" do
29
+ let(:data){data}
30
+ it{subject.lcs.should == result}
31
+ end
32
+ end
33
+ end
34
+
35
+ describe '#read' do
36
+ let(:data){'ABCDEFGHI'}
37
+ it{subject.read(7).should == 'ABCDEFG'}
38
+ end
39
+
40
+ describe '#string' do
41
+ let(:data){"ABC\0DEF"}
42
+ it 'should NUL terminated String' do
43
+ subject.string.should == 'ABC'
44
+ end
45
+ end
46
+
47
+ describe '#utiny' do
48
+ [
49
+ ["\x01", 0x01],
50
+ ["\xFF", 0xff],
51
+ ].each do |data, result|
52
+ context "for '#{_ data}'" do
53
+ let(:data){data}
54
+ it{subject.utiny.should == result}
55
+ end
56
+ end
57
+ end
58
+
59
+ describe '#ushort' do
60
+ [
61
+ ["\x01\x02", 0x0201],
62
+ ["\xFF\xFE", 0xfeff],
63
+ ].each do |data, result|
64
+ context "for '#{_ data}'" do
65
+ let(:data){data}
66
+ it{subject.ushort.should == result}
67
+ end
68
+ end
69
+ end
70
+
71
+ describe '#ulong' do
72
+ [
73
+ ["\x01\x02\x03\x04", 0x04030201],
74
+ ["\xFF\xFE\xFD\xFC", 0xfcfdfeff],
75
+ ].each do |data, result|
76
+ context "for '#{_ data}'" do
77
+ let(:data){data}
78
+ it{subject.ulong.should == result}
79
+ end
80
+ end
81
+ end
82
+
83
+ describe '#eof?' do
84
+ [
85
+ ["\xfe\x00\x00\x00\x00", true],
86
+ ["ABCDE", false],
87
+ ].each do |data, result|
88
+ context "for '#{_ data}'" do
89
+ let(:data){data}
90
+ it{subject.eof?.should == result}
91
+ end
92
+ end
93
+ end
94
+
95
+ end
96
+
97
+ describe 'Mysql::Packet.lcb' do
98
+ [
99
+ [nil, "\xfb"],
100
+ [1, "\x01"],
101
+ [250, "\xfa"],
102
+ [251, "\xfc\xfb\x00"],
103
+ [65535, "\xfc\xff\xff"],
104
+ [65536, "\xfd\x00\x00\x01"],
105
+ [16777215, "\xfd\xff\xff\xff"],
106
+ [16777216, "\xfe\x00\x00\x00\x01\x00\x00\x00\x00"],
107
+ [0xffffffffffffffff, "\xfe\xff\xff\xff\xff\xff\xff\xff\xff"],
108
+ ].each do |val, result|
109
+ context "with #{val}" do
110
+ it{Mysql::Packet.lcb(val).should == result}
111
+ end
112
+ end
113
+ end
114
+
115
+ describe 'Mysql::Packet.lcs' do
116
+ it{Mysql::Packet.lcs("hoge").should == "\x04hoge"}
117
+ it{Mysql::Packet.lcs("あいう".force_encoding("UTF-8")).should == "\x09\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86"}
118
+ end
@@ -0,0 +1,1683 @@
1
+ # -*- coding: utf-8 -*-
2
+ require "tempfile"
3
+
4
+ require "mysql"
5
+
6
+ # MYSQL_USER must have ALL privilege for MYSQL_DATABASE.* and RELOAD privilege for *.*
7
+ MYSQL_SERVER = ENV['MYSQL_SERVER']
8
+ MYSQL_USER = ENV['MYSQL_USER']
9
+ MYSQL_PASSWORD = ENV['MYSQL_PASSWORD']
10
+ MYSQL_DATABASE = ENV['MYSQL_DATABASE'] || "test_for_mysql_ruby"
11
+ MYSQL_PORT = ENV['MYSQL_PORT']
12
+ MYSQL_SOCKET = ENV['MYSQL_SOCKET']
13
+
14
+ describe 'Mysql::VERSION' do
15
+ it 'returns client version' do
16
+ Mysql::VERSION.should == 20907
17
+ end
18
+ end
19
+
20
+ describe 'Mysql.init' do
21
+ it 'returns Mysql object' do
22
+ Mysql.init.should be_kind_of Mysql
23
+ end
24
+ end
25
+
26
+ describe 'Mysql.real_connect' do
27
+ it 'connect to mysqld' do
28
+ @m = Mysql.real_connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
29
+ @m.should be_kind_of Mysql
30
+ end
31
+ it 'flag argument affects' do
32
+ @m = Mysql.real_connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET, Mysql::CLIENT_FOUND_ROWS)
33
+ @m.query 'create temporary table t (c int)'
34
+ @m.query 'insert into t values (123)'
35
+ @m.query 'update t set c=123'
36
+ @m.affected_rows.should == 1
37
+ end
38
+ after do
39
+ @m.close
40
+ end
41
+ end
42
+
43
+ describe 'Mysql.connect' do
44
+ it 'connect to mysqld' do
45
+ @m = Mysql.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
46
+ @m.should be_kind_of Mysql
47
+ end
48
+ after do
49
+ @m.close if @m
50
+ end
51
+ end
52
+
53
+ describe 'Mysql.new' do
54
+ it 'connect to mysqld' do
55
+ @m = Mysql.new(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
56
+ @m.should be_kind_of Mysql
57
+ end
58
+ after do
59
+ @m.close if @m
60
+ end
61
+ end
62
+
63
+ describe 'Mysql.escape_string' do
64
+ it 'escape special character' do
65
+ Mysql.escape_string("abc'def\"ghi\0jkl%mno").should == "abc\\'def\\\"ghi\\0jkl%mno"
66
+ end
67
+ end
68
+
69
+ describe 'Mysql.quote' do
70
+ it 'escape special character' do
71
+ Mysql.quote("abc'def\"ghi\0jkl%mno").should == "abc\\'def\\\"ghi\\0jkl%mno"
72
+ end
73
+ end
74
+
75
+ describe 'Mysql.client_info' do
76
+ it 'returns client version as string' do
77
+ Mysql.client_info.should == '5.0.0'
78
+ end
79
+ end
80
+
81
+ describe 'Mysql.get_client_info' do
82
+ it 'returns client version as string' do
83
+ Mysql.get_client_info.should == '5.0.0'
84
+ end
85
+ end
86
+
87
+ describe 'Mysql.client_version' do
88
+ it 'returns client version as Integer' do
89
+ Mysql.client_version.should == 50000
90
+ end
91
+ end
92
+
93
+ describe 'Mysql.get_client_version' do
94
+ it 'returns client version as Integer' do
95
+ Mysql.client_version.should == 50000
96
+ end
97
+ end
98
+
99
+ describe 'Mysql#real_connect' do
100
+ it 'connect to mysqld' do
101
+ @m = Mysql.init
102
+ @m.real_connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET).should == @m
103
+ end
104
+ after do
105
+ @m.close if @m
106
+ end
107
+ end
108
+
109
+ describe 'Mysql#connect' do
110
+ it 'connect to mysqld' do
111
+ @m = Mysql.init
112
+ @m.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET).should == @m
113
+ end
114
+ after do
115
+ @m.close if @m
116
+ end
117
+ end
118
+
119
+ describe 'Mysql#options' do
120
+ before do
121
+ @m = Mysql.init
122
+ end
123
+ after do
124
+ @m.close
125
+ end
126
+ it 'INIT_COMMAND: execute query when connecting' do
127
+ @m.options(Mysql::INIT_COMMAND, "SET AUTOCOMMIT=0").should == @m
128
+ @m.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET).should == @m
129
+ @m.query('select @@AUTOCOMMIT').fetch_row.should == ["0"]
130
+ end
131
+ it 'OPT_CONNECT_TIMEOUT: set timeout for connecting' do
132
+ @m.options(Mysql::OPT_CONNECT_TIMEOUT, 0.1).should == @m
133
+ UNIXSocket.stub!(:new).and_return{sleep 1}
134
+ TCPSocket.stub!(:new).and_return{sleep 1}
135
+ proc{@m.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)}.should raise_error Mysql::ClientError, 'connection timeout'
136
+ proc{@m.connect}.should raise_error Mysql::ClientError, 'connection timeout'
137
+ end
138
+ it 'OPT_LOCAL_INFILE: client can execute LOAD DATA LOCAL INFILE query' do
139
+ tmpf = Tempfile.new 'mysql_spec'
140
+ tmpf.puts "123\tabc\n"
141
+ tmpf.close
142
+ @m.options(Mysql::OPT_LOCAL_INFILE, true).should == @m
143
+ @m.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
144
+ @m.query('create temporary table t (i int, c char(10))')
145
+ @m.query("load data local infile '#{tmpf.path}' into table t")
146
+ @m.query('select * from t').fetch_row.should == ['123','abc']
147
+ end
148
+ it 'OPT_READ_TIMEOUT: set timeout for reading packet' do
149
+ @m.options(Mysql::OPT_READ_TIMEOUT, 10).should == @m
150
+ end
151
+ it 'OPT_WRITE_TIMEOUT: set timeout for writing packet' do
152
+ @m.options(Mysql::OPT_WRITE_TIMEOUT, 10).should == @m
153
+ end
154
+ it 'SET_CHARSET_NAME: set charset for connection' do
155
+ @m.options(Mysql::SET_CHARSET_NAME, 'utf8').should == @m
156
+ @m.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
157
+ @m.query('select @@character_set_connection').fetch_row.should == ['utf8']
158
+ end
159
+ end
160
+
161
+ describe 'Mysql' do
162
+ before do
163
+ @m = Mysql.new(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
164
+ end
165
+
166
+ after do
167
+ @m.close if @m rescue nil
168
+ end
169
+
170
+ describe '#escape_string' do
171
+ if defined? ::Encoding
172
+ it 'escape special character for charset' do
173
+ @m.charset = 'cp932'
174
+ @m.escape_string("abc'def\"ghi\0jkl%mno_表".encode('cp932')).should == "abc\\'def\\\"ghi\\0jkl%mno_表".encode('cp932')
175
+ end
176
+ else
177
+ it 'raise error if charset is multibyte' do
178
+ @m.charset = 'cp932'
179
+ proc{@m.escape_string("abc'def\"ghi\0jkl%mno_\x95\\")}.should raise_error(Mysql::ClientError, 'Mysql#escape_string is called for unsafe multibyte charset')
180
+ end
181
+ it 'not warn if charset is singlebyte' do
182
+ @m.charset = 'latin1'
183
+ @m.escape_string("abc'def\"ghi\0jkl%mno_\x95\\").should == "abc\\'def\\\"ghi\\0jkl%mno_\x95\\\\"
184
+ end
185
+ end
186
+ end
187
+
188
+ describe '#quote' do
189
+ it 'is alias of #escape_string' do
190
+ @m.method(:quote).should == @m.method(:escape_string)
191
+ end
192
+ end
193
+
194
+ describe '#client_info' do
195
+ it 'returns client version as string' do
196
+ @m.client_info.should == '5.0.0'
197
+ end
198
+ end
199
+
200
+ describe '#get_client_info' do
201
+ it 'returns client version as string' do
202
+ @m.get_client_info.should == '5.0.0'
203
+ end
204
+ end
205
+
206
+ describe '#affected_rows' do
207
+ it 'returns number of affected rows' do
208
+ @m.query 'create temporary table t (id int)'
209
+ @m.query 'insert into t values (1),(2)'
210
+ @m.affected_rows.should == 2
211
+ end
212
+ end
213
+
214
+ describe '#character_set_name' do
215
+ it 'returns charset name' do
216
+ m = Mysql.init
217
+ m.options Mysql::SET_CHARSET_NAME, 'cp932'
218
+ m.connect MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET
219
+ m.character_set_name.should == 'cp932'
220
+ end
221
+ end
222
+
223
+ describe '#close' do
224
+ it 'returns self' do
225
+ @m.close.should == @m
226
+ end
227
+ end
228
+
229
+ describe '#close!' do
230
+ it 'returns self' do
231
+ @m.close!.should == @m
232
+ end
233
+ end
234
+
235
+ # describe '#create_db' do
236
+ # end
237
+
238
+ # describe '#drop_db' do
239
+ # end
240
+
241
+ describe '#errno' do
242
+ it 'default value is 0' do
243
+ @m.errno.should == 0
244
+ end
245
+ it 'returns error number of latest error' do
246
+ @m.query('hogehoge') rescue nil
247
+ @m.errno.should == 1064
248
+ end
249
+ end
250
+
251
+ describe '#error' do
252
+ it 'returns error message of latest error' do
253
+ @m.query('hogehoge') rescue nil
254
+ @m.error.should == "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'hogehoge' at line 1"
255
+ end
256
+ end
257
+
258
+ describe '#field_count' do
259
+ it 'returns number of fields for latest query' do
260
+ @m.query 'select 1,2,3'
261
+ @m.field_count.should == 3
262
+ end
263
+ end
264
+
265
+ describe '#client_version' do
266
+ it 'returns client version as Integer' do
267
+ @m.client_version.should be_kind_of Integer
268
+ end
269
+ end
270
+
271
+ describe '#get_client_version' do
272
+ it 'returns client version as Integer' do
273
+ @m.get_client_version.should be_kind_of Integer
274
+ end
275
+ end
276
+
277
+ describe '#get_host_info' do
278
+ it 'returns connection type as String' do
279
+ if MYSQL_SERVER == nil or MYSQL_SERVER == 'localhost'
280
+ @m.get_host_info.should == 'Localhost via UNIX socket'
281
+ else
282
+ @m.get_host_info.should == "#{MYSQL_SERVER} via TCP/IP"
283
+ end
284
+ end
285
+ end
286
+
287
+ describe '#host_info' do
288
+ it 'returns connection type as String' do
289
+ if MYSQL_SERVER == nil or MYSQL_SERVER == 'localhost'
290
+ @m.host_info.should == 'Localhost via UNIX socket'
291
+ else
292
+ @m.host_info.should == "#{MYSQL_SERVER} via TCP/IP"
293
+ end
294
+ end
295
+ end
296
+
297
+ describe '#get_proto_info' do
298
+ it 'returns version of connection as Integer' do
299
+ @m.get_proto_info.should == 10
300
+ end
301
+ end
302
+
303
+ describe '#proto_info' do
304
+ it 'returns version of connection as Integer' do
305
+ @m.proto_info.should == 10
306
+ end
307
+ end
308
+
309
+ describe '#get_server_info' do
310
+ it 'returns server version as String' do
311
+ @m.get_server_info.should =~ /\A\d+\.\d+\.\d+/
312
+ end
313
+ end
314
+
315
+ describe '#server_info' do
316
+ it 'returns server version as String' do
317
+ @m.server_info.should =~ /\A\d+\.\d+\.\d+/
318
+ end
319
+ end
320
+
321
+ describe '#info' do
322
+ it 'returns information of latest query' do
323
+ @m.query 'create temporary table t (id int)'
324
+ @m.query 'insert into t values (1),(2),(3)'
325
+ @m.info.should == 'Records: 3 Duplicates: 0 Warnings: 0'
326
+ end
327
+ end
328
+
329
+ describe '#insert_id' do
330
+ it 'returns latest auto_increment value' do
331
+ @m.query 'create temporary table t (id int auto_increment, unique (id))'
332
+ @m.query 'insert into t values (0)'
333
+ @m.insert_id.should == 1
334
+ @m.query 'alter table t auto_increment=1234'
335
+ @m.query 'insert into t values (0)'
336
+ @m.insert_id.should == 1234
337
+ end
338
+ end
339
+
340
+ describe '#kill' do
341
+ it 'returns self' do
342
+ @m.kill(@m.thread_id).should == @m
343
+ end
344
+ it 'kill specified connection' do
345
+ m = Mysql.new(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
346
+ m.list_processes.map(&:first).should be_include @m.thread_id.to_s
347
+ m.close
348
+ end
349
+ end
350
+
351
+ describe '#list_dbs' do
352
+ it 'returns database list' do
353
+ ret = @m.list_dbs
354
+ ret.should be_kind_of Array
355
+ ret.should be_include MYSQL_DATABASE
356
+ end
357
+ it 'with pattern returns databases that matches pattern' do
358
+ @m.list_dbs('info%').should be_include 'information_schema'
359
+ end
360
+ end
361
+
362
+ describe '#list_fields' do
363
+ before do
364
+ @m.query 'create temporary table t (i int, c char(10), d date)'
365
+ end
366
+ it 'returns result set that contains information of fields' do
367
+ ret = @m.list_fields('t')
368
+ ret.should be_kind_of Mysql::Result
369
+ ret.num_rows.should == 0
370
+ ret.fetch_fields.map{|f|f.name}.should == ['i','c','d']
371
+ end
372
+ it 'with pattern returns result set that contains information of fields that matches pattern' do
373
+ ret = @m.list_fields('t', 'i')
374
+ ret.should be_kind_of Mysql::Result
375
+ ret.num_rows.should == 0
376
+ ret.fetch_fields.map{|f|f.name}.should == ['i']
377
+ end
378
+ end
379
+
380
+ describe '#list_processes' do
381
+ it 'returns result set that contains information of all connections' do
382
+ ret = @m.list_processes
383
+ ret.should be_kind_of Mysql::Result
384
+ ret.find{|r|r[0].to_i == @m.thread_id}[4].should == "Processlist"
385
+ end
386
+ end
387
+
388
+ describe '#list_tables' do
389
+ before do
390
+ @m.query 'create table test_mysql_list_tables (id int)'
391
+ end
392
+ after do
393
+ @m.query 'drop table test_mysql_list_tables'
394
+ end
395
+ it 'returns table list' do
396
+ ret = @m.list_tables
397
+ ret.should be_kind_of Array
398
+ ret.should be_include 'test_mysql_list_tables'
399
+ end
400
+ it 'with pattern returns lists that matches pattern' do
401
+ ret = @m.list_tables '%mysql\_list\_t%'
402
+ ret.should be_include 'test_mysql_list_tables'
403
+ end
404
+ end
405
+
406
+ describe '#ping' do
407
+ it 'returns self' do
408
+ @m.ping.should == @m
409
+ end
410
+ end
411
+
412
+ describe '#query' do
413
+ it 'returns Mysql::Result if query returns results' do
414
+ @m.query('select 123').should be_kind_of Mysql::Result
415
+ end
416
+ it 'returns nil if query returns no results' do
417
+ @m.query('set @hoge:=123').should == nil
418
+ end
419
+ it 'returns self if query_with_result is false' do
420
+ @m.query_with_result = false
421
+ @m.query('select 123').should == @m
422
+ @m.store_result
423
+ @m.query('set @hoge:=123').should == @m
424
+ end
425
+ end
426
+
427
+ describe '#real_query' do
428
+ it 'is same as #query' do
429
+ @m.real_query('select 123').should be_kind_of Mysql::Result
430
+ end
431
+ end
432
+
433
+ describe '#refresh' do
434
+ it 'returns self' do
435
+ @m.refresh(Mysql::REFRESH_HOSTS).should == @m
436
+ end
437
+ end
438
+
439
+ describe '#reload' do
440
+ it 'returns self' do
441
+ @m.reload.should == @m
442
+ end
443
+ end
444
+
445
+ describe '#select_db' do
446
+ it 'changes default database' do
447
+ @m.select_db 'information_schema'
448
+ @m.query('select database()').fetch_row.first.should == 'information_schema'
449
+ end
450
+ end
451
+
452
+ # describe '#shutdown' do
453
+ # end
454
+
455
+ describe '#stat' do
456
+ it 'returns server status' do
457
+ @m.stat.should =~ /\AUptime: \d+ Threads: \d+ Questions: \d+ Slow queries: \d+ Opens: \d+ Flush tables: \d+ Open tables: \d+ Queries per second avg: \d+\.\d+\z/
458
+ end
459
+ end
460
+
461
+ describe '#store_result' do
462
+ it 'returns Mysql::Result' do
463
+ @m.query_with_result = false
464
+ @m.query 'select 1,2,3'
465
+ ret = @m.store_result
466
+ ret.should be_kind_of Mysql::Result
467
+ ret.fetch_row.should == ['1','2','3']
468
+ end
469
+ it 'raises error when no query' do
470
+ proc{@m.store_result}.should raise_error Mysql::Error
471
+ end
472
+ it 'raises error when query does not return results' do
473
+ @m.query 'set @hoge:=123'
474
+ proc{@m.store_result}.should raise_error Mysql::Error
475
+ end
476
+ end
477
+
478
+ describe '#thread_id' do
479
+ it 'returns thread id as Integer' do
480
+ @m.thread_id.should be_kind_of Integer
481
+ end
482
+ end
483
+
484
+ describe '#use_result' do
485
+ it 'returns Mysql::Result' do
486
+ @m.query_with_result = false
487
+ @m.query 'select 1,2,3'
488
+ ret = @m.use_result
489
+ ret.should be_kind_of Mysql::Result
490
+ ret.fetch_row.should == ['1','2','3']
491
+ end
492
+ it 'raises error when no query' do
493
+ proc{@m.use_result}.should raise_error Mysql::Error
494
+ end
495
+ it 'raises error when query does not return results' do
496
+ @m.query 'set @hoge:=123'
497
+ proc{@m.use_result}.should raise_error Mysql::Error
498
+ end
499
+ end
500
+
501
+ describe '#get_server_version' do
502
+ it 'returns server version as Integer' do
503
+ @m.get_server_version.should be_kind_of Integer
504
+ end
505
+ end
506
+
507
+ describe '#server_version' do
508
+ it 'returns server version as Integer' do
509
+ @m.server_version.should be_kind_of Integer
510
+ end
511
+ end
512
+
513
+ describe '#warning_count' do
514
+ it 'default values is zero' do
515
+ @m.warning_count.should == 0
516
+ end
517
+ it 'returns number of warnings' do
518
+ @m.query 'create temporary table t (i tinyint)'
519
+ @m.query 'insert into t values (1234567)'
520
+ @m.warning_count.should == 1
521
+ end
522
+ end
523
+
524
+ describe '#commit' do
525
+ it 'returns self' do
526
+ @m.commit.should == @m
527
+ end
528
+ end
529
+
530
+ describe '#rollback' do
531
+ it 'returns self' do
532
+ @m.rollback.should == @m
533
+ end
534
+ end
535
+
536
+ describe '#autocommit' do
537
+ it 'returns self' do
538
+ @m.autocommit(true).should == @m
539
+ end
540
+
541
+ it 'change auto-commit mode' do
542
+ @m.autocommit(true)
543
+ @m.query('select @@autocommit').fetch_row.should == ['1']
544
+ @m.autocommit(false)
545
+ @m.query('select @@autocommit').fetch_row.should == ['0']
546
+ end
547
+ end
548
+
549
+ describe '#set_server_option' do
550
+ it 'returns self' do
551
+ @m.set_server_option(Mysql::OPTION_MULTI_STATEMENTS_ON).should == @m
552
+ end
553
+ end
554
+
555
+ describe '#sqlstate' do
556
+ it 'default values is "00000"' do
557
+ @m.sqlstate.should == "00000"
558
+ end
559
+ it 'returns sqlstate code' do
560
+ proc{@m.query("hoge")}.should raise_error
561
+ @m.sqlstate.should == "42000"
562
+ end
563
+ end
564
+
565
+ describe '#query_with_result' do
566
+ it 'default value is true' do
567
+ @m.query_with_result.should == true
568
+ end
569
+ it 'can set value' do
570
+ (@m.query_with_result=true).should == true
571
+ @m.query_with_result.should == true
572
+ (@m.query_with_result=false).should == false
573
+ @m.query_with_result.should == false
574
+ end
575
+ end
576
+
577
+ describe '#query_with_result is false' do
578
+ it 'Mysql#query returns self and Mysql#store_result returns result set' do
579
+ @m.query_with_result = false
580
+ @m.query('select 1,2,3').should == @m
581
+ res = @m.store_result
582
+ res.fetch_row.should == ['1','2','3']
583
+ end
584
+ end
585
+
586
+ describe '#query with block' do
587
+ it 'returns self' do
588
+ @m.query('select 1'){}.should == @m
589
+ end
590
+ it 'evaluate block with Mysql::Result' do
591
+ @m.query('select 1'){|res| res.should be_kind_of Mysql::Result}.should == @m
592
+ end
593
+ it 'evaluate block multiple times if multiple query is specified' do
594
+ @m.set_server_option Mysql::OPTION_MULTI_STATEMENTS_ON
595
+ cnt = 0
596
+ expect = [["1"], ["2"]]
597
+ @m.query('select 1; select 2'){|res|
598
+ res.fetch_row.should == expect.shift
599
+ cnt += 1
600
+ }.should == @m
601
+ cnt.should == 2
602
+ end
603
+ it 'evaluate block only when query has result' do
604
+ @m.set_server_option Mysql::OPTION_MULTI_STATEMENTS_ON
605
+ cnt = 0
606
+ expect = [["1"], ["2"]]
607
+ @m.query('select 1; set @hoge:=1; select 2'){|res|
608
+ res.fetch_row.should == expect.shift
609
+ cnt += 1
610
+ }.should == @m
611
+ cnt.should == 2
612
+ end
613
+ end
614
+ end
615
+
616
+ describe 'multiple statement query:' do
617
+ before :all do
618
+ @m = Mysql.new(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
619
+ @m.set_server_option(Mysql::OPTION_MULTI_STATEMENTS_ON)
620
+ @res = @m.query 'select 1,2; select 3,4,5'
621
+ end
622
+ it 'Mysql#query returns results for first query' do
623
+ @res.entries.should == [['1','2']]
624
+ end
625
+ it 'Mysql#more_results is true' do
626
+ @m.more_results.should == true
627
+ end
628
+ it 'Mysql#more_results? is true' do
629
+ @m.more_results?.should == true
630
+ end
631
+ it 'Mysql#next_result is true' do
632
+ @m.next_result.should == true
633
+ end
634
+ it 'Mysql#store_result returns results for next query' do
635
+ res = @m.store_result
636
+ res.entries.should == [['3','4','5']]
637
+ end
638
+ it 'Mysql#more_results is false' do
639
+ @m.more_results.should == false
640
+ end
641
+ it 'Mysql#more_results? is false' do
642
+ @m.more_results?.should == false
643
+ end
644
+ it 'Mysql#next_result is false' do
645
+ @m.next_result.should == false
646
+ end
647
+ end
648
+
649
+ describe 'Mysql::Result' do
650
+ before do
651
+ @m = Mysql.new(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
652
+ @m.query 'create temporary table t (id int, str char(10), primary key (id))'
653
+ @m.query "insert into t values (1,'abc'),(2,'defg'),(3,'hi'),(4,null)"
654
+ @res = @m.query 'select * from t'
655
+ end
656
+
657
+ after do
658
+ @m.close if @m
659
+ end
660
+
661
+ it '#data_seek set position of current record' do
662
+ @res.fetch_row.should == ['1', 'abc']
663
+ @res.fetch_row.should == ['2', 'defg']
664
+ @res.fetch_row.should == ['3', 'hi']
665
+ @res.data_seek 1
666
+ @res.fetch_row.should == ['2', 'defg']
667
+ end
668
+
669
+ it '#fetch_field return current field' do
670
+ f = @res.fetch_field
671
+ f.name.should == 'id'
672
+ f.table.should == 't'
673
+ f.def.should == nil
674
+ f.type.should == Mysql::Field::TYPE_LONG
675
+ f.length.should == 11
676
+ f.max_length == 1
677
+ f.flags.should == Mysql::Field::NUM_FLAG|Mysql::Field::PRI_KEY_FLAG|Mysql::Field::PART_KEY_FLAG|Mysql::Field::NOT_NULL_FLAG
678
+ f.decimals.should == 0
679
+
680
+ f = @res.fetch_field
681
+ f.name.should == 'str'
682
+ f.table.should == 't'
683
+ f.def.should == nil
684
+ f.type.should == Mysql::Field::TYPE_STRING
685
+ f.length.should == 10
686
+ f.max_length == 4
687
+ f.flags.should == 0
688
+ f.decimals.should == 0
689
+
690
+ @res.fetch_field.should == nil
691
+ end
692
+
693
+ it '#fetch_fields returns array of fields' do
694
+ ret = @res.fetch_fields
695
+ ret.size.should == 2
696
+ ret[0].name.should == 'id'
697
+ ret[1].name.should == 'str'
698
+ end
699
+
700
+ it '#fetch_field_direct returns field' do
701
+ f = @res.fetch_field_direct 0
702
+ f.name.should == 'id'
703
+ f = @res.fetch_field_direct 1
704
+ f.name.should == 'str'
705
+ proc{@res.fetch_field_direct(-1)}.should raise_error Mysql::ClientError, 'invalid argument: -1'
706
+ proc{@res.fetch_field_direct 2}.should raise_error Mysql::ClientError, 'invalid argument: 2'
707
+ end
708
+
709
+ it '#fetch_lengths returns array of length of field data' do
710
+ @res.fetch_lengths.should == nil
711
+ @res.fetch_row
712
+ @res.fetch_lengths.should == [1, 3]
713
+ @res.fetch_row
714
+ @res.fetch_lengths.should == [1, 4]
715
+ @res.fetch_row
716
+ @res.fetch_lengths.should == [1, 2]
717
+ @res.fetch_row
718
+ @res.fetch_lengths.should == [1, 0]
719
+ @res.fetch_row
720
+ @res.fetch_lengths.should == nil
721
+ end
722
+
723
+ it '#fetch_row returns one record as array for current record' do
724
+ @res.fetch_row.should == ['1', 'abc']
725
+ @res.fetch_row.should == ['2', 'defg']
726
+ @res.fetch_row.should == ['3', 'hi']
727
+ @res.fetch_row.should == ['4', nil]
728
+ @res.fetch_row.should == nil
729
+ end
730
+
731
+ it '#fetch_hash returns one record as hash for current record' do
732
+ @res.fetch_hash.should == {'id'=>'1', 'str'=>'abc'}
733
+ @res.fetch_hash.should == {'id'=>'2', 'str'=>'defg'}
734
+ @res.fetch_hash.should == {'id'=>'3', 'str'=>'hi'}
735
+ @res.fetch_hash.should == {'id'=>'4', 'str'=>nil}
736
+ @res.fetch_hash.should == nil
737
+ end
738
+
739
+ it '#fetch_hash(true) returns with table name' do
740
+ @res.fetch_hash(true).should == {'t.id'=>'1', 't.str'=>'abc'}
741
+ @res.fetch_hash(true).should == {'t.id'=>'2', 't.str'=>'defg'}
742
+ @res.fetch_hash(true).should == {'t.id'=>'3', 't.str'=>'hi'}
743
+ @res.fetch_hash(true).should == {'t.id'=>'4', 't.str'=>nil}
744
+ @res.fetch_hash(true).should == nil
745
+ end
746
+
747
+ it '#num_fields returns number of fields' do
748
+ @res.num_fields.should == 2
749
+ end
750
+
751
+ it '#num_rows returns number of records' do
752
+ @res.num_rows.should == 4
753
+ end
754
+
755
+ it '#each iterate block with a record' do
756
+ expect = [["1","abc"], ["2","defg"], ["3","hi"], ["4",nil]]
757
+ @res.each do |a|
758
+ a.should == expect.shift
759
+ end
760
+ end
761
+
762
+ it '#each_hash iterate block with a hash' do
763
+ expect = [{"id"=>"1","str"=>"abc"}, {"id"=>"2","str"=>"defg"}, {"id"=>"3","str"=>"hi"}, {"id"=>"4","str"=>nil}]
764
+ @res.each_hash do |a|
765
+ a.should == expect.shift
766
+ end
767
+ end
768
+
769
+ it '#each_hash(true): hash key has table name' do
770
+ expect = [{"t.id"=>"1","t.str"=>"abc"}, {"t.id"=>"2","t.str"=>"defg"}, {"t.id"=>"3","t.str"=>"hi"}, {"t.id"=>"4","t.str"=>nil}]
771
+ @res.each_hash(true) do |a|
772
+ a.should == expect.shift
773
+ end
774
+ end
775
+
776
+ it '#row_tell returns position of current record, #row_seek set position of current record' do
777
+ @res.fetch_row.should == ['1', 'abc']
778
+ pos = @res.row_tell
779
+ @res.fetch_row.should == ['2', 'defg']
780
+ @res.fetch_row.should == ['3', 'hi']
781
+ @res.row_seek pos
782
+ @res.fetch_row.should == ['2', 'defg']
783
+ end
784
+
785
+ it '#field_tell returns position of current field, #field_seek set position of current field' do
786
+ @res.field_tell.should == 0
787
+ @res.fetch_field
788
+ @res.field_tell.should == 1
789
+ @res.fetch_field
790
+ @res.field_tell.should == 2
791
+ @res.field_seek 1
792
+ @res.field_tell.should == 1
793
+ end
794
+
795
+ it '#free returns nil' do
796
+ @res.free.should == nil
797
+ end
798
+
799
+ it '#num_fields returns number of fields' do
800
+ @res.num_fields.should == 2
801
+ end
802
+
803
+ it '#num_rows returns number of records' do
804
+ @res.num_rows.should == 4
805
+ end
806
+ end
807
+
808
+ describe 'Mysql::Field' do
809
+ before do
810
+ @m = Mysql.new(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
811
+ @m.query 'create temporary table t (id int default 0, str char(10), primary key (id))'
812
+ @m.query "insert into t values (1,'abc'),(2,'defg'),(3,'hi'),(4,null)"
813
+ @res = @m.query 'select * from t'
814
+ end
815
+
816
+ after do
817
+ @m.close if @m
818
+ end
819
+
820
+ it '#name is name of field' do
821
+ @res.fetch_field.name.should == 'id'
822
+ end
823
+
824
+ it '#table is name of table for field' do
825
+ @res.fetch_field.table.should == 't'
826
+ end
827
+
828
+ it '#def for result set is null' do
829
+ @res.fetch_field.def.should == nil
830
+ end
831
+
832
+ it '#def for field information is default value' do
833
+ @m.list_fields('t').fetch_field.def.should == '0'
834
+ end
835
+
836
+ it '#type is type of field as Integer' do
837
+ @res.fetch_field.type.should == Mysql::Field::TYPE_LONG
838
+ @res.fetch_field.type.should == Mysql::Field::TYPE_STRING
839
+ end
840
+
841
+ it '#length is length of field' do
842
+ @res.fetch_field.length.should == 11
843
+ @res.fetch_field.length.should == 10
844
+ end
845
+
846
+ it '#max_length is maximum length of field value' do
847
+ @res.fetch_field.max_length.should == 1
848
+ @res.fetch_field.max_length.should == 4
849
+ end
850
+
851
+ it '#flags is flag of field as Integer' do
852
+ @res.fetch_field.flags.should == Mysql::Field::NUM_FLAG|Mysql::Field::PRI_KEY_FLAG|Mysql::Field::PART_KEY_FLAG|Mysql::Field::NOT_NULL_FLAG
853
+ @res.fetch_field.flags.should == 0
854
+ end
855
+
856
+ it '#decimals is number of decimal digits' do
857
+ @m.query('select 1.23').fetch_field.decimals.should == 2
858
+ end
859
+
860
+ it '#hash return field as hash' do
861
+ @res.fetch_field.hash.should == {
862
+ 'name' => 'id',
863
+ 'table' => 't',
864
+ 'def' => nil,
865
+ 'type' => Mysql::Field::TYPE_LONG,
866
+ 'length' => 11,
867
+ 'max_length' => 1,
868
+ 'flags' => Mysql::Field::NUM_FLAG|Mysql::Field::PRI_KEY_FLAG|Mysql::Field::PART_KEY_FLAG|Mysql::Field::NOT_NULL_FLAG,
869
+ 'decimals' => 0,
870
+ }
871
+ @res.fetch_field.hash.should == {
872
+ 'name' => 'str',
873
+ 'table' => 't',
874
+ 'def' => nil,
875
+ 'type' => Mysql::Field::TYPE_STRING,
876
+ 'length' => 10,
877
+ 'max_length' => 4,
878
+ 'flags' => 0,
879
+ 'decimals' => 0,
880
+ }
881
+ end
882
+
883
+ it '#inspect returns "#<Mysql::Field:name>"' do
884
+ @res.fetch_field.inspect.should == '#<Mysql::Field:id>'
885
+ @res.fetch_field.inspect.should == '#<Mysql::Field:str>'
886
+ end
887
+
888
+ it '#is_num? returns true if the field is numeric' do
889
+ @res.fetch_field.is_num?.should == true
890
+ @res.fetch_field.is_num?.should == false
891
+ end
892
+
893
+ it '#is_not_null? returns true if the field is not null' do
894
+ @res.fetch_field.is_not_null?.should == true
895
+ @res.fetch_field.is_not_null?.should == false
896
+ end
897
+
898
+ it '#is_pri_key? returns true if the field is primary key' do
899
+ @res.fetch_field.is_pri_key?.should == true
900
+ @res.fetch_field.is_pri_key?.should == false
901
+ end
902
+ end
903
+
904
+ describe 'create Mysql::Stmt object:' do
905
+ before do
906
+ @m = Mysql.new(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
907
+ end
908
+
909
+ after do
910
+ @m.close if @m
911
+ end
912
+
913
+ it 'Mysql#stmt_init returns Mysql::Stmt object' do
914
+ @m.stmt_init.should be_kind_of Mysql::Stmt
915
+ end
916
+
917
+ it 'Mysq;#prepare returns Mysql::Stmt object' do
918
+ @m.prepare("select 1").should be_kind_of Mysql::Stmt
919
+ end
920
+ end
921
+
922
+ describe 'Mysql::Stmt' do
923
+ before do
924
+ @m = Mysql.new(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
925
+ @s = @m.stmt_init
926
+ end
927
+
928
+ after do
929
+ @s.close if @s rescue nil
930
+ @m.close if @m
931
+ end
932
+
933
+ it '#affected_rows returns number of affected records' do
934
+ @m.query 'create temporary table t (i int, c char(10))'
935
+ @s.prepare 'insert into t values (?,?)'
936
+ @s.execute 1, 'hoge'
937
+ @s.affected_rows.should == 1
938
+ @s.execute 2, 'hoge'
939
+ @s.execute 3, 'hoge'
940
+ @s.prepare 'update t set c=?'
941
+ @s.execute 'fuga'
942
+ @s.affected_rows.should == 3
943
+ end
944
+
945
+ describe '#bind_result' do
946
+ before do
947
+ @m.query 'create temporary table t (i int, c char(10), d double, t datetime)'
948
+ @m.query 'insert into t values (123,"9abcdefg",1.2345,20091208100446)'
949
+ @s.prepare 'select * from t'
950
+ end
951
+
952
+ it '(nil) make result format to be standard value' do
953
+ @s.bind_result nil, nil, nil, nil
954
+ @s.execute
955
+ @s.fetch.should == [123, '9abcdefg', 1.2345, Mysql::Time.new(2009,12,8,10,4,46)]
956
+ end
957
+
958
+ it '(Numeric) make result format to be Integer value' do
959
+ @s.bind_result Numeric, Numeric, Numeric, Numeric
960
+ @s.execute
961
+ @s.fetch.should == [123, 9, 1, 20091208100446]
962
+ end
963
+
964
+ it '(Integer) make result format to be Integer value' do
965
+ @s.bind_result Integer, Integer, Integer, Integer
966
+ @s.execute
967
+ @s.fetch.should == [123, 9, 1, 20091208100446]
968
+ end
969
+
970
+ it '(Fixnum) make result format to be Integer value' do
971
+ @s.bind_result Fixnum, Fixnum, Fixnum, Fixnum
972
+ @s.execute
973
+ @s.fetch.should == [123, 9, 1, 20091208100446]
974
+ end
975
+
976
+ it '(String) make result format to be String value' do
977
+ @s.bind_result String, String, String, String
978
+ @s.execute
979
+ @s.fetch.should == ["123", "9abcdefg", "1.2345", "2009-12-08 10:04:46"]
980
+ end
981
+
982
+ it '(Float) make result format to be Float value' do
983
+ @s.bind_result Float, Float, Float, Float
984
+ @s.execute
985
+ @s.fetch.should == [123.0, 9.0, 1.2345 , 20091208100446.0]
986
+ end
987
+
988
+ it '(Mysql::Time) make result format to be Mysql::Time value' do
989
+ @s.bind_result Mysql::Time, Mysql::Time, Mysql::Time, Mysql::Time
990
+ @s.execute
991
+ @s.fetch.should == [Mysql::Time.new(2000,1,23), Mysql::Time.new, Mysql::Time.new, Mysql::Time.new(2009,12,8,10,4,46)]
992
+ end
993
+
994
+ it '(invalid) raises error' do
995
+ proc{@s.bind_result(Time, nil, nil, nil)}.should raise_error(TypeError)
996
+ end
997
+
998
+ it 'with mismatch argument count raise error' do
999
+ proc{@s.bind_result(nil)}.should raise_error(Mysql::ClientError, 'bind_result: result value count(4) != number of argument(1)')
1000
+ end
1001
+ end
1002
+
1003
+ it '#close returns nil' do
1004
+ @s.close.should == nil
1005
+ end
1006
+
1007
+ it '#data_seek set position of current record' do
1008
+ @m.query 'create temporary table t (i int)'
1009
+ @m.query 'insert into t values (0),(1),(2),(3),(4),(5),(6)'
1010
+ @s.prepare 'select i from t'
1011
+ @s.execute
1012
+ @s.fetch.should == [0]
1013
+ @s.fetch.should == [1]
1014
+ @s.fetch.should == [2]
1015
+ @s.data_seek 5
1016
+ @s.fetch.should == [5]
1017
+ @s.data_seek 1
1018
+ @s.fetch.should == [1]
1019
+ end
1020
+
1021
+ it '#each iterate block with a record' do
1022
+ @m.query 'create temporary table t (i int, c char(255), d datetime)'
1023
+ @m.query "insert into t values (1,'abc','19701224235905'),(2,'def','21120903123456'),(3,'123',null)"
1024
+ @s.prepare 'select * from t'
1025
+ @s.execute
1026
+ expect = [
1027
+ [1, 'abc', Mysql::Time.new(1970,12,24,23,59,05)],
1028
+ [2, 'def', Mysql::Time.new(2112,9,3,12,34,56)],
1029
+ [3, '123', nil],
1030
+ ]
1031
+ @s.each do |a|
1032
+ a.should == expect.shift
1033
+ end
1034
+ end
1035
+
1036
+ it '#execute returns self' do
1037
+ @s.prepare 'select 1'
1038
+ @s.execute.should == @s
1039
+ end
1040
+
1041
+ it '#execute pass arguments to query' do
1042
+ @m.query 'create temporary table t (i int)'
1043
+ @s.prepare 'insert into t values (?)'
1044
+ @s.execute 123
1045
+ @s.execute '456'
1046
+ @m.query('select * from t').entries.should == [['123'], ['456']]
1047
+ end
1048
+
1049
+ it '#execute with various arguments' do
1050
+ @m.query 'create temporary table t (i int, c char(255), t timestamp)'
1051
+ @s.prepare 'insert into t values (?,?,?)'
1052
+ @s.execute 123, 'hoge', Time.local(2009,12,8,19,56,21)
1053
+ @m.query('select * from t').fetch_row.should == ['123', 'hoge', '2009-12-08 19:56:21']
1054
+ end
1055
+
1056
+ it '#execute with arguments that is invalid count raise error' do
1057
+ @s.prepare 'select ?'
1058
+ proc{@s.execute 123, 456}.should raise_error(Mysql::ClientError, 'parameter count mismatch')
1059
+ end
1060
+
1061
+ it '#execute with huge value' do
1062
+ [30, 31, 32, 62, 63].each do |i|
1063
+ @m.prepare('select cast(? as signed)').execute(2**i-1).fetch.should == [2**i-1]
1064
+ @m.prepare('select cast(? as signed)').execute(-(2**i)).fetch.should == [-2**i]
1065
+ end
1066
+ end
1067
+
1068
+ it '#fetch returns result-record' do
1069
+ @s.prepare 'select 123, "abc", null'
1070
+ @s.execute
1071
+ @s.fetch.should == [123, 'abc', nil]
1072
+ end
1073
+
1074
+ it '#fetch bit column (8bit)' do
1075
+ @m.query 'create temporary table t (i bit(8))'
1076
+ @m.query 'insert into t values (0),(-1),(127),(-128),(255),(-255),(256)'
1077
+ @s.prepare 'select i from t'
1078
+ @s.execute
1079
+ if defined? Encoding
1080
+ @s.entries.should == [
1081
+ ["\x00".force_encoding('ASCII-8BIT')],
1082
+ ["\xff".force_encoding('ASCII-8BIT')],
1083
+ ["\x7f".force_encoding('ASCII-8BIT')],
1084
+ ["\xff".force_encoding('ASCII-8BIT')],
1085
+ ["\xff".force_encoding('ASCII-8BIT')],
1086
+ ["\xff".force_encoding('ASCII-8BIT')],
1087
+ ["\xff".force_encoding('ASCII-8BIT')],
1088
+ ]
1089
+ else
1090
+ @s.entries.should == [["\x00"], ["\xff"], ["\x7f"], ["\xff"], ["\xff"], ["\xff"], ["\xff"]]
1091
+ end
1092
+ end
1093
+
1094
+ it '#fetch bit column (64bit)' do
1095
+ @m.query 'create temporary table t (i bit(64))'
1096
+ @m.query 'insert into t values (0),(-1),(4294967296),(18446744073709551615),(18446744073709551616)'
1097
+ @s.prepare 'select i from t'
1098
+ @s.execute
1099
+ if defined? Encoding
1100
+ @s.entries.should == [
1101
+ ["\x00\x00\x00\x00\x00\x00\x00\x00".force_encoding('ASCII-8BIT')],
1102
+ ["\xff\xff\xff\xff\xff\xff\xff\xff".force_encoding('ASCII-8BIT')],
1103
+ ["\x00\x00\x00\x01\x00\x00\x00\x00".force_encoding('ASCII-8BIT')],
1104
+ ["\xff\xff\xff\xff\xff\xff\xff\xff".force_encoding('ASCII-8BIT')],
1105
+ ["\xff\xff\xff\xff\xff\xff\xff\xff".force_encoding('ASCII-8BIT')],
1106
+ ]
1107
+ else
1108
+ @s.entries.should == [
1109
+ ["\x00\x00\x00\x00\x00\x00\x00\x00"],
1110
+ ["\xff\xff\xff\xff\xff\xff\xff\xff"],
1111
+ ["\x00\x00\x00\x01\x00\x00\x00\x00"],
1112
+ ["\xff\xff\xff\xff\xff\xff\xff\xff"],
1113
+ ["\xff\xff\xff\xff\xff\xff\xff\xff"],
1114
+ ]
1115
+ end
1116
+ end
1117
+
1118
+ it '#fetch tinyint column' do
1119
+ @m.query 'create temporary table t (i tinyint)'
1120
+ @m.query 'insert into t values (0),(-1),(127),(-128),(255),(-255)'
1121
+ @s.prepare 'select i from t'
1122
+ @s.execute
1123
+ @s.entries.should == [[0], [-1], [127], [-128], [127], [-128]]
1124
+ end
1125
+
1126
+ it '#fetch tinyint unsigned column' do
1127
+ @m.query 'create temporary table t (i tinyint unsigned)'
1128
+ @m.query 'insert into t values (0),(-1),(127),(-128),(255),(-255),(256)'
1129
+ @s.prepare 'select i from t'
1130
+ @s.execute
1131
+ @s.entries.should == [[0], [0], [127], [0], [255], [0], [255]]
1132
+ end
1133
+
1134
+ it '#fetch smallint column' do
1135
+ @m.query 'create temporary table t (i smallint)'
1136
+ @m.query 'insert into t values (0),(-1),(32767),(-32768),(65535),(-65535),(65536)'
1137
+ @s.prepare 'select i from t'
1138
+ @s.execute
1139
+ @s.entries.should == [[0], [-1], [32767], [-32768], [32767], [-32768], [32767]]
1140
+ end
1141
+
1142
+ it '#fetch smallint unsigned column' do
1143
+ @m.query 'create temporary table t (i smallint unsigned)'
1144
+ @m.query 'insert into t values (0),(-1),(32767),(-32768),(65535),(-65535),(65536)'
1145
+ @s.prepare 'select i from t'
1146
+ @s.execute
1147
+ @s.entries.should == [[0], [0], [32767], [0], [65535], [0], [65535]]
1148
+ end
1149
+
1150
+ it '#fetch mediumint column' do
1151
+ @m.query 'create temporary table t (i mediumint)'
1152
+ @m.query 'insert into t values (0),(-1),(8388607),(-8388608),(16777215),(-16777215),(16777216)'
1153
+ @s.prepare 'select i from t'
1154
+ @s.execute
1155
+ @s.entries.should == [[0], [-1], [8388607], [-8388608], [8388607], [-8388608], [8388607]]
1156
+ end
1157
+
1158
+ it '#fetch mediumint unsigned column' do
1159
+ @m.query 'create temporary table t (i mediumint unsigned)'
1160
+ @m.query 'insert into t values (0),(-1),(8388607),(-8388608),(16777215),(-16777215),(16777216)'
1161
+ @s.prepare 'select i from t'
1162
+ @s.execute
1163
+ @s.entries.should == [[0], [0], [8388607], [0], [16777215], [0], [16777215]]
1164
+ end
1165
+
1166
+ it '#fetch int column' do
1167
+ @m.query 'create temporary table t (i int)'
1168
+ @m.query 'insert into t values (0),(-1),(2147483647),(-2147483648),(4294967295),(-4294967295),(4294967296)'
1169
+ @s.prepare 'select i from t'
1170
+ @s.execute
1171
+ @s.entries.should == [[0], [-1], [2147483647], [-2147483648], [2147483647], [-2147483648], [2147483647]]
1172
+ end
1173
+
1174
+ it '#fetch int unsigned column' do
1175
+ @m.query 'create temporary table t (i int unsigned)'
1176
+ @m.query 'insert into t values (0),(-1),(2147483647),(-2147483648),(4294967295),(-4294967295),(4294967296)'
1177
+ @s.prepare 'select i from t'
1178
+ @s.execute
1179
+ @s.entries.should == [[0], [0], [2147483647], [0], [4294967295], [0], [4294967295]]
1180
+ end
1181
+
1182
+ it '#fetch bigint column' do
1183
+ @m.query 'create temporary table t (i bigint)'
1184
+ @m.query 'insert into t values (0),(-1),(9223372036854775807),(-9223372036854775808),(18446744073709551615),(-18446744073709551615),(18446744073709551616)'
1185
+ @s.prepare 'select i from t'
1186
+ @s.execute
1187
+ @s.entries.should == [[0], [-1], [9223372036854775807], [-9223372036854775808], [9223372036854775807], [-9223372036854775808], [9223372036854775807]]
1188
+ end
1189
+
1190
+ it '#fetch bigint unsigned column' do
1191
+ @m.query 'create temporary table t (i bigint unsigned)'
1192
+ @m.query 'insert into t values (0),(-1),(9223372036854775807),(-9223372036854775808),(18446744073709551615),(-18446744073709551615),(18446744073709551616)'
1193
+ @s.prepare 'select i from t'
1194
+ @s.execute
1195
+ @s.entries.should == [[0], [0], [9223372036854775807], [0], [18446744073709551615], [0], [18446744073709551615]]
1196
+ end
1197
+
1198
+ it '#fetch float column' do
1199
+ @m.query 'create temporary table t (i float)'
1200
+ @m.query 'insert into t values (0),(-3.402823466E+38),(-1.175494351E-38),(1.175494351E-38),(3.402823466E+38)'
1201
+ @s.prepare 'select i from t'
1202
+ @s.execute
1203
+ @s.fetch[0].should == 0.0
1204
+ (@s.fetch[0] - -3.402823466E+38).abs.should < 0.000000001E+38
1205
+ (@s.fetch[0] - -1.175494351E-38).abs.should < 0.000000001E-38
1206
+ (@s.fetch[0] - 1.175494351E-38).abs.should < 0.000000001E-38
1207
+ (@s.fetch[0] - 3.402823466E+38).abs.should < 0.000000001E+38
1208
+ end
1209
+
1210
+ it '#fetch float unsigned column' do
1211
+ @m.query 'create temporary table t (i float unsigned)'
1212
+ @m.query 'insert into t values (0),(-3.402823466E+38),(-1.175494351E-38),(1.175494351E-38),(3.402823466E+38)'
1213
+ @s.prepare 'select i from t'
1214
+ @s.execute
1215
+ @s.fetch[0].should == 0.0
1216
+ @s.fetch[0].should == 0.0
1217
+ @s.fetch[0].should == 0.0
1218
+ (@s.fetch[0] - 1.175494351E-38).abs.should < 0.000000001E-38
1219
+ (@s.fetch[0] - 3.402823466E+38).abs.should < 0.000000001E+38
1220
+ end
1221
+
1222
+ it '#fetch double column' do
1223
+ @m.query 'create temporary table t (i double)'
1224
+ @m.query 'insert into t values (0),(-1.7976931348623157E+308),(-2.2250738585072014E-308),(2.2250738585072014E-308),(1.7976931348623157E+308)'
1225
+ @s.prepare 'select i from t'
1226
+ @s.execute
1227
+ @s.fetch[0].should == 0.0
1228
+ (@s.fetch[0] - -Float::MAX).abs.should < Float::EPSILON
1229
+ (@s.fetch[0] - -Float::MIN).abs.should < Float::EPSILON
1230
+ (@s.fetch[0] - Float::MIN).abs.should < Float::EPSILON
1231
+ (@s.fetch[0] - Float::MAX).abs.should < Float::EPSILON
1232
+ end
1233
+
1234
+ it '#fetch double unsigned column' do
1235
+ @m.query 'create temporary table t (i double unsigned)'
1236
+ @m.query 'insert into t values (0),(-1.7976931348623157E+308),(-2.2250738585072014E-308),(2.2250738585072014E-308),(1.7976931348623157E+308)'
1237
+ @s.prepare 'select i from t'
1238
+ @s.execute
1239
+ @s.fetch[0].should == 0.0
1240
+ @s.fetch[0].should == 0.0
1241
+ @s.fetch[0].should == 0.0
1242
+ (@s.fetch[0] - Float::MIN).abs.should < Float::EPSILON
1243
+ (@s.fetch[0] - Float::MAX).abs.should < Float::EPSILON
1244
+ end
1245
+
1246
+ it '#fetch decimal column' do
1247
+ @m.query 'create temporary table t (i decimal)'
1248
+ @m.query 'insert into t values (0),(9999999999),(-9999999999),(10000000000),(-10000000000)'
1249
+ @s.prepare 'select i from t'
1250
+ @s.execute
1251
+ @s.entries.should == [["0"], ["9999999999"], ["-9999999999"], ["9999999999"], ["-9999999999"]]
1252
+ end
1253
+
1254
+ it '#fetch decimal unsigned column' do
1255
+ @m.query 'create temporary table t (i decimal unsigned)'
1256
+ @m.query 'insert into t values (0),(9999999998),(9999999999),(-9999999998),(-9999999999),(10000000000),(-10000000000)'
1257
+ @s.prepare 'select i from t'
1258
+ @s.execute
1259
+ @s.entries.should == [["0"], ["9999999998"], ["9999999999"], ["0"], ["0"], ["9999999999"], ["0"]]
1260
+ end
1261
+
1262
+ it '#fetch date column' do
1263
+ @m.query 'create temporary table t (i date)'
1264
+ @m.query "insert into t values ('0000-00-00'),('1000-01-01'),('9999-12-31')"
1265
+ @s.prepare 'select i from t'
1266
+ @s.execute
1267
+ cols = @s.fetch
1268
+ cols.should == [Mysql::Time.new]
1269
+ cols.first.to_s.should == '0000-00-00'
1270
+ cols = @s.fetch
1271
+ cols.should == [Mysql::Time.new(1000,1,1)]
1272
+ cols.first.to_s.should == '1000-01-01'
1273
+ cols = @s.fetch
1274
+ cols.should == [Mysql::Time.new(9999,12,31)]
1275
+ cols.first.to_s.should == '9999-12-31'
1276
+ end
1277
+
1278
+ it '#fetch datetime column' do
1279
+ @m.query 'create temporary table t (i datetime)'
1280
+ @m.query "insert into t values ('0000-00-00 00:00:00'),('1000-01-01 00:00:00'),('9999-12-31 23:59:59')"
1281
+ @s.prepare 'select i from t'
1282
+ @s.execute
1283
+ @s.fetch.should == [Mysql::Time.new]
1284
+ @s.fetch.should == [Mysql::Time.new(1000,1,1)]
1285
+ @s.fetch.should == [Mysql::Time.new(9999,12,31,23,59,59)]
1286
+ end
1287
+
1288
+ it '#fetch timestamp column' do
1289
+ @m.query 'create temporary table t (i timestamp)'
1290
+ @m.query("insert into t values ('1970-01-02 00:00:00'),('2037-12-30 23:59:59')")
1291
+ @s.prepare 'select i from t'
1292
+ @s.execute
1293
+ @s.fetch.should == [Mysql::Time.new(1970,1,2)]
1294
+ @s.fetch.should == [Mysql::Time.new(2037,12,30,23,59,59)]
1295
+ end
1296
+
1297
+ it '#fetch time column' do
1298
+ @m.query 'create temporary table t (i time)'
1299
+ @m.query "insert into t values ('-838:59:59'),(0),('838:59:59')"
1300
+ @s.prepare 'select i from t'
1301
+ @s.execute
1302
+ @s.fetch.should == [Mysql::Time.new(0,0,0,838,59,59,true)]
1303
+ @s.fetch.should == [Mysql::Time.new(0,0,0,0,0,0,false)]
1304
+ @s.fetch.should == [Mysql::Time.new(0,0,0,838,59,59,false)]
1305
+ end
1306
+
1307
+ it '#fetch year column' do
1308
+ @m.query 'create temporary table t (i year)'
1309
+ @m.query 'insert into t values (0),(70),(69),(1901),(2155)'
1310
+ @s.prepare 'select i from t'
1311
+ @s.execute
1312
+ @s.entries.should == [[0], [1970], [2069], [1901], [2155]]
1313
+ end
1314
+
1315
+ it '#fetch char column' do
1316
+ @m.query 'create temporary table t (i char(10))'
1317
+ @m.query "insert into t values (null),('abc')"
1318
+ @s.prepare 'select i from t'
1319
+ @s.execute
1320
+ @s.entries.should == [[nil], ['abc']]
1321
+ end
1322
+
1323
+ it '#fetch varchar column' do
1324
+ @m.query 'create temporary table t (i varchar(10))'
1325
+ @m.query "insert into t values (null),('abc')"
1326
+ @s.prepare 'select i from t'
1327
+ @s.execute
1328
+ @s.entries.should == [[nil], ['abc']]
1329
+ end
1330
+
1331
+ it '#fetch binary column' do
1332
+ @m.query 'create temporary table t (i binary(10))'
1333
+ @m.query "insert into t values (null),('abc')"
1334
+ @s.prepare 'select i from t'
1335
+ @s.execute
1336
+ @s.entries.should == [[nil], ["abc\0\0\0\0\0\0\0"]]
1337
+ end
1338
+
1339
+ it '#fetch varbinary column' do
1340
+ @m.query 'create temporary table t (i varbinary(10))'
1341
+ @m.query "insert into t values (null),('abc')"
1342
+ @s.prepare 'select i from t'
1343
+ @s.execute
1344
+ @s.entries.should == [[nil], ["abc"]]
1345
+ end
1346
+
1347
+ it '#fetch tinyblob column' do
1348
+ @m.query 'create temporary table t (i tinyblob)'
1349
+ @m.query "insert into t values (null),('abc')"
1350
+ @s.prepare 'select i from t'
1351
+ @s.execute
1352
+ @s.entries.should == [[nil], ["abc"]]
1353
+ end
1354
+
1355
+ it '#fetch tinytext column' do
1356
+ @m.query 'create temporary table t (i tinytext)'
1357
+ @m.query "insert into t values (null),('abc')"
1358
+ @s.prepare 'select i from t'
1359
+ @s.execute
1360
+ @s.entries.should == [[nil], ["abc"]]
1361
+ end
1362
+
1363
+ it '#fetch blob column' do
1364
+ @m.query 'create temporary table t (i blob)'
1365
+ @m.query "insert into t values (null),('abc')"
1366
+ @s.prepare 'select i from t'
1367
+ @s.execute
1368
+ @s.entries.should == [[nil], ["abc"]]
1369
+ end
1370
+
1371
+ it '#fetch text column' do
1372
+ @m.query 'create temporary table t (i text)'
1373
+ @m.query "insert into t values (null),('abc')"
1374
+ @s.prepare 'select i from t'
1375
+ @s.execute
1376
+ @s.entries.should == [[nil], ["abc"]]
1377
+ end
1378
+
1379
+ it '#fetch mediumblob column' do
1380
+ @m.query 'create temporary table t (i mediumblob)'
1381
+ @m.query "insert into t values (null),('abc')"
1382
+ @s.prepare 'select i from t'
1383
+ @s.execute
1384
+ @s.entries.should == [[nil], ["abc"]]
1385
+ end
1386
+
1387
+ it '#fetch mediumtext column' do
1388
+ @m.query 'create temporary table t (i mediumtext)'
1389
+ @m.query "insert into t values (null),('abc')"
1390
+ @s.prepare 'select i from t'
1391
+ @s.execute
1392
+ @s.entries.should == [[nil], ["abc"]]
1393
+ end
1394
+
1395
+ it '#fetch longblob column' do
1396
+ @m.query 'create temporary table t (i longblob)'
1397
+ @m.query "insert into t values (null),('abc')"
1398
+ @s.prepare 'select i from t'
1399
+ @s.execute
1400
+ @s.entries.should == [[nil], ["abc"]]
1401
+ end
1402
+
1403
+ it '#fetch longtext column' do
1404
+ @m.query 'create temporary table t (i longtext)'
1405
+ @m.query "insert into t values (null),('abc')"
1406
+ @s.prepare 'select i from t'
1407
+ @s.execute
1408
+ @s.entries.should == [[nil], ["abc"]]
1409
+ end
1410
+
1411
+ it '#fetch enum column' do
1412
+ @m.query "create temporary table t (i enum('abc','def'))"
1413
+ @m.query "insert into t values (null),(0),(1),(2),('abc'),('def'),('ghi')"
1414
+ @s.prepare 'select i from t'
1415
+ @s.execute
1416
+ @s.entries.should == [[nil], [''], ['abc'], ['def'], ['abc'], ['def'], ['']]
1417
+ end
1418
+
1419
+ it '#fetch set column' do
1420
+ @m.query "create temporary table t (i set('abc','def'))"
1421
+ @m.query "insert into t values (null),(0),(1),(2),(3),('abc'),('def'),('abc,def'),('ghi')"
1422
+ @s.prepare 'select i from t'
1423
+ @s.execute
1424
+ @s.entries.should == [[nil], [''], ['abc'], ['def'], ['abc,def'], ['abc'], ['def'], ['abc,def'], ['']]
1425
+ end
1426
+
1427
+ it '#field_count' do
1428
+ @s.prepare 'select 1,2,3'
1429
+ @s.field_count.should == 3
1430
+ @s.prepare 'set @a=1'
1431
+ @s.field_count.should == 0
1432
+ end
1433
+
1434
+ it '#free_result' do
1435
+ @s.free_result
1436
+ @s.prepare 'select 1,2,3'
1437
+ @s.execute
1438
+ @s.free_result
1439
+ end
1440
+
1441
+ it '#insert_id' do
1442
+ @m.query 'create temporary table t (i int auto_increment, unique(i))'
1443
+ @s.prepare 'insert into t values (0)'
1444
+ @s.execute
1445
+ @s.insert_id.should == 1
1446
+ @s.execute
1447
+ @s.insert_id.should == 2
1448
+ end
1449
+
1450
+ it '#num_rows' do
1451
+ @m.query 'create temporary table t (i int)'
1452
+ @m.query 'insert into t values (1),(2),(3),(4)'
1453
+ @s.prepare 'select * from t'
1454
+ @s.execute
1455
+ @s.num_rows.should == 4
1456
+ end
1457
+
1458
+ it '#param_count' do
1459
+ @m.query 'create temporary table t (a int, b int, c int)'
1460
+ @s.prepare 'select * from t'
1461
+ @s.param_count.should == 0
1462
+ @s.prepare 'insert into t values (?,?,?)'
1463
+ @s.param_count.should == 3
1464
+ end
1465
+
1466
+ it '#prepare' do
1467
+ @s.prepare('select 1').should be_kind_of Mysql::Stmt
1468
+ proc{@s.prepare 'invalid syntax'}.should raise_error Mysql::ParseError
1469
+ end
1470
+
1471
+ it '#prepare returns self' do
1472
+ @s.prepare('select 1').should == @s
1473
+ end
1474
+
1475
+ it '#prepare with invalid query raises error' do
1476
+ proc{@s.prepare 'invalid query'}.should raise_error Mysql::ParseError
1477
+ end
1478
+
1479
+ it '#result_metadata' do
1480
+ @s.prepare 'select 1 foo, 2 bar'
1481
+ f = @s.result_metadata.fetch_fields
1482
+ f[0].name.should == 'foo'
1483
+ f[1].name.should == 'bar'
1484
+ end
1485
+
1486
+ it '#result_metadata forn no data' do
1487
+ @s.prepare 'set @a=1'
1488
+ @s.result_metadata.should == nil
1489
+ end
1490
+
1491
+ it '#row_seek and #row_tell' do
1492
+ @m.query 'create temporary table t (i int)'
1493
+ @m.query 'insert into t values (0),(1),(2),(3),(4)'
1494
+ @s.prepare 'select * from t'
1495
+ @s.execute
1496
+ row0 = @s.row_tell
1497
+ @s.fetch.should == [0]
1498
+ @s.fetch.should == [1]
1499
+ row2 = @s.row_seek row0
1500
+ @s.fetch.should == [0]
1501
+ @s.row_seek row2
1502
+ @s.fetch.should == [2]
1503
+ end
1504
+
1505
+ it '#sqlstate' do
1506
+ @s.prepare 'select 1'
1507
+ @s.sqlstate.should == '00000'
1508
+ proc{@s.prepare 'hogehoge'}.should raise_error Mysql::ParseError
1509
+ @s.sqlstate.should == '42000'
1510
+ end
1511
+ end
1512
+
1513
+ describe 'Mysql::Time' do
1514
+ before do
1515
+ @t = Mysql::Time.new
1516
+ end
1517
+
1518
+ it '.new with no arguments returns 0' do
1519
+ @t.year.should == 0
1520
+ @t.month.should == 0
1521
+ @t.day.should == 0
1522
+ @t.hour.should == 0
1523
+ @t.minute.should == 0
1524
+ @t.second.should == 0
1525
+ @t.neg.should == false
1526
+ @t.second_part.should == 0
1527
+ end
1528
+
1529
+ it '#inspect' do
1530
+ Mysql::Time.new(2009,12,8,23,35,21).inspect.should == '#<Mysql::Time:2009-12-08 23:35:21>'
1531
+ end
1532
+
1533
+ it '#to_s' do
1534
+ Mysql::Time.new(2009,12,8,23,35,21).to_s.should == '2009-12-08 23:35:21'
1535
+ end
1536
+
1537
+ it '#to_i' do
1538
+ Mysql::Time.new(2009,12,8,23,35,21).to_i.should == 20091208233521
1539
+ end
1540
+
1541
+ it '#year' do
1542
+ (@t.year = 2009).should == 2009
1543
+ @t.year.should == 2009
1544
+ end
1545
+
1546
+ it '#month' do
1547
+ (@t.month = 12).should == 12
1548
+ @t.month.should == 12
1549
+ end
1550
+
1551
+ it '#day' do
1552
+ (@t.day = 8).should == 8
1553
+ @t.day.should == 8
1554
+ end
1555
+
1556
+ it '#hour' do
1557
+ (@t.hour = 23).should == 23
1558
+ @t.hour.should == 23
1559
+ end
1560
+
1561
+ it '#minute' do
1562
+ (@t.minute = 35).should == 35
1563
+ @t.minute.should == 35
1564
+ end
1565
+
1566
+ it '#second' do
1567
+ (@t.second = 21).should == 21
1568
+ @t.second.should == 21
1569
+ end
1570
+
1571
+ it '#neg' do
1572
+ @t.neg.should == false
1573
+ end
1574
+
1575
+ it '#second_part' do
1576
+ @t.second_part.should == 0
1577
+ end
1578
+
1579
+ it '#==' do
1580
+ t1 = Mysql::Time.new 2009,12,8,23,35,21
1581
+ t2 = Mysql::Time.new 2009,12,8,23,35,21
1582
+ t1.should == t2
1583
+ end
1584
+ end
1585
+
1586
+ describe 'Mysql::Error' do
1587
+ before do
1588
+ m = Mysql.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
1589
+ begin
1590
+ m.query('hogehoge')
1591
+ rescue => @e
1592
+ end
1593
+ end
1594
+
1595
+ it '#error is error message' do
1596
+ @e.error.should == "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'hogehoge' at line 1"
1597
+ end
1598
+
1599
+ it '#errno is error number' do
1600
+ @e.errno.should == 1064
1601
+ end
1602
+
1603
+ it '#sqlstate is sqlstate value as String' do
1604
+ @e.sqlstate.should == '42000'
1605
+ end
1606
+ end
1607
+
1608
+ if defined? Encoding
1609
+ describe 'Connection charset is UTF-8:' do
1610
+ before do
1611
+ @m = Mysql.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
1612
+ @m.charset = "utf8"
1613
+ @m.query "create temporary table t (utf8 char(10) charset utf8, cp932 char(10) charset cp932, eucjp char(10) charset eucjpms, bin varbinary(10))"
1614
+ @utf8 = "いろは"
1615
+ @cp932 = @utf8.encode "CP932"
1616
+ @eucjp = @utf8.encode "EUC-JP-MS"
1617
+ @bin = "\x00\x01\x7F\x80\xFE\xFF".force_encoding("ASCII-8BIT")
1618
+ @default_internal = Encoding.default_internal
1619
+ end
1620
+
1621
+ after do
1622
+ Encoding.default_internal = @default_internal
1623
+ end
1624
+
1625
+ describe 'default_internal is CP932' do
1626
+ before do
1627
+ Encoding.default_internal = 'CP932'
1628
+ end
1629
+ it 'is converted to CP932' do
1630
+ @m.query('select "あいう"').fetch.should == ["\x82\xA0\x82\xA2\x82\xA4".force_encoding("CP932")]
1631
+ end
1632
+ end
1633
+
1634
+ describe 'query with CP932 encoding' do
1635
+ it 'is converted to UTF-8' do
1636
+ @m.query('select HEX("あいう")'.encode("CP932")).fetch.should == ["E38182E38184E38186"]
1637
+ end
1638
+ end
1639
+
1640
+ describe 'prepared statement with CP932 encoding' do
1641
+ it 'is converted to UTF-8' do
1642
+ @m.prepare('select HEX("あいう")'.encode("CP932")).execute.fetch.should == ["E38182E38184E38186"]
1643
+ end
1644
+ end
1645
+
1646
+ describe 'The encoding of data are correspond to charset of column:' do
1647
+ before do
1648
+ @m.prepare("insert into t (utf8,cp932,eucjp,bin) values (?,?,?,?)").execute @utf8, @cp932, @eucjp, @bin
1649
+ end
1650
+ it 'data is stored as is' do
1651
+ @m.query('select hex(utf8),hex(cp932),hex(eucjp),hex(bin) from t').fetch.should == ['E38184E3828DE381AF', '82A282EB82CD', 'A4A4A4EDA4CF', '00017F80FEFF']
1652
+ end
1653
+ it 'By simple query, charset of retrieved data is connection charset' do
1654
+ @m.query('select utf8,cp932,eucjp,bin from t').fetch.should == [@utf8, @utf8, @utf8, @bin.dup.force_encoding("UTF-8")]
1655
+ end
1656
+ it 'By prepared statement, charset of retrieved data is connection charset except for binary' do
1657
+ @m.prepare('select utf8,cp932,eucjp,bin from t').execute.fetch.should == [@utf8, @utf8, @utf8, @bin]
1658
+ end
1659
+ end
1660
+
1661
+ describe 'The encoding of data are different from charset of column:' do
1662
+ before do
1663
+ @m.prepare("insert into t (utf8,cp932,eucjp,bin) values (?,?,?,?)").execute @utf8, @utf8, @utf8, @utf8
1664
+ end
1665
+ it 'stored data is converted' do
1666
+ @m.query("select hex(utf8),hex(cp932),hex(eucjp),hex(bin) from t").fetch.should == ["E38184E3828DE381AF", "82A282EB82CD", "A4A4A4EDA4CF", "E38184E3828DE381AF"]
1667
+ end
1668
+ it 'By simple query, charset of retrieved data is connection charset' do
1669
+ @m.query("select utf8,cp932,eucjp,bin from t").fetch.should == [@utf8, @utf8, @utf8, @utf8]
1670
+ end
1671
+ it 'By prepared statement, charset of retrieved data is connection charset except for binary' do
1672
+ @m.prepare("select utf8,cp932,eucjp,bin from t").execute.fetch.should == [@utf8, @utf8, @utf8, @utf8.dup.force_encoding("ASCII-8BIT")]
1673
+ end
1674
+ end
1675
+
1676
+ describe 'The data include invalid byte code:' do
1677
+ it 'raises Encoding::InvalidByteSequenceError' do
1678
+ cp932 = "\x01\xFF\x80".force_encoding("CP932")
1679
+ proc{@m.prepare("insert into t (cp932) values (?)").execute cp932}.should raise_error(Encoding::InvalidByteSequenceError)
1680
+ end
1681
+ end
1682
+ end
1683
+ end