« order by rand() | メイン | ぱどタウンの横浜タウンに中田市長が »

「Class::DBI で疑似的カラム」をちょっと機能強化と、Class::DBIにStorable::freezeなデータ

nipotanさんの「Class::DBI で疑似的カラムを扱う」で(自演)紹介されてるClass::DBI::Plugin::PseudoColumnsなんですが、ObjectやHASHをStorableでSerializeしてデータベースに突っ込む方法を便利にできるプラグインとしてちょっと気になった。

ただ、2つほど弱点があって

  • create/insert時に使えない
  • SerializeがData::Dumperオンリー

このあたりが解決されると使いやすいと思うのでいじってみた。

podを書いてないんだけど、ソース一式はこちら→Class-DBI-Plugin-SerializeColumns-0.01.tar.gz。なかなかうまく動かなくていろいろ変更しているうちにソースコードは派手に変わっています。

使い方はPseudoColumnsと同じで、

create table movies (
    id    int primary key,
    title    varchar(255),
    serialized    blob
);

というテーブルで、

package My::Film;
use base 'Class::DBI';
use Class::DBI::Plugin::SerializeColumns;
__PACKAGE__->table('Movies');
__PACKAGE__->columns(All => qw/id title serialized/);
__PACKAGE__->serialize_columns(serialized=>qw/year director/);

というクラスを作って、使う。

My::Film->create({
    id=>1,
    title=>'四月物語',
    year=>'1998',
    director=>'岩井俊二'
});

createして、

my $film = My::Film->retrieve(1);
$film-> year #1998

と動くはず。

Serializerは、Class::DBI::Plugin::SerializeColumns::Serializerにthawとfreezeの2つの関数を作成しておいて、

__PACKAGE__->columns_serializer('Serializer');

とすると利用できるハズ。未テスト。
なにも指定しなければStorableが使われる。

はまったのは、Class::DBIにStorable::freezeなデータを渡す部分。

package My::Film;
use strict;
use warnings;
use base 'Class::DBI';
__PACKAGE__->table('Movies');
__PACKAGE__->columns(All => qw/id title serialized/);

を用意して、

{
    My::Film->create({
        id=>1,
        title=>'四月物語',
        serialized=>Storable::freeze({year=>1998,director=>'岩井俊二'})
    });
}
{
    my $film = My::Film->retrieve(1);
    my $ref = Storable::thaw($film->serialized);
    print $ref->{year},"\n";
}

これが動かない。「$film->serialized」が保存しようとしたものと違う。

とりあえず、katoさんのCatalyst::Plugin::Session::ManagerのStorage::CDBIを参考にbase64で対応したけどまだ調べる必要がありそうです。

トラックバック

この一覧は、次のエントリーを参照しています: 「Class::DBI で疑似的カラム」をちょっと機能強化と、Class::DBIにStorable::freezeなデータ:

» Class::DBI でもっと透過的に擬似的カラムを扱う from にぽたん研究所
以前 Class::DBI で疑似的カラムを扱うというタイトルで、Class::DBI::Plugin::PseudoColumns という CPAN モ... [詳しくはこちら]