Here is the patch implementing 'rows fetched so far'. rows() now also
properly returns -1 when the $sth->{'proxy_rows'} is not defined. It is
debatable whether execute should undefine proxy _rows or set it to 0.
Unless someone has a good argument otherwise, it seems to me that
undefining proxy_rows is the most reasonable thing to do there.
- philip
Philip Dye wrote:
Tim,
You are quite correct. I was too hasty in writing that first patch.
According to the DBI documentation there are actually two approaches
in vogue for select operations:
rows <http://search.cpan.org/%7Etimb/DBI/DBI.pm#___top>
$rv = $sth->rows;
Returns the number of rows affected by the last row affecting
command, or -1 if the number of rows is not known or not available.
Generally, you can only rely on a row count after a /non/-|SELECT|
|execute| (for some specific operations like |UPDATE| and
|DELETE|), or after fetching all the rows of a |SELECT| statement.
For |SELECT| statements, it is generally not possible to know how
many rows will be returned except by fetching them all. Some
drivers will return the number of rows the application has fetched
so far, but others may return -1 until all rows have been fetched.
So use of the |rows| method or |$DBI::rows| with |SELECT|
statements is not recommended.
I will implement the 'rows fetched so far' model. Oddly enough
neither my earlier fix or this fix will fix the problem I had with
Rose::DB::Object::load() that expects sth->rows() to be greater than
zero if and only if the most recent fetch() has returned a row. I
posted a fix Rose::DB::Object::load() to its mailing list.
Ideally, the implementation of sth->rows() would become standardized
so that its value would be dependable one way or the other after a
fetch().
Respectfully,
Philip Dye
Senior Research Systems Programmer
Computing Facilities Group
School of Computer Science
[EMAIL PROTECTED]
*** DBD/Proxy.pm Fri Aug 17 07:54:55 2007
--- DBD/Proxy.pm.new Fri Aug 17 07:55:06 2007
*************** sub execute ($@) {
*** 510,515 ****
--- 510,516 ----
# new execute, so delete any cached rows from previous execute
undef $sth->{'proxy_data'};
+ undef $sth->{'proxy_rows'};
my $rsth = $sth->{proxy_sth};
my $dbh = $sth->FETCH('Database');
*************** sub fetch ($) {
*** 590,595 ****
--- 591,599 ----
my $data = $sth->{'proxy_data'};
+ defined($sth->{'proxy_rows'}) ||
+ ( $sth->{'proxy_rows'} = 0 );
+
if(!$data || [EMAIL PROTECTED]) {
return undef unless $sth->SUPER::FETCH('Active');
*************** sub fetch ($) {
*** 613,625 ****
my $row = shift @$data;
$sth->SUPER::STORE(Active => 0) if ( $sth->{proxy_cache_only} and [EMAIL
PROTECTED] );
return $sth->_set_fbav($row);
}
*fetchrow_arrayref = \&fetch;
sub rows ($) {
my($sth) = @_;
! $sth->{'proxy_rows'};
}
sub finish ($) {
--- 617,630 ----
my $row = shift @$data;
$sth->SUPER::STORE(Active => 0) if ( $sth->{proxy_cache_only} and [EMAIL
PROTECTED] );
+ $sth->{'proxy_rows'}++;
return $sth->_set_fbav($row);
}
*fetchrow_arrayref = \&fetch;
sub rows ($) {
my($sth) = @_;
! $sth->{'proxy_rows'} || -1;
}
sub finish ($) {