From: Justin Hunter Date: Fri, 21 Jan 2011 01:52:50 +0000 (+0000) Subject: base cache key on sql and binds plus dbname and username X-Git-Tag: v1.1.0~6 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=c94953274bec9dac0655040ec70da3e710044270;p=dbsrgits%2FDBIx-Class-Cursor-Cached.git base cache key on sql and binds plus dbname and username --- diff --git a/lib/DBIx/Class/Cursor/Cached.pm b/lib/DBIx/Class/Cursor/Cached.pm index 5eaf6b0..758cf5d 100644 --- a/lib/DBIx/Class/Cursor/Cached.pm +++ b/lib/DBIx/Class/Cursor/Cached.pm @@ -48,7 +48,24 @@ sub reset { 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); + my $connect_info = $storage->_dbi_connect_info; + my ($dbname, $username); + if (ref($connect_info->[0]) eq 'CODE') { + my $dbh = $connect_info->[0]->(); + $dbname = $dbh->{Name}; + $username = $dbh->{Username} || ''; + } else { + $dbname = $connect_info->[0]; + $username = $connect_info->[1] || ''; + } + + local $Storable::canonical = 1; + return Digest::SHA1::sha1_hex(Storable::nfreeze( [ $ref, $dbname, $username ] )); + } sub _fill_data { diff --git a/t/simple.t b/t/simple.t index 9263e59..57454f9 100644 --- a/t/simple.t +++ b/t/simple.t @@ -101,3 +101,52 @@ is_deeply($cache->get($rs->cursor->cache_key), $expect_data, 'correct data in cache'); } + +{ + my $schema = SchemaClass->connect( + sub { + DBI->connect('dbi:SQLite:t/var/test.db', '', '', { RaiseError => 1 }) }, + { cursor_class => 'DBIx::Class::Cursor::Cached' } + ); + + $schema->default_resultset_attributes({ + cache_object => Cache::FileCache->new({ namespace => 'SchemaClass' }), + }); + +my $cache = $schema->default_resultset_attributes->{cache_object}; + + my $rs = $schema->resultset('CD')->search(undef, { cache_for => 300 }); + + my @cds = $rs->all; # fills cache + +is_deeply([ map { [ $_->id, $_->title ] } @cds ], $expect_data, + 'correct data in objects'); +is_deeply($cache->get($rs->cursor->cache_key), $expect_data, + 'correct data in cache'); + + $rs = $schema->resultset('CD')->search(undef, { cache_for => 300 }); + # refresh resultset + +$schema->storage->disconnect; + + @cds = $rs->all; # uses cache, no SQL run + +ok(!$schema->storage->connected, 'no reconnect made since no SQL required'); +is_deeply([ map { [ $_->id, $_->title ] } @cds ], $expect_data, + 'correct data in objects'); +is_deeply($cache->get($rs->cursor->cache_key), $expect_data, + 'correct data in cache'); + + $rs->cursor->clear_cache; # deletes data from cache + +ok(!defined($cache->get($rs->cursor->cache_key)), 'cache cleared'); + + @cds = (); while (my $rec = $rs->next) { push(@cds, $rec); } + +is_deeply([ map { [ $_->id, $_->title ] } @cds ], $expect_data, + 'correct data in objects'); +is_deeply($cache->get($rs->cursor->cache_key), $expect_data, + 'correct data in cache'); +} + +