[freeside] Stuck on a hashref and mod_perl

Stephen Amadei amadei at dandy.net
Thu Jun 22 19:22:21 PDT 2000


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






More information about the freeside-devel mailing list