X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class.git;a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FResultSource.pm;h=8ea0b1f7f8714066555a37482d410437dfca58bc;hp=ceb5d3675187b3d67d97d91b00b2e478f2984f4e;hb=489709af09215594801ecdbe208f542e0432d0a0;hpb=5ec6bc2ed4f0de3f0764196e0295799a0dd61b99 diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index ceb5d36..8ea0b1f 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -352,26 +352,31 @@ Returns the join structure required for the related result source =cut sub resolve_join { - my ($self, $join, $alias) = @_; + my ($self, $join, $alias, $seen) = @_; + $seen ||= {}; if (ref $join eq 'ARRAY') { - return map { $self->resolve_join($_, $alias) } @$join; + return map { $self->resolve_join($_, $alias, $seen) } @$join; } elsif (ref $join eq 'HASH') { - return map { $self->resolve_join($_, $alias), - $self->related_source($_)->resolve_join($join->{$_}, $_) } + return + map { $self->resolve_join($_, $alias, $seen), + $self->related_source($_)->resolve_join($join->{$_}, $_, $seen) } keys %$join; } elsif (ref $join) { $self->throw_exception("No idea how to resolve join reftype ".ref $join); } else { + my $count = ++$seen->{$join}; + #use Data::Dumper; warn Dumper($seen); + my $as = ($count > 1 ? "${join}_${count}" : $join); my $rel_info = $self->relationship_info($join); $self->throw_exception("No such relationship ${join}") unless $rel_info; my $type = $rel_info->{attrs}{join_type} || ''; - return [ { $join => $self->related_source($join)->from, + return [ { $as => $self->related_source($join)->from, -join_type => $type }, - $self->resolve_condition($rel_info->{cond}, $join, $alias) ]; + $self->resolve_condition($rel_info->{cond}, $as, $alias) ]; } } -=head2 resolve_condition($cond, $rel, $alias|$object) +=head2 resolve_condition($cond, $as, $alias|$object) Resolves the passed condition to a concrete query fragment. If given an alias, returns a join condition; if given an object, inverts that object to produce @@ -380,7 +385,7 @@ a related conditional from that object. =cut sub resolve_condition { - my ($self, $cond, $rel, $for) = @_; + my ($self, $cond, $as, $for) = @_; #warn %$cond; if (ref $cond eq 'HASH') { my %ret; @@ -393,12 +398,12 @@ sub resolve_condition { $ret{$k} = $for->get_column($v); #warn %ret; } else { - $ret{"${rel}.${k}"} = "${for}.${v}"; + $ret{"${as}.${k}"} = "${for}.${v}"; } } return \%ret; } elsif (ref $cond eq 'ARRAY') { - return [ map { $self->resolve_condition($_, $rel, $for) } @$cond ]; + return [ map { $self->resolve_condition($_, $as, $for) } @$cond ]; } else { die("Can't handle this yet :("); } @@ -448,20 +453,21 @@ in the supplied relationships. Examples: =cut sub resolve_prefetch { - my( $self, $pre, $alias ) = @_; + my ($self, $pre, $alias, $seen) = @_; + $seen ||= {}; use Data::Dumper; #$alias ||= $self->name; #warn $alias, Dumper $pre; if( ref $pre eq 'ARRAY' ) { - return map { $self->resolve_prefetch( $_, $alias ) } @$pre; + return map { $self->resolve_prefetch( $_, $alias, $seen ) } @$pre; } elsif( ref $pre eq 'HASH' ) { my @ret = map { - $self->resolve_prefetch($_, $alias), - $self->related_source($_)->resolve_prefetch( $pre->{$_}, $_ ) - } - keys %$pre; + $self->resolve_prefetch($_, $alias, $seen), + $self->related_source($_)->resolve_prefetch( + $pre->{$_}, "${alias}.$_", $seen) + } keys %$pre; #die Dumper \@ret; return @ret; } @@ -469,12 +475,15 @@ sub resolve_prefetch { $self->throw_exception( "don't know how to resolve prefetch reftype " . ref $pre); } else { + my $count = ++$seen->{$pre}; + my $as = ($count > 1 ? "${pre}_${count}" : $pre); my $rel_info = $self->relationship_info( $pre ); $self->throw_exception( $self->name . " has no such relationship '$pre'" ) unless $rel_info; - my $prefix = $alias && $alias ne 'me' ? "$alias.$pre" : $pre; - my @ret = map { "$prefix.$_" } $self->related_source($pre)->columns; + my $as_prefix = ($alias =~ /^.*?\.(.*)$/ ? $1.'.' : ''); + return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] } + $self->related_source($pre)->columns; #warn $alias, Dumper (\@ret); - return @ret; + #return @ret; } }