ruby-mysql 2.9.12 → 2.11.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.
@@ -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