Journal(2005) | Blog(2006) | RandomLink | WhoAmI | LiveBookmark | HomePage

<<Previous: Catalyst 的用户鉴定登陆  >>Next: another part-time job day

DBIx::Class 的 inflate_column

Category: Catalyst   Keywords: DBIx::Class inflate

DBIx::Class is great, 所以我在最近写的论坛代码 Foorum 中就使用了 DBIx::Class 作为我的 Model. (use base 'Catalyst::Model::DBIC';)
但我挺喜欢 Class::DBI 的 Trigger,而 DBIx::Class 要使用这个东西似乎比较麻烦。按它 wiki 上的说法似乎要载入 use base qw/ DBIx::Class::CDBICompat::Triggers DBIx::Class::Core/; 没有其他的办法。

我在写 Foorum 的注册程序,表 user 里有一个字段是 register_date 类型为 DATETIME。如果用 Trigger 的话似乎简单一些, register_date = NOW() 就可以(用 mysql 的函数)。

还好 DBIx::Class 也提供了 inflate. 所以我就用这个来完成我的任务。 inflate 在这里只是一个暗喻,它主要用于在表的某一字段的数据存入或取出之前做一些变动。 deflate 用于做存入前的变动,而 inflate 做取出后的变动。

在无法用 register_date = NOW() 之后,要将 localtime 或 gmtime 转为 DATATIME 类型似乎比较麻烦。还好 CPAN 上有一模块为 DateTime::Format::MySQL 用于将 DateTime 对象转为 MySQL 所需要的类型。所以代码很简单:

package Foorum::Model::DBIC::User;

use strict;
use base 'Foorum::Model::DBIC';

use DateTime::Format::MySQL;

__PACKAGE__->inflate_column( 'register_date',
{ inflate => sub { return shift; },
deflate => sub { DateTime::Format::MySQL->format_datetime( shift ); } }
);

而当我们存入数据时就可以使用:
use DateTime;
$c->model('DBIC')->table('user')->create({
username => $username,
password => $computed,
email => $email,
register_date => DateTime->now,
register_ip => $c->req->address,
});
当 create 创建新的 record 时,将传入的 register_date(这里是 DateTime->now;)先用 deflate 做一些变动,这里将它(shift 指的是 DateTime->now)处理(format_datetime)后再存入。
而 inflate 反一下,指取出后立即处理的匿名函数。我这里只是直接返回,因为我不需要再处理。如果你想它取出来也是一个 DateTime 对象好方便你进一步处理的话,可以将 inflate 的函数改为:
inflate => sub { DateTime::Format::MySQL->parse_datetime( shift ); },
:) have fun. 如有疑问,发 mail 跟我探讨。 thanks.

<<Previous: Catalyst 的用户鉴定登陆  >>Next: another part-time job day

Options: +Del.icio.us

Created on 2006-02-23 23:42:15, Last modified on 2006-02-23 23:44:15
Copyright 2004-2006 All Rights Reserved. Powered by Eplanet && Catalyst 5.65.