2010年2月27日

PerlからBerkeley DBを使う - BTree形式を使う

引き続き、しつこくBerkeley DBの話です。今回はBTree形式でのDBを作成します。BTree形式はHash形式と違って、キーがソートされているという特徴が有ります。ソートアルゴリズムはデフォルトの物が用意されていますが、自分で関数を書いて指定する事もできます。

また、BTree形式のDBで、カーソルアクセスする場合、キーの一部だけを指定する事でアクセスする機能が提供されます。指定したキー情報を、DB上に格納されているキーと前方一致で比較して対象となるレコードを特定します。そんなキーの一部一致でのアクセスパターンです。

DBへの書き込み
btree_input.pl

#!/usr/bin/perl

use strict;
use warnings;

use utf8;
use Encode;

use BerkeleyDB;

# DBの作成
my $DB_name = 'berkelry.db';
unlink($DB_name);

my $db = new BerkeleyDB::Btree
	-Filename   =>$DB_name,
	-Flags      => DB_CREATE,
    or die "Cannot open $DB_name: $! $BerkeleyDB::Error\n";

# 値の設定.親レコードが0001と0002の2パターンを相互に挿入します。
$db->db_put('0001', 'ash');
$db->db_put('0002', 'roova');
$db->db_put('0001:Date:01', '2010/02/25');
$db->db_put('0001:Date:02', '2010/02/20');
$db->db_put('0002:Date:01', '2010/02/26');
$db->db_put('0001:Age:01', '21');
$db->db_put('0002:Age:01', '20');

# DBのクローズ
undef $db;


DBからの読み込み
btree_output.pl

#!/usr/bin/perl

use strict;
use warnings;

use utf8;
use Encode;

use BerkeleyDB;

# DBの準備
my $DB_name = 'berkelry.db';

my $db = new BerkeleyDB::Btree
    -Filename =>$DB_name,
    or die "Cannot open $DB_name: $! $BerkeleyDB::Error\n";

# キーの一部指定でアクセス
my $key_origin = "0001";
my ($key, $value) = ($key_origin, "") ;
my $cursor = $db->db_cursor() ;

$cursor->c_get($key, $value, DB_SET_RANGE);

print "$key -> $value\n";

while($cursor->c_get($key, $value, DB_NEXT) == 0) {
    last unless ($key =~ /^$key_origin/);
    print "$key -> $value\n";
}

# クローズ
undef $cursor ;
undef $db;

実行結果

$ perl btree_output.pl
0001 -> ash
0001:Age:01 -> 21
0001:Date:01 -> 2010/02/25
0001:Date:02 -> 2010/02/20

関連する記録のキーを前方一致で揃えておくとカーソルアクセスで、高速にまとめて取得できます、という例です。なんだかTree型データベースみたいですね(イマドキ使われる事は無いと思いますが)。

2010年2月25日

PerlからBerkeley DBを使う - 重複キーを扱う

Berkeley DBではDBを作る時に重複キーを扱うかどうかを指定する事が出来ます。キー重複してもあまりうれしく無い気もしますが、使ってみましょう。今回はハッシュ形式のアクセスではなく、Berkeley DBのネイティブAPI(のPerl Wrapper)を使います。

DBへの書き込み
dup_input.pl

#!/usr/bin/perl

use strict;
use warnings;

use utf8;
use Encode;

use BerkeleyDB;

# DBファイルの準備
my $DB_name = "berkeley.db" ;
unlink($DB_name);		# 存在したら削除
my $db = new BerkeleyDB::Hash
    -Filename => $DB_name,
    -Flags    => DB_CREATE,	# ファイルを作成
    -Property  => DB_DUP	# DBを重複キー有りで作成
    or die "Cannot open file $DB_name: $! $BerkeleyDB::Error\n" ;

# DBの値設定
$db->db_put("name", "ash");
$db->db_put("name", encode('UTF-8', 'アッシュ'));
$db->db_put("name", "roova");

# DBクローズ
undef $db;


次にキーを順番に取得します。

DBからの読み込み
dup_output.pl

#!/usr/bin/perl

use strict;
use warnings;

use utf8;
use Encode;

use BerkeleyDB;

# DBファイルの準備
my $DB_name = "berkeley.db" ;

my $db = new BerkeleyDB::Hash
    -Filename => $DB_name,
    -Property  => DB_DUP,	# DBは重複キー有り
    or die "Cannot open file $DB_name: $! $BerkeleyDB::Error\n" ;

# キー重複有りのDBなので、カーソルアクセスで順番に処理する。
my ($key, $value) = ("", "") ;
my $cursor = $db->db_cursor() ;
while ($cursor->c_get($key, $value, DB_NEXT) == 0)
    { print "$key -> $value\n" }

# クローズ
undef $cursor ;
undef $db;

結果

$ perl dup_output.pl
name -> ash
name -> アッシュ
name -> roova

キーが重複した場合、格納順は最後になります。ただし、これも格納位置を判定する関数を書けば制御できます。DB_DUPSORTフラグと比較用の関数を渡せばOKです。

2010年2月24日

PerlからBerkeley DBを使う

前回はBerkeley DBのインストール方法と、Perlから使うためのBerkeleyDBモジュールのインストール方法を解説しました。

今回は最も基本的な使い方です。


Berkeley DBはPerlからは単なるハッシュ変数としてアクセスする事が出来ます。

DBへの書き込み
input.pl

#!/usr/bin/perl

use strict;
use warnings;

use utf8;
use Encode;

use BerkeleyDB;

# DBの作成
my $filename = "Berkeley.db" ;
tie my %hash, "BerkeleyDB::Hash",
    -Filename => $filename,	# ファイル名
    -Flags    => DB_CREATE	# ファイルが無い時は作る
    or die "Cannot open file $filename: $! $BerkeleyDB::Error\n" ;

# hashへの値設定

$hash{'Name'} = 'ash';
$hash{'名前'} = 'アッシュ';

# DBのクローズ
untie %hash;


DBからの読み込み
output.pl

#!/usr/bin/perl

use strict;
use warnings;

use utf8;
use Encode;

use BerkeleyDB;

# DBの作成
my $filename = "Berkeley.db" ;
tie my %hash, "BerkeleyDB::Hash",
    -Filename => $filename,	# ファイル名
    or die "Cannot open file $filename: $! $BerkeleyDB::Error\n" ;

# hashへの値設定

print "$hash{'Name'}\n";
print "$hash{'名前'}\n";

# DBのクローズ
untie %hash;

読み込み時の出力

$ perl output.pl
ash
アッシュ

いくらマニュアルを漁ってもDBの文字コードを設定したり、utf8フラグを自動的に設定する様な機能は見あたらず。取得したデータは単なるバイト列なので、そのまま出力してもOK。でもちゃんと文字列として扱いたい場合は、自分でutf8フラグを立ててあげる必要が有ります。

単なるハッシュ変数として使う分にはあまり面白くないですね。次回は重複キーや、BTree版を試してみます。

2010年2月21日

PerlからBerkeley DBを使う

ちょっと前にUnix系OSで使われるMDBの事を色々と調べる事が有ったのだけど、実際に使ってみないとやっぱり分からないので使ってみる。そしてやっぱり伝統(?)に則り、まずはBerkeley DBを使う事にする。

Berkeley DBって何?という人はWikipediaを参照の事。

Berkeley DB - Wikipedia

サーバプロセスが不要なDBMSというと今はSQLiteが有るので、DBMじゃないとダメっていうのはシビアに速度が要求されるような用途ぐらいしか思いつかないんだけど。


  1. Berkeley DBのダウンロード
  2. 今はOracle社プロダクトになっている。ダウンロードもOracle社のサイトから。

    ダウンロード先のページ - Oracle

    最新バージョンは4.8系列。ここではtar.gz形式を選択。

  3. インストール
  4. safari等からクリックすれば、ダウンロードフォルダに格納され、ダブルクリックすると解凍される。後は以下の手順でインストールする。

    2010年2月21日時点の最新バージョンは4.8.26

    $ cd db-4.8.26
    $ cd build_unix/
    $ ../dist/configure
    $ make
    $ sudo make install
    $ make clean

  5. Perlモジュールのインストール
  6. PerlでBerkeley DBへアクセスするためのモジュールは、「BerkeleyDB」です。cpanからインストールしようとすると、Berkeley DBのライブラリやヘッダを見つけられずエラーになってしまいます。

    必ずモジュールのディストリビューションをダウンロードして、「config.in」というファイルを書き換えます。Berkeley DB v4.8.26の場合、下記の通り書き換えます。

    INCLUDE	= /usr/local/BerkeleyDB.4.8/include
    LIB	= /usr/local/BerkeleyDB.4.8/lib

    あとは通常のPerlモジュールのインストールと同じです。

    2010年2月21日時点の最新バージョンは0.41

    $ cd BerkeleyDB-0.41
    $ perl Makefile.PL
    $ make
    $ sudo make install
    $ make clean

実際にPerlからのアクセス方法はまた次回。

2010年2月 9日

Module::BuildをWindows環境で使う

Module::Buildは便利なモジュールですが、その中でも地味にWindows環境でのスクリプト起動用のbatファイルを作成してくれる機能が便利です。

以下、その使い方の例です。

  1. 事前準備
  2. 事前にModule::Starterをインストールした上で、下記のコマンドを投入します。最後の「--mb」がModule::Buildを使う事の指定です。

    C:\>module-starter --module=Foo::Bar --email=infor@roova.jp --author=ash --mb
    この例ではCドライブ直下に、Foo-Barディレクトリが作成され、その中に必要なファイルが作成されています。

  3. bin or scriptディレクトリの作成
  4. スクリプトを格納する「bin」ディレクトリ又は「script」ディレクトリを、Foo-Bar直下に作成します。「bin」ディレクトリの中に配置したスクリプトは自動的に認識されますが、「script」ディレクトリ配下のファイルは自動的に認識してくれないので、Build.PLに追記が必要です。詳細は、この記事を参照して下さい

  5. Perlスクリプトの配置
  6. 作成した「bin」ディレクトリ又は「script」ディレクトリ配下に、スクリプトファイルを格納します。なお、スクリプトファイルの拡張子は有っても無くてもかまいませんが、.pl拡張子を付けておいた方が利用上は便利です(後述)。

  7. Buildコマンドの生成
  8. 以下のコマンドを投入します。これでBuildコマンドが生成されます。scriptフォルダの配置を変更した場合は、再度投入しなおします。

    C:\Foo-Bar>perl Build

  9. Buildコマンドの実行
  10. 生成したBuildコマンドを実行します。

    C:\Foo-Bar>.\Build

    このコマンドを実行する事で、blib\scriptディレクトリが作成され、その配下にスクリプトと起動用のbatファイルが格納されます。例として、test.plというスクリプトファイルの場合、blib\script配下には以下の様なファイルが格納されます。

    • test.pl
    • test.bat

    この状態でテストを実施します(Build testはblib配下に対してテストを実施します)。batファイルが作成されているので、「.\test」とタイプするだけでbatファイルの中でPerlが呼び出され、スクリプトが起動されます。

    C:\Foo-Bar\blib\script>.\test

    なお、当然ですが元となるPerlスクリプトに拡張子が付いていないと、起動時に「.\test.bat」とファイル名をフルにタイプする必要が有ります。

  11. Perlスクリプトのインストール
  12. テストが終わったら、スクリプトをインストールします。

    C:\Foo-Bar>.\Build install
    環境にも寄りますが、ActivePerlを素でインストールした環境ではC:\Perl\site\binディレクトリ配下にインストールされました。必要に応じてパスを通して、スクリプトを起動します。

以上がModule::Buildを使って、shebangが無いWindows環境でスクリプト名だけタイプする事で起動できるようにするための手順です。

2010年2月 8日

Perlのpack関数を使ってみた

今まで使う事の無かったpack関数を使ってみた。UTF-8の文字コード一覧(コードが文字列として書かれている)に本当に正しい内容が入っているか、コード値の内容を変換しながら出力する、という作業が有ったので。

print pack('H*', $Code);

$Codeには、UTF-8のコードが入っているものとします(例:「あ」なら「E38182」)。

これでUTF-8の文字が得られたので、全部出力してチェックしてみた。pack関数は、それ自体が言語内言語という感じで、正規表現と並ぶ分かりにくさかも...。

2010年2月 6日

実用Git

オライリーから「実用Git」が今月リリースされます。GitというLinux Kernelで使われているバージョン管理ソフトウェアの解説書です。GitはLinuxというソフトウェア開発における思想みたいな物がそのまま機能に現れている非常に興味深いソフトウェアではないかと。

実用Git実用Git
吉藤 英明 (監訳)

オライリージャパン 2010-02-19
売り上げランキング :

Amazonで詳しく見る
by G-Tools

でも、現メンテナの濱野 純(Junio C Hamano)自ら書き下ろした「入門Git」が有るからなぁ。オライリーから出たからと言って、そんなに必読!って感じがしないなぁ。

入門Git入門Git

秀和システム 2009-09-19
売り上げランキング : 39760

Amazonで詳しく見る
by G-Tools

Perlスクリプトの拡張子は何?

Perlスクリプトのファイルに何の拡張子を付けるのか、あんまり決まりが無い気がする。自分でコーディングする時のパターンをまとめてみた。はたして実際にはどのパターンが多いんでしょうか。

  • cgi用のPerlコード
  • apacheの設定次第だが、基本的に.cgiの拡張子を付ける。

  • モジュール
  • .pmの拡張子を付ける。

  • テストコード
  • Test::Harnessの要求に従って、.tの拡張子を付ける。

  • Windows上でのPerlコード
  • 拡張子.plを付けないとエクスプローラやエディタがきちんと認識してくれないので、.plの拡張子を付ける。

    Module::Buildを使って.plのファイルをインストールする設定にすると、ちゃんとコマンドプロンプトでの起動用に同名の.batファイルを作ってくれるので、利用者向けにはこちらを使うようにマニュアルに書くと良い。

  • Unix系OSでのPerlコード
  • 拡張子.plを付けなくても、1行目にシェバン(#!/usr/bin/perl)が有れば、エディタが自動的にPerlのコードと認識してくれる事が多い。

    拡張子.plを付ける必然性は無い。逆に付けると開発言語を変えた時にマニュアルを変える必要が有るので、拡張子は無い方が良い。