Teng でデータ入出時に自動的にフィールド値を変換するようにしてみる
この機能は Teng に既に実装されておりSchemaクラスにinflate及びdeflate関数で処理を定義することで 定義したフィールドでのデータの入出力時に自動で値の変換処理を行わせることができるようになる大変便利な機能です。
具体例で説明するとある文字列をinsertするとデータベース上では圧縮されて保存され、それをデータベースから取り出すと自動的に元に復元された状態で取り出せる自動フィルタのような機能です。
今回は日付を扱うクラスTime::Pieceオブジェクトでinsertするとデータベース上ではepoch時間で保存され、取り出した時は自動的に Time::Piece オブジェクトになって出てくる処理を書きたいと思う。
■データベーステーブルとschemaクラスの作成
CREATE TABLE entry( id integer primary key, body text, create_at integer );
日付を格納するのに create_at カラムを定義します。 型は秒数で保存されるので integer型ですね。
この場合のSchemaは以下の様になります。
package Entry::Model::Schema; use Teng::Schema::Declare; table { name 'entry'; pk 'id'; columns qw(id body create_at); }; 1;
上記schemaにinflate, deflateの処理を追加します。
package Entry::Model::Schema; use Teng::Schema::Declare; use Time::Piece; table { name 'entry'; pk 'id'; columns qw(id body create_at); inflate 'create_at' => sub { my ($col_value) = shift; return localtime( $col_value ); }; deflate 'create_at' => sub { my ($col_value) = @_; return ref $col_value eq 'Time::Piece' ? $col_value->epoch : die "Time::Piece obj only"; }; }; 1;
inflate処理
inflate ではデータを取得する際にかかる処理を書きます。 データベース上にepoch時間で保存されたデータを Time::Piece オブジェクトに変換して出力します。 Time::Piece クラスにあるlocaltime()関数にepoch時間を渡すことで簡単にオブジェクト化することができます。
deflate処理
deflate ではデータを保存する際にかかる処理を書きます。 渡ってきた Time::Piece オブジェクトをepoch時間に変換するだけです。 渡ってくるデータが'Time::Piece'か確認してオブジェクトであればepochメソッドを呼びepoch時間に変換しています。
■データの登録と確認
#!/usr/bin/env perl use Time::Piece; use Entry::Model; my $teng = Entry::Model->new({connect_info => ['DBI:SQLite:database=myapp.db;','','']}); my $now = localtime; my $row = $teng->insert( 'entry' => { body => "moe". int(rand(1)*1000), create_at => $now, } ); my $itr = $teng->search('entry',{},{}); while ( my $row = $itr->next) { warn join "|", $row->id, $row->body, $row->create_at; }
■結果表示
1|moe421|Thu Dec 1 00:07:01 2011 at entry.pl line 20. 2|moe842|Thu Dec 1 00:07:15 2011 at entry.pl line 20. 3|moe485|Thu Dec 1 00:07:18 2011 at entry.pl line 20. 4|moe706|Thu Dec 1 00:07:19 2011 at entry.pl line 20. 5|moe857|Thu Dec 1 00:07:20 2011 at entry.pl line 20.
inflate 及び deflate を利用することで日付の部分は$row->create_atでオブジェクトとして取得できるので日付の加減算や表示フォーマットなどが簡単に変更出来るので便利ですね。