ruby-mysql 3.0.1 → 4.1.0

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