DBIx::RewriteDSN でB!

前置き

みなさんこんにちは、cho45 です。

こちらは hacker track ということで、僕がつくったモジュールの一つを紹介したいとおもいます。今回ご紹介するモジュールは DBIx::RewriteDSN です。

本題

DBIx::RewriteDSN は非常に小粒なツールですが、なかなか苦しいモジュールなんじゃないかと自分でもおもっています。使わなくていいなら幸せでしょうね。

歴史あるプロジェクトを開発する際、データソースがハードコードされているというようなケースはままあります。さっさと書きかえられる程度ならばいいのですが、修正箇所が多ければ多いほどミスが発生しやすいわけですし、それが本番のデータベースであるならば、一箇所ミスをしただけで甚大な被害が出ることも予想するに難しくありません。

「DBI は使っているが、データベースサーバへの IP などが各所にちらばっており、こわくてテストや開発ができない」というなケースで、DBIx::RewriteDSN はぴったんこです。

DBIx::RewriteDSN は一言でいえば DBI における mod_rewrite です。

例えば以下のようにして使います。

BEGIN {
	$ENV{DBI_REWRITE_DSN} = defined $ENV{DBI_REWRITE_DSN} ? $ENV{DBI_REWRITE_DSN} : 1;
}

use DBIx::RewriteDSN -rules => q{
	# white list
	(dbi:mysql:dbname=([^;]+);host=(?:localhost|127.0.0.1)) $&
	 dbi:mysql:dbname=([^;]+?_test);host=.+ dbi:mysql:dbname=$1;host=localhost

	# fallback all mysql connection to local database
	dbi:mysql:dbname=([^;]+);.* dbi:mysql:dbname=$1_test

	.* dbi:fallback
};

環境変数 DBI_REWRITE_DSN がセットされていない場合、このモジュールは何もしません (この挙動については悩み所なのですが、意図せずこのモジュールがロードされても副作用がないようにと思いこうしています)。

環境変数が設定されている場合、DBIx::RewriteDSN は DBI::connect をさしかえて定義に沿った dsn の書き変えを行います。

上記定義では

dbi:mysql:dbname=fumino;host=192.168.0.230
=> dbi:mysql:dbname=fumino_test (fallback による)

dbi:mysql:dbname=session;host=localhost
=> dbi:mysql:dbname=session;host=localhost (white list)

のような書き換えが起こります。(実際に書きかえの様子を観察するには DBI_REWRITE_DSN=verbose とすれば STDERR に吐かれます)

どれにもマッチしない場合には dbi:fallback に書きかわるため、エラーになります。エラーになったときはそれを注意深く white list として定義すればいいのです。

まとめ

今回は DBIx::RewriteDSN について、解説しました。

このモジュールは、もともとリモートサーバに繋ぎにいくのが重くて開発効率ガタ落ちだよ、全部ローカルに繋ぎかえたいんだよ、という欲求のために作りました。

普段から「開発効率よくなんねぇかなー」と気をつけていることが重要ですね。

というわけで今回はここまで。明日は download_takeshi さんです。