From: Ash Berlin Date: Thu, 20 Dec 2007 11:02:15 +0000 (+0000) Subject: Add proper thaw hooks so schema gets re-attached X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=4146e3dae3771b13b83eb1ba124ba74287f83dcd;p=dbsrgits%2FDBIx-Class-Historic.git Add proper thaw hooks so schema gets re-attached --- diff --git a/Changes b/Changes index 4c5c48e..f22d6bf 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,8 @@ Revision history for DBIx::Class + - Added freeze, thaw and dclone methods to Schema so that thawed + objects will get re-attached to the schema. + 0.08008 2007-11-16 14:30:00 - Fixed join merging bug (test from Zby) - When adding relationships, it will throw an exception if you get the diff --git a/lib/DBIx/Class/ResultSourceHandle.pm b/lib/DBIx/Class/ResultSourceHandle.pm index ae11ce6..c1a5070 100644 --- a/lib/DBIx/Class/ResultSourceHandle.pm +++ b/lib/DBIx/Class/ResultSourceHandle.pm @@ -14,6 +14,9 @@ use overload __PACKAGE__->mk_group_accessors('simple' => qw/schema source_moniker/); +# Schema to use when thawing. +our $thaw_schema; + =head1 NAME DBIx::Class::ResultSourceHandle @@ -71,20 +74,32 @@ Freezes a handle. sub STORABLE_freeze { my ($self, $cloning) = @_; + my $to_serialize = { %$self }; + delete $to_serialize->{schema}; return (Storable::freeze($to_serialize)); } =head2 STORABLE_thaw -Thaws frozen handle. +Thaws frozen handle. Resets the internal schema reference to the package +variable C<$thaw_schema>. The recomened way of setting this is to use +C<$schema->thaw($ice)> which handles this for you. =cut + sub STORABLE_thaw { my ($self, $cloning,$ice) = @_; %$self = %{ Storable::thaw($ice) }; + $self->{schema} = $thaw_schema; } +=head1 AUTHOR + +Ash Berlin C<< >> + +=cut + 1; diff --git a/lib/DBIx/Class/Schema.pm b/lib/DBIx/Class/Schema.pm index b668c83..09edb9b 100644 --- a/lib/DBIx/Class/Schema.pm +++ b/lib/DBIx/Class/Schema.pm @@ -1059,8 +1059,44 @@ L or L. For an example of what you can do with this, see L. +=head2 thaw + +Provided as the recommened way of thawing schema objects. You can call +C directly if you wish, but the thawed objects will not have a +reference to any schema, so are rather useless + +=cut + +sub thaw { + my ($self, $obj) = @_; + local $DBIx::Class::ResultSourceHandle::thaw_schema = $self; + return Storable::thaw($obj); +} + +=head2 freeze + +This doesn't actualy do anything more than call L, it is just +provided here for symetry. + =cut +sub freeze { + return Storable::freeze($_[1]); +} + +=head2 dclone + +Recommeneded way of dcloning objects. This is needed to properly maintain +references to the schema object (which itself is B cloned.) + +=cut + +sub dclone { + my ($self, $obj) = @_; + local $DBIx::Class::ResultSourceHandle::thaw_schema = $self; + return Storable::dclone($obj); +} + 1; =head1 AUTHORS diff --git a/t/84serialize.t b/t/84serialize.t index a8cedf0..c1b67dc 100644 --- a/t/84serialize.t +++ b/t/84serialize.t @@ -8,9 +8,25 @@ use Storable; my $schema = DBICTest->init_schema(); -plan tests => 1; +plan tests => 6; my $artist = $schema->resultset('Artist')->find(1); -my $copy = eval { Storable::dclone($artist) }; -is_deeply($copy, $artist, 'serialize row object works'); + +{ + my $copy = $schema->dclone($artist); + is_deeply($copy, $artist, "dclone row object works"); + eval { $copy->discard_changes }; + ok( !$@, "discard_changes okay" ); + is($copy->id, $artist->id, "IDs still match "); +} + +{ + my $ice = $schema->freeze($artist); + my $copy = $schema->thaw($ice); + is_deeply($copy, $artist, 'dclone row object works'); + + eval { $copy->discard_changes }; + ok( !$@, "discard_changes okay" ); + is($copy->id, $artist->id, "IDs still okay"); +}