Class::DBIとTime::Piece
MT::Neko::kak 500 Internal Server ErrorのnekokakさんがClass::DBI::Plugin::TimePieceという記事をアップされてます。
Class::DBIとTime::Pieceの連携(infalte/defalte)はClass::DBI::mysqlの実装がいい感じです。
autoinflateで一発。
__PACKAGE__->autoinflate(column_type => 'Inflation::Class'); #カラム型=>クラス __PACKAGE__->autoinflate(timestamp => 'Time::Piece'); __PACKAGE__->autoinflate(datetime => 'Time::Piece'); __PACKAGE__->autoinflate(date => 'Time::Piece'); __PACKAGE__->autoinflate(dates => 'Time::Piece');#上の3行を1つでまかなう
inflateクラスにTime::Pieceを指定した場合、内部的にTime::Piece::MySQLを呼び出してフォーマット変換を自動的にやってくれるのもいい具合です。
MySQL限定と思えば、Class::DBI::mysqlを参考にしつつ
package Class::DBI::Plugin::TimePiece::MySQL use Time::Piece::MySQL; sub import { my $class = shift; my $pkg = caller(0); unless($pkg->isa('Class::DBI')){ croak(__PACKAGE__." is for Class::DBI application."); } no strict 'refs'; *{"$pkg\::has_a_timepiece"} = sub { my $self = shift; my $colum = shift; my $type = shift; $self->has_a( $colum => 'Time::Piece', inflate => "from_mysql_$type", deflate => "mysql_$type", ) }; } 1;
これで良いと思う。
使い方はTokulogさんのDateTimeを使う方法と同じ。
__PACKAGE__->has_a_timepiece(last_modified=>'datetime');
でどうでしょう。
個人的には、pieceの綴りにいつも自信がないので、has_a_tpとかいうショートカットが欲しいところです。あと、MySQL以外、例えばPostgreSQLなどへ対応をしようと思うと、Time::Piece::Pgがないし、かなり大変かと思う。
あ、そもそもMySQLならClass::DBI::mysqlを使うか。
コメント
はじめまして。nekokakです。
トラバありがとうございます。
Time::Piece::MySQL初めて知りました。
確かにMySQLの場合、かぜぶろさんのがスマートかつ美しいですね。
Class::DBI::Plugin::TimePiece::MySQLって名前ですから、
MySQL限定でもOKなんじゃないですか?
アップ希望w
自分が今やってるシステムの場合、Oracleなんで使えないのですが。。。
自分のはどうもダサイです^^;
Oracleの場合とMySQLの場合でDate型の取得時のデフォルトフォーマットが
ちがうから至れり尽くせりで作るとなるとやっかいっぽいんですよね。
だからせめてTime::Pieceに渡すフォーマットだけでも
パラメータ化できればとも思ってます。
pieceの綴りですが、自分もよく間違えます。
has_a_timepieceのエイリアスってのもありですね。
Class::DBI::Sweetでもpageメソッドのエイリアスとしてpagerを定義してます。
しかしClass::DBI、奥が深いっす。
でわ。
投稿者: nekokak | 2005年10月31日 21:16
フォーマットを渡すとなると、__PACKAGE__->has_a_timepiece(
last_modified,
deflate_format=>"%Y/%m/%d %T",
inflate_format=>"%Y/%m/%d %T"
);
こういう感じかな。
*{"$pkg\::has_a_timepiece"} = sub {
my $self = shift;
my $colum = shift;
my %args = @_;
$self->has_a(
$colum => 'Time::Piece',
inflate => sub{Time::Piece->strptime(shift,$args{infalte_format})},
deflate=> sub{shift->strptime($args{deflate_format})}
);
}
フォーマット自動判断とかいれないとあまり楽にはならないっすね。もしくはTime::Piece::MySQLを参考に必要なだけのメソッドを追加したTime::Piece::Oracleのようなものを作ってしまうというのはいかがでしょうか?
投稿者: かぜぶろ | 2005年11月01日 13:17
入れ違いでhttp://www.border.jp/nekokak/blog/archives/2005/11/classdbiplugint_1.htmlを
書いてしまいました。
かぜぶろさんのやりかたでもさっきまで試行錯誤してたのですが、
どうも、updateの際、deflateが呼ばれる前に、inflateが呼ばれるんですよね。
で、deflateとinflateのフォーマットが異なると、与える値によってはエラーになってしまうんです。
なので、deflateとinflateのフォーマットはあわせるしかないかなぁと思ってます。
フォーマット自動判別はあれば便利でしょうね。
Class::DBI::Plugin::TimePieceを親のクラスにして、
Class::DBI::Plugin::TimePiece::Oracle
Class::DBI::Plugin::TimePiece::MySQL
みたいに拡張できればいい感じかもしれないですね。
Time::Pieceに慣れてないので結構くたびれました。
投稿者: nekokak | 2005年11月01日 14:02