Inflate についてB!

はじめに

今回から数回にわたって Inflate にについて書きます。

Data::Model でも、他の ORM と同様に Inflate/Deflate が用意されています。

これは、データベースから値を取得した時に自動的にオブジェクトのインスタンスを作ってユーザがオブジェクトごしに値にアクセス出来るようになります。

ぎゃくに、オブジェクトを渡して INSERT すると自動的にシリアライズしてテーブルに保存します。

スキーマ定義

さて、実際に Inflate を使ったカラムを作ってみましょう。

MyBookmark の bookmark テーブルは、ブックマークした時間が保存出来ないので、保存出来るようにします。

そして、ブックマークした日時を DateTime のオブジェクトとして扱えるようにしましょう。

データベースには epoch time を保存しておいて、通常は DateTime として扱いたい場合を書いてみます。

以下のようなコードになります。

    column create_at => int => {
        required => 1,
        unsigned => 1,
        default => sub { time() },
        inflate => sub {
            DateTime->from_epoch( epoch => $_[0] );
        },
        deflate => sub {
            ref($_[0]) && $_[0]->isa('DateTime') ? $_[0]->epoch : $_[0];
        },
    };

INSERT 時に値を省略出来るように default の定義をしています。今回は INSERT した時の time の値をそのまま入れます。

inflate の第一引数はデータベースから取り出したままの値です。

今回は epoch time が入ってくるので DateTime オブジェクトにして返します。

deflate の第一引数は row オブジェクトで利用している、そのカラムの値です。

inflate と比べて若干ややこしいですが、 $row->create_at( time() ) などと DateTime ではなく直接 epoch time を入れられる事に対応するためにこうなってます。

使ってみる

使い方は特に変わった事をする必要はありません。

create_at が DateTime オブジェクトを返すという事と、 create_at に epoch time と DateTime を入れられるという事位です。

以下のように使います。

    $bookmark->set( bookmark => [1, 1] );
    my $row = $bookmark->lookup( bookmark => [1, 1] );
    print $row->create_at . "\n";

    my $dt = DateTime->new( year => 1978, month => 3, day => 20 );
    $row->create_at( $dt );
    print $row->create_at . "\n";
    $row->update;

    my $row2 = $bookmark->lookup( bookmark => [1, 1] );
    print $row2->create_at . "\n";
    $row2->create_at( 0 );
    print $row2->create_at . "\n";
    $row2->update;

    my $row3 = $bookmark->lookup( bookmark => [1, 1] );
    print $row3->create_at . "\n";

結果は下記の通り。

(この行は実行した時間が入ります)
1978-03-20T00:00:00
1978-03-20T00:00:00
0
1970-01-01T00:00:00

0 になってる部分は、 create_at に 0 を入れたため、そのまま出てきてしまっています。

あくまでもデータベスから値を出すときに inflate 処理されているという事です。

これは、回避策がありますがまた今度の機会に。

まとめ

本日は Inflate を使ったカラムの作り方を扱いました。

明日はもう少し Inflate について掘り下げます。