• このエントリーをはてなブックマークに追加

はじめに

ちょっとDBIx::Skinnyの勉強ちゅうです.

チュートリアルが詰まっているJPerl Advent Calendar 2009 の DBIx::Skinny trackに目を通して,「inflate」「deflate」なる概念を初めて知りました>< というか,O/Rマッパを触るのが初めt(ry

ということで,以下,その動作確認のメモです.

参考

主要モジュールのバージョン

DBIx::Skinny
0.0712
DBIx::Skinny::Schema::Loader
0.12

確認用コード

UNIX時間が格納されているカラムを読み,DateTime::Format::MySQLを使ってDateTimeオブジェクトとして取得することを考えてみます.

まず,モデルの定義.

package Hoge::DB;
use DBIx::Skinny setup => +{
    dsn      => 'dbi:mysql:hoge',
    username => 'hoge',
    password => 'hogehoge',
};
1;
 
 
package Hoge::DB::Schema;
use base qw/DBIx::Skinny::Schema::Loader/;
use DBIx::Skinny::Schema;
use DateTime::Format::MySQL;
 
install_inflate_rule qr/^t_add$/ => callback {
    inflate {
        my $v = shift;
        my @t = reverse ((localtime($v))[0..5]);
        $t[0] += 1900; $t[1]++;
        my $dt = sprintf(
            '%04d-%02d-%02d %02d:%02d:%02d',
            @t,
        );
        return DateTime::Format::MySQL->parse_datetime($dt);
    };
};
 
__PACKAGE__->load_schema;
1;

モデルオブジェクトを生成してSELECTして「t_add」カラムを取得するコード.DBIx::Skinny::Rowオブジェクトで指定のカラムを取得する方法が何とおりかあるようなので,とりあえず確認できた3パタンで確認しています.

use Hoge::DB;
use Data::Dumper;
 
my $model = Hoge::DB->new;
 
my $itr = $model->search_by_sql(
    'SELECT t_add FROM table',
    [],
    'table',
);
 
my $row = $itr->first;
print Dumper [
    $row->get_columns->{t_add},
    $row->get_column('t_add'),
    $row->t_add,
];

出力結果

次のように出ました.

$VAR1 = [
          '1278191892',
          '1278191892',
          bless( {
                   'local_rd_secs' => 22692,
                   'local_rd_days' => 39966,
                   'rd_nanosecs' => 0,
                   'locale' => bless( {
                                        'default_time_format_length' => 'medium',
                                        'native_territory' => 'United States',
                                        'native_language' => 'English',
                                        'native_complete_name' => 'English United States',
                                        'en_language' => 'English',
                                        'id' => 'en_US',
                                        'default_date_format_length' => 'medium',
                                        'en_complete_name' => 'English United States',
                                        'en_territory' => 'United States'
                                      }, 'DateTime::Locale::en_US' ),
                   'local_c' => {
                                  'hour' => 6,
                                  'second' => 12,
                                  'month' => 6,
                                  'quarter' => 2,
                                  'day_of_year' => 155,
                                  'day_of_quarter' => 65,
                                  'minute' => 18,
                                  'day' => 4,
                                  'day_of_week' => 3,
                                  'year' => 110
                                },
                   'utc_rd_secs' => 22692,
                   'formatter' => undef,
                   'tz' => bless( {
                                    'name' => 'floating',
                                    'offset' => 0
                                  }, 'DateTime::TimeZone::Floating' ),
                   'utc_year' => 111,
                   'utc_rd_days' => 39966,
                   'offset_modifier' => 0
                 }, 'DateTime' )
        ];

まとめ

inflateされたものを取得するには,rowオブジェクトからカラム名なメソッドで呼び出す必要があるようです.

ちょっと気になったところ

inflate/deflateの引数となるコードの中でエラーがあった場合,これを拾う方法はあるのかな.まぁ,値がinflateされずにそのまま得られるので,問題があることに気づくとは思いますが.

あと,この場合,$model->schema->schema_infoの値が空なハッシュリファレンスになりますね.(あまり関係ない?)

おわりに

以上,初めてのO/Rマッパ(でもある)DBIx::Skinnyの勉強の一環として,inflateの動作を確認してみました.

まだほんの少ししか触っていませんが,inflate/deflateは非常にありがたい機能ですね.しっかり使いこなせるよう精進します.