「最近 DBIx::Schema がよくバージョンあがりますね」と言われましたが、またあがりました。Version 0.10 で Yokohama.pm#7 の発表では「予定」としていた 問い合わせ結果の Filter と引数の Deflate をサポートしました。
まず、Filter ですが、methodを作成する際に最後にCodeRefを渡します。
my $DTFMT = DateTime::Format::Strptime->new(
time_zone => 'UTC',
pattern => '%Y-%m-%d %H:%M:%S',
);
__PACKAGE__->select_all(
'entry_list',
'offset' => { isa => 'Uint', default => 0 },
q{SELECT id,nick,body,ctime FROM entries ORDER BY ctime DESC LIMIT ?,11},
sub {
my $row = shift;
$row->{ctime} = $DTFMT->parse_datetime($row->{ctime});
$row->{ctime}->set_time_zone("Asia/Tokyo");
}
);
上記の例のように select_all ならすべてのrowに対してfilterをかけ、select_row なら得られたrowだけにfilterを適用します。for文を書かなくてよくなるので便利ですね。select_one と query はこの機能をサポートしていないので注意。
次に、Deflate ですが、こちらは引数の定義の中に埋め込みます。
__PACKAGE__->query(
'add_entry',
id => 'Str',
nick => { isa => 'Str', default => 'anonymouse' },
body => 'Str',
datetime => {
isa => 'DateTime',
default => sub { DateTime->now( time_zone=>'UTC' ) },
deflater => sub { $DTFMT->format_datetime(shift) },
},
q{INSERT INTO entries ( id, nick, body, ctime ) values ( ?, ?, ?, ? )},
);
上の例は datetime のカラムに対して、DateTimeのオブジェクトだけを受け取り、デフォルトはUTCの現在時間という定義をし、deflater で DateTimeオブジェクトをDBに保存するための文字列化を行っています
時間系のカラムを扱う際はこれでコードを短くできるので、便利ではないでしょうか。
NoPasteのサンプルアプリは、これを使って書き直しているので、参考にどうぞ。