create insert_bulk using execute_array, and make populate use it in void context
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI.pm
index a4abf35..3ede145 100644 (file)
@@ -58,9 +58,11 @@ WHERE ROW_NUM BETWEEN $offset AND $last
 
 # While we're at it, this should make LIMIT queries more efficient,
 #  without digging into things too deeply
+use Scalar::Util 'blessed';
 sub _find_syntax {
   my ($self, $syntax) = @_;
-  my $dbhname = ref $syntax eq 'HASH' ? $syntax->{Driver}{Name} : '';
+  my $dbhname = blessed($syntax) ?  $syntax->{Driver}{Name} : $syntax;
+#  print STDERR "Found DBH $syntax >$dbhname< ", $syntax->{Driver}->{Name}, "\n";
   if(ref($self) && $dbhname && $dbhname eq 'DB2') {
     return 'RowNumberOver';
   }
@@ -305,6 +307,7 @@ sub new {
   $new->transaction_depth(0);
   $new->_sql_maker_opts({});
   $new->{_in_dbh_do} = 0;
+  $new->{_dbh_gen} = 0;
 
   $new;
 }
@@ -590,6 +593,7 @@ sub disconnect {
     $self->_dbh->rollback unless $self->_dbh->{AutoCommit};
     $self->_dbh->disconnect;
     $self->_dbh(undef);
+    $self->{_dbh_gen}++;
   }
 }
 
@@ -598,7 +602,9 @@ sub connected {
 
   if(my $dbh = $self->_dbh) {
       if(defined $self->_conn_tid && $self->_conn_tid != threads->tid) {
-          return $self->_dbh(undef);
+          $self->_dbh(undef);
+          $self->{_dbh_gen}++;
+          return;
       }
       else {
           $self->_verify_pid;
@@ -618,6 +624,7 @@ sub _verify_pid {
 
   $self->_dbh->{InactiveDestroy} = 1;
   $self->_dbh(undef);
+  $self->{_dbh_gen}++;
 
   return;
 }
@@ -824,7 +831,7 @@ sub _execute {
     $self->throw_exception("'$sql' did not generate a statement.");
   }
   if ($self->debug) {
-      my @debug_bind = map { defined $_ ? qq{`$_'} : q{`NULL'} } @bind;
+      my @debug_bind = map { defined $_ ? qq{`$_'} : q{`NULL'} } @bind; 
       $self->debugobj->query_end($sql, @debug_bind);
   }
   return (wantarray ? ($rv, $sth, @bind) : $rv);
@@ -840,6 +847,41 @@ sub insert {
   return $to_insert;
 }
 
+sub insert_bulk {
+  my ($self, $table, $cols, $data) = @_;
+  my ($sql, @bind) = $self->sql_maker->insert($table, @$data);
+
+  if ($self->debug) {
+      my @debug_bind = map { defined $_ ? qq{'$_'} : q{'NULL'} } @bind;
+      $self->debugobj->query_start($sql, @debug_bind);
+  }
+  my $sth = eval { $self->sth($sql,'insert') };
+
+  if (!$sth || $@) {
+    $self->throw_exception(
+      'no sth generated via sql (' . ($@ || $self->_dbh->errstr) . "): $sql"
+    );
+  }
+#  @bind = map { ref $_ ? ''.$_ : $_ } @bind; # stringify args
+
+  my $rv;
+  if ($sth) {
+    my $time = time();
+    $rv = eval { $sth->execute_array({ ArrayTupleFetch => sub { return shift @$data; }}) };
+
+    if ($@ || !$rv) {
+      $self->throw_exception("Error executing '$sql': ".($@ || $sth->errstr));
+    }
+  } else {
+    $self->throw_exception("'$sql' did not generate a statement.");
+  }
+  if ($self->debug) {
+      my @debug_bind = map { defined $_ ? qq{`$_'} : q{`NULL'} } @bind;
+      $self->debugobj->query_end($sql, @debug_bind);
+  }
+  return (wantarray ? ($rv, $sth, @bind) : $rv);
+}
+
 sub update {
   return shift->_execute('update' => [], @_);
 }