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 との組み合わせについて解説しました。
カラム定義まわりは、まだちょびっとだけ続くぞ。