2007-04-07 12:31:08

Cache::Memcached と DBIx::Class

[DBIx::Class] [Perl]

Cache::Memcached (Cache::FileCache,Catalyst::Plugin::Cache::Memcachedも) はオブジェクトがキャッシュできる。とても便利。
でもDBIx::Classのオブジェクトは、キャッシュできないことがある。

サンプル:
#!/usr/bin/perl
use strict;
use Cache::Memcached;
use TestDB;

my $memd = new Cache::Memcached {'servers' => [ "127.0.0.1:11211" ]};
my $schema = TestDB->connect("dbi:mysql:testdb;localhost",'user','password');

#OK pattern
my $ok = $schema->resultset('Test')->find(1);
$memd->set('key', $ok);
print $memd->get('key')->message,"\n";

#NG pattern
my $ng = $schema->resultset('Test')->search({id => 1});
$memd->set('key', $ng); #ここでエラー
print $memd->get('key')->next->message,"\n";

$ngはSQL実行結果の値を持っていない。
DBIx::Classのイテレータが素晴らしいのはSQLを最後の最後で実行することだし・・。

↓以下なら動く。Cache::Memcached使用時、イテレータは要注意。

#NG->OK pattern 1
my $ng = $schema->resultset('Test')->search({id => 1})->next;
$memd->set('key', $ng);
print $memd->get('key')->message,"\n";

#NG->OK pattern 2
my @ng = $schema->resultset('Test')->search({id => 1});
$memd->set('key', \@ng);
foreach (@{$memd->get('key')}) {
        print $_->message,"\n";
}