use Storable;
use Data::Dumper;
use Scalar::Util qw/weaken/;
-
+use Data::Dumper;
use DBIx::Class::ResultSetColumn;
use base qw/DBIx::Class/;
__PACKAGE__->load_components(qw/AccessorGroup/);
my $having = delete $our_attrs->{having};
# XXX this is getting messy
- if ($attrs->{_live_join_stack} || $our_attrs->{_live_join_stack}) {
- my $live_join = $attrs->{_live_join_stack} || $our_attrs->{_live_join_stack};
+ if ($attrs->{_live_join_stack}) {
+ my $live_join = $attrs->{_live_join_stack};
foreach (reverse @{$live_join}) {
$attrs->{_live_join_h} = (defined $attrs->{_live_join_h}) ? { $_ => $attrs->{_live_join_h} } : $_;
}
next unless (exists $attrs->{$key});
if ($attrs->{_live_join_stack} || $our_attrs->{_live_join_stack}) {
my $live_join = $attrs->{_live_join_stack} || $our_attrs->{_live_join_stack};
- foreach (@{$live_join}) {
+ foreach (reverse @{$live_join}) {
$attrs->{$key} = { $_ => $attrs->{$key} };
}
}
- if ($attrs->{_live_join} || $our_attrs->{_live_join}) {
- $attrs->{$key} = { ($attrs->{_live_join}) ? $attrs->{_live_join} : $our_attrs->{_live_join} => $attrs->{$key} };
- }
+
if (exists $our_attrs->{$key}) {
$our_attrs->{$key} = $self->_merge_attr($our_attrs->{$key}, $attrs->{$key});
} else {
}
unless ($self->_is_unique_query($attrs->{where})) {
- carp "Query not guarnteed to return a single row"
+ carp "Query not guaranteed to return a single row"
. "; please declare your unique constraints or use search instead";
}
my @asadds = (ref($asadds) eq 'ARRAY' ? @$asadds : ($asadds));
$attrs->{as} = [ @{ $attrs->{as} }, @asadds ];
}
-
my $collapse = $attrs->{collapse} || {};
if (my $prefetch = delete $attrs->{prefetch}) {
my @pre_order;
push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
unless $seen{$p};
}
- my @prefetch = $source->resolve_prefetch(
+
+ # we're about to resolve_join on the current class, so we need to bring
+ # the joins (which are from the original class) to the right level
+ # XXX the below alg is ridiculous
+ if ($attrs->{_live_join_stack}) {
+ STACK: foreach (@{$attrs->{_live_join_stack}}) {
+ if (ref $p eq 'HASH') {
+ if (exists $p->{$_}) {
+ $p = $p->{$_};
+ } else {
+ $p = undef;
+ last STACK;
+ }
+ } elsif (ref $p eq 'ARRAY') {
+ foreach my $pe (@{$p}) {
+ if ($pe eq $_) {
+ $p = undef;
+ last STACK;
+ }
+ next unless(ref $pe eq 'HASH');
+ next unless(exists $pe->{$_});
+ $p = $pe->{$_};
+ next STACK;
+ }
+ $p = undef;
+ last STACK;
+ } else {
+ $p = undef;
+ last STACK;
+ }
+ }
+ }
+
+ if ($p) {
+ my @prefetch = $self->result_source->resolve_prefetch(
$p, $attrs->{alias}, {}, \@pre_order, $collapse);
- push(@{$attrs->{select}}, map { $_->[0] } @prefetch);
- push(@{$attrs->{as}}, map { $_->[1] } @prefetch);
+
+ push(@{$attrs->{select}}, map { $_->[0] } @prefetch);
+ push(@{$attrs->{as}}, map { $_->[1] } @prefetch);
+ }
}
push(@{$attrs->{order_by}}, @pre_order);
}
if (exists $a->{$key}) {
$a->{$key} = $self->_merge_attr($a->{$key}, $b->{$key}, $is_prefetch);
} else {
- $a->{$key} = delete $b->{$key};
+ $a->{$key} = $b->{$key};
}
}
return $a;
}
}
}
- if ($is_prefetch) {
- my $final_array = [];
- foreach my $element (@{$array}) {
- push(@{$final_array}, $element) unless (exists $hash->{$element});
- }
- $array = $final_array;
- }
+
+ my $final_array = [];
+ foreach my $element (@{$array}) {
+ push(@{$final_array}, $element) unless (exists $hash->{$element});
+ }
+ $array = $final_array;
+
if ((keys %{$hash}) && (scalar(@{$array} > 0))) {
return [$hash, @{$array}];
} else {
$info->[0] = $const{$key};
}
}
-
my @collapse;
+
if (defined $prefix) {
@collapse = map {
m/^\Q${prefix}.\E(.+)$/ ? ($1) : ()
}
my $c_prefix = (defined($prefix) ? "${prefix}.${c}" : $c);
my @co_key = @{$self->{_attrs}->{collapse}{$c_prefix}};
- my %co_check = map { ($_, $target->[0]->{$_}); } @co_key;
my $tree = $self->_collapse_result($as, $row, $c_prefix);
+ my %co_check = map { ($_, $tree->[0]->{$_}); } @co_key;
my (@final, @raw);
+
while ( !(grep {
!defined($tree->[0]->{$_}) ||
$co_check{$_} ne $tree->[0]->{$_}
@$target = (@final ? @final : [ {}, {} ]);
# single empty result to indicate an empty prefetched has_many
}
+
+ #print "final info: " . Dumper($info);
return $info;
}
return $self->{related_resultsets}{$rel} ||= do {
#warn "fetching related resultset for rel '$rel' " . $self->result_source->{name};
my $rel_obj = $self->result_source->relationship_info($rel);
+ #print Dumper($self->result_source->_relationships);
$self->throw_exception(
"search_related: result source '" . $self->result_source->name .
"' has no such relationship ${rel}")
unless $rel_obj; #die Dumper $self->{attrs};
- my $live_join_stack = $self->{attrs}->{_live_join_stack} || [];
- push(@{$live_join_stack}, $rel);
+ my @live_join_stack = (exists $self->{attrs}->{_live_join_stack}) ?
+ @{$self->{attrs}->{_live_join_stack}}:
+ ();
+ push(@live_join_stack, $rel);
my $rs = $self->result_source->schema->resultset($rel_obj->{class}
)->search( undef,
{ select => undef,
as => undef,
- #join => $rel,
- _live_join => $rel,
- _live_join_stack => $live_join_stack,
+ _live_join => $rel, #the most recent
+ _live_join_stack => \@live_join_stack, #the trail of rels
_parent_attrs => $self->{attrs}}
- );
+ );
# keep reference of the original resultset
$rs->{_parent_rs} = ($self->{_parent_rs}) ? $self->{_parent_rs} : $self->result_source;