On Thu, Sep 07, 2000 at 06:22:40PM -0700, Perrin Harkins wrote:
> I'd say this is probably useful to some people, so go ahead.  A few
> suggestions: 
> - Use the DBIx namespace for the module. 

Sounds reasonable.  The question then is: what should the API be like?

The way it works right now is with an API of its own:
$arrayref_of_arrays = SelectCache::select($dbh, $st, $timeout);

It'd be nice to have an API that mimics the DBI one more closely, with
the different fetchrow_* and fetchall_* interfaces.  Then again, for a
module whose main purpose in life is to speed up SELECTs, maybe
restricting it to mimic the selectall_arrayref(), selectrow_array() and
selectcol_arrayref() would be enough.  

I really don't see much of a purpose on writing iterators a-la
fetchrow_* for a module that gets all the rows at the same time.  This
is actually an important thing to decide, because AFAICS
fetchrow_hashref is the only method that returns hashes and therefore
needs to care about column names.  So if we decide to support only the
select* interfaces, all we have to store are arrayrefs of arrayrefs.  If
we do support fetchrow_hashref, then we need either two kinds of storage
(so that the results of the same SELECT can be cached twice, if one
scrpit wants arrays and the other wants hashes), or a way to get arrays
from hashes or vice versa, which looks hard because one loses the order
and the other the names.

Another matter is: should this be a subclass of DBI, mimicing its API,
with an interface like:

my $dbc = DBI::SelectCache->new($db);
$dbc->expiration(180);
my $st = qq{ select ... };
my $rows = $dbc->selectall_arrayref($st);

and letting everything else (prepare, fetch*, etc) fall through to the
superclass, or should it be passing the expiration time as part of the
main function all, as I was doing before?  That woudl be something like:

my $st = qq{ select ... };
my $rows = DBI::SelectCache->selectall_arrayref($db, $st);

The first option fits in better with DBI, but the second is more
practical for the user, who doesn't need to create another object, and
can think of the expiration as a per-statement thing (which it is),
rather than per-connection.

Any suggestions?  I'm a bit lost on how to give this thing a good,
extendable interface.

> - If possible, use some existing cache module for the storage, like
> Apache::Session or one of the m/Cache/ modules on CPAN.

Others have suggested Storable.  I've used this one before, and I can
agree that it's probably a good solution.

Right now, what I'm doing is just join()ing the arrays with null
characters as separators, and using spilt() to get them back.  But null
chars are allowed in databases, so I agree that switching to Storable
would be a good idea.

> - Provide a safety check so that if a query brought back a few million
> rows by accident you wouldn't try to write the whole mess to disk.
> - Maybe try to support the other results interfaces in DBI?

Sounds good.  This means that this module would need a config file.

-- 
Roger Espel Llima, [EMAIL PROTECTED]
http://www.iagora.com/~espel/index.html

Reply via email to