[Bast-commits] r8887 - in DBIx-Class/0.08/trunk: . lib/DBIx/Class t t/row

ribasushi at dev.catalyst.perl.org ribasushi at dev.catalyst.perl.org
Thu Mar 4 18:10:49 GMT 2010


Author: ribasushi
Date: 2010-03-04 18:10:49 +0000 (Thu, 04 Mar 2010)
New Revision: 8887

Added:
   DBIx-Class/0.08/trunk/t/row/
   DBIx-Class/0.08/trunk/t/row/pkless.t
Modified:
   DBIx-Class/0.08/trunk/Changes
   DBIx-Class/0.08/trunk/lib/DBIx/Class/Row.pm
Log:
Fix identity fiasco

Modified: DBIx-Class/0.08/trunk/Changes
===================================================================
--- DBIx-Class/0.08/trunk/Changes	2010-03-04 14:43:17 UTC (rev 8886)
+++ DBIx-Class/0.08/trunk/Changes	2010-03-04 18:10:49 UTC (rev 8887)
@@ -3,6 +3,7 @@
         - Fix regression on not properly throwing when $obj->relationship
           is unresolvable
         - Add has_relationship method to row objects
+        - Fix regression in set_column on PK-less objects
         - Fix for SQLite to ignore the { for => ... } attribute
 
 0.08120 2010-02-24 08:58:00 (UTC)

Modified: DBIx-Class/0.08/trunk/lib/DBIx/Class/Row.pm
===================================================================
--- DBIx-Class/0.08/trunk/lib/DBIx/Class/Row.pm	2010-03-04 14:43:17 UTC (rev 8886)
+++ DBIx-Class/0.08/trunk/lib/DBIx/Class/Row.pm	2010-03-04 18:10:49 UTC (rev 8887)
@@ -477,17 +477,18 @@
 sub update {
   my ($self, $upd) = @_;
   $self->throw_exception( "Not in database" ) unless $self->in_storage;
-  my $ident_cond = $self->ident_condition;
-  $self->throw_exception("Cannot safely update a row in a PK-less table")
+
+  my $ident_cond = $self->{_orig_ident} || $self->ident_condition;
+
+  $self->throw_exception('Unable to update a row with incomplete or no identity')
     if ! keys %$ident_cond;
 
   $self->set_inflated_columns($upd) if $upd;
   my %to_update = $self->get_dirty_columns;
   return $self unless keys %to_update;
   my $rows = $self->result_source->storage->update(
-               $self->result_source, \%to_update,
-               $self->{_orig_ident} || $ident_cond
-             );
+    $self->result_source, \%to_update, $ident_cond
+  );
   if ($rows == 0) {
     $self->throw_exception( "Can't update ${self}: row not found" );
   } elsif ($rows > 1) {
@@ -495,7 +496,7 @@
   }
   $self->{_dirty_columns} = {};
   $self->{related_resultsets} = {};
-  undef $self->{_orig_ident};
+  delete $self->{_orig_ident};
   return $self;
 }
 
@@ -544,17 +545,19 @@
   my $self = shift;
   if (ref $self) {
     $self->throw_exception( "Not in database" ) unless $self->in_storage;
+
     my $ident_cond = $self->{_orig_ident} || $self->ident_condition;
-    $self->throw_exception("Cannot safely delete a row in a PK-less table")
+    $self->throw_exception('Unable to delete a row with incomplete or no identity')
       if ! keys %$ident_cond;
-    foreach my $column (keys %$ident_cond) {
-            $self->throw_exception("Can't delete the object unless it has loaded the primary keys")
-              unless exists $self->{_column_data}{$column};
-    }
+
     $self->result_source->storage->delete(
-      $self->result_source, $ident_cond);
+      $self->result_source, $ident_cond
+    );
+
+    delete $self->{_orig_ident};
     $self->in_storage(undef);
-  } else {
+  }
+  else {
     $self->throw_exception("Can't do class delete without a ResultSource instance")
       unless $self->can('result_source_instance');
     my $attrs = @_ > 1 && ref $_[$#_] eq 'HASH' ? { %{pop(@_)} } : {};
@@ -812,9 +815,10 @@
 sub set_column {
   my ($self, $column, $new_value) = @_;
 
-  $self->{_orig_ident} ||= $self->ident_condition;
+  # if we can't get an ident condition on first try - mark the object as unidentifiable
+  $self->{_orig_ident} ||= (eval { $self->ident_condition }) || {};
+
   my $old_value = $self->get_column($column);
-
   $new_value = $self->store_column($column, $new_value);
 
   my $dirty;
@@ -1297,7 +1301,12 @@
       $resultset = $resultset->search(undef, $attrs);
     }
 
-    return $resultset->find($self->{_orig_ident} || $self->ident_condition);
+    my $ident_cond = $self->{_orig_ident} || $self->ident_condition;
+
+    $self->throw_exception('Unable to requery a row with incomplete or no identity')
+      if ! keys %$ident_cond;
+
+    return $resultset->find($ident_cond);
 }
 
 =head2 discard_changes ($attrs)

Added: DBIx-Class/0.08/trunk/t/row/pkless.t
===================================================================
--- DBIx-Class/0.08/trunk/t/row/pkless.t	                        (rev 0)
+++ DBIx-Class/0.08/trunk/t/row/pkless.t	2010-03-04 18:10:49 UTC (rev 8887)
@@ -0,0 +1,32 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Test::Exception;
+
+use lib qw(t/lib);
+use DBICTest;
+
+my $schema = DBICTest->init_schema();
+
+my $rs = $schema->resultset('NoPrimaryKey');
+
+my $row = $rs->create ({ foo => 1, bar => 1, baz => 1 });
+
+lives_ok (sub {
+  $row->foo (2);
+}, 'Set on pkless object works');
+
+is ($row->foo, 2, 'Column updated in-object');
+
+dies_ok (sub {
+  $row->update ({baz => 3});
+}, 'update() fails on pk-less object');
+
+is ($row->foo, 2, 'Column not updated by failed update()');
+
+dies_ok (sub {
+  $row->delete;
+}, 'delete() fails on pk-less object');
+
+done_testing;




More information about the Bast-commits mailing list