[Bast-commits] r9555 - in DBIx-Class/0.08/branches/extended_rels:
lib/DBIx/Class lib/DBIx/Class/Relationship t/lib/DBICTest/Schema
ruoso at dev.catalyst.perl.org
ruoso at dev.catalyst.perl.org
Wed Jun 2 17:27:37 GMT 2010
Author: ruoso
Date: 2010-06-02 18:27:37 +0100 (Wed, 02 Jun 2010)
New Revision: 9555
Modified:
DBIx-Class/0.08/branches/extended_rels/lib/DBIx/Class/Relationship/Base.pm
DBIx-Class/0.08/branches/extended_rels/lib/DBIx/Class/Relationship/ManyToMany.pm
DBIx-Class/0.08/branches/extended_rels/lib/DBIx/Class/ResultSource.pm
DBIx-Class/0.08/branches/extended_rels/t/lib/DBICTest/Schema/Artist.pm
DBIx-Class/0.08/branches/extended_rels/t/lib/DBICTest/Schema/Track.pm
Log:
Most of the code reviewed... Missing ResultSet->populate, ResultSet->find, Row->copy and Relationship::Accessor->add_relationship_accessor
Modified: DBIx-Class/0.08/branches/extended_rels/lib/DBIx/Class/Relationship/Base.pm
===================================================================
--- DBIx-Class/0.08/branches/extended_rels/lib/DBIx/Class/Relationship/Base.pm 2010-06-02 13:41:23 UTC (rev 9554)
+++ DBIx-Class/0.08/branches/extended_rels/lib/DBIx/Class/Relationship/Base.pm 2010-06-02 17:27:37 UTC (rev 9555)
@@ -203,7 +203,15 @@
# condition resolution may fail if an incomplete master-object prefetch
# is encountered - that is ok during prefetch construction (not yet in_storage)
- my $cond = eval { $source->_resolve_condition( $rel_info->{cond}, $rel, $self ) };
+
+ # if $rel_info->{cond} is a CODE, we might need to join from the
+ # current resultsource instead of just querying the target
+ # resultsource, in that case, the condition might provide an
+ # additional condition in order to avoid an unecessary join if
+ # that is at all possible.
+ my ($cond, $cond2) =
+ eval { $source->_resolve_condition( $rel_info->{cond}, $rel, $self ) };
+
if (my $err = $@) {
if ($self->in_storage) {
$self->throw_exception ($err);
@@ -239,10 +247,31 @@
}
} @$cond ];
} elsif (ref $cond eq 'HASH') {
- foreach my $key (grep { ! /\./ } keys %$cond) {
- $cond->{"me.$key"} = delete $cond->{$key};
+
+ # this is where we're going to check if we have an extended
+ # rel. In that case, we need to: 1) If there's a second
+ # condition, we use that instead. 2) If there is only one
+ # condition, we need to join the current resultsource and have
+ # additional conditions.
+ if (ref $rel_info->{cond} eq 'CODE') {
+ # this is an extended relationship.
+ if ($cond2) {
+ $cond = $cond2;
+ } else {
+ if (exists $attrs->{join} && $attrs->{join}) {
+ # it's a bit hard to find out what to do here.
+ $self->throw_exception('Extended relationship '.$rel.' with additional join not supported');
+ } else {
+ $attrs->{join} = $rel;
+ }
+ }
+ } else {
+ foreach my $key (grep { ! /\./ } keys %$cond) {
+ $cond->{"me.$key"} = delete $cond->{$key};
+ }
}
}
+
$query = ($query ? { '-and' => [ $cond, $query ] } : $cond);
$self->result_source->related_source($rel)->resultset->search(
$query, $attrs
@@ -424,9 +453,16 @@
$self->throw_exception( "Object $f_obj isn't a ".$f_class )
unless Scalar::Util::blessed($f_obj) and $f_obj->isa($f_class);
}
- $self->set_columns(
- $self->result_source->_resolve_condition(
- $rel_info->{cond}, $f_obj, $rel));
+
+ # _resolve_condition might return two hashrefs, specially in the
+ # current case, since we know $f_object is an object.
+ my ($condref1, $condref2) = $self->result_source->_resolve_condition
+ ($rel_info->{cond}, $f_obj, $rel);
+
+ # if we get two condrefs, we need to use the second, otherwise we
+ # use the first.
+ $self->set_columns($condref2 ? $condref2 : $condref1);
+
return 1;
}
Modified: DBIx-Class/0.08/branches/extended_rels/lib/DBIx/Class/Relationship/ManyToMany.pm
===================================================================
--- DBIx-Class/0.08/branches/extended_rels/lib/DBIx/Class/Relationship/ManyToMany.pm 2010-06-02 13:41:23 UTC (rev 9554)
+++ DBIx-Class/0.08/branches/extended_rels/lib/DBIx/Class/Relationship/ManyToMany.pm 2010-06-02 17:27:37 UTC (rev 9555)
@@ -131,9 +131,20 @@
or $self->throw_exception("${remove_meth} needs an object");
my $rel_source = $self->search_related($rel)->result_source;
my $cond = $rel_source->relationship_info($f_rel)->{cond};
- my $link_cond = $rel_source->_resolve_condition(
- $cond, $obj, $f_rel
- );
+ my $link_cond;
+ if (ref $cond eq 'CODE') {
+ my ($cond1, $cond2) = $rel_source->_resolve_condition
+ ($cond, $obj, $f_rel);
+ if ($cond2) {
+ $link_cond = $cond2;
+ } else {
+ $self->throw_exception('Extended relationship '.$rel.
+ ' requires optimized version for ManyToMany.');
+ }
+ } else {
+ $link_cond = $rel_source->_resolve_condition
+ ($cond, $obj, $f_rel);
+ }
$self->search_related($rel, $link_cond)->delete;
};
Modified: DBIx-Class/0.08/branches/extended_rels/lib/DBIx/Class/ResultSource.pm
===================================================================
--- DBIx-Class/0.08/branches/extended_rels/lib/DBIx/Class/ResultSource.pm 2010-06-02 13:41:23 UTC (rev 9554)
+++ DBIx-Class/0.08/branches/extended_rels/lib/DBIx/Class/ResultSource.pm 2010-06-02 17:27:37 UTC (rev 9555)
@@ -1365,12 +1365,7 @@
$self->throw_exception ('Unable to determine relationship name for condition resolution');
}
- $cond = $cond->(
- $for,
- ref $for ? 'me' : $as,
- $self,
- $rel,
- );
+ return $cond->($for, ref $for ? 'me' : $as, $self, $rel, ref $for ? $for : undef);
} elsif (ref $cond eq 'HASH') {
my %ret;
Modified: DBIx-Class/0.08/branches/extended_rels/t/lib/DBICTest/Schema/Artist.pm
===================================================================
--- DBIx-Class/0.08/branches/extended_rels/t/lib/DBICTest/Schema/Artist.pm 2010-06-02 13:41:23 UTC (rev 9554)
+++ DBIx-Class/0.08/branches/extended_rels/t/lib/DBICTest/Schema/Artist.pm 2010-06-02 17:27:37 UTC (rev 9555)
@@ -46,13 +46,18 @@
__PACKAGE__->has_many(
cds_80s => 'DBICTest::Schema::CD',
sub {
- my ( $me, $as, $self_rsrc, $rel ) = @_;
- return {
- "${as}.artist" => (ref $me ? $me->artistid : { '=' => \"${me}.artistid"}),
- "${as}.year" => { '>', "1979",
- '<', "1990" }
- };
- }
+ my ( $me_alias, $rel_alias, $me_result_source, $rel_name, $optional_me_object ) = @_;
+ return
+ ({ "${rel_alias}.artist" => { '=' => \"${me_alias}.artistid"},
+ "${rel_aliase}.year" => { '>', "1979",
+ '<', "1990" }
+ },
+ $optional_me_object &&
+ { "${rel_alias}.artist" => $optional_me_object->artistid,
+ "${rel_alias}.year" => { '>', "1979",
+ '<', "1990" }
+ });
+ }
);
Modified: DBIx-Class/0.08/branches/extended_rels/t/lib/DBICTest/Schema/Track.pm
===================================================================
--- DBIx-Class/0.08/branches/extended_rels/t/lib/DBICTest/Schema/Track.pm 2010-06-02 13:41:23 UTC (rev 9554)
+++ DBIx-Class/0.08/branches/extended_rels/t/lib/DBICTest/Schema/Track.pm 2010-06-02 17:27:37 UTC (rev 9555)
@@ -67,11 +67,15 @@
'next_track',
__PACKAGE__,
sub {
- my ( $me, $as, $self_rsrc, $rel_name ) = @_;
- return {
- "${as}.cd" => (ref $me ? $me->cd : { '=' => \"${me}.cd" }),
- "${as}.position" => { '>', (ref $me ? $me->position : \"${me}.position" )},
- };
+ my ( $me_alias, $rel_alias, $me_result_source, $rel_name, $optional_me_object ) = @_;
+ return
+ ({ "${rel_alias}.cd" => { '=', \"${me_alias}.cd" },
+ "${rel_alias}.position" => { '>', \"${me_alias}.position" },
+ },
+ $optional_me_object &&
+ { "${rel_alias}.cd" => $optional_me_object->cd,
+ "${rel_alias}.position" => { '>', $optional_me_object->position },
+ });
},
);
More information about the Bast-commits
mailing list