\n"
53 | else
54 | exit 1
55 | end
56 |
57 | # make mysql constant
58 | File.open("conftest.c", "w") do |f|
59 | f.puts src
60 | end
61 | if defined? cpp_command then
62 | cpp = RbConfig.expand(cpp_command(''))
63 | else
64 | cpp = RbConfig.expand sprintf(CPP, $CPPFLAGS, $CFLAGS, '')
65 | end
66 | if RUBY_PLATFORM =~ /mswin/ && !/-E/.match(cpp)
67 | cpp << " -E"
68 | end
69 | unless system "#{cpp} > confout" then
70 | exit 1
71 | end
72 | File.unlink "conftest.c"
73 |
74 | error_syms = []
75 | IO.foreach('confout') do |l|
76 | next unless l =~ /errmsg\.h|mysqld_error\.h/
77 | fn = l.split(/\"/)[1]
78 | IO.foreach(fn) do |m|
79 | if m =~ /^#define\s+([CE]R_[0-9A-Z_]+)/ then
80 | error_syms << $1
81 | end
82 | end
83 | end
84 | File.unlink 'confout'
85 | error_syms.uniq!
86 |
87 | File.open('error_const.h', 'w') do |f|
88 | error_syms.each do |s|
89 | f.puts " rb_define_mysql_const(#{s});"
90 | end
91 | end
92 |
93 | create_makefile("mysql/mysql_api")
94 |
--------------------------------------------------------------------------------
/extra/README.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | MySQL/Ruby
9 |
10 |
11 |
12 | MySQL/Ruby
13 | [Japanese]
14 |
15 |
16 | This is the MySQL API module for Ruby.
17 | It provides the same functions for Ruby programs that the MySQL C API provides for C programs.
18 |
19 |
20 | Download
21 |
25 |
26 | Requirement
27 |
28 | MySQL 5.0.67
29 | Ruby 1.8.7, 1.9.1
30 |
31 |
32 | The module may work for other versions, but that has not been verified.
33 |
34 |
35 | License
36 |
37 | This program is under Ruby's license .
38 |
39 |
40 | Install
41 |
42 | 1st:
43 |
44 |
45 | % ruby extconf.rb
46 |
47 |
48 | or
49 |
50 |
51 | % ruby extconf.rb --with-mysql-dir=/usr/local/mysql
52 |
53 |
54 | or
55 |
56 |
57 | % ruby extconf.rb --with-mysql-config
58 |
59 |
60 | then
61 |
62 |
63 | % make
64 |
65 |
66 | extconf.rb has following options:
67 |
68 |
69 | --with-mysql-include=dir
70 |
71 | MySQL header file directory. Default is /usr/local/include.
72 |
73 | --with-mysql-lib=dir
74 |
75 | MySQL library directory. Default is /usr/local/lib.
76 |
77 | --with-mysql-dir=dir
78 |
79 | Same as --with-mysql-include=dir /include,
80 | --with-mysql-lib=dir /lib.
81 |
82 | --with-mysql-config[=/path/to/mysql_config ]
83 |
84 | Get compile-parameter from mysql_config command.
85 |
86 |
87 | 2nd:
88 |
89 |
90 | % ruby ./test.rb -- [hostname [user [passwd [dbname [port [socket [flag ]]]]]]]
91 |
92 |
93 |
94 | 3rd:
95 |
96 |
97 | # make install
98 |
99 |
100 | Note
101 |
102 | If you get error like 'libmysqlclient not found' when testing,
103 | you need to specify the directory in which the library is
104 | located so that make can find it.
105 |
106 |
107 | % env LD_RUN_PATH=libmysqlclient.so directory make
108 |
109 |
110 | test.rb is tested on Linux only.
111 |
112 |
113 | Usage
114 |
115 | The names of methods provided by this module basically are the
116 | same as the names of the functions in the C API, except that the
117 | Ruby method names do not begin with a 'mysql_' prefix. For
118 | example, the Ruby query() method corresponds to the C API
119 | mysql_query() function. For details on the use of each Ruby
120 | method, see the descriptions of the corresponding C functions in
121 | the MySQL Reference Manual.
122 |
123 |
124 | Some Ruby methods may be invoked under other names that serve as
125 | equivalent aliases, as noted below.
126 |
127 |
128 | If an error occurs when a method executes, it raises a
129 | Mysql::Error exception.
130 |
131 |
132 | Mysql class
133 | CLASS METHODS
134 |
135 | init()
136 |
137 |
138 | It return Mysql object. It not connect to mysqld.
139 |
140 |
141 | real_connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil)
142 | connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil)
143 | new(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil)
144 |
145 |
146 | connect to mysqld and return Mysql object.
147 |
148 |
149 | escape_string(str)
150 | quote(str)
151 |
152 |
153 | quote string for insert/update.
154 |
155 |
156 | get_client_info()
157 | client_info()
158 |
159 |
160 | return client version information.
161 |
162 |
163 | get_client_version()
164 | client_version()
165 |
166 |
167 | return client version as number.
168 |
169 |
170 | debug(str)
171 |
172 |
173 | same as C API mysql_debug().
174 |
175 |
176 |
177 | OBJECT METHODS
178 |
179 | options(opt, val=nil)
180 |
181 |
182 | same as C API mysql_options().
183 |
184 |
185 | real_connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil)
186 | connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil)
187 |
188 |
189 | same as Mysql.real_connect().
190 |
191 |
192 | affected_rows()
193 |
194 |
195 | return affected rows.
196 |
197 |
198 | autocommit(mode)
199 |
200 |
201 | set autocommit mode.
202 |
203 |
204 | change_user(user=nil, passwd=nil, db=nil)
205 |
206 |
207 | change user.
208 |
209 |
210 | character_set_name()
211 |
212 |
213 | return character set.
214 |
215 |
216 | close()
217 |
218 |
219 | close connection.
220 |
221 |
222 | commit()
223 |
224 |
225 | commit transaction.
226 |
227 |
228 | create_db(db)
229 |
230 |
231 | create database.
232 |
233 |
234 | drop_db(db)
235 |
236 |
237 | drop database.
238 |
239 |
240 | dump_debug_info()
241 |
242 |
243 | same as C API mysql_dump_debug_info().
244 |
245 |
246 | errno()
247 |
248 |
249 | return error number.
250 |
251 |
252 | error()
253 |
254 |
255 | return error message.
256 |
257 |
258 | escape_string(str)
259 | quote(str)
260 |
261 |
262 | quote strings for insert/update.
263 | same as C API mysql_real_escape_string().
264 |
265 |
266 | field_count()
267 |
268 |
269 | return number of columns of last query.
270 |
271 |
272 | get_client_info()
273 | client_info()
274 |
275 |
276 | return client version information.
277 |
278 |
279 | get_client_version()
280 | client_version()
281 |
282 |
283 | return client version number.
284 |
285 |
286 | get_host_info()
287 | host_info()
288 |
289 |
290 | return connection information.
291 |
292 |
293 | get_proto_info()
294 | proto_info()
295 |
296 |
297 | return connection protocol version.
298 |
299 |
300 | get_server_info()
301 | server_info()
302 |
303 |
304 | return server version information.
305 |
306 |
307 | get_server_version()
308 | server_version()
309 |
310 |
311 | return server version number.
312 |
313 |
314 | info()
315 |
316 |
317 | return information of last query.
318 |
319 |
320 | insert_id()
321 |
322 |
323 | return last AUTO_INCREMENT value.
324 |
325 |
326 | kill(id)
327 |
328 |
329 | kill thread.
330 |
331 |
332 | list_dbs(db=nil)
333 |
334 |
335 | return database list.
336 |
337 |
338 | list_fields(table, field=nil)
339 |
340 |
341 | return Mysql::Result object.
342 |
343 |
344 | list_processes()
345 |
346 |
347 | return Mysql::Result object.
348 |
349 |
350 | list_tables(table=nil)
351 |
352 |
353 | return table list Array.
354 |
355 |
356 | more_results?()
357 |
358 |
359 | returns true if more results exist from the currently executed query.
360 |
361 |
362 | next_result()
363 |
364 |
365 | returns true if more results exist from the currently executed query.
366 | after this, you do store_result() to get result table of query.
367 |
368 |
369 | ping()
370 |
371 |
372 | check server.
373 |
374 |
375 | prepare(q)
376 |
377 |
378 |
379 |
380 | query(q)
381 | real_query(q)
382 |
383 |
384 | do query and store_result(). return Mysql::Result object.
385 | If query_with_result is false, it does not store_result().
386 |
387 |
388 | query(q) {|res| ...}
389 | real_query(q) {|res| ...}
390 |
391 |
392 | do query and execute block with Mysql::Result object.
393 | Mysql::Result object is freed when exiting block.
394 | If multiple statement mode, it does repeat block each query.
395 |
396 |
397 | Since MySQL/Ruby 2.8, it no longer turn on multiple statement mode automatically.
398 | If you want to turn on multiple statement mode, set Mysql::CLIENT_MULTI_STATEMENTS for Mysql.connect or execute Mysql#set_server_option(Mysql::OPTION_MULTI_STATEMENTS_ON).
399 |
400 |
401 | refresh(r)
402 |
403 |
404 | flush server log or cache.
405 |
406 |
407 | reload()
408 |
409 |
410 | reload access privilege table.
411 |
412 |
413 | rollback()
414 |
415 |
416 | rollback transaction.
417 |
418 |
419 | select_db(db)
420 |
421 |
422 | select database.
423 |
424 |
425 | set_server_option(opt)
426 |
427 |
428 | set option to server.
429 | options is one of Mysql::OPTION_MULTI_STATEMENTS_ON, Mysql::OPTION_MULTI_STATEMENTS_OFF.
430 |
431 |
432 | shutdown()
433 |
434 |
435 | shutdown server.
436 |
437 |
438 | ssl_set(key=nil, cert=nil, ca=nil, capath=nil, cipher=nil)
439 |
440 |
441 | use SSL.
442 |
443 |
444 | stat()
445 |
446 |
447 | return server status.
448 |
449 |
450 | stmt_init()
451 |
452 |
453 | return Mysql::Stmt class object.
454 |
455 |
456 | store_result()
457 |
458 |
459 | return Mysql::Result object.
460 |
461 |
462 | thread_id()
463 |
464 |
465 | retrun thread id.
466 |
467 |
468 | use_result()
469 |
470 |
471 | return Mysql::Result object.
472 |
473 |
474 | warning_count()
475 |
476 |
477 | return warning count last query.
478 |
479 |
480 |
481 | OBJECT VARIABLES
482 |
483 |
484 | query_with_result
485 |
486 |
487 | If true, query() also invokes store_result() and returns a
488 | Mysql::Result object. Default is true.
489 |
490 |
491 | reconnect
492 |
493 |
494 | If true, reconnect to server automatically when disconect to server.
495 | Default is false.
496 |
497 |
498 |
499 |
500 | Mysql::Result class
501 |
502 | OBJECT METHODS
503 |
504 | free()
505 |
506 |
507 | free memory of result table.
508 |
509 |
510 | data_seek(offset)
511 |
512 |
513 | seek row.
514 |
515 |
516 | fetch_field()
517 |
518 |
519 | return next Mysql::Field object.
520 |
521 |
522 | fetch_fields()
523 |
524 |
525 | return Array of Mysql::Field object.
526 |
527 |
528 | fetch_field_direct(fieldnr)
529 |
530 |
531 | return Mysql::Field object.
532 |
533 |
534 | fetch_lengths()
535 |
536 |
537 | return Array of field length.
538 |
539 |
540 | fetch_row()
541 |
542 |
543 | return row as Array.
544 |
545 |
546 | fetch_hash(with_table=false)
547 |
548 |
549 | return row as Hash.
550 | If with_table is true, hash key format is "tablename.fieldname".
551 |
552 |
553 | field_seek(offset)
554 |
555 |
556 | seek field.
557 |
558 |
559 | field_tell()
560 |
561 |
562 | return field position.
563 |
564 |
565 | num_fields()
566 |
567 |
568 | return number of fields.
569 |
570 |
571 | num_rows()
572 |
573 |
574 | return number of rows.
575 |
576 |
577 | row_seek(offset)
578 |
579 |
580 | seek row.
581 |
582 |
583 | row_tell()
584 |
585 |
586 | return row position.
587 |
588 |
589 |
590 | ITERATOR
591 |
592 | each() {|x| ...}
593 |
594 |
595 | 'x' is array of column values.
596 |
597 |
598 | each_hash(with_table=false) {|x| ...}
599 |
600 |
601 | 'x' is hash of column values, and the keys are the column names.
602 |
603 |
604 |
605 | Mysql::Field class
606 |
607 | OBJECT VARIABLES(read only)
608 |
609 | name field name
610 | table table name
611 | def default value
612 | type field type
613 | length field length
614 | max_length max field length
615 | flags field flag
616 | decimals number of decimals
617 |
618 |
619 | OBJECT METHODS
620 |
621 | hash()
622 |
623 |
624 | return field as Hash.
625 |
626 |
627 | ex.) obj.name == obj.hash['name']
628 |
629 |
630 | is_not_null?()
631 |
632 |
633 | True if this field is defined as NOT NULL.
634 |
635 |
636 | is_num?()
637 |
638 |
639 | True if this field type is numeric.
640 |
641 |
642 | is_pri_key?()
643 |
644 |
645 | True if this field is a primary key.
646 |
647 |
648 | inspect()
649 |
650 |
651 | return "#<Mysql::Field:fieldname>"
652 |
653 |
654 |
655 | Mysql::Stmt class
656 |
657 | Example:
658 |
659 |
660 | my = Mysql.new(hostname, username, password, databasename)
661 | st = my.prepare("insert into tblname (col1,col2,col3) values (?,?,?)")
662 | st.execute("abc",123,Time.now)
663 | st.prepare("select col1,col2,col3 from tblname")
664 | st.execute
665 | st.fetch # => ["abc", 123, #<Mysql::Time:2005-07-24 23:52:55>]
666 | st.close
667 |
668 |
669 | OBJECT METHODS
670 |
671 | affected_rows()
672 |
673 |
674 |
675 |
676 | bind_result(class, ...)
677 |
678 |
679 |
680 |
681 | close()
682 |
683 |
684 |
685 |
686 | data_seek(offset)
687 |
688 |
689 |
690 |
691 | execute(arg, ...)
692 |
693 |
694 |
695 |
696 | fetch()
697 |
698 |
699 |
700 |
701 | Type mapping:
702 |
703 |
704 | MySQL type Ruby class
705 | TINYINT, SMALLINT, MEDIUMINT, YEAR Fixnum
706 | INT, BIGINT Fixnum or Bignum
707 | FLOAT, DOUBLE Float
708 | DECIMAL String
709 | DATE, DATETIME, TIMESTAMP, TIME Mysql::Time
710 | CHAR, VARCHAR, BINARY, VARBINARY, TINYBLOB, TINYTEXT, TINYBLOB, TINYTEXT, MEDIUMBLOB, MEDIUMTEXT, LONGBLOB, LONGTEXT, ENUM, SET, BIT String
711 | NULL NilClass
712 |
713 |
714 | field_count()
715 |
716 |
717 |
718 |
719 | free_result()
720 |
721 |
722 |
723 |
724 | insert_id()
725 |
726 |
727 |
728 |
729 | num_rows()
730 |
731 |
732 |
733 |
734 | param_count()
735 |
736 |
737 |
738 |
739 | prepare(q)
740 |
741 |
742 |
743 |
744 | result_metadata()
745 |
746 |
747 |
748 |
749 | row_seek(offset)
750 |
751 |
752 |
753 |
754 | row_tell()
755 |
756 |
757 |
758 |
759 | sqlstate()
760 |
761 |
762 |
763 |
764 |
765 | ITERATOR
766 |
767 | each() {|x| ...}
768 |
769 |
770 |
771 |
772 |
773 | Mysql::Time class
774 |
775 |
776 |
777 | CLASS METHODS
778 |
779 | new(year=0,month=0,day=0,hour=0,minute=0,second=0,neg=false,second_part=0)
780 |
781 |
782 |
783 |
784 |
785 | OBJECT VARIABLES
786 |
787 | year
788 |
789 |
790 | month
791 |
792 |
793 | day
794 |
795 |
796 | hour
797 |
798 |
799 | minute
800 |
801 |
802 | second
803 |
804 |
805 | neg
806 |
807 |
808 | second_part
809 |
810 |
811 |
812 | Mysql::Error class
813 |
814 | OBJECT VARIABLES(read only)
815 |
816 | error
817 | eror message
818 | errno
819 | error number
820 |
821 |
822 | History
823 |
824 | 2010-02-11
825 |
826 | version 2.8.2
827 |
828 | Fix: Mysql#insert_id returns invalid value when larger than 2**32.
829 |
830 |
831 | 2009-02-01
832 |
833 | version 2.8.1
834 |
835 | correspond to Ruby 1.9.1
836 |
837 |
838 | 2008-09-29
839 |
840 | version 2.8
841 | version 2.7.7
842 |
843 | When connecting to MySQL, EINTR is occurred sometimes ([ruby-dev:31842])
844 | MySQL/Ruby 2.7.* can not be compiled on Ruby 1.8.5.
845 |
846 |
847 | 2008-06-20
848 |
849 | version 2.8pre4
850 |
851 | [ruby-dev:35152]
852 |
853 |
854 | 2008-06-17
855 |
856 | version 2.8pre3
857 | version 2.7.6
858 |
859 | On 64bit machine, Mysql::Stmt#execute raise error on large numeric value(>= 2**30).
860 |
861 |
862 | 2008-03-08
863 |
864 | version 2.8pre2
865 | version 2.7.5
866 |
867 | On 64bit machine, Mysql::Stmt#fetch return invalid numeric value.
868 |
869 |
870 | 2007-12-26
871 |
872 | version 2.8pre1
873 |
874 | for Ruby 1.9.0
875 | Incompat: Mysql::Result#each_hash don't create column name string each row. it's shared.
876 | Incompat: Mysql#query with block no longer turn on multi-statements mode automatically.
877 |
878 |
879 | 2007-08-22
880 |
881 | version 2.7.4
882 |
883 | BUG: Mysql::Stmt#execute memory leak.
884 |
885 |
886 | 2006-12-20
887 |
888 | version 2.7.3
889 |
890 | BUG: Mysql#query with block is stopped when last query failed.
891 |
892 |
893 | 2006-10-28
894 |
895 | version 2.7.2
896 |
897 | BUG: Mysql::Stmt#result_metadata don't return nil. (Thanks to Hidetoshi)
898 | BUG: Mysql#close check mysql_errno.
899 | BUG: multistatement Mysql#query with block ignore error.
900 | extconf.rb for Visual C++. (Thanks to Shugo Maeda)
901 | support MySQL BIT type.
902 | add Mysql::Field::TYPE_BIT, TYPE_NEWDECIMAL.
903 |
904 |
905 | 2006-06-04
906 |
907 | version 2.7.1
908 |
909 | change free() to xfree(). To avoid crash on Windows. (Thanks Tobias Grimm)
910 |
911 |
912 | 2005-08-22
913 |
914 | version 2.7
915 |
916 | add constants for Mysql#options: Mysql::OPT_GUESS_CONNECTION, Mysql::OPT_USE_EMBEDDED_CONNECTION, Mysql::OPT_USE_REMOTE_CONNECTION, Mysql::SET_CLIENT_IP
917 | test.rb: for 4.0.x, 5.0.x
918 |
919 |
920 | 2005-08-16
921 |
922 | version 2.7-beta3
923 |
924 | add Mysql::Stmt#bind_result
925 |
926 |
927 | 2005-08-02
928 |
929 | version 2.7-beta2
930 |
931 | BUG: mysql.c.in: fetch_hash: nil value doesn't exist in hash. (Thanks Stefan Kaes)
932 | add constant Mysql::VERSION.
933 | add Mysql#prepare
934 |
935 |
936 | 2005-07-24
937 |
938 | version 2.7-beta
939 |
940 | add Mysql#stmt_init method
941 | add Mysql::Stmt, Mysql::Time, Mysql::RowOffset class
942 | add Mysql::Error#sqlstate method
943 | change offset value to Mysql::RowOffset object that is used by Mysql::Result#row_seek,row_tell
944 |
945 |
946 | 2005-07-31
947 |
948 | version 2.6.3
949 |
950 | add constant Mysql::VERSION.
951 |
952 |
953 | 2005-07-26
954 |
955 | version 2.6.2
956 |
957 | BUG: mysql.c.in: fetch_hash: nil value doesn't exist in hash. (Thanks Stefan Kaes)
958 |
959 |
960 | 2005-06-28
961 |
962 | version 2.6.1
963 |
964 | mysql.c.in: fix to compile error on MacOSX.
965 |
966 |
967 | 2005-04-25
968 |
969 | version 2.6
970 |
971 | add constants for Mysql#option():
972 | Mysql::OPT_PROTOCOL, Mysql::OPT_READ_TIMEOUT,
973 | Mysql::OPT_WRITE_TIMEOUT, Mysql::SET_CHARSET_DIR,
974 | Mysql::SET_CHARSET_NAME, Mysql::SHARED_MEMORY_BASE_NAME,
975 | Mysql::SECURE_AUTH
976 | add methods: Mysql#more_results?(), Mysql#next_result(),
977 | Mysql#set_server_option(), Mysql#sqlstate()
978 | add constants for Mysql#connect():
979 | Mysql::CLIENT_MULTI_STATEMENTS, Mysql::CLIENT_MULTI_RESULTS
980 | add constants for Mysql#set_server_option():
981 | Mysql::OPTION_MULTI_STATEMENTS_ON,
982 | Mysql::OPTION_MULTI_STATEMENTS_OFF
983 | add Mysql#query() with block
984 | add Mysql#reconnect(), Mysql#reconnect=()
985 | When connection was closed, it don't try to reconnect by default.
986 |
987 |
988 | 2005-02-12
989 |
990 | version 2.5.2
991 |
992 | BUG: Mysql#connect make object to not close. (Thanks Andres Salomon)
993 |
994 |
995 | 2004-09-20
996 |
997 | version 2.5.1
998 |
999 | add Mysql#set_ssl().
1000 |
1001 |
1002 | 2004-08-31
1003 |
1004 | version 2.5
1005 |
1006 | correspond to MySQL 4.1.x.
1007 | change MysqlRes, MysqlField, MysqlError to Mysql::Result, Mysql::Field, Mysql::Error.
1008 | add Mysql.client_version(), Mysql.get_client_version(),
1009 | Mysql#client_version(), Mysql#get_client_version(),
1010 | Mysql#server_version(), Mysql#get_server_version(),
1011 | Mysql#warning_count(), Mysql#commit(), Mysql#rollback(),
1012 | Mysql#autocommit().
1013 | add Mysql::Field#is_not_null?(), Mysql::Field#is_pri_key?(),
1014 | Mysql::Field#is_num?().
1015 | add MysqlField::TYPE_VAR_STRING.
1016 |
1017 |
1018 | 2003-08-10
1019 |
1020 | version 2.4.5
1021 |
1022 | extconf.rb: correspond to MySQL 4.1.
1023 | mysql.c.in: correspond to Ruby 1.8.
1024 |
1025 |
1026 | 2003-02-23
1027 |
1028 | version 2.4.4a
1029 |
1030 | make extconf.rb to correspond to Ruby 1.8.0
1031 |
1032 |
1033 | 2003-01-29
1034 |
1035 | version 2.4.4
1036 |
1037 | add Mysql::OPT_LOCAL_INFILE.
1038 | add --with-mysql-config option to extconf.rb.
1039 | extconf.rb automatically detect typical library.
1040 |
1041 |
1042 | 2003-01-05
1043 |
1044 | version 2.4.3c
1045 |
1046 | modified English README. Thanks to Paul DuBois.
1047 |
1048 |
1049 | 2002-12-24
1050 |
1051 | version 2.4.3b
1052 |
1053 | make extconf.rb to correspond to Ruby 1.6.8.
1054 |
1055 |
1056 | 2002-11-07
1057 |
1058 | version 2.4.3a
1059 |
1060 | fix bug duplicating constant.
1061 |
1062 |
1063 | 2002-09-10
1064 |
1065 | version 2.4.3
1066 |
1067 | for error number with prefix ER_ .
1068 | get error constant from errmsg.h and mysqld_error.h automatically.
1069 |
1070 |
1071 | 2002-01-07
1072 |
1073 | version 2.4.2
1074 |
1075 | for MySQL 4.0.
1076 | change `uint' to `unsigned int' (for mswin).
1077 |
1078 |
1079 | 2001-12-02
1080 |
1081 | version 2.4.1
1082 |
1083 | remove `extern' (for Cygiwn).
1084 | change option of extconf.rb.
1085 |
1086 |
1087 | 2001-10-12
1088 |
1089 | version 2.4.0
1090 |
1091 | for Ruby 1.7.
1092 | add Mysql::debug(), Mysql#change_user(), Mysql#character_set_name(), Mysql#dump_debug_info().
1093 |
1094 |
1095 |
1096 | Author
1097 |
1098 | e-mail: TOMITA Masahiro tommy@tmtm.org
1099 | http://tmtm.org
1100 |
1101 |
1102 | TOMITA Masahiro
1103 |
1104 |
1105 | Last modified: Sun Feb 1 17:48:41 JST 2009
1106 |
1107 |
1108 |
1109 |
--------------------------------------------------------------------------------
/test/test_mysql.rb:
--------------------------------------------------------------------------------
1 | #!/usr/local/bin/ruby
2 | # $Id: test.rb 244 2009-02-01 08:43:39Z tommy $
3 |
4 | require "test/unit"
5 | require 'ostruct'
6 | require 'mysql'
7 |
8 | CONFIG = OpenStruct.new
9 | CONFIG.host = ENV['MYSQL_HOST'] || 'localhost'
10 | CONFIG.port = ENV['MYSQL_PORT'] || '3306'
11 | CONFIG.user = ENV['MYSQL_USER'] || 'root'
12 | CONFIG.pass = ENV['MYSQL_PASS'] || ''
13 | CONFIG.sock = ENV['MYSQL_SOCK']
14 | CONFIG.flag = ENV['MYSQL_FLAG']
15 | CONFIG.database = ENV['MYSQL_DATABASE'] || 'test'
16 |
17 | class TC_Mysql < Test::Unit::TestCase
18 | def setup()
19 | @host = CONFIG.host
20 | @user = CONFIG.user
21 | @pass = CONFIG.pass
22 | @db = CONFIG.database
23 |
24 | @port = CONFIG.port.to_i
25 | @sock = CONFIG.sock
26 | @flag = CONFIG.flag.to_i
27 | end
28 |
29 | def teardown()
30 | end
31 |
32 | def test_version()
33 | assert_equal(20802, Mysql::VERSION)
34 | end
35 |
36 | def test_init()
37 | assert_nothing_raised{@m = Mysql.init}
38 | assert_nothing_raised{@m.close}
39 | end
40 |
41 | def test_real_connect()
42 | assert_nothing_raised{@m = Mysql.real_connect(@host, @user, @pass, @db, @port, @sock, @flag)}
43 | assert_nothing_raised{@m.close}
44 | end
45 |
46 | def test_connect()
47 | assert_nothing_raised{@m = Mysql.connect(@host, @user, @pass, @db, @port, @sock, @flag)}
48 | assert_nothing_raised{@m.close}
49 | end
50 |
51 | def test_new()
52 | assert_nothing_raised{@m = Mysql.new(@host, @user, @pass, @db, @port, @sock, @flag)}
53 | assert_nothing_raised{@m.close}
54 | end
55 |
56 | def test_escape_string()
57 | assert_equal("abc\\'def\\\"ghi\\0jkl%mno", Mysql.escape_string("abc'def\"ghi\0jkl%mno"))
58 | end
59 |
60 | def test_quote()
61 | assert_equal("abc\\'def\\\"ghi\\0jkl%mno", Mysql.quote("abc'def\"ghi\0jkl%mno"))
62 | end
63 |
64 | def test_get_client_info()
65 | assert_match(/^\d.\d+.\d+[a-z]?(-.*)?$/, Mysql.get_client_info())
66 | end
67 |
68 | def test_client_info()
69 | assert_match(/^\d.\d+.\d+[a-z]?(-.*)?$/, Mysql.client_info())
70 | end
71 |
72 | def test_options()
73 | @m = Mysql.init
74 | assert_equal(@m, @m.options(Mysql::INIT_COMMAND, "SET AUTOCOMMIT=0"))
75 | assert_equal(@m, @m.options(Mysql::OPT_COMPRESS))
76 | assert_equal(@m, @m.options(Mysql::OPT_CONNECT_TIMEOUT, 10))
77 | assert_equal(@m, @m.options(Mysql::GUESS_CONNECTION)) if defined? Mysql::GUESS_CONNECTION
78 | assert_equal(@m, @m.options(Mysql::OPT_LOCAL_INFILE, true))
79 | # assert_equal(@m, @m.options(Mysql::OPT_NAMED_PIPE))
80 | # assert_equal(@m, @m.options(Mysql::OPT_PROTOCOL, 1))
81 | assert_equal(@m, @m.options(Mysql::OPT_READ_TIMEOUT, 10)) if defined? Mysql::OPT_READ_TIMEOUT
82 | assert_equal(@m, @m.options(Mysql::OPT_USE_EMBEDDED_CONNECTION)) if defined? Mysql::OPT_USE_EMBEDDED_CONNECTION
83 | assert_equal(@m, @m.options(Mysql::OPT_USE_REMOTE_CONNECTION)) if defined? Mysql::OPT_USE_REMOTE_CONNECTION
84 | assert_equal(@m, @m.options(Mysql::OPT_WRITE_TIMEOUT, 10)) if defined? Mysql::OPT_WRITE_TIMEOUT
85 | # assert_equal(@m, @m.options(Mysql::READ_DEFAULT_FILE, "/tmp/hoge"))
86 | assert_equal(@m, @m.options(Mysql::READ_DEFAULT_GROUP, "test"))
87 | assert_equal(@m, @m.options(Mysql::SECURE_AUTH, true)) if defined? Mysql::SECURE_AUTH
88 | # assert_equal(@m, @m.options(Mysql::SET_CHARSET_DIR, "??"))
89 | assert_equal(@m, @m.options(Mysql::SET_CHARSET_NAME, "latin1"))
90 | assert_equal(@m, @m.options(Mysql::SET_CLIENT_IP, "127.0.0.1")) if defined? Mysql::SET_CLIENT_IP
91 | # assert_equal(@m, @m.options(Mysql::SHARED_MEMORY_BASE_NAME, "xxx"))
92 | assert_equal(@m, @m.connect(@host, @user, @pass, @db, @port, @sock, @flag))
93 | @m.close
94 | end
95 |
96 | def test_real_connect2()
97 | @m = Mysql.init
98 | assert_equal(@m, @m.real_connect(@host, @user, @pass, @db, @port, @sock, @flag))
99 | @m.close
100 | end
101 |
102 | def test_connect2()
103 | @m = Mysql.init
104 | assert_equal(@m, @m.connect(@host, @user, @pass, @db, @port, @sock, @flag))
105 | @m.close
106 | end
107 |
108 | end
109 |
110 | class TC_Mysql2 < Test::Unit::TestCase
111 | def setup()
112 | @host = CONFIG.host
113 | @user = CONFIG.user
114 | @pass = CONFIG.pass
115 | @db = CONFIG.database
116 |
117 | @port = CONFIG.port.to_i
118 | @sock = CONFIG.sock
119 | @flag = CONFIG.flag.to_i
120 |
121 | @m = Mysql.new(@host, @user, @pass, @db, @port, @sock, @flag)
122 | end
123 |
124 | def teardown()
125 | @m.close if @m
126 | end
127 |
128 | def test_affected_rows()
129 | @m.query("create temporary table t (id int)")
130 | @m.query("insert into t values (1)")
131 | assert_equal(1, @m.affected_rows)
132 | end
133 |
134 | def test_autocommit()
135 | if @m.methods.include? "autocommit" then
136 | assert_equal(@m, @m.autocommit(true))
137 | assert_equal(@m, @m.autocommit(false))
138 | end
139 | end
140 |
141 | # def test_ssl_set()
142 | # end
143 |
144 | def test_more_results_next_result()
145 | if @m.server_version >= 40100 then
146 | @m.query_with_result = false
147 | @m.set_server_option(Mysql::OPTION_MULTI_STATEMENTS_ON) if defined? Mysql::OPTION_MULTI_STATEMENTS_ON
148 | @m.query("select 1,2,3; select 4,5,6")
149 | res = @m.store_result
150 | assert_equal(["1","2","3"], res.fetch_row)
151 | assert_equal(nil, res.fetch_row)
152 | assert_equal(true, @m.more_results)
153 | assert_equal(true, @m.more_results?)
154 | assert_equal(true, @m.next_result)
155 | res = @m.store_result
156 | assert_equal(["4","5","6"], res.fetch_row)
157 | assert_equal(nil, res.fetch_row)
158 | assert_equal(false, @m.more_results)
159 | assert_equal(false, @m.more_results?)
160 | assert_equal(false, @m.next_result)
161 | end
162 | end if Mysql.client_version >= 40100
163 |
164 | def test_query_with_block()
165 | if @m.server_version >= 40100 then
166 | @m.set_server_option(Mysql::OPTION_MULTI_STATEMENTS_ON)
167 | expect = [["1","2","3"], ["4","5","6"]]
168 | @m.query("select 1,2,3; select 4,5,6") {|res|
169 | assert_equal(1, res.num_rows)
170 | assert_equal(expect.shift, res.fetch_row)
171 | }
172 | assert(expect.empty?)
173 | expect = [["1","2","3"], ["4","5","6"]]
174 | assert_raises(Mysql::Error) {
175 | @m.query("select 1,2,3; hoge; select 4,5,6") {|res|
176 | assert_equal(1, res.num_rows)
177 | assert_equal(expect.shift, res.fetch_row)
178 | }
179 | }
180 | assert_equal(1, expect.size)
181 | expect = [["1","2","3"], ["4","5","6"]]
182 | assert_raises(Mysql::Error) {
183 | @m.query("select 1,2,3; select 4,5,6; hoge") {|res|
184 | assert_equal(1, res.num_rows)
185 | assert_equal(expect.shift, res.fetch_row)
186 | }
187 | }
188 | assert(expect.empty?)
189 | end
190 | end
191 |
192 | def test_query_with_block_single()
193 | @m.query("select 1,2,3") {|res|
194 | assert_equal(1, res.num_rows)
195 | assert_equal(["1","2","3"], res.fetch_row)
196 | }
197 | end
198 |
199 | def test_set_server_option()
200 | if @m.server_version >= 40101 then
201 | assert_equal(@m, @m.set_server_option(Mysql::OPTION_MULTI_STATEMENTS_ON))
202 | assert_equal(@m, @m.set_server_option(Mysql::OPTION_MULTI_STATEMENTS_OFF))
203 | end
204 | end if Mysql.client_version >= 40101
205 |
206 | def test_sqlstate()
207 | if @m.server_version >= 40100 then
208 | if RUBY_PLATFORM !~ /mingw|mswin/ then
209 | assert_equal("00000", @m.sqlstate)
210 | else
211 | assert_equal("HY000", @m.sqlstate)
212 | end
213 | assert_raises(Mysql::Error){@m.query("hogehoge")}
214 | assert_equal("42000", @m.sqlstate)
215 | end
216 | end
217 |
218 | def test_query_with_result()
219 | assert_equal(true, @m.query_with_result)
220 | assert_equal(false, @m.query_with_result = false)
221 | assert_equal(false, @m.query_with_result)
222 | assert_equal(true, @m.query_with_result = true)
223 | assert_equal(true, @m.query_with_result)
224 | end
225 |
226 | def test_reconnect()
227 | assert_equal(false, @m.reconnect)
228 | assert_equal(true, @m.reconnect = true)
229 | assert_equal(true, @m.reconnect)
230 | assert_equal(false, @m.reconnect = false)
231 | assert_equal(false, @m.reconnect)
232 | end
233 | end
234 |
235 | class TC_MysqlRes < Test::Unit::TestCase
236 | def setup()
237 | @host = CONFIG.host
238 | @user = CONFIG.user
239 | @pass = CONFIG.pass
240 | @db = CONFIG.database
241 |
242 | @port = CONFIG.port.to_i
243 | @sock = CONFIG.sock
244 | @flag = CONFIG.flag.to_i
245 |
246 | @m = Mysql.new(@host, @user, @pass, @db, @port, @sock, @flag)
247 | @m.query("create temporary table t (id int, str char(10), primary key (id))")
248 | @m.query("insert into t values (1, 'abc'), (2, 'defg'), (3, 'hi'), (4, null)")
249 | @res = @m.query("select * from t")
250 | end
251 |
252 | def teardown()
253 | @res.free
254 | @m.close
255 | end
256 |
257 | def test_num_fields()
258 | assert_equal(2, @res.num_fields)
259 | end
260 |
261 | def test_num_rows()
262 | assert_equal(4, @res.num_rows)
263 | end
264 |
265 | def test_fetch_row()
266 | assert_equal(["1","abc"], @res.fetch_row)
267 | assert_equal(["2","defg"], @res.fetch_row)
268 | assert_equal(["3","hi"], @res.fetch_row)
269 | assert_equal(["4",nil], @res.fetch_row)
270 | assert_equal(nil, @res.fetch_row)
271 | end
272 |
273 | def test_fetch_hash()
274 | assert_equal({"id"=>"1", "str"=>"abc"}, @res.fetch_hash)
275 | assert_equal({"id"=>"2", "str"=>"defg"}, @res.fetch_hash)
276 | assert_equal({"id"=>"3", "str"=>"hi"}, @res.fetch_hash)
277 | assert_equal({"id"=>"4", "str"=>nil}, @res.fetch_hash)
278 | assert_equal(nil, @res.fetch_hash)
279 | end
280 |
281 | def test_fetch_hash2()
282 | assert_equal({"t.id"=>"1", "t.str"=>"abc"}, @res.fetch_hash(true))
283 | assert_equal({"t.id"=>"2", "t.str"=>"defg"}, @res.fetch_hash(true))
284 | assert_equal({"t.id"=>"3", "t.str"=>"hi"}, @res.fetch_hash(true))
285 | assert_equal({"t.id"=>"4", "t.str"=>nil}, @res.fetch_hash(true))
286 | assert_equal(nil, @res.fetch_hash)
287 | end
288 |
289 | def test_each()
290 | ary = [["1","abc"], ["2","defg"], ["3","hi"], ["4",nil]]
291 | @res.each do |a|
292 | assert_equal(ary.shift, a)
293 | end
294 | end
295 |
296 | def test_each_hash()
297 | hash = [{"id"=>"1","str"=>"abc"}, {"id"=>"2","str"=>"defg"}, {"id"=>"3","str"=>"hi"}, {"id"=>"4","str"=>nil}]
298 | @res.each_hash do |h|
299 | assert_equal(hash.shift, h)
300 | end
301 | end
302 |
303 | def test_data_seek()
304 | assert_equal(["1","abc"], @res.fetch_row)
305 | assert_equal(["2","defg"], @res.fetch_row)
306 | assert_equal(["3","hi"], @res.fetch_row)
307 | @res.data_seek(1)
308 | assert_equal(["2","defg"], @res.fetch_row)
309 | end
310 |
311 | def test_row_seek()
312 | assert_equal(["1","abc"], @res.fetch_row)
313 | pos = @res.row_tell
314 | assert_equal(["2","defg"], @res.fetch_row)
315 | assert_equal(["3","hi"], @res.fetch_row)
316 | @res.row_seek(pos)
317 | assert_equal(["2","defg"], @res.fetch_row)
318 | end
319 |
320 | def test_field_seek()
321 | assert_equal(0, @res.field_tell)
322 | @res.fetch_field
323 | assert_equal(1, @res.field_tell)
324 | @res.fetch_field
325 | assert_equal(2, @res.field_tell)
326 | @res.field_seek(1)
327 | assert_equal(1, @res.field_tell)
328 | end
329 |
330 | def test_fetch_field()
331 | f = @res.fetch_field
332 | assert_equal("id", f.name)
333 | assert_equal("t", f.table)
334 | assert_equal(nil, f.def)
335 | assert_equal(Mysql::Field::TYPE_LONG, f.type)
336 | assert_equal(11, f.length)
337 | assert_equal(1, f.max_length)
338 | assert_equal(Mysql::Field::NUM_FLAG|Mysql::Field::PRI_KEY_FLAG|Mysql::Field::PART_KEY_FLAG|Mysql::Field::NOT_NULL_FLAG, f.flags)
339 | assert_equal(0, f.decimals)
340 | f = @res.fetch_field
341 | assert_equal("str", f.name)
342 | assert_equal("t", f.table)
343 | assert_equal(nil, f.def)
344 | assert_equal(Mysql::Field::TYPE_STRING, f.type)
345 | assert_equal(30, f.length)
346 | assert_equal(4, f.max_length)
347 | assert_equal(0, f.flags)
348 | assert_equal(0, f.decimals)
349 | f = @res.fetch_field
350 | assert_equal(nil, f)
351 | end
352 |
353 | def test_fetch_fields()
354 | a = @res.fetch_fields
355 | assert_equal(2, a.size)
356 | assert_equal("id", a[0].name)
357 | assert_equal("str", a[1].name)
358 | end
359 |
360 | def test_fetch_field_direct()
361 | f = @res.fetch_field_direct(0)
362 | assert_equal("id", f.name)
363 | f = @res.fetch_field_direct(1)
364 | assert_equal("str", f.name)
365 | assert_raises(Mysql::Error){@res.fetch_field_direct(-1)}
366 | assert_raises(Mysql::Error){@res.fetch_field_direct(2)}
367 | end
368 |
369 | def test_fetch_lengths()
370 | assert_equal(nil, @res.fetch_lengths())
371 | @res.fetch_row
372 | assert_equal([1, 3], @res.fetch_lengths())
373 | @res.fetch_row
374 | assert_equal([1, 4], @res.fetch_lengths())
375 | @res.fetch_row
376 | assert_equal([1, 2], @res.fetch_lengths())
377 | @res.fetch_row
378 | assert_equal([1, 0], @res.fetch_lengths())
379 | @res.fetch_row
380 | assert_equal(nil, @res.fetch_lengths())
381 | end
382 |
383 | def test_field_hash()
384 | f = @res.fetch_field
385 | h = {
386 | "name" => "id",
387 | "table" => "t",
388 | "def" => nil,
389 | "type" => Mysql::Field::TYPE_LONG,
390 | "length" => 11,
391 | "max_length" => 1,
392 | "flags" => Mysql::Field::NUM_FLAG|Mysql::Field::PRI_KEY_FLAG|Mysql::Field::PART_KEY_FLAG|Mysql::Field::NOT_NULL_FLAG,
393 | "decimals" => 0,
394 | }
395 | assert_equal(h, f.hash)
396 | f = @res.fetch_field
397 | h = {
398 | "name" => "str",
399 | "table" => "t",
400 | "def" => nil,
401 | "type" => Mysql::Field::TYPE_STRING,
402 | "length" => 30,
403 | "max_length" => 4,
404 | "flags" => 0,
405 | "decimals" => 0,
406 | }
407 | assert_equal(h, f.hash)
408 | end
409 |
410 | def test_field_inspect()
411 | f = @res.fetch_field
412 | assert_equal("#", f.inspect)
413 | f = @res.fetch_field
414 | assert_equal("#", f.inspect)
415 | end
416 |
417 | def test_is_num()
418 | f = @res.fetch_field
419 | assert_equal(true, f.is_num?)
420 | f = @res.fetch_field
421 | assert_equal(false, f.is_num?)
422 | end
423 |
424 | def test_is_not_null()
425 | f = @res.fetch_field
426 | assert_equal(true, f.is_not_null?)
427 | f = @res.fetch_field
428 | assert_equal(false, f.is_not_null?)
429 | end
430 |
431 | def test_is_pri_key()
432 | f = @res.fetch_field
433 | assert_equal(true, f.is_pri_key?)
434 | f = @res.fetch_field
435 | assert_equal(false, f.is_pri_key?)
436 | end
437 |
438 | end
439 |
440 | class TC_MysqlStmt < Test::Unit::TestCase
441 | def setup()
442 | @host = CONFIG.host
443 | @user = CONFIG.user
444 | @pass = CONFIG.pass
445 | @db = CONFIG.database
446 |
447 | @port = CONFIG.port.to_i
448 | @sock = CONFIG.sock
449 | @flag = CONFIG.flag.to_i
450 |
451 | @m = Mysql.new(@host, @user, @pass, @db, @port, @sock, @flag)
452 | end
453 |
454 | def teardown()
455 | end
456 |
457 | def test_init()
458 | if @m.server_version >= 40100 then
459 | s = @m.stmt_init()
460 | assert_equal(Mysql::Stmt, s.class)
461 | s.close
462 | end
463 | end
464 |
465 | def test_prepare()
466 | if @m.server_version >= 40100 then
467 | s = @m.prepare("select 1")
468 | assert_equal(Mysql::Stmt, s.class)
469 | s.close
470 | end
471 | end
472 |
473 | end if Mysql.client_version >= 40100
474 |
475 | class TC_MysqlStmt2 < Test::Unit::TestCase
476 | def setup()
477 | @host = CONFIG.host
478 | @user = CONFIG.user
479 | @pass = CONFIG.pass
480 | @db = CONFIG.database
481 |
482 | @port = CONFIG.port.to_i
483 | @sock = CONFIG.sock
484 | @flag = CONFIG.flag.to_i
485 |
486 | @m = Mysql.new(@host, @user, @pass, @db, @port, @sock, @flag)
487 | @s = @m.stmt_init()
488 | end
489 |
490 | def teardown()
491 | @s.close
492 | @m.close
493 | end
494 |
495 | def test_affected_rows()
496 | if @m.server_version >= 40100 then
497 | @m.query("create temporary table t (i int, c char(10))")
498 | @s.prepare("insert into t values (?,?)")
499 | @s.execute(1, "hoge")
500 | assert_equal(1, @s.affected_rows())
501 | @s.execute(2, "hoge")
502 | @s.execute(3, "hoge")
503 | @s.prepare("update t set c=?")
504 | @s.execute("fuga")
505 | assert_equal(3, @s.affected_rows())
506 | end
507 | end
508 |
509 | =begin
510 | def test_attr_get()
511 | assert_equal(false, @s.attr_get(Mysql::Stmt::ATTR_UPDATE_MAX_LENGTH))
512 | assert_raises(Mysql::Error){@s.attr_get(999)}
513 | end
514 |
515 | def test_attr_set()
516 | @s.attr_set(Mysql::Stmt::ATTR_UPDATE_MAX_LENGTH, true)
517 | assert_equal(true, @s.attr_get(Mysql::Stmt::ATTR_UPDATE_MAX_LENGTH))
518 | @s.attr_set(Mysql::Stmt::ATTR_UPDATE_MAX_LENGTH, false)
519 | assert_equal(false, @s.attr_get(Mysql::Stmt::ATTR_UPDATE_MAX_LENGTH))
520 | assert_raises(Mysql::Error){@s.attr_set(999, true)}
521 | end
522 |
523 | def test_bind_param()
524 | @s.prepare("insert into t values (?,?)")
525 | @s.bind_param(123, "abc")
526 | @s.bind_param(Time.now, nil)
527 | assert_raises(Mysql::Error){@s.bind_param(1, 2, 3)}
528 | b = @s.bind_param(Bind.new(Mysql::TYPE_TINY, 99, false))
529 | @s.bind_param(98.765, b)
530 | end
531 | =end
532 |
533 | def test_bind_result_nil()
534 | if @m.server_version >= 40100 then
535 | @m.query("create temporary table t (i int, c char(10), d double, t datetime)")
536 | @m.query("insert into t values (123, '9abcdefg', 1.2345, 20050802235011)")
537 | @s.prepare("select * from t")
538 | @s.bind_result(nil,nil,nil,nil)
539 | @s.execute
540 | a = @s.fetch
541 | assert_equal([123, "9abcdefg", 1.2345, Mysql::Time.new(2005,8,2,23,50,11)], a)
542 | end
543 | end
544 |
545 | def test_bind_result_numeric()
546 | if @m.server_version >= 40100 then
547 | @m.query("create temporary table t (i int, c char(10), d double, t datetime)")
548 | @m.query("insert into t values (123, '9abcdefg', 1.2345, 20050802235011)")
549 | @s.prepare("select * from t")
550 | @s.bind_result(Numeric, Numeric, Numeric, Numeric)
551 | @s.execute
552 | a = @s.fetch
553 | if Mysql.client_version < 50000 then
554 | assert_equal([123, 9, 1, 2005], a)
555 | else
556 | assert_equal([123, 9, 1, 20050802235011], a)
557 | end
558 | end
559 | end
560 |
561 | def test_bind_result_integer()
562 | if @m.server_version >= 40100 then
563 | @m.query("create temporary table t (i int, c char(10), d double, t datetime)")
564 | @m.query("insert into t values (123, '9abcdefg', 1.2345, 20050802235011)")
565 | @s.prepare("select * from t")
566 | @s.bind_result(Integer, Integer, Integer, Integer)
567 | @s.execute
568 | a = @s.fetch
569 | if Mysql.client_version < 50000 then
570 | assert_equal([123, 9, 1, 2005], a)
571 | else
572 | assert_equal([123, 9, 1, 20050802235011], a)
573 | end
574 | end
575 | end
576 |
577 | def test_bind_result_fixnum()
578 | if @m.server_version >= 40100 then
579 | @m.query("create temporary table t (i int, c char(10), d double, t datetime)")
580 | @m.query("insert into t values (123, '9abcdefg', 1.2345, 20050802235011)")
581 | @s.prepare("select * from t")
582 | @s.bind_result(Fixnum, Fixnum, Fixnum, Fixnum)
583 | @s.execute
584 | a = @s.fetch
585 | if Mysql.client_version < 50000 then
586 | assert_equal([123, 9, 1, 2005], a)
587 | else
588 | assert_equal([123, 9, 1, 20050802235011.0], a)
589 | end
590 | end
591 | end
592 |
593 | def test_bind_result_string()
594 | if @m.server_version >= 40100 then
595 | @m.query("create temporary table t (i int, c char(10), d double, t datetime)")
596 | @m.query("insert into t values (123, '9abcdefg', 1.2345, 20050802235011)")
597 | @s.prepare("select * from t")
598 | @s.bind_result(String, String, String, String)
599 | @s.execute
600 | a = @s.fetch
601 | assert_equal(["123", "9abcdefg", "1.2345", "2005-08-02 23:50:11"], a)
602 | end
603 | end
604 |
605 | def test_bind_result_float()
606 | if @m.server_version >= 40100 then
607 | @m.query("create temporary table t (i int, c char(10), d double, t datetime)")
608 | @m.query("insert into t values (123, '9abcdefg', 1.2345, 20050802235011)")
609 | @s.prepare("select * from t")
610 | @s.bind_result(Float, Float, Float, Float)
611 | @s.execute
612 | a = @s.fetch
613 | if Mysql.client_version < 50000 then
614 | assert_equal([123.0, 9.0, 1.2345, 2005.0], a)
615 | else
616 | assert_equal([123.0, 9.0, 1.2345, 20050802235011.0], a)
617 | end
618 | end
619 | end
620 |
621 | def test_bind_result_mysqltime()
622 | if @m.server_version >= 40100 then
623 | @m.query("create temporary table t (i int, c char(10), d double, t datetime)")
624 | @m.query("insert into t values (123, '9abcdefg', 1.2345, 20050802235011)")
625 | @s.prepare("select * from t")
626 | @s.bind_result(Mysql::Time, Mysql::Time, Mysql::Time, Mysql::Time)
627 | @s.execute
628 | a = @s.fetch
629 | if Mysql.client_version < 50000 then
630 | assert_equal([Mysql::Time.new, Mysql::Time.new, Mysql::Time.new, Mysql::Time.new(2005,8,2,23,50,11)], a)
631 | else
632 | assert_equal([Mysql::Time.new(2000,1,23), Mysql::Time.new, Mysql::Time.new, Mysql::Time.new(2005,8,2,23,50,11)], a)
633 | end
634 | end
635 | end
636 |
637 | def test_bind_result_unknown()
638 | if @m.server_version >= 40100 then
639 | @m.query("create temporary table t (i int, c char(10), d double, t datetime)")
640 | @m.query("insert into t values (123, '9abcdefg', 1.2345, 20050802235011)")
641 | @s.prepare("select * from t")
642 | assert_raises(TypeError){@s.bind_result(Time, nil, nil, nil)}
643 | end
644 | end
645 |
646 | def test_bind_result_unmatch_count()
647 | if @m.server_version >= 40100 then
648 | @m.query("create temporary table t (i int, c char(10), d double, t datetime)")
649 | @m.query("insert into t values (123, '9abcdefg', 1.2345, 20050802235011)")
650 | @s.prepare("select * from t")
651 | assert_raises(Mysql::Error){@s.bind_result(nil, nil)}
652 | end
653 | end
654 |
655 | def test_data_seek()
656 | if @m.server_version >= 40100 then
657 | @m.query("create temporary table t (i int)")
658 | @m.query("insert into t values (0),(1),(2),(3),(4),(5)")
659 | @s.prepare("select i from t")
660 | @s.execute
661 | assert_equal([0], @s.fetch)
662 | assert_equal([1], @s.fetch)
663 | assert_equal([2], @s.fetch)
664 | @s.data_seek(5)
665 | assert_equal([5], @s.fetch)
666 | @s.data_seek(1)
667 | assert_equal([1], @s.fetch)
668 | end
669 | end
670 |
671 | =begin
672 | def test_errno()
673 | @s.errno()
674 | end
675 |
676 | def test_error()
677 | @s.error()
678 | end
679 | =end
680 |
681 | def test_execute()
682 | if @m.server_version >= 40100 then
683 | @m.query("create temporary table t (i int)")
684 | @s.prepare("insert into t values (123)")
685 | @s.execute()
686 | assert_equal(1, @s.affected_rows)
687 | @s.execute()
688 | assert_equal(1, @s.affected_rows)
689 | assert_equal(2, @m.query("select count(*) from t").fetch_row[0].to_i)
690 | end
691 | end
692 |
693 | def test_execute2()
694 | if @m.server_version >= 40100 then
695 | @m.query("create temporary table t (i int)")
696 | @s.prepare("insert into t values (?)")
697 | @s.execute(123)
698 | @s.execute("456")
699 | @s.prepare("select * from t")
700 | @s.execute
701 | assert_equal([123], @s.fetch)
702 | assert_equal([456], @s.fetch)
703 | end
704 | end
705 |
706 | def test_execute3()
707 | if @m.server_version >= 40100 then
708 | @m.query("create temporary table t (i int, c char(255), t timestamp)")
709 | @s.prepare("insert into t values (?,?,?)")
710 | @s.execute(123, "hoge", Time.local(2005,7,19,23,53,0));
711 | assert_raises(Mysql::Error){@s.execute(123, "hoge")}
712 | assert_raises(Mysql::Error){@s.execute(123, "hoge", 0, "fuga")}
713 | @s.prepare("select * from t")
714 | @s.execute
715 | assert_equal([123, "hoge", Mysql::Time.new(2005,7,19,23,53,0)], @s.fetch)
716 | end
717 | end
718 |
719 | def test_execute4()
720 | if @m.server_version >= 40100 then
721 | @m.query("create temporary table t (i int, c char(255), t timestamp)")
722 | @s.prepare("insert into t values (?,?,?)")
723 | @s.execute(nil, "hoge", Mysql::Time.new(2005,7,19,23,53,0));
724 | @s.prepare("select * from t")
725 | @s.execute
726 | assert_equal([nil, "hoge", Mysql::Time.new(2005,7,19,23,53,0)], @s.fetch)
727 | end
728 | end
729 |
730 | def test_execute5()
731 | if @m.server_version >= 40100 then
732 | [30, 31, 32, 62, 63].each do |i|
733 | v, = @m.prepare("select cast(? as signed)").execute(2**i-1).fetch
734 | assert_equal(2**i-1, v)
735 | v, = @m.prepare("select cast(? as signed)").execute(-(2**i)).fetch
736 | assert_equal(-(2**i), v)
737 | end
738 | end
739 | end
740 |
741 | def test_fetch()
742 | if @m.server_version >= 40100 then
743 | @s.prepare("select 123, 'abc', null")
744 | @s.execute()
745 | assert_equal([123, "abc", nil], @s.fetch())
746 | end
747 | end
748 |
749 | def test_fetch_bit()
750 | if @m.client_version >= 50003 and @m.server_version >= 50003 then
751 | @m.query("create temporary table t (i bit(8))")
752 | @m.query("insert into t values (0),(-1),(127),(-128),(255),(-255),(256)")
753 | @s.prepare("select i from t")
754 | @s.execute
755 | assert_equal(["\x00"], @s.fetch)
756 | assert_equal(["\xff"], @s.fetch)
757 | assert_equal(["\x7f"], @s.fetch)
758 | assert_equal(["\xff"], @s.fetch)
759 | assert_equal(["\xff"], @s.fetch)
760 | assert_equal(["\xff"], @s.fetch)
761 | assert_equal(["\xff"], @s.fetch)
762 | @m.query("create temporary table t2 (i bit(64))")
763 | @m.query("insert into t2 values (0),(-1),(4294967296),(18446744073709551615),(18446744073709551616)")
764 | @s.prepare("select i from t2")
765 | @s.execute
766 | assert_equal(["\x00\x00\x00\x00\x00\x00\x00\x00"], @s.fetch)
767 | assert_equal(["\xff\xff\xff\xff\xff\xff\xff\xff"], @s.fetch)
768 | assert_equal(["\x00\x00\x00\x01\x00\x00\x00\x00"], @s.fetch)
769 | assert_equal(["\xff\xff\xff\xff\xff\xff\xff\xff"], @s.fetch)
770 | assert_equal(["\xff\xff\xff\xff\xff\xff\xff\xff"], @s.fetch)
771 | end
772 | end
773 |
774 | def test_fetch_tinyint()
775 | if @m.server_version >= 40100 then
776 | @m.query("create temporary table t (i tinyint)")
777 | @m.query("insert into t values (0),(-1),(127),(-128),(255),(-255)")
778 | @s.prepare("select i from t")
779 | @s.execute
780 | assert_equal([0], @s.fetch)
781 | assert_equal([-1], @s.fetch)
782 | assert_equal([127], @s.fetch)
783 | assert_equal([-128], @s.fetch)
784 | assert_equal([127], @s.fetch)
785 | assert_equal([-128], @s.fetch)
786 | end
787 | end
788 |
789 | def test_fetch_tinyint_unsigned()
790 | if @m.server_version >= 40100 then
791 | @m.query("create temporary table t (i tinyint unsigned)")
792 | @m.query("insert into t values (0),(-1),(127),(-128),(255),(-255),(256)")
793 | @s.prepare("select i from t")
794 | @s.execute
795 | assert_equal([0], @s.fetch)
796 | assert_equal([0], @s.fetch)
797 | assert_equal([127], @s.fetch)
798 | assert_equal([0], @s.fetch)
799 | assert_equal([255], @s.fetch)
800 | assert_equal([0], @s.fetch)
801 | assert_equal([255], @s.fetch)
802 | end
803 | end
804 |
805 | def test_fetch_smallint()
806 | if @m.server_version >= 40100 then
807 | @m.query("create temporary table t (i smallint)")
808 | @m.query("insert into t values (0),(-1),(32767),(-32768),(65535),(-65535),(65536)")
809 | @s.prepare("select i from t")
810 | @s.execute
811 | assert_equal([0], @s.fetch)
812 | assert_equal([-1], @s.fetch)
813 | assert_equal([32767], @s.fetch)
814 | assert_equal([-32768], @s.fetch)
815 | assert_equal([32767], @s.fetch)
816 | assert_equal([-32768], @s.fetch)
817 | end
818 | end
819 |
820 | def test_fetch_smallint_unsigned()
821 | if @m.server_version >= 40100 then
822 | @m.query("create temporary table t (i smallint unsigned)")
823 | @m.query("insert into t values (0),(-1),(32767),(-32768),(65535),(-65535),(65536)")
824 | @s.prepare("select i from t")
825 | @s.execute
826 | assert_equal([0], @s.fetch)
827 | assert_equal([0], @s.fetch)
828 | assert_equal([32767], @s.fetch)
829 | assert_equal([0], @s.fetch)
830 | assert_equal([65535], @s.fetch)
831 | assert_equal([0], @s.fetch)
832 | assert_equal([65535], @s.fetch)
833 | end
834 | end
835 |
836 | def test_fetch_mediumint()
837 | if @m.server_version >= 40100 then
838 | @m.query("create temporary table t (i mediumint)")
839 | @m.query("insert into t values (0),(-1),(8388607),(-8388608),(16777215),(-16777215),(16777216)")
840 | @s.prepare("select i from t")
841 | @s.execute
842 | assert_equal([0], @s.fetch)
843 | assert_equal([-1], @s.fetch)
844 | assert_equal([8388607], @s.fetch)
845 | assert_equal([-8388608], @s.fetch)
846 | assert_equal([8388607], @s.fetch)
847 | assert_equal([-8388608], @s.fetch)
848 | end
849 | end
850 |
851 | def test_fetch_mediumint_unsigned()
852 | if @m.server_version >= 40100 then
853 | @m.query("create temporary table t (i mediumint unsigned)")
854 | @m.query("insert into t values (0),(-1),(8388607),(-8388608),(16777215),(-16777215),(16777216)")
855 | @s.prepare("select i from t")
856 | @s.execute
857 | assert_equal([0], @s.fetch)
858 | assert_equal([0], @s.fetch)
859 | assert_equal([8388607], @s.fetch)
860 | assert_equal([0], @s.fetch)
861 | assert_equal([16777215], @s.fetch)
862 | assert_equal([0], @s.fetch)
863 | assert_equal([16777215], @s.fetch)
864 | end
865 | end
866 |
867 | def test_fetch_int()
868 | if @m.server_version >= 40100 then
869 | @m.query("create temporary table t (i int)")
870 | @m.query("insert into t values (0),(-1),(2147483647),(-2147483648),(4294967295),(-4294967295),(4294967296)")
871 | @s.prepare("select i from t")
872 | @s.execute
873 | assert_equal([0], @s.fetch)
874 | assert_equal([-1], @s.fetch)
875 | assert_equal([2147483647], @s.fetch)
876 | assert_equal([-2147483648], @s.fetch)
877 | assert_equal([2147483647], @s.fetch)
878 | assert_equal([-2147483648], @s.fetch)
879 | end
880 | end
881 |
882 | def test_fetch_int_unsigned()
883 | if @m.server_version >= 40100 then
884 | @m.query("create temporary table t (i int unsigned)")
885 | @m.query("insert into t values (0),(-1),(2147483647),(-2147483648),(4294967295),(-4294967295),(4294967296)")
886 | @s.prepare("select i from t")
887 | @s.execute
888 | assert_equal([0], @s.fetch)
889 | assert_equal([0], @s.fetch)
890 | assert_equal([2147483647], @s.fetch)
891 | assert_equal([0], @s.fetch)
892 | assert_equal([4294967295], @s.fetch)
893 | assert_equal([0], @s.fetch)
894 | assert_equal([4294967295], @s.fetch)
895 | end
896 | end
897 |
898 | def test_fetch_bigint()
899 | if @m.server_version >= 40100 then
900 | @m.query("create temporary table t (i bigint)")
901 | @m.query("insert into t values (0),(-1),(9223372036854775807),(-9223372036854775808),(18446744073709551615),(-18446744073709551615),(18446744073709551616)")
902 | @s.prepare("select i from t")
903 | @s.execute
904 | assert_equal([0], @s.fetch)
905 | assert_equal([-1], @s.fetch)
906 | assert_equal([9223372036854775807], @s.fetch)
907 | assert_equal([-9223372036854775808], @s.fetch)
908 | if @m.server_version >= 50000 then
909 | assert_equal([9223372036854775807], @s.fetch)
910 | else
911 | assert_equal([-1], @s.fetch) # MySQL problem
912 | end
913 | assert_equal([-9223372036854775808], @s.fetch)
914 | assert_equal([9223372036854775807], @s.fetch)
915 | end
916 | end
917 |
918 | def test_fetch_bigint_unsigned()
919 | if @m.server_version >= 40100 then
920 | @m.query("create temporary table t (i bigint unsigned)")
921 | @m.query("insert into t values (0),(-1),(9223372036854775807),(-9223372036854775808),(18446744073709551615),(-18446744073709551615),(18446744073709551616)")
922 | @s.prepare("select i from t")
923 | @s.execute
924 | assert_equal([0], @s.fetch)
925 | if @m.server_version >= 50000 then
926 | assert_equal([0], @s.fetch)
927 | else
928 | assert_equal([18446744073709551615], @s.fetch) # MySQL problem
929 | end
930 | assert_equal([9223372036854775807], @s.fetch)
931 | if @m.server_version >= 50000 then
932 | assert_equal([0], @s.fetch)
933 | else
934 | assert_equal([9223372036854775808], @s.fetch) # MySQL problem
935 | end
936 | assert_equal([18446744073709551615], @s.fetch)
937 | assert_equal([0], @s.fetch)
938 | assert_equal([18446744073709551615], @s.fetch)
939 | end
940 | end
941 |
942 | def test_fetch_float()
943 | if @m.server_version >= 40100 then
944 | @m.query("create temporary table t (i float)")
945 | @m.query("insert into t values (0),(-3.402823466E+38),(-1.175494351E-38),(1.175494351E-38),(3.402823466E+38)")
946 | @s.prepare("select i from t")
947 | @s.execute
948 | assert_equal([0], @s.fetch)
949 | assert_in_delta(-3.402823466E+38, @s.fetch[0], 0.000000001E+38)
950 | assert_in_delta(-1.175494351E-38, @s.fetch[0], 0.000000001E-38)
951 | assert_in_delta(1.175494351E-38, @s.fetch[0], 0.000000001E-38)
952 | assert_in_delta(3.402823466E+38, @s.fetch[0], 0.000000001E+38)
953 | end
954 | end
955 |
956 | def test_fetch_float_unsigned()
957 | if @m.server_version >= 40100 then
958 | @m.query("create temporary table t (i float unsigned)")
959 | @m.query("insert into t values (0),(-3.402823466E+38),(-1.175494351E-38),(1.175494351E-38),(3.402823466E+38)")
960 | @s.prepare("select i from t")
961 | @s.execute
962 | assert_equal([0], @s.fetch)
963 | assert_equal([0], @s.fetch)
964 | assert_equal([0], @s.fetch)
965 | assert_in_delta(1.175494351E-38, @s.fetch[0], 0.000000001E-38)
966 | assert_in_delta(3.402823466E+38, @s.fetch[0], 0.000000001E+38)
967 | end
968 | end
969 |
970 | def test_fetch_double()
971 | if @m.server_version >= 40100 then
972 | @m.query("create temporary table t (i double)")
973 | @m.query("insert into t values (0),(-1.7976931348623157E+308),(-2.2250738585072014E-308),(2.2250738585072014E-308),(1.7976931348623157E+308)")
974 | @s.prepare("select i from t")
975 | @s.execute
976 | assert_equal([0], @s.fetch)
977 | assert_in_delta(-Float::MAX, @s.fetch[0], Float::EPSILON)
978 | assert_in_delta(-Float::MIN, @s.fetch[0], Float::EPSILON)
979 | assert_in_delta(Float::MIN, @s.fetch[0], Float::EPSILON)
980 | assert_in_delta(Float::MAX, @s.fetch[0], Float::EPSILON)
981 | end
982 | end
983 |
984 | def test_fetch_double_unsigned()
985 | if @m.server_version >= 40100 then
986 | @m.query("create temporary table t (i double unsigned)")
987 | @m.query("insert into t values (0),(-1.7976931348623157E+308),(-2.2250738585072014E-308),(2.2250738585072014E-308),(1.7976931348623157E+308)")
988 | @s.prepare("select i from t")
989 | @s.execute
990 | assert_equal([0], @s.fetch)
991 | assert_equal([0], @s.fetch)
992 | assert_equal([0], @s.fetch)
993 | assert_in_delta(Float::MIN, @s.fetch[0], Float::EPSILON)
994 | assert_in_delta(Float::MAX, @s.fetch[0], Float::EPSILON)
995 | end
996 | end
997 |
998 | def test_fetch_decimal()
999 | if (@m.server_version >= 50000 and Mysql.client_version >= 50000) or (@m.server_version >= 40100 and @m.server_version < 50000) then
1000 | @m.query("create temporary table t (i decimal)")
1001 | @m.query("insert into t values (0),(9999999999),(-9999999999),(10000000000),(-10000000000)")
1002 | @s.prepare("select i from t")
1003 | @s.execute
1004 | assert_equal(["0"], @s.fetch)
1005 | assert_equal(["9999999999"], @s.fetch)
1006 | assert_equal(["-9999999999"], @s.fetch)
1007 | if @m.server_version < 50000 then
1008 | assert_equal(["10000000000"], @s.fetch) # MySQL problem
1009 | else
1010 | assert_equal(["9999999999"], @s.fetch)
1011 | end
1012 | assert_equal(["-9999999999"], @s.fetch)
1013 | end
1014 | end
1015 |
1016 | def test_fetch_decimal_unsigned()
1017 | if (@m.server_version >= 50000 and Mysql.client_version >= 50000) or (@m.server_version >= 40100 and @m.server_version < 50000) then
1018 | @m.query("create temporary table t (i decimal unsigned)")
1019 | @m.query("insert into t values (0),(9999999998),(9999999999),(-9999999998),(-9999999999),(10000000000),(-10000000000)")
1020 | @s.prepare("select i from t")
1021 | @s.execute
1022 | assert_equal(["0"], @s.fetch)
1023 | assert_equal(["9999999998"], @s.fetch)
1024 | assert_equal(["9999999999"], @s.fetch)
1025 | assert_equal(["0"], @s.fetch)
1026 | assert_equal(["0"], @s.fetch)
1027 | assert_equal(["9999999999"], @s.fetch)
1028 | assert_equal(["0"], @s.fetch)
1029 | end
1030 | end
1031 |
1032 | def test_fetch_date()
1033 | if @m.server_version >= 40100 then
1034 | @m.query("create temporary table t (i date)")
1035 | @m.query("insert into t values ('0000-00-00'),('1000-01-01'),('9999-12-31')")
1036 | @s.prepare("select i from t")
1037 | @s.execute
1038 | assert_equal([Mysql::Time.new(0,0,0)], @s.fetch)
1039 | assert_equal([Mysql::Time.new(1000,1,1)], @s.fetch)
1040 | assert_equal([Mysql::Time.new(9999,12,31)], @s.fetch)
1041 | end
1042 | end
1043 |
1044 | def test_fetch_datetime()
1045 | if @m.server_version >= 40100 then
1046 | @m.query("create temporary table t (i datetime)")
1047 | @m.query("insert into t values ('0000-00-00 00:00:00'),('1000-01-01 00:00:00'),('9999-12-31 23:59:59')")
1048 | @s.prepare("select i from t")
1049 | @s.execute
1050 | assert_equal([Mysql::Time.new(0,0,0,0,0,0)], @s.fetch)
1051 | assert_equal([Mysql::Time.new(1000,1,1,0,0,0)], @s.fetch)
1052 | assert_equal([Mysql::Time.new(9999,12,31,23,59,59)], @s.fetch)
1053 | end
1054 | end
1055 |
1056 | def test_fetch_timestamp()
1057 | if @m.server_version >= 40100 then
1058 | @m.query("create temporary table t (i timestamp)")
1059 | @m.query("insert into t values ('1970-01-02 00:00:00'),('2037-12-30 23:59:59')")
1060 | @s.prepare("select i from t")
1061 | @s.execute
1062 | assert_equal([Mysql::Time.new(1970,1,2,0,0,0)], @s.fetch)
1063 | assert_equal([Mysql::Time.new(2037,12,30,23,59,59)], @s.fetch)
1064 | end
1065 | end
1066 |
1067 | def test_fetch_time()
1068 | if @m.server_version >= 40100 then
1069 | @m.query("create temporary table t (i time)")
1070 | @m.query("insert into t values ('-838:59:59'),(0),('838:59:59')")
1071 | @s.prepare("select i from t")
1072 | @s.execute
1073 | assert_equal([Mysql::Time.new(0,0,0,838,59,59,true)], @s.fetch)
1074 | assert_equal([Mysql::Time.new(0,0,0,0,0,0,false)], @s.fetch)
1075 | assert_equal([Mysql::Time.new(0,0,0,838,59,59,false)], @s.fetch)
1076 | end
1077 | end
1078 |
1079 | def test_fetch_year()
1080 | if @m.server_version >= 40100 then
1081 | @m.query("create temporary table t (i year)")
1082 | @m.query("insert into t values (0),(70),(69),(1901),(2155)")
1083 | @s.prepare("select i from t")
1084 | @s.execute
1085 | assert_equal([0], @s.fetch)
1086 | assert_equal([1970], @s.fetch)
1087 | assert_equal([2069], @s.fetch)
1088 | assert_equal([1901], @s.fetch)
1089 | assert_equal([2155], @s.fetch)
1090 | end
1091 | end
1092 |
1093 | def test_fetch_char()
1094 | if @m.server_version >= 40100 then
1095 | @m.query("create temporary table t (i char(10))")
1096 | @m.query("insert into t values (null),('abc')")
1097 | @s.prepare("select i from t")
1098 | @s.execute
1099 | assert_equal([nil], @s.fetch)
1100 | assert_equal(["abc"], @s.fetch)
1101 | end
1102 | end
1103 |
1104 | def test_fetch_varchar()
1105 | if @m.server_version >= 40100 then
1106 | @m.query("create temporary table t (i varchar(10))")
1107 | @m.query("insert into t values (null),('abc')")
1108 | @s.prepare("select i from t")
1109 | @s.execute
1110 | assert_equal([nil], @s.fetch)
1111 | assert_equal(["abc"], @s.fetch)
1112 | end
1113 | end
1114 |
1115 | def test_fetch_binary()
1116 | if @m.server_version >= 40100 then
1117 | @m.query("create temporary table t (i binary(10))")
1118 | @m.query("insert into t values (null),('abc')")
1119 | @s.prepare("select i from t")
1120 | @s.execute
1121 | assert_equal([nil], @s.fetch)
1122 | if @m.server_version >= 50000 then
1123 | assert_equal(["abc\0\0\0\0\0\0\0"], @s.fetch)
1124 | else
1125 | assert_equal(["abc"], @s.fetch)
1126 | end
1127 | end
1128 | end
1129 |
1130 | def test_fetch_varbinary()
1131 | if @m.server_version >= 40100 then
1132 | @m.query("create temporary table t (i varbinary(10))")
1133 | @m.query("insert into t values (null),('abc')")
1134 | @s.prepare("select i from t")
1135 | @s.execute
1136 | assert_equal([nil], @s.fetch)
1137 | assert_equal(["abc"], @s.fetch)
1138 | end
1139 | end
1140 |
1141 | def test_fetch_tinyblob()
1142 | if @m.server_version >= 40100 then
1143 | @m.query("create temporary table t (i tinyblob)")
1144 | @m.query("insert into t values (null),('abc')")
1145 | @s.prepare("select i from t")
1146 | @s.execute
1147 | assert_equal([nil], @s.fetch)
1148 | assert_equal(["abc"], @s.fetch)
1149 | end
1150 | end
1151 |
1152 | def test_fetch_tinytext()
1153 | if @m.server_version >= 40100 then
1154 | @m.query("create temporary table t (i tinytext)")
1155 | @m.query("insert into t values (null),('abc')")
1156 | @s.prepare("select i from t")
1157 | @s.execute
1158 | assert_equal([nil], @s.fetch)
1159 | assert_equal(["abc"], @s.fetch)
1160 | end
1161 | end
1162 |
1163 | def test_fetch_blob()
1164 | if @m.server_version >= 40100 then
1165 | @m.query("create temporary table t (i blob)")
1166 | @m.query("insert into t values (null),('abc')")
1167 | @s.prepare("select i from t")
1168 | @s.execute
1169 | assert_equal([nil], @s.fetch)
1170 | assert_equal(["abc"], @s.fetch)
1171 | end
1172 | end
1173 |
1174 | def test_fetch_text()
1175 | if @m.server_version >= 40100 then
1176 | @m.query("create temporary table t (i text)")
1177 | @m.query("insert into t values (null),('abc')")
1178 | @s.prepare("select i from t")
1179 | @s.execute
1180 | assert_equal([nil], @s.fetch)
1181 | assert_equal(["abc"], @s.fetch)
1182 | end
1183 | end
1184 |
1185 | def test_fetch_mediumblob()
1186 | if @m.server_version >= 40100 then
1187 | @m.query("create temporary table t (i mediumblob)")
1188 | @m.query("insert into t values (null),('abc')")
1189 | @s.prepare("select i from t")
1190 | @s.execute
1191 | assert_equal([nil], @s.fetch)
1192 | assert_equal(["abc"], @s.fetch)
1193 | end
1194 | end
1195 |
1196 | def test_fetch_mediumtext()
1197 | if @m.server_version >= 40100 then
1198 | @m.query("create temporary table t (i mediumtext)")
1199 | @m.query("insert into t values (null),('abc')")
1200 | @s.prepare("select i from t")
1201 | @s.execute
1202 | assert_equal([nil], @s.fetch)
1203 | assert_equal(["abc"], @s.fetch)
1204 | end
1205 | end
1206 |
1207 | def test_fetch_longblob()
1208 | if @m.server_version >= 40100 then
1209 | @m.query("create temporary table t (i longblob)")
1210 | @m.query("insert into t values (null),('abc')")
1211 | @s.prepare("select i from t")
1212 | @s.execute
1213 | assert_equal([nil], @s.fetch)
1214 | assert_equal(["abc"], @s.fetch)
1215 | end
1216 | end
1217 |
1218 | def test_fetch_longtext()
1219 | if @m.server_version >= 40100 then
1220 | @m.query("create temporary table t (i longtext)")
1221 | @m.query("insert into t values (null),('abc')")
1222 | @s.prepare("select i from t")
1223 | @s.execute
1224 | assert_equal([nil], @s.fetch)
1225 | assert_equal(["abc"], @s.fetch)
1226 | end
1227 | end
1228 |
1229 | def test_fetch_enum()
1230 | if @m.server_version >= 40100 then
1231 | @m.query("create temporary table t (i enum('abc','def'))")
1232 | @m.query("insert into t values (null),(0),(1),(2),('abc'),('def'),('ghi')")
1233 | @s.prepare("select i from t")
1234 | @s.execute
1235 | assert_equal([nil], @s.fetch)
1236 | assert_equal([""], @s.fetch)
1237 | assert_equal(["abc"], @s.fetch)
1238 | assert_equal(["def"], @s.fetch)
1239 | assert_equal(["abc"], @s.fetch)
1240 | assert_equal(["def"], @s.fetch)
1241 | assert_equal([""], @s.fetch)
1242 | end
1243 | end
1244 |
1245 | def test_fetch_set()
1246 | if @m.server_version >= 40100 then
1247 | @m.query("create temporary table t (i set('abc','def'))")
1248 | @m.query("insert into t values (null),(0),(1),(2),(3),('abc'),('def'),('abc,def'),('ghi')")
1249 | @s.prepare("select i from t")
1250 | @s.execute
1251 | assert_equal([nil], @s.fetch)
1252 | assert_equal([""], @s.fetch)
1253 | assert_equal(["abc"], @s.fetch)
1254 | assert_equal(["def"], @s.fetch)
1255 | assert_equal(["abc,def"], @s.fetch)
1256 | assert_equal(["abc"], @s.fetch)
1257 | assert_equal(["def"], @s.fetch)
1258 | assert_equal(["abc,def"], @s.fetch)
1259 | assert_equal([""], @s.fetch)
1260 | end
1261 | end
1262 |
1263 | def test_each()
1264 | if @m.server_version >= 40100 then
1265 | @m.query("create temporary table t (i int, c char(255), d datetime)")
1266 | @m.query("insert into t values (1,'abc','19701224235905'),(2,'def','21120903123456'),(3,'123',null)")
1267 | @s.prepare("select * from t")
1268 | @s.execute
1269 | c = 0
1270 | @s.each do |a|
1271 | case c
1272 | when 0
1273 | assert_equal([1,"abc",Mysql::Time.new(1970,12,24,23,59,05)], a)
1274 | when 1
1275 | assert_equal([2,"def",Mysql::Time.new(2112,9,3,12,34,56)], a)
1276 | when 2
1277 | assert_equal([3,"123",nil], a)
1278 | else
1279 | raise
1280 | end
1281 | c += 1
1282 | end
1283 | end
1284 | end
1285 |
1286 | def test_field_count()
1287 | if @m.server_version >= 40100 then
1288 | @s.prepare("select 1,2,3")
1289 | @s.execute()
1290 | assert_equal(3, @s.field_count())
1291 | @s.prepare("set @a=1")
1292 | @s.execute()
1293 | assert_equal(0, @s.field_count())
1294 | end
1295 | end
1296 |
1297 | def test_free_result()
1298 | if @m.server_version >= 40100 then
1299 | @s.free_result()
1300 | @s.prepare("select 1,2,3")
1301 | @s.execute()
1302 | @s.free_result()
1303 | end
1304 | end
1305 |
1306 | def test_insert_id()
1307 | if @m.server_version >= 40100 then
1308 | @m.query("create temporary table t (i bigint auto_increment, unique(i))")
1309 | @s.prepare("insert into t values (?)")
1310 | @s.execute(0)
1311 | assert_equal(1, @s.insert_id())
1312 | @s.execute(0)
1313 | assert_equal(2, @s.insert_id())
1314 | @s.execute(2**32)
1315 | assert_equal(2**32, @s.insert_id())
1316 | @s.execute(0)
1317 | assert_equal(2**32+1, @s.insert_id())
1318 | end
1319 | end
1320 |
1321 | def test_num_rows()
1322 | if @m.server_version >= 40100 then
1323 | @m.query("create temporary table t (i int)")
1324 | @m.query("insert into t values (1),(2),(3),(4)")
1325 | @s.prepare("select * from t")
1326 | @s.execute
1327 | assert_equal(4, @s.num_rows())
1328 | end
1329 | end
1330 |
1331 | def test_param_count()
1332 | if @m.server_version >= 40100 then
1333 | @m.query("create temporary table t (a int, b int, c int)")
1334 | @s.prepare("select * from t")
1335 | assert_equal(0, @s.param_count())
1336 | @s.prepare("insert into t values (?,?,?)")
1337 | assert_equal(3, @s.param_count())
1338 | end
1339 | end
1340 |
1341 | =begin
1342 | def test_param_metadata()
1343 | @s.param_metadata()
1344 | end
1345 | =end
1346 |
1347 | def test_prepare()
1348 | if @m.server_version >= 40100 then
1349 | @s.prepare("select 1")
1350 | assert_raises(Mysql::Error){@s.prepare("invalid syntax")}
1351 | end
1352 | end
1353 |
1354 | =begin
1355 | def test_reset()
1356 | @s.reset()
1357 | end
1358 | =end
1359 |
1360 | def test_result_metadata()
1361 | if @m.server_version >= 40100 then
1362 | @s.prepare("select 1 foo, 2 bar")
1363 | res = @s.result_metadata()
1364 | f = res.fetch_fields
1365 | assert_equal("foo", f[0].name)
1366 | assert_equal("bar", f[1].name)
1367 | end
1368 | end
1369 |
1370 | def test_result_metadata_nodata()
1371 | if @m.server_version >= 40100 then
1372 | @m.query("create temporary table t (i int)")
1373 | @s.prepare("insert into t values (1)")
1374 | assert_equal(nil, @s.result_metadata())
1375 | end
1376 | end
1377 |
1378 | def test_row_seek_tell()
1379 | if @m.server_version >= 40100 then
1380 | @m.query("create temporary table t (i int)")
1381 | @m.query("insert into t values (0),(1),(2),(3),(4)")
1382 | @s.prepare("select * from t")
1383 | @s.execute
1384 | row0 = @s.row_tell
1385 | assert_equal([0], @s.fetch)
1386 | assert_equal([1], @s.fetch)
1387 | row2 = @s.row_seek(row0)
1388 | assert_equal([0], @s.fetch)
1389 | @s.row_seek(row2)
1390 | assert_equal([2], @s.fetch)
1391 | end
1392 | end
1393 |
1394 | =begin
1395 | def test_send_long_data()
1396 | @m.query("create temporary table t (i int, t text)")
1397 | @s.prepare("insert into t values (?,?)")
1398 | @s.send_long_data(1, "long long data ")
1399 | @s.send_long_data(1, "long long data2")
1400 | assert_raises(Mysql::Error){@s.send_long_data(9, "invalid param number")}
1401 | @s.execute(99, "hoge")
1402 | assert_equal("long long data long long data2", @m.query("select t from t").fetch_row[0])
1403 | end
1404 | =end
1405 |
1406 | def test_sqlstate()
1407 | if @m.server_version >= 40100 then
1408 | @s.prepare("select 1")
1409 | if @m.client_version >= 50000 then
1410 | assert_equal("00000", @s.sqlstate)
1411 | else
1412 | assert_equal("", @s.sqlstate)
1413 | end
1414 | assert_raises(Mysql::Error){@s.prepare("hogehoge")}
1415 | assert_equal("42000", @s.sqlstate)
1416 | end
1417 | end
1418 |
1419 | =begin
1420 | def test_store_result()
1421 | @s.store_result()
1422 | end
1423 | =end
1424 |
1425 | end if Mysql.client_version >= 40100
1426 |
1427 | class TC_MysqlTime < Test::Unit::TestCase
1428 | def setup()
1429 | end
1430 | def teardown()
1431 | end
1432 |
1433 | def test_init()
1434 | t = Mysql::Time.new
1435 | assert_equal(0, t.year);
1436 | assert_equal(0, t.month);
1437 | assert_equal(0, t.day);
1438 | assert_equal(0, t.hour);
1439 | assert_equal(0, t.minute);
1440 | assert_equal(0, t.second);
1441 | assert_equal(false, t.neg);
1442 | assert_equal(0, t.second_part);
1443 | end
1444 |
1445 | def test_year()
1446 | t = Mysql::Time.new
1447 | assert_equal(2005, t.year = 2005)
1448 | assert_equal(2005, t.year)
1449 | end
1450 |
1451 | def test_month()
1452 | t = Mysql::Time.new
1453 | assert_equal(11, t.month = 11)
1454 | assert_equal(11, t.month)
1455 | end
1456 |
1457 | def test_day()
1458 | t = Mysql::Time.new
1459 | assert_equal(23, t.day = 23)
1460 | assert_equal(23, t.day)
1461 | end
1462 |
1463 | def test_hour()
1464 | t = Mysql::Time.new
1465 | assert_equal(15, t.hour = 15)
1466 | assert_equal(15, t.hour)
1467 | end
1468 |
1469 | def test_minute()
1470 | t = Mysql::Time.new
1471 | assert_equal(58, t.month = 58)
1472 | assert_equal(58, t.month)
1473 | end
1474 |
1475 | def test_second()
1476 | t = Mysql::Time.new
1477 | assert_equal(34, t.second = 34)
1478 | assert_equal(34, t.second)
1479 | end
1480 |
1481 | def test_tos()
1482 | t = Mysql::Time.new(2005, 7, 19, 10, 15, 49)
1483 | assert_equal("2005-07-19 10:15:49", t.to_s)
1484 | end
1485 |
1486 | def test_eql()
1487 | t1 = Mysql::Time.new(2005,7,19,23,56,13)
1488 | t2 = Mysql::Time.new(2005,7,19,23,56,13)
1489 | assert_equal(t1, t2)
1490 | end
1491 |
1492 | end if Mysql.client_version >= 40100
1493 |
--------------------------------------------------------------------------------
/ext/mysql_api/mysql.c:
--------------------------------------------------------------------------------
1 | /* ruby mysql module
2 | * $Id: mysql.c 250 2010-02-11 10:42:54Z tommy $
3 | */
4 |
5 | #include
6 | #ifndef RSTRING_PTR
7 | #define RSTRING_PTR(str) RSTRING(str)->ptr
8 | #endif
9 | #ifndef RSTRING_LEN
10 | #define RSTRING_LEN(str) RSTRING(str)->len
11 | #endif
12 | #ifndef RARRAY_PTR
13 | #define RARRAY_PTR(ary) RARRAY(ary)->ptr
14 | #endif
15 | #ifndef HAVE_RB_STR_SET_LEN
16 | #define rb_str_set_len(str, length) (RSTRING_LEN(str) = (length))
17 | #endif
18 |
19 | #ifdef HAVE_MYSQL_H
20 | #include
21 | #include
22 | #include
23 | #else
24 | #include
25 | #include
26 | #include
27 | #endif
28 |
29 | #define MYSQL_RUBY_VERSION 20802
30 |
31 | #define GC_STORE_RESULT_LIMIT 20
32 |
33 | #if MYSQL_VERSION_ID < 32224
34 | #define mysql_field_count mysql_num_fields
35 | #endif
36 |
37 | #define NILorSTRING(obj) (NIL_P(obj)? NULL: StringValuePtr(obj))
38 | #define NILorINT(obj) (NIL_P(obj)? 0: NUM2INT(obj))
39 |
40 | #define GetMysqlStruct(obj) (Check_Type(obj, T_DATA), (struct mysql*)DATA_PTR(obj))
41 | #define GetHandler(obj) (Check_Type(obj, T_DATA), &(((struct mysql*)DATA_PTR(obj))->handler))
42 | #define GetMysqlRes(obj) (Check_Type(obj, T_DATA), ((struct mysql_res*)DATA_PTR(obj))->res)
43 | #define GetMysqlStmt(obj) (Check_Type(obj, T_DATA), ((struct mysql_stmt*)DATA_PTR(obj))->stmt)
44 |
45 | VALUE cMysql;
46 | VALUE cMysqlRes;
47 | VALUE cMysqlField;
48 | VALUE cMysqlStmt;
49 | VALUE cMysqlRowOffset;
50 | VALUE cMysqlTime;
51 | VALUE eMysql;
52 |
53 | static int store_result_count = 0;
54 |
55 | struct mysql {
56 | MYSQL handler;
57 | char connection;
58 | char query_with_result;
59 | };
60 |
61 | struct mysql_res {
62 | MYSQL_RES* res;
63 | char freed;
64 | };
65 |
66 | #if MYSQL_VERSION_ID >= 40101
67 | struct mysql_stmt {
68 | MYSQL_STMT *stmt;
69 | char closed;
70 | struct {
71 | int n;
72 | MYSQL_BIND *bind;
73 | unsigned long *length;
74 | MYSQL_TIME *buffer;
75 | } param;
76 | struct {
77 | int n;
78 | MYSQL_BIND *bind;
79 | my_bool *is_null;
80 | unsigned long *length;
81 | } result;
82 | MYSQL_RES *res;
83 | };
84 | #endif
85 |
86 | /* free Mysql class object */
87 | static void free_mysql(struct mysql* my)
88 | {
89 | if (my->connection == Qtrue)
90 | mysql_close(&my->handler);
91 | xfree(my);
92 | }
93 |
94 | static void free_mysqlres(struct mysql_res* resp)
95 | {
96 | if (resp->freed == Qfalse) {
97 | mysql_free_result(resp->res);
98 | store_result_count--;
99 | }
100 | xfree(resp);
101 | }
102 |
103 | #if MYSQL_VERSION_ID >= 40101
104 | static void free_mysqlstmt_memory(struct mysql_stmt *s)
105 | {
106 | if (s->param.bind) {
107 | xfree(s->param.bind);
108 | s->param.bind = NULL;
109 | }
110 | if (s->param.length) {
111 | xfree(s->param.length);
112 | s->param.length = NULL;
113 | }
114 | if (s->param.buffer) {
115 | xfree(s->param.buffer);
116 | s->param.buffer = NULL;
117 | }
118 | s->param.n = 0;
119 | if (s->res) {
120 | mysql_free_result(s->res);
121 | s->res = NULL;
122 | }
123 | if (s->result.bind) {
124 | int i;
125 | for (i = 0; i < s->result.n; i++) {
126 | if (s->result.bind[i].buffer)
127 | xfree(s->result.bind[i].buffer);
128 | s->result.bind[i].buffer = NULL;
129 | }
130 | xfree(s->result.bind);
131 | s->result.bind = NULL;
132 | }
133 | if (s->result.is_null) {
134 | xfree(s->result.is_null);
135 | s->result.is_null = NULL;
136 | }
137 | if (s->result.length) {
138 | xfree(s->result.length);
139 | s->result.length = NULL;
140 | }
141 | s->result.n = 0;
142 | }
143 |
144 | static void free_execute_memory(struct mysql_stmt *s)
145 | {
146 | if (s->res && s->result.bind) {
147 | int i;
148 | for (i = 0; i < s->result.n; i++) {
149 | if (s->result.bind[i].buffer)
150 | xfree(s->result.bind[i].buffer);
151 | s->result.bind[i].buffer = NULL;
152 | }
153 | }
154 | mysql_stmt_free_result(s->stmt);
155 | }
156 |
157 | static void free_mysqlstmt(struct mysql_stmt* s)
158 | {
159 | free_mysqlstmt_memory(s);
160 | if (s->closed == Qfalse)
161 | mysql_stmt_close(s->stmt);
162 | if (s->res)
163 | mysql_free_result(s->res);
164 | xfree(s);
165 | }
166 | #endif
167 |
168 | static void mysql_raise(MYSQL* m)
169 | {
170 | VALUE e = rb_exc_new2(eMysql, mysql_error(m));
171 | rb_iv_set(e, "errno", INT2FIX(mysql_errno(m)));
172 | #if MYSQL_VERSION_ID >= 40101
173 | rb_iv_set(e, "sqlstate", rb_tainted_str_new2(mysql_sqlstate(m)));
174 | #endif
175 | rb_exc_raise(e);
176 | }
177 |
178 | static VALUE mysqlres2obj(MYSQL_RES* res)
179 | {
180 | VALUE obj;
181 | struct mysql_res* resp;
182 | obj = Data_Make_Struct(cMysqlRes, struct mysql_res, 0, free_mysqlres, resp);
183 | rb_iv_set(obj, "colname", Qnil);
184 | rb_iv_set(obj, "tblcolname", Qnil);
185 | resp->res = res;
186 | resp->freed = Qfalse;
187 | rb_obj_call_init(obj, 0, NULL);
188 | if (++store_result_count > GC_STORE_RESULT_LIMIT)
189 | rb_gc();
190 | return obj;
191 | }
192 |
193 | /* make Mysql::Field object */
194 | static VALUE make_field_obj(MYSQL_FIELD* f)
195 | {
196 | VALUE obj;
197 | if (f == NULL)
198 | return Qnil;
199 | obj = rb_obj_alloc(cMysqlField);
200 | rb_iv_set(obj, "name", f->name? rb_str_freeze(rb_tainted_str_new2(f->name)): Qnil);
201 | rb_iv_set(obj, "table", f->table? rb_str_freeze(rb_tainted_str_new2(f->table)): Qnil);
202 | rb_iv_set(obj, "def", f->def? rb_str_freeze(rb_tainted_str_new2(f->def)): Qnil);
203 | rb_iv_set(obj, "type", INT2NUM(f->type));
204 | rb_iv_set(obj, "length", INT2NUM(f->length));
205 | rb_iv_set(obj, "max_length", INT2NUM(f->max_length));
206 | rb_iv_set(obj, "flags", INT2NUM(f->flags));
207 | rb_iv_set(obj, "decimals", INT2NUM(f->decimals));
208 | return obj;
209 | }
210 |
211 | /*-------------------------------
212 | * Mysql class method
213 | */
214 |
215 | /* init() */
216 | static VALUE init(VALUE klass)
217 | {
218 | struct mysql* myp;
219 | VALUE obj;
220 |
221 | obj = Data_Make_Struct(klass, struct mysql, 0, free_mysql, myp);
222 | mysql_init(&myp->handler);
223 | myp->connection = Qfalse;
224 | myp->query_with_result = Qtrue;
225 | rb_obj_call_init(obj, 0, NULL);
226 | return obj;
227 | }
228 |
229 | /* real_connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil) */
230 | static VALUE real_connect(int argc, VALUE* argv, VALUE klass)
231 | {
232 | VALUE host, user, passwd, db, port, sock, flag;
233 | char *h, *u, *p, *d, *s;
234 | unsigned int pp, f;
235 | struct mysql* myp;
236 | VALUE obj;
237 |
238 | #if MYSQL_VERSION_ID >= 32200
239 | rb_scan_args(argc, argv, "07", &host, &user, &passwd, &db, &port, &sock, &flag);
240 | d = NILorSTRING(db);
241 | f = NILorINT(flag);
242 | #elif MYSQL_VERSION_ID >= 32115
243 | rb_scan_args(argc, argv, "06", &host, &user, &passwd, &port, &sock, &flag);
244 | f = NILorINT(flag);
245 | #else
246 | rb_scan_args(argc, argv, "05", &host, &user, &passwd, &port, &sock);
247 | #endif
248 | h = NILorSTRING(host);
249 | u = NILorSTRING(user);
250 | p = NILorSTRING(passwd);
251 | pp = NILorINT(port);
252 | s = NILorSTRING(sock);
253 |
254 | #ifdef HAVE_RB_THREAD_START_TIMER
255 | rb_thread_stop_timer();
256 | #endif
257 | obj = Data_Make_Struct(klass, struct mysql, 0, free_mysql, myp);
258 | #if MYSQL_VERSION_ID >= 32200
259 | mysql_init(&myp->handler);
260 | if (mysql_real_connect(&myp->handler, h, u, p, d, pp, s, f) == NULL)
261 | #elif MYSQL_VERSION_ID >= 32115
262 | if (mysql_real_connect(&myp->handler, h, u, p, pp, s, f) == NULL)
263 | #else
264 | if (mysql_real_connect(&myp->handler, h, u, p, pp, s) == NULL)
265 | #endif
266 | {
267 | #ifdef HAVE_RB_THREAD_START_TIMER
268 | rb_thread_start_timer();
269 | #endif
270 | mysql_raise(&myp->handler);
271 | }
272 | #ifdef HAVE_RB_THREAD_START_TIMER
273 | rb_thread_start_timer();
274 | #endif
275 |
276 | myp->handler.reconnect = 0;
277 | myp->connection = Qtrue;
278 | myp->query_with_result = Qtrue;
279 | rb_obj_call_init(obj, argc, argv);
280 |
281 | return obj;
282 | }
283 |
284 | /* escape_string(string) */
285 | static VALUE escape_string(VALUE klass, VALUE str)
286 | {
287 | VALUE ret;
288 | Check_Type(str, T_STRING);
289 | ret = rb_str_new(0, (RSTRING_LEN(str))*2+1);
290 | rb_str_set_len(ret, mysql_escape_string(RSTRING_PTR(ret), RSTRING_PTR(str), RSTRING_LEN(str)));
291 | return ret;
292 | }
293 |
294 | /* client_info() */
295 | static VALUE client_info(VALUE klass)
296 | {
297 | return rb_tainted_str_new2(mysql_get_client_info());
298 | }
299 |
300 | #if MYSQL_VERSION_ID >= 32332
301 | /* my_debug(string) */
302 | static VALUE my_debug(VALUE obj, VALUE str)
303 | {
304 | mysql_debug(StringValuePtr(str));
305 | return obj;
306 | }
307 | #endif
308 |
309 | #if MYSQL_VERSION_ID >= 40000
310 | /* client_version() */
311 | static VALUE client_version(VALUE obj)
312 | {
313 | return INT2NUM(mysql_get_client_version());
314 | }
315 | #endif
316 |
317 | /*-------------------------------
318 | * Mysql object method
319 | */
320 |
321 | #if MYSQL_VERSION_ID >= 32200
322 | /* real_connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil) */
323 | static VALUE real_connect2(int argc, VALUE* argv, VALUE obj)
324 | {
325 | VALUE host, user, passwd, db, port, sock, flag;
326 | char *h, *u, *p, *d, *s;
327 | unsigned int pp, f;
328 | MYSQL* m = GetHandler(obj);
329 | rb_scan_args(argc, argv, "07", &host, &user, &passwd, &db, &port, &sock, &flag);
330 | d = NILorSTRING(db);
331 | f = NILorINT(flag);
332 | h = NILorSTRING(host);
333 | u = NILorSTRING(user);
334 | p = NILorSTRING(passwd);
335 | pp = NILorINT(port);
336 | s = NILorSTRING(sock);
337 |
338 | #ifdef HAVE_RB_THREAD_START_TIMER
339 | rb_thread_stop_timer();
340 | #endif
341 | if (mysql_real_connect(m, h, u, p, d, pp, s, f) == NULL) {
342 | #ifdef HAVE_RB_THREAD_START_TIMER
343 | rb_thread_start_timer();
344 | #endif
345 | mysql_raise(m);
346 | }
347 | #ifdef HAVE_RB_THREAD_START_TIMER
348 | rb_thread_start_timer();
349 | #endif
350 | m->reconnect = 0;
351 | GetMysqlStruct(obj)->connection = Qtrue;
352 |
353 | return obj;
354 | }
355 |
356 | /* options(opt, value=nil) */
357 | static VALUE options(int argc, VALUE* argv, VALUE obj)
358 | {
359 | VALUE opt, val;
360 | int n;
361 | my_bool b;
362 | char* v;
363 | MYSQL* m = GetHandler(obj);
364 |
365 | rb_scan_args(argc, argv, "11", &opt, &val);
366 | switch(NUM2INT(opt)) {
367 | case MYSQL_OPT_CONNECT_TIMEOUT:
368 | #if MYSQL_VERSION_ID >= 40100
369 | case MYSQL_OPT_PROTOCOL:
370 | #endif
371 | #if MYSQL_VERSION_ID >= 40101
372 | case MYSQL_OPT_READ_TIMEOUT:
373 | case MYSQL_OPT_WRITE_TIMEOUT:
374 | #endif
375 | if (val == Qnil)
376 | rb_raise(rb_eArgError, "wrong # of arguments(1 for 2)");
377 | n = NUM2INT(val);
378 | v = (char*)&n;
379 | break;
380 | case MYSQL_INIT_COMMAND:
381 | case MYSQL_READ_DEFAULT_FILE:
382 | case MYSQL_READ_DEFAULT_GROUP:
383 | #if MYSQL_VERSION_ID >= 32349
384 | case MYSQL_SET_CHARSET_DIR:
385 | case MYSQL_SET_CHARSET_NAME:
386 | #endif
387 | #if MYSQL_VERSION_ID >= 40100
388 | case MYSQL_SHARED_MEMORY_BASE_NAME:
389 | #endif
390 | #if MYSQL_VERSION_ID >= 40101
391 | case MYSQL_SET_CLIENT_IP:
392 | #endif
393 | if (val == Qnil)
394 | rb_raise(rb_eArgError, "wrong # of arguments(1 for 2)");
395 | v = StringValuePtr(val);
396 | break;
397 | #if MYSQL_VERSION_ID >= 40101
398 | case MYSQL_SECURE_AUTH:
399 | if (val == Qnil || val == Qfalse)
400 | b = 1;
401 | else
402 | b = 0;
403 | v = (char*)&b;
404 | break;
405 | #endif
406 | #if MYSQL_VERSION_ID >= 32349
407 | case MYSQL_OPT_LOCAL_INFILE:
408 | if (val == Qnil || val == Qfalse)
409 | v = NULL;
410 | else {
411 | n = 1;
412 | v = (char*)&n;
413 | }
414 | break;
415 | #endif
416 | default:
417 | v = NULL;
418 | }
419 |
420 | if (mysql_options(m, NUM2INT(opt), v) != 0)
421 | rb_raise(eMysql, "unknown option: %d", NUM2INT(opt));
422 | return obj;
423 | }
424 | #endif
425 |
426 | #if MYSQL_VERSION_ID >= 32332
427 | /* real_escape_string(string) */
428 | static VALUE real_escape_string(VALUE obj, VALUE str)
429 | {
430 | MYSQL* m = GetHandler(obj);
431 | VALUE ret;
432 | Check_Type(str, T_STRING);
433 | ret = rb_str_new(0, (RSTRING_LEN(str))*2+1);
434 | rb_str_set_len(ret, mysql_real_escape_string(m, RSTRING_PTR(ret), RSTRING_PTR(str), RSTRING_LEN(str)));
435 | return ret;
436 | }
437 | #endif
438 |
439 | /* initialize() */
440 | static VALUE initialize(int argc, VALUE* argv, VALUE obj)
441 | {
442 | return obj;
443 | }
444 |
445 | /* affected_rows() */
446 | static VALUE affected_rows(VALUE obj)
447 | {
448 | return ULL2NUM(mysql_affected_rows(GetHandler(obj)));
449 | }
450 |
451 | #if MYSQL_VERSION_ID >= 32303
452 | /* change_user(user=nil, passwd=nil, db=nil) */
453 | static VALUE change_user(int argc, VALUE* argv, VALUE obj)
454 | {
455 | VALUE user, passwd, db;
456 | char *u, *p, *d;
457 | MYSQL* m = GetHandler(obj);
458 | rb_scan_args(argc, argv, "03", &user, &passwd, &db);
459 | u = NILorSTRING(user);
460 | p = NILorSTRING(passwd);
461 | d = NILorSTRING(db);
462 | if (mysql_change_user(m, u, p, d) != 0)
463 | mysql_raise(m);
464 | return obj;
465 | }
466 | #endif
467 |
468 | #if MYSQL_VERSION_ID >= 32321
469 | /* character_set_name() */
470 | static VALUE character_set_name(VALUE obj)
471 | {
472 | return rb_tainted_str_new2(mysql_character_set_name(GetHandler(obj)));
473 | }
474 | #endif
475 |
476 | /* close() */
477 | static VALUE my_close(VALUE obj)
478 | {
479 | MYSQL* m = GetHandler(obj);
480 | mysql_close(m);
481 | GetMysqlStruct(obj)->connection = Qfalse;
482 | return obj;
483 | }
484 |
485 | #if MYSQL_VERSION_ID < 40000
486 | /* create_db(db) */
487 | static VALUE create_db(VALUE obj, VALUE db)
488 | {
489 | MYSQL* m = GetHandler(obj);
490 | if (mysql_create_db(m, StringValuePtr(db)) != 0)
491 | mysql_raise(m);
492 | return obj;
493 | }
494 |
495 | /* drop_db(db) */
496 | static VALUE drop_db(VALUE obj, VALUE db)
497 | {
498 | MYSQL* m = GetHandler(obj);
499 | if (mysql_drop_db(m, StringValuePtr(db)) != 0)
500 | mysql_raise(m);
501 | return obj;
502 | }
503 | #endif
504 |
505 | #if MYSQL_VERSION_ID >= 32332
506 | /* dump_debug_info() */
507 | static VALUE dump_debug_info(VALUE obj)
508 | {
509 | MYSQL* m = GetHandler(obj);
510 | if (mysql_dump_debug_info(m) != 0)
511 | mysql_raise(m);
512 | return obj;
513 | }
514 | #endif
515 |
516 | /* errno() */
517 | static VALUE my_errno(VALUE obj)
518 | {
519 | return INT2NUM(mysql_errno(GetHandler(obj)));
520 | }
521 |
522 | /* error() */
523 | static VALUE my_error(VALUE obj)
524 | {
525 | return rb_str_new2(mysql_error(GetHandler(obj)));
526 | }
527 |
528 | /* field_count() */
529 | static VALUE field_count(VALUE obj)
530 | {
531 | return INT2NUM(mysql_field_count(GetHandler(obj)));
532 | }
533 |
534 | /* host_info() */
535 | static VALUE host_info(VALUE obj)
536 | {
537 | return rb_tainted_str_new2(mysql_get_host_info(GetHandler(obj)));
538 | }
539 |
540 | /* proto_info() */
541 | static VALUE proto_info(VALUE obj)
542 | {
543 | return INT2NUM(mysql_get_proto_info(GetHandler(obj)));
544 | }
545 |
546 | /* server_info() */
547 | static VALUE server_info(VALUE obj)
548 | {
549 | return rb_tainted_str_new2(mysql_get_server_info(GetHandler(obj)));
550 | }
551 |
552 | /* info() */
553 | static VALUE info(VALUE obj)
554 | {
555 | const char* p = mysql_info(GetHandler(obj));
556 | return p? rb_tainted_str_new2(p): Qnil;
557 | }
558 |
559 | /* insert_id() */
560 | static VALUE insert_id(VALUE obj)
561 | {
562 | return ULL2NUM(mysql_insert_id(GetHandler(obj)));
563 | }
564 |
565 | /* kill(pid) */
566 | static VALUE my_kill(VALUE obj, VALUE pid)
567 | {
568 | int p = NUM2INT(pid);
569 | MYSQL* m = GetHandler(obj);
570 | if (mysql_kill(m, p) != 0)
571 | mysql_raise(m);
572 | return obj;
573 | }
574 |
575 | /* list_dbs(db=nil) */
576 | static VALUE list_dbs(int argc, VALUE* argv, VALUE obj)
577 | {
578 | unsigned int i, n;
579 | VALUE db, ret;
580 | MYSQL* m = GetHandler(obj);
581 | MYSQL_RES* res;
582 |
583 | rb_scan_args(argc, argv, "01", &db);
584 | res = mysql_list_dbs(m, NILorSTRING(db));
585 | if (res == NULL)
586 | mysql_raise(m);
587 |
588 | n = mysql_num_rows(res);
589 | ret = rb_ary_new2(n);
590 | for (i=0; i= 40103
685 | if (mysql_shutdown(m, NIL_P(level) ? SHUTDOWN_DEFAULT : NUM2INT(level)) != 0)
686 | #else
687 | if (mysql_shutdown(m) != 0)
688 | #endif
689 | mysql_raise(m);
690 | return obj;
691 | }
692 |
693 | /* stat() */
694 | static VALUE my_stat(VALUE obj)
695 | {
696 | MYSQL* m = GetHandler(obj);
697 | const char* s = mysql_stat(m);
698 | if (s == NULL)
699 | mysql_raise(m);
700 | return rb_tainted_str_new2(s);
701 | }
702 |
703 | /* store_result() */
704 | static VALUE store_result(VALUE obj)
705 | {
706 | MYSQL* m = GetHandler(obj);
707 | MYSQL_RES* res = mysql_store_result(m);
708 | if (res == NULL)
709 | mysql_raise(m);
710 | return mysqlres2obj(res);
711 | }
712 |
713 | /* thread_id() */
714 | static VALUE thread_id(VALUE obj)
715 | {
716 | return INT2NUM(mysql_thread_id(GetHandler(obj)));
717 | }
718 |
719 | /* use_result() */
720 | static VALUE use_result(VALUE obj)
721 | {
722 | MYSQL* m = GetHandler(obj);
723 | MYSQL_RES* res = mysql_use_result(m);
724 | if (res == NULL)
725 | mysql_raise(m);
726 | return mysqlres2obj(res);
727 | }
728 |
729 | static VALUE res_free(VALUE);
730 | /* query(sql) */
731 | static VALUE query(VALUE obj, VALUE sql)
732 | {
733 | int loop = 0;
734 | VALUE e;
735 | MYSQL* m = GetHandler(obj);
736 | Check_Type(sql, T_STRING);
737 | if (GetMysqlStruct(obj)->connection == Qfalse) {
738 | e = rb_exc_new2(eMysql, "query: not connected");
739 | rb_iv_set(e, "errno", Qnil);
740 | rb_exc_raise(e);
741 | }
742 | if (rb_block_given_p()) {
743 | if (mysql_real_query(m, RSTRING_PTR(sql), RSTRING_LEN(sql)) != 0)
744 | mysql_raise(m);
745 | do {
746 | MYSQL_RES* res = mysql_store_result(m);
747 | if (res == NULL) {
748 | if (mysql_field_count(m) != 0)
749 | mysql_raise(m);
750 | } else {
751 | VALUE robj = mysqlres2obj(res);
752 | rb_ensure(rb_yield, robj, res_free, robj);
753 | }
754 | #if MYSQL_VERSION_ID >= 40101
755 | if ((loop = mysql_next_result(m)) > 0)
756 | mysql_raise(m);
757 | } while (loop == 0);
758 | #else
759 | } while (0);
760 | #endif
761 | return obj;
762 | }
763 | if (mysql_real_query(m, RSTRING_PTR(sql), RSTRING_LEN(sql)) != 0)
764 | mysql_raise(m);
765 | if (GetMysqlStruct(obj)->query_with_result == Qfalse)
766 | return obj;
767 | if (mysql_field_count(m) == 0)
768 | return Qnil;
769 | return store_result(obj);
770 | }
771 |
772 | #if MYSQL_VERSION_ID >= 40100
773 | /* server_version() */
774 | static VALUE server_version(VALUE obj)
775 | {
776 | return INT2NUM(mysql_get_server_version(GetHandler(obj)));
777 | }
778 |
779 | /* warning_count() */
780 | static VALUE warning_count(VALUE obj)
781 | {
782 | return INT2NUM(mysql_warning_count(GetHandler(obj)));
783 | }
784 |
785 | /* commit() */
786 | static VALUE commit(VALUE obj)
787 | {
788 | MYSQL* m = GetHandler(obj);
789 | if (mysql_commit(m) != 0)
790 | mysql_raise(m);
791 | return obj;
792 | }
793 |
794 | /* rollback() */
795 | static VALUE rollback(VALUE obj)
796 | {
797 | MYSQL* m = GetHandler(obj);
798 | if (mysql_rollback(m) != 0)
799 | mysql_raise(m);
800 | return obj;
801 | }
802 |
803 | /* autocommit() */
804 | static VALUE autocommit(VALUE obj, VALUE mode)
805 | {
806 | MYSQL* m = GetHandler(obj);
807 | int f;
808 | f = (mode == Qnil || mode == Qfalse || (rb_type(mode) == T_FIXNUM && NUM2INT(mode) == 0)) ? 0 : 1;
809 | if (mysql_autocommit(m, f) != 0)
810 | mysql_raise(m);
811 | return obj;
812 | }
813 | #endif
814 |
815 | #ifdef HAVE_MYSQL_SSL_SET
816 | /* ssl_set(key=nil, cert=nil, ca=nil, capath=nil, cipher=nil) */
817 | static VALUE ssl_set(int argc, VALUE* argv, VALUE obj)
818 | {
819 | VALUE key, cert, ca, capath, cipher;
820 | char *s_key, *s_cert, *s_ca, *s_capath, *s_cipher;
821 | MYSQL* m = GetHandler(obj);
822 | rb_scan_args(argc, argv, "05", &key, &cert, &ca, &capath, &cipher);
823 | s_key = NILorSTRING(key);
824 | s_cert = NILorSTRING(cert);
825 | s_ca = NILorSTRING(ca);
826 | s_capath = NILorSTRING(capath);
827 | s_cipher = NILorSTRING(cipher);
828 | mysql_ssl_set(m, s_key, s_cert, s_ca, s_capath, s_cipher);
829 | return obj;
830 | }
831 | #endif
832 |
833 | #if MYSQL_VERSION_ID >= 40100
834 | /* more_results() */
835 | static VALUE more_results(VALUE obj)
836 | {
837 | if (mysql_more_results(GetHandler(obj)) == 0)
838 | return Qfalse;
839 | else
840 | return Qtrue;
841 | }
842 |
843 | static VALUE next_result(VALUE obj)
844 | {
845 | MYSQL* m = GetHandler(obj);
846 | int ret;
847 | ret = mysql_next_result(m);
848 | if (ret > 0)
849 | mysql_raise(m);
850 | if (ret == 0)
851 | return Qtrue;
852 | return Qfalse;
853 | }
854 | #endif
855 |
856 | #if MYSQL_VERSION_ID >= 40101
857 | /* set_server_option(option) */
858 | static VALUE set_server_option(VALUE obj, VALUE option)
859 | {
860 | MYSQL *m = GetHandler(obj);
861 | if (mysql_set_server_option(m, NUM2INT(option)) != 0)
862 | mysql_raise(m);
863 | return obj;
864 | }
865 |
866 | /* sqlstate() */
867 | static VALUE sqlstate(VALUE obj)
868 | {
869 | MYSQL *m = GetHandler(obj);
870 | return rb_tainted_str_new2(mysql_sqlstate(m));
871 | }
872 | #endif
873 |
874 | #if MYSQL_VERSION_ID >= 40102
875 | /* stmt_init() */
876 | static VALUE stmt_init(VALUE obj)
877 | {
878 | MYSQL *m = GetHandler(obj);
879 | MYSQL_STMT *s;
880 | struct mysql_stmt* stmt;
881 | my_bool true = 1;
882 | VALUE st_obj;
883 |
884 | if ((s = mysql_stmt_init(m)) == NULL)
885 | mysql_raise(m);
886 | if (mysql_stmt_attr_set(s, STMT_ATTR_UPDATE_MAX_LENGTH, &true))
887 | rb_raise(rb_eArgError, "mysql_stmt_attr_set() failed");
888 | st_obj = Data_Make_Struct(cMysqlStmt, struct mysql_stmt, 0, free_mysqlstmt, stmt);
889 | memset(stmt, 0, sizeof(*stmt));
890 | stmt->stmt = s;
891 | stmt->closed = Qfalse;
892 | return st_obj;
893 | }
894 |
895 | static VALUE stmt_prepare(VALUE obj, VALUE query);
896 | /* prepare(query) */
897 | static VALUE prepare(VALUE obj, VALUE query)
898 | {
899 | VALUE st;
900 | st = stmt_init(obj);
901 | return stmt_prepare(st, query);
902 | }
903 | #endif
904 |
905 | /* query_with_result() */
906 | static VALUE query_with_result(VALUE obj)
907 | {
908 | return GetMysqlStruct(obj)->query_with_result? Qtrue: Qfalse;
909 | }
910 |
911 | /* query_with_result=(flag) */
912 | static VALUE query_with_result_set(VALUE obj, VALUE flag)
913 | {
914 | if (TYPE(flag) != T_TRUE && TYPE(flag) != T_FALSE)
915 | rb_raise(rb_eTypeError, "invalid type, required true or false.");
916 | GetMysqlStruct(obj)->query_with_result = flag;
917 | return flag;
918 | }
919 |
920 | /* reconnect() */
921 | static VALUE reconnect(VALUE obj)
922 | {
923 | return GetHandler(obj)->reconnect ? Qtrue : Qfalse;
924 | }
925 |
926 | /* reconnect=(flag) */
927 | static VALUE reconnect_set(VALUE obj, VALUE flag)
928 | {
929 | GetHandler(obj)->reconnect = (flag == Qnil || flag == Qfalse) ? 0 : 1;
930 | return flag;
931 | }
932 |
933 | /*-------------------------------
934 | * Mysql::Result object method
935 | */
936 |
937 | /* check if already freed */
938 | static void check_free(VALUE obj)
939 | {
940 | struct mysql_res* resp = DATA_PTR(obj);
941 | if (resp->freed == Qtrue)
942 | rb_raise(eMysql, "Mysql::Result object is already freed");
943 | }
944 |
945 | /* data_seek(offset) */
946 | static VALUE data_seek(VALUE obj, VALUE offset)
947 | {
948 | check_free(obj);
949 | mysql_data_seek(GetMysqlRes(obj), NUM2INT(offset));
950 | return obj;
951 | }
952 |
953 | /* fetch_field() */
954 | static VALUE fetch_field(VALUE obj)
955 | {
956 | check_free(obj);
957 | return make_field_obj(mysql_fetch_field(GetMysqlRes(obj)));
958 | }
959 |
960 | /* fetch_fields() */
961 | static VALUE fetch_fields(VALUE obj)
962 | {
963 | MYSQL_RES* res;
964 | MYSQL_FIELD* f;
965 | unsigned int n;
966 | VALUE ret;
967 | unsigned int i;
968 | check_free(obj);
969 | res = GetMysqlRes(obj);
970 | f = mysql_fetch_fields(res);
971 | n = mysql_num_fields(res);
972 | ret = rb_ary_new2(n);
973 | for (i=0; i= max)
989 | rb_raise(eMysql, "%d: out of range (max: %d)", n, max-1);
990 | #if MYSQL_VERSION_ID >= 32226
991 | return make_field_obj(mysql_fetch_field_direct(res, n));
992 | #else
993 | return make_field_obj(&mysql_fetch_field_direct(res, n));
994 | #endif
995 | }
996 |
997 | /* fetch_lengths() */
998 | static VALUE fetch_lengths(VALUE obj)
999 | {
1000 | MYSQL_RES* res;
1001 | unsigned int n;
1002 | unsigned long* lengths;
1003 | VALUE ary;
1004 | unsigned int i;
1005 | check_free(obj);
1006 | res = GetMysqlRes(obj);
1007 | n = mysql_num_fields(res);
1008 | lengths = mysql_fetch_lengths(res);
1009 | if (lengths == NULL)
1010 | return Qnil;
1011 | ary = rb_ary_new2(n);
1012 | for (i=0; ires);
1118 | resp->freed = Qtrue;
1119 | store_result_count--;
1120 | return Qnil;
1121 | }
1122 |
1123 | /* num_fields() */
1124 | static VALUE num_fields(VALUE obj)
1125 | {
1126 | check_free(obj);
1127 | return INT2NUM(mysql_num_fields(GetMysqlRes(obj)));
1128 | }
1129 |
1130 | /* num_rows() */
1131 | static VALUE num_rows(VALUE obj)
1132 | {
1133 | check_free(obj);
1134 | return INT2NUM(mysql_num_rows(GetMysqlRes(obj)));
1135 | }
1136 |
1137 | /* row_seek(offset) */
1138 | static VALUE row_seek(VALUE obj, VALUE offset)
1139 | {
1140 | MYSQL_ROW_OFFSET prev_offset;
1141 | if (CLASS_OF(offset) != cMysqlRowOffset)
1142 | rb_raise(rb_eTypeError, "wrong argument type %s (expected Mysql::RowOffset)", rb_obj_classname(offset));
1143 | check_free(obj);
1144 | prev_offset = mysql_row_seek(GetMysqlRes(obj), DATA_PTR(offset));
1145 | return Data_Wrap_Struct(cMysqlRowOffset, 0, NULL, prev_offset);
1146 | }
1147 |
1148 | /* row_tell() */
1149 | static VALUE row_tell(VALUE obj)
1150 | {
1151 | MYSQL_ROW_OFFSET offset;
1152 | check_free(obj);
1153 | offset = mysql_row_tell(GetMysqlRes(obj));
1154 | return Data_Wrap_Struct(cMysqlRowOffset, 0, NULL, offset);
1155 | }
1156 |
1157 | /* each {...} */
1158 | static VALUE each(VALUE obj)
1159 | {
1160 | VALUE row;
1161 | check_free(obj);
1162 | while ((row = fetch_row(obj)) != Qnil)
1163 | rb_yield(row);
1164 | return obj;
1165 | }
1166 |
1167 | /* each_hash(with_table=false) {...} */
1168 | static VALUE each_hash(int argc, VALUE* argv, VALUE obj)
1169 | {
1170 | VALUE with_table;
1171 | VALUE hash;
1172 | check_free(obj);
1173 | rb_scan_args(argc, argv, "01", &with_table);
1174 | if (with_table == Qnil)
1175 | with_table = Qfalse;
1176 | while ((hash = fetch_hash2(obj, with_table)) != Qnil)
1177 | rb_yield(hash);
1178 | return obj;
1179 | }
1180 |
1181 | /*-------------------------------
1182 | * Mysql::Field object method
1183 | */
1184 |
1185 | /* hash */
1186 | static VALUE field_hash(VALUE obj)
1187 | {
1188 | VALUE h = rb_hash_new();
1189 | rb_hash_aset(h, rb_str_new2("name"), rb_iv_get(obj, "name"));
1190 | rb_hash_aset(h, rb_str_new2("table"), rb_iv_get(obj, "table"));
1191 | rb_hash_aset(h, rb_str_new2("def"), rb_iv_get(obj, "def"));
1192 | rb_hash_aset(h, rb_str_new2("type"), rb_iv_get(obj, "type"));
1193 | rb_hash_aset(h, rb_str_new2("length"), rb_iv_get(obj, "length"));
1194 | rb_hash_aset(h, rb_str_new2("max_length"), rb_iv_get(obj, "max_length"));
1195 | rb_hash_aset(h, rb_str_new2("flags"), rb_iv_get(obj, "flags"));
1196 | rb_hash_aset(h, rb_str_new2("decimals"), rb_iv_get(obj, "decimals"));
1197 | return h;
1198 | }
1199 |
1200 | /* inspect */
1201 | static VALUE field_inspect(VALUE obj)
1202 | {
1203 | VALUE n = rb_iv_get(obj, "name");
1204 | VALUE s = rb_str_new(0, RSTRING_LEN(n) + 16);
1205 | sprintf(RSTRING_PTR(s), "#", RSTRING_PTR(n));
1206 | return s;
1207 | }
1208 |
1209 | #define DefineMysqlFieldMemberMethod(m)\
1210 | static VALUE field_##m(VALUE obj)\
1211 | {return rb_iv_get(obj, #m);}
1212 |
1213 | DefineMysqlFieldMemberMethod(name)
1214 | DefineMysqlFieldMemberMethod(table)
1215 | DefineMysqlFieldMemberMethod(def)
1216 | DefineMysqlFieldMemberMethod(type)
1217 | DefineMysqlFieldMemberMethod(length)
1218 | DefineMysqlFieldMemberMethod(max_length)
1219 | DefineMysqlFieldMemberMethod(flags)
1220 | DefineMysqlFieldMemberMethod(decimals)
1221 |
1222 | #ifdef IS_NUM
1223 | /* is_num? */
1224 | static VALUE field_is_num(VALUE obj)
1225 | {
1226 | return IS_NUM(NUM2INT(rb_iv_get(obj, "type"))) ? Qtrue : Qfalse;
1227 | }
1228 | #endif
1229 |
1230 | #ifdef IS_NOT_NULL
1231 | /* is_not_null? */
1232 | static VALUE field_is_not_null(VALUE obj)
1233 | {
1234 | return IS_NOT_NULL(NUM2INT(rb_iv_get(obj, "flags"))) ? Qtrue : Qfalse;
1235 | }
1236 | #endif
1237 |
1238 | #ifdef IS_PRI_KEY
1239 | /* is_pri_key? */
1240 | static VALUE field_is_pri_key(VALUE obj)
1241 | {
1242 | return IS_PRI_KEY(NUM2INT(rb_iv_get(obj, "flags"))) ? Qtrue : Qfalse;
1243 | }
1244 | #endif
1245 |
1246 | #if MYSQL_VERSION_ID >= 40102
1247 | /*-------------------------------
1248 | * Mysql::Stmt object method
1249 | */
1250 |
1251 | /* check if stmt is already closed */
1252 | static void check_stmt_closed(VALUE obj)
1253 | {
1254 | struct mysql_stmt* s = DATA_PTR(obj);
1255 | if (s->closed == Qtrue)
1256 | rb_raise(eMysql, "Mysql::Stmt object is already closed");
1257 | }
1258 |
1259 | static void mysql_stmt_raise(MYSQL_STMT* s)
1260 | {
1261 | VALUE e = rb_exc_new2(eMysql, mysql_stmt_error(s));
1262 | rb_iv_set(e, "errno", INT2FIX(mysql_stmt_errno(s)));
1263 | rb_iv_set(e, "sqlstate", rb_tainted_str_new2(mysql_stmt_sqlstate(s)));
1264 | rb_exc_raise(e);
1265 | }
1266 |
1267 | /* affected_rows() */
1268 | static VALUE stmt_affected_rows(VALUE obj)
1269 | {
1270 | struct mysql_stmt* s = DATA_PTR(obj);
1271 | my_ulonglong n;
1272 | check_stmt_closed(obj);
1273 | n = mysql_stmt_affected_rows(s->stmt);
1274 | return ULL2NUM(n);
1275 | }
1276 |
1277 | #if 0
1278 | /* attr_get(option) */
1279 | static VALUE stmt_attr_get(VALUE obj, VALUE opt)
1280 | {
1281 | struct mysql_stmt* s = DATA_PTR(obj);
1282 | check_stmt_closed(obj);
1283 | if (NUM2INT(opt) == STMT_ATTR_UPDATE_MAX_LENGTH) {
1284 | my_bool arg;
1285 | mysql_stmt_attr_get(s->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &arg);
1286 | return arg == 1 ? Qtrue : Qfalse;
1287 | }
1288 | rb_raise(eMysql, "unknown option: %d", NUM2INT(opt));
1289 | }
1290 |
1291 | /* attr_set(option, arg) */
1292 | static VALUE stmt_attr_set(VALUE obj, VALUE opt, VALUE val)
1293 | {
1294 | struct mysql_stmt* s = DATA_PTR(obj);
1295 | check_stmt_closed(obj);
1296 | if (NUM2INT(opt) == STMT_ATTR_UPDATE_MAX_LENGTH) {
1297 | my_bool arg;
1298 | arg = (val == Qnil || val == Qfalse) ? 0 : 1;
1299 | mysql_stmt_attr_set(s->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &arg);
1300 | return obj;
1301 | }
1302 | rb_raise(eMysql, "unknown option: %d", NUM2INT(opt));
1303 | }
1304 | #endif
1305 |
1306 | /* bind_result(bind,...) */
1307 | static VALUE stmt_bind_result(int argc, VALUE *argv, VALUE obj)
1308 | {
1309 | struct mysql_stmt* s = DATA_PTR(obj);
1310 | int i;
1311 | MYSQL_FIELD *field;
1312 |
1313 | check_stmt_closed(obj);
1314 | if (argc != s->result.n)
1315 | rb_raise(eMysql, "bind_result: result value count(%d) != number of argument(%d)", s->result.n, argc);
1316 | for (i = 0; i < argc; i++) {
1317 | if (argv[i] == Qnil || argv[i] == rb_cNilClass) {
1318 | field = mysql_fetch_fields(s->res);
1319 | s->result.bind[i].buffer_type = field[i].type;
1320 | }
1321 | else if (argv[i] == rb_cString)
1322 | s->result.bind[i].buffer_type = MYSQL_TYPE_STRING;
1323 | else if (argv[i] == rb_cNumeric || argv[i] == rb_cInteger || argv[i] == rb_cFixnum)
1324 | s->result.bind[i].buffer_type = MYSQL_TYPE_LONGLONG;
1325 | else if (argv[i] == rb_cFloat)
1326 | s->result.bind[i].buffer_type = MYSQL_TYPE_DOUBLE;
1327 | else if (argv[i] == cMysqlTime)
1328 | s->result.bind[i].buffer_type = MYSQL_TYPE_DATETIME;
1329 | else
1330 | rb_raise(rb_eTypeError, "unrecognized class: %s", RSTRING_PTR(rb_inspect(argv[i])));
1331 | if (mysql_stmt_bind_result(s->stmt, s->result.bind))
1332 | mysql_stmt_raise(s->stmt);
1333 | }
1334 | return obj;
1335 | }
1336 |
1337 | /* close() */
1338 | static VALUE stmt_close(VALUE obj)
1339 | {
1340 | struct mysql_stmt* s = DATA_PTR(obj);
1341 | check_stmt_closed(obj);
1342 | mysql_stmt_close(s->stmt);
1343 | s->closed = Qtrue;
1344 | return Qnil;
1345 | }
1346 |
1347 | /* data_seek(offset) */
1348 | static VALUE stmt_data_seek(VALUE obj, VALUE offset)
1349 | {
1350 | struct mysql_stmt* s = DATA_PTR(obj);
1351 | check_stmt_closed(obj);
1352 | mysql_stmt_data_seek(s->stmt, NUM2INT(offset));
1353 | return obj;
1354 | }
1355 |
1356 | /* execute(arg,...) */
1357 | static VALUE stmt_execute(int argc, VALUE *argv, VALUE obj)
1358 | {
1359 | struct mysql_stmt *s = DATA_PTR(obj);
1360 | MYSQL_STMT *stmt = s->stmt;
1361 | int i;
1362 |
1363 | check_stmt_closed(obj);
1364 | free_execute_memory(s);
1365 | if (s->param.n != argc)
1366 | rb_raise(eMysql, "execute: param_count(%d) != number of argument(%d)", s->param.n, argc);
1367 | if (argc > 0) {
1368 | memset(s->param.bind, 0, sizeof(*(s->param.bind))*argc);
1369 | for (i = 0; i < argc; i++) {
1370 | switch (TYPE(argv[i])) {
1371 | case T_NIL:
1372 | s->param.bind[i].buffer_type = MYSQL_TYPE_NULL;
1373 | break;
1374 | case T_FIXNUM:
1375 | #if SIZEOF_INT < SIZEOF_LONG
1376 | s->param.bind[i].buffer_type = MYSQL_TYPE_LONGLONG;
1377 | s->param.bind[i].buffer = &(s->param.buffer[i]);
1378 | *(LONG_LONG*)(s->param.bind[i].buffer) = FIX2LONG(argv[i]);
1379 | #else
1380 | s->param.bind[i].buffer_type = MYSQL_TYPE_LONG;
1381 | s->param.bind[i].buffer = &(s->param.buffer[i]);
1382 | *(int*)(s->param.bind[i].buffer) = FIX2INT(argv[i]);
1383 | #endif
1384 | break;
1385 | case T_BIGNUM:
1386 | s->param.bind[i].buffer_type = MYSQL_TYPE_LONGLONG;
1387 | s->param.bind[i].buffer = &(s->param.buffer[i]);
1388 | *(LONG_LONG*)(s->param.bind[i].buffer) = rb_big2ll(argv[i]);
1389 | break;
1390 | case T_FLOAT:
1391 | s->param.bind[i].buffer_type = MYSQL_TYPE_DOUBLE;
1392 | s->param.bind[i].buffer = &(s->param.buffer[i]);
1393 | *(double*)(s->param.bind[i].buffer) = NUM2DBL(argv[i]);
1394 | break;
1395 | case T_STRING:
1396 | s->param.bind[i].buffer_type = MYSQL_TYPE_STRING;
1397 | s->param.bind[i].buffer = RSTRING_PTR(argv[i]);
1398 | s->param.bind[i].buffer_length = RSTRING_LEN(argv[i]);
1399 | s->param.length[i] = RSTRING_LEN(argv[i]);
1400 | s->param.bind[i].length = &(s->param.length[i]);
1401 | break;
1402 | default:
1403 | if (CLASS_OF(argv[i]) == rb_cTime) {
1404 | MYSQL_TIME t;
1405 | VALUE a = rb_funcall(argv[i], rb_intern("to_a"), 0);
1406 | s->param.bind[i].buffer_type = MYSQL_TYPE_DATETIME;
1407 | s->param.bind[i].buffer = &(s->param.buffer[i]);
1408 | memset(&t, 0, sizeof(t)); /* avoid warning */
1409 | t.second_part = 0;
1410 | t.neg = 0;
1411 | t.second = FIX2INT(RARRAY_PTR(a)[0]);
1412 | t.minute = FIX2INT(RARRAY_PTR(a)[1]);
1413 | t.hour = FIX2INT(RARRAY_PTR(a)[2]);
1414 | t.day = FIX2INT(RARRAY_PTR(a)[3]);
1415 | t.month = FIX2INT(RARRAY_PTR(a)[4]);
1416 | t.year = FIX2INT(RARRAY_PTR(a)[5]);
1417 | *(MYSQL_TIME*)&(s->param.buffer[i]) = t;
1418 | } else if (CLASS_OF(argv[i]) == cMysqlTime) {
1419 | MYSQL_TIME t;
1420 | s->param.bind[i].buffer_type = MYSQL_TYPE_DATETIME;
1421 | s->param.bind[i].buffer = &(s->param.buffer[i]);
1422 | memset(&t, 0, sizeof(t)); /* avoid warning */
1423 | t.second_part = 0;
1424 | t.neg = 0;
1425 | t.second = NUM2INT(rb_iv_get(argv[i], "second"));
1426 | t.minute = NUM2INT(rb_iv_get(argv[i], "minute"));
1427 | t.hour = NUM2INT(rb_iv_get(argv[i], "hour"));
1428 | t.day = NUM2INT(rb_iv_get(argv[i], "day"));
1429 | t.month = NUM2INT(rb_iv_get(argv[i], "month"));
1430 | t.year = NUM2INT(rb_iv_get(argv[i], "year"));
1431 | *(MYSQL_TIME*)&(s->param.buffer[i]) = t;
1432 | } else
1433 | rb_raise(rb_eTypeError, "unsupported type: %d", TYPE(argv[i]));
1434 | }
1435 | }
1436 | if (mysql_stmt_bind_param(stmt, s->param.bind))
1437 | mysql_stmt_raise(stmt);
1438 | }
1439 |
1440 | if (mysql_stmt_execute(stmt))
1441 | mysql_stmt_raise(stmt);
1442 | if (s->res) {
1443 | MYSQL_FIELD *field;
1444 | if (mysql_stmt_store_result(stmt))
1445 | mysql_stmt_raise(stmt);
1446 | field = mysql_fetch_fields(s->res);
1447 | for (i = 0; i < s->result.n; i++) {
1448 | switch(s->result.bind[i].buffer_type) {
1449 | case MYSQL_TYPE_NULL:
1450 | break;
1451 | case MYSQL_TYPE_TINY:
1452 | case MYSQL_TYPE_SHORT:
1453 | case MYSQL_TYPE_YEAR:
1454 | case MYSQL_TYPE_INT24:
1455 | case MYSQL_TYPE_LONG:
1456 | case MYSQL_TYPE_LONGLONG:
1457 | case MYSQL_TYPE_FLOAT:
1458 | case MYSQL_TYPE_DOUBLE:
1459 | s->result.bind[i].buffer = xmalloc(8);
1460 | s->result.bind[i].buffer_length = 8;
1461 | memset(s->result.bind[i].buffer, 0, 8);
1462 | break;
1463 | case MYSQL_TYPE_DECIMAL:
1464 | case MYSQL_TYPE_STRING:
1465 | case MYSQL_TYPE_VAR_STRING:
1466 | case MYSQL_TYPE_TINY_BLOB:
1467 | case MYSQL_TYPE_BLOB:
1468 | case MYSQL_TYPE_MEDIUM_BLOB:
1469 | case MYSQL_TYPE_LONG_BLOB:
1470 | #if MYSQL_VERSION_ID >= 50003
1471 | case MYSQL_TYPE_NEWDECIMAL:
1472 | case MYSQL_TYPE_BIT:
1473 | #endif
1474 | s->result.bind[i].buffer = xmalloc(field[i].max_length);
1475 | memset(s->result.bind[i].buffer, 0, field[i].max_length);
1476 | s->result.bind[i].buffer_length = field[i].max_length;
1477 | break;
1478 | case MYSQL_TYPE_TIME:
1479 | case MYSQL_TYPE_DATE:
1480 | case MYSQL_TYPE_DATETIME:
1481 | case MYSQL_TYPE_TIMESTAMP:
1482 | s->result.bind[i].buffer = xmalloc(sizeof(MYSQL_TIME));
1483 | s->result.bind[i].buffer_length = sizeof(MYSQL_TIME);
1484 | memset(s->result.bind[i].buffer, 0, sizeof(MYSQL_TIME));
1485 | break;
1486 | default:
1487 | rb_raise(rb_eTypeError, "unknown buffer_type: %d", s->result.bind[i].buffer_type);
1488 | }
1489 | }
1490 | if (mysql_stmt_bind_result(s->stmt, s->result.bind))
1491 | mysql_stmt_raise(s->stmt);
1492 | }
1493 | return obj;
1494 | }
1495 |
1496 | /* fetch() */
1497 | static VALUE stmt_fetch(VALUE obj)
1498 | {
1499 | struct mysql_stmt* s = DATA_PTR(obj);
1500 | VALUE ret;
1501 | int i;
1502 | int r;
1503 |
1504 | check_stmt_closed(obj);
1505 | r = mysql_stmt_fetch(s->stmt);
1506 | if (r == MYSQL_NO_DATA)
1507 | return Qnil;
1508 | #ifdef MYSQL_DATA_TRUNCATED
1509 | if (r == MYSQL_DATA_TRUNCATED)
1510 | rb_raise(rb_eRuntimeError, "unexpectedly data truncated");
1511 | #endif
1512 | if (r == 1)
1513 | mysql_stmt_raise(s->stmt);
1514 |
1515 | ret = rb_ary_new2(s->result.n);
1516 | for (i = 0; i < s->result.n; i++) {
1517 | if (s->result.is_null[i])
1518 | rb_ary_push(ret, Qnil);
1519 | else {
1520 | VALUE v;
1521 | MYSQL_TIME *t;
1522 | switch (s->result.bind[i].buffer_type) {
1523 | case MYSQL_TYPE_TINY:
1524 | if (s->result.bind[i].is_unsigned)
1525 | v = UINT2NUM(*(unsigned char *)s->result.bind[i].buffer);
1526 | else
1527 | v = INT2NUM(*(signed char *)s->result.bind[i].buffer);
1528 | break;
1529 | case MYSQL_TYPE_SHORT:
1530 | case MYSQL_TYPE_YEAR:
1531 | if (s->result.bind[i].is_unsigned)
1532 | v = UINT2NUM(*(unsigned short *)s->result.bind[i].buffer);
1533 | else
1534 | v = INT2NUM(*(short *)s->result.bind[i].buffer);
1535 | break;
1536 | case MYSQL_TYPE_INT24:
1537 | case MYSQL_TYPE_LONG:
1538 | if (s->result.bind[i].is_unsigned)
1539 | v = UINT2NUM(*(unsigned int *)s->result.bind[i].buffer);
1540 | else
1541 | v = INT2NUM(*(int *)s->result.bind[i].buffer);
1542 | break;
1543 | case MYSQL_TYPE_LONGLONG:
1544 | if (s->result.bind[i].is_unsigned)
1545 | v = ULL2NUM(*(unsigned long long *)s->result.bind[i].buffer);
1546 | else
1547 | v = LL2NUM(*(long long *)s->result.bind[i].buffer);
1548 | break;
1549 | case MYSQL_TYPE_FLOAT:
1550 | v = rb_float_new((double)(*(float *)s->result.bind[i].buffer));
1551 | break;
1552 | case MYSQL_TYPE_DOUBLE:
1553 | v = rb_float_new(*(double *)s->result.bind[i].buffer);
1554 | break;
1555 | case MYSQL_TYPE_TIME:
1556 | case MYSQL_TYPE_DATE:
1557 | case MYSQL_TYPE_DATETIME:
1558 | case MYSQL_TYPE_TIMESTAMP:
1559 | t = (MYSQL_TIME *)s->result.bind[i].buffer;
1560 | v = rb_obj_alloc(cMysqlTime);
1561 | rb_funcall(v, rb_intern("initialize"), 8,
1562 | INT2FIX(t->year), INT2FIX(t->month),
1563 | INT2FIX(t->day), INT2FIX(t->hour),
1564 | INT2FIX(t->minute), INT2FIX(t->second),
1565 | (t->neg ? Qtrue : Qfalse),
1566 | INT2FIX(t->second_part));
1567 | break;
1568 | case MYSQL_TYPE_DECIMAL:
1569 | case MYSQL_TYPE_STRING:
1570 | case MYSQL_TYPE_VAR_STRING:
1571 | case MYSQL_TYPE_TINY_BLOB:
1572 | case MYSQL_TYPE_BLOB:
1573 | case MYSQL_TYPE_MEDIUM_BLOB:
1574 | case MYSQL_TYPE_LONG_BLOB:
1575 | #if MYSQL_VERSION_ID >= 50003
1576 | case MYSQL_TYPE_NEWDECIMAL:
1577 | case MYSQL_TYPE_BIT:
1578 | #endif
1579 | v = rb_tainted_str_new(s->result.bind[i].buffer, s->result.length[i]);
1580 | break;
1581 | default:
1582 | rb_raise(rb_eTypeError, "unknown buffer_type: %d", s->result.bind[i].buffer_type);
1583 | }
1584 | rb_ary_push(ret, v);
1585 | }
1586 | }
1587 | return ret;
1588 | }
1589 |
1590 | /* each {...} */
1591 | static VALUE stmt_each(VALUE obj)
1592 | {
1593 | VALUE row;
1594 | check_stmt_closed(obj);
1595 | while ((row = stmt_fetch(obj)) != Qnil)
1596 | rb_yield(row);
1597 | return obj;
1598 | }
1599 |
1600 | /* field_count() */
1601 | static VALUE stmt_field_count(VALUE obj)
1602 | {
1603 | struct mysql_stmt* s = DATA_PTR(obj);
1604 | unsigned int n;
1605 | check_stmt_closed(obj);
1606 | n = mysql_stmt_field_count(s->stmt);
1607 | return INT2NUM(n);
1608 | }
1609 |
1610 | /* free_result() */
1611 | static VALUE stmt_free_result(VALUE obj)
1612 | {
1613 | struct mysql_stmt* s = DATA_PTR(obj);
1614 | check_stmt_closed(obj);
1615 | if (mysql_stmt_free_result(s->stmt))
1616 | mysql_stmt_raise(s->stmt);
1617 | return obj;
1618 | }
1619 |
1620 | /* insert_id() */
1621 | static VALUE stmt_insert_id(VALUE obj)
1622 | {
1623 | struct mysql_stmt* s = DATA_PTR(obj);
1624 | my_ulonglong n;
1625 | check_stmt_closed(obj);
1626 | n = mysql_stmt_insert_id(s->stmt);
1627 | return ULL2NUM(n);
1628 | }
1629 |
1630 | /* num_rows() */
1631 | static VALUE stmt_num_rows(VALUE obj)
1632 | {
1633 | struct mysql_stmt* s = DATA_PTR(obj);
1634 | my_ulonglong n;
1635 | check_stmt_closed(obj);
1636 | n = mysql_stmt_num_rows(s->stmt);
1637 | return INT2NUM(n);
1638 | }
1639 |
1640 | /* param_count() */
1641 | static VALUE stmt_param_count(VALUE obj)
1642 | {
1643 | struct mysql_stmt* s = DATA_PTR(obj);
1644 | unsigned long n;
1645 | check_stmt_closed(obj);
1646 | n = mysql_stmt_param_count(s->stmt);
1647 | return INT2NUM(n);
1648 | }
1649 |
1650 | /* prepare(query) */
1651 | static VALUE stmt_prepare(VALUE obj, VALUE query)
1652 | {
1653 | struct mysql_stmt* s = DATA_PTR(obj);
1654 | int n;
1655 | int i;
1656 | MYSQL_FIELD *field;
1657 |
1658 | free_mysqlstmt_memory(s);
1659 | check_stmt_closed(obj);
1660 | Check_Type(query, T_STRING);
1661 | if (mysql_stmt_prepare(s->stmt, RSTRING_PTR(query), RSTRING_LEN(query)))
1662 | mysql_stmt_raise(s->stmt);
1663 |
1664 | n = mysql_stmt_param_count(s->stmt);
1665 | s->param.n = n;
1666 | s->param.bind = xmalloc(sizeof(s->param.bind[0]) * n);
1667 | s->param.length = xmalloc(sizeof(s->param.length[0]) * n);
1668 | s->param.buffer = xmalloc(sizeof(s->param.buffer[0]) * n);
1669 |
1670 | s->res = mysql_stmt_result_metadata(s->stmt);
1671 | if (s->res) {
1672 | n = s->result.n = mysql_num_fields(s->res);
1673 | s->result.bind = xmalloc(sizeof(s->result.bind[0]) * n);
1674 | s->result.is_null = xmalloc(sizeof(s->result.is_null[0]) * n);
1675 | s->result.length = xmalloc(sizeof(s->result.length[0]) * n);
1676 | field = mysql_fetch_fields(s->res);
1677 | memset(s->result.bind, 0, sizeof(s->result.bind[0]) * n);
1678 | for (i = 0; i < n; i++) {
1679 | s->result.bind[i].buffer_type = field[i].type;
1680 | #if MYSQL_VERSION_ID < 50003
1681 | if (field[i].type == MYSQL_TYPE_DECIMAL)
1682 | s->result.bind[i].buffer_type = MYSQL_TYPE_STRING;
1683 | #endif
1684 | s->result.bind[i].is_null = &(s->result.is_null[i]);
1685 | s->result.bind[i].length = &(s->result.length[i]);
1686 | s->result.bind[i].is_unsigned = ((field[i].flags & UNSIGNED_FLAG) != 0);
1687 | }
1688 | } else {
1689 | if (mysql_stmt_errno(s->stmt))
1690 | mysql_stmt_raise(s->stmt);
1691 | }
1692 |
1693 | return obj;
1694 | }
1695 |
1696 | #if 0
1697 | /* reset() */
1698 | static VALUE stmt_reset(VALUE obj)
1699 | {
1700 | struct mysql_stmt* s = DATA_PTR(obj);
1701 | check_stmt_closed(obj);
1702 | if (mysql_stmt_reset(s->stmt))
1703 | mysql_stmt_raise(s->stmt);
1704 | return obj;
1705 | }
1706 | #endif
1707 |
1708 | /* result_metadata() */
1709 | static VALUE stmt_result_metadata(VALUE obj)
1710 | {
1711 | struct mysql_stmt* s = DATA_PTR(obj);
1712 | MYSQL_RES *res;
1713 | check_stmt_closed(obj);
1714 | res = mysql_stmt_result_metadata(s->stmt);
1715 | if (res == NULL) {
1716 | if (mysql_stmt_errno(s->stmt) != 0)
1717 | mysql_stmt_raise(s->stmt);
1718 | return Qnil;
1719 | }
1720 | return mysqlres2obj(res);
1721 | }
1722 |
1723 | /* row_seek(offset) */
1724 | static VALUE stmt_row_seek(VALUE obj, VALUE offset)
1725 | {
1726 | struct mysql_stmt* s = DATA_PTR(obj);
1727 | MYSQL_ROW_OFFSET prev_offset;
1728 | if (CLASS_OF(offset) != cMysqlRowOffset)
1729 | rb_raise(rb_eTypeError, "wrong argument type %s (expected Mysql::RowOffset)", rb_obj_classname(offset));
1730 | check_stmt_closed(obj);
1731 | prev_offset = mysql_stmt_row_seek(s->stmt, DATA_PTR(offset));
1732 | return Data_Wrap_Struct(cMysqlRowOffset, 0, NULL, prev_offset);
1733 | }
1734 |
1735 | /* row_tell() */
1736 | static VALUE stmt_row_tell(VALUE obj)
1737 | {
1738 | struct mysql_stmt* s = DATA_PTR(obj);
1739 | MYSQL_ROW_OFFSET offset;
1740 | check_stmt_closed(obj);
1741 | offset = mysql_stmt_row_tell(s->stmt);
1742 | return Data_Wrap_Struct(cMysqlRowOffset, 0, NULL, offset);
1743 | }
1744 |
1745 | #if 0
1746 | /* send_long_data(col, data) */
1747 | static VALUE stmt_send_long_data(VALUE obj, VALUE col, VALUE data)
1748 | {
1749 | struct mysql_stmt* s = DATA_PTR(obj);
1750 | int c;
1751 | check_stmt_closed(obj);
1752 | c = NUM2INT(col);
1753 | if (0 <= c && c < s->param.n) {
1754 | s->param.bind[c].buffer_type = MYSQL_TYPE_STRING;
1755 | if (mysql_stmt_bind_param(s->stmt, s->param.bind))
1756 | mysql_stmt_raise(s->stmt);
1757 | }
1758 | if (mysql_stmt_send_long_data(s->stmt, c, RSTRING_PTR(data), RSTRING_LEN(data)))
1759 | mysql_stmt_raise(s->stmt);
1760 | return obj;
1761 | }
1762 | #endif
1763 |
1764 | /* sqlstate() */
1765 | static VALUE stmt_sqlstate(VALUE obj)
1766 | {
1767 | struct mysql_stmt* s = DATA_PTR(obj);
1768 | return rb_tainted_str_new2(mysql_stmt_sqlstate(s->stmt));
1769 | }
1770 |
1771 | /*-------------------------------
1772 | * Mysql::Time object method
1773 | */
1774 |
1775 | static VALUE time_initialize(int argc, VALUE* argv, VALUE obj)
1776 | {
1777 | VALUE year, month, day, hour, minute, second, neg, second_part;
1778 | rb_scan_args(argc, argv, "08", &year, &month, &day, &hour, &minute, &second, &neg, &second_part);
1779 | #define NILorFIXvalue(o) (NIL_P(o) ? INT2FIX(0) : (Check_Type(o, T_FIXNUM), o))
1780 | rb_iv_set(obj, "year", NILorFIXvalue(year));
1781 | rb_iv_set(obj, "month", NILorFIXvalue(month));
1782 | rb_iv_set(obj, "day", NILorFIXvalue(day));
1783 | rb_iv_set(obj, "hour", NILorFIXvalue(hour));
1784 | rb_iv_set(obj, "minute", NILorFIXvalue(minute));
1785 | rb_iv_set(obj, "second", NILorFIXvalue(second));
1786 | rb_iv_set(obj, "neg", (neg == Qnil || neg == Qfalse) ? Qfalse : Qtrue);
1787 | rb_iv_set(obj, "second_part", NILorFIXvalue(second_part));
1788 | return obj;
1789 | }
1790 |
1791 | static VALUE time_inspect(VALUE obj)
1792 | {
1793 | char buf[36];
1794 | sprintf(buf, "#",
1795 | NUM2INT(rb_iv_get(obj, "year")),
1796 | NUM2INT(rb_iv_get(obj, "month")),
1797 | NUM2INT(rb_iv_get(obj, "day")),
1798 | NUM2INT(rb_iv_get(obj, "hour")),
1799 | NUM2INT(rb_iv_get(obj, "minute")),
1800 | NUM2INT(rb_iv_get(obj, "second")));
1801 | return rb_str_new2(buf);
1802 | }
1803 |
1804 | static VALUE time_to_s(VALUE obj)
1805 | {
1806 | char buf[20];
1807 | sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d",
1808 | NUM2INT(rb_iv_get(obj, "year")),
1809 | NUM2INT(rb_iv_get(obj, "month")),
1810 | NUM2INT(rb_iv_get(obj, "day")),
1811 | NUM2INT(rb_iv_get(obj, "hour")),
1812 | NUM2INT(rb_iv_get(obj, "minute")),
1813 | NUM2INT(rb_iv_get(obj, "second")));
1814 | return rb_str_new2(buf);
1815 | }
1816 |
1817 | #define DefineMysqlTimeGetMethod(m)\
1818 | static VALUE time_get_##m(VALUE obj)\
1819 | {return rb_iv_get(obj, #m);}
1820 |
1821 | DefineMysqlTimeGetMethod(year)
1822 | DefineMysqlTimeGetMethod(month)
1823 | DefineMysqlTimeGetMethod(day)
1824 | DefineMysqlTimeGetMethod(hour)
1825 | DefineMysqlTimeGetMethod(minute)
1826 | DefineMysqlTimeGetMethod(second)
1827 | DefineMysqlTimeGetMethod(neg)
1828 | DefineMysqlTimeGetMethod(second_part)
1829 |
1830 | #define DefineMysqlTimeSetMethod(m)\
1831 | static VALUE time_set_##m(VALUE obj, VALUE v)\
1832 | {rb_iv_set(obj, #m, NILorFIXvalue(v)); return v;}
1833 |
1834 | DefineMysqlTimeSetMethod(year)
1835 | DefineMysqlTimeSetMethod(month)
1836 | DefineMysqlTimeSetMethod(day)
1837 | DefineMysqlTimeSetMethod(hour)
1838 | DefineMysqlTimeSetMethod(minute)
1839 | DefineMysqlTimeSetMethod(second)
1840 | DefineMysqlTimeSetMethod(second_part)
1841 |
1842 | static VALUE time_set_neg(VALUE obj, VALUE v)
1843 | {
1844 | rb_iv_set(obj, "neg", (v == Qnil || v == Qfalse) ? Qfalse : Qtrue);
1845 | return v;
1846 | }
1847 |
1848 | static VALUE time_equal(VALUE obj, VALUE v)
1849 | {
1850 | if (CLASS_OF(v) == cMysqlTime &&
1851 | NUM2INT(rb_iv_get(obj, "year")) == NUM2INT(rb_iv_get(v, "year")) &&
1852 | NUM2INT(rb_iv_get(obj, "month")) == NUM2INT(rb_iv_get(v, "month")) &&
1853 | NUM2INT(rb_iv_get(obj, "day")) == NUM2INT(rb_iv_get(v, "day")) &&
1854 | NUM2INT(rb_iv_get(obj, "hour")) == NUM2INT(rb_iv_get(v, "hour")) &&
1855 | NUM2INT(rb_iv_get(obj, "minute")) == NUM2INT(rb_iv_get(v, "minute")) &&
1856 | NUM2INT(rb_iv_get(obj, "second")) == NUM2INT(rb_iv_get(v, "second")) &&
1857 | rb_iv_get(obj, "neg") == rb_iv_get(v, "neg") &&
1858 | NUM2INT(rb_iv_get(obj, "second_part")) == NUM2INT(rb_iv_get(v, "second_part")))
1859 | return Qtrue;
1860 | return Qfalse;
1861 | }
1862 |
1863 | #endif
1864 |
1865 | /*-------------------------------
1866 | * Mysql::Error object method
1867 | */
1868 |
1869 | static VALUE error_error(VALUE obj)
1870 | {
1871 | return rb_iv_get(obj, "mesg");
1872 | }
1873 |
1874 | static VALUE error_errno(VALUE obj)
1875 | {
1876 | return rb_iv_get(obj, "errno");
1877 | }
1878 |
1879 | static VALUE error_sqlstate(VALUE obj)
1880 | {
1881 | return rb_iv_get(obj, "sqlstate");
1882 | }
1883 |
1884 | /*-------------------------------
1885 | * Initialize
1886 | */
1887 |
1888 | void Init_mysql_api(void)
1889 | {
1890 | int i;
1891 | int dots = 0;
1892 | const char *lib = mysql_get_client_info();
1893 | for (i = 0; lib[i] != 0 && MYSQL_SERVER_VERSION[i] != 0; i++) {
1894 | if (lib[i] == '.') {
1895 | dots++;
1896 | /* we only compare MAJOR and MINOR */
1897 | if (dots == 2) break;
1898 | }
1899 | if (lib[i] != MYSQL_SERVER_VERSION[i]) {
1900 | rb_raise(rb_eRuntimeError, "Incorrect MySQL client library version! This gem was compiled for %s but the client library is %s.", MYSQL_SERVER_VERSION, lib);
1901 | return;
1902 | }
1903 | }
1904 |
1905 | cMysql = rb_define_class("Mysql", rb_cObject);
1906 | cMysqlRes = rb_define_class_under(cMysql, "Result", rb_cObject);
1907 | cMysqlField = rb_define_class_under(cMysql, "Field", rb_cObject);
1908 | #if MYSQL_VERSION_ID >= 40102
1909 | cMysqlStmt = rb_define_class_under(cMysql, "Stmt", rb_cObject);
1910 | cMysqlRowOffset = rb_define_class_under(cMysql, "RowOffset", rb_cObject);
1911 | cMysqlTime = rb_define_class_under(cMysql, "Time", rb_cObject);
1912 | #endif
1913 | eMysql = rb_define_class_under(cMysql, "Error", rb_eStandardError);
1914 |
1915 | rb_define_global_const("MysqlRes", cMysqlRes);
1916 | rb_define_global_const("MysqlField", cMysqlField);
1917 | rb_define_global_const("MysqlError", eMysql);
1918 |
1919 | /* Mysql class method */
1920 | rb_define_singleton_method(cMysql, "init", init, 0);
1921 | rb_define_singleton_method(cMysql, "real_connect", real_connect, -1);
1922 | rb_define_singleton_method(cMysql, "connect", real_connect, -1);
1923 | rb_define_singleton_method(cMysql, "new", real_connect, -1);
1924 | rb_define_singleton_method(cMysql, "escape_string", escape_string, 1);
1925 | rb_define_singleton_method(cMysql, "quote", escape_string, 1);
1926 | rb_define_singleton_method(cMysql, "client_info", client_info, 0);
1927 | rb_define_singleton_method(cMysql, "get_client_info", client_info, 0);
1928 | #if MYSQL_VERSION_ID >= 32332
1929 | rb_define_singleton_method(cMysql, "debug", my_debug, 1);
1930 | #endif
1931 | #if MYSQL_VERSION_ID >= 40000
1932 | rb_define_singleton_method(cMysql, "get_client_version", client_version, 0);
1933 | rb_define_singleton_method(cMysql, "client_version", client_version, 0);
1934 | #endif
1935 |
1936 | /* Mysql object method */
1937 | #if MYSQL_VERSION_ID >= 32200
1938 | rb_define_method(cMysql, "real_connect", real_connect2, -1);
1939 | rb_define_method(cMysql, "connect", real_connect2, -1);
1940 | rb_define_method(cMysql, "options", options, -1);
1941 | #endif
1942 | rb_define_method(cMysql, "initialize", initialize, -1);
1943 | #if MYSQL_VERSION_ID >= 32332
1944 | rb_define_method(cMysql, "escape_string", real_escape_string, 1);
1945 | rb_define_method(cMysql, "quote", real_escape_string, 1);
1946 | #else
1947 | rb_define_method(cMysql, "escape_string", escape_string, 1);
1948 | rb_define_method(cMysql, "quote", escape_string, 1);
1949 | #endif
1950 | rb_define_method(cMysql, "client_info", client_info, 0);
1951 | rb_define_method(cMysql, "get_client_info", client_info, 0);
1952 | rb_define_method(cMysql, "affected_rows", affected_rows, 0);
1953 | #if MYSQL_VERSION_ID >= 32303
1954 | rb_define_method(cMysql, "change_user", change_user, -1);
1955 | #endif
1956 | #if MYSQL_VERSION_ID >= 32321
1957 | rb_define_method(cMysql, "character_set_name", character_set_name, 0);
1958 | #endif
1959 | rb_define_method(cMysql, "close", my_close, 0);
1960 | #if MYSQL_VERSION_ID < 40000
1961 | rb_define_method(cMysql, "create_db", create_db, 1);
1962 | rb_define_method(cMysql, "drop_db", drop_db, 1);
1963 | #endif
1964 | #if MYSQL_VERSION_ID >= 32332
1965 | rb_define_method(cMysql, "dump_debug_info", dump_debug_info, 0);
1966 | #endif
1967 | rb_define_method(cMysql, "errno", my_errno, 0);
1968 | rb_define_method(cMysql, "error", my_error, 0);
1969 | rb_define_method(cMysql, "field_count", field_count, 0);
1970 | #if MYSQL_VERSION_ID >= 40000
1971 | rb_define_method(cMysql, "get_client_version", client_version, 0);
1972 | rb_define_method(cMysql, "client_version", client_version, 0);
1973 | #endif
1974 | rb_define_method(cMysql, "get_host_info", host_info, 0);
1975 | rb_define_method(cMysql, "host_info", host_info, 0);
1976 | rb_define_method(cMysql, "get_proto_info", proto_info, 0);
1977 | rb_define_method(cMysql, "proto_info", proto_info, 0);
1978 | rb_define_method(cMysql, "get_server_info", server_info, 0);
1979 | rb_define_method(cMysql, "server_info", server_info, 0);
1980 | rb_define_method(cMysql, "info", info, 0);
1981 | rb_define_method(cMysql, "insert_id", insert_id, 0);
1982 | rb_define_method(cMysql, "kill", my_kill, 1);
1983 | rb_define_method(cMysql, "list_dbs", list_dbs, -1);
1984 | rb_define_method(cMysql, "list_fields", list_fields, -1);
1985 | rb_define_method(cMysql, "list_processes", list_processes, 0);
1986 | rb_define_method(cMysql, "list_tables", list_tables, -1);
1987 | #if MYSQL_VERSION_ID >= 32200
1988 | rb_define_method(cMysql, "ping", ping, 0);
1989 | #endif
1990 | rb_define_method(cMysql, "query", query, 1);
1991 | rb_define_method(cMysql, "real_query", query, 1);
1992 | rb_define_method(cMysql, "refresh", refresh, 1);
1993 | rb_define_method(cMysql, "reload", reload, 0);
1994 | rb_define_method(cMysql, "select_db", select_db, 1);
1995 | rb_define_method(cMysql, "shutdown", my_shutdown, -1);
1996 | rb_define_method(cMysql, "stat", my_stat, 0);
1997 | rb_define_method(cMysql, "store_result", store_result, 0);
1998 | rb_define_method(cMysql, "thread_id", thread_id, 0);
1999 | rb_define_method(cMysql, "use_result", use_result, 0);
2000 | #if MYSQL_VERSION_ID >= 40100
2001 | rb_define_method(cMysql, "get_server_version", server_version, 0);
2002 | rb_define_method(cMysql, "server_version", server_version, 0);
2003 | rb_define_method(cMysql, "warning_count", warning_count, 0);
2004 | rb_define_method(cMysql, "commit", commit, 0);
2005 | rb_define_method(cMysql, "rollback", rollback, 0);
2006 | rb_define_method(cMysql, "autocommit", autocommit, 1);
2007 | #endif
2008 | #ifdef HAVE_MYSQL_SSL_SET
2009 | rb_define_method(cMysql, "ssl_set", ssl_set, -1);
2010 | #endif
2011 | #if MYSQL_VERSION_ID >= 40102
2012 | rb_define_method(cMysql, "stmt_init", stmt_init, 0);
2013 | rb_define_method(cMysql, "prepare", prepare, 1);
2014 | #endif
2015 | #if MYSQL_VERSION_ID >= 40100
2016 | rb_define_method(cMysql, "more_results", more_results, 0);
2017 | rb_define_method(cMysql, "more_results?", more_results, 0);
2018 | rb_define_method(cMysql, "next_result", next_result, 0);
2019 | #endif
2020 | #if MYSQL_VERSION_ID >= 40101
2021 | rb_define_method(cMysql, "set_server_option", set_server_option, 1);
2022 | rb_define_method(cMysql, "sqlstate", sqlstate, 0);
2023 | #endif
2024 | rb_define_method(cMysql, "query_with_result", query_with_result, 0);
2025 | rb_define_method(cMysql, "query_with_result=", query_with_result_set, 1);
2026 |
2027 | rb_define_method(cMysql, "reconnect", reconnect, 0);
2028 | rb_define_method(cMysql, "reconnect=", reconnect_set, 1);
2029 |
2030 | /* Mysql constant */
2031 | rb_define_const(cMysql, "VERSION", INT2FIX(MYSQL_RUBY_VERSION));
2032 | #if MYSQL_VERSION_ID >= 32200
2033 | rb_define_const(cMysql, "OPT_CONNECT_TIMEOUT", INT2NUM(MYSQL_OPT_CONNECT_TIMEOUT));
2034 | rb_define_const(cMysql, "OPT_COMPRESS", INT2NUM(MYSQL_OPT_COMPRESS));
2035 | rb_define_const(cMysql, "OPT_NAMED_PIPE", INT2NUM(MYSQL_OPT_NAMED_PIPE));
2036 | rb_define_const(cMysql, "INIT_COMMAND", INT2NUM(MYSQL_INIT_COMMAND));
2037 | rb_define_const(cMysql, "READ_DEFAULT_FILE", INT2NUM(MYSQL_READ_DEFAULT_FILE));
2038 | rb_define_const(cMysql, "READ_DEFAULT_GROUP", INT2NUM(MYSQL_READ_DEFAULT_GROUP));
2039 | #endif
2040 | #if MYSQL_VERSION_ID >= 32349
2041 | rb_define_const(cMysql, "SET_CHARSET_DIR", INT2NUM(MYSQL_SET_CHARSET_DIR));
2042 | rb_define_const(cMysql, "SET_CHARSET_NAME", INT2NUM(MYSQL_SET_CHARSET_NAME));
2043 | rb_define_const(cMysql, "OPT_LOCAL_INFILE", INT2NUM(MYSQL_OPT_LOCAL_INFILE));
2044 | #endif
2045 | #if MYSQL_VERSION_ID >= 40100
2046 | rb_define_const(cMysql, "OPT_PROTOCOL", INT2NUM(MYSQL_OPT_PROTOCOL));
2047 | rb_define_const(cMysql, "SHARED_MEMORY_BASE_NAME", INT2NUM(MYSQL_SHARED_MEMORY_BASE_NAME));
2048 | #endif
2049 | #if MYSQL_VERSION_ID >= 40101
2050 | rb_define_const(cMysql, "OPT_READ_TIMEOUT", INT2NUM(MYSQL_OPT_READ_TIMEOUT));
2051 | rb_define_const(cMysql, "OPT_WRITE_TIMEOUT", INT2NUM(MYSQL_OPT_WRITE_TIMEOUT));
2052 | rb_define_const(cMysql, "SECURE_AUTH", INT2NUM(MYSQL_SECURE_AUTH));
2053 | rb_define_const(cMysql, "OPT_GUESS_CONNECTION", INT2NUM(MYSQL_OPT_GUESS_CONNECTION));
2054 | rb_define_const(cMysql, "OPT_USE_EMBEDDED_CONNECTION", INT2NUM(MYSQL_OPT_USE_EMBEDDED_CONNECTION));
2055 | rb_define_const(cMysql, "OPT_USE_REMOTE_CONNECTION", INT2NUM(MYSQL_OPT_USE_REMOTE_CONNECTION));
2056 | rb_define_const(cMysql, "SET_CLIENT_IP", INT2NUM(MYSQL_SET_CLIENT_IP));
2057 | #endif
2058 | rb_define_const(cMysql, "REFRESH_GRANT", INT2NUM(REFRESH_GRANT));
2059 | rb_define_const(cMysql, "REFRESH_LOG", INT2NUM(REFRESH_LOG));
2060 | rb_define_const(cMysql, "REFRESH_TABLES", INT2NUM(REFRESH_TABLES));
2061 | #ifdef REFRESH_HOSTS
2062 | rb_define_const(cMysql, "REFRESH_HOSTS", INT2NUM(REFRESH_HOSTS));
2063 | #endif
2064 | #ifdef REFRESH_STATUS
2065 | rb_define_const(cMysql, "REFRESH_STATUS", INT2NUM(REFRESH_STATUS));
2066 | #endif
2067 | #ifdef REFRESH_THREADS
2068 | rb_define_const(cMysql, "REFRESH_THREADS", INT2NUM(REFRESH_THREADS));
2069 | #endif
2070 | #ifdef REFRESH_SLAVE
2071 | rb_define_const(cMysql, "REFRESH_SLAVE", INT2NUM(REFRESH_SLAVE));
2072 | #endif
2073 | #ifdef REFRESH_MASTER
2074 | rb_define_const(cMysql, "REFRESH_MASTER", INT2NUM(REFRESH_MASTER));
2075 | #endif
2076 | #ifdef CLIENT_LONG_PASSWORD
2077 | #endif
2078 | #ifdef CLIENT_FOUND_ROWS
2079 | rb_define_const(cMysql, "CLIENT_FOUND_ROWS", INT2NUM(CLIENT_FOUND_ROWS));
2080 | #endif
2081 | #ifdef CLIENT_LONG_FLAG
2082 | #endif
2083 | #ifdef CLIENT_CONNECT_WITH_DB
2084 | #endif
2085 | #ifdef CLIENT_NO_SCHEMA
2086 | rb_define_const(cMysql, "CLIENT_NO_SCHEMA", INT2NUM(CLIENT_NO_SCHEMA));
2087 | #endif
2088 | #ifdef CLIENT_COMPRESS
2089 | rb_define_const(cMysql, "CLIENT_COMPRESS", INT2NUM(CLIENT_COMPRESS));
2090 | #endif
2091 | #ifdef CLIENT_ODBC
2092 | rb_define_const(cMysql, "CLIENT_ODBC", INT2NUM(CLIENT_ODBC));
2093 | #endif
2094 | #ifdef CLIENT_LOCAL_FILES
2095 | rb_define_const(cMysql, "CLIENT_LOCAL_FILES", INT2NUM(CLIENT_LOCAL_FILES));
2096 | #endif
2097 | #ifdef CLIENT_IGNORE_SPACE
2098 | rb_define_const(cMysql, "CLIENT_IGNORE_SPACE", INT2NUM(CLIENT_IGNORE_SPACE));
2099 | #endif
2100 | #ifdef CLIENT_CHANGE_USER
2101 | rb_define_const(cMysql, "CLIENT_CHANGE_USER", INT2NUM(CLIENT_CHANGE_USER));
2102 | #endif
2103 | #ifdef CLIENT_INTERACTIVE
2104 | rb_define_const(cMysql, "CLIENT_INTERACTIVE", INT2NUM(CLIENT_INTERACTIVE));
2105 | #endif
2106 | #ifdef CLIENT_SSL
2107 | rb_define_const(cMysql, "CLIENT_SSL", INT2NUM(CLIENT_SSL));
2108 | #endif
2109 | #ifdef CLIENT_IGNORE_SIGPIPE
2110 | rb_define_const(cMysql, "CLIENT_IGNORE_SIGPIPE", INT2NUM(CLIENT_IGNORE_SIGPIPE));
2111 | #endif
2112 | #ifdef CLIENT_TRANSACTIONS
2113 | rb_define_const(cMysql, "CLIENT_TRANSACTIONS", INT2NUM(CLIENT_TRANSACTIONS));
2114 | #endif
2115 | #ifdef CLIENT_MULTI_STATEMENTS
2116 | rb_define_const(cMysql, "CLIENT_MULTI_STATEMENTS", INT2NUM(CLIENT_MULTI_STATEMENTS));
2117 | #endif
2118 | #ifdef CLIENT_MULTI_RESULTS
2119 | rb_define_const(cMysql, "CLIENT_MULTI_RESULTS", INT2NUM(CLIENT_MULTI_RESULTS));
2120 | #endif
2121 | #if MYSQL_VERSION_ID >= 40101
2122 | rb_define_const(cMysql, "OPTION_MULTI_STATEMENTS_ON", INT2NUM(MYSQL_OPTION_MULTI_STATEMENTS_ON));
2123 | rb_define_const(cMysql, "OPTION_MULTI_STATEMENTS_OFF", INT2NUM(MYSQL_OPTION_MULTI_STATEMENTS_OFF));
2124 | #endif
2125 |
2126 | /* Mysql::Result object method */
2127 | rb_define_method(cMysqlRes, "data_seek", data_seek, 1);
2128 | rb_define_method(cMysqlRes, "fetch_field", fetch_field, 0);
2129 | rb_define_method(cMysqlRes, "fetch_fields", fetch_fields, 0);
2130 | rb_define_method(cMysqlRes, "fetch_field_direct", fetch_field_direct, 1);
2131 | rb_define_method(cMysqlRes, "fetch_lengths", fetch_lengths, 0);
2132 | rb_define_method(cMysqlRes, "fetch_row", fetch_row, 0);
2133 | rb_define_method(cMysqlRes, "fetch_hash", fetch_hash, -1);
2134 | rb_define_method(cMysqlRes, "field_seek", field_seek, 1);
2135 | rb_define_method(cMysqlRes, "field_tell", field_tell, 0);
2136 | rb_define_method(cMysqlRes, "free", res_free, 0);
2137 | rb_define_method(cMysqlRes, "num_fields", num_fields, 0);
2138 | rb_define_method(cMysqlRes, "num_rows", num_rows, 0);
2139 | rb_define_method(cMysqlRes, "row_seek", row_seek, 1);
2140 | rb_define_method(cMysqlRes, "row_tell", row_tell, 0);
2141 | rb_define_method(cMysqlRes, "each", each, 0);
2142 | rb_define_method(cMysqlRes, "each_hash", each_hash, -1);
2143 |
2144 | /* MysqlField object method */
2145 | rb_define_method(cMysqlField, "name", field_name, 0);
2146 | rb_define_method(cMysqlField, "table", field_table, 0);
2147 | rb_define_method(cMysqlField, "def", field_def, 0);
2148 | rb_define_method(cMysqlField, "type", field_type, 0);
2149 | rb_define_method(cMysqlField, "length", field_length, 0);
2150 | rb_define_method(cMysqlField, "max_length", field_max_length, 0);
2151 | rb_define_method(cMysqlField, "flags", field_flags, 0);
2152 | rb_define_method(cMysqlField, "decimals", field_decimals, 0);
2153 | rb_define_method(cMysqlField, "hash", field_hash, 0);
2154 | rb_define_method(cMysqlField, "inspect", field_inspect, 0);
2155 | #ifdef IS_NUM
2156 | rb_define_method(cMysqlField, "is_num?", field_is_num, 0);
2157 | #endif
2158 | #ifdef IS_NOT_NULL
2159 | rb_define_method(cMysqlField, "is_not_null?", field_is_not_null, 0);
2160 | #endif
2161 | #ifdef IS_PRI_KEY
2162 | rb_define_method(cMysqlField, "is_pri_key?", field_is_pri_key, 0);
2163 | #endif
2164 |
2165 | /* Mysql::Field constant: TYPE */
2166 | rb_define_const(cMysqlField, "TYPE_TINY", INT2NUM(FIELD_TYPE_TINY));
2167 | #if MYSQL_VERSION_ID >= 32115
2168 | rb_define_const(cMysqlField, "TYPE_ENUM", INT2NUM(FIELD_TYPE_ENUM));
2169 | #endif
2170 | rb_define_const(cMysqlField, "TYPE_DECIMAL", INT2NUM(FIELD_TYPE_DECIMAL));
2171 | rb_define_const(cMysqlField, "TYPE_SHORT", INT2NUM(FIELD_TYPE_SHORT));
2172 | rb_define_const(cMysqlField, "TYPE_LONG", INT2NUM(FIELD_TYPE_LONG));
2173 | rb_define_const(cMysqlField, "TYPE_FLOAT", INT2NUM(FIELD_TYPE_FLOAT));
2174 | rb_define_const(cMysqlField, "TYPE_DOUBLE", INT2NUM(FIELD_TYPE_DOUBLE));
2175 | rb_define_const(cMysqlField, "TYPE_NULL", INT2NUM(FIELD_TYPE_NULL));
2176 | rb_define_const(cMysqlField, "TYPE_TIMESTAMP", INT2NUM(FIELD_TYPE_TIMESTAMP));
2177 | rb_define_const(cMysqlField, "TYPE_LONGLONG", INT2NUM(FIELD_TYPE_LONGLONG));
2178 | rb_define_const(cMysqlField, "TYPE_INT24", INT2NUM(FIELD_TYPE_INT24));
2179 | rb_define_const(cMysqlField, "TYPE_DATE", INT2NUM(FIELD_TYPE_DATE));
2180 | rb_define_const(cMysqlField, "TYPE_TIME", INT2NUM(FIELD_TYPE_TIME));
2181 | rb_define_const(cMysqlField, "TYPE_DATETIME", INT2NUM(FIELD_TYPE_DATETIME));
2182 | #if MYSQL_VERSION_ID >= 32130
2183 | rb_define_const(cMysqlField, "TYPE_YEAR", INT2NUM(FIELD_TYPE_YEAR));
2184 | #endif
2185 | #if MYSQL_VERSION_ID >= 50003
2186 | rb_define_const(cMysqlField, "TYPE_BIT", INT2NUM(FIELD_TYPE_BIT));
2187 | rb_define_const(cMysqlField, "TYPE_NEWDECIMAL", INT2NUM(FIELD_TYPE_NEWDECIMAL));
2188 | #endif
2189 | rb_define_const(cMysqlField, "TYPE_SET", INT2NUM(FIELD_TYPE_SET));
2190 | rb_define_const(cMysqlField, "TYPE_BLOB", INT2NUM(FIELD_TYPE_BLOB));
2191 | rb_define_const(cMysqlField, "TYPE_STRING", INT2NUM(FIELD_TYPE_STRING));
2192 | #if MYSQL_VERSION_ID >= 40000
2193 | rb_define_const(cMysqlField, "TYPE_VAR_STRING", INT2NUM(FIELD_TYPE_VAR_STRING));
2194 | #endif
2195 | rb_define_const(cMysqlField, "TYPE_CHAR", INT2NUM(FIELD_TYPE_CHAR));
2196 |
2197 | /* Mysql::Field constant: FLAG */
2198 | rb_define_const(cMysqlField, "NOT_NULL_FLAG", INT2NUM(NOT_NULL_FLAG));
2199 | rb_define_const(cMysqlField, "PRI_KEY_FLAG", INT2NUM(PRI_KEY_FLAG));
2200 | rb_define_const(cMysqlField, "UNIQUE_KEY_FLAG", INT2NUM(UNIQUE_KEY_FLAG));
2201 | rb_define_const(cMysqlField, "MULTIPLE_KEY_FLAG", INT2NUM(MULTIPLE_KEY_FLAG));
2202 | rb_define_const(cMysqlField, "BLOB_FLAG", INT2NUM(BLOB_FLAG));
2203 | rb_define_const(cMysqlField, "UNSIGNED_FLAG", INT2NUM(UNSIGNED_FLAG));
2204 | rb_define_const(cMysqlField, "ZEROFILL_FLAG", INT2NUM(ZEROFILL_FLAG));
2205 | rb_define_const(cMysqlField, "BINARY_FLAG", INT2NUM(BINARY_FLAG));
2206 | #ifdef ENUM_FLAG
2207 | rb_define_const(cMysqlField, "ENUM_FLAG", INT2NUM(ENUM_FLAG));
2208 | #endif
2209 | #ifdef AUTO_INCREMENT_FLAG
2210 | rb_define_const(cMysqlField, "AUTO_INCREMENT_FLAG", INT2NUM(AUTO_INCREMENT_FLAG));
2211 | #endif
2212 | #ifdef TIMESTAMP_FLAG
2213 | rb_define_const(cMysqlField, "TIMESTAMP_FLAG", INT2NUM(TIMESTAMP_FLAG));
2214 | #endif
2215 | #ifdef SET_FLAG
2216 | rb_define_const(cMysqlField, "SET_FLAG", INT2NUM(SET_FLAG));
2217 | #endif
2218 | #ifdef NUM_FLAG
2219 | rb_define_const(cMysqlField, "NUM_FLAG", INT2NUM(NUM_FLAG));
2220 | #endif
2221 | #ifdef PART_KEY_FLAG
2222 | rb_define_const(cMysqlField, "PART_KEY_FLAG", INT2NUM(PART_KEY_FLAG));
2223 | #endif
2224 |
2225 | #if MYSQL_VERSION_ID >= 40102
2226 | /* Mysql::Stmt object method */
2227 | rb_define_method(cMysqlStmt, "affected_rows", stmt_affected_rows, 0);
2228 | #if 0
2229 | rb_define_method(cMysqlStmt, "attr_get", stmt_attr_get, 1);
2230 | rb_define_method(cMysqlStmt, "attr_set", stmt_attr_set, 2);
2231 | #endif
2232 | rb_define_method(cMysqlStmt, "bind_result", stmt_bind_result, -1);
2233 | rb_define_method(cMysqlStmt, "close", stmt_close, 0);
2234 | rb_define_method(cMysqlStmt, "data_seek", stmt_data_seek, 1);
2235 | rb_define_method(cMysqlStmt, "each", stmt_each, 0);
2236 | rb_define_method(cMysqlStmt, "execute", stmt_execute, -1);
2237 | rb_define_method(cMysqlStmt, "fetch", stmt_fetch, 0);
2238 | rb_define_method(cMysqlStmt, "field_count", stmt_field_count, 0);
2239 | rb_define_method(cMysqlStmt, "free_result", stmt_free_result, 0);
2240 | rb_define_method(cMysqlStmt, "insert_id", stmt_insert_id, 0);
2241 | rb_define_method(cMysqlStmt, "num_rows", stmt_num_rows, 0);
2242 | rb_define_method(cMysqlStmt, "param_count", stmt_param_count, 0);
2243 | rb_define_method(cMysqlStmt, "prepare", stmt_prepare, 1);
2244 | #if 0
2245 | rb_define_method(cMysqlStmt, "reset", stmt_reset, 0);
2246 | #endif
2247 | rb_define_method(cMysqlStmt, "result_metadata", stmt_result_metadata, 0);
2248 | rb_define_method(cMysqlStmt, "row_seek", stmt_row_seek, 1);
2249 | rb_define_method(cMysqlStmt, "row_tell", stmt_row_tell, 0);
2250 | #if 0
2251 | rb_define_method(cMysqlStmt, "send_long_data", stmt_send_long_data, 2);
2252 | #endif
2253 | rb_define_method(cMysqlStmt, "sqlstate", stmt_sqlstate, 0);
2254 |
2255 | #if 0
2256 | rb_define_const(cMysqlStmt, "ATTR_UPDATE_MAX_LENGTH", INT2NUM(STMT_ATTR_UPDATE_MAX_LENGTH));
2257 | #endif
2258 |
2259 | /* Mysql::Time object method */
2260 | rb_define_method(cMysqlTime, "initialize", time_initialize, -1);
2261 | rb_define_method(cMysqlTime, "inspect", time_inspect, 0);
2262 | rb_define_method(cMysqlTime, "to_s", time_to_s, 0);
2263 | rb_define_method(cMysqlTime, "year", time_get_year, 0);
2264 | rb_define_method(cMysqlTime, "month", time_get_month, 0);
2265 | rb_define_method(cMysqlTime, "day", time_get_day, 0);
2266 | rb_define_method(cMysqlTime, "hour", time_get_hour, 0);
2267 | rb_define_method(cMysqlTime, "minute", time_get_minute, 0);
2268 | rb_define_method(cMysqlTime, "second", time_get_second, 0);
2269 | rb_define_method(cMysqlTime, "neg", time_get_neg, 0);
2270 | rb_define_method(cMysqlTime, "second_part", time_get_second_part, 0);
2271 | rb_define_method(cMysqlTime, "year=", time_set_year, 1);
2272 | rb_define_method(cMysqlTime, "month=", time_set_month, 1);
2273 | rb_define_method(cMysqlTime, "day=", time_set_day, 1);
2274 | rb_define_method(cMysqlTime, "hour=", time_set_hour, 1);
2275 | rb_define_method(cMysqlTime, "minute=", time_set_minute, 1);
2276 | rb_define_method(cMysqlTime, "second=", time_set_second, 1);
2277 | rb_define_method(cMysqlTime, "neg=", time_set_neg, 1);
2278 | rb_define_method(cMysqlTime, "second_part=", time_set_second_part, 1);
2279 | rb_define_method(cMysqlTime, "==", time_equal, 1);
2280 |
2281 | #endif
2282 |
2283 | /* Mysql::Error object method */
2284 | rb_define_method(eMysql, "error", error_error, 0);
2285 | rb_define_method(eMysql, "errno", error_errno, 0);
2286 | rb_define_method(eMysql, "sqlstate", error_sqlstate, 0);
2287 |
2288 | /* Mysql::Error constant */
2289 | #define rb_define_mysql_const(s) rb_define_const(eMysql, #s, INT2NUM(s))
2290 | #include "error_const.h"
2291 | }
2292 |
--------------------------------------------------------------------------------