Make freeze/thaw and dclone work as functions on CDBICompat objects.
Michael G Schwern [Thu, 17 Jan 2008 19:31:44 +0000 (11:31 -0800)]
lib/DBIx/Class/ResultSourceHandle.pm
t/84serialize.t

index c1a5070..9354318 100644 (file)
@@ -3,6 +3,7 @@ package DBIx::Class::ResultSourceHandle;
 use strict;
 use warnings;
 use Storable;
+use Carp;
 
 use base qw/DBIx::Class/;
 
@@ -77,7 +78,8 @@ sub STORABLE_freeze {
 
     my $to_serialize = { %$self };
     
-    delete $to_serialize->{schema};
+    my $class = $self->schema->class($self->source_moniker);
+    $to_serialize->{schema} = $class;
     return (Storable::freeze($to_serialize));
 }
 
@@ -93,7 +95,17 @@ C<$schema->thaw($ice)> which handles this for you.
 sub STORABLE_thaw {
     my ($self, $cloning,$ice) = @_;
     %$self = %{ Storable::thaw($ice) };
-    $self->{schema} = $thaw_schema;
+
+    my $class = delete $self->{schema};
+    if( $thaw_schema ) {
+        $self->{schema} = $thaw_schema;
+    }
+    else {
+        my $rs = $class->result_source_instance;
+        $self->{schema} = $rs->schema if $rs;
+    }
+
+    carp "Unable to restore schema" unless $self->{schema};
 }
 
 =head1 AUTHOR
index 0819d8c..76e18c2 100644 (file)
@@ -9,11 +9,15 @@ use Storable qw(dclone freeze thaw);
 my $schema = DBICTest->init_schema();
 
 my %stores = (
-    dclone_method          => sub { return $schema->dclone($_[0]) },
-    "freeze/thaw_method"   => sub {
+    dclone_method           => sub { return $schema->dclone($_[0]) },
+    dclone_func             => sub { return dclone($_[0]) },
+    "freeze/thaw_method"    => sub {
         my $ice = $schema->freeze($_[0]);
         return $schema->thaw($ice);
     },
+    "freeze/thaw_func"      => sub {
+        thaw(freeze($_[0]));
+    },
 );
 
 plan tests => (7 * keys %stores);
@@ -22,11 +26,25 @@ for my $name (keys %stores) {
     my $store = $stores{$name};
 
     my $artist = $schema->resultset('Artist')->find(1);
+    
+    # Test that the procedural versions will work if there's a registered
+    # schema as with CDBICompat objects and that the methods work
+    # without.
+    if( $name =~ /func/ ) {
+        $artist->result_source_instance->schema($schema);
+        DBICTest::CD->result_source_instance->schema($schema);
+    }
+    else {
+        $artist->result_source_instance->schema(undef);
+        DBICTest::CD->result_source_instance->schema(undef);
+    }
+
     my $copy = eval { $store->($artist) };
     is_deeply($copy, $artist, "serialize row object works: $name");
 
     # Test that an object with a related_resultset can be serialized.
     my @cds = $artist->related_resultset("cds");
+
     ok $artist->{related_resultsets}, 'has key: related_resultsets';
 
     $copy = eval { $store->($artist) };