ruby-mysql 3.0.0 → 4.0.0

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