ruby-mysql 2.9.12 → 2.11.0

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