DoqueDBにはPerlのAPIも付属しています。
現時点ではこれといったマニュアルもなく、また、特別なインストーラーなどは準備しておりません。ソースコードの doqueDB/sydney/Perl フォルダー以下のファイル(DBDとNet以外にあるものは不要)を適当な場所に配置しておけば、perl のインクルードパス配列(@INC)に加えるだけで使用可能となります。
DBIの実装クラスとして実現されており、主要なメソッドは提供されているので、多くの操作は他のデータベースを扱う場合と同様に使用できます。doquedb/sydney/Perl/DBD/sqli.pl が、コマンドライン版のsqliのと同様のものを実装しているサンプルコードとなりますので、それを参照するとよいでしょう。
データベースへ接続する典型的なプログラムは、以下のようなコードから始まるはずです。
use lib qw(/path/to/DoqueDB/sydney/Perl/); #ライブラリの場所を指定
use DBI;
my $dbh = DBI->connect(join(q(;),
q(dbi:TRMeisterPP:database=DefaultDB), # データベース名
q(host=hostname), # ホスト名
q(port=54321)), # ポート番号
q(root), q(doqadmin), # ユーザ名, パスワード
{RaiseError => 0, printError => 0, # エラー発生時の扱い
userEncode => q(utf-8)} # データベースの文字コード
);
後は、他のデータベースと同じように、取得したデータベースハンドル($dbh)に対して、prepare()メソッドでSQLを設定し、execute()で実行すればよいだけですので、ここではDBIのメソッドに関しては説明しません。
この記事では、日本語を扱う際の注意事項に関して述べます。
perlは、以前はデータはバイナリも文字列も区別なく扱っていましたが、Unicodeを扱うにあたって、順次改訂されています。バージョンによって動作が異なる点もあるので注意が必要なのですが、典型的なのは、文字列を扱う関数、特に正規表現などでもUnicodeが使えるようになったため、日本語処理をする際には、以前のように文字コードの内部のバイトのパターンで正規表現を書く必要はなくなりました。ただし、この際に UTF8フラグという概念が導入されております。これにより少し面倒な問題が起こります。
日本語などのutf-8でエンコードされた文字列を扱う際は、文字列処理を便利に行うためには、対象文字列のutf-8フラグがonになっている必要がありますが、prepare()などのメソッドに渡す場合、UTF8フラグをoffにしておく必要があります。
従って、perlのプログラムを記載する際は、ソースに直に記載された文字列、外部から受け取った文字列などは、UTF8フラグがどうなっているかを理解していないと、意味不明な警告やエラーに悩まされることになります。
perlのソースコードをutf-8で保存したとして、直に文字列を記載した場合は、その文字列のUTF8フラグはoffです。(ただし、use utf8;プラグマを使用した場合はonになります。)
また、外部からファイルを単純に、例えばwhile(<>){ $line = $_; }のような典型的なコードで、1行ずつ読み込んで文字列に格納した場合も、標準入力に対して特別な処理をしていない場合は、行を受け取った変数のUTF8フラグはoffです。
utf-8フラグを変更するには、以下のようなメソッドを使います。
use Encode;
my $decoded = Encode::decode('utf8', $str); # UTF8フラグon
my $encoded = Encode::encode('utf8', $decoded); # UTF8フラグoff
Encodeモジュールは、文字コード変換にも用いることが多いモジュールなので、これらはむしろUTF8フラグの存在をユーザーに意識させないようなメソッド名になっており、これを使うのが安全とされていますが、詳細は複雑で、実際のところUTF8フラグを直接変更するメソッドもあります。
use Encode;
Encode::_utf8_on($str);
Encode::_utf8_off($str);
事前チェックなどを行わず、フラグを変更するだけなので、こちらの方が高速なのですが、マニュアルには内部メソッド扱いで、将来変更される可能性があるメソッドとなっております。また、フラグの値のチェックが必要な場合は、Encode::is_utf8()を使うことはできますが、今回はこの詳細には触れません。
また、Encodeモジュールを用いなくても、utf8::decode(), utf8::encode()を使用してUTF8フラグを変更することも可能です。
utf8::decode($str); # UTF8フラグon
utf8::encode($str); # UTF8フラグoff
これらは、Encodeモジュールのものとは異なり、直接引数の文字列を変更します。値チェックのためのutf8::is_utf8()も同様に提供されています。
perlのバージョンによってモジュールのバージョンも異なり、詳細な動作が異なる場合もありますので、お使いのperlのバージョンの該当するマニュアルを参照してください。記事末尾に最新版に対するリンクを入れておきます。
従って、utf-8でエンコードされたテキストファイルから行を読み込んで、DoqueDBで操作するようなコードは、以下のように記載することになります。ここでの説明では、入力ファイルのデータはutf-8のテキストで間違いがないものという前提で、_utf8_on(), _utf8_off()を使った記述としています。エラー処理は入っておりません。
use lib qw(/path/to/Perl/);
use DBI;
use Encode;
my $dbh = DBI->connect(...);
while(<>) {
chomp(my $line = $_);
# 文字列操作をしたいので、外部から得たデータのUTF8フラグをonにする。
Encode::_utf8_on($line);
# $line に対して文字列操作して、欲しい結果を $str に得る。
my $str = do_something($line);
# 外部に渡す前にUTF8フラグをoffにする。
Encode::_utf8_off($str);
# SQLを実行
my $sth = $dbh->prepare(qq(
select column from table where text contains ('$str');
));
$sth->execute();
# 結果取得
while (my $row = $sth->fetch()) {
my $column = $row->[0];
# 取得したデータを操作したいので、UTF8フラグをonにする。
Encode::_utf8_on($column);
# $columnに対して文字列操作した結果を$resultに
my $result = do_something($column);
# 標準出力に渡す前もUTF8フラグはoffにする。
Encode::_utf8_off($result);
print STDOUT $result;
}
}
$dbh->disconnect();
perlのUTF8フラグは、外部からデータを受け取ったらUTF8フラグをonに、外部に渡す前にoffにするというのが原則です。
なお、標準入出力などに関しては、受け取った時点でUTF8フラグをonにする方法もあります。
binmode STDOUT, ":utf8";
のように指定するか、openを使う場合は
open(FH, "<:utf8", $filename);
のように記載できます。
詳しくは、perlのマニュアル中、Encodeモジュール、utf8プラグマや、perlunicodeを参照してください。perlunifaqも参考になります。