utf8_column 'column_name'; utf8_columns qw/ column_name1 column_name2 column_name3 column_name4 /;
先日紹介した column と columns に utf8 flagged してくれる inflate を wrap したカラム定義をしてくれます。
例えば以下のような定義をすると
{
package TestTable;
use base 'Data::Model';
use Data::Model::Schema;
use Data::Model::Driver::DBI;
my $driver = Data::Model::Driver::DBI->new(
dsn => 'dbi:mysql:database=test'
);
base_driver $driver;
install_model utf8_test => schema {
key 'id';
column 'id';
utf8_column name
=> char => {
required => 1,
size => 32,
};
};
}
次のように使えます。
use utf8;
use Encode;
my $db = TestTable->new;
$db->set( utf8_test => 1 => { name => '大沢和宏' } );
my $row = $db->lookup( utf8_test => 1 );
if (Encode::is_utf8($row->name)) {
print $row->name . "\n";
}
$row->name には普通に utf8 flag が立つのできちんと名前が表示されます。
utf8_column したカラムに inflate 処理を追加したい事もあるでしょう。
それも、もちろんできます。
utf8_column foo
=> char => {
inflate => sub {
my $val = shift; # utf8 flag 付きで値が入る
},
deflate => sub {
return $utf_flagged_val; # utf8 flag 付きの値を返す
},
};
のような感じで、 inflate する CODE リファレンスには utf8 flag を立てた状態の値が渡されます。
deflate で return する値はもちろん flagged utf8 な値である必要があります。
例として先程の TestTable の utf8_test テーブルに対して utf8_column な inflate 定義をします。
ついでなので alias_column でエイリアス張ったカラムに inflate 設定しましょう。
utf8_column name
=> char => {
required => 1,
size => 32,
};
alias_column name => obj => {
inflate => sub { Name->new($_[0]) },
deflate => sub { $_[0]->name },
};
Name は以下のようなコードです。
package Name;
sub new {
my($class, $name) = @_;
bless \$name, $class;
}
sub name { ${ $_[0] } }
実際に動かしてみましょう。
use utf8;
use Encode;
my $db = TestTable->new;
$db->set( utf8_test => 1 => { name => '大沢和宏' } );
my $row = $db->lookup( utf8_test => 1 );
if (Encode::is_utf8($row->name)) {
print $row->name . "\n";
}
if (Encode::is_utf8($row->obj->name)) {
print $row->obj->name . "\n";
}
# update してみる
$row->name('ねこかくたろう');
if (Encode::is_utf8($row->name)) {
print $row->name . "\n";
}
if (Encode::is_utf8($row->obj->name)) {
print $row->obj->name . "\n";
}
$row->update;
my $row2 = $db->lookup( utf8_test => 1 );
if (Encode::is_utf8($row->name)) {
print $row->name . "\n";
}
if (Encode::is_utf8($row->obj->name)) {
print $row->obj->name . "\n";
}
結果は以下のようになっています。
大沢和宏 大沢和宏 ねこかくたろう ねこかくたろう ねこかくたろう ねこかくたろう
ちゃんと decode 処理してないで print するので Wide character とか出ますが、 utf8 flag がきちんと立ってることがわかると思います。
今日は utf8 column の使い方と inflate との組み合わせについて解説しました。
カラム定義まわりは、まだちょびっとだけ続くぞ。