push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
unless $seen{$p};
}
- #print "res pre: " . Dumper($p, $collapse);
- 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);
-
- #print "prefetch: " . Dumper(\@prefetch);
- 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);
}
my ($self, @row) = @_;
my @as = @{ $self->{_attrs}{as} };
- #print "row in: " . Dumper(\@row);
my $info = $self->_collapse_result(\@as, \@row);
my $new = $self->result_class->inflate_result($self->result_source, @$info);
$new = $self->{_attrs}{record_filter}->($new)
}
my @collapse;
- #print "collapse: " . Dumper($self->{_attrs}->{collapse});
if (defined $prefix) {
@collapse = map {
m/^\Q${prefix}.\E(.+)$/ ? ($1) : ()
my %co_check = map { ($_, $tree->[0]->{$_}); } @co_key;
my (@final, @raw);
- #print "les free: " . Dumper($tree->[0], \%co_check, \@co_key);
while ( !(grep {
!defined($tree->[0]->{$_}) ||
$co_check{$_} ne $tree->[0]->{$_}
# single empty result to indicate an empty prefetched has_many
}
- # get prefetch tree back to result_source level
- # $self could be a related resultset
- #if ($self->{attrs}->{_live_join_stack}) {
- # foreach (@{$self->{attrs}->{_live_join_stack}}) {
- # $info->[1] = $info->[1]->{$_}->[1] if(exists $info->[1]->{$_});
- #}
- #}
#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,
_live_join => $rel, #the most recent
- _live_join_stack => $live_join_stack, #the trail of rels
+ _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;
my $schema = DBICTest->init_schema();
-plan tests => 11;
+plan tests => 14;
my @rs1a_results = $schema->resultset("Artist")->search_related('cds', {title => 'Forkful of bees'}, {order_by => 'title'});
is($rs1a_results[0]->title, 'Forkful of bees', "bare field conditions okay after search related");
my @cds = $artists2[0]->cds;
cmp_ok(scalar @cds, '==', 1, "condition based on inherited join okay");
-# this is wrong, should accept me.title really
+#this is wrong, should accept me.title really
my $rs3 = $rs2->search_related('cds');
cmp_ok($rs3->count, '==', 9, "Nine artists returned");
my @tracks = $cd->tracks->all;
is(scalar(@tracks), 3, 'right number of prefetched tracks after has many');
-# causes ambig col error due to order_by
+#causes ambig col error due to order_by
#my $tracks_rs = $cds->search_related('tracks', { 'tracks.position' => '2', 'disc.title' => 'Forkful of bees' });
#my $first_tracks_rs = $tracks_rs->first;
my $related_rs = $schema->resultset("Artist")->search({ name => 'Caterwauler McCrae' })->search_related('cds', { year => '2001'})->search_related('tracks', { 'position' => '2' });
is($related_rs->first->trackid, '5', 'search related on search related okay');
-# causes ambig col error due to order_by
+#causes ambig col error due to order_by
#$related_rs->search({'cd.year' => '2001'}, {join => ['cd', 'cd']})->all;
my $title = $schema->resultset("Artist")->search_related('twokeys')->search_related('cd')->search({'tracks.position' => '2'}, {join => 'tracks', order_by => 'tracks.trackid'})->next->title;
is($title, 'Forkful of bees', 'search relateds with order by okay');
-# my $prod_rs = $schema->resultset("CD")->find(1)->other_producers;
-# my $prod_rs2 = $prod_rs->search({ name => 'Matt S Trout' }, { prefetch => 'producer_to_cd', order_by => 'other_producer.name' });
-# my $prod_first = $prod_rs2->first;
-# warn $prod_first->name;
+my $prod_rs = $schema->resultset("CD")->find(1)->producers_sorted;
+my $prod_rs2 = $prod_rs->search({ name => 'Matt S Trout' });
+my $prod_first = $prod_rs2->first;
+is($prod_first->id, '1', 'somewhat pointless search on rel with order_by on it okay');
my $prod_map_rs = $schema->resultset("Artist")->find(1)->cds->search_related('cd_to_producer', {}, { join => 'producer', prefetch => 'producer' });
-use Data::Dumper;
-warn $prod_map_rs->count;
-print Dumper($prod_map_rs->{attrs});
-print Dumper($prod_map_rs->{_attrs});
-$prod_map_rs->first;
+is($prod_map_rs->next->producer->producerid, '1', 'search related with prefetch okay');
+my $stupid = $schema->resultset("Artist")->search_related('artist_undirected_maps', {}, { prefetch => 'artist1' })->search_related('mapped_artists')->search_related('cds', {'cds.cdid' => '2'}, { prefetch => 'tracks' });
+#use Data::Dumper; warn Dumper($stupid->{attrs});
+my $cd_final = $schema->resultset("Artist")->search_related('artist_undirected_maps', {}, { prefetch => 'artist1' })->search_related('mapped_artists')->search_related('cds', {'cds.cdid' => '2'}, { prefetch => 'tracks' })->first;
+is($cd_final->cdid, '2', 'bonkers search_related-with-join-midway okay');
1;
{ proxy => [ qw/notes/ ] },
);
__PACKAGE__->many_to_many( producers => cd_to_producer => 'producer' );
-__PACKAGE__->many_to_many( other_producers => cd_to_producer => 'other_producer' );
__PACKAGE__->many_to_many(
producers_sorted => cd_to_producer => 'producer',
{ order_by => 'producer.name' },
{ 'foreign.producerid' => 'self.producer' }
);
-__PACKAGE__->belongs_to(
- 'other_producer', 'DBICTest::Schema::Producer',
- { 'foreign.producerid' => 'self.producer' }
-);
-
1;
__PACKAGE__->set_primary_key('producerid');
__PACKAGE__->add_unique_constraint(prod_name => [ qw/name/ ]);
-__PACKAGE__->has_many(
- producer_to_cd => 'DBICTest::Schema::CD_to_Producer' => 'producer'
-);
-
-
1;