Subject: | ::Cached doesn't work with DBIx::Class::ResultSet::WithMetaData (and is too sensitive to irrelevant attrs) |
DBIx-Class-Cursor-Cached doesn't work with DBIx::Class::ResultSet::WithMetaData, or any
other module that adds code refs into the attributes, because Storable croaks.
It's will also generate different keys for searches that differ only by attribute values that are
irrelevant to the database query.
It's also affected by the pseudo-random ordering of hash keys (because it doesn't set
$Storable::canonical - which would be costly for hashes anyway).
The attached patch (outlined by ribasushi++) avoids all these problems by basing the cache
key on the rendered SQL query and bind values.
Subject: | DBIx-Class-Cursor-Cached-as_query1.patch |
--- perl/cpan/lib/perl5/DBIx/Class/Cursor/Cached.pm.orig 2010-10-17 22:35:43.000000000 +0100
+++ perl/cpan/lib/perl5/DBIx/Class/Cursor/Cached.pm 2010-10-17 22:40:58.000000000 +0100
@@ -48,7 +48,15 @@
sub _build_cache_key {
my ($class, $storage, $args, $attrs) = @_;
- return Digest::SHA1::sha1_hex(Storable::nfreeze([ $args, $attrs ]));
+ # compose the query and bind values, like as_query(),
+ # so the cache key is only affected by what the database sees
+ # and not any other cruft in $attrs
+ my $ref = $storage->_select_args_to_query(@{$args}[0..2], $attrs);
+ # nfreeze is used because bind args may include refs
+ # $Storable::canonical is used just in case the refs incude
+ # hash refs (unlikely, but this is cheap insurance)
+ local $Storable::canonical = 1;
+ return Digest::SHA1::sha1_hex(Storable::nfreeze( $ref ));
}
sub _fill_data {