From: Ash Berlin Date: Tue, 21 Nov 2006 09:46:41 +0000 (+0000) Subject: Changed row and rs objects to not have direct handle to a source, instead a X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=aec3eff1a3bba3ee46eaadabf496e9a369b8638a;p=dbsrgits%2FDBIx-Class-Historic.git Changed row and rs objects to not have direct handle to a source, instead a (schema,source_name) tuple of type ResultSourceHandle. --- diff --git a/lib/DBIx/Class/Core.pm b/lib/DBIx/Class/Core.pm index 504480e..92dd74c 100644 --- a/lib/DBIx/Class/Core.pm +++ b/lib/DBIx/Class/Core.pm @@ -7,14 +7,12 @@ no warnings 'qw'; use base qw/DBIx::Class/; __PACKAGE__->load_components(qw/ - Serialize::Storable Relationship InflateColumn PK::Auto PK Row - ResultSourceProxy::Table - /); + ResultSourceProxy::Table/); 1; diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index b6fbb05..824f973 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -10,9 +10,10 @@ use Carp::Clan qw/^DBIx::Class/; use Data::Page; use Storable; use DBIx::Class::ResultSetColumn; +use DBIx::Class::ResultSourceHandle; use base qw/DBIx::Class/; -__PACKAGE__->mk_group_accessors('simple' => qw/result_source result_class/); +__PACKAGE__->mk_group_accessors('simple' => qw/result_class _source_handle/); =head1 NAME @@ -84,7 +85,8 @@ sub new { return $class->new_result(@_) if ref $class; my ($source, $attrs) = @_; - #weaken $source; + $source = $source->handle + unless $source->isa('DBIx::Class::ResultSourceHandle'); if ($attrs->{page}) { $attrs->{rows} ||= 10; @@ -95,8 +97,8 @@ sub new { $attrs->{alias} ||= 'me'; my $self = { - result_source => $source, - result_class => $attrs->{result_class} || $source->result_class, + _source_handle => $source, + result_class => $attrs->{result_class} || $source->resolve->result_class, cond => $attrs->{where}, count => undef, pager => undef, @@ -237,7 +239,7 @@ sub search_rs { : $having); } - my $rs = (ref $self)->new($self->result_source, $new_attrs); + my $rs = (ref $self)->new($self->_source_handle, $new_attrs); if ($rows) { $rs->set_cache($rows); } @@ -739,7 +741,7 @@ sub next { sub _construct_object { my ($self, @row) = @_; my $info = $self->_collapse_result($self->{_attrs}{as}, \@row); - my @new = $self->result_class->inflate_result($self->result_source, @$info); + my @new = $self->result_class->inflate_result($self->_source_handle, @$info); @new = $self->{_attrs}{record_filter}->(@new) if exists $self->{_attrs}{record_filter}; return @new; @@ -915,7 +917,7 @@ sub _count { # Separated out so pager can get the full count # offset, order by and page are not needed to count. record_filter is cdbi delete $attrs->{$_} for qw/rows offset order_by page pager record_filter/; - my $tmp_rs = (ref $self)->new($self->result_source, $attrs); + my $tmp_rs = (ref $self)->new($self->_source_handle, $attrs); my ($count) = $tmp_rs->cursor->next; return $count; } @@ -1226,7 +1228,7 @@ attribute set on the resultset (10 by default). sub page { my ($self, $page) = @_; - return (ref $self)->new($self->result_source, { %{$self->{attrs}}, page => $page }); + return (ref $self)->new($self->_source_handle, { %{$self->{attrs}}, page => $page }); } =head2 new_result @@ -1256,7 +1258,7 @@ sub new_result { my %new = ( %{ $self->_remove_alias($values, $alias) }, %{ $self->_remove_alias($collapsed_cond, $alias) }, - -result_source => $self->result_source, + -source_handle => $self->_source_handle, ); my $obj = $self->result_class->new(\%new); @@ -1554,7 +1556,7 @@ sub related_resultset { my $rel_obj = $self->result_source->relationship_info($rel); $self->throw_exception( - "search_related: result source '" . $self->result_source->name . + "search_related: result source '" . $self->_source_handle->source_monkier . "' has no such relationship $rel") unless $rel_obj; @@ -1563,7 +1565,7 @@ sub related_resultset { my $join_count = $seen->{$rel}; my $alias = ($join_count > 1 ? join('_', $rel, $join_count) : $rel); - $self->result_source->schema->resultset($rel_obj->{class})->search_rs( + $self->_source_handle->schema->resultset($rel_obj->{class})->search_rs( undef, { %{$self->{attrs}||{}}, join => undef, @@ -1604,7 +1606,7 @@ sub _resolved_attrs { return $self->{_attrs} if $self->{_attrs}; my $attrs = { %{$self->{attrs}||{}} }; - my $source = $self->{result_source}; + my $source = $self->result_source; my $alias = $attrs->{alias}; $attrs->{columns} ||= delete $attrs->{cols} if exists $attrs->{cols}; @@ -1736,6 +1738,16 @@ sub _merge_attr { } } +sub result_source { + my $self = shift; + + if (@_) { + $self->_source_handle($_[0]->handle); + } else { + $self->_source_handle->resolve; + } +} + =head2 throw_exception See L for details. @@ -1744,7 +1756,7 @@ See L for details. sub throw_exception { my $self=shift; - $self->result_source->schema->throw_exception(@_); + $self->_source_handle->schema->throw_exception(@_); } # XXX: FIXME: Attributes docs need clearing up diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index 8cc5b6c..aa14aa6 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -4,6 +4,7 @@ use strict; use warnings; use DBIx::Class::ResultSet; +use DBIx::Class::ResultSourceHandle; use Carp::Clan qw/^DBIx::Class/; use Storable; @@ -999,6 +1000,20 @@ its class name. # from your schema... $schema->resultset('Books')->find(1); +=head2 handle + +Obtain a new handle to this source. Returns an instance of a +L. + +=cut + +sub handle { + return new DBIx::Class::ResultSourceHandle({ + schema => $_[0]->schema, + source_monkier => $_[0]->source_name + }); +} + =head2 throw_exception See L. diff --git a/lib/DBIx/Class/ResultSourceHandle.pm b/lib/DBIx/Class/ResultSourceHandle.pm new file mode 100644 index 0000000..2621610 --- /dev/null +++ b/lib/DBIx/Class/ResultSourceHandle.pm @@ -0,0 +1,76 @@ +package DBIx::Class::ResultSourceHandle; + +use strict; +use warnings; +use Storable; + +use base qw/DBIx::Class/; + +use overload + q/""/ => sub { __PACKAGE__ . ":" . shift->source_monkier; }, + fallback => 1; + +__PACKAGE__->mk_group_accessors('simple' => qw/schema source_monkier/); + +=head1 NAME + +DBIx::Class::ResultSourceHandle + +=head1 DESCRIPTION + +This module removes fixed link between Rows/ResultSets and the actual source +objects, which gets round the following problems + +=over 4 + +=item * + +Needing to keep C<$schema> in scope, since any objects/result_sets +will have a C<$schema> object through their source handle + +=item * + +Large output when using Data::Dump(er) since this class can be set to +stringify to almost nothing + +=item * + +Closer to being aboe to do a Serialize::Storable that doesn't require class-based connections + +=back + +=head1 METHODS + +=head2 new + +=cut + +sub new { + my ($class, $data) = @_; + + $class = ref $class if ref $class; + + bless $data, $class; +} + +=head2 resolve + +Resolve the monkier into the actual ResultSource object + +=cut + +sub resolve { return $_[0]->schema->source($_[0]->source_monkier) } + +sub STORABLE_freeze { + my ($self, $cloning) = @_; + my $to_serialize = { %$self }; + delete $to_serialize->{schema}; + return (Storable::freeze($to_serialize)); +} + +sub STORABLE_thaw { + my ($self, $cloning,$ice) = @_; + %$self = %{ Storable::thaw($ice) }; +} + +1; diff --git a/lib/DBIx/Class/Row.pm b/lib/DBIx/Class/Row.pm index 7d9298d..11c3dd1 100644 --- a/lib/DBIx/Class/Row.pm +++ b/lib/DBIx/Class/Row.pm @@ -6,7 +6,7 @@ use warnings; use base qw/DBIx::Class/; use Carp::Clan qw/^DBIx::Class/; -__PACKAGE__->mk_group_accessors('simple' => 'result_source'); +__PACKAGE__->mk_group_accessors('simple' => qw/_source_handle/); =head1 NAME @@ -39,8 +39,8 @@ sub new { if ($attrs) { $new->throw_exception("attrs must be a hashref") unless ref($attrs) eq 'HASH'; - if (my $source = delete $attrs->{-result_source}) { - $new->result_source($source); + if (my $source = delete $attrs->{-source_handle}) { + $new->_source_handle($source); } foreach my $k (keys %$attrs) { $new->throw_exception("No such column $k on $class") @@ -325,9 +325,17 @@ Called by ResultSet to inflate a result from storage sub inflate_result { my ($class, $source, $me, $prefetch) = @_; - #use Data::Dumper; print Dumper(@_); + + my ($source_handle) = $source; + + if ($source->isa('DBIx::Class::ResultSourceHandle')) { + $source = $source_handle->resolve + } else { + $source_handle = $source->handle + } + my $new = { - result_source => $source, + _source_handle => $source_handle, _column_data => $me, _in_storage => 1 }; @@ -427,6 +435,18 @@ sub is_column_changed { Accessor to the ResultSource this object was created from +=cut + +sub result_source { + my $self = shift; + + if (@_) { + $self->_source_handle($_[0]->handle); + } else { + $self->_source_handle->resolve; + } +} + =head2 register_column $column_info = { .... }; diff --git a/lib/DBIx/Class/Serialize/Storable.pm b/lib/DBIx/Class/Serialize/Storable.pm deleted file mode 100644 index 7ccd2b0..0000000 --- a/lib/DBIx/Class/Serialize/Storable.pm +++ /dev/null @@ -1,68 +0,0 @@ -package DBIx::Class::Serialize::Storable; -use strict; -use warnings; -use Storable; - -sub STORABLE_freeze { - my ($self,$cloning) = @_; - my $to_serialize = { %$self }; - delete $to_serialize->{result_source}; - return (Storable::freeze($to_serialize)); -} - -sub STORABLE_thaw { - my ($self,$cloning,$serialized) = @_; - %$self = %{ Storable::thaw($serialized) }; - $self->result_source($self->result_source_instance) - if $self->can('result_source_instance'); -} - -1; - -__END__ - -=head1 NAME - - DBIx::Class::Serialize::Storable - hooks for Storable freeze/thaw - -=head1 SYNOPSIS - - # in a table class definition - __PACKAGE__->load_components(qw/Serialize::Storable/); - - # meanwhile, in a nearby piece of code - my $cd = $schema->resultset('CD')->find(12); - # if the cache uses Storable, this will work automatically - $cache->set($cd->ID, $cd); - -=head1 DESCRIPTION - -This component adds hooks for Storable so that row objects can be -serialized. It assumes that your row object class (C) is -the same as your table class, which is the normal situation. - -=head1 HOOKS - -The following hooks are defined for L - see the -documentation for L for detailed information on these -hooks. - -=head2 STORABLE_freeze - -The serializing hook, called on the object during serialization. It -can be inherited, or defined in the class itself, like any other -method. - -=head2 STORABLE_thaw - -The deserializing hook called on the object during deserialization. - -=head1 AUTHORS - -David Kamholz - -=head1 LICENSE - -You may distribute this code under the same terms as Perl itself. - -=cut diff --git a/t/lib/DBICTest/Schema/ArtistSourceName.pm b/t/lib/DBICTest/Schema/ArtistSourceName.pm index c4c8a8b..c59bbe5 100644 --- a/t/lib/DBICTest/Schema/ArtistSourceName.pm +++ b/t/lib/DBICTest/Schema/ArtistSourceName.pm @@ -2,7 +2,7 @@ package # hide from PAUSE DBICTest::Schema::ArtistSourceName; use base 'DBICTest::Schema::Artist'; - +__PACKAGE__->table(__PACKAGE__->table); __PACKAGE__->source_name('SourceNameArtists'); 1;