[Bast-commits] r4425 - in DBIx-Class/0.08/branches/replication_dedux: lib/DBIx/Class lib/DBIx/Class/Storage lib/DBIx/Class/Storage/DBI t

jnapiorkowski at dev.catalyst.perl.org jnapiorkowski at dev.catalyst.perl.org
Thu May 29 19:30:40 BST 2008


Author: jnapiorkowski
Date: 2008-05-29 19:30:39 +0100 (Thu, 29 May 2008)
New Revision: 4425

Modified:
   DBIx-Class/0.08/branches/replication_dedux/lib/DBIx/Class/PK.pm
   DBIx-Class/0.08/branches/replication_dedux/lib/DBIx/Class/Storage.pm
   DBIx-Class/0.08/branches/replication_dedux/lib/DBIx/Class/Storage/DBI.pm
   DBIx-Class/0.08/branches/replication_dedux/lib/DBIx/Class/Storage/DBI/Replicated.pm
   DBIx-Class/0.08/branches/replication_dedux/t/93storage_replication.t
Log:
discard changes now is forced to use master for replication.  changed discard_changes guts to point to new method called reload_row in storage.  fixed problem with replicated transactionws not returning the right thing.  added tests to all the above

Modified: DBIx-Class/0.08/branches/replication_dedux/lib/DBIx/Class/PK.pm
===================================================================
--- DBIx-Class/0.08/branches/replication_dedux/lib/DBIx/Class/PK.pm	2008-05-28 19:15:34 UTC (rev 4424)
+++ DBIx-Class/0.08/branches/replication_dedux/lib/DBIx/Class/PK.pm	2008-05-29 18:30:39 UTC (rev 4425)
@@ -37,23 +37,8 @@
 
 sub discard_changes {
   my ($self) = @_;
-  delete $self->{_dirty_columns};
-  return unless $self->in_storage; # Don't reload if we aren't real!
-
-  my $reload = $self->result_source->resultset->find(
-    map { $self->$_ } $self->primary_columns
-  );
-  unless ($reload) { # If we got deleted in the mean-time
-    $self->in_storage(0);
-    return $self;
-  }
-
-  %$self = %$reload;
-  
-  # Avoid a possible infinite loop with
-  # sub DESTROY { $_[0]->discard_changes }
-  bless $reload, 'Do::Not::Exist';
-
+  my $storage = $self->result_source->schema->storage;
+  $storage->reload_row($self);
   return $self;
 }
 

Modified: DBIx-Class/0.08/branches/replication_dedux/lib/DBIx/Class/Storage/DBI/Replicated.pm
===================================================================
--- DBIx-Class/0.08/branches/replication_dedux/lib/DBIx/Class/Storage/DBI/Replicated.pm	2008-05-28 19:15:34 UTC (rev 4424)
+++ DBIx-Class/0.08/branches/replication_dedux/lib/DBIx/Class/Storage/DBI/Replicated.pm	2008-05-29 18:30:39 UTC (rev 4425)
@@ -229,6 +229,7 @@
         sth
         deploy
         schema
+        reload_row
     /],
 );
 
@@ -385,9 +386,10 @@
         my $name = shift @_;
         $schema->resultset('User')->create({name=>$name});
         my $user_rs = $schema->resultset('User')->find({name=>$name}); 
+        return $user_rs;
     };
 
-    $schema->storage->execute_reliably($reliably, 'John');
+    my $user_rs = $schema->storage->execute_reliably($reliably, 'John');
 
 Use this when you must be certain of your database state, such as when you just
 inserted something and need to get a resultset including it, etc.
@@ -411,16 +413,31 @@
     $self->read_handler($master);
     
     ## do whatever the caller needs
+    my @result;
+    my $want_array = wantarray;
+    
     eval {
-        $coderef->(@args);
+	    if($want_array) {
+	        @result = $coderef->(@args);
+	    }
+	    elsif(defined $want_array) {
+	        ($result[0]) = ($coderef->(@args));
+	    } else {
+	        $coderef->(@args);
+	    }    	
     };
     
+    ##Reset to the original state
+    $self->schema->storage->read_handler($current); 
+    
+    ##Exception testing has to come last, otherwise you might leave the 
+    ##read_handler set to master.
+    
     if($@) {
         $self->throw_exception("coderef returned an error: $@");
+    } else {
+    	return $want_array ? @result : $result[0];
     }
-  
-    ##Reset to the original state
-    $self->schema->storage->read_handler($current);	
 }
 
 =head2 set_reliable_storage
@@ -466,6 +483,20 @@
 	$self->execute_reliably($coderef, @args);
 }
 
+=head2 reload_row ($row)
+
+Overload to the reload_row method so that the reloading is always directed to
+the master storage.
+
+=cut
+
+around 'reload_row' => sub {
+	my ($reload_row, $self, $row) = @_;
+	$self->execute_reliably(sub {
+		$self->$reload_row(shift);
+	}, $row);
+};
+
 =head2 connected
 
 Check that the master and at least one of the replicants is connected.

Modified: DBIx-Class/0.08/branches/replication_dedux/lib/DBIx/Class/Storage/DBI.pm
===================================================================
--- DBIx-Class/0.08/branches/replication_dedux/lib/DBIx/Class/Storage/DBI.pm	2008-05-28 19:15:34 UTC (rev 4424)
+++ DBIx-Class/0.08/branches/replication_dedux/lib/DBIx/Class/Storage/DBI.pm	2008-05-29 18:30:39 UTC (rev 4425)
@@ -1296,6 +1296,28 @@
   return @row;
 }
 
+sub reload_row { 
+  my ($self, $row) = @_;
+  delete $row->{_dirty_columns};
+  return unless $row->in_storage; # Don't reload if we aren't real!
+
+  my $reload = $row->result_source->resultset->find(
+    map { $row->$_ } $row->primary_columns
+  );
+  unless ($reload) { # If we got deleted in the mean-time
+    $row->in_storage(0);
+    return $row;
+  }
+
+  $row = %$reload;
+  
+  # Avoid a possible infinite loop with
+  # sub DESTROY { $_[0]->discard_changes }
+  bless $reload, 'Do::Not::Exist';
+
+  return $row;
+}
+
 =head2 sth
 
 =over 4

Modified: DBIx-Class/0.08/branches/replication_dedux/lib/DBIx/Class/Storage.pm
===================================================================
--- DBIx-Class/0.08/branches/replication_dedux/lib/DBIx/Class/Storage.pm	2008-05-28 19:15:34 UTC (rev 4424)
+++ DBIx-Class/0.08/branches/replication_dedux/lib/DBIx/Class/Storage.pm	2008-05-29 18:30:39 UTC (rev 4425)
@@ -438,6 +438,15 @@
 
 sub select_single { die "Virtual method!" }
 
+=head2 reload_row ($row)
+
+given a L<DBIx::Class::Row> object, 'reloads' it from the storage.  This will
+destroy any existing changes you have not yet saved.
+
+=cut
+
+sub reload_row { die "Virtual method!" }
+
 =head2 columns_info_for
 
 Returns metadata for the given source's columns.  This

Modified: DBIx-Class/0.08/branches/replication_dedux/t/93storage_replication.t
===================================================================
--- DBIx-Class/0.08/branches/replication_dedux/t/93storage_replication.t	2008-05-28 19:15:34 UTC (rev 4424)
+++ DBIx-Class/0.08/branches/replication_dedux/t/93storage_replication.t	2008-05-29 18:30:39 UTC (rev 4425)
@@ -9,7 +9,7 @@
     eval "use Moose; use Test::Moose";
     plan $@
         ? ( skip_all => 'needs Moose for testing' )
-        : ( tests => 57 );
+        : ( tests => 71 );
 }
 
 use_ok 'DBIx::Class::Storage::DBI::Replicated::Pool';
@@ -455,30 +455,81 @@
 } => 'created coderef properly';
 
 throws_ok {$replicated->schema->storage->execute_reliably($unreliably)} 
-    qr/coderef returned an error: Can't find source for ArtistXX/
+    qr/Can't find source for ArtistXX/
     => 'Bad coderef throws proper error';
     
+## Make sure replication came back
+
+ok $replicated->schema->resultset('Artist')->find(3)
+    => 'replicant reactivated';
+    
 ## make sure transactions are set to execute_reliably
 
 ok my $transaction = sub {
 	
+	my $id = shift @_;
+	
 	$replicated
 	    ->schema
 	    ->populate('Artist', [
 	        [ qw/artistid name/ ],
-	        [ 666, "Children of the Grave"],
+	        [ $id, "Children of the Grave"],
 	    ]);
 	    
-   ok my $result = $replicated->schema->resultset('Artist')->find(666);
+   ok my $result = $replicated->schema->resultset('Artist')->find($id);
+   ok my $more = $replicated->schema->resultset('Artist')->find(1);
    
+   return ($result, $more);
+   
 };
 
-$replicated->schema->txn_do($transaction);
+## Test the transaction with multi return
+{
+	ok my @return = $replicated->schema->txn_do($transaction, 666)
+	    => 'did transaction';
+	    
+	    is $return[0]->id, 666
+	        => 'first returned value is correct';
+	        
+	    is $return[1]->id, 1
+	        => 'second returned value is correct';
+}
 
+## Test that asking for single return works
+{
+	ok my $return = $replicated->schema->txn_do($transaction, 777)
+	    => 'did transaction';
+	    
+	    is $return->id, 777
+	        => 'first returned value is correct';
+}
+
+## Test transaction returning a single value
+
+{
+	ok my $result = $replicated->schema->txn_do(sub {
+		ok my $more = $replicated->schema->resultset('Artist')->find(1);
+		return $more;
+	}) => 'successfully processed transaction';
+	
+	is $result->id, 1
+	   => 'Got expected single result from transaction';
+}
+
 ## Make sure replication came back
 
-ok $replicated->schema->resultset('Artist')->find(5)
+ok $replicated->schema->resultset('Artist')->find(1)
     => 'replicant reactivated';
+    
+## Test Discard changes
+
+{
+	ok my $artist = $replicated->schema->resultset('Artist')->find(2)
+	    => 'got an artist to test discard changes';
+	    
+	ok $artist->discard_changes
+	   => 'properly discard changes';
+}
         
 ## Delete the old database files
 $replicated->cleanup;




More information about the Bast-commits mailing list