DBD::drizzleでMySQLに接続してみる
DrizzleのクライアントをCentOS 5.3に入れてPerl DBIでMySQL 5.1につないでみた日記。Drizzleって何?って方はIntroducing the Drizzle Projectをご覧ください。
Drizzle Client & Protocol LibraryからDownloadsと書いてあるリンクをたどって、libdrizzle-0.3.tar.gzをダウンロードする。libdrizzleのビルドは何事もない感じ。
$ tar xvzf libdrizzle-0.3.tar.gz $ cd libdrizzle-0.3 $ ./configure $ make $ sudo make install
CPANからDBD-drizzle-0.100.tar.gzをダウンロードする。ところがビルドしようと素でperl Makefile.PLを叩くと失敗する。
$ tar xvzf DBD-drizzle-0.100.tar.gz $ cd DBD-drizzle-0.100 $ perl Makefile.PL Must specify package names on the command line Cannot find the file 'pkg-config'! Your execution PATH doesn't seem not contain the path to pkg-config. Resorting to guessed values! running pkg-config --testdb libdrizzle --testdb: unknown option running pkg-config --testhost libdrizzle --testhost: unknown option running pkg-config --cflags libdrizzle Package libdrizzle was not found in the pkg-config search path. Perhaps you should add the directory containing `libdrizzle.pc' to the PKG_CONFIG_PATH environment variable No package 'libdrizzle' found running pkg-config --libs libdrizzle Package libdrizzle was not found in the pkg-config search path. Perhaps you should add the directory containing `libdrizzle.pc' to the PKG_CONFIG_PATH environment variable No package 'libdrizzle' found running pkg-config --nocatchstderr libdrizzle --nocatchstderr: unknown option running pkg-config --ssl libdrizzle --ssl: unknown option running pkg-config --nofoundrows libdrizzle --nofoundrows: unknown option I will use the following settings for compiling and testing: libs (pkg-config) = -lz pkg-config (guessed ) = pkg-config testdb (default ) = test To change these settings, see 'perl Makefile.PL --help' and 'perldoc INSTALL'. Use of uninitialized value in concatenation (.) or string at Makefile.PL line 140. Using DBI 1.608 (for perl 5.008008 on i386-linux-thread-multi) installed in /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/auto/DBI/ Writing Makefile for DBD::drizzle
MySQLの場合はmysql_configコマンドでコンパイルオプションが取れるけど、Drizzleの場合は標準的なpkg-configコマンドを使うらしい。言われるがままにPKG_CONFIG_PATHを設定する。
$ export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig $ pkg-config --cflags libdrizzle -I/usr/local/include $ pkg-config --libs libdrizzle -L/usr/local/lib -ldrizzle
なるほど。リトライ。
$ perl Makefile.PL Must specify package names on the command line Cannot find the file 'pkg-config'! Your execution PATH doesn't seem not contain the path to pkg-config. Resorting to guessed values! running pkg-config --testdb libdrizzle --testdb: unknown option running pkg-config --testhost libdrizzle --testhost: unknown option running pkg-config --cflags libdrizzle running pkg-config --libs libdrizzle running pkg-config --nocatchstderr libdrizzle --nocatchstderr: unknown option running pkg-config --ssl libdrizzle --ssl: unknown option running pkg-config --nofoundrows libdrizzle --nofoundrows: unknown option I will use the following settings for compiling and testing: cflags (pkg-config) = -I/usr/local/include libs (pkg-config) = -L/usr/local/lib -ldrizzle -lz pkg-config (guessed ) = pkg-config testdb (default ) = test To change these settings, see 'perl Makefile.PL --help' and 'perldoc INSTALL'. Using DBI 1.608 (for perl 5.008008 on i386-linux-thread-multi) installed in /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/auto/DBI/ Writing Makefile for DBD::drizzle
なんかまだ怪しいけど…とりあえず先に進む。
$ make $ sudo make install
サンプル。
#!/usr/bin/perl use utf8; use open ':utf8'; binmode(STDIN, ':utf8'); binmode(STDOUT, ':utf8'); binmode(STDERR, ':utf8'); use strict; use warnings; use Encode; use DBI qw(:sql_types); my ($dbh); eval { my ($dsn, $sth, $row, $ename); $dsn = 'DBI:drizzle:scott;port=3306'; # ※1 ※2 ※3 ※4 # $dsn = 'DBI:mysql:scott;mysql_read_default_file=/etc/my.cnf'; $dbh = DBI->connect($dsn, 'scott', '', { RaiseError => 1, PrintError => 0, AutoCommit => 0 }); # ※5 ※6 ※7 $sth = $dbh->prepare_cached('insert into emp (empno, ename) values (?, ?)'); $sth->bind_param(1, 9001, SQL_INTEGER); $sth->bind_param(2, 'テスト', SQL_VARCHAR); $sth->execute(); $sth->finish(); $sth = $dbh->prepare_cached('select ename from emp where empno = ?'); $sth->bind_param(1, 9001, SQL_INTEGER); $sth->execute(); while ($row = $sth->fetch()) { $ename = decode_utf8($row->[0]); print "$ename\n"; } $sth->finish(); $dbh->rollback(); $dbh->disconnect(); }; if ($@) { print decode_utf8($@); if ($dbh) { eval { $dbh->rollback(); }; eval { $dbh->disconnect(); }; } exit(1); }
動いた。気づいたことをいくつか。
- [仕様] UNIX Socket経由の接続はできない。必ずTCP/IP経由
- [仕様] DrizzleのTCPポートは4427番なので、MySQLに接続するときは明示的に3306番を指定する
- [仕様] UTF-8しかサポートしないので、default-character-setとかset namesしなくていい。ある意味文字化けフリー
- [未実装] drizzle_read_default_fileというパラメータでmy.cnfを読み込めるとマニュアルに書いてあったけど、ソースを見たらまだ実装されてなかった
- [仕様] 認証機能がないので、パスワードつきのユーザアカウントだと接続できない
- [未実装] どうやらRaiseErrorしてくれない
- [未実装] どうしてもPrintErrorを抑止できない
なるほど確かにバージョン0.100 (^^;
うまくいったらクライアントの性能を測ってみようと思ったんだけど、まだ早いね。libdrizzleはBSDライセンスというところに魅力を感じる人もいると思うので、今後に期待。
2009/06/21追記
id:tokuhiromさんから「MySQLプロトコルでつなぐ場合はDRIZZLE_CON_MYSQLオプションを指定すべき」というコメントをいただきました。DBD::drizzleのソースを確認してみると、dbdimp.cの1,031行目が実際に接続している箇所のようです。
if (imp_dbh->con != NULL) { imp_dbh->con= drizzle_con_add_tcp(drizzle, NULL, host, portNr, user, password, dbname, DRIZZLE_CON_NONE); } ret = drizzle_con_connect(imp_dbh->con);
最後の引数で何種類かオプションを指定できるのですが、今のところDBD::drizzleには何も作りこまれていません。試しに直接書きかえて再ビルドしてみました。
if (imp_dbh->con != NULL) { imp_dbh->con= drizzle_con_add_tcp(drizzle, NULL, host, portNr, user, password, dbname, DRIZZLE_CON_MYSQL); } ret = drizzle_con_connect(imp_dbh->con);
すると、portを指定しなくてもMySQLに接続することができました。
$dsn = 'DBI:drizzle:scott'; # $dsn = 'DBI:drizzle:scott;port=3306';
バージョン1.0までの道のりは長そうです。