DBIC以降の選択肢
今回はデータベース話の締めくくりとして、DBIx::Class以降に登場したいくつかの選択肢についてざっくりまとめておきます。これらはいずれも若く、DBICに比べてユーザ数も少ないためドキュメントなどの整備が遅れている部分もありますが、今回とりあげるものの多くは日本人がつくっているものですから、英語圏で開発が進められているものより疑問や要望は送りやすいはず。気になることがあったらぜひそれぞれの作者氏に伝えていただければと思います。
DBIx::Skinny
nekokakこと小林篤氏のDBIx::Skinnyは、今回紹介するもののなかではもっとも実績豊富なものといってよいでしょう。開発の動機については氏のブログによくまとまっていますが、標準で用意されているCRUDメソッドを使うときだけでなく、速度を稼ぐために生のSQLを書いたときでもinflateなどの補助機能を使えるようになっているのがこのモジュールの肝。2009年末にはAdvent Calendarの一環として25回にわたる連載記事が書かれているので、一般的な用途であれば特に使い方に困ることはないと思います。スキーマの設定からデータベースの操作まで含めて最低限のサンプルを書くならこのような感じになるでしょうか。install_inflate_ruleのおかげで、search_by_sqlで生のSQLを書いているにもかかわらずcreated_atがきちんとTime::Pieceのオブジェクトになっているのがポイントです。
Teng
DBIx::Skinnyはよくできたモジュールですが、誕生から2年が過ぎて、細々としたところでかゆいところに手が届かなかったり扱いにくかったりする部分もあることがわかってきました。そのため、既存のSkinnyとは別に、先日からはTengという後継プロダクトの開発が始まっています。先週開催されたKamakura.pmのイベントなどでも発表がありましたが、こちらは当初DBIx::Skinという名前で開発されていたことからもわかるようにSkinny以上に薄いO/Rマッパを目指して書かれているのが特徴で、Skinnyでは標準で組み込まれていたいくつかの機能は、廃止されたり、プラグインに追い出されました。また、SQLの構築部分もSQL::Makerという別パッケージにまとめられています。一方で、需要が高く、内部的な変更の影響も受けやすいスキーマのダンプやロードについては自前で用意するようになりました(その他の変更点については同じく小林氏のブログ記事などをご覧ください)。まだ開発開始から一ヶ月ほどしかたっていないため細かなAPIは変わる可能性がありますが、基本的なところはすでにできていますし、ソースコードの行数もSkinnyの半分ほどになっているので、全容をつかむのはそうむずかしくないでしょう。先ほどのコードをTengで書き直すと、このような感じになります。この原稿を書いている時点ではinflate_ruleはまだ宙ぶらりんの状態でしたが、Skinnyに慣れた人であればさほど違和感なく移行できるはずです。
Data::Model
Yappoこと大沢和宏氏のData::Modelは、Data::という名前空間の下にあることからもわかるように、SkinnyやTengとはやや毛色が異なるのですが、Skinnyとほぼ同時期に開発が始まったこともあってお互いに影響を与えあっています。これも開発の意図については氏のブログによくまとまっていますし、2009年にはSkinnyともどもAdvent Calendarにまとまった記事が書かれているので、ふつうに使う分には特に困ることはないでしょう。ここで用意したサンプルではcolumn_sugarを使って複数のテーブルでカラム定義やinflateの設定を共有しているところと、テーブルの作成に生のSQLを使っていないところがポイントですが、細かいところでは、キャッシュされたデータがあればキャッシュを優先して使う設定もしてあります[1]。
DBIx::ObjectMapper
2010年のYAPC::Asiaでも発表があった大石英介氏のDBIx::ObjectMapperは、いわゆるData Mapperパターンを実装したものです。Data Mapperパターンではアプリケーション側で利用するクラスとデータベースのテーブルをかならずしも1対1で対応させる必要がなく、アプリ側ではアプリ側の最適な実装に、データベース側ではデータベース側の最適な実装に、とわけられるので、変更や拡張が長期的に続いていく(アプリケーションのクラスとデータベースのスキーマが乖離しやすい)大規模アプリケーション向きといわれていますが、もう少し身近なところでは、オブジェクトとデータベースが密接に結びついていないためテストを書きやすくなる(いちいちデータベースにダミーデータを食わせてSQLを実行しなくてもオブジェクトをつくれる)のと、アプリケーション側のオブジェクトにはデータベースの接続情報などが入っていないため、デバッグのときなど気軽にオブジェクトの中身をダンプできるのが長所といえるでしょうか。単純な例ではいわゆるActive Recordパターンよりも記述が冗長になるデメリットが目立ってしまうのですが、このサンプルではメタデータとして格納されているテーブル情報を利用してテストデータを挿入したあと、メタデータに入っているテーブルと、アプリケーション側で使うクラス(MyUser, MyEmail)とをマッピングして、最後にリレーションを含むデータの取得と更新を試しています。詳しい使い方については、YAPC::Asiaでの発表のほか、2010年のAdvent Calendarの記事や、付属のテストが参考になります。
ORLite
ここまで見てきたものはMySQLであろうとPostgreSQLやSQLiteであろうと基本的にはそれほど意識しなくても使えるようになっていましたが、どうせデータベースの乗り換えなどしないのだからと割り切るのであれば最初から特定のデータベースにすり寄ったO/Rマッパを書いてもよいはずです。アダム・ケネディ(Adam Kennedy)氏のORLiteは、SQLiteに特化したO/Rマッパとして、連載第17回で紹介したPadreや、CPANDBやORDB::CPANUploads、ORDB::CPANTS、ORDB::CPANRTなどのCPANまわりのツール群のなかで使われています(これらのツールは必要に応じて各サーバに用意されているデータベースのダウンロードや解凍をしたり、データベースのスキーマから動的にクラスを作成したりもしてくれます)。どのテーブルがどのクラスにマッピングされているかなどはいまのところ自分でデータベースハンドルを取りだしてクエリを発行しないとわからないので、事前にある程度概要をつかんでおく必要はありますが、CPANの統計をとったり検索サイトなどをつくるのであればワンライナーでも一覧を取り出せますので、使い方を覚えておくと便利なことがあるかもしれません。
ほかにもいろいろありますが
今回は比較的新しく、かつCPANにリリースされるくらいには成熟しているものという条件でいくつかのモジュールを取り上げてみましたが、もちろんCPANやgithubにはここで取り上げたほかにも新旧あわせてさまざまな選択肢が公開されています。それぞれに特徴(向き不向き)がありますので、ご自分の必要にあわせて適切なものを選んでください。