「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で対応したけどまだ調べる必要がありそうです。