cvsuser     02/07/24 12:58:11

  Modified:    P5EEx/Blue/P5EEx/Blue/Repository DBI.pm
  Log:
  added store_row() implementation, overriding the base class
  
  Revision  Changes    Path
  1.14      +203 -11   p5ee/P5EEx/Blue/P5EEx/Blue/Repository/DBI.pm
  
  Index: DBI.pm
  ===================================================================
  RCS file: /cvs/public/p5ee/P5EEx/Blue/P5EEx/Blue/Repository/DBI.pm,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -w -r1.13 -r1.14
  --- DBI.pm    12 Jul 2002 21:08:31 -0000      1.13
  +++ DBI.pm    24 Jul 2002 19:58:11 -0000      1.14
  @@ -1,13 +1,13 @@
   
   ######################################################################
  -## File: $Id: DBI.pm,v 1.13 2002/07/12 21:08:31 spadkins Exp $
  +## File: $Id: DBI.pm,v 1.14 2002/07/24 19:58:11 spadkins Exp $
   ######################################################################
   
   use P5EEx::Blue::P5EE;
   use P5EEx::Blue::Repository;
   
   package P5EEx::Blue::Repository::DBI;
  -$VERSION = do { my @r=(q$Revision: 1.13 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r};
  +$VERSION = do { my @r=(q$Revision: 1.14 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r};
   
   @ISA = ( "P5EEx::Blue::Repository" );
   
  @@ -1279,17 +1279,212 @@
   }
   
   #############################################################################
  +# store_row()
  +#############################################################################
  +
  +=head2 store_row()
  +
  +    * Signature: $ok = $rep->store_row ($table, $cols, $row);
  +    * Signature: $ok = $rep->store_row ($table, $cols, $row, $keycolidx);
  +    * Signature: $ok = $rep->store_row ($table, $cols, $row, $keycolidx, 
$update_first);
  +    * Param:     $table             string
  +    * Param:     $cols              []
  +    * Param:     $row               []
  +    * Param:     $keycolidx         []
  +    * Param:     $update_first      boolean
  +    * Return:    $ok                boolean
  +    * Throws:    P5EEx::Blue::Exception::Repository
  +    * Since:     0.01
  +
  +    Sample Usage: 
  +
  +    $rep->store_row ($table, \@cols, \@rows, \@keycolidx);
  +
  +The store_row() method ensures that the row of data is stored regardless
  +whether the row exists currently in the table or not.  (The $update_first
  +flag may be set as a performance hint that under most conditions, the
  +application would expect a row to be present.)
  +
  +The method returns the number of rows properly stored (i.e. 0 or 1).
  +
  +If you have many rows to store, it is probably more efficient to use
  +the store_rows() method so that various implementation-specific
  +issues like locking may only be performed once.
  +
  +=cut
  +
  +sub store_row {
  +    my ($self, $table, $cols, $row, $keycolidx, $update_first) = @_;
  +    my ($ok, $nrows, $rownum, $colnum, $column, $tabledef);
  +    my ($pk_column, @insert_cols, @insert_cols_ih);
  +    my ($id, %paramvalues, $oldrow, $different, $key);
  +    my ($table_ih, $auto_id, $current_datetime, $context, $error, $sql);
  +    my ($column_obsolete_dttm, $column_change_dttm, %colidx, %nodiff_column);
  +
  +    $context = $self->{context};
  +    if ($P5EEx::Blue::DEBUG && $context->dbg(1)) {
  +        $context->dbgprint("store_row($table, col=$cols, row=$row (", ($#$row + 1), 
"), kidx=$keycolidx, up=$update_first)");
  +        $context->dbgprint("   cols=[",      join(",",@$cols),     "]") if ($cols);
  +        $context->dbgprint("   keycolidx=[", join(",",@$keycolidx),  "]") if 
($keycolidx);
  +    }
  +
  +    $self->store_begin($table);
  +    $tabledef = $self->{table}{$table};
  +    $table_ih = $tabledef->{table_ih} || "";
  +    $column_change_dttm = $tabledef->{column_change_dttm} || "";
  +    $column_obsolete_dttm = $tabledef->{column_obsolete_dttm} || "";
  +
  +    @insert_cols = @$cols;
  +    @insert_cols_ih = @$cols;
  +    %colidx = ();
  +    $pk_column = "";
  +    $auto_id = 0;
  +
  +    # todo: make it work with PK bigger than one column
  +    if ($tabledef->{prikey} && ref($tabledef->{prikey}) eq "ARRAY" && 
$#{$tabledef->{prikey}} == 0) {
  +        $pk_column = $tabledef->{prikey}[0];
  +        $auto_id = $tabledef->{column}{$pk_column}{auto_id};
  +    }
  +
  +    if ($P5EEx::Blue::DEBUG && $context->dbg(1)) {
  +        $context->dbgprint("    auto_id=$auto_id pk=$pk_column 
chg=$column_change_dttm obs=$column_obsolete_dttm");
  +    }
  +
  +    if (($auto_id && $pk_column) ||
  +        ($column_change_dttm && $column_obsolete_dttm)) {
  +
  +        for ($colnum = 0; $colnum <= $#$cols; $colnum++) {
  +            $column = $cols->[$colnum];
  +            $colidx{$column} = $colnum;
  +        }
  +
  +        if ($pk_column && ! defined $colidx{$pk_column}) {
  +            push(@insert_cols, $pk_column);
  +            push(@insert_cols_ih, $pk_column);
  +            $colidx{$pk_column} = $#insert_cols;
  +        }
  +
  +        if ($column_change_dttm && ! defined $colidx{$column_change_dttm}) {
  +            push(@insert_cols, $column_change_dttm);
  +            push(@insert_cols_ih, $column_change_dttm);
  +            $colidx{$column_change_dttm} = $#insert_cols;
  +        }
  +
  +        if ($column_obsolete_dttm && ! defined $colidx{$column_obsolete_dttm}) {
  +            push(@insert_cols_ih, $column_obsolete_dttm);
  +            $colidx{$column_obsolete_dttm} = $#insert_cols_ih;
  +        }
  +    }
  +
  +    %nodiff_column = ();
  +    if ($tabledef->{nodiff_column}) {
  +        foreach $column (split(/,/,$tabledef->{nodiff_column})) {
  +            $nodiff_column{$column} = 1;
  +        }
  +    }
  +
  +    # (todo) allow for $keycolidx to be undef (use "prikey")
  +    if ($keycolidx) {
  +        %paramvalues = ();
  +        foreach $colnum (@$keycolidx) {
  +            $column = $cols->[$colnum];
  +            $paramvalues{$column} = $row->[$colnum];
  +        }
  +        $oldrow = $self->select_row($table,\@insert_cols_ih,undef,\%paramvalues);
  +    }
  +
  +    $ok = 1;
  +    if ($keycolidx && $oldrow && $#$oldrow > -1) {  # old row existed
  +        # next if (does not have permission to modify);  (todo)
  +        # reduce the non-key column list to the set this user is permitted to 
modify (todo)
  +
  +        # check if data is the same
  +        $different = 0;
  +        for ($colnum = 0; $colnum <= $#$cols; $colnum++) {
  +            $column = $cols->[$colnum];
  +            next if ($nodiff_column{$column});
  +
  +            if ((!defined $row->[$colnum] &&  defined $oldrow->[$colnum]) ||
  +                ( defined $row->[$colnum] && !defined $oldrow->[$colnum])) {
  +                $different = 1;
  +            }
  +
  +            if (defined $row->[$colnum] && defined $oldrow->[$colnum]) {
  +                if (($row->[$colnum] =~ /^-?[0-9]+\.?[0-9]*$/ || $row->[$colnum] =~ 
/^-?\.[0-9]+$/) &&
  +                    ($oldrow->[$colnum] =~ /^-?[0-9]+\.?[0-9]*$/ || 
$oldrow->[$colnum] =~ /^-?\.[0-9]+$/)) {
  +                    if ($row->[$colnum] != $oldrow->[$colnum]) {
  +                        $different = 1;
  +                    }
  +                }
  +                else {
  +                    if ($row->[$colnum] ne $oldrow->[$colnum]) {
  +                        $different = 1;
  +                    }
  +                }
  +            }
  +            last if ($different);
  +        }
  +
  +        # only if it is considered different do we try to physically store the row
  +        if ($different) {
  +            # substitute any defaults (todo)
  +            if ($table_ih) {
  +                if ($column_obsolete_dttm && $column_change_dttm) {
  +                    $oldrow->[$colidx{$column_obsolete_dttm}] = 
$row->[$colidx{$column_change_dttm}];
  +                }
  +                $ok = $self->insert_row($table_ih,\@insert_cols_ih,$oldrow);
  +            }
  +            $ok = $self->update_row($table,$cols,$row,$keycolidx) if ($ok);
  +        }
  +
  +        if ($P5EEx::Blue::DEBUG && $context->dbg(2)) {
  +            $context->dbgprint("store_row() old=[", join(",",@$oldrow), "]");
  +            $context->dbgprint("             new=[", join(",",@$row), "]");
  +            $error = $self->error();
  +            $sql = $error ? $self->{sql} : "";
  +            $context->dbgprint("             diff=$different ok=$ok err=$error 
$sql");
  +        }
  +    }
  +    else {
  +        # next if (does not have permission to insert);  (todo)
  +
  +        # if we need to automatically allocate an ID ...
  +        if ($auto_id && ! $row->[$colidx{$pk_column}]) {
  +            $id = $self->next_id($table, $id);
  +            $row->[$colidx{$pk_column}] = $id;
  +        }
  +        $ok = $self->insert_row($table,\@insert_cols,$row);
  +
  +        if ($P5EEx::Blue::DEBUG && $context->dbg(2)) {
  +            $context->dbgprint("store_row() new=[", join(",",@$row), "]");
  +            $error = $self->error();
  +            $sql = $error ? $self->{sql} : "";
  +            $context->dbgprint("                   ok=$ok err=$error $sql");
  +        }
  +    }
  +
  +    $nrows = $ok ? 1 : 0;
  +
  +    $self->store_end($table);
  +    $self->{numrows} = $nrows;
  +    $nrows;
  +}
  +
  +#############################################################################
   # store_rows()
   #############################################################################
   
   =head2 store_rows()
   
  +    * Signature: $nrows = $rep->store_rows ($table, $cols, $rows, $keycolidx);
       * Signature: $nrows = $rep->store_rows ($table, $cols, $rows, $keycolidx, 
$update_first);
  +    * Signature: $nrows = $rep->store_rows ($table, $cols, $rows, $keycolidx, 
$update_first, $row_crit);
       * Param:     $table             string
       * Param:     $cols              []
       * Param:     $rows              [][]
       * Param:     $keycolidx         []
       * Param:     $update_first      boolean
  +    * Param:     $row_crit          {}
       * Return:    $nrows             integer
       * Throws:    P5EEx::Blue::Exception::Repository
       * Since:     0.01
  @@ -1298,24 +1493,21 @@
   
       $rep->store_rows ($table, \@cols, \@rows, \@keycolidx, $update_first);
   
  -The store_rows() method ensures that all rows of data are stored by
  -trying both an insert, then an update (or vice-versa, depending on the
  -$update_first flag).
  +The store_rows() method ensures that all rows of data are stored regardless
  +whether the row exists currently in the table or not.  (The $update_first
  +flag may be set as a performance hint that under most conditions, the
  +application would expect a row to be present.)
   
   If any row fails to be stored, the method will exit immediately,
   returning the number of rows that were successfully stored.
   
  -The default implementation here is built on using the store_row() method.
  -It is fully functional, but it may be overridden in
  -the subclass if there is a more efficient way to do it.
  -
   =cut
   
   # $nrows = $rep->store_rows ($table, \@cols, \@rows, \@keycolidx, $update_first);
   sub store_rows {
       my ($self, $table, $cols, $rows, $keycolidx, $update_first, $row_crit) = @_;
       my ($row, $ok, $nrows, $rownum, $colnum, $column, $tabledef);
  -    my ($pk_column, @extra_cols, @insert_cols, @insert_cols_ih);
  +    my ($pk_column, @insert_cols, @insert_cols_ih);
       my ($id, %paramvalues, $oldrow, $oldrows, %oldrows, $different, $key);
       my ($table_ih, $auto_id, $current_datetime, $context, $error, $sql);
       my ($column_obsolete_dttm, $column_change_dttm, %colidx, %nodiff_column);
  @@ -1490,7 +1682,7 @@
               # next if (does not have permission to insert);  (todo)
   
               # if we need to automatically allocate an ID ...
  -            if ($auto_id) {
  +            if ($auto_id && ! $row->[$colidx{$pk_column}]) {
                   $id = $self->next_id($table, $id);
                   $row->[$colidx{$pk_column}] = $id;
               }
  
  
  


Reply via email to