ruby-mysql 3.0.1 → 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,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