2013年2月11日
DBIx::Schema::DSLってのを書いている話
https://github.com/Songmu/p5-DBIx-Schema-DSL
Teng使って開発しててDDLを直接書くのに大分疲れてきたので、RDBのスキーマを定義、 管理するDSLモジュールを書いています。
Podに書いてあるのとほぼ同じですが、こんな風にスキーマ定義しておいて、
package My::Schema;
use DBIx::Schema::DSL;
database 'MySQL';
create_database 'my_database';
default_unsigned;
create_table 'book' => columns {
integer 'id', primary_key, auto_increment;
varchar 'name', null;
integer 'author_id', not_null;
decimal 'price', 'size' => [4,2];
add_index 'author_id_idx' => ['author_id'];
belongs_to 'author';
};
create_table 'author' => columns {
primary_key 'id';
varchar 'name';
tinyint 'age';
add_index 'age_idx' => ['age'];
has_many 'book';
};
1;
こんな感じで、DDLを出力できます。
use 5.014;
use My::Schema;
say My::Schema->output; # output DDL
say My::Schema->no_fk_output; # without fk constraints
そんな違和感ないんじゃないかなーと思います。
内部的にはSQL::Translatorを使っていて、SQL::Translatorオブジェクトを 組み立てるDSLを提供しているだけとも言えます。
案の定、@fujiwaraには「直でSQL書けばいいじゃん」とか言われてしまったのですが、 @typesterには「ちゃんと完成したら使うよ」と評価を頂いております。
作っている動機としては
- DDL直接書くのはクオートとかカンマとか気をつけないといけないし、冗長な記述も多いのでたるい
- DDL直書きスタイルだと、複数人開発だと微妙に書き方がバラバラになったりするのがイヤン
- ER図描画等のため、MySQL workbenchには外部キー制約つけたDDL食わせたいけど、本 番ではある程度インデックスを間引きたいので、外部キー制約つけてないDDLも出力 したいとかそういうニーズがある
- ゆくゆくはORMと連携させて、クラス定義とか、リレーションメソッド生やすとかそういうことできると良さそう
という感じですかね。
本番で外部キー制約つけないとか「SQLアンチパターン」に見事にアンチパターンとし て書かれていましたね。仕方ないね。
あと、SQL::TranslatorがMoo依存になってたので、Moo使っております。
今やってるプロジェクトで使い始めてるんで、もうちょっとしたらCPAN上げる予定。