Fixed bug in _strip_cond_qualifiers, patch generously by Grant Street Group.
Rob Kinyon [Sat, 12 Mar 2011 03:34:28 +0000 (22:34 -0500)]
.gitignore
Changes
lib/DBIx/Class.pm
lib/DBIx/Class/Storage/DBI/Replicated.pm
lib/DBIx/Class/Storage/DBIHacks.pm
t/delete/complex.t

index 30d2e53..48fbe68 100644 (file)
@@ -13,3 +13,4 @@ inc/
 lib/DBIx/Class/Optional/Dependencies.pod
 pm_to_blib
 t/var/
+.*.sw?
diff --git a/Changes b/Changes
index c54d6a4..db1bbae 100644 (file)
--- a/Changes
+++ b/Changes
@@ -27,6 +27,8 @@ Revision history for DBIx::Class
           (RT#64795)
         - Work around a Firebird ODBC driver bug exposed by DBD::ODBC 1.29
         - Fix exiting via next warnings in ResultSource::sequence()
+        - Fix stripping of table qualifiers in update/delete in arrayref
+          condition elements
 
     * Misc
         - Only load Class::C3 and friends if necessary ($] < 5.010)
index 86bc9b0..c150c3d 100644 (file)
@@ -308,6 +308,8 @@ goraxe: Gordon Irving <goraxe@cpan.org>
 
 gphat: Cory G Watson <gphat@cpan.org>
 
+Grant Street Group L<http://www.grantstreet.com/>
+
 groditi: Guillermo Roditi <groditi@cpan.org>
 
 Haarg: Graham Knop <haarg@haarg.org>
index c004c39..87f5416 100644 (file)
@@ -355,6 +355,7 @@ has 'write_handler' => (
     _resolve_column_info
     _prune_unused_joins
     _strip_cond_qualifiers
+    _strip_cond_qualifiers_from_array
     _resolve_aliastypes_from_select_args
     _execute
     _do_query
index 01b6383..defcecd 100644 (file)
@@ -579,6 +579,26 @@ sub _inner_join_to_node {
 # at all. What this code tries to do (badly) is introspect the condition
 # and remove all column qualifiers. If it bails out early (returns undef)
 # the calling code should try another approach (e.g. a subquery)
+
+sub _strip_cond_qualifiers_from_array {
+  my ($self, $where) = @_;
+  my @cond;
+  for (my $i = 0; $i < @$where; $i++) {
+    my $entry = $where->[$i];
+    my $hash;
+    my $ref = ref $entry;
+    if ($ref eq 'HASH' or $ref eq 'ARRAY') {
+      $hash = $self->_strip_cond_qualifiers($entry);
+    }
+    elsif (! $ref) {
+      $entry =~ /([^.]+)$/;
+      $hash->{$1} = $where->[++$i];
+    }
+    push @cond, $hash;
+  }
+  return \@cond;
+}
+
 sub _strip_cond_qualifiers {
   my ($self, $where) = @_;
 
@@ -588,37 +608,12 @@ sub _strip_cond_qualifiers {
   return $cond unless $where;
 
   if (ref $where eq 'ARRAY') {
-    $cond = [
-      map {
-        my %hash;
-        foreach my $key (keys %{$_}) {
-          $key =~ /([^.]+)$/;
-          $hash{$1} = $_->{$key};
-        }
-        \%hash;
-      } @$where
-    ];
+    $cond = $self->_strip_cond_qualifiers_from_array($where);
   }
   elsif (ref $where eq 'HASH') {
     if ( (keys %$where) == 1 && ( (keys %{$where})[0] eq '-and' )) {
-      $cond->{-and} = [];
-      my @cond = @{$where->{-and}};
-       for (my $i = 0; $i < @cond; $i++) {
-        my $entry = $cond[$i];
-        my $hash;
-        my $ref = ref $entry;
-        if ($ref eq 'HASH' or $ref eq 'ARRAY') {
-          $hash = $self->_strip_cond_qualifiers($entry);
-        }
-        elsif (! $ref) {
-          $entry =~ /([^.]+)$/;
-          $hash->{$1} = $cond[++$i];
-        }
-        else {
-          $self->throw_exception ("_strip_cond_qualifiers() is unable to handle a condition reftype $ref");
-        }
-        push @{$cond->{-and}}, $hash;
-      }
+      $cond->{-and} =
+        $self->_strip_cond_qualifiers_from_array($where->{-and});
     }
     else {
       foreach my $key (keys %$where) {
index 5057391..149bcf1 100644 (file)
@@ -11,25 +11,30 @@ my $artist_rs = $schema->resultset ('Artist');
 my $init_count = $artist_rs->count;
 ok ($init_count, 'Some artists is database');
 
-$artist_rs->populate ([
-  {
-    name => 'foo',
-  },
-  {
-    name => 'bar',
-  }
-]);
-
-is ($artist_rs->count, $init_count + 2, '2 Artists created');
-
-$artist_rs->search ({
- -and => [
-  { 'me.artistid' => { '!=', undef } },
+foreach my $delete_arg (
   [ { 'me.name' => 'foo' }, { 'me.name' => 'bar' } ],
- ],
-})->delete;
-
-is ($artist_rs->count, $init_count, 'Correct amount of artists deleted');
+  [ 'me.name' => 'foo', 'me.name' => 'bar' ],
+) {
+  $artist_rs->populate ([
+    {
+      name => 'foo',
+    },
+    {
+      name => 'bar',
+    }
+  ]);
+
+  is ($artist_rs->count, $init_count + 2, '2 Artists created');
+
+  $artist_rs->search ({
+   -and => [
+    { 'me.artistid' => { '!=', undef } },
+    $delete_arg,
+   ],
+  })->delete;
+
+  is ($artist_rs->count, $init_count, 'Correct amount of artists deleted');
+}
 
 done_testing;