From: Luke Saunders Date: Fri, 12 May 2006 11:38:30 +0000 (+0000) Subject: proper deep merging on join attrs X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=447e7b286002ac0434d9ccb6601c3df56a1474e4;p=dbsrgits%2FDBIx-Class-Historic.git proper deep merging on join attrs --- diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 93588e0..c3a7bbe 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -165,14 +165,13 @@ sub search_rs { # merge new attrs into old foreach my $key (qw/join prefetch/) { - next unless (exists $attrs->{$key}); - if (exists $our_attrs->{$key}) { - $our_attrs->{$key} = [$our_attrs->{$key}] if (ref $our_attrs->{$key} ne 'ARRAY'); - push(@{$our_attrs->{$key}}, (ref $attrs->{$key} eq 'ARRAY') ? @{$attrs->{$key}} : $attrs->{$key}); - } else { - $our_attrs->{$key} = $attrs->{$key}; - } - delete $attrs->{$key}; + next unless (exists $attrs->{$key}); + if (exists $our_attrs->{$key}) { + $our_attrs->{$key} = $self->_merge_attr($our_attrs->{$key}, $attrs->{$key}); + } else { + $our_attrs->{$key} = $attrs->{$key}; + } + delete $attrs->{$key}; } my $new_attrs = { %{$our_attrs}, %{$attrs} }; @@ -649,6 +648,43 @@ sub _resolve { $self->{_attrs} = $attrs; } +sub _merge_attr { + my ($self, $a, $b) = @_; + + if (ref $b eq 'HASH' && ref $a eq 'HASH') { + return $self->_merge_hash($a, $b); + } else { + $a = [$a] unless (ref $a eq 'ARRAY'); + $b = [$b] unless (ref $b eq 'ARRAY'); + my @new_array = (@{$a}, @{$b}); + foreach my $a_element (@new_array) { + my $i = 0; + foreach my $b_element (@new_array) { + if ((ref $a_element eq 'HASH') && (ref $b_element eq 'HASH') && ($a_element ne $b_element)) { + $a_element = $self->_merge_hash($a_element, $b_element); + $new_array[$i] = undef; + } + $i++; + } + } + @new_array = grep($_, @new_array); + return \@new_array; + } +} + +sub _merge_hash { + my ($self, $a, $b) = @_; + + foreach my $key (keys %{$b}) { + if (exists $a->{$key}) { + $a->{$key} = $self->_merge_attr($a->{$key}, $b->{$key}); + } else { + $a->{$key} = delete $b->{$key}; + } + } + return $a; +} + sub _construct_object { my ($self, @row) = @_; my @as = @{ $self->{_attrs}{as} };