dbmopen

dbm ファイルのバインディングを生成する

構文

解説

※ この関数は tie 関数に置き換えられました。

dbmopen は、 dbm(3)ndbm(3)sdbm(3)gdbm(3)、 または、Berkeley DB のファイルをハッシュにバインドします。 HASH にはデータベースファイルのデータをバインドしたい連想配列の変数を、 DBNAME には前述のデータベースファイルの名前を、 MASK には新規にデータベースを生成する際の MASK を指定します。 もし指定のデータベースファイルが存在しなければ新規に生成します。

次コードは sample という名前のデータベースファイルを連想配列 %data にバインドし、連想配列を通してデータベースファイルにデータを書き込んでいます。

dbmopen my %data, './sample', 0666;
while ( my ( $key, $val ) = each %ENV ) {
    $data{$key} = $val;
}
dbmclose(%data);

上記コードは、データベースファイルが存在しなければ新規に生成します。 データベース名が sample なら、sample.dirsample.pag という 2 つのファイルが生成されます。

もし新規にデータベースファイルを生成したくなければ MASK に 0 を指定します。 その場合、データベースファイルが見つからなければ dbmopen は偽を返します。

if ( dbmopen my %data, './sample', 0 ) {
    print "Success!\n";
    dbmclose(%data);
}
else {
    die "Database file was not found: $!\n";
}

もしデータベースファイルに書き込み権限がなければ、値を書き込むことはできません。 書き込み権限の有無を調べるには、ファイルテスト演算子 -w 等を使って .dir.pag ファイルのパーミッションをテストするか、 evel でダミーのデータを書き込んでみて、 例外の発生の有無をチェックします。

my $dbname = './sample';
if ( -w "${dbname}.dir" && -w "${dbname}.pag" ) {
    dbmopen my %data, $dbname, 0666;
    while ( my ( $key, $val ) = each %ENV ) {
        $data{$key} = $val;
    }
    dbmclose(%data);
}
else {
    die "Failed to write data to the database file.\n";
}

データベースファイルが大きい場合、keysvalues は巨大なリストを返すことになり、 膨大なメモリリソースを消費してしまいます。 そのような状況では、each を使ってレコードを逐次処理するのが良いでしょう。

dbmopen my %hugedata, './hugedata', 0666;
while ( my ( $key, $val ) = each %hugedata ) {
    print "${key}: ${val}\n";
}
dbmclose(%hugedata);

なお、dbmopen は Perl4 から用意された組み込み関数です。 Perl5 では新たに tie が実装され、 現在では tie の利用が一般的です。 今のところ dbmopen は廃止予定になったわけではありませんが、 特別な理由がない限り、tie を使うほうが良いでしょう。