[freeside-devel] Re: [freeside] Stuck on a hashref and mod_perl

ivan ivan at 420.am
Fri Jun 23 05:33:08 PDT 2000


Okay, I rewrote FS::Record::qsearch; it no longer uses the return value of
$sth->execute as a number of rows (and also uses prepare_cached and
placeholders).

I decided not to add the stuff for lowercasing column names to the main
Freeside tree; the DBI docs seem to point in that direction (though not
everything can do this yet; notably, fetchall_arrayref in HASH mode has no
provisions for passing `NAME_lc' or `NAME_uc' to the underlying
fetchrow_hashref call). 

On Thu, Jun 22, 2000 at 10:22:24PM -0400, Stephen Amadei wrote:
> On Thu, 22 Jun 2000, ivan wrote:
> 
> > Yes, you're not supposed to count on that behaviour.  It's in the TODO:
> > 
> >   Portability: in FS::Record, $sth->execute does not return a number of
> >   rows for all DBD's.  see man DBI
> > 
> > So I'd be interested getting a copy of those changes if you can isolate
> > them.
> 
> Well, after some testing, I had to remove my changes from "new" and
> put everything in "qsearch".  It's not as graceful as the original code,
> but it's working very nicely for me... now I can back out all my little
> patches and apply them to 1.2.3.
> 
> I tried using the attribute $sth->{NAME_lc} to force DB2 to lowercase
> the column names, but either I am using it wrong or it's broken... at
> least in DB2.  If this worked, it would eliminate alot of code from
> my qsearch.  Also DBD-DB2 versions after .71 seem to have a bug that 
> my code is ticking off, so I had to downgrade from .73 to .71.  I'm
> still trying to figure this out.
> 
> Here is my version of "qsearch" from record.pm, version 1.2.2... IIRC,
> this chunk of code is the same as 1.2.3.  I'm sure the code can be
> optimized and cleaned up, but I'm still too new to PERL for that... ;-)
> 
> ----
> sub qsearch {
>   my($table,$record) = @_;
>   my($dbh) = dbh;
> 
>   my(@fields)=grep exists($record->{$_}), fields($table);
> 
>   my($sth);
>   my($statement) = "SELECT * FROM $table". ( @fields
>     ? " WHERE ". join(' AND ',
>       map {
>         $record->{$_} eq ''
>           ? ( datasrc =~ m/Pg/
>                 ? "$_ IS NULL"
>                 : "( $_ IS NULL OR $_ = \"\" )"
>             )
>           : "$_ = ". _quote($record->{$_},$table,$_)
>       } @fields
>     ) : ''
>   );
>   $sth=$dbh->prepare($statement)
>     or croak $dbh->errstr; #is that a little too harsh?  hmm.
>   #warn $statement #if $debug # or some such;
> 
>   my $row;
>   my @therows;
>   $sth->execute;
> 
>   if ( eval ' scalar(@FS::'. $table. '::ISA);' ) {
>     while ( $row=$sth->fetchrow_hashref) {
> 
>       # This next block lowercases all the keys, since DB2
>       # returns them all uppercase.  I tried using $sth->{NAME_lc},
>       # but either I am using it wrong or it doesn't work in DBD:DB2.
>       # 6/20/2000 SPA amadei at dandy.net
> 
>       if (datasrc =~ m/DB2/ ) {
>         while (( my $key, my $value) = each %$row) {
>           $row->{lc($key)}=$value;
>           delete $row->{$key};
>           }
>         }
> 
>       eval ' push @therows, new FS::' . $table. ' ( $row );';
>     }
>   } else {
>     cluck "qsearch: warning: FS::$table not loaded; returning generic FS::Record objects";
>     while ( $row=$sth->fetchrow_hashref) {
> 
>       if (datasrc =~ m/DB2/ ) {
>         while (( my $key, my $value) = each %$row) {
>           $row->{lc($key)}=$value;
>           delete $row->{$key};
>           }
>         }
> 
>       eval ' push @therows, new FS::' . $table. ' ( $row );';
>     }
>   }
>   @therows;
> }
> ----
> 
> > Another possibility is that your modifications have caused the qsearch() 
> > call to return one or more undefined values (since it's called in list
> > context, it returns a list). 
> 
> Ah ha!  That was it.  Being a C++ programmer, I am not used to these
> PERL contexts.  Took a bit more code to do, but it works...
> 
> 					----Steve
> Stephen Amadei
> Dandy.net CTO
> Atlantic City, NJ
> 
> 
> 

-- 
meow
_ivan



More information about the freeside-devel mailing list