<html><head><style type="text/css"><!-- DIV {margin:0px;} --></style></head><body><div style="font-family:times new roman, new york, times, serif;font-size:12pt"><div>I am pondering writing a simple little package and sticking it on CPAN that would try and do a little generic sql caching. The topic seems to come up about once a week, and I think I have a pretty good solution, kind of gleaned from much discussion on the list over the years. The code is at the end of this message.<br><br>You have sql with ?s as place holders. You pass the sql and what will fill the place holders ($binds). There is also a memcache_version_key which tries to keep a bit of state. The memcache_version_key might look like<br><br>'mvk.product_id.15'<br><br>When data_fallback runs, it generates a memkey like so<br><br><span id="1_messageHeaderCC" class="headerCC">my $memkey = 'df.' . ( $memcache->get($memcache_version_key) || 0 ) . '.' .
md5_hex($sql) . '.' . md5_hex( join( ', ', @$binds ) );<br><br>if data_fallback can find anything based on that memkey, it returns it, otherwise, it queries and sets memcache.<br><br>This is not a panacea, as you need to know when certain queries have become invalid and invalidate the cache yourself, so when you know that the data for the product with id 15 changes, you do something like<br><br>$memcache->incr($memcache_version_key);<br><br>Anyway, I think it works well, and the paradigm has worked well in the past, though the code below is from last night. The tactic is especially good for querying a table in many different ways.<br><br>There are also a couple niceties; like getting hash refs back, or making queries that return </span><span id="1_messageHeaderCC" class="headerCC">only </span><span id="1_messageHeaderCC" class="headerCC">one column into a simple array ref.<br><br>Ideas for a name are welcome. It would be nice to have some
simple CPAN code to point to when the discussion comes up again. This strategy alleviated my need for namespaces, and might be a nice stopgap until tags are incorporated.<br><br>Thoughts?<br>
</span><br>Thanks,<br>Earl<br><br><span id="1_messageHeaderCC" class="headerCC">use Carp qw(confess);<br>use Digest::MD5 qw(md5_hex);<br><br>sub data_fallback {<br> my $hash = shift || confess 'need a hash';<br><br> my $dbh = $hash->{dbh} || confess 'need a dbh';<br> my $sql = $hash->{sql} || confess 'need some sql';<br> my $binds = $hash->{binds} || confess 'need some binds';<br> my $memcache_version_key = $hash->{memcache_version_key}<br> || confess 'need a memcache_version_key';<br> my $ttl = $hash->{ttl} || 3600;<br> my $memcache = $hash->{memcache} || confess 'need a memcache object';<br> my $as_hash_ref =
$hash->{as_hash_ref};<br><br> my $memkey = 'df.'<br> . ( $memcache->get($memcache_version_key) || 0 ) . '.'<br> . md5_hex($sql) . '.'<br> . md5_hex( join( ', ', @$binds ) );<br><br> my $data;<br> if ( $data = $memcache->get($memkey) ) {<br> } else {<br> $data = [];<br><br> my $sth = $dbh->prepare($sql);<br> $sth->execute( @$binds );<br><br> if ($as_hash_ref) {<br> while ( my $hash_ref = $sth->fetchrow_hashref('NAME_lc') )
{<br> push @$data, $hash_ref;<br> }<br> } else {<br> while ( my @array = $sth->fetchrow_array ) {<br> if ( scalar @array == 1 ) {<br> push @$data, $array[0];<br> } else {<br> push @$data, \@array;<br>
}<br> }<br> }<br> $memcache->set( $memkey, $data, $ttl );<br> }<br> return $data;<br>}<br></span></div></div><br>
<hr size=1>Luggage? GPS? Comic books? <br>
Check out fitting <a href="http://us.rd.yahoo.com/evt=48249/*http://search.yahoo.com/search?fr=oni_on_mail&p=graduation+gifts&cs=bz"> gifts for grads</a> at Yahoo! Search.</body></html>