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 したカラムに 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 との組み合わせについて解説しました。

カラム定義まわりは、まだちょびっとだけ続くぞ。

Thu, 17 Dec 2009 07:48:01 GMT  |  Index

Main Tracks

Yet Anthor Tracks

Other Sites

Powered by nim