Author: spadkins
Date: Fri Dec  5 08:50:45 2008
New Revision: 12140

Modified:
   p5ee/trunk/App-Repository/lib/App/Repository/Oracle.pm

Log:
added insert_rows() logic for multiple rows per insert statement for Oracle

Modified: p5ee/trunk/App-Repository/lib/App/Repository/Oracle.pm
==============================================================================
--- p5ee/trunk/App-Repository/lib/App/Repository/Oracle.pm      (original)
+++ p5ee/trunk/App-Repository/lib/App/Repository/Oracle.pm      Fri Dec  5 
08:50:45 2008
@@ -240,7 +240,7 @@
 
 # $insert_sql = $rep->_mk_insert_rows_sql ($table, [EMAIL PROTECTED], [EMAIL 
PROTECTED], \%options);
 # i.e. $options->{replace}
-sub TBD_mk_insert_rows_sql {
+sub _mk_insert_rows_sql {
     &App::sub_entry if ($App::trace);
     my ($self, $table, $cols, $rows, $options) = @_;
 
@@ -257,12 +257,19 @@
     }
     my $column_defs = $self->{table}{$table}{column};
 
-    my $insert = $options->{replace} ? "replace" : "insert";
-    my $sql = "$insert into $table\n  (" . join(", ", @$cols) . ")\nvalues\n";
+    #INSERT ALL
+    #   INTO suppliers (supplier_id, supplier_name) VALUES (1000, 'IBM')
+    #   INTO suppliers (supplier_id, supplier_name) VALUES (2000, 'Microsoft')
+    #   INTO suppliers (supplier_id, supplier_name) VALUES (3000, 'Google')
+    #SELECT * FROM dual;
+
+    my $sql = "insert all\n";
+    my $sql_row_prefix = "  into $table (" . join(",", @$cols) . ") values ";
     my ($value, $colnum, $quoted, $row, $col);
     if ($rows && $#$rows > -1 && ref($rows->[0]) eq "ARRAY") {
         for (my $rownum = 0; $rownum <= $#$rows; $rownum++) {
             $row = $rows->[$rownum];
+            $sql .= $sql_row_prefix;
             for ($colnum = 0; $colnum <= $#$cols; $colnum++) {
                 $col = $cols->[$colnum];
                 $value = $row->[$colnum];
@@ -278,14 +285,15 @@
                 if ($column_defs->{$col}{dbexpr_update}) {
                     $value = sprintf($column_defs->{$col}{dbexpr_update}, 
$value);
                 }
-                $sql .= ($colnum == 0) ? "  ($value" : ", $value";
+                $sql .= ($colnum == 0) ? "($value" : ",$value";
             }
-            $sql .= ($rownum < $#$rows) ? "),\n" : ")\n";
+            $sql .= ")\n";
         }
     }
     else {  # if $row is a HASH or OBJECT ...
         for (my $rownum = 0; $rownum <= $#$rows; $rownum++) {
             $row = $rows->[$rownum];
+            $sql .= $sql_row_prefix;
             for ($colnum = 0; $colnum <= $#$cols; $colnum++) {
                 $col = $cols->[$colnum];
                 $value = $row->{$col};
@@ -301,31 +309,18 @@
                 if ($column_defs->{$col}{dbexpr_update}) {
                     $value = sprintf($column_defs->{$col}{dbexpr_update}, 
$value);
                 }
-                $sql .= ($colnum == 0) ? "  ($value" : ", $value";
-            }
-            $sql .= ($rownum < $#$rows) ? "),\n" : ")\n";
-        }
-    }
-    if (!$options->{replace} && $options->{update}) {
-        my $update = $options->{update};
-        $sql .= "on duplicate key update";
-        my $first_update_column = 1;
-        for ($colnum = 0; $colnum <= $#$cols; $colnum++) {
-            $col = $cols->[$colnum];
-            if (!ref($update) || $update->{$col}) {
-                $sql .= "," if (!$first_update_column);
-                $first_update_column = 0;
-                $sql .= "\n   $col = values($col)";
+                $sql .= ($colnum == 0) ? "($value" : ",$value";
             }
+            $sql .= ")\n";
         }
-        $sql .= "\n";
     }
+    $sql .= "select * from dual\n";
     &App::sub_exit($sql) if ($App::trace);
     $sql;
 }
 
 # $nrows = $rep->_insert_rows ($table, [EMAIL PROTECTED], [EMAIL PROTECTED]);
-sub TBD_insert_rows {
+sub _insert_rows {
     &App::sub_entry if ($App::trace);
     my ($self, $table, $cols, $rows, $options) = @_;
     $self->{error} = "";
@@ -366,16 +361,6 @@
                 print $App::DEBUG_FILE "\n";
             }
 
-            # The MySQL "insert ... on duplicate key update ..." statement 
returns 2 rows affected
-            # when the insert gets a collision and causes an update.  So we 
have to make this
-            # adjustment.  I don't know if it affects the "replace ..." 
statement in a similar way,
-            # but I figure this can't hurt.
-            if ($options->{update} || $options->{replace}) {
-                if ($retval > $nrows_this_insert) {
-                    $retval = $nrows_this_insert;
-                }
-            }
-
             $nrows += $retval;
             $rownum += $maxrows;
         }
@@ -388,8 +373,8 @@
         my ($fh);
         if (!$rows_ref) {
             my $file = $rows;          # assume it is a file name
-            open(App::Repository::MySQL::FILE, $file) || die "Unable to open 
$file for reading: $!";
-            $fh = \*App::Repository::MySQL::FILE;
+            open(App::Repository::Oracle::FILE, $file) || die "Unable to open 
$file for reading: $!";
+            $fh = \*App::Repository::Oracle::FILE;
         }
         else {
             $fh = $rows;               # assume it is a file handle
@@ -421,7 +406,7 @@
         }
         $self->{numrows} = $nrows;
         if (!$rows_ref) {
-            close(App::Repository::MySQL::FILE);
+            close(App::Repository::Oracle::FILE);
         }
     }
     if ($debug_sql) {
@@ -444,20 +429,14 @@
     if ($import_method eq "basic") {
         $nrows = $self->SUPER::import_rows($table, $columns, $file, $options);
     }
-    # DOESN'T WORK YET
-    #elsif ($import_method eq "insert") {
-    #    $nrows = $self->insert_rows($table, $columns, $file, $options);
-    #}
+    elsif ($import_method eq "insert") {
+        $nrows = $self->insert_rows($table, $columns, $file, $options);
+    }
     else {
         my $context_options = $self->{context}{options};
         my $prefix    = $context_options->{prefix};
         my $debug_sql = $context_options->{debug_sql};
         my ($timer, $elapsed_time);
-        if ($debug_sql) {
-            $timer = $self->_get_timer();
-            print $App::DEBUG_FILE "DEBUG_SQL: import_rows()\n";
-            print $App::DEBUG_FILE "$table (", join(",", @$columns), ")\n";
-        }
 
         my $datfile = $file;
 
@@ -466,9 +445,14 @@
         $filebase =~ s/\.dat$//;
 
         my $dbname = $self->{dbname};
-        my $column_hash = sha1_hex(join(",", @$columns));
+        my $control_key_source = join(",", @$columns);
+        if ($options && %$options) {
+            my @option_keys = sort keys %$options;
+            $control_key_source .= ":" . join(",", map { $_ => $options->{$_} 
} @option_keys);
+        }
+        my $control_key = sha1_hex($control_key_source);
 
-        my $ctlfile = 
"$prefix/data/app/Repository/$dbname/$table.$column_hash.ctl";
+        my $ctlfile = 
"$prefix/data/app/Repository/$dbname/$table.$control_key.ctl";
         if (! -f $ctlfile) {
             mkdir("$prefix/data") if (! -d "$prefix/data");
             mkdir("$prefix/data/app") if (! -d "$prefix/data/app");
@@ -496,15 +480,16 @@
         }
 
         my $cmd = "sqlldr userid=$self->{dbuser}/$self->[EMAIL PROTECTED] 
data=$datfile control=$ctlfile bad=$badfile log=$logfile errors=0 
$sqlldr_options > $outfile 2>&1";
-        #print STDERR "sqlldr userid=$self->{dbuser}/$self->[EMAIL PROTECTED] 
data=$datfile control=$ctlfile bad=$badfile log=$logfile errors=0 
$sqlldr_options > $outfile 2>&1\n";
-        my $rc = system($cmd);
-        my $exit_value  = $rc >> 8;
 
         if ($debug_sql) {
-            $elapsed_time = $self->_read_timer($timer);
-            print $App::DEBUG_FILE "DEBUG_SQL: import_rows=[$nrows] 
($elapsed_time sec) $DBI::errstr\n";
+            $timer = $self->_get_timer();
+            print $App::DEBUG_FILE "DEBUG_SQL: import_rows() : 
$table.$control_key_source\n";
+            print $App::DEBUG_FILE "system> $cmd\n";
         }
 
+        my $rc = system($cmd);
+        my $exit_value  = $rc >> 8;
+
         my $badfile_size = (-s $badfile || 0);
         if ($rc || $badfile_size) {
             # failed
@@ -523,6 +508,11 @@
             unlink($logfile);
             unlink($outfile);
         }
+
+        if ($debug_sql) {
+            $elapsed_time = $self->_read_timer($timer);
+            print $App::DEBUG_FILE "DEBUG_SQL: import_rows=[$nrows] 
($elapsed_time sec) $DBI::errstr\n";
+        }
     }
 
     &App::sub_exit($nrows) if ($App::trace);
@@ -615,7 +605,7 @@
 sub TBDexplain_sql {
     my ($self, $sql) = @_;
     my $dbh = $self->{dbh};
-    # NOTE: MySQL "explain" only works for "select".
+    # NOTE: Oracle "explain" only works for "select".
     # We convert "update" and "delete" to "select" to explain them.
     if (defined $dbh) {
         if ($sql =~ s/^delete/select */is) {
@@ -708,11 +698,5 @@
     return(undef, uc($dbschema), uc($table), "%");
 }
 
-#INSERT ALL
-#   INTO suppliers (supplier_id, supplier_name) VALUES (1000, 'IBM')
-#   INTO suppliers (supplier_id, supplier_name) VALUES (2000, 'Microsoft')
-#   INTO suppliers (supplier_id, supplier_name) VALUES (3000, 'Google')
-#SELECT * FROM dual;
-
 1;
 

Reply via email to