From: Matt S Trout Date: Fri, 15 Nov 2013 14:54:10 +0000 (+0000) Subject: move _extract_fixed dq methods into resultsource to share between rs and row X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=bcd73dac886f1f8134fa85cda2d80c8f8f3e9f4d;p=dbsrgits%2FDBIx-Class.git move _extract_fixed dq methods into resultsource to share between rs and row --- diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 071d7e8..615723a 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -2339,7 +2339,8 @@ sub populate { ); if (ref($related) eq 'REF' and ref($$related) eq 'HASH') { - $related = $self->_extract_fixed_values_for($$related, $rel); + $related = $self->result_source + ->_extract_fixed_values_for($$related, $rel); } my @rows_to_add = ref $item->{$rel} eq 'ARRAY' ? @{$item->{$rel}} : ($item->{$rel}); @@ -2351,43 +2352,6 @@ sub populate { } } -sub _extract_fixed_values_for { - my ($self, $dq, $alias) = @_; - my $fixed = $self->_extract_fixed_conditions_for($dq, $alias); - return +{ map { - is_Value($fixed->{$_}) - ? ($_ => $fixed->{$_}{value}) - : () - } keys %$fixed }; -} - -sub _extract_fixed_conditions_for { - my ($self, $dq, $alias) = @_; - my (@q, %found) = ($dq); - while (my $n = shift @q) { - if (is_Operator($n)) { - if (($n->{operator}{Perl}||'') =~ /^(?:==|eq)$/) { - my ($l, $r) = @{$n->{args}}; - if ( - is_Identifier($r) and @{$r->{elements}} == 2 - and $r->{elements}[0] eq $alias - ) { - ($l, $r) = ($r, $l); - } - if ( - is_Identifier($l) and @{$l->{elements}} == 2 - and $l->{elements}[0] eq $alias - ) { - $found{$l->{elements}[1]} = $r; - } elsif (($n->{operator}{Perl}||'') eq 'and') { - push @q, @{$n->{args}}; - } - } - } - } - return \%found; -} - # populate() arguments went over several incarnations # What we ultimately support is AoH sub _normalize_populate_args { @@ -2579,7 +2543,8 @@ sub _merge_with_rscond { } } elsif (ref $self->{cond} eq 'REF' and ref ${$self->{cond}} eq 'HASH') { - %new_data = %{$self->_extract_fixed_values_for(${$self->{cond}}, $alias)}; + %new_data = %{$self->result_source + ->_extract_fixed_values_for(${$self->{cond}}, $alias)}; } else { $self->throw_exception( diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index e536cce..c9c86dc 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -1536,6 +1536,43 @@ sub __strip_relcond { return undef; } +sub _extract_fixed_values_for { + my ($self, $dq, $alias) = @_; + my $fixed = $self->_extract_fixed_conditions_for($dq, $alias); + return +{ map { + is_Value($fixed->{$_}) + ? ($_ => $fixed->{$_}{value}) + : () + } keys %$fixed }; +} + +sub _extract_fixed_conditions_for { + my ($self, $dq, $alias) = @_; + my (@q, %found) = ($dq); + while (my $n = shift @q) { + if (is_Operator($n)) { + if (($n->{operator}{Perl}||'') =~ /^(?:==|eq)$/) { + my ($l, $r) = @{$n->{args}}; + if ( + is_Identifier($r) and @{$r->{elements}} == 2 + and $r->{elements}[0] eq $alias + ) { + ($l, $r) = ($r, $l); + } + if ( + is_Identifier($l) and @{$l->{elements}} == 2 + and $l->{elements}[0] eq $alias + ) { + $found{$l->{elements}[1]} = $r; + } elsif (($n->{operator}{Perl}||'') eq 'and') { + push @q, @{$n->{args}}; + } + } + } + } + return \%found; +} + sub compare_relationship_keys { carp 'compare_relationship_keys is a private method, stop calling it'; my $self = shift; diff --git a/lib/DBIx/Class/Row.pm b/lib/DBIx/Class/Row.pm index 000498a..b4b7f19 100644 --- a/lib/DBIx/Class/Row.pm +++ b/lib/DBIx/Class/Row.pm @@ -1125,7 +1125,7 @@ sub copy { my $new = { _column_data => $col_data }; bless $new, ref $self; - $new->result_source($self->result_source); + $new->result_source(my $source = $self->result_source); $new->set_inflated_columns($changes); $new->insert; @@ -1134,15 +1134,19 @@ sub copy { # constraints my $relnames_copied = {}; - foreach my $relname ($self->result_source->relationships) { - my $rel_info = $self->result_source->relationship_info($relname); + foreach my $relname ($source->relationships) { + my $rel_info = $source->relationship_info($relname); next unless $rel_info->{attrs}{cascade_copy}; - my $resolved = $self->result_source->_resolve_condition( + my $resolved = $source->_resolve_condition( $rel_info->{cond}, $relname, $new, $relname ); + if (ref($resolved) eq 'REF') { + $resolved = $source->_extract_fixed_values_for($$resolved, 'me'); + } + my $copied = $relnames_copied->{ $rel_info->{source} } ||= {}; foreach my $related ($self->search_related($relname)->all) { my $id_str = join("\0", $related->id);