pax_global_header00006660000000000000000000000064116316676730014532gustar00rootroot0000000000000052 comment=68ec8d14e71bd0a14392b92565751e2fb8e57a6f ruby-mysql-2.8.2+gem2deb/000077500000000000000000000000001163166767300151705ustar00rootroot00000000000000ruby-mysql-2.8.2+gem2deb/COPYING000066400000000000000000000046751163166767300162370ustar00rootroot00000000000000Ruby is copyrighted free software by Yukihiro Matsumoto . You can redistribute it and/or modify it under either the terms of the GPL (see the file GPL), or the conditions below: 1. You may make and give away verbatim copies of the source form of the software without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may modify your copy of the software in any way, provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or by allowing the author to include your modifications in the software. b) use the modified software only within your corporation or organization. c) give non-standard binaries non-standard names, with instructions on where to get the original software distribution. d) make other distribution arrangements with the author. 3. You may distribute the software in object code or binary form, provided that you do at least ONE of the following: a) distribute the binaries and library files of the software, together with instructions (in the manual page or equivalent) on where to get the original distribution. b) accompany the distribution with the machine-readable source of the software. c) give non-standard binaries non-standard names, with instructions on where to get the original software distribution. d) make other distribution arrangements with the author. 4. You may modify and include the part of the software into any other software (possibly commercial). But some files in the distribution are not written by the author, so that they are not under these terms. For the list of those files and their copying conditions, see the file LEGAL. 5. The scripts and library files supplied as input to or produced as output from the software do not automatically fall under the copyright of the software, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this software. 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ruby-mysql-2.8.2+gem2deb/COPYING.ja000066400000000000000000000040551163166767300166200ustar00rootroot00000000000000$BK\%W%m%0%i%`$O%U%j!<%=%U%H%&%'%"$G$9!%(BGPL(the GNU General Public License)$B$^$?$O0J2<$K<($9>r7o$GK\%W%m%0%i%`$r:FG[I[$G(B $B$-$^$9!%(BGPL$B$K$D$$$F$O(BGPL$B%U%!%$%k$r;2>H$7$F2<$5$$!%(B 1. $BJ#@=$O@)8B$J$/<+M3$G$9!%(B 2. $B0J2<$N>r7o$N$$$:$l$+$rK~$?$9;~$KK\%W%m%0%i%`$N%=!<%9$r(B $B<+M3$KJQ99$G$-$^$9!%(B (a) $B%M%C%H%K%e!<%:$K%]%9%H$7$?$j!$:nA0$rJQ99$9$k!%(B $B$=$N%=%U%H%&%'%"$rG[I[$9$k;~$K$OJQ99A0$NK\%W%m%0%i(B $B%`$bF1;~$KG[I[$9$k!%$^$?$OJQ99A0$NK\%W%m%0%i%`$N%=!<(B $B%9$NF~$NJQ99>r7o$r:nr7o$N$$$:$l$+$rK~$?$9;~$KK\%W%m%0%i%`$r%3%s%Q%$(B $B%k$7$?%*%V%8%'%/%H%3!<%I$dA0$rJQ99$7$?$&$(!$%*%j%8%J(B $B%k$N%=!<%9%3!<%I$NF~$NG[I[>r7o$r:n$N%W%m%0%i%`$X$N0zMQ$O$$$+$J$kL\E*$G$"$l<+M3$G$9!%$?(B $B$@$7!$K\%W%m%0%i%`$K4^$^$l$kB>$N:n$l$N:nl9g$,$"$j$^$9!%(B $B$=$l$i%U%!%$%k$N0lMw$H$=$l$>$l$NG[I[>r7o$J$I$KIU$$$F$O(B LEGAL$B%U%!%$%k$r;2>H$7$F$/$@$5$$!%(B 5. $BK\%W%m%0%i%`$X$NF~NO$H$J$k%9%/%j%W%H$*$h$S!$K\%W%m%0%i(B $B%`$+$i$N=PNO$N8"Mx$OK\%W%m%0%i%`$N:n(B $B$l$NF~=PNO$r@8@.$7$??M$KB0$7$^$9!%$^$?!$K\%W%m%0%i%`$K(B $BAH$_9~$^$l$k$?$a$N3HD%%i%$%V%i%j$K$D$$$F$bF1MM$G$9!%(B 6. $BK\%W%m%0%i%`$OL5J]>Z$G$9!%:n MySQL/Ruby

MySQL/Ruby

[Japanese]


This is the MySQL API module for Ruby. It provides the same functions for Ruby programs that the MySQL C API provides for C programs.

Download

Requirement

  • MySQL 5.0.67
  • Ruby 1.8.7, 1.9.1

The module may work for other versions, but that has not been verified.

License

This program is under Ruby's license.

Install

1st:

% ruby extconf.rb

or

% ruby extconf.rb --with-mysql-dir=/usr/local/mysql

or

% ruby extconf.rb --with-mysql-config

then

% make

extconf.rb has following options:

--with-mysql-include=dir
MySQL header file directory. Default is /usr/local/include.
--with-mysql-lib=dir
MySQL library directory. Default is /usr/local/lib.
--with-mysql-dir=dir
Same as --with-mysql-include=dir/include, --with-mysql-lib=dir/lib.
--with-mysql-config[=/path/to/mysql_config]
Get compile-parameter from mysql_config command.

2nd:

% ruby ./test.rb -- [hostname [user [passwd [dbname [port [socket [flag]]]]]]]

3rd:

# make install

Note

If you get error like 'libmysqlclient not found' when testing, you need to specify the directory in which the library is located so that make can find it.

% env LD_RUN_PATH=libmysqlclient.so directory make

test.rb is tested on Linux only.

Usage

The names of methods provided by this module basically are the same as the names of the functions in the C API, except that the Ruby method names do not begin with a 'mysql_' prefix. For example, the Ruby query() method corresponds to the C API mysql_query() function. For details on the use of each Ruby method, see the descriptions of the corresponding C functions in the MySQL Reference Manual.

Some Ruby methods may be invoked under other names that serve as equivalent aliases, as noted below.

If an error occurs when a method executes, it raises a Mysql::Error exception.

Mysql class

CLASS METHODS

init()

It return Mysql object. It not connect to mysqld.

real_connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil)
connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil)
new(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil)

connect to mysqld and return Mysql object.

escape_string(str)
quote(str)

quote string for insert/update.

get_client_info()
client_info()

return client version information.

get_client_version()
client_version()

return client version as number.

debug(str)

same as C API mysql_debug().

OBJECT METHODS

options(opt, val=nil)

same as C API mysql_options().

real_connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil)
connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil)

same as Mysql.real_connect().

affected_rows()

return affected rows.

autocommit(mode)

set autocommit mode.

change_user(user=nil, passwd=nil, db=nil)

change user.

character_set_name()

return character set.

close()

close connection.

commit()

commit transaction.

create_db(db)

create database.

drop_db(db)

drop database.

dump_debug_info()

same as C API mysql_dump_debug_info().

errno()

return error number.

error()

return error message.

escape_string(str)
quote(str)

quote strings for insert/update. same as C API mysql_real_escape_string().

field_count()

return number of columns of last query.

get_client_info()
client_info()

return client version information.

get_client_version()
client_version()

return client version number.

get_host_info()
host_info()

return connection information.

get_proto_info()
proto_info()

return connection protocol version.

get_server_info()
server_info()

return server version information.

get_server_version()
server_version()

return server version number.

info()

return information of last query.

insert_id()

return last AUTO_INCREMENT value.

kill(id)

kill thread.

list_dbs(db=nil)

return database list.

list_fields(table, field=nil)

return Mysql::Result object.

list_processes()

return Mysql::Result object.

list_tables(table=nil)

return table list Array.

more_results?()

returns true if more results exist from the currently executed query.

next_result()

returns true if more results exist from the currently executed query. after this, you do store_result() to get result table of query.

ping()

check server.

prepare(q)

query(q)
real_query(q)

do query and store_result(). return Mysql::Result object. If query_with_result is false, it does not store_result().

query(q) {|res| ...}
real_query(q) {|res| ...}

do query and execute block with Mysql::Result object. Mysql::Result object is freed when exiting block. If multiple statement mode, it does repeat block each query.

Since MySQL/Ruby 2.8, it no longer turn on multiple statement mode automatically. 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).

refresh(r)

flush server log or cache.

reload()

reload access privilege table.

rollback()

rollback transaction.

select_db(db)

select database.

set_server_option(opt)

set option to server. options is one of Mysql::OPTION_MULTI_STATEMENTS_ON, Mysql::OPTION_MULTI_STATEMENTS_OFF.

shutdown()

shutdown server.

ssl_set(key=nil, cert=nil, ca=nil, capath=nil, cipher=nil)

use SSL.

stat()

return server status.

stmt_init()

return Mysql::Stmt class object.

store_result()

return Mysql::Result object.

thread_id()

retrun thread id.

use_result()

return Mysql::Result object.

warning_count()

return warning count last query.

OBJECT VARIABLES

query_with_result

If true, query() also invokes store_result() and returns a Mysql::Result object. Default is true.

reconnect

If true, reconnect to server automatically when disconect to server. Default is false.

Mysql::Result class

OBJECT METHODS

free()

free memory of result table.

data_seek(offset)

seek row.

fetch_field()

return next Mysql::Field object.

fetch_fields()

return Array of Mysql::Field object.

fetch_field_direct(fieldnr)

return Mysql::Field object.

fetch_lengths()

return Array of field length.

fetch_row()

return row as Array.

fetch_hash(with_table=false)

return row as Hash. If with_table is true, hash key format is "tablename.fieldname".

field_seek(offset)

seek field.

field_tell()

return field position.

num_fields()

return number of fields.

num_rows()

return number of rows.

row_seek(offset)

seek row.

row_tell()

return row position.

ITERATOR

each() {|x| ...}

'x' is array of column values.

each_hash(with_table=false) {|x| ...}

'x' is hash of column values, and the keys are the column names.

Mysql::Field class

OBJECT VARIABLES(read only)

name
field name
table
table name
def
default value
type
field type
length
field length
max_length
max field length
flags
field flag
decimals
number of decimals

OBJECT METHODS

hash()

return field as Hash.

ex.) obj.name == obj.hash['name']

is_not_null?()

True if this field is defined as NOT NULL.

is_num?()

True if this field type is numeric.

is_pri_key?()

True if this field is a primary key.

inspect()

return "#<Mysql::Field:fieldname>"

Mysql::Stmt class

Example:

my = Mysql.new(hostname, username, password, databasename)
st = my.prepare("insert into tblname (col1,col2,col3) values (?,?,?)")
st.execute("abc",123,Time.now)
st.prepare("select col1,col2,col3 from tblname")
st.execute
st.fetch  # => ["abc", 123, #<Mysql::Time:2005-07-24 23:52:55>]
st.close

OBJECT METHODS

affected_rows()

bind_result(class, ...)

close()

data_seek(offset)

execute(arg, ...)

fetch()

Type mapping:

MySQL typeRuby class
TINYINT, SMALLINT, MEDIUMINT, YEARFixnum
INT, BIGINTFixnum or Bignum
FLOAT, DOUBLEFloat
DECIMALString
DATE, DATETIME, TIMESTAMP, TIMEMysql::Time
CHAR, VARCHAR, BINARY, VARBINARY, TINYBLOB, TINYTEXT, TINYBLOB, TINYTEXT, MEDIUMBLOB, MEDIUMTEXT, LONGBLOB, LONGTEXT, ENUM, SET, BITString
NULLNilClass
field_count()

free_result()

insert_id()

num_rows()

param_count()

prepare(q)

result_metadata()

row_seek(offset)

row_tell()

sqlstate()

ITERATOR

each() {|x| ...}

Mysql::Time class

CLASS METHODS

new(year=0,month=0,day=0,hour=0,minute=0,second=0,neg=false,second_part=0)

OBJECT VARIABLES

year
month
day
hour
minute
second
neg
second_part

Mysql::Error class

OBJECT VARIABLES(read only)

error
eror message
errno
error number

History

2010-02-11
version 2.8.2
  • Fix: Mysql#insert_id returns invalid value when larger than 2**32.
2009-02-01
version 2.8.1
  • correspond to Ruby 1.9.1
2008-09-29
version 2.8
version 2.7.7
  • When connecting to MySQL, EINTR is occurred sometimes ([ruby-dev:31842])
  • MySQL/Ruby 2.7.* can not be compiled on Ruby 1.8.5.
2008-06-20
version 2.8pre4
  • [ruby-dev:35152]
2008-06-17
version 2.8pre3
version 2.7.6
  • On 64bit machine, Mysql::Stmt#execute raise error on large numeric value(>= 2**30).
2008-03-08
version 2.8pre2
version 2.7.5
  • On 64bit machine, Mysql::Stmt#fetch return invalid numeric value.
2007-12-26
version 2.8pre1
  • for Ruby 1.9.0
  • Incompat: Mysql::Result#each_hash don't create column name string each row. it's shared.
  • Incompat: Mysql#query with block no longer turn on multi-statements mode automatically.
2007-08-22
version 2.7.4
  • BUG: Mysql::Stmt#execute memory leak.
2006-12-20
version 2.7.3
  • BUG: Mysql#query with block is stopped when last query failed.
2006-10-28
version 2.7.2
  • BUG: Mysql::Stmt#result_metadata don't return nil. (Thanks to Hidetoshi)
  • BUG: Mysql#close check mysql_errno.
  • BUG: multistatement Mysql#query with block ignore error.
  • extconf.rb for Visual C++. (Thanks to Shugo Maeda)
  • support MySQL BIT type.
  • add Mysql::Field::TYPE_BIT, TYPE_NEWDECIMAL.
2006-06-04
version 2.7.1
  • change free() to xfree(). To avoid crash on Windows. (Thanks Tobias Grimm)
2005-08-22
version 2.7
  • add constants for Mysql#options: Mysql::OPT_GUESS_CONNECTION, Mysql::OPT_USE_EMBEDDED_CONNECTION, Mysql::OPT_USE_REMOTE_CONNECTION, Mysql::SET_CLIENT_IP
  • test.rb: for 4.0.x, 5.0.x
2005-08-16
version 2.7-beta3
  • add Mysql::Stmt#bind_result
2005-08-02
version 2.7-beta2
  • BUG: mysql.c.in: fetch_hash: nil value doesn't exist in hash. (Thanks Stefan Kaes)
  • add constant Mysql::VERSION.
  • add Mysql#prepare
2005-07-24
version 2.7-beta
  • add Mysql#stmt_init method
  • add Mysql::Stmt, Mysql::Time, Mysql::RowOffset class
  • add Mysql::Error#sqlstate method
  • change offset value to Mysql::RowOffset object that is used by Mysql::Result#row_seek,row_tell
2005-07-31
version 2.6.3
  • add constant Mysql::VERSION.
2005-07-26
version 2.6.2
  • BUG: mysql.c.in: fetch_hash: nil value doesn't exist in hash. (Thanks Stefan Kaes)
2005-06-28
version 2.6.1
  • mysql.c.in: fix to compile error on MacOSX.
2005-04-25
version 2.6
  • add constants for Mysql#option(): Mysql::OPT_PROTOCOL, Mysql::OPT_READ_TIMEOUT, Mysql::OPT_WRITE_TIMEOUT, Mysql::SET_CHARSET_DIR, Mysql::SET_CHARSET_NAME, Mysql::SHARED_MEMORY_BASE_NAME, Mysql::SECURE_AUTH
  • add methods: Mysql#more_results?(), Mysql#next_result(), Mysql#set_server_option(), Mysql#sqlstate()
  • add constants for Mysql#connect(): Mysql::CLIENT_MULTI_STATEMENTS, Mysql::CLIENT_MULTI_RESULTS
  • add constants for Mysql#set_server_option(): Mysql::OPTION_MULTI_STATEMENTS_ON, Mysql::OPTION_MULTI_STATEMENTS_OFF
  • add Mysql#query() with block
  • add Mysql#reconnect(), Mysql#reconnect=()
  • When connection was closed, it don't try to reconnect by default.
2005-02-12
version 2.5.2
  • BUG: Mysql#connect make object to not close. (Thanks Andres Salomon)
2004-09-20
version 2.5.1
  • add Mysql#set_ssl().
2004-08-31
version 2.5
  • correspond to MySQL 4.1.x.
  • change MysqlRes, MysqlField, MysqlError to Mysql::Result, Mysql::Field, Mysql::Error.
  • add Mysql.client_version(), Mysql.get_client_version(), Mysql#client_version(), Mysql#get_client_version(), Mysql#server_version(), Mysql#get_server_version(), Mysql#warning_count(), Mysql#commit(), Mysql#rollback(), Mysql#autocommit().
  • add Mysql::Field#is_not_null?(), Mysql::Field#is_pri_key?(), Mysql::Field#is_num?().
  • add MysqlField::TYPE_VAR_STRING.
2003-08-10
version 2.4.5
  • extconf.rb: correspond to MySQL 4.1.
  • mysql.c.in: correspond to Ruby 1.8.
2003-02-23
version 2.4.4a
  • make extconf.rb to correspond to Ruby 1.8.0
2003-01-29
version 2.4.4
  • add Mysql::OPT_LOCAL_INFILE.
  • add --with-mysql-config option to extconf.rb.
  • extconf.rb automatically detect typical library.
2003-01-05
version 2.4.3c
  • modified English README. Thanks to Paul DuBois.
2002-12-24
version 2.4.3b
  • make extconf.rb to correspond to Ruby 1.6.8.
2002-11-07
version 2.4.3a
  • fix bug duplicating constant.
2002-09-10
version 2.4.3
  • for error number with prefix ER_ .
  • get error constant from errmsg.h and mysqld_error.h automatically.
2002-01-07
version 2.4.2
  • for MySQL 4.0.
  • change `uint' to `unsigned int' (for mswin).
2001-12-02
version 2.4.1
  • remove `extern' (for Cygiwn).
  • change option of extconf.rb.
2001-10-12
version 2.4.0
  • for Ruby 1.7.
  • add Mysql::debug(), Mysql#change_user(), Mysql#character_set_name(), Mysql#dump_debug_info().

Author

e-mail: TOMITA Masahiro tommy@tmtm.org http://tmtm.org


TOMITA Masahiro
Last modified: Sun Feb 1 17:48:41 JST 2009 ruby-mysql-2.8.2+gem2deb/README_ja.html000066400000000000000000000710411163166767300174700ustar00rootroot00000000000000 MySQL/Ruby

MySQL/Ruby

[English]


これは MySQL の Ruby API です。MySQL の C API とほぼ同等の機能があります。

ダウンロード

必要なもの

  • MySQL 5.0.67
  • Ruby 1.8.7, 1.9.1

これら以外でも make できるかもしれませんが、確認してません。

ライセンス

このプログラムは Ruby ライセンス に従います。

インストール

次を実行してください。

% ruby extconf.rb

または

% ruby extconf.rb --with-mysql-dir=/usr/local/mysql

または

% ruby extconf.rb --with-mysql-config

それから

% make

extconf.rb には次のオプションを指定できます。

--with-mysql-include=dir
MySQL のへッダファイルの場所として /usr/local/include の代わりのディレクトリを指定します。
--with-mysql-lib=dir
MySQL のライブラリの場所として /usr/local/lib の代わりのディレクトリを指定します。
--with-mysql-dir=dir
--with-mysql-include=dir/include, --with-mysql-lib=dir/lib と同じです。
--with-mysql-config[=/path/to/mysql_config]
mysql_config コマンドの結果からコンパイルパラメータを得ます。

次で簡単なテストができます。

% ruby ./test.rb -- [hostname [user [passwd [dbname [port [socket [flag]]]]]]]

test.rb に与える引数は Mysql.real_connect() の引数と同じです。

問題なければ、スーパーユーザでインストールしてください。

# make install

注意

テスト時にライブラリ libmysqlclient が見つからないというエラーが出る場合は、make 時にライブラリの場所を指定する必要があります。次のようにして make してみてください。

% env LD_RUN_PATH=libmysqlclient.soの場所 make

test.rb は Linux 上での動作しか確認していません。 他のプラットフォームではエラーが出るかもしれません。

使い方

メソッド名は C API の関数から mysql_ 接頭辞を除いたものと同じです。メソッドの使用方法も基本的に対応する C API 関数と同様ですので、詳細は MySQL のマニュアルを見てください。

メソッド中でエラーが発生した場合は Mysql::Error 例外が発生します。

特に意味のある値を返さない関数は self を返します。

Mysql クラス

MySQL を操作するためのクラスです。

クラスメソッド

init()

Mysql クラスオブジェクトを返します。mysqld に接続はしません。 Mysql#options() が必要な場合は、これを呼んだ後に行ないます。

real_connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil)
connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil)
new(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil)

mysqld に接続し、Mysql クラスオブジェクトを返します。 flag の定数は C API のものと同じです。

例) Mysql::CLIENT_FOUND_ROWS

escape_string(str)
quote(str)

insert, update 用に文字列をクオートします。

get_client_info()
client_info()

クライアントバージョン情報の文字列を返します。

get_client_version()
client_version()

クライアントバージョン情報を数値で返します。

debug(str)

C API mysql_debug() と同じ。

オブジェクトメソッド

options(opt, val=nil)

C API の mysql_options() と同じです。 opt に指定する定数は C API から MYSQL_ 接頭辞を取り除いたものです。

例) Mysql::OPT_CONNECT_TIMEOUT

real_connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil)
connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil)

Mysql.real_connect() と同じです。Mysql.init() で生成したオブジェクトをサーバに接続するために使用します。

affected_rows()

影響された行数を返します。

autocommit(mode)

autocommit モードを mode に設定します。mode が nil, false, 0 の時はオフ、それ以外の場合はオンです。

change_user(user=nil, passwd=nil, db=nil)

接続ユーザを変更します。

character_set_name()

現在の文字セットを返します。

close()

接続を切断します。

commit()

トランザクションをコミットします。

create_db(db)

データベースを作成します。

drop_db(db)

データベースを破棄します。

dump_debug_info()

C API mysql_dump_debug_info() と同じ。

errno()

エラー番号を返します。

error()

エラーメッセージを返します。

escape_string(str)
quote(str)

insert, update 用に文字列をクオートします。 C API の mysql_real_escape_string() と同じ。

field_count()

最後に実行されたクエリの項目数を返します。

get_client_info()
client_info()

クライアントバージョン情報の文字列を返します。

get_client_version()
client_version()

クライアントバージョン情報を数値で返します。

get_host_info()
host_info()

接続情報を文字列で返します。

get_proto_info()
proto_info()

接続プロトコルバージョンを数値で返します。

get_server_info()
server_info()

サーバのバージョン情報を文字列で返します。

get_server_version()
server_version()

サーバのバージョン情報を数値で返します。

info()

直前のクエリの情報を文字列で返します。特に情報がなければ nil が返ります。

insert_id()

最後に生成された AUTO_INCREMENT 項目の値を返します。

kill(id)

id で指定したスレッドを殺します。

list_dbs(db=nil)

データベースの一覧を配列で返します。

list_fields(table, field=nil)

テーブル内の項目情報の一覧を示す Mysql::Result クラスオブジェクトを返します。

list_processes()

サーバ上の現在のスレッドの一覧を示す Mysql::Result クラスオブジェクトを返します。

list_tables(table=nil)

テーブルの一覧を配列で返します。

more_results?()

取得していないクエリ結果がある場合は真を返します。

next_result()

取得していないクエリ結果がある場合は真を返します。 この後に store_result() を実行するとクエリ結果を取得できます。

ping()

サーバが生きているかどうかをチェックします。

prepare(q)

クエリをサーバに送ります。この時点ではまだ実行されません。 Mysql::Stmt クラスオブジェクトを返します。

Mysql#stmt_init.prepare(q) と同じです。

query(q)
real_query(q)

クエリを実行します。 クエリが結果を返す場合、自動的に store_result() も実行して、Mysql::Result クラスオブジェクトを返します。 query_with_result に false が設定されていれば、store_result() は実行しません。

query(q) {|res| ...}
real_query(q) {|res| ...}

クエリを実行します。 クエリが結果を返す場合、Mysql::Result オブジェクトを引数としてブロックを実行します。 ブロック終了時に Mysql::Result オブジェクトは解放されます。 マルチステートメントモードで、引数に「;」で区切られた複数のクエリを指定した場合は、クエリの数だけブロックを繰り返します。

MySQL/Ruby 2.8 からは、自動的にマルチステートメントモードにはならなくなりました。 Mysql.connect の flag に Mysql::CLIENT_MULTI_STATEMENTS を指定するか、Mysql#set_server_option(Mysql::OPTION_MULTI_STATEMENTS_ON) を実行してください。

refresh(r)

サーバのログやキャッシュ等をフラッシュします。

reload()

アクセス権テーブルを再読み込みします。

rollback()

トランザクションをロールバックします。

select_db(db)

データベースを選択します。

set_server_option(opt)

引数で指定したオプションをサーバに設定します。 引数には、Mysql::OPTION_MULTI_STATEMENTS_ON, Mysql::OPTION_MULTI_STATEMENTS_OFF が指定できます。

shutdown()

サーバを停止します。

ssl_set(key=nil, cert=nil, ca=nil, capath=nil, cipher=nil)

SSL接続を使用します。Mysql.init() 後、Mysql#connect() 前に行なう必要があります。

stat()

サーバの状態を文字列で返します。

stmt_init()

Mysql::Stmt クラスオブジェクトを返します。

store_result()

クエリの結果の Mysql::Result クラスオブジェクトを返します。

thread_id()

現在の接続のスレッドIDを返します。

use_result()

クエリの結果の Mysql::Result クラスオブジェクトを返します。

warning_count()

直前のクエリの警告数を返します。

オブジェクト変数

query_with_result

true に設定すると query() 時に store_result() も実行して、Mysql::Result クラスオブジェクトを返します。 false に設定するとその動作は行われません。デフォルトは true です。

reconnect

true に設定すると MySQL サーバとの接続が切れたときに自動的に再接続します。 デフォルトは false です。

Mysql::Result クラス

クエリ結果のクラスです。

オブジェクトメソッド

free()

結果テーブル用メモリを解放します。

data_seek(offset)

現在の行の位置を offset 番目の行にします。

fetch_field()

現在の項目の Mysql::Field クラスオブジェクトを返します。 次に呼ばれた時は次の項目を返します。

fetch_fields()

項目全体を表す Mysql::Field クラスオブジェクトの配列を返します。

fetch_field_direct(fieldnr)

fieldnr 番目の項目の Mysql::Field クラスオブジェクトを返します。

fetch_lengths()

現在の行の各項目値の長さの配列を返します。

fetch_row()

検索結果の1行を返します。次に呼ばれた時は次の行を返します。 戻り値は項目値の配列です。

fetch_hash(with_table=false)

検索結果の1行を返します。次に呼ばれた時は次の行を返します。 戻り値は項目名をキーとした項目値のハッシュです。 with_table が true の場合はキーにテーブル名も付加され、"テーブル名.項目名" という形式のキーになります。

field_seek(offset)

現在の項目位置を offset 番目の項目にします。

field_tell()

現在の項目の位置を返します。

num_fields()

項目数を返します。

num_rows()

検索件数を返します。

row_seek(offset)

現在の行の位置を設定します。 offset は内部表現で row_tell() が返した Mysql::RowOffset クラスオブジェクトです。

row_tell()

現在の行の位置を Mysql::RowOffset クラスオブジェクトで返します。

イテレータ

each() {|x| 〜}

検索結果の各行ごとに {〜} を繰り返します。x は項目値の配列です。

each_hash(with_table=false) {|x| 〜}

検索結果の各行ごとに {〜} を繰り返します。 x は項目名をキーとした項目値のハッシュです。 with_table が true の場合はキーにテーブル名も付加され、"テーブル名.項目名" という形式のキーになります。

Mysql::Field クラス

項目の詳細を表すクラスです。C API と異なり、オブジェクトは Mysql::Result とは独立して存在するので、Mysql::Result クラスオブジェクトが解放された後でも利用できます。が、そのため C API よりもメモリを使用します。

オブジェクト変数(読み出しのみ)

name
項目名
table
テーブル名
def
デフォルト値
type
項目の型
length
項目の長さ
max_length
検索結果中の項目値の最大長
flags
フラグ
decimals
小数部桁数

type に対応する定数は C API のものから FIELD_ 接頭辞を除いたものです。

例) Mysql::Field::TYPE_STRING

flag に対応する定数は C API のものと同じです。

例) Mysql::Field::BLOB_FLAG

オブジェクトメソッド

hash()

上記の変数名をキーとするハッシュを返します。

例) obj.name == obj.hash['name']

is_not_null?()

フィールドが "NOT NULL" と定義されていれば真を返します。

is_num?()

フィールドが数値の場合は真を返します。

is_pri_key?()

フィールドがプライマリキーの場合は真を返します。

inspect()

文字列 "#<Mysql::Field:項目名>" を返します。

Mysql::Stmt クラス

MySQL でプリペアドステートメントを扱うためのクラスです。

使用例:

my = Mysql.new(hostname, username, password, databasename)
st = my.prepare("insert into tblname (col1,col2,col3) values (?,?,?)")
st.execute("abc",123,Time.now)
st.prepare("select col1,col2,col3 from tblname")
st.execute
st.fetch  # => ["abc", 123, #<Mysql::Time:2005-07-24 23:52:55>]
st.close

オブジェクトメソッド

affected_rows()

影響された行数を返します。

bind_result(class, ...)

結果を返すクエリの場合に、取り出される値のクラスを指定します。 指定できるクラスは、Numeric, Integer, Fixnum, Float, Mysql::Time です。 nil を指定すると、自動判別します。 bind_result を実行しない場合は自動判別します。

close()

Mysql::Stmt オブジェクトを解放します。

data_seek(offset)

次に fetch() で取り出される行を offset 番目の行にします。 offset は 0 から始まります。

execute(arg, ...)

prepare() したクエリにパラメータを与えて実行します。

fetch()

execute() で実行したクエリの結果の値を配列で取り出します。 値を返さないクエリの場合や、最後まで取り出した場合は nil を返します。

配列の各要素は MySQL の型に応じて次のようになります。

MySQLの型Rubyのクラス
TINYINT, SMALLINT, MEDIUMINT, YEARFixnum
INT, BIGINTFixnumまたはBignum
FLOAT, DOUBLEFloat
DECIMALString
DATE, DATETIME, TIMESTAMP, TIMEMysql::Time
CHAR, VARCHAR, BINARY, VARBINARY, TINYBLOB, TINYTEXT, TINYBLOB, TINYTEXT, MEDIUMBLOB, MEDIUMTEXT, LONGBLOB, LONGTEXT, ENUM, SET, BITString
NULLNilClass
field_count()

prepare したクエリが返す結果のフィールド数を返します。

free_result()

検索結果を解放します。

insert_id()

生成された AUTO_INCREMENT 項目の値を返します。

num_rows()

検索結果の行数を返します。

param_count()

prepare() したクエリのパラメータ「?」の数を返します。

prepare(q)

クエリをサーバに送ります。この時点ではまだ実行されません。 execute() で実行されます。

result_metadata()

prepare() したクエリの返される結果のフィールドを Mysql::Result クラスオブジェクトで返します。

row_seek(offset)

次に fetch() で取り出される行を offset の位置にします。 data_seek と異なり offset は row_tell() で返される Mysql::RowOffset クラスオブジェクトです。

row_tell()

現在の行の位置を Mysql::RowOffset クラスオブジェクトで返します。

sqlstate()

エラーコードを SQLSTATE 文字列で返します。

イテレータ

each() {|x| 〜}

検索結果の各行ごとに {〜} を繰り返します。 x は fetch() で返されるものと同じ配列です。

Mysql::Time クラス

Mysql::Stmt で使われる日時を表すためのクラスです。

クラスメソッド

new(year=0,month=0,day=0,hour=0,minute=0,second=0,neg=false,second_part=0)

Mysql::Timeクラスを作成します。

オブジェクト変数

year
month
day
hour
minute
second
neg
時刻が正の場合は false, 負の場合は true
second_part
秒の小数点以下。未使用

Mysql::Error クラス

MySQL のエラーを表わすクラスです。 MySQL のエラーが発生した場合に例外として生成されます。

オブジェクト変数(読み出しのみ)

error
エラーメッセージ
errno
エラー番号

errno に対応する定数は C API のものと同じです。

例) Mysql::Error::CR_UNKNOWN_HOST

履歴

2010-02-11
version 2.8.2
  • Fix: Mysql#insert_id が 2**32 以上の時に不正な値を返す。
2009-02-01
version 2.8.1
  • Ruby 1.9.1 に対応。
2008-09-29
version 2.8
version 2.7.7
  • MySQLへの接続時に SIGVTALRM で EINTR になることがある問題を修正 ([ruby-dev:31842])
  • MySQL/Ruby 2.7.* が Ruby 1.8.5 でコンパイルできなかった。
2008-06-20
version 2.8pre4
  • エラー定義ファイルを外だし。その他。[ruby-dev:35152]
2008-06-17
version 2.8pre3
version 2.7.6
  • 64bit 環境で Mysql::Stmt#execute で大きな数値(2**30 以上)でエラーになる問題を修正。
2008-03-08
version 2.8pre2
version 2.7.5
  • 64bit 環境で Mysql::Stmt#fetch で数値が壊れる問題を修正。
2007-12-26
version 2.8pre1
  • Ruby 1.9.0 対応
  • Incompat: Mysql::Result#each_hash が行毎にカラム名文字列を生成するのではなく、共有するようにした。
  • Incompat: ブロックつき Mysql#query で自動的にマルチステートメントモードにならないようにした。
2007-08-22
version 2.7.4
  • BUG: Mysql::Stmt#execute がメモリリークしていた。
2006-12-20
version 2.7.3
  • BUG: ブロックつき Mysql#query が、最後のクエリがエラーの場合に停止してしまう。
2006-10-28
version 2.7.2
  • BUG: 結果を返さないクエリで Mysql::Stmt#result_metadata が nil を変えすようにした (Thanks to Hidetoshi)
  • BUG: Mysql#close で mysql_errno を見ないように変更
  • BUG: ブロックつき Mysql#query で複数ステートメント時にエラーを無視していた。
  • extconf.rb の Visual C++ 対応 (Thanks to Shugo Maeda)
  • BIT型に対応
  • Mysql::Field に TYPE_BIT, TYPE_NEWDECIMAL 追加
2006-06-04
version 2.7.1
  • free() を xfree() に変更。Windows でのクラッシュの回避のため。(Tobias Grimm に感謝)
2005-08-22
version 2.7
  • Mysql#options用定数追加。Mysql::OPT_GUESS_CONNECTION, Mysql::OPT_USE_EMBEDDED_CONNECTION, Mysql::OPT_USE_REMOTE_CONNECTION, Mysql::SET_CLIENT_IP
  • test.rb: 4.0.x, 5.0.x 対応
2005-08-16
version 2.7-beta3
  • Mysql::Stmt#bind_result 追加
2005-08-02
version 2.7-beta2
  • BUG: mysql.c.in: fetch_hash: 値が nil の要素がハッシュに含まれない。(Stefan Kaes に感謝)
  • 定数 Mysql::VERSION 追加
  • Mysql#prepare 追加
2005-07-24
version 2.7-beta
  • Mysql#stmt_init 追加
  • Mysql::Stmt, Mysql::Time, Mysql::RowOffset クラス追加
  • Mysql::Error#sqlstate 追加
  • Mysql::Result#row_seek,row_tell が扱う offset 値を Mysql::RowOffset オブジェクトに変更
2005-07-31
version 2.6.3
  • 定数 Mysql::VERSION 追加
2005-07-26
version 2.6.2
  • BUG: mysql.c.in: fetch_hash: 値が nil の要素がハッシュに含まれない。(Stefan Kaes に感謝)
2005-06-28
version 2.6.1
  • mysql.c.in: MacOSX でのコンパイルエラーを修正。
2005-04-25
version 2.6
  • Mysql#option() 用の定数追加 Mysql::OPT_PROTOCOL, Mysql::OPT_READ_TIMEOUT, Mysql::OPT_WRITE_TIMEOUT, Mysql::SET_CHARSET_DIR, Mysql::SET_CHARSET_NAME, Mysql::SHARED_MEMORY_BASE_NAME, Mysql::SECURE_AUTH
  • Mysql#more_results?(), Mysql#next_result(), Mysql#set_server_option(), Mysql#sqlstate() 追加
  • Mysql#connect() のフラグ用定数追加 Mysql::CLIENT_MULTI_STATEMENTS, Mysql::CLIENT_MULTI_RESULTS
  • Mysql#set_server_option() 用の定数追加 Mysql::OPTION_MULTI_STATEMENTS_ON, Mysql::OPTION_MULTI_STATEMENTS_OFF
  • ブロック付き Mysql#query()
  • Mysql#reconnect(), Mysql#reconnect=() 追加
  • MySQL との接続が切れたときに、デフォルトでは再接続しないようにした。
2005-02-12
version 2.5.2
  • BUG: Mysql#connect で接続すると接続が切断されない。(Andres Salomon に感謝)
2004-09-20
version 2.5.1
  • Mysql#set_ssl() 追加。
2004-08-31
version 2.5
  • MySQL 4.1.x 対応
  • MysqlRes, MysqlField, MysqlError を Mysql::Result, Mysql::Field, Mysql::Error に変更。
  • Mysql.client_version(), Mysql.get_client_version(), Mysql#client_version(), Mysql#get_client_version(), Mysql#server_version(), Mysql#get_server_version(), Mysql#warning_count(), Mysql#commit(), Mysql#rollback(), Mysql#autocommit() 追加。
  • Mysql::Field#is_not_null?(), Mysql::Field#is_pri_key?(), Mysql::Field#is_num?() 追加。
  • MysqlField::TYPE_VAR_STRING 追加。
2003-08-10
version 2.4.5
  • extconf.rb: MySQL 4.1 対応。
  • mysql.c.in: Ruby 1.8 対応。
2003-02-23
version 2.4.4a
  • extconf.rb の Ruby 1.8.0 対応。
2003-01-29
version 2.4.4
  • Mysql::OPT_LOCAL_INFILE を追加。
  • extconf.rb に --with-mysql-config オプションを追加
  • extconf.rb 時に主なライブラリを自動検出するようにした。
2003-01-05
version 2.4.3c
  • 英語の README の改版。Paul DuBois に感謝。
2002-12-24
version 2.4.3b
  • extconf.rb の Ruby 1.6.8 対応。
2002-11-07
version 2.4.3a
  • エラー定数が重複定義されることがあるバグを修正。
2002-09-10
version 2.4.3
  • ER_ で始まるエラー定数にも対応した。
  • errmsg.h と mysqld_error.h から自動的にエラー定数を取得するようにした。
2002-01-07
version 2.4.2
  • MySQL 4.0 対応。
  • uint を unsigned int に変更(mswin対応)。
2001-12-02
version 2.4.1
  • 不要な extern を削除(Cygiwn対応)。
  • extconf.rb のオプションを変更。
2001-10-12
version 2.4.0
  • Ruby 1.7 に対応。
  • Mysql::debug(), Mysql#change_user(), Mysql#character_set_name(), Mysql#dump_debug_info() を追加。
2001-03-25
version 2.3.2a
  • t/50update.rb の判定方法を変更
2001-03-19
version 2.3.2
  • 一定数(20回) MysqlRes オブジェクトを生成したら、強制的に GC するようにした。
  • Mysql#escape_string(), Mysql#quote() は mysql_real_escape_string() を使用するようにした。
2000-09-02
version 2.3.1
  • Mysql#initialize() を追加(Ruby 1.6 対応)。
2000-07-22
version 2.3.0
  • MysqlRes#free() を追加。
  • Mysql#initialize(), MysqlRes#initialize() を有効にした。
  • true を返していたメソッドを、self を返すようにした。
2000-05-27
version 2.2.1a
  • test.rb を引数でパラメータを指定できるようにした。
2000-05-10
version 2.2.1
  • データベースからのデータを「汚染された」文字列に変更。
  • テストスクリプト追加。
1999-09-28
version 2.2.0
  • Mysql::init(), Mysql#options(), Mysql#real_connect() を追加。
  • Mysql#field_count を追加。
1999-09-24
version 2.1.7
  • MySQL 3.22.26 に対応。
  • MysqlField#inspect() を追加。
1999-06-17
version 2.1.6
  • fetch_field で落ちることがあった。
1999-06-12
version 2.1.5
  • Ruby 1.3.x 対応が中途半端だった。
1999-05-30
version 2.1.4
  • Ruby 1.3.x に対応。
1999-04-13
version 2.1.3
  • fetch_hash/each_hash の引数の数の定義が間違っていた。
  • fetch_hash/each_hash に true を指定した時の項目名が欠けていた。
  • NULL値の項目があると fetch_hash/each_hash の動きがおかしかった。
1999-02-01
version 2.1.2
  • Mysql#refresh() と Mysql::REFRESH_* を追加。
  • MySQL 3.21.xx にも対応(させたつもり…)。
1999-01-24
version 2.1.1
  • MysqlError#error(), MysqlError#errno() を追加。
  • MysqlError::CR_* を追加。
1999-01-17
version 2.1
  • fetch_hash, each_hash を C ソースに移動。
  • MysqlField#hash() を追加。
  • escape_string, get_client_info をオブジェクトメソッドとしても使えるようにした。
1998-11-29
version 2.0.1
  • fetch_hash, each_hash に with_table 引数を追加。
  • やっぱり get_* メソッド名も C API と同じにした。
  • mysql-compat.rb を alias で書き直した。
  • Mysql の定数 CLIENT_* が MysqlField の定数になっていた。
1998-11-15
version 2.0
  • メソッド名を C API と同じにした。
  • C++ でも通るように書き直した。
1998-08-13
version 1.0
  • 初期バージョン。

作者

e-mail: とみたまさひろ tommy@tmtm.org http://tmtm.org


TOMITA Masahiro
Last modified: Sun Feb 1 17:48:26 JST 2009 ruby-mysql-2.8.2+gem2deb/extconf.rb000066400000000000000000000032301163166767300171610ustar00rootroot00000000000000require 'mkmf' if /mswin32/ =~ RUBY_PLATFORM inc, lib = dir_config('mysql') exit 1 unless have_library("libmysql") elsif mc = with_config('mysql-config') then mc = 'mysql_config' if mc == true cflags = `#{mc} --cflags`.chomp exit 1 if $? != 0 libs = `#{mc} --libs`.chomp exit 1 if $? != 0 $CPPFLAGS += ' ' + cflags $libs = libs + " " + $libs else inc, lib = dir_config('mysql', '/usr/local') libs = ['m', 'z', 'socket', 'nsl', 'mygcc'] while not find_library('mysqlclient', 'mysql_query', lib, "#{lib}/mysql") do exit 1 if libs.empty? have_library(libs.shift) end end have_func('mysql_ssl_set') have_func('rb_str_set_len') have_func('rb_thread_start_timer') if have_header('mysql.h') then src = "#include \n#include \n" elsif have_header('mysql/mysql.h') then src = "#include \n#include \n" else exit 1 end # make mysql constant File.open("conftest.c", "w") do |f| f.puts src end if defined? cpp_command then cpp = Config.expand(cpp_command('')) else cpp = Config.expand sprintf(CPP, $CPPFLAGS, $CFLAGS, '') end if /mswin32/ =~ RUBY_PLATFORM && !/-E/.match(cpp) cpp << " -E" end unless system "#{cpp} > confout" then exit 1 end File.unlink "conftest.c" error_syms = [] IO.foreach('confout') do |l| next unless l =~ /errmsg\.h|mysqld_error\.h/ fn = l.split(/\"/)[1] IO.foreach(fn) do |m| if m =~ /^#define\s+([CE]R_[0-9A-Z_]+)/ then error_syms << $1 end end end File.unlink 'confout' error_syms.uniq! File.open('error_const.h', 'w') do |f| error_syms.each do |s| f.puts " rb_define_mysql_const(#{s});" end end create_makefile("mysql") ruby-mysql-2.8.2+gem2deb/mysql.c000066400000000000000000002064541163166767300165140ustar00rootroot00000000000000/* ruby mysql module * $Id: mysql.c 250 2010-02-11 10:42:54Z tommy $ */ #include #ifndef RSTRING_PTR #define RSTRING_PTR(str) RSTRING(str)->ptr #endif #ifndef RSTRING_LEN #define RSTRING_LEN(str) RSTRING(str)->len #endif #ifndef RARRAY_PTR #define RARRAY_PTR(ary) RARRAY(ary)->ptr #endif #ifndef HAVE_RB_STR_SET_LEN #define rb_str_set_len(str, length) (RSTRING_LEN(str) = (length)) #endif #ifdef HAVE_MYSQL_H #include #include #include #else #include #include #include #endif #define MYSQL_RUBY_VERSION 20802 #define GC_STORE_RESULT_LIMIT 20 #if MYSQL_VERSION_ID < 32224 #define mysql_field_count mysql_num_fields #endif #define NILorSTRING(obj) (NIL_P(obj)? NULL: StringValuePtr(obj)) #define NILorINT(obj) (NIL_P(obj)? 0: NUM2INT(obj)) #define GetMysqlStruct(obj) (Check_Type(obj, T_DATA), (struct mysql*)DATA_PTR(obj)) #define GetHandler(obj) (Check_Type(obj, T_DATA), &(((struct mysql*)DATA_PTR(obj))->handler)) #define GetMysqlRes(obj) (Check_Type(obj, T_DATA), ((struct mysql_res*)DATA_PTR(obj))->res) #define GetMysqlStmt(obj) (Check_Type(obj, T_DATA), ((struct mysql_stmt*)DATA_PTR(obj))->stmt) VALUE cMysql; VALUE cMysqlRes; VALUE cMysqlField; VALUE cMysqlStmt; VALUE cMysqlRowOffset; VALUE cMysqlTime; VALUE eMysql; static int store_result_count = 0; struct mysql { MYSQL handler; char connection; char query_with_result; }; struct mysql_res { MYSQL_RES* res; char freed; }; #if MYSQL_VERSION_ID >= 40101 struct mysql_stmt { MYSQL_STMT *stmt; char closed; struct { int n; MYSQL_BIND *bind; unsigned long *length; MYSQL_TIME *buffer; } param; struct { int n; MYSQL_BIND *bind; my_bool *is_null; unsigned long *length; } result; MYSQL_RES *res; }; #endif /* free Mysql class object */ static void free_mysql(struct mysql* my) { if (my->connection == Qtrue) mysql_close(&my->handler); xfree(my); } static void free_mysqlres(struct mysql_res* resp) { if (resp->freed == Qfalse) { mysql_free_result(resp->res); store_result_count--; } xfree(resp); } #if MYSQL_VERSION_ID >= 40101 static void free_mysqlstmt_memory(struct mysql_stmt *s) { if (s->param.bind) { xfree(s->param.bind); s->param.bind = NULL; } if (s->param.length) { xfree(s->param.length); s->param.length = NULL; } if (s->param.buffer) { xfree(s->param.buffer); s->param.buffer = NULL; } s->param.n = 0; if (s->res) { mysql_free_result(s->res); s->res = NULL; } if (s->result.bind) { int i; for (i = 0; i < s->result.n; i++) { if (s->result.bind[i].buffer) xfree(s->result.bind[i].buffer); s->result.bind[i].buffer = NULL; } xfree(s->result.bind); s->result.bind = NULL; } if (s->result.is_null) { xfree(s->result.is_null); s->result.is_null = NULL; } if (s->result.length) { xfree(s->result.length); s->result.length = NULL; } s->result.n = 0; } static void free_execute_memory(struct mysql_stmt *s) { if (s->res && s->result.bind) { int i; for (i = 0; i < s->result.n; i++) { if (s->result.bind[i].buffer) xfree(s->result.bind[i].buffer); s->result.bind[i].buffer = NULL; } } mysql_stmt_free_result(s->stmt); } static void free_mysqlstmt(struct mysql_stmt* s) { free_mysqlstmt_memory(s); if (s->closed == Qfalse) mysql_stmt_close(s->stmt); if (s->res) mysql_free_result(s->res); xfree(s); } #endif static void mysql_raise(MYSQL* m) { VALUE e = rb_exc_new2(eMysql, mysql_error(m)); rb_iv_set(e, "errno", INT2FIX(mysql_errno(m))); #if MYSQL_VERSION_ID >= 40101 rb_iv_set(e, "sqlstate", rb_tainted_str_new2(mysql_sqlstate(m))); #endif rb_exc_raise(e); } static VALUE mysqlres2obj(MYSQL_RES* res) { VALUE obj; struct mysql_res* resp; obj = Data_Make_Struct(cMysqlRes, struct mysql_res, 0, free_mysqlres, resp); rb_iv_set(obj, "colname", Qnil); rb_iv_set(obj, "tblcolname", Qnil); resp->res = res; resp->freed = Qfalse; rb_obj_call_init(obj, 0, NULL); if (++store_result_count > GC_STORE_RESULT_LIMIT) rb_gc(); return obj; } /* make Mysql::Field object */ static VALUE make_field_obj(MYSQL_FIELD* f) { VALUE obj; if (f == NULL) return Qnil; obj = rb_obj_alloc(cMysqlField); rb_iv_set(obj, "name", f->name? rb_str_freeze(rb_tainted_str_new2(f->name)): Qnil); rb_iv_set(obj, "table", f->table? rb_str_freeze(rb_tainted_str_new2(f->table)): Qnil); rb_iv_set(obj, "def", f->def? rb_str_freeze(rb_tainted_str_new2(f->def)): Qnil); rb_iv_set(obj, "type", INT2NUM(f->type)); rb_iv_set(obj, "length", INT2NUM(f->length)); rb_iv_set(obj, "max_length", INT2NUM(f->max_length)); rb_iv_set(obj, "flags", INT2NUM(f->flags)); rb_iv_set(obj, "decimals", INT2NUM(f->decimals)); return obj; } /*------------------------------- * Mysql class method */ /* init() */ static VALUE init(VALUE klass) { struct mysql* myp; VALUE obj; obj = Data_Make_Struct(klass, struct mysql, 0, free_mysql, myp); mysql_init(&myp->handler); myp->connection = Qfalse; myp->query_with_result = Qtrue; rb_obj_call_init(obj, 0, NULL); return obj; } /* real_connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil) */ static VALUE real_connect(int argc, VALUE* argv, VALUE klass) { VALUE host, user, passwd, db, port, sock, flag; char *h, *u, *p, *d, *s; unsigned int pp, f; struct mysql* myp; VALUE obj; #if MYSQL_VERSION_ID >= 32200 rb_scan_args(argc, argv, "07", &host, &user, &passwd, &db, &port, &sock, &flag); d = NILorSTRING(db); f = NILorINT(flag); #elif MYSQL_VERSION_ID >= 32115 rb_scan_args(argc, argv, "06", &host, &user, &passwd, &port, &sock, &flag); f = NILorINT(flag); #else rb_scan_args(argc, argv, "05", &host, &user, &passwd, &port, &sock); #endif h = NILorSTRING(host); u = NILorSTRING(user); p = NILorSTRING(passwd); pp = NILorINT(port); s = NILorSTRING(sock); #ifdef HAVE_RB_THREAD_START_TIMER rb_thread_stop_timer(); #endif obj = Data_Make_Struct(klass, struct mysql, 0, free_mysql, myp); #if MYSQL_VERSION_ID >= 32200 mysql_init(&myp->handler); if (mysql_real_connect(&myp->handler, h, u, p, d, pp, s, f) == NULL) #elif MYSQL_VERSION_ID >= 32115 if (mysql_real_connect(&myp->handler, h, u, p, pp, s, f) == NULL) #else if (mysql_real_connect(&myp->handler, h, u, p, pp, s) == NULL) #endif { #ifdef HAVE_RB_THREAD_START_TIMER rb_thread_start_timer(); #endif mysql_raise(&myp->handler); } #ifdef HAVE_RB_THREAD_START_TIMER rb_thread_start_timer(); #endif myp->handler.reconnect = 0; myp->connection = Qtrue; myp->query_with_result = Qtrue; rb_obj_call_init(obj, argc, argv); return obj; } /* escape_string(string) */ static VALUE escape_string(VALUE klass, VALUE str) { VALUE ret; Check_Type(str, T_STRING); ret = rb_str_new(0, (RSTRING_LEN(str))*2+1); rb_str_set_len(ret, mysql_escape_string(RSTRING_PTR(ret), RSTRING_PTR(str), RSTRING_LEN(str))); return ret; } /* client_info() */ static VALUE client_info(VALUE klass) { return rb_tainted_str_new2(mysql_get_client_info()); } #if MYSQL_VERSION_ID >= 32332 /* my_debug(string) */ static VALUE my_debug(VALUE obj, VALUE str) { mysql_debug(StringValuePtr(str)); return obj; } #endif #if MYSQL_VERSION_ID >= 40000 /* client_version() */ static VALUE client_version(VALUE obj) { return INT2NUM(mysql_get_client_version()); } #endif /*------------------------------- * Mysql object method */ #if MYSQL_VERSION_ID >= 32200 /* real_connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil) */ static VALUE real_connect2(int argc, VALUE* argv, VALUE obj) { VALUE host, user, passwd, db, port, sock, flag; char *h, *u, *p, *d, *s; unsigned int pp, f; MYSQL* m = GetHandler(obj); rb_scan_args(argc, argv, "07", &host, &user, &passwd, &db, &port, &sock, &flag); d = NILorSTRING(db); f = NILorINT(flag); h = NILorSTRING(host); u = NILorSTRING(user); p = NILorSTRING(passwd); pp = NILorINT(port); s = NILorSTRING(sock); #ifdef HAVE_RB_THREAD_START_TIMER rb_thread_stop_timer(); #endif if (mysql_real_connect(m, h, u, p, d, pp, s, f) == NULL) { #ifdef HAVE_RB_THREAD_START_TIMER rb_thread_start_timer(); #endif mysql_raise(m); } #ifdef HAVE_RB_THREAD_START_TIMER rb_thread_start_timer(); #endif m->reconnect = 0; GetMysqlStruct(obj)->connection = Qtrue; return obj; } /* options(opt, value=nil) */ static VALUE options(int argc, VALUE* argv, VALUE obj) { VALUE opt, val; int n; my_bool b; char* v; MYSQL* m = GetHandler(obj); rb_scan_args(argc, argv, "11", &opt, &val); switch(NUM2INT(opt)) { case MYSQL_OPT_CONNECT_TIMEOUT: #if MYSQL_VERSION_ID >= 40100 case MYSQL_OPT_PROTOCOL: #endif #if MYSQL_VERSION_ID >= 40101 case MYSQL_OPT_READ_TIMEOUT: case MYSQL_OPT_WRITE_TIMEOUT: #endif if (val == Qnil) rb_raise(rb_eArgError, "wrong # of arguments(1 for 2)"); n = NUM2INT(val); v = (char*)&n; break; case MYSQL_INIT_COMMAND: case MYSQL_READ_DEFAULT_FILE: case MYSQL_READ_DEFAULT_GROUP: #if MYSQL_VERSION_ID >= 32349 case MYSQL_SET_CHARSET_DIR: case MYSQL_SET_CHARSET_NAME: #endif #if MYSQL_VERSION_ID >= 40100 case MYSQL_SHARED_MEMORY_BASE_NAME: #endif #if MYSQL_VERSION_ID >= 40101 case MYSQL_SET_CLIENT_IP: #endif if (val == Qnil) rb_raise(rb_eArgError, "wrong # of arguments(1 for 2)"); v = StringValuePtr(val); break; #if MYSQL_VERSION_ID >= 40101 case MYSQL_SECURE_AUTH: if (val == Qnil || val == Qfalse) b = 1; else b = 0; v = (char*)&b; break; #endif #if MYSQL_VERSION_ID >= 32349 case MYSQL_OPT_LOCAL_INFILE: if (val == Qnil || val == Qfalse) v = NULL; else { n = 1; v = (char*)&n; } break; #endif default: v = NULL; } if (mysql_options(m, NUM2INT(opt), v) != 0) rb_raise(eMysql, "unknown option: %d", NUM2INT(opt)); return obj; } #endif #if MYSQL_VERSION_ID >= 32332 /* real_escape_string(string) */ static VALUE real_escape_string(VALUE obj, VALUE str) { MYSQL* m = GetHandler(obj); VALUE ret; Check_Type(str, T_STRING); ret = rb_str_new(0, (RSTRING_LEN(str))*2+1); rb_str_set_len(ret, mysql_real_escape_string(m, RSTRING_PTR(ret), RSTRING_PTR(str), RSTRING_LEN(str))); return ret; } #endif /* initialize() */ static VALUE initialize(int argc, VALUE* argv, VALUE obj) { return obj; } /* affected_rows() */ static VALUE affected_rows(VALUE obj) { return INT2NUM(mysql_affected_rows(GetHandler(obj))); } #if MYSQL_VERSION_ID >= 32303 /* change_user(user=nil, passwd=nil, db=nil) */ static VALUE change_user(int argc, VALUE* argv, VALUE obj) { VALUE user, passwd, db; char *u, *p, *d; MYSQL* m = GetHandler(obj); rb_scan_args(argc, argv, "03", &user, &passwd, &db); u = NILorSTRING(user); p = NILorSTRING(passwd); d = NILorSTRING(db); if (mysql_change_user(m, u, p, d) != 0) mysql_raise(m); return obj; } #endif #if MYSQL_VERSION_ID >= 32321 /* character_set_name() */ static VALUE character_set_name(VALUE obj) { return rb_tainted_str_new2(mysql_character_set_name(GetHandler(obj))); } #endif /* close() */ static VALUE my_close(VALUE obj) { MYSQL* m = GetHandler(obj); mysql_close(m); GetMysqlStruct(obj)->connection = Qfalse; return obj; } #if MYSQL_VERSION_ID < 40000 /* create_db(db) */ static VALUE create_db(VALUE obj, VALUE db) { MYSQL* m = GetHandler(obj); if (mysql_create_db(m, StringValuePtr(db)) != 0) mysql_raise(m); return obj; } /* drop_db(db) */ static VALUE drop_db(VALUE obj, VALUE db) { MYSQL* m = GetHandler(obj); if (mysql_drop_db(m, StringValuePtr(db)) != 0) mysql_raise(m); return obj; } #endif #if MYSQL_VERSION_ID >= 32332 /* dump_debug_info() */ static VALUE dump_debug_info(VALUE obj) { MYSQL* m = GetHandler(obj); if (mysql_dump_debug_info(m) != 0) mysql_raise(m); return obj; } #endif /* errno() */ static VALUE my_errno(VALUE obj) { return INT2NUM(mysql_errno(GetHandler(obj))); } /* error() */ static VALUE my_error(VALUE obj) { return rb_str_new2(mysql_error(GetHandler(obj))); } /* field_count() */ static VALUE field_count(VALUE obj) { return INT2NUM(mysql_field_count(GetHandler(obj))); } /* host_info() */ static VALUE host_info(VALUE obj) { return rb_tainted_str_new2(mysql_get_host_info(GetHandler(obj))); } /* proto_info() */ static VALUE proto_info(VALUE obj) { return INT2NUM(mysql_get_proto_info(GetHandler(obj))); } /* server_info() */ static VALUE server_info(VALUE obj) { return rb_tainted_str_new2(mysql_get_server_info(GetHandler(obj))); } /* info() */ static VALUE info(VALUE obj) { const char* p = mysql_info(GetHandler(obj)); return p? rb_tainted_str_new2(p): Qnil; } /* insert_id() */ static VALUE insert_id(VALUE obj) { return ULL2NUM(mysql_insert_id(GetHandler(obj))); } /* kill(pid) */ static VALUE my_kill(VALUE obj, VALUE pid) { int p = NUM2INT(pid); MYSQL* m = GetHandler(obj); if (mysql_kill(m, p) != 0) mysql_raise(m); return obj; } /* list_dbs(db=nil) */ static VALUE list_dbs(int argc, VALUE* argv, VALUE obj) { unsigned int i, n; VALUE db, ret; MYSQL* m = GetHandler(obj); MYSQL_RES* res; rb_scan_args(argc, argv, "01", &db); res = mysql_list_dbs(m, NILorSTRING(db)); if (res == NULL) mysql_raise(m); n = mysql_num_rows(res); ret = rb_ary_new2(n); for (i=0; i= 40103 if (mysql_shutdown(m, NIL_P(level) ? SHUTDOWN_DEFAULT : NUM2INT(level)) != 0) #else if (mysql_shutdown(m) != 0) #endif mysql_raise(m); return obj; } /* stat() */ static VALUE my_stat(VALUE obj) { MYSQL* m = GetHandler(obj); const char* s = mysql_stat(m); if (s == NULL) mysql_raise(m); return rb_tainted_str_new2(s); } /* store_result() */ static VALUE store_result(VALUE obj) { MYSQL* m = GetHandler(obj); MYSQL_RES* res = mysql_store_result(m); if (res == NULL) mysql_raise(m); return mysqlres2obj(res); } /* thread_id() */ static VALUE thread_id(VALUE obj) { return INT2NUM(mysql_thread_id(GetHandler(obj))); } /* use_result() */ static VALUE use_result(VALUE obj) { MYSQL* m = GetHandler(obj); MYSQL_RES* res = mysql_use_result(m); if (res == NULL) mysql_raise(m); return mysqlres2obj(res); } static VALUE res_free(VALUE); /* query(sql) */ static VALUE query(VALUE obj, VALUE sql) { int loop = 0; MYSQL* m = GetHandler(obj); Check_Type(sql, T_STRING); if (GetMysqlStruct(obj)->connection == Qfalse) { rb_raise(eMysql, "query: not connected"); } if (rb_block_given_p()) { if (mysql_real_query(m, RSTRING_PTR(sql), RSTRING_LEN(sql)) != 0) mysql_raise(m); do { MYSQL_RES* res = mysql_store_result(m); if (res == NULL) { if (mysql_field_count(m) != 0) mysql_raise(m); } else { VALUE robj = mysqlres2obj(res); rb_ensure(rb_yield, robj, res_free, robj); } #if MYSQL_VERSION_ID >= 40101 if ((loop = mysql_next_result(m)) > 0) mysql_raise(m); } while (loop == 0); #else } while (0); #endif return obj; } if (mysql_real_query(m, RSTRING_PTR(sql), RSTRING_LEN(sql)) != 0) mysql_raise(m); if (GetMysqlStruct(obj)->query_with_result == Qfalse) return obj; if (mysql_field_count(m) == 0) return Qnil; return store_result(obj); } #if MYSQL_VERSION_ID >= 40100 /* server_version() */ static VALUE server_version(VALUE obj) { return INT2NUM(mysql_get_server_version(GetHandler(obj))); } /* warning_count() */ static VALUE warning_count(VALUE obj) { return INT2NUM(mysql_warning_count(GetHandler(obj))); } /* commit() */ static VALUE commit(VALUE obj) { MYSQL* m = GetHandler(obj); if (mysql_commit(m) != 0) mysql_raise(m); return obj; } /* rollback() */ static VALUE rollback(VALUE obj) { MYSQL* m = GetHandler(obj); if (mysql_rollback(m) != 0) mysql_raise(m); return obj; } /* autocommit() */ static VALUE autocommit(VALUE obj, VALUE mode) { MYSQL* m = GetHandler(obj); int f; f = (mode == Qnil || mode == Qfalse || (rb_type(mode) == T_FIXNUM && NUM2INT(mode) == 0)) ? 0 : 1; if (mysql_autocommit(m, f) != 0) mysql_raise(m); return obj; } #endif #ifdef HAVE_MYSQL_SSL_SET /* ssl_set(key=nil, cert=nil, ca=nil, capath=nil, cipher=nil) */ static VALUE ssl_set(int argc, VALUE* argv, VALUE obj) { VALUE key, cert, ca, capath, cipher; char *s_key, *s_cert, *s_ca, *s_capath, *s_cipher; MYSQL* m = GetHandler(obj); rb_scan_args(argc, argv, "05", &key, &cert, &ca, &capath, &cipher); s_key = NILorSTRING(key); s_cert = NILorSTRING(cert); s_ca = NILorSTRING(ca); s_capath = NILorSTRING(capath); s_cipher = NILorSTRING(cipher); mysql_ssl_set(m, s_key, s_cert, s_ca, s_capath, s_cipher); return obj; } #endif #if MYSQL_VERSION_ID >= 40100 /* more_results() */ static VALUE more_results(VALUE obj) { if (mysql_more_results(GetHandler(obj)) == 0) return Qfalse; else return Qtrue; } static VALUE next_result(VALUE obj) { MYSQL* m = GetHandler(obj); int ret; ret = mysql_next_result(m); if (ret > 0) mysql_raise(m); if (ret == 0) return Qtrue; return Qfalse; } #endif #if MYSQL_VERSION_ID >= 40101 /* set_server_option(option) */ static VALUE set_server_option(VALUE obj, VALUE option) { MYSQL *m = GetHandler(obj); if (mysql_set_server_option(m, NUM2INT(option)) != 0) mysql_raise(m); return obj; } /* sqlstate() */ static VALUE sqlstate(VALUE obj) { MYSQL *m = GetHandler(obj); return rb_tainted_str_new2(mysql_sqlstate(m)); } #endif #if MYSQL_VERSION_ID >= 40102 /* stmt_init() */ static VALUE stmt_init(VALUE obj) { MYSQL *m = GetHandler(obj); MYSQL_STMT *s; struct mysql_stmt* stmt; my_bool true = 1; VALUE st_obj; if ((s = mysql_stmt_init(m)) == NULL) mysql_raise(m); if (mysql_stmt_attr_set(s, STMT_ATTR_UPDATE_MAX_LENGTH, &true)) rb_raise(rb_eArgError, "mysql_stmt_attr_set() failed"); st_obj = Data_Make_Struct(cMysqlStmt, struct mysql_stmt, 0, free_mysqlstmt, stmt); memset(stmt, 0, sizeof(*stmt)); stmt->stmt = s; stmt->closed = Qfalse; return st_obj; } static VALUE stmt_prepare(VALUE obj, VALUE query); /* prepare(query) */ static VALUE prepare(VALUE obj, VALUE query) { VALUE st; st = stmt_init(obj); return stmt_prepare(st, query); } #endif /* query_with_result() */ static VALUE query_with_result(VALUE obj) { return GetMysqlStruct(obj)->query_with_result? Qtrue: Qfalse; } /* query_with_result=(flag) */ static VALUE query_with_result_set(VALUE obj, VALUE flag) { if (TYPE(flag) != T_TRUE && TYPE(flag) != T_FALSE) rb_raise(rb_eTypeError, "invalid type, required true or false."); GetMysqlStruct(obj)->query_with_result = flag; return flag; } /* reconnect() */ static VALUE reconnect(VALUE obj) { return GetHandler(obj)->reconnect ? Qtrue : Qfalse; } /* reconnect=(flag) */ static VALUE reconnect_set(VALUE obj, VALUE flag) { GetHandler(obj)->reconnect = (flag == Qnil || flag == Qfalse) ? 0 : 1; return flag; } /*------------------------------- * Mysql::Result object method */ /* check if already freed */ static void check_free(VALUE obj) { struct mysql_res* resp = DATA_PTR(obj); if (resp->freed == Qtrue) rb_raise(eMysql, "Mysql::Result object is already freed"); } /* data_seek(offset) */ static VALUE data_seek(VALUE obj, VALUE offset) { check_free(obj); mysql_data_seek(GetMysqlRes(obj), NUM2INT(offset)); return obj; } /* fetch_field() */ static VALUE fetch_field(VALUE obj) { check_free(obj); return make_field_obj(mysql_fetch_field(GetMysqlRes(obj))); } /* fetch_fields() */ static VALUE fetch_fields(VALUE obj) { MYSQL_RES* res; MYSQL_FIELD* f; unsigned int n; VALUE ret; unsigned int i; check_free(obj); res = GetMysqlRes(obj); f = mysql_fetch_fields(res); n = mysql_num_fields(res); ret = rb_ary_new2(n); for (i=0; i= max) rb_raise(eMysql, "%d: out of range (max: %d)", n, max-1); #if MYSQL_VERSION_ID >= 32226 return make_field_obj(mysql_fetch_field_direct(res, n)); #else return make_field_obj(&mysql_fetch_field_direct(res, n)); #endif } /* fetch_lengths() */ static VALUE fetch_lengths(VALUE obj) { MYSQL_RES* res; unsigned int n; unsigned long* lengths; VALUE ary; unsigned int i; check_free(obj); res = GetMysqlRes(obj); n = mysql_num_fields(res); lengths = mysql_fetch_lengths(res); if (lengths == NULL) return Qnil; ary = rb_ary_new2(n); for (i=0; ires); resp->freed = Qtrue; store_result_count--; return Qnil; } /* num_fields() */ static VALUE num_fields(VALUE obj) { check_free(obj); return INT2NUM(mysql_num_fields(GetMysqlRes(obj))); } /* num_rows() */ static VALUE num_rows(VALUE obj) { check_free(obj); return INT2NUM(mysql_num_rows(GetMysqlRes(obj))); } /* row_seek(offset) */ static VALUE row_seek(VALUE obj, VALUE offset) { MYSQL_ROW_OFFSET prev_offset; if (CLASS_OF(offset) != cMysqlRowOffset) rb_raise(rb_eTypeError, "wrong argument type %s (expected Mysql::RowOffset)", rb_obj_classname(offset)); check_free(obj); prev_offset = mysql_row_seek(GetMysqlRes(obj), DATA_PTR(offset)); return Data_Wrap_Struct(cMysqlRowOffset, 0, NULL, prev_offset); } /* row_tell() */ static VALUE row_tell(VALUE obj) { MYSQL_ROW_OFFSET offset; check_free(obj); offset = mysql_row_tell(GetMysqlRes(obj)); return Data_Wrap_Struct(cMysqlRowOffset, 0, NULL, offset); } /* each {...} */ static VALUE each(VALUE obj) { VALUE row; check_free(obj); while ((row = fetch_row(obj)) != Qnil) rb_yield(row); return obj; } /* each_hash(with_table=false) {...} */ static VALUE each_hash(int argc, VALUE* argv, VALUE obj) { VALUE with_table; VALUE hash; check_free(obj); rb_scan_args(argc, argv, "01", &with_table); if (with_table == Qnil) with_table = Qfalse; while ((hash = fetch_hash2(obj, with_table)) != Qnil) rb_yield(hash); return obj; } /*------------------------------- * Mysql::Field object method */ /* hash */ static VALUE field_hash(VALUE obj) { VALUE h = rb_hash_new(); rb_hash_aset(h, rb_str_new2("name"), rb_iv_get(obj, "name")); rb_hash_aset(h, rb_str_new2("table"), rb_iv_get(obj, "table")); rb_hash_aset(h, rb_str_new2("def"), rb_iv_get(obj, "def")); rb_hash_aset(h, rb_str_new2("type"), rb_iv_get(obj, "type")); rb_hash_aset(h, rb_str_new2("length"), rb_iv_get(obj, "length")); rb_hash_aset(h, rb_str_new2("max_length"), rb_iv_get(obj, "max_length")); rb_hash_aset(h, rb_str_new2("flags"), rb_iv_get(obj, "flags")); rb_hash_aset(h, rb_str_new2("decimals"), rb_iv_get(obj, "decimals")); return h; } /* inspect */ static VALUE field_inspect(VALUE obj) { VALUE n = rb_iv_get(obj, "name"); VALUE s = rb_str_new(0, RSTRING_LEN(n) + 16); sprintf(RSTRING_PTR(s), "#", RSTRING_PTR(n)); return s; } #define DefineMysqlFieldMemberMethod(m)\ static VALUE field_##m(VALUE obj)\ {return rb_iv_get(obj, #m);} DefineMysqlFieldMemberMethod(name) DefineMysqlFieldMemberMethod(table) DefineMysqlFieldMemberMethod(def) DefineMysqlFieldMemberMethod(type) DefineMysqlFieldMemberMethod(length) DefineMysqlFieldMemberMethod(max_length) DefineMysqlFieldMemberMethod(flags) DefineMysqlFieldMemberMethod(decimals) #ifdef IS_NUM /* is_num? */ static VALUE field_is_num(VALUE obj) { return IS_NUM(NUM2INT(rb_iv_get(obj, "type"))) ? Qtrue : Qfalse; } #endif #ifdef IS_NOT_NULL /* is_not_null? */ static VALUE field_is_not_null(VALUE obj) { return IS_NOT_NULL(NUM2INT(rb_iv_get(obj, "flags"))) ? Qtrue : Qfalse; } #endif #ifdef IS_PRI_KEY /* is_pri_key? */ static VALUE field_is_pri_key(VALUE obj) { return IS_PRI_KEY(NUM2INT(rb_iv_get(obj, "flags"))) ? Qtrue : Qfalse; } #endif #if MYSQL_VERSION_ID >= 40102 /*------------------------------- * Mysql::Stmt object method */ /* check if stmt is already closed */ static void check_stmt_closed(VALUE obj) { struct mysql_stmt* s = DATA_PTR(obj); if (s->closed == Qtrue) rb_raise(eMysql, "Mysql::Stmt object is already closed"); } static void mysql_stmt_raise(MYSQL_STMT* s) { VALUE e = rb_exc_new2(eMysql, mysql_stmt_error(s)); rb_iv_set(e, "errno", INT2FIX(mysql_stmt_errno(s))); rb_iv_set(e, "sqlstate", rb_tainted_str_new2(mysql_stmt_sqlstate(s))); rb_exc_raise(e); } /* affected_rows() */ static VALUE stmt_affected_rows(VALUE obj) { struct mysql_stmt* s = DATA_PTR(obj); my_ulonglong n; check_stmt_closed(obj); n = mysql_stmt_affected_rows(s->stmt); return INT2NUM(n); } #if 0 /* attr_get(option) */ static VALUE stmt_attr_get(VALUE obj, VALUE opt) { struct mysql_stmt* s = DATA_PTR(obj); check_stmt_closed(obj); if (NUM2INT(opt) == STMT_ATTR_UPDATE_MAX_LENGTH) { my_bool arg; mysql_stmt_attr_get(s->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &arg); return arg == 1 ? Qtrue : Qfalse; } rb_raise(eMysql, "unknown option: %d", NUM2INT(opt)); } /* attr_set(option, arg) */ static VALUE stmt_attr_set(VALUE obj, VALUE opt, VALUE val) { struct mysql_stmt* s = DATA_PTR(obj); check_stmt_closed(obj); if (NUM2INT(opt) == STMT_ATTR_UPDATE_MAX_LENGTH) { my_bool arg; arg = (val == Qnil || val == Qfalse) ? 0 : 1; mysql_stmt_attr_set(s->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &arg); return obj; } rb_raise(eMysql, "unknown option: %d", NUM2INT(opt)); } #endif /* bind_result(bind,...) */ static VALUE stmt_bind_result(int argc, VALUE *argv, VALUE obj) { struct mysql_stmt* s = DATA_PTR(obj); int i; MYSQL_FIELD *field; check_stmt_closed(obj); if (argc != s->result.n) rb_raise(eMysql, "bind_result: result value count(%d) != number of argument(%d)", s->result.n, argc); for (i = 0; i < argc; i++) { if (argv[i] == Qnil || argv[i] == rb_cNilClass) { field = mysql_fetch_fields(s->res); s->result.bind[i].buffer_type = field[i].type; } else if (argv[i] == rb_cString) s->result.bind[i].buffer_type = MYSQL_TYPE_STRING; else if (argv[i] == rb_cNumeric || argv[i] == rb_cInteger || argv[i] == rb_cFixnum) s->result.bind[i].buffer_type = MYSQL_TYPE_LONGLONG; else if (argv[i] == rb_cFloat) s->result.bind[i].buffer_type = MYSQL_TYPE_DOUBLE; else if (argv[i] == cMysqlTime) s->result.bind[i].buffer_type = MYSQL_TYPE_DATETIME; else rb_raise(rb_eTypeError, "unrecognized class: %s", RSTRING_PTR(rb_inspect(argv[i]))); if (mysql_stmt_bind_result(s->stmt, s->result.bind)) mysql_stmt_raise(s->stmt); } return obj; } /* close() */ static VALUE stmt_close(VALUE obj) { struct mysql_stmt* s = DATA_PTR(obj); check_stmt_closed(obj); mysql_stmt_close(s->stmt); s->closed = Qtrue; return Qnil; } /* data_seek(offset) */ static VALUE stmt_data_seek(VALUE obj, VALUE offset) { struct mysql_stmt* s = DATA_PTR(obj); check_stmt_closed(obj); mysql_stmt_data_seek(s->stmt, NUM2INT(offset)); return obj; } /* execute(arg,...) */ static VALUE stmt_execute(int argc, VALUE *argv, VALUE obj) { struct mysql_stmt *s = DATA_PTR(obj); MYSQL_STMT *stmt = s->stmt; int i; check_stmt_closed(obj); free_execute_memory(s); if (s->param.n != argc) rb_raise(eMysql, "execute: param_count(%d) != number of argument(%d)", s->param.n, argc); if (argc > 0) { memset(s->param.bind, 0, sizeof(*(s->param.bind))*argc); for (i = 0; i < argc; i++) { switch (TYPE(argv[i])) { case T_NIL: s->param.bind[i].buffer_type = MYSQL_TYPE_NULL; break; case T_FIXNUM: #if SIZEOF_INT < SIZEOF_LONG s->param.bind[i].buffer_type = MYSQL_TYPE_LONGLONG; s->param.bind[i].buffer = &(s->param.buffer[i]); *(LONG_LONG*)(s->param.bind[i].buffer) = FIX2LONG(argv[i]); #else s->param.bind[i].buffer_type = MYSQL_TYPE_LONG; s->param.bind[i].buffer = &(s->param.buffer[i]); *(int*)(s->param.bind[i].buffer) = FIX2INT(argv[i]); #endif break; case T_BIGNUM: s->param.bind[i].buffer_type = MYSQL_TYPE_LONGLONG; s->param.bind[i].buffer = &(s->param.buffer[i]); *(LONG_LONG*)(s->param.bind[i].buffer) = rb_big2ll(argv[i]); break; case T_FLOAT: s->param.bind[i].buffer_type = MYSQL_TYPE_DOUBLE; s->param.bind[i].buffer = &(s->param.buffer[i]); *(double*)(s->param.bind[i].buffer) = NUM2DBL(argv[i]); break; case T_STRING: s->param.bind[i].buffer_type = MYSQL_TYPE_STRING; s->param.bind[i].buffer = RSTRING_PTR(argv[i]); s->param.bind[i].buffer_length = RSTRING_LEN(argv[i]); s->param.length[i] = RSTRING_LEN(argv[i]); s->param.bind[i].length = &(s->param.length[i]); break; default: if (CLASS_OF(argv[i]) == rb_cTime) { MYSQL_TIME t; VALUE a = rb_funcall(argv[i], rb_intern("to_a"), 0); s->param.bind[i].buffer_type = MYSQL_TYPE_DATETIME; s->param.bind[i].buffer = &(s->param.buffer[i]); memset(&t, 0, sizeof(t)); /* avoid warning */ t.second_part = 0; t.neg = 0; t.second = FIX2INT(RARRAY_PTR(a)[0]); t.minute = FIX2INT(RARRAY_PTR(a)[1]); t.hour = FIX2INT(RARRAY_PTR(a)[2]); t.day = FIX2INT(RARRAY_PTR(a)[3]); t.month = FIX2INT(RARRAY_PTR(a)[4]); t.year = FIX2INT(RARRAY_PTR(a)[5]); *(MYSQL_TIME*)&(s->param.buffer[i]) = t; } else if (CLASS_OF(argv[i]) == cMysqlTime) { MYSQL_TIME t; s->param.bind[i].buffer_type = MYSQL_TYPE_DATETIME; s->param.bind[i].buffer = &(s->param.buffer[i]); memset(&t, 0, sizeof(t)); /* avoid warning */ t.second_part = 0; t.neg = 0; t.second = NUM2INT(rb_iv_get(argv[i], "second")); t.minute = NUM2INT(rb_iv_get(argv[i], "minute")); t.hour = NUM2INT(rb_iv_get(argv[i], "hour")); t.day = NUM2INT(rb_iv_get(argv[i], "day")); t.month = NUM2INT(rb_iv_get(argv[i], "month")); t.year = NUM2INT(rb_iv_get(argv[i], "year")); *(MYSQL_TIME*)&(s->param.buffer[i]) = t; } else rb_raise(rb_eTypeError, "unsupported type: %d", TYPE(argv[i])); } } if (mysql_stmt_bind_param(stmt, s->param.bind)) mysql_stmt_raise(stmt); } if (mysql_stmt_execute(stmt)) mysql_stmt_raise(stmt); if (s->res) { MYSQL_FIELD *field; if (mysql_stmt_store_result(stmt)) mysql_stmt_raise(stmt); field = mysql_fetch_fields(s->res); for (i = 0; i < s->result.n; i++) { switch(s->result.bind[i].buffer_type) { case MYSQL_TYPE_NULL: break; case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_YEAR: case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: case MYSQL_TYPE_LONGLONG: case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_DOUBLE: s->result.bind[i].buffer = xmalloc(8); s->result.bind[i].buffer_length = 8; memset(s->result.bind[i].buffer, 0, 8); break; case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: #if MYSQL_VERSION_ID >= 50003 case MYSQL_TYPE_NEWDECIMAL: case MYSQL_TYPE_BIT: #endif s->result.bind[i].buffer = xmalloc(field[i].max_length); memset(s->result.bind[i].buffer, 0, field[i].max_length); s->result.bind[i].buffer_length = field[i].max_length; break; case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: s->result.bind[i].buffer = xmalloc(sizeof(MYSQL_TIME)); s->result.bind[i].buffer_length = sizeof(MYSQL_TIME); memset(s->result.bind[i].buffer, 0, sizeof(MYSQL_TIME)); break; default: rb_raise(rb_eTypeError, "unknown buffer_type: %d", s->result.bind[i].buffer_type); } } if (mysql_stmt_bind_result(s->stmt, s->result.bind)) mysql_stmt_raise(s->stmt); } return obj; } /* fetch() */ static VALUE stmt_fetch(VALUE obj) { struct mysql_stmt* s = DATA_PTR(obj); VALUE ret; int i; int r; check_stmt_closed(obj); r = mysql_stmt_fetch(s->stmt); if (r == MYSQL_NO_DATA) return Qnil; #ifdef MYSQL_DATA_TRUNCATED if (r == MYSQL_DATA_TRUNCATED) rb_raise(rb_eRuntimeError, "unexpectedly data truncated"); #endif if (r == 1) mysql_stmt_raise(s->stmt); ret = rb_ary_new2(s->result.n); for (i = 0; i < s->result.n; i++) { if (s->result.is_null[i]) rb_ary_push(ret, Qnil); else { VALUE v; MYSQL_TIME *t; switch (s->result.bind[i].buffer_type) { case MYSQL_TYPE_TINY: if (s->result.bind[i].is_unsigned) v = UINT2NUM(*(unsigned char *)s->result.bind[i].buffer); else v = INT2NUM(*(signed char *)s->result.bind[i].buffer); break; case MYSQL_TYPE_SHORT: case MYSQL_TYPE_YEAR: if (s->result.bind[i].is_unsigned) v = UINT2NUM(*(unsigned short *)s->result.bind[i].buffer); else v = INT2NUM(*(short *)s->result.bind[i].buffer); break; case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: if (s->result.bind[i].is_unsigned) v = UINT2NUM(*(unsigned int *)s->result.bind[i].buffer); else v = INT2NUM(*(int *)s->result.bind[i].buffer); break; case MYSQL_TYPE_LONGLONG: if (s->result.bind[i].is_unsigned) v = ULL2NUM(*(unsigned long long *)s->result.bind[i].buffer); else v = LL2NUM(*(long long *)s->result.bind[i].buffer); break; case MYSQL_TYPE_FLOAT: v = rb_float_new((double)(*(float *)s->result.bind[i].buffer)); break; case MYSQL_TYPE_DOUBLE: v = rb_float_new(*(double *)s->result.bind[i].buffer); break; case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: t = (MYSQL_TIME *)s->result.bind[i].buffer; v = rb_obj_alloc(cMysqlTime); rb_funcall(v, rb_intern("initialize"), 8, INT2FIX(t->year), INT2FIX(t->month), INT2FIX(t->day), INT2FIX(t->hour), INT2FIX(t->minute), INT2FIX(t->second), (t->neg ? Qtrue : Qfalse), INT2FIX(t->second_part)); break; case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: #if MYSQL_VERSION_ID >= 50003 case MYSQL_TYPE_NEWDECIMAL: case MYSQL_TYPE_BIT: #endif v = rb_tainted_str_new(s->result.bind[i].buffer, s->result.length[i]); break; default: rb_raise(rb_eTypeError, "unknown buffer_type: %d", s->result.bind[i].buffer_type); } rb_ary_push(ret, v); } } return ret; } /* each {...} */ static VALUE stmt_each(VALUE obj) { VALUE row; check_stmt_closed(obj); while ((row = stmt_fetch(obj)) != Qnil) rb_yield(row); return obj; } /* field_count() */ static VALUE stmt_field_count(VALUE obj) { struct mysql_stmt* s = DATA_PTR(obj); unsigned int n; check_stmt_closed(obj); n = mysql_stmt_field_count(s->stmt); return INT2NUM(n); } /* free_result() */ static VALUE stmt_free_result(VALUE obj) { struct mysql_stmt* s = DATA_PTR(obj); check_stmt_closed(obj); if (mysql_stmt_free_result(s->stmt)) mysql_stmt_raise(s->stmt); return obj; } /* insert_id() */ static VALUE stmt_insert_id(VALUE obj) { struct mysql_stmt* s = DATA_PTR(obj); my_ulonglong n; check_stmt_closed(obj); n = mysql_stmt_insert_id(s->stmt); return ULL2NUM(n); } /* num_rows() */ static VALUE stmt_num_rows(VALUE obj) { struct mysql_stmt* s = DATA_PTR(obj); my_ulonglong n; check_stmt_closed(obj); n = mysql_stmt_num_rows(s->stmt); return INT2NUM(n); } /* param_count() */ static VALUE stmt_param_count(VALUE obj) { struct mysql_stmt* s = DATA_PTR(obj); unsigned long n; check_stmt_closed(obj); n = mysql_stmt_param_count(s->stmt); return INT2NUM(n); } /* prepare(query) */ static VALUE stmt_prepare(VALUE obj, VALUE query) { struct mysql_stmt* s = DATA_PTR(obj); int n; int i; MYSQL_FIELD *field; free_mysqlstmt_memory(s); check_stmt_closed(obj); Check_Type(query, T_STRING); if (mysql_stmt_prepare(s->stmt, RSTRING_PTR(query), RSTRING_LEN(query))) mysql_stmt_raise(s->stmt); n = mysql_stmt_param_count(s->stmt); s->param.n = n; s->param.bind = xmalloc(sizeof(s->param.bind[0]) * n); s->param.length = xmalloc(sizeof(s->param.length[0]) * n); s->param.buffer = xmalloc(sizeof(s->param.buffer[0]) * n); s->res = mysql_stmt_result_metadata(s->stmt); if (s->res) { n = s->result.n = mysql_num_fields(s->res); s->result.bind = xmalloc(sizeof(s->result.bind[0]) * n); s->result.is_null = xmalloc(sizeof(s->result.is_null[0]) * n); s->result.length = xmalloc(sizeof(s->result.length[0]) * n); field = mysql_fetch_fields(s->res); memset(s->result.bind, 0, sizeof(s->result.bind[0]) * n); for (i = 0; i < n; i++) { s->result.bind[i].buffer_type = field[i].type; #if MYSQL_VERSION_ID < 50003 if (field[i].type == MYSQL_TYPE_DECIMAL) s->result.bind[i].buffer_type = MYSQL_TYPE_STRING; #endif s->result.bind[i].is_null = &(s->result.is_null[i]); s->result.bind[i].length = &(s->result.length[i]); s->result.bind[i].is_unsigned = ((field[i].flags & UNSIGNED_FLAG) != 0); } } else { if (mysql_stmt_errno(s->stmt)) mysql_stmt_raise(s->stmt); } return obj; } #if 0 /* reset() */ static VALUE stmt_reset(VALUE obj) { struct mysql_stmt* s = DATA_PTR(obj); check_stmt_closed(obj); if (mysql_stmt_reset(s->stmt)) mysql_stmt_raise(s->stmt); return obj; } #endif /* result_metadata() */ static VALUE stmt_result_metadata(VALUE obj) { struct mysql_stmt* s = DATA_PTR(obj); MYSQL_RES *res; check_stmt_closed(obj); res = mysql_stmt_result_metadata(s->stmt); if (res == NULL) { if (mysql_stmt_errno(s->stmt) != 0) mysql_stmt_raise(s->stmt); return Qnil; } return mysqlres2obj(res); } /* row_seek(offset) */ static VALUE stmt_row_seek(VALUE obj, VALUE offset) { struct mysql_stmt* s = DATA_PTR(obj); MYSQL_ROW_OFFSET prev_offset; if (CLASS_OF(offset) != cMysqlRowOffset) rb_raise(rb_eTypeError, "wrong argument type %s (expected Mysql::RowOffset)", rb_obj_classname(offset)); check_stmt_closed(obj); prev_offset = mysql_stmt_row_seek(s->stmt, DATA_PTR(offset)); return Data_Wrap_Struct(cMysqlRowOffset, 0, NULL, prev_offset); } /* row_tell() */ static VALUE stmt_row_tell(VALUE obj) { struct mysql_stmt* s = DATA_PTR(obj); MYSQL_ROW_OFFSET offset; check_stmt_closed(obj); offset = mysql_stmt_row_tell(s->stmt); return Data_Wrap_Struct(cMysqlRowOffset, 0, NULL, offset); } #if 0 /* send_long_data(col, data) */ static VALUE stmt_send_long_data(VALUE obj, VALUE col, VALUE data) { struct mysql_stmt* s = DATA_PTR(obj); int c; check_stmt_closed(obj); c = NUM2INT(col); if (0 <= c && c < s->param.n) { s->param.bind[c].buffer_type = MYSQL_TYPE_STRING; if (mysql_stmt_bind_param(s->stmt, s->param.bind)) mysql_stmt_raise(s->stmt); } if (mysql_stmt_send_long_data(s->stmt, c, RSTRING_PTR(data), RSTRING_LEN(data))) mysql_stmt_raise(s->stmt); return obj; } #endif /* sqlstate() */ static VALUE stmt_sqlstate(VALUE obj) { struct mysql_stmt* s = DATA_PTR(obj); return rb_tainted_str_new2(mysql_stmt_sqlstate(s->stmt)); } /*------------------------------- * Mysql::Time object method */ static VALUE time_initialize(int argc, VALUE* argv, VALUE obj) { VALUE year, month, day, hour, minute, second, neg, second_part; rb_scan_args(argc, argv, "08", &year, &month, &day, &hour, &minute, &second, &neg, &second_part); #define NILorFIXvalue(o) (NIL_P(o) ? INT2FIX(0) : (Check_Type(o, T_FIXNUM), o)) rb_iv_set(obj, "year", NILorFIXvalue(year)); rb_iv_set(obj, "month", NILorFIXvalue(month)); rb_iv_set(obj, "day", NILorFIXvalue(day)); rb_iv_set(obj, "hour", NILorFIXvalue(hour)); rb_iv_set(obj, "minute", NILorFIXvalue(minute)); rb_iv_set(obj, "second", NILorFIXvalue(second)); rb_iv_set(obj, "neg", (neg == Qnil || neg == Qfalse) ? Qfalse : Qtrue); rb_iv_set(obj, "second_part", NILorFIXvalue(second_part)); return obj; } static VALUE time_inspect(VALUE obj) { char buf[36]; sprintf(buf, "#", NUM2INT(rb_iv_get(obj, "year")), NUM2INT(rb_iv_get(obj, "month")), NUM2INT(rb_iv_get(obj, "day")), NUM2INT(rb_iv_get(obj, "hour")), NUM2INT(rb_iv_get(obj, "minute")), NUM2INT(rb_iv_get(obj, "second"))); return rb_str_new2(buf); } static VALUE time_to_s(VALUE obj) { char buf[20]; sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d", NUM2INT(rb_iv_get(obj, "year")), NUM2INT(rb_iv_get(obj, "month")), NUM2INT(rb_iv_get(obj, "day")), NUM2INT(rb_iv_get(obj, "hour")), NUM2INT(rb_iv_get(obj, "minute")), NUM2INT(rb_iv_get(obj, "second"))); return rb_str_new2(buf); } #define DefineMysqlTimeGetMethod(m)\ static VALUE time_get_##m(VALUE obj)\ {return rb_iv_get(obj, #m);} DefineMysqlTimeGetMethod(year) DefineMysqlTimeGetMethod(month) DefineMysqlTimeGetMethod(day) DefineMysqlTimeGetMethod(hour) DefineMysqlTimeGetMethod(minute) DefineMysqlTimeGetMethod(second) DefineMysqlTimeGetMethod(neg) DefineMysqlTimeGetMethod(second_part) #define DefineMysqlTimeSetMethod(m)\ static VALUE time_set_##m(VALUE obj, VALUE v)\ {rb_iv_set(obj, #m, NILorFIXvalue(v)); return v;} DefineMysqlTimeSetMethod(year) DefineMysqlTimeSetMethod(month) DefineMysqlTimeSetMethod(day) DefineMysqlTimeSetMethod(hour) DefineMysqlTimeSetMethod(minute) DefineMysqlTimeSetMethod(second) DefineMysqlTimeSetMethod(second_part) static VALUE time_set_neg(VALUE obj, VALUE v) { rb_iv_set(obj, "neg", (v == Qnil || v == Qfalse) ? Qfalse : Qtrue); return v; } static VALUE time_equal(VALUE obj, VALUE v) { if (CLASS_OF(v) == cMysqlTime && NUM2INT(rb_iv_get(obj, "year")) == NUM2INT(rb_iv_get(v, "year")) && NUM2INT(rb_iv_get(obj, "month")) == NUM2INT(rb_iv_get(v, "month")) && NUM2INT(rb_iv_get(obj, "day")) == NUM2INT(rb_iv_get(v, "day")) && NUM2INT(rb_iv_get(obj, "hour")) == NUM2INT(rb_iv_get(v, "hour")) && NUM2INT(rb_iv_get(obj, "minute")) == NUM2INT(rb_iv_get(v, "minute")) && NUM2INT(rb_iv_get(obj, "second")) == NUM2INT(rb_iv_get(v, "second")) && rb_iv_get(obj, "neg") == rb_iv_get(v, "neg") && NUM2INT(rb_iv_get(obj, "second_part")) == NUM2INT(rb_iv_get(v, "second_part"))) return Qtrue; return Qfalse; } #endif /*------------------------------- * Mysql::Error object method */ static VALUE error_error(VALUE obj) { return rb_iv_get(obj, "mesg"); } static VALUE error_errno(VALUE obj) { return rb_iv_get(obj, "errno"); } static VALUE error_sqlstate(VALUE obj) { return rb_iv_get(obj, "sqlstate"); } /*------------------------------- * Initialize */ void Init_mysql(void) { cMysql = rb_define_class("Mysql", rb_cObject); cMysqlRes = rb_define_class_under(cMysql, "Result", rb_cObject); cMysqlField = rb_define_class_under(cMysql, "Field", rb_cObject); #if MYSQL_VERSION_ID >= 40102 cMysqlStmt = rb_define_class_under(cMysql, "Stmt", rb_cObject); cMysqlRowOffset = rb_define_class_under(cMysql, "RowOffset", rb_cObject); cMysqlTime = rb_define_class_under(cMysql, "Time", rb_cObject); #endif eMysql = rb_define_class_under(cMysql, "Error", rb_eStandardError); rb_define_global_const("MysqlRes", cMysqlRes); rb_define_global_const("MysqlField", cMysqlField); rb_define_global_const("MysqlError", eMysql); /* Mysql class method */ rb_define_singleton_method(cMysql, "init", init, 0); rb_define_singleton_method(cMysql, "real_connect", real_connect, -1); rb_define_singleton_method(cMysql, "connect", real_connect, -1); rb_define_singleton_method(cMysql, "new", real_connect, -1); rb_define_singleton_method(cMysql, "escape_string", escape_string, 1); rb_define_singleton_method(cMysql, "quote", escape_string, 1); rb_define_singleton_method(cMysql, "client_info", client_info, 0); rb_define_singleton_method(cMysql, "get_client_info", client_info, 0); #if MYSQL_VERSION_ID >= 32332 rb_define_singleton_method(cMysql, "debug", my_debug, 1); #endif #if MYSQL_VERSION_ID >= 40000 rb_define_singleton_method(cMysql, "get_client_version", client_version, 0); rb_define_singleton_method(cMysql, "client_version", client_version, 0); #endif /* Mysql object method */ #if MYSQL_VERSION_ID >= 32200 rb_define_method(cMysql, "real_connect", real_connect2, -1); rb_define_method(cMysql, "connect", real_connect2, -1); rb_define_method(cMysql, "options", options, -1); #endif rb_define_method(cMysql, "initialize", initialize, -1); #if MYSQL_VERSION_ID >= 32332 rb_define_method(cMysql, "escape_string", real_escape_string, 1); rb_define_method(cMysql, "quote", real_escape_string, 1); #else rb_define_method(cMysql, "escape_string", escape_string, 1); rb_define_method(cMysql, "quote", escape_string, 1); #endif rb_define_method(cMysql, "client_info", client_info, 0); rb_define_method(cMysql, "get_client_info", client_info, 0); rb_define_method(cMysql, "affected_rows", affected_rows, 0); #if MYSQL_VERSION_ID >= 32303 rb_define_method(cMysql, "change_user", change_user, -1); #endif #if MYSQL_VERSION_ID >= 32321 rb_define_method(cMysql, "character_set_name", character_set_name, 0); #endif rb_define_method(cMysql, "close", my_close, 0); #if MYSQL_VERSION_ID < 40000 rb_define_method(cMysql, "create_db", create_db, 1); rb_define_method(cMysql, "drop_db", drop_db, 1); #endif #if MYSQL_VERSION_ID >= 32332 rb_define_method(cMysql, "dump_debug_info", dump_debug_info, 0); #endif rb_define_method(cMysql, "errno", my_errno, 0); rb_define_method(cMysql, "error", my_error, 0); rb_define_method(cMysql, "field_count", field_count, 0); #if MYSQL_VERSION_ID >= 40000 rb_define_method(cMysql, "get_client_version", client_version, 0); rb_define_method(cMysql, "client_version", client_version, 0); #endif rb_define_method(cMysql, "get_host_info", host_info, 0); rb_define_method(cMysql, "host_info", host_info, 0); rb_define_method(cMysql, "get_proto_info", proto_info, 0); rb_define_method(cMysql, "proto_info", proto_info, 0); rb_define_method(cMysql, "get_server_info", server_info, 0); rb_define_method(cMysql, "server_info", server_info, 0); rb_define_method(cMysql, "info", info, 0); rb_define_method(cMysql, "insert_id", insert_id, 0); rb_define_method(cMysql, "kill", my_kill, 1); rb_define_method(cMysql, "list_dbs", list_dbs, -1); rb_define_method(cMysql, "list_fields", list_fields, -1); rb_define_method(cMysql, "list_processes", list_processes, 0); rb_define_method(cMysql, "list_tables", list_tables, -1); #if MYSQL_VERSION_ID >= 32200 rb_define_method(cMysql, "ping", ping, 0); #endif rb_define_method(cMysql, "query", query, 1); rb_define_method(cMysql, "real_query", query, 1); rb_define_method(cMysql, "refresh", refresh, 1); rb_define_method(cMysql, "reload", reload, 0); rb_define_method(cMysql, "select_db", select_db, 1); rb_define_method(cMysql, "shutdown", my_shutdown, -1); rb_define_method(cMysql, "stat", my_stat, 0); rb_define_method(cMysql, "store_result", store_result, 0); rb_define_method(cMysql, "thread_id", thread_id, 0); rb_define_method(cMysql, "use_result", use_result, 0); #if MYSQL_VERSION_ID >= 40100 rb_define_method(cMysql, "get_server_version", server_version, 0); rb_define_method(cMysql, "server_version", server_version, 0); rb_define_method(cMysql, "warning_count", warning_count, 0); rb_define_method(cMysql, "commit", commit, 0); rb_define_method(cMysql, "rollback", rollback, 0); rb_define_method(cMysql, "autocommit", autocommit, 1); #endif #ifdef HAVE_MYSQL_SSL_SET rb_define_method(cMysql, "ssl_set", ssl_set, -1); #endif #if MYSQL_VERSION_ID >= 40102 rb_define_method(cMysql, "stmt_init", stmt_init, 0); rb_define_method(cMysql, "prepare", prepare, 1); #endif #if MYSQL_VERSION_ID >= 40100 rb_define_method(cMysql, "more_results", more_results, 0); rb_define_method(cMysql, "more_results?", more_results, 0); rb_define_method(cMysql, "next_result", next_result, 0); #endif #if MYSQL_VERSION_ID >= 40101 rb_define_method(cMysql, "set_server_option", set_server_option, 1); rb_define_method(cMysql, "sqlstate", sqlstate, 0); #endif rb_define_method(cMysql, "query_with_result", query_with_result, 0); rb_define_method(cMysql, "query_with_result=", query_with_result_set, 1); rb_define_method(cMysql, "reconnect", reconnect, 0); rb_define_method(cMysql, "reconnect=", reconnect_set, 1); /* Mysql constant */ rb_define_const(cMysql, "VERSION", INT2FIX(MYSQL_RUBY_VERSION)); #if MYSQL_VERSION_ID >= 32200 rb_define_const(cMysql, "OPT_CONNECT_TIMEOUT", INT2NUM(MYSQL_OPT_CONNECT_TIMEOUT)); rb_define_const(cMysql, "OPT_COMPRESS", INT2NUM(MYSQL_OPT_COMPRESS)); rb_define_const(cMysql, "OPT_NAMED_PIPE", INT2NUM(MYSQL_OPT_NAMED_PIPE)); rb_define_const(cMysql, "INIT_COMMAND", INT2NUM(MYSQL_INIT_COMMAND)); rb_define_const(cMysql, "READ_DEFAULT_FILE", INT2NUM(MYSQL_READ_DEFAULT_FILE)); rb_define_const(cMysql, "READ_DEFAULT_GROUP", INT2NUM(MYSQL_READ_DEFAULT_GROUP)); #endif #if MYSQL_VERSION_ID >= 32349 rb_define_const(cMysql, "SET_CHARSET_DIR", INT2NUM(MYSQL_SET_CHARSET_DIR)); rb_define_const(cMysql, "SET_CHARSET_NAME", INT2NUM(MYSQL_SET_CHARSET_NAME)); rb_define_const(cMysql, "OPT_LOCAL_INFILE", INT2NUM(MYSQL_OPT_LOCAL_INFILE)); #endif #if MYSQL_VERSION_ID >= 40100 rb_define_const(cMysql, "OPT_PROTOCOL", INT2NUM(MYSQL_OPT_PROTOCOL)); rb_define_const(cMysql, "SHARED_MEMORY_BASE_NAME", INT2NUM(MYSQL_SHARED_MEMORY_BASE_NAME)); #endif #if MYSQL_VERSION_ID >= 40101 rb_define_const(cMysql, "OPT_READ_TIMEOUT", INT2NUM(MYSQL_OPT_READ_TIMEOUT)); rb_define_const(cMysql, "OPT_WRITE_TIMEOUT", INT2NUM(MYSQL_OPT_WRITE_TIMEOUT)); rb_define_const(cMysql, "SECURE_AUTH", INT2NUM(MYSQL_SECURE_AUTH)); rb_define_const(cMysql, "OPT_GUESS_CONNECTION", INT2NUM(MYSQL_OPT_GUESS_CONNECTION)); rb_define_const(cMysql, "OPT_USE_EMBEDDED_CONNECTION", INT2NUM(MYSQL_OPT_USE_EMBEDDED_CONNECTION)); rb_define_const(cMysql, "OPT_USE_REMOTE_CONNECTION", INT2NUM(MYSQL_OPT_USE_REMOTE_CONNECTION)); rb_define_const(cMysql, "SET_CLIENT_IP", INT2NUM(MYSQL_SET_CLIENT_IP)); #endif rb_define_const(cMysql, "REFRESH_GRANT", INT2NUM(REFRESH_GRANT)); rb_define_const(cMysql, "REFRESH_LOG", INT2NUM(REFRESH_LOG)); rb_define_const(cMysql, "REFRESH_TABLES", INT2NUM(REFRESH_TABLES)); #ifdef REFRESH_HOSTS rb_define_const(cMysql, "REFRESH_HOSTS", INT2NUM(REFRESH_HOSTS)); #endif #ifdef REFRESH_STATUS rb_define_const(cMysql, "REFRESH_STATUS", INT2NUM(REFRESH_STATUS)); #endif #ifdef REFRESH_THREADS rb_define_const(cMysql, "REFRESH_THREADS", INT2NUM(REFRESH_THREADS)); #endif #ifdef REFRESH_SLAVE rb_define_const(cMysql, "REFRESH_SLAVE", INT2NUM(REFRESH_SLAVE)); #endif #ifdef REFRESH_MASTER rb_define_const(cMysql, "REFRESH_MASTER", INT2NUM(REFRESH_MASTER)); #endif #ifdef CLIENT_LONG_PASSWORD #endif #ifdef CLIENT_FOUND_ROWS rb_define_const(cMysql, "CLIENT_FOUND_ROWS", INT2NUM(CLIENT_FOUND_ROWS)); #endif #ifdef CLIENT_LONG_FLAG #endif #ifdef CLIENT_CONNECT_WITH_DB #endif #ifdef CLIENT_NO_SCHEMA rb_define_const(cMysql, "CLIENT_NO_SCHEMA", INT2NUM(CLIENT_NO_SCHEMA)); #endif #ifdef CLIENT_COMPRESS rb_define_const(cMysql, "CLIENT_COMPRESS", INT2NUM(CLIENT_COMPRESS)); #endif #ifdef CLIENT_ODBC rb_define_const(cMysql, "CLIENT_ODBC", INT2NUM(CLIENT_ODBC)); #endif #ifdef CLIENT_LOCAL_FILES rb_define_const(cMysql, "CLIENT_LOCAL_FILES", INT2NUM(CLIENT_LOCAL_FILES)); #endif #ifdef CLIENT_IGNORE_SPACE rb_define_const(cMysql, "CLIENT_IGNORE_SPACE", INT2NUM(CLIENT_IGNORE_SPACE)); #endif #ifdef CLIENT_CHANGE_USER rb_define_const(cMysql, "CLIENT_CHANGE_USER", INT2NUM(CLIENT_CHANGE_USER)); #endif #ifdef CLIENT_INTERACTIVE rb_define_const(cMysql, "CLIENT_INTERACTIVE", INT2NUM(CLIENT_INTERACTIVE)); #endif #ifdef CLIENT_SSL rb_define_const(cMysql, "CLIENT_SSL", INT2NUM(CLIENT_SSL)); #endif #ifdef CLIENT_IGNORE_SIGPIPE rb_define_const(cMysql, "CLIENT_IGNORE_SIGPIPE", INT2NUM(CLIENT_IGNORE_SIGPIPE)); #endif #ifdef CLIENT_TRANSACTIONS rb_define_const(cMysql, "CLIENT_TRANSACTIONS", INT2NUM(CLIENT_TRANSACTIONS)); #endif #ifdef CLIENT_MULTI_STATEMENTS rb_define_const(cMysql, "CLIENT_MULTI_STATEMENTS", INT2NUM(CLIENT_MULTI_STATEMENTS)); #endif #ifdef CLIENT_MULTI_RESULTS rb_define_const(cMysql, "CLIENT_MULTI_RESULTS", INT2NUM(CLIENT_MULTI_RESULTS)); #endif #if MYSQL_VERSION_ID >= 40101 rb_define_const(cMysql, "OPTION_MULTI_STATEMENTS_ON", INT2NUM(MYSQL_OPTION_MULTI_STATEMENTS_ON)); rb_define_const(cMysql, "OPTION_MULTI_STATEMENTS_OFF", INT2NUM(MYSQL_OPTION_MULTI_STATEMENTS_OFF)); #endif /* Mysql::Result object method */ rb_define_method(cMysqlRes, "data_seek", data_seek, 1); rb_define_method(cMysqlRes, "fetch_field", fetch_field, 0); rb_define_method(cMysqlRes, "fetch_fields", fetch_fields, 0); rb_define_method(cMysqlRes, "fetch_field_direct", fetch_field_direct, 1); rb_define_method(cMysqlRes, "fetch_lengths", fetch_lengths, 0); rb_define_method(cMysqlRes, "fetch_row", fetch_row, 0); rb_define_method(cMysqlRes, "fetch_hash", fetch_hash, -1); rb_define_method(cMysqlRes, "field_seek", field_seek, 1); rb_define_method(cMysqlRes, "field_tell", field_tell, 0); rb_define_method(cMysqlRes, "free", res_free, 0); rb_define_method(cMysqlRes, "num_fields", num_fields, 0); rb_define_method(cMysqlRes, "num_rows", num_rows, 0); rb_define_method(cMysqlRes, "row_seek", row_seek, 1); rb_define_method(cMysqlRes, "row_tell", row_tell, 0); rb_define_method(cMysqlRes, "each", each, 0); rb_define_method(cMysqlRes, "each_hash", each_hash, -1); /* MysqlField object method */ rb_define_method(cMysqlField, "name", field_name, 0); rb_define_method(cMysqlField, "table", field_table, 0); rb_define_method(cMysqlField, "def", field_def, 0); rb_define_method(cMysqlField, "type", field_type, 0); rb_define_method(cMysqlField, "length", field_length, 0); rb_define_method(cMysqlField, "max_length", field_max_length, 0); rb_define_method(cMysqlField, "flags", field_flags, 0); rb_define_method(cMysqlField, "decimals", field_decimals, 0); rb_define_method(cMysqlField, "hash", field_hash, 0); rb_define_method(cMysqlField, "inspect", field_inspect, 0); #ifdef IS_NUM rb_define_method(cMysqlField, "is_num?", field_is_num, 0); #endif #ifdef IS_NOT_NULL rb_define_method(cMysqlField, "is_not_null?", field_is_not_null, 0); #endif #ifdef IS_PRI_KEY rb_define_method(cMysqlField, "is_pri_key?", field_is_pri_key, 0); #endif /* Mysql::Field constant: TYPE */ rb_define_const(cMysqlField, "TYPE_TINY", INT2NUM(FIELD_TYPE_TINY)); #if MYSQL_VERSION_ID >= 32115 rb_define_const(cMysqlField, "TYPE_ENUM", INT2NUM(FIELD_TYPE_ENUM)); #endif rb_define_const(cMysqlField, "TYPE_DECIMAL", INT2NUM(FIELD_TYPE_DECIMAL)); rb_define_const(cMysqlField, "TYPE_SHORT", INT2NUM(FIELD_TYPE_SHORT)); rb_define_const(cMysqlField, "TYPE_LONG", INT2NUM(FIELD_TYPE_LONG)); rb_define_const(cMysqlField, "TYPE_FLOAT", INT2NUM(FIELD_TYPE_FLOAT)); rb_define_const(cMysqlField, "TYPE_DOUBLE", INT2NUM(FIELD_TYPE_DOUBLE)); rb_define_const(cMysqlField, "TYPE_NULL", INT2NUM(FIELD_TYPE_NULL)); rb_define_const(cMysqlField, "TYPE_TIMESTAMP", INT2NUM(FIELD_TYPE_TIMESTAMP)); rb_define_const(cMysqlField, "TYPE_LONGLONG", INT2NUM(FIELD_TYPE_LONGLONG)); rb_define_const(cMysqlField, "TYPE_INT24", INT2NUM(FIELD_TYPE_INT24)); rb_define_const(cMysqlField, "TYPE_DATE", INT2NUM(FIELD_TYPE_DATE)); rb_define_const(cMysqlField, "TYPE_TIME", INT2NUM(FIELD_TYPE_TIME)); rb_define_const(cMysqlField, "TYPE_DATETIME", INT2NUM(FIELD_TYPE_DATETIME)); #if MYSQL_VERSION_ID >= 32130 rb_define_const(cMysqlField, "TYPE_YEAR", INT2NUM(FIELD_TYPE_YEAR)); #endif #if MYSQL_VERSION_ID >= 50003 rb_define_const(cMysqlField, "TYPE_BIT", INT2NUM(FIELD_TYPE_BIT)); rb_define_const(cMysqlField, "TYPE_NEWDECIMAL", INT2NUM(FIELD_TYPE_NEWDECIMAL)); #endif rb_define_const(cMysqlField, "TYPE_SET", INT2NUM(FIELD_TYPE_SET)); rb_define_const(cMysqlField, "TYPE_BLOB", INT2NUM(FIELD_TYPE_BLOB)); rb_define_const(cMysqlField, "TYPE_STRING", INT2NUM(FIELD_TYPE_STRING)); #if MYSQL_VERSION_ID >= 40000 rb_define_const(cMysqlField, "TYPE_VAR_STRING", INT2NUM(FIELD_TYPE_VAR_STRING)); #endif rb_define_const(cMysqlField, "TYPE_CHAR", INT2NUM(FIELD_TYPE_CHAR)); /* Mysql::Field constant: FLAG */ rb_define_const(cMysqlField, "NOT_NULL_FLAG", INT2NUM(NOT_NULL_FLAG)); rb_define_const(cMysqlField, "PRI_KEY_FLAG", INT2NUM(PRI_KEY_FLAG)); rb_define_const(cMysqlField, "UNIQUE_KEY_FLAG", INT2NUM(UNIQUE_KEY_FLAG)); rb_define_const(cMysqlField, "MULTIPLE_KEY_FLAG", INT2NUM(MULTIPLE_KEY_FLAG)); rb_define_const(cMysqlField, "BLOB_FLAG", INT2NUM(BLOB_FLAG)); rb_define_const(cMysqlField, "UNSIGNED_FLAG", INT2NUM(UNSIGNED_FLAG)); rb_define_const(cMysqlField, "ZEROFILL_FLAG", INT2NUM(ZEROFILL_FLAG)); rb_define_const(cMysqlField, "BINARY_FLAG", INT2NUM(BINARY_FLAG)); #ifdef ENUM_FLAG rb_define_const(cMysqlField, "ENUM_FLAG", INT2NUM(ENUM_FLAG)); #endif #ifdef AUTO_INCREMENT_FLAG rb_define_const(cMysqlField, "AUTO_INCREMENT_FLAG", INT2NUM(AUTO_INCREMENT_FLAG)); #endif #ifdef TIMESTAMP_FLAG rb_define_const(cMysqlField, "TIMESTAMP_FLAG", INT2NUM(TIMESTAMP_FLAG)); #endif #ifdef SET_FLAG rb_define_const(cMysqlField, "SET_FLAG", INT2NUM(SET_FLAG)); #endif #ifdef NUM_FLAG rb_define_const(cMysqlField, "NUM_FLAG", INT2NUM(NUM_FLAG)); #endif #ifdef PART_KEY_FLAG rb_define_const(cMysqlField, "PART_KEY_FLAG", INT2NUM(PART_KEY_FLAG)); #endif #if MYSQL_VERSION_ID >= 40102 /* Mysql::Stmt object method */ rb_define_method(cMysqlStmt, "affected_rows", stmt_affected_rows, 0); #if 0 rb_define_method(cMysqlStmt, "attr_get", stmt_attr_get, 1); rb_define_method(cMysqlStmt, "attr_set", stmt_attr_set, 2); #endif rb_define_method(cMysqlStmt, "bind_result", stmt_bind_result, -1); rb_define_method(cMysqlStmt, "close", stmt_close, 0); rb_define_method(cMysqlStmt, "data_seek", stmt_data_seek, 1); rb_define_method(cMysqlStmt, "each", stmt_each, 0); rb_define_method(cMysqlStmt, "execute", stmt_execute, -1); rb_define_method(cMysqlStmt, "fetch", stmt_fetch, 0); rb_define_method(cMysqlStmt, "field_count", stmt_field_count, 0); rb_define_method(cMysqlStmt, "free_result", stmt_free_result, 0); rb_define_method(cMysqlStmt, "insert_id", stmt_insert_id, 0); rb_define_method(cMysqlStmt, "num_rows", stmt_num_rows, 0); rb_define_method(cMysqlStmt, "param_count", stmt_param_count, 0); rb_define_method(cMysqlStmt, "prepare", stmt_prepare, 1); #if 0 rb_define_method(cMysqlStmt, "reset", stmt_reset, 0); #endif rb_define_method(cMysqlStmt, "result_metadata", stmt_result_metadata, 0); rb_define_method(cMysqlStmt, "row_seek", stmt_row_seek, 1); rb_define_method(cMysqlStmt, "row_tell", stmt_row_tell, 0); #if 0 rb_define_method(cMysqlStmt, "send_long_data", stmt_send_long_data, 2); #endif rb_define_method(cMysqlStmt, "sqlstate", stmt_sqlstate, 0); #if 0 rb_define_const(cMysqlStmt, "ATTR_UPDATE_MAX_LENGTH", INT2NUM(STMT_ATTR_UPDATE_MAX_LENGTH)); #endif /* Mysql::Time object method */ rb_define_method(cMysqlTime, "initialize", time_initialize, -1); rb_define_method(cMysqlTime, "inspect", time_inspect, 0); rb_define_method(cMysqlTime, "to_s", time_to_s, 0); rb_define_method(cMysqlTime, "year", time_get_year, 0); rb_define_method(cMysqlTime, "month", time_get_month, 0); rb_define_method(cMysqlTime, "day", time_get_day, 0); rb_define_method(cMysqlTime, "hour", time_get_hour, 0); rb_define_method(cMysqlTime, "minute", time_get_minute, 0); rb_define_method(cMysqlTime, "second", time_get_second, 0); rb_define_method(cMysqlTime, "neg", time_get_neg, 0); rb_define_method(cMysqlTime, "second_part", time_get_second_part, 0); rb_define_method(cMysqlTime, "year=", time_set_year, 1); rb_define_method(cMysqlTime, "month=", time_set_month, 1); rb_define_method(cMysqlTime, "day=", time_set_day, 1); rb_define_method(cMysqlTime, "hour=", time_set_hour, 1); rb_define_method(cMysqlTime, "minute=", time_set_minute, 1); rb_define_method(cMysqlTime, "second=", time_set_second, 1); rb_define_method(cMysqlTime, "neg=", time_set_neg, 1); rb_define_method(cMysqlTime, "second_part=", time_set_second_part, 1); rb_define_method(cMysqlTime, "==", time_equal, 1); #endif /* Mysql::Error object method */ rb_define_method(eMysql, "error", error_error, 0); rb_define_method(eMysql, "errno", error_errno, 0); rb_define_method(eMysql, "sqlstate", error_sqlstate, 0); /* Mysql::Error constant */ #define rb_define_mysql_const(s) rb_define_const(eMysql, #s, INT2NUM(s)) #include "error_const.h" } ruby-mysql-2.8.2+gem2deb/test.rb000066400000000000000000001317301163166767300165010ustar00rootroot00000000000000#!/usr/local/bin/ruby # $Id: test.rb 250 2010-02-11 10:42:54Z tommy $ require "test/unit" require "./mysql.o" class TC_Mysql < Test::Unit::TestCase def setup() @host, @user, @pass, db, port, sock, flag = ARGV @db = db || "test" @port = port.to_i @sock = sock.nil? || sock.empty? ? nil : sock @flag = flag.to_i end def teardown() end def test_version() assert_equal(20802, Mysql::VERSION) end def test_init() assert_nothing_raised{@m = Mysql.init} assert_nothing_raised{@m.close} end def test_real_connect() assert_nothing_raised{@m = Mysql.real_connect(@host, @user, @pass, @db, @port, @sock, @flag)} assert_nothing_raised{@m.close} end def test_connect() assert_nothing_raised{@m = Mysql.connect(@host, @user, @pass, @db, @port, @sock, @flag)} assert_nothing_raised{@m.close} end def test_new() assert_nothing_raised{@m = Mysql.new(@host, @user, @pass, @db, @port, @sock, @flag)} assert_nothing_raised{@m.close} end def test_escape_string() assert_equal("abc\\'def\\\"ghi\\0jkl%mno", Mysql.escape_string("abc'def\"ghi\0jkl%mno")) end def test_quote() assert_equal("abc\\'def\\\"ghi\\0jkl%mno", Mysql.quote("abc'def\"ghi\0jkl%mno")) end def test_get_client_info() assert_match(/^\d.\d+.\d+[a-z]?(-.*)?$/, Mysql.get_client_info()) end def test_client_info() assert_match(/^\d.\d+.\d+[a-z]?(-.*)?$/, Mysql.client_info()) end def test_options() @m = Mysql.init assert_equal(@m, @m.options(Mysql::INIT_COMMAND, "SET AUTOCOMMIT=0")) assert_equal(@m, @m.options(Mysql::OPT_COMPRESS)) assert_equal(@m, @m.options(Mysql::OPT_CONNECT_TIMEOUT, 10)) assert_equal(@m, @m.options(Mysql::GUESS_CONNECTION)) if defined? Mysql::GUESS_CONNECTION assert_equal(@m, @m.options(Mysql::OPT_LOCAL_INFILE, true)) # assert_equal(@m, @m.options(Mysql::OPT_NAMED_PIPE)) # assert_equal(@m, @m.options(Mysql::OPT_PROTOCOL, 1)) assert_equal(@m, @m.options(Mysql::OPT_READ_TIMEOUT, 10)) if defined? Mysql::OPT_READ_TIMEOUT assert_equal(@m, @m.options(Mysql::OPT_USE_EMBEDDED_CONNECTION)) if defined? Mysql::OPT_USE_EMBEDDED_CONNECTION assert_equal(@m, @m.options(Mysql::OPT_USE_REMOTE_CONNECTION)) if defined? Mysql::OPT_USE_REMOTE_CONNECTION assert_equal(@m, @m.options(Mysql::OPT_WRITE_TIMEOUT, 10)) if defined? Mysql::OPT_WRITE_TIMEOUT # assert_equal(@m, @m.options(Mysql::READ_DEFAULT_FILE, "/tmp/hoge")) assert_equal(@m, @m.options(Mysql::READ_DEFAULT_GROUP, "test")) assert_equal(@m, @m.options(Mysql::SECURE_AUTH, true)) if defined? Mysql::SECURE_AUTH # assert_equal(@m, @m.options(Mysql::SET_CHARSET_DIR, "??")) assert_equal(@m, @m.options(Mysql::SET_CHARSET_NAME, "latin1")) assert_equal(@m, @m.options(Mysql::SET_CLIENT_IP, "127.0.0.1")) if defined? Mysql::SET_CLIENT_IP # assert_equal(@m, @m.options(Mysql::SHARED_MEMORY_BASE_NAME, "xxx")) assert_equal(@m, @m.connect(@host, @user, @pass, @db, @port, @sock, @flag)) @m.close end def test_real_connect2() @m = Mysql.init assert_equal(@m, @m.real_connect(@host, @user, @pass, @db, @port, @sock, @flag)) @m.close end def test_connect2() @m = Mysql.init assert_equal(@m, @m.connect(@host, @user, @pass, @db, @port, @sock, @flag)) @m.close end end class TC_Mysql2 < Test::Unit::TestCase def setup() @host, @user, @pass, db, port, sock, flag = ARGV @db = db || "test" @port = port.to_i @sock = sock.nil? || sock.empty? ? nil : sock @flag = flag.to_i @m = Mysql.new(@host, @user, @pass, @db, @port, @sock, @flag) end def teardown() @m.close if @m end def test_affected_rows() @m.query("create temporary table t (id int)") @m.query("insert into t values (1)") assert_equal(1, @m.affected_rows) end def test_autocommit() if @m.methods.include? "autocommit" then assert_equal(@m, @m.autocommit(true)) assert_equal(@m, @m.autocommit(false)) end end # def test_ssl_set() # end def test_more_results_next_result() if @m.server_version >= 40100 then @m.query_with_result = false @m.set_server_option(Mysql::OPTION_MULTI_STATEMENTS_ON) if defined? Mysql::OPTION_MULTI_STATEMENTS_ON @m.query("select 1,2,3; select 4,5,6") res = @m.store_result assert_equal(["1","2","3"], res.fetch_row) assert_equal(nil, res.fetch_row) assert_equal(true, @m.more_results) assert_equal(true, @m.more_results?) assert_equal(true, @m.next_result) res = @m.store_result assert_equal(["4","5","6"], res.fetch_row) assert_equal(nil, res.fetch_row) assert_equal(false, @m.more_results) assert_equal(false, @m.more_results?) assert_equal(false, @m.next_result) end end if Mysql.client_version >= 40100 def test_query_with_block() if @m.server_version >= 40100 then @m.set_server_option(Mysql::OPTION_MULTI_STATEMENTS_ON) expect = [["1","2","3"], ["4","5","6"]] @m.query("select 1,2,3; select 4,5,6") {|res| assert_equal(1, res.num_rows) assert_equal(expect.shift, res.fetch_row) } assert(expect.empty?) expect = [["1","2","3"], ["4","5","6"]] assert_raises(Mysql::Error) { @m.query("select 1,2,3; hoge; select 4,5,6") {|res| assert_equal(1, res.num_rows) assert_equal(expect.shift, res.fetch_row) } } assert_equal(1, expect.size) expect = [["1","2","3"], ["4","5","6"]] assert_raises(Mysql::Error) { @m.query("select 1,2,3; select 4,5,6; hoge") {|res| assert_equal(1, res.num_rows) assert_equal(expect.shift, res.fetch_row) } } assert(expect.empty?) end end def test_query_with_block_single() @m.query("select 1,2,3") {|res| assert_equal(1, res.num_rows) assert_equal(["1","2","3"], res.fetch_row) } end def test_set_server_option() if @m.server_version >= 40101 then assert_equal(@m, @m.set_server_option(Mysql::OPTION_MULTI_STATEMENTS_ON)) assert_equal(@m, @m.set_server_option(Mysql::OPTION_MULTI_STATEMENTS_OFF)) end end if Mysql.client_version >= 40101 def test_sqlstate() if @m.server_version >= 40100 then assert_equal("00000", @m.sqlstate) assert_raises(Mysql::Error){@m.query("hogehoge")} assert_equal("42000", @m.sqlstate) end end if Mysql.client_version >= 40100 def test_query_with_result() assert_equal(true, @m.query_with_result) assert_equal(false, @m.query_with_result = false) assert_equal(false, @m.query_with_result) assert_equal(true, @m.query_with_result = true) assert_equal(true, @m.query_with_result) end def test_reconnect() assert_equal(false, @m.reconnect) assert_equal(true, @m.reconnect = true) assert_equal(true, @m.reconnect) assert_equal(false, @m.reconnect = false) assert_equal(false, @m.reconnect) end end class TC_MysqlRes < Test::Unit::TestCase def setup() @host, @user, @pass, db, port, sock, flag = ARGV @db = db || "test" @port = port.to_i @sock = sock.nil? || sock.empty? ? nil : sock @flag = flag.to_i @m = Mysql.new(@host, @user, @pass, @db, @port, @sock, @flag) @m.query("create temporary table t (id int, str char(10), primary key (id))") @m.query("insert into t values (1, 'abc'), (2, 'defg'), (3, 'hi'), (4, null)") @res = @m.query("select * from t") end def teardown() @res.free @m.close end def test_num_fields() assert_equal(2, @res.num_fields) end def test_num_rows() assert_equal(4, @res.num_rows) end def test_fetch_row() assert_equal(["1","abc"], @res.fetch_row) assert_equal(["2","defg"], @res.fetch_row) assert_equal(["3","hi"], @res.fetch_row) assert_equal(["4",nil], @res.fetch_row) assert_equal(nil, @res.fetch_row) end def test_fetch_hash() assert_equal({"id"=>"1", "str"=>"abc"}, @res.fetch_hash) assert_equal({"id"=>"2", "str"=>"defg"}, @res.fetch_hash) assert_equal({"id"=>"3", "str"=>"hi"}, @res.fetch_hash) assert_equal({"id"=>"4", "str"=>nil}, @res.fetch_hash) assert_equal(nil, @res.fetch_hash) end def test_fetch_hash2() assert_equal({"t.id"=>"1", "t.str"=>"abc"}, @res.fetch_hash(true)) assert_equal({"t.id"=>"2", "t.str"=>"defg"}, @res.fetch_hash(true)) assert_equal({"t.id"=>"3", "t.str"=>"hi"}, @res.fetch_hash(true)) assert_equal({"t.id"=>"4", "t.str"=>nil}, @res.fetch_hash(true)) assert_equal(nil, @res.fetch_hash) end def test_each() ary = [["1","abc"], ["2","defg"], ["3","hi"], ["4",nil]] @res.each do |a| assert_equal(ary.shift, a) end end def test_each_hash() hash = [{"id"=>"1","str"=>"abc"}, {"id"=>"2","str"=>"defg"}, {"id"=>"3","str"=>"hi"}, {"id"=>"4","str"=>nil}] @res.each_hash do |h| assert_equal(hash.shift, h) end end def test_data_seek() assert_equal(["1","abc"], @res.fetch_row) assert_equal(["2","defg"], @res.fetch_row) assert_equal(["3","hi"], @res.fetch_row) @res.data_seek(1) assert_equal(["2","defg"], @res.fetch_row) end def test_row_seek() assert_equal(["1","abc"], @res.fetch_row) pos = @res.row_tell assert_equal(["2","defg"], @res.fetch_row) assert_equal(["3","hi"], @res.fetch_row) @res.row_seek(pos) assert_equal(["2","defg"], @res.fetch_row) end def test_field_seek() assert_equal(0, @res.field_tell) @res.fetch_field assert_equal(1, @res.field_tell) @res.fetch_field assert_equal(2, @res.field_tell) @res.field_seek(1) assert_equal(1, @res.field_tell) end def test_fetch_field() f = @res.fetch_field assert_equal("id", f.name) assert_equal("t", f.table) assert_equal(nil, f.def) assert_equal(Mysql::Field::TYPE_LONG, f.type) assert_equal(11, f.length) assert_equal(1, f.max_length) assert_equal(Mysql::Field::NUM_FLAG|Mysql::Field::PRI_KEY_FLAG|Mysql::Field::PART_KEY_FLAG|Mysql::Field::NOT_NULL_FLAG, f.flags) assert_equal(0, f.decimals) f = @res.fetch_field assert_equal("str", f.name) assert_equal("t", f.table) assert_equal(nil, f.def) assert_equal(Mysql::Field::TYPE_STRING, f.type) assert_equal(10, f.length) assert_equal(4, f.max_length) assert_equal(0, f.flags) assert_equal(0, f.decimals) f = @res.fetch_field assert_equal(nil, f) end def test_fetch_fields() a = @res.fetch_fields assert_equal(2, a.size) assert_equal("id", a[0].name) assert_equal("str", a[1].name) end def test_fetch_field_direct() f = @res.fetch_field_direct(0) assert_equal("id", f.name) f = @res.fetch_field_direct(1) assert_equal("str", f.name) assert_raises(Mysql::Error){@res.fetch_field_direct(-1)} assert_raises(Mysql::Error){@res.fetch_field_direct(2)} end def test_fetch_lengths() assert_equal(nil, @res.fetch_lengths()) @res.fetch_row assert_equal([1, 3], @res.fetch_lengths()) @res.fetch_row assert_equal([1, 4], @res.fetch_lengths()) @res.fetch_row assert_equal([1, 2], @res.fetch_lengths()) @res.fetch_row assert_equal([1, 0], @res.fetch_lengths()) @res.fetch_row assert_equal(nil, @res.fetch_lengths()) end def test_field_hash() f = @res.fetch_field h = { "name" => "id", "table" => "t", "def" => nil, "type" => Mysql::Field::TYPE_LONG, "length" => 11, "max_length" => 1, "flags" => Mysql::Field::NUM_FLAG|Mysql::Field::PRI_KEY_FLAG|Mysql::Field::PART_KEY_FLAG|Mysql::Field::NOT_NULL_FLAG, "decimals" => 0, } assert_equal(h, f.hash) f = @res.fetch_field h = { "name" => "str", "table" => "t", "def" => nil, "type" => Mysql::Field::TYPE_STRING, "length" => 10, "max_length" => 4, "flags" => 0, "decimals" => 0, } assert_equal(h, f.hash) end def test_field_inspect() f = @res.fetch_field assert_equal("#", f.inspect) f = @res.fetch_field assert_equal("#", f.inspect) end def test_is_num() f = @res.fetch_field assert_equal(true, f.is_num?) f = @res.fetch_field assert_equal(false, f.is_num?) end def test_is_not_null() f = @res.fetch_field assert_equal(true, f.is_not_null?) f = @res.fetch_field assert_equal(false, f.is_not_null?) end def test_is_pri_key() f = @res.fetch_field assert_equal(true, f.is_pri_key?) f = @res.fetch_field assert_equal(false, f.is_pri_key?) end end class TC_MysqlStmt < Test::Unit::TestCase def setup() @host, @user, @pass, db, port, sock, flag = ARGV @db = db || "test" @port = port.to_i @sock = sock.nil? || sock.empty? ? nil : sock @flag = flag.to_i @m = Mysql.new(@host, @user, @pass, @db, @port, @sock, @flag) end def teardown() end def test_init() if @m.server_version >= 40100 then s = @m.stmt_init() assert_equal(Mysql::Stmt, s.class) s.close end end def test_prepare() if @m.server_version >= 40100 then s = @m.prepare("select 1") assert_equal(Mysql::Stmt, s.class) s.close end end end if Mysql.client_version >= 40100 class TC_MysqlStmt2 < Test::Unit::TestCase def setup() @host, @user, @pass, db, port, sock, flag = ARGV @db = db || "test" @port = port.to_i @sock = sock.nil? || sock.empty? ? nil : sock @flag = flag.to_i @m = Mysql.new(@host, @user, @pass, @db, @port, @sock, @flag) @s = @m.stmt_init() end def teardown() @s.close @m.close end def test_affected_rows() if @m.server_version >= 40100 then @m.query("create temporary table t (i int, c char(10))") @s.prepare("insert into t values (?,?)") @s.execute(1, "hoge") assert_equal(1, @s.affected_rows()) @s.execute(2, "hoge") @s.execute(3, "hoge") @s.prepare("update t set c=?") @s.execute("fuga") assert_equal(3, @s.affected_rows()) end end =begin def test_attr_get() assert_equal(false, @s.attr_get(Mysql::Stmt::ATTR_UPDATE_MAX_LENGTH)) assert_raises(Mysql::Error){@s.attr_get(999)} end def test_attr_set() @s.attr_set(Mysql::Stmt::ATTR_UPDATE_MAX_LENGTH, true) assert_equal(true, @s.attr_get(Mysql::Stmt::ATTR_UPDATE_MAX_LENGTH)) @s.attr_set(Mysql::Stmt::ATTR_UPDATE_MAX_LENGTH, false) assert_equal(false, @s.attr_get(Mysql::Stmt::ATTR_UPDATE_MAX_LENGTH)) assert_raises(Mysql::Error){@s.attr_set(999, true)} end def test_bind_param() @s.prepare("insert into t values (?,?)") @s.bind_param(123, "abc") @s.bind_param(Time.now, nil) assert_raises(Mysql::Error){@s.bind_param(1, 2, 3)} b = @s.bind_param(Bind.new(Mysql::TYPE_TINY, 99, false)) @s.bind_param(98.765, b) end =end def test_bind_result_nil() if @m.server_version >= 40100 then @m.query("create temporary table t (i int, c char(10), d double, t datetime)") @m.query("insert into t values (123, '9abcdefg', 1.2345, 20050802235011)") @s.prepare("select * from t") @s.bind_result(nil,nil,nil,nil) @s.execute a = @s.fetch assert_equal([123, "9abcdefg", 1.2345, Mysql::Time.new(2005,8,2,23,50,11)], a) end end def test_bind_result_numeric() if @m.server_version >= 40100 then @m.query("create temporary table t (i int, c char(10), d double, t datetime)") @m.query("insert into t values (123, '9abcdefg', 1.2345, 20050802235011)") @s.prepare("select * from t") @s.bind_result(Numeric, Numeric, Numeric, Numeric) @s.execute a = @s.fetch if Mysql.client_version < 50000 then assert_equal([123, 9, 1, 2005], a) else assert_equal([123, 9, 1, 20050802235011], a) end end end def test_bind_result_integer() if @m.server_version >= 40100 then @m.query("create temporary table t (i int, c char(10), d double, t datetime)") @m.query("insert into t values (123, '9abcdefg', 1.2345, 20050802235011)") @s.prepare("select * from t") @s.bind_result(Integer, Integer, Integer, Integer) @s.execute a = @s.fetch if Mysql.client_version < 50000 then assert_equal([123, 9, 1, 2005], a) else assert_equal([123, 9, 1, 20050802235011], a) end end end def test_bind_result_fixnum() if @m.server_version >= 40100 then @m.query("create temporary table t (i int, c char(10), d double, t datetime)") @m.query("insert into t values (123, '9abcdefg', 1.2345, 20050802235011)") @s.prepare("select * from t") @s.bind_result(Fixnum, Fixnum, Fixnum, Fixnum) @s.execute a = @s.fetch if Mysql.client_version < 50000 then assert_equal([123, 9, 1, 2005], a) else assert_equal([123, 9, 1, 20050802235011.0], a) end end end def test_bind_result_string() if @m.server_version >= 40100 then @m.query("create temporary table t (i int, c char(10), d double, t datetime)") @m.query("insert into t values (123, '9abcdefg', 1.2345, 20050802235011)") @s.prepare("select * from t") @s.bind_result(String, String, String, String) @s.execute a = @s.fetch assert_equal(["123", "9abcdefg", "1.2345", "2005-08-02 23:50:11"], a) end end def test_bind_result_float() if @m.server_version >= 40100 then @m.query("create temporary table t (i int, c char(10), d double, t datetime)") @m.query("insert into t values (123, '9abcdefg', 1.2345, 20050802235011)") @s.prepare("select * from t") @s.bind_result(Float, Float, Float, Float) @s.execute a = @s.fetch if Mysql.client_version < 50000 then assert_equal([123.0, 9.0, 1.2345, 2005.0], a) else assert_equal([123.0, 9.0, 1.2345, 20050802235011.0], a) end end end def test_bind_result_mysqltime() if @m.server_version >= 40100 then @m.query("create temporary table t (i int, c char(10), d double, t datetime)") @m.query("insert into t values (123, '9abcdefg', 1.2345, 20050802235011)") @s.prepare("select * from t") @s.bind_result(Mysql::Time, Mysql::Time, Mysql::Time, Mysql::Time) @s.execute a = @s.fetch if Mysql.client_version < 50000 then assert_equal([Mysql::Time.new, Mysql::Time.new, Mysql::Time.new, Mysql::Time.new(2005,8,2,23,50,11)], a) else assert_equal([Mysql::Time.new(2000,1,23), Mysql::Time.new, Mysql::Time.new, Mysql::Time.new(2005,8,2,23,50,11)], a) end end end def test_bind_result_unknown() if @m.server_version >= 40100 then @m.query("create temporary table t (i int, c char(10), d double, t datetime)") @m.query("insert into t values (123, '9abcdefg', 1.2345, 20050802235011)") @s.prepare("select * from t") assert_raises(TypeError){@s.bind_result(Time, nil, nil, nil)} end end def test_bind_result_unmatch_count() if @m.server_version >= 40100 then @m.query("create temporary table t (i int, c char(10), d double, t datetime)") @m.query("insert into t values (123, '9abcdefg', 1.2345, 20050802235011)") @s.prepare("select * from t") assert_raises(Mysql::Error){@s.bind_result(nil, nil)} end end def test_data_seek() if @m.server_version >= 40100 then @m.query("create temporary table t (i int)") @m.query("insert into t values (0),(1),(2),(3),(4),(5)") @s.prepare("select i from t") @s.execute assert_equal([0], @s.fetch) assert_equal([1], @s.fetch) assert_equal([2], @s.fetch) @s.data_seek(5) assert_equal([5], @s.fetch) @s.data_seek(1) assert_equal([1], @s.fetch) end end =begin def test_errno() @s.errno() end def test_error() @s.error() end =end def test_execute() if @m.server_version >= 40100 then @m.query("create temporary table t (i int)") @s.prepare("insert into t values (123)") @s.execute() assert_equal(1, @s.affected_rows) @s.execute() assert_equal(1, @s.affected_rows) assert_equal(2, @m.query("select count(*) from t").fetch_row[0].to_i) end end def test_execute2() if @m.server_version >= 40100 then @m.query("create temporary table t (i int)") @s.prepare("insert into t values (?)") @s.execute(123) @s.execute("456") @s.prepare("select * from t") @s.execute assert_equal([123], @s.fetch) assert_equal([456], @s.fetch) end end def test_execute3() if @m.server_version >= 40100 then @m.query("create temporary table t (i int, c char(255), t timestamp)") @s.prepare("insert into t values (?,?,?)") @s.execute(123, "hoge", Time.local(2005,7,19,23,53,0)); assert_raises(Mysql::Error){@s.execute(123, "hoge")} assert_raises(Mysql::Error){@s.execute(123, "hoge", 0, "fuga")} @s.prepare("select * from t") @s.execute assert_equal([123, "hoge", Mysql::Time.new(2005,7,19,23,53,0)], @s.fetch) end end def test_execute4() if @m.server_version >= 40100 then @m.query("create temporary table t (i int, c char(255), t timestamp)") @s.prepare("insert into t values (?,?,?)") @s.execute(nil, "hoge", Mysql::Time.new(2005,7,19,23,53,0)); @s.prepare("select * from t") @s.execute assert_equal([nil, "hoge", Mysql::Time.new(2005,7,19,23,53,0)], @s.fetch) end end def test_execute5() if @m.server_version >= 40100 then [30, 31, 32, 62, 63].each do |i| v, = @m.prepare("select cast(? as signed)").execute(2**i-1).fetch assert_equal(2**i-1, v) v, = @m.prepare("select cast(? as signed)").execute(-(2**i)).fetch assert_equal(-(2**i), v) end end end def test_fetch() if @m.server_version >= 40100 then @s.prepare("select 123, 'abc', null") @s.execute() assert_equal([123, "abc", nil], @s.fetch()) end end def test_fetch_bit() if @m.client_version >= 50003 and @m.server_version >= 50003 then @m.query("create temporary table t (i bit(8))") @m.query("insert into t values (0),(-1),(127),(-128),(255),(-255),(256)") @s.prepare("select i from t") @s.execute assert_equal(["\x00"], @s.fetch) assert_equal(["\xff"], @s.fetch) assert_equal(["\x7f"], @s.fetch) assert_equal(["\xff"], @s.fetch) assert_equal(["\xff"], @s.fetch) assert_equal(["\xff"], @s.fetch) assert_equal(["\xff"], @s.fetch) @m.query("create temporary table t2 (i bit(64))") @m.query("insert into t2 values (0),(-1),(4294967296),(18446744073709551615),(18446744073709551616)") @s.prepare("select i from t2") @s.execute assert_equal(["\x00\x00\x00\x00\x00\x00\x00\x00"], @s.fetch) assert_equal(["\xff\xff\xff\xff\xff\xff\xff\xff"], @s.fetch) assert_equal(["\x00\x00\x00\x01\x00\x00\x00\x00"], @s.fetch) assert_equal(["\xff\xff\xff\xff\xff\xff\xff\xff"], @s.fetch) assert_equal(["\xff\xff\xff\xff\xff\xff\xff\xff"], @s.fetch) end end def test_fetch_tinyint() if @m.server_version >= 40100 then @m.query("create temporary table t (i tinyint)") @m.query("insert into t values (0),(-1),(127),(-128),(255),(-255)") @s.prepare("select i from t") @s.execute assert_equal([0], @s.fetch) assert_equal([-1], @s.fetch) assert_equal([127], @s.fetch) assert_equal([-128], @s.fetch) assert_equal([127], @s.fetch) assert_equal([-128], @s.fetch) end end def test_fetch_tinyint_unsigned() if @m.server_version >= 40100 then @m.query("create temporary table t (i tinyint unsigned)") @m.query("insert into t values (0),(-1),(127),(-128),(255),(-255),(256)") @s.prepare("select i from t") @s.execute assert_equal([0], @s.fetch) assert_equal([0], @s.fetch) assert_equal([127], @s.fetch) assert_equal([0], @s.fetch) assert_equal([255], @s.fetch) assert_equal([0], @s.fetch) assert_equal([255], @s.fetch) end end def test_fetch_smallint() if @m.server_version >= 40100 then @m.query("create temporary table t (i smallint)") @m.query("insert into t values (0),(-1),(32767),(-32768),(65535),(-65535),(65536)") @s.prepare("select i from t") @s.execute assert_equal([0], @s.fetch) assert_equal([-1], @s.fetch) assert_equal([32767], @s.fetch) assert_equal([-32768], @s.fetch) assert_equal([32767], @s.fetch) assert_equal([-32768], @s.fetch) end end def test_fetch_smallint_unsigned() if @m.server_version >= 40100 then @m.query("create temporary table t (i smallint unsigned)") @m.query("insert into t values (0),(-1),(32767),(-32768),(65535),(-65535),(65536)") @s.prepare("select i from t") @s.execute assert_equal([0], @s.fetch) assert_equal([0], @s.fetch) assert_equal([32767], @s.fetch) assert_equal([0], @s.fetch) assert_equal([65535], @s.fetch) assert_equal([0], @s.fetch) assert_equal([65535], @s.fetch) end end def test_fetch_mediumint() if @m.server_version >= 40100 then @m.query("create temporary table t (i mediumint)") @m.query("insert into t values (0),(-1),(8388607),(-8388608),(16777215),(-16777215),(16777216)") @s.prepare("select i from t") @s.execute assert_equal([0], @s.fetch) assert_equal([-1], @s.fetch) assert_equal([8388607], @s.fetch) assert_equal([-8388608], @s.fetch) assert_equal([8388607], @s.fetch) assert_equal([-8388608], @s.fetch) end end def test_fetch_mediumint_unsigned() if @m.server_version >= 40100 then @m.query("create temporary table t (i mediumint unsigned)") @m.query("insert into t values (0),(-1),(8388607),(-8388608),(16777215),(-16777215),(16777216)") @s.prepare("select i from t") @s.execute assert_equal([0], @s.fetch) assert_equal([0], @s.fetch) assert_equal([8388607], @s.fetch) assert_equal([0], @s.fetch) assert_equal([16777215], @s.fetch) assert_equal([0], @s.fetch) assert_equal([16777215], @s.fetch) end end def test_fetch_int() if @m.server_version >= 40100 then @m.query("create temporary table t (i int)") @m.query("insert into t values (0),(-1),(2147483647),(-2147483648),(4294967295),(-4294967295),(4294967296)") @s.prepare("select i from t") @s.execute assert_equal([0], @s.fetch) assert_equal([-1], @s.fetch) assert_equal([2147483647], @s.fetch) assert_equal([-2147483648], @s.fetch) assert_equal([2147483647], @s.fetch) assert_equal([-2147483648], @s.fetch) end end def test_fetch_int_unsigned() if @m.server_version >= 40100 then @m.query("create temporary table t (i int unsigned)") @m.query("insert into t values (0),(-1),(2147483647),(-2147483648),(4294967295),(-4294967295),(4294967296)") @s.prepare("select i from t") @s.execute assert_equal([0], @s.fetch) assert_equal([0], @s.fetch) assert_equal([2147483647], @s.fetch) assert_equal([0], @s.fetch) assert_equal([4294967295], @s.fetch) assert_equal([0], @s.fetch) assert_equal([4294967295], @s.fetch) end end def test_fetch_bigint() if @m.server_version >= 40100 then @m.query("create temporary table t (i bigint)") @m.query("insert into t values (0),(-1),(9223372036854775807),(-9223372036854775808),(18446744073709551615),(-18446744073709551615),(18446744073709551616)") @s.prepare("select i from t") @s.execute assert_equal([0], @s.fetch) assert_equal([-1], @s.fetch) assert_equal([9223372036854775807], @s.fetch) assert_equal([-9223372036854775808], @s.fetch) if @m.server_version >= 50000 then assert_equal([9223372036854775807], @s.fetch) else assert_equal([-1], @s.fetch) # MySQL problem end assert_equal([-9223372036854775808], @s.fetch) assert_equal([9223372036854775807], @s.fetch) end end def test_fetch_bigint_unsigned() if @m.server_version >= 40100 then @m.query("create temporary table t (i bigint unsigned)") @m.query("insert into t values (0),(-1),(9223372036854775807),(-9223372036854775808),(18446744073709551615),(-18446744073709551615),(18446744073709551616)") @s.prepare("select i from t") @s.execute assert_equal([0], @s.fetch) if @m.server_version >= 50000 then assert_equal([0], @s.fetch) else assert_equal([18446744073709551615], @s.fetch) # MySQL problem end assert_equal([9223372036854775807], @s.fetch) if @m.server_version >= 50000 then assert_equal([0], @s.fetch) else assert_equal([9223372036854775808], @s.fetch) # MySQL problem end assert_equal([18446744073709551615], @s.fetch) assert_equal([0], @s.fetch) assert_equal([18446744073709551615], @s.fetch) end end def test_fetch_float() if @m.server_version >= 40100 then @m.query("create temporary table t (i float)") @m.query("insert into t values (0),(-3.402823466E+38),(-1.175494351E-38),(1.175494351E-38),(3.402823466E+38)") @s.prepare("select i from t") @s.execute assert_equal([0], @s.fetch) assert_in_delta(-3.402823466E+38, @s.fetch[0], 0.000000001E+38) assert_in_delta(-1.175494351E-38, @s.fetch[0], 0.000000001E-38) assert_in_delta(1.175494351E-38, @s.fetch[0], 0.000000001E-38) assert_in_delta(3.402823466E+38, @s.fetch[0], 0.000000001E+38) end end def test_fetch_float_unsigned() if @m.server_version >= 40100 then @m.query("create temporary table t (i float unsigned)") @m.query("insert into t values (0),(-3.402823466E+38),(-1.175494351E-38),(1.175494351E-38),(3.402823466E+38)") @s.prepare("select i from t") @s.execute assert_equal([0], @s.fetch) assert_equal([0], @s.fetch) assert_equal([0], @s.fetch) assert_in_delta(1.175494351E-38, @s.fetch[0], 0.000000001E-38) assert_in_delta(3.402823466E+38, @s.fetch[0], 0.000000001E+38) end end def test_fetch_double() if @m.server_version >= 40100 then @m.query("create temporary table t (i double)") @m.query("insert into t values (0),(-1.7976931348623157E+308),(-2.2250738585072014E-308),(2.2250738585072014E-308),(1.7976931348623157E+308)") @s.prepare("select i from t") @s.execute assert_equal([0], @s.fetch) assert_in_delta(-Float::MAX, @s.fetch[0], Float::EPSILON) assert_in_delta(-Float::MIN, @s.fetch[0], Float::EPSILON) assert_in_delta(Float::MIN, @s.fetch[0], Float::EPSILON) assert_in_delta(Float::MAX, @s.fetch[0], Float::EPSILON) end end def test_fetch_double_unsigned() if @m.server_version >= 40100 then @m.query("create temporary table t (i double unsigned)") @m.query("insert into t values (0),(-1.7976931348623157E+308),(-2.2250738585072014E-308),(2.2250738585072014E-308),(1.7976931348623157E+308)") @s.prepare("select i from t") @s.execute assert_equal([0], @s.fetch) assert_equal([0], @s.fetch) assert_equal([0], @s.fetch) assert_in_delta(Float::MIN, @s.fetch[0], Float::EPSILON) assert_in_delta(Float::MAX, @s.fetch[0], Float::EPSILON) end end def test_fetch_decimal() if (@m.server_version >= 50000 and Mysql.client_version >= 50000) or (@m.server_version >= 40100 and @m.server_version < 50000) then @m.query("create temporary table t (i decimal)") @m.query("insert into t values (0),(9999999999),(-9999999999),(10000000000),(-10000000000)") @s.prepare("select i from t") @s.execute assert_equal(["0"], @s.fetch) assert_equal(["9999999999"], @s.fetch) assert_equal(["-9999999999"], @s.fetch) if @m.server_version < 50000 then assert_equal(["10000000000"], @s.fetch) # MySQL problem else assert_equal(["9999999999"], @s.fetch) end assert_equal(["-9999999999"], @s.fetch) end end def test_fetch_decimal_unsigned() if (@m.server_version >= 50000 and Mysql.client_version >= 50000) or (@m.server_version >= 40100 and @m.server_version < 50000) then @m.query("create temporary table t (i decimal unsigned)") @m.query("insert into t values (0),(9999999998),(9999999999),(-9999999998),(-9999999999),(10000000000),(-10000000000)") @s.prepare("select i from t") @s.execute assert_equal(["0"], @s.fetch) assert_equal(["9999999998"], @s.fetch) assert_equal(["9999999999"], @s.fetch) assert_equal(["0"], @s.fetch) assert_equal(["0"], @s.fetch) assert_equal(["9999999999"], @s.fetch) assert_equal(["0"], @s.fetch) end end def test_fetch_date() if @m.server_version >= 40100 then @m.query("create temporary table t (i date)") @m.query("insert into t values ('0000-00-00'),('1000-01-01'),('9999-12-31')") @s.prepare("select i from t") @s.execute assert_equal([Mysql::Time.new(0,0,0)], @s.fetch) assert_equal([Mysql::Time.new(1000,1,1)], @s.fetch) assert_equal([Mysql::Time.new(9999,12,31)], @s.fetch) end end def test_fetch_datetime() if @m.server_version >= 40100 then @m.query("create temporary table t (i datetime)") @m.query("insert into t values ('0000-00-00 00:00:00'),('1000-01-01 00:00:00'),('9999-12-31 23:59:59')") @s.prepare("select i from t") @s.execute assert_equal([Mysql::Time.new(0,0,0,0,0,0)], @s.fetch) assert_equal([Mysql::Time.new(1000,1,1,0,0,0)], @s.fetch) assert_equal([Mysql::Time.new(9999,12,31,23,59,59)], @s.fetch) end end def test_fetch_timestamp() if @m.server_version >= 40100 then @m.query("create temporary table t (i timestamp)") @m.query("insert into t values ('1970-01-02 00:00:00'),('2037-12-30 23:59:59')") @s.prepare("select i from t") @s.execute assert_equal([Mysql::Time.new(1970,1,2,0,0,0)], @s.fetch) assert_equal([Mysql::Time.new(2037,12,30,23,59,59)], @s.fetch) end end def test_fetch_time() if @m.server_version >= 40100 then @m.query("create temporary table t (i time)") @m.query("insert into t values ('-838:59:59'),(0),('838:59:59')") @s.prepare("select i from t") @s.execute assert_equal([Mysql::Time.new(0,0,0,838,59,59,true)], @s.fetch) assert_equal([Mysql::Time.new(0,0,0,0,0,0,false)], @s.fetch) assert_equal([Mysql::Time.new(0,0,0,838,59,59,false)], @s.fetch) end end def test_fetch_year() if @m.server_version >= 40100 then @m.query("create temporary table t (i year)") @m.query("insert into t values (0),(70),(69),(1901),(2155)") @s.prepare("select i from t") @s.execute assert_equal([0], @s.fetch) assert_equal([1970], @s.fetch) assert_equal([2069], @s.fetch) assert_equal([1901], @s.fetch) assert_equal([2155], @s.fetch) end end def test_fetch_char() if @m.server_version >= 40100 then @m.query("create temporary table t (i char(10))") @m.query("insert into t values (null),('abc')") @s.prepare("select i from t") @s.execute assert_equal([nil], @s.fetch) assert_equal(["abc"], @s.fetch) end end def test_fetch_varchar() if @m.server_version >= 40100 then @m.query("create temporary table t (i varchar(10))") @m.query("insert into t values (null),('abc')") @s.prepare("select i from t") @s.execute assert_equal([nil], @s.fetch) assert_equal(["abc"], @s.fetch) end end def test_fetch_binary() if @m.server_version >= 40100 then @m.query("create temporary table t (i binary(10))") @m.query("insert into t values (null),('abc')") @s.prepare("select i from t") @s.execute assert_equal([nil], @s.fetch) if @m.server_version >= 50000 then assert_equal(["abc\0\0\0\0\0\0\0"], @s.fetch) else assert_equal(["abc"], @s.fetch) end end end def test_fetch_varbinary() if @m.server_version >= 40100 then @m.query("create temporary table t (i varbinary(10))") @m.query("insert into t values (null),('abc')") @s.prepare("select i from t") @s.execute assert_equal([nil], @s.fetch) assert_equal(["abc"], @s.fetch) end end def test_fetch_tinyblob() if @m.server_version >= 40100 then @m.query("create temporary table t (i tinyblob)") @m.query("insert into t values (null),('abc')") @s.prepare("select i from t") @s.execute assert_equal([nil], @s.fetch) assert_equal(["abc"], @s.fetch) end end def test_fetch_tinytext() if @m.server_version >= 40100 then @m.query("create temporary table t (i tinytext)") @m.query("insert into t values (null),('abc')") @s.prepare("select i from t") @s.execute assert_equal([nil], @s.fetch) assert_equal(["abc"], @s.fetch) end end def test_fetch_blob() if @m.server_version >= 40100 then @m.query("create temporary table t (i blob)") @m.query("insert into t values (null),('abc')") @s.prepare("select i from t") @s.execute assert_equal([nil], @s.fetch) assert_equal(["abc"], @s.fetch) end end def test_fetch_text() if @m.server_version >= 40100 then @m.query("create temporary table t (i text)") @m.query("insert into t values (null),('abc')") @s.prepare("select i from t") @s.execute assert_equal([nil], @s.fetch) assert_equal(["abc"], @s.fetch) end end def test_fetch_mediumblob() if @m.server_version >= 40100 then @m.query("create temporary table t (i mediumblob)") @m.query("insert into t values (null),('abc')") @s.prepare("select i from t") @s.execute assert_equal([nil], @s.fetch) assert_equal(["abc"], @s.fetch) end end def test_fetch_mediumtext() if @m.server_version >= 40100 then @m.query("create temporary table t (i mediumtext)") @m.query("insert into t values (null),('abc')") @s.prepare("select i from t") @s.execute assert_equal([nil], @s.fetch) assert_equal(["abc"], @s.fetch) end end def test_fetch_longblob() if @m.server_version >= 40100 then @m.query("create temporary table t (i longblob)") @m.query("insert into t values (null),('abc')") @s.prepare("select i from t") @s.execute assert_equal([nil], @s.fetch) assert_equal(["abc"], @s.fetch) end end def test_fetch_longtext() if @m.server_version >= 40100 then @m.query("create temporary table t (i longtext)") @m.query("insert into t values (null),('abc')") @s.prepare("select i from t") @s.execute assert_equal([nil], @s.fetch) assert_equal(["abc"], @s.fetch) end end def test_fetch_enum() if @m.server_version >= 40100 then @m.query("create temporary table t (i enum('abc','def'))") @m.query("insert into t values (null),(0),(1),(2),('abc'),('def'),('ghi')") @s.prepare("select i from t") @s.execute assert_equal([nil], @s.fetch) assert_equal([""], @s.fetch) assert_equal(["abc"], @s.fetch) assert_equal(["def"], @s.fetch) assert_equal(["abc"], @s.fetch) assert_equal(["def"], @s.fetch) assert_equal([""], @s.fetch) end end def test_fetch_set() if @m.server_version >= 40100 then @m.query("create temporary table t (i set('abc','def'))") @m.query("insert into t values (null),(0),(1),(2),(3),('abc'),('def'),('abc,def'),('ghi')") @s.prepare("select i from t") @s.execute assert_equal([nil], @s.fetch) assert_equal([""], @s.fetch) assert_equal(["abc"], @s.fetch) assert_equal(["def"], @s.fetch) assert_equal(["abc,def"], @s.fetch) assert_equal(["abc"], @s.fetch) assert_equal(["def"], @s.fetch) assert_equal(["abc,def"], @s.fetch) assert_equal([""], @s.fetch) end end def test_each() if @m.server_version >= 40100 then @m.query("create temporary table t (i int, c char(255), d datetime)") @m.query("insert into t values (1,'abc','19701224235905'),(2,'def','21120903123456'),(3,'123',null)") @s.prepare("select * from t") @s.execute c = 0 @s.each do |a| case c when 0 assert_equal([1,"abc",Mysql::Time.new(1970,12,24,23,59,05)], a) when 1 assert_equal([2,"def",Mysql::Time.new(2112,9,3,12,34,56)], a) when 2 assert_equal([3,"123",nil], a) else raise end c += 1 end end end def test_field_count() if @m.server_version >= 40100 then @s.prepare("select 1,2,3") @s.execute() assert_equal(3, @s.field_count()) @s.prepare("set @a=1") @s.execute() assert_equal(0, @s.field_count()) end end def test_free_result() if @m.server_version >= 40100 then @s.free_result() @s.prepare("select 1,2,3") @s.execute() @s.free_result() end end def test_insert_id() if @m.server_version >= 40100 then @m.query("create temporary table t (i bigint auto_increment, unique(i))") @s.prepare("insert into t values (?)") @s.execute(0) assert_equal(1, @s.insert_id()) @s.execute(0) assert_equal(2, @s.insert_id()) @s.execute(2**32) assert_equal(2**32, @s.insert_id()) @s.execute(0) assert_equal(2**32+1, @s.insert_id()) end end def test_num_rows() if @m.server_version >= 40100 then @m.query("create temporary table t (i int)") @m.query("insert into t values (1),(2),(3),(4)") @s.prepare("select * from t") @s.execute assert_equal(4, @s.num_rows()) end end def test_param_count() if @m.server_version >= 40100 then @m.query("create temporary table t (a int, b int, c int)") @s.prepare("select * from t") assert_equal(0, @s.param_count()) @s.prepare("insert into t values (?,?,?)") assert_equal(3, @s.param_count()) end end =begin def test_param_metadata() @s.param_metadata() end =end def test_prepare() if @m.server_version >= 40100 then @s.prepare("select 1") assert_raises(Mysql::Error){@s.prepare("invalid syntax")} end end =begin def test_reset() @s.reset() end =end def test_result_metadata() if @m.server_version >= 40100 then @s.prepare("select 1 foo, 2 bar") res = @s.result_metadata() f = res.fetch_fields assert_equal("foo", f[0].name) assert_equal("bar", f[1].name) end end def test_result_metadata_nodata() if @m.server_version >= 40100 then @m.query("create temporary table t (i int)") @s.prepare("insert into t values (1)") assert_equal(nil, @s.result_metadata()) end end def test_row_seek_tell() if @m.server_version >= 40100 then @m.query("create temporary table t (i int)") @m.query("insert into t values (0),(1),(2),(3),(4)") @s.prepare("select * from t") @s.execute row0 = @s.row_tell assert_equal([0], @s.fetch) assert_equal([1], @s.fetch) row2 = @s.row_seek(row0) assert_equal([0], @s.fetch) @s.row_seek(row2) assert_equal([2], @s.fetch) end end =begin def test_send_long_data() @m.query("create temporary table t (i int, t text)") @s.prepare("insert into t values (?,?)") @s.send_long_data(1, "long long data ") @s.send_long_data(1, "long long data2") assert_raises(Mysql::Error){@s.send_long_data(9, "invalid param number")} @s.execute(99, "hoge") assert_equal("long long data long long data2", @m.query("select t from t").fetch_row[0]) end =end def test_sqlstate() if @m.server_version >= 40100 then @s.prepare("select 1") if @m.client_version >= 50000 then assert_equal("00000", @s.sqlstate) else assert_equal("", @s.sqlstate) end assert_raises(Mysql::Error){@s.prepare("hogehoge")} assert_equal("42000", @s.sqlstate) end end =begin def test_store_result() @s.store_result() end =end end if Mysql.client_version >= 40100 class TC_MysqlTime < Test::Unit::TestCase def setup() end def teardown() end def test_init() t = Mysql::Time.new assert_equal(0, t.year); assert_equal(0, t.month); assert_equal(0, t.day); assert_equal(0, t.hour); assert_equal(0, t.minute); assert_equal(0, t.second); assert_equal(false, t.neg); assert_equal(0, t.second_part); end def test_year() t = Mysql::Time.new assert_equal(2005, t.year = 2005) assert_equal(2005, t.year) end def test_month() t = Mysql::Time.new assert_equal(11, t.month = 11) assert_equal(11, t.month) end def test_day() t = Mysql::Time.new assert_equal(23, t.day = 23) assert_equal(23, t.day) end def test_hour() t = Mysql::Time.new assert_equal(15, t.hour = 15) assert_equal(15, t.hour) end def test_minute() t = Mysql::Time.new assert_equal(58, t.month = 58) assert_equal(58, t.month) end def test_second() t = Mysql::Time.new assert_equal(34, t.second = 34) assert_equal(34, t.second) end def test_tos() t = Mysql::Time.new(2005, 7, 19, 10, 15, 49) assert_equal("2005-07-19 10:15:49", t.to_s) end def test_eql() t1 = Mysql::Time.new(2005,7,19,23,56,13) t2 = Mysql::Time.new(2005,7,19,23,56,13) assert_equal(t1, t2) end end if Mysql.client_version >= 40100 ruby-mysql-2.8.2+gem2deb/tommy.css000066400000000000000000000024571163166767300170570ustar00rootroot00000000000000body { color: black; background: white; margin-left: 10%; margin-right: 10%; } h1 { color: white; background: #08d; width: 100%; } h1 a { color: white; } h1 a:link { } h1 a:visited { color: white; } h1 a:hover { } h2 { width: 100%; border: thin #0cc; border-style: solid none; background: #cff; } h3 { width: 100%; border: thin #0cc; border-style: none none solid; background: #eff; } h4 { border: thin #0cc; border-style: none none solid; } dt { font-weight: bold; } dd { margin-bottom: 3ex; } table { border-collapse: collapse; border: thin solid; } tr,th,td { border: thin solid; padding: 3px; } th { background-color: #00ffff; } td { background-color: #eeeeee; } div.intro { margin-right: 10%; margin-left: 10%; font-size: 90%; } div.code { margin-left: 10%; color: white; background: black; border: thin inset; padding: 4px; } div.code2 { margin-left: 10%; color: white; background: darkgreen; border: thin inset; padding: 4px; } pre { margin: 20px; padding: 4px; border: #363 inset; color: #fff; background: #232; width: 80%; } /* a { background: #eee; } */ a:link { color: #008; } a:visited { color: black; } a:hover { background: #fcc; } .red { color: red; } .notice { font-weight: bold; background: #f88; } .input { font-weight:bold; }