additional refactoring to better handle source objects
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI.pm
index 41b30a0..04dd140 100644 (file)
@@ -10,6 +10,7 @@ use SQL::Abstract::Limit;
 use DBIx::Class::Storage::DBI::Cursor;
 use DBIx::Class::Storage::Statistics;
 use IO::File;
+use Scalar::Util 'blessed';
 
 __PACKAGE__->mk_group_accessors(
   'simple' =>
@@ -817,7 +818,9 @@ sub _prep_for_execute {
   my ($self, $op, $extra_bind, $ident, @args) = @_;
 
   my ($sql, @bind) = $self->sql_maker->$op($ident, @args);
-  unshift(@bind, @$extra_bind) if $extra_bind;
+  unshift(@bind,
+    map { ref $_ eq 'ARRAY' ? $_ : [ '!!dummy', $_ ] } @$extra_bind)
+      if $extra_bind;
   @bind = map { ref $_ ? ''.$_ : $_ } @bind; # stringify args
 
   return ($sql, @bind);
@@ -826,10 +829,18 @@ sub _prep_for_execute {
 sub _execute {
   my ($self, $op, $extra_bind, $ident, $bind_attributes, @args) = @_;
   
+  if( blessed($ident) && $ident->isa("DBIx::Class::ResultSource") )
+  {
+    $ident = $ident->from();
+  }
+  
   my ($sql, @bind) = $self->sql_maker->$op($ident, @args);
-  unshift(@bind, @$extra_bind) if $extra_bind;
+  unshift(@bind,
+    map { ref $_ eq 'ARRAY' ? $_ : [ '!!dummy', $_ ] } @$extra_bind)
+      if $extra_bind;
   if ($self->debug) {
-      my @debug_bind = map { defined ($_ && $_->[1]) ? qq{'$_->[1]'} : q{'NULL'} } @bind;
+      my @debug_bind =
+        map { defined ($_ && $_->[1]) ? qq{'$_->[1]'} : q{'NULL'} } @bind;
       $self->debugobj->query_start($sql, @debug_bind);
   }
   my $sth = eval { $self->sth($sql,$op) };
@@ -851,19 +862,22 @@ sub _execute {
       foreach my $bound (@bind) {
 
         my $attributes = {};
-        my($column_name, $data) = @$bound;
+        my($column_name, @data) = @$bound;
 
         if( $bind_attributes ) {
           $attributes = $bind_attributes->{$column_name}
           if defined $bind_attributes->{$column_name};
-        }                      
+        }
 
-        $data = ref $data ? ''.$data : $data; # stringify args
+               foreach my $data (@data)
+               {
+          $data = ref $data ? ''.$data : $data; # stringify args
 
-        $sth->bind_param($placeholder_index, $data, $attributes);
-        $placeholder_index++;
+          $sth->bind_param($placeholder_index, $data, $attributes);
+          $placeholder_index++;                  
+               }
       }
-      $sth->execute;
+      $sth->execute();
     };
   
     if ($@ || !$rv) {
@@ -884,19 +898,13 @@ sub insert {
   my ($self, $source, $to_insert) = @_;
   
   my $ident = $source->from; 
-  my $bind_attributes;
-  foreach my $column ($source->columns) {
-  
-    my $data_type = $source->column_info($column)->{data_type} || '';
-    $bind_attributes->{$column} = $self->bind_attribute_by_data_type($data_type)
-        if $data_type;
-  } 
-  
+  my $bind_attributes = $self->source_bind_attributes($source);
+
   $self->throw_exception(
     "Couldn't insert ".join(', ',
       map "$_ => $to_insert->{$_}", keys %$to_insert
     )." into ${ident}"
-  ) unless ($self->_execute('insert' => [], $ident, $bind_attributes, $to_insert));
+  ) unless ($self->_execute('insert' => [], $source, $bind_attributes, $to_insert));
   return $to_insert;
 }
 
@@ -948,18 +956,9 @@ sub insert_bulk {
     #};
        
        ## Get the bind_attributes, if any exist
-       
-    my $bind_attributes;
-    foreach my $column ($source->columns) {
-  
-      my $data_type = $source->column_info($column)->{data_type} || '';
-         
-      $bind_attributes->{$column} = $self->bind_attribute_by_data_type($data_type)
-          if $data_type;
-    } 
-       
+    my $bind_attributes = $self->source_bind_attributes($source);
+
        ## Bind the values and execute
-       
        $rv = eval {
        
      my $placeholder_index = 1; 
@@ -983,9 +982,6 @@ sub insert_bulk {
 
        };
    
-#print STDERR Dumper($tuple_status);
-#print STDERR "RV: $rv\n";
-
     if ($@ || !defined $rv) {
       my $errors = '';
       foreach my $tuple (@$tuple_status)
@@ -1007,17 +1003,9 @@ sub insert_bulk {
 sub update {
   my $self = shift @_;
   my $source = shift @_;
+  my $bind_attributes = $self->source_bind_attributes($source);
   
-  my $bind_attributes;
-  foreach my $column ($source->columns) {
-  
-    my $data_type = $source->column_info($column)->{data_type} || '';
-    $bind_attributes->{$column} = $self->bind_attribute_by_data_type($data_type)
-        if $data_type;
-  }
-
-  my $ident = $source->from;
-  return $self->_execute('update' => [], $ident, $bind_attributes, @_);
+  return $self->_execute('update' => [], $source, $bind_attributes, @_);
 }
 
 
@@ -1026,9 +1014,8 @@ sub delete {
   my $source = shift @_;
   
   my $bind_attrs = {}; ## If ever it's needed...
-  my $ident = $source->from;
   
-  return $self->_execute('delete' => [], $ident, $bind_attrs, @_);
+  return $self->_execute('delete' => [], $source, $bind_attrs, @_);
 }
 
 sub _select {
@@ -1057,6 +1044,20 @@ sub _select {
   return $self->_execute(@args);
 }
 
+sub source_bind_attributes {
+  my ($self, $source) = @_;
+  
+  my $bind_attributes;
+  foreach my $column ($source->columns) {
+  
+    my $data_type = $source->column_info($column)->{data_type} || '';
+    $bind_attributes->{$column} = $self->bind_attribute_by_data_type($data_type)
+        if $data_type;
+  }
+
+  return $bind_attributes;
+}
+
 =head2 select
 
 =over 4