From: Peter Rabbitson Date: Fri, 3 Jul 2015 13:23:14 +0000 (+0200) Subject: Switch a couple 'no-brainer' spots to _resolve_relationship_condition X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class.git;a=commitdiff_plain;h=b70a4bb5fb07064a3a3255d0647d768f6c219061 Switch a couple 'no-brainer' spots to _resolve_relationship_condition More to come, all of this should result in no functional changes --- diff --git a/lib/DBIx/Class/Relationship/Base.pm b/lib/DBIx/Class/Relationship/Base.pm index 04b1a88..f5d34f8 100644 --- a/lib/DBIx/Class/Relationship/Base.pm +++ b/lib/DBIx/Class/Relationship/Base.pm @@ -521,10 +521,27 @@ sub related_resultset { my $rel_info = $rsrc->relationship_info($rel) or $self->throw_exception( "No such relationship '$rel'" ); - my ($cond, $is_crosstable) = $rsrc->_resolve_condition( $rel_info->{cond}, $rel, $self, $rel ); + my $cond_res = $rsrc->_resolve_relationship_condition( + rel_name => $rel, + self_result_object => $self, + + # this may look weird, but remember that we are making a resultset + # out of an existing object, with the new source being at the head + # of the FROM chain. Having a 'me' alias is nothing but expected there + foreign_alias => 'me', + + self_alias => "!!!\xFF()!!!_SHOULD_NEVER_BE_SEEN_IN_USE_!!!()\xFF!!!", + + # not strictly necessary, but shouldn't hurt either + require_join_free_condition => !!(ref $rel_info->{cond} ne 'CODE'), + ); # keep in mind that the following if() block is part of a do{} - no return()s!!! - if ($is_crosstable and ref $rel_info->{cond} eq 'CODE') { + if ( + ! $cond_res->{join_free_condition} + and + ref $rel_info->{cond} eq 'CODE' + ) { # A WHOREIFFIC hack to reinvoke the entire condition resolution # with the correct alias. Another way of doing this involves a @@ -551,12 +568,13 @@ sub related_resultset { )->search_related('me', undef, $rel_info->{attrs}) } else { - my $attrs = { %{ $rel_info->{attrs} } }; # FIXME - this conditional doesn't seem correct - got to figure out # at some point what it does. Also the entire UNRESOLVABLE_CONDITION # business seems shady - we could simply not query *at all* - if ($cond eq UNRESOLVABLE_CONDITION) { + my $attrs; + if ( $cond_res->{join_free_condition} eq UNRESOLVABLE_CONDITION ) { + $attrs = { %{$rel_info->{attrs}} }; my $reverse = $rsrc->reverse_relationship_info($rel); foreach my $rev_rel (keys %$reverse) { if ($reverse->{$rev_rel}{attrs}{accessor} && $reverse->{$rev_rel}{attrs}{accessor} eq 'multi') { @@ -566,27 +584,11 @@ sub related_resultset { } } } - elsif (ref $cond eq 'ARRAY') { - $cond = [ map { - if (ref $_ eq 'HASH') { - my $hash; - foreach my $key (keys %$_) { - my $newkey = $key !~ /\./ ? "me.$key" : $key; - $hash->{$newkey} = $_->{$key}; - } - $hash; - } else { - $_; - } - } @$cond ]; - } - elsif (ref $cond eq 'HASH') { - foreach my $key (grep { ! /\./ } keys %$cond) { - $cond->{"me.$key"} = delete $cond->{$key}; - } - } - $rsrc->related_source($rel)->resultset->search( $cond, $attrs ); + $rsrc->related_source($rel)->resultset->search( + $cond_res->{join_free_condition}, + $attrs || $rel_info->{attrs}, + ); } }; } diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index 3c45662..c67fa45 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -1715,7 +1715,11 @@ sub _resolve_join { -alias => $as, -relation_chain_depth => ( $seen->{-relation_chain_depth} || 0 ) + 1, }, - scalar $self->_resolve_condition($rel_info->{cond}, $as, $alias, $join) + $self->_resolve_relationship_condition( + rel_name => $join, + self_alias => $alias, + foreign_alias => $as, + )->{condition}, ]; } } diff --git a/lib/DBIx/Class/ResultSource/RowParser.pm b/lib/DBIx/Class/ResultSource/RowParser.pm index 8ed29b3..83be406 100644 --- a/lib/DBIx/Class/ResultSource/RowParser.pm +++ b/lib/DBIx/Class/ResultSource/RowParser.pm @@ -197,26 +197,12 @@ sub _resolve_collapse { is_single => ( $inf->{attrs}{accessor} && $inf->{attrs}{accessor} ne 'multi' ), is_inner => ( ( $inf->{attrs}{join_type} || '' ) !~ /^left/i), rsrc => $self->related_source($rel), + fk_map => $self->_resolve_relationship_condition( + rel_name => $rel, + self_alias => "\xFE", # irrelevant + foreign_alias => "\xFF", # irrelevant + )->{identity_map}, }; - - # FIME - need to use _resolve_cond here instead - my $cond = $inf->{cond}; - - if ( - ref $cond eq 'HASH' - and - keys %$cond - and - ! defined first { $_ !~ /^foreign\./ } (keys %$cond) - and - ! defined first { $_ !~ /^self\./ } (values %$cond) - ) { - for my $f (keys %$cond) { - my $s = $cond->{$f}; - $_ =~ s/^ (?: foreign | self ) \.//x for ($f, $s); - $relinfo->{$rel}{fk_map}{$s} = $f; - } - } } # inject non-left fk-bridges from *INNER-JOINED* children (if any) diff --git a/lib/DBIx/Class/Row.pm b/lib/DBIx/Class/Row.pm index a4a18b9..5425fd8 100644 --- a/lib/DBIx/Class/Row.pm +++ b/lib/DBIx/Class/Row.pm @@ -1174,16 +1174,21 @@ sub copy { next unless $rel_info->{attrs}{cascade_copy}; - my $resolved = $rsrc->_resolve_condition( - $rel_info->{cond}, $rel_name, $new, $rel_name - ); - + my $foreign_vals; my $copied = $rel_names_copied->{ $rel_info->{source} } ||= {}; - foreach my $related ($self->search_related($rel_name)->all) { - $related->copy($resolved) - unless $copied->{$related->ID}++; - } + $copied->{$_->ID}++ or $_->copy( + + $foreign_vals ||= $rsrc->_resolve_relationship_condition( + infer_values_based_on => {}, + rel_name => $rel_name, + self_result_object => $new, + + self_alias => "\xFE", # irrelevant + foreign_alias => "\xFF", # irrelevant, + )->{inferred_values} + + ) for $self->search_related($rel_name)->all; } return $new; }