- Scale back validation of the 'as' attribute - in the field
there are legitimate-ish uses of a inflating into an apparently
invalid relationship graph
-
+ - Warn in case of iterative collapse being upgraded to an eager
+ cursor slurp
0.08209 2013-03-01 12:56 (UTC)
* New Features / Changes
my $rsrc = $self->result_source;
my $attrs = $self->_resolved_attrs;
- if (!$fetch_all and ! $attrs->{order_by} and $attrs->{collapse}) {
+ if (
+ ! $fetch_all
+ and
+ ! $attrs->{order_by}
+ and
+ $attrs->{collapse}
+ and
+ my @pcols = $rsrc->primary_columns
+ ) {
# default order for collapsing unless the user asked for something
- $attrs->{order_by} = [ map { join '.', $attrs->{alias}, $_} $rsrc->primary_columns ];
+ $attrs->{order_by} = [ map { join '.', $attrs->{alias}, $_} @pcols ];
$attrs->{_ordered_for_collapse} = 1;
$attrs->{_order_is_artificial} = 1;
}
# a surprising amount actually
my $rows = delete $self->{_stashed_rows};
+ my $did_fetch_all = $fetch_all;
+
if ($fetch_all) {
# FIXME SUBOPTIMAL - we can do better, cursor->next/all (well diff. methods) should return a ref
$rows = [ ($rows ? @$rows : ()), $cursor->all ];
} unless defined $attrs->{_ordered_for_collapse};
if (! $attrs->{_ordered_for_collapse}) {
- $fetch_all = 1;
+ $did_fetch_all = 1;
# instead of looping over ->next, use ->all in stealth mode
# *without* calling a ->reset afterwards
}
}
- if (! $fetch_all and ! @{$rows||[]} ) {
+ if (! $did_fetch_all and ! @{$rows||[]} ) {
# FIXME SUBOPTIMAL - we can do better, cursor->next/all (well diff. methods) should return a ref
if (scalar (my @r = $cursor->next) ) {
$rows = [ \@r ];
return undef unless @{$rows||[]};
my @extra_collapser_args;
- if ($attrs->{collapse} and ! $fetch_all ) {
+ if ($attrs->{collapse} and ! $did_fetch_all ) {
@extra_collapser_args = (
# FIXME SUBOPTIMAL - we can do better, cursor->next/all (well diff. methods) should return a ref
$_ = $inflator_cref->($res_class, $rsrc, @$_) for @$rows;
}
+ # The @$rows check seems odd at first - why wouldn't we want to warn
+ # regardless? The issue is things like find() etc, where the user
+ # *knows* only one result will come back. In these cases the ->all
+ # is not a pessimization, but rather something we actually want
+ carp_unique(
+ 'Unable to properly collapse has_many results in iterator mode due '
+ . 'to order criteria - performed an eager cursor slurp underneath. '
+ . 'Consider using ->all() instead'
+ ) if ( ! $fetch_all and @$rows > 1 );
+
return $rows;
}
);
is ($most_tracks_rs->count, 2, 'Limit works');
- my $top_cd = $most_tracks_rs->first;
+ my ($top_cd) = $most_tracks_rs->all;
is ($top_cd->id, 2, 'Correct cd fetched on top'); # 2 because of the slice(1,1) earlier
my $query_cnt = 0;
);
is ($rs->count, 2, 'Correct number of collapsed artists');
- my $we_are_goth = $rs->first;
+ my ($we_are_goth) = $rs->all;
is ($we_are_goth->name, 'We Are Goth', 'Correct first artist');
is ($we_are_goth->cds->count, 1, 'Correct number of CDs for first artist');
is ($we_are_goth->cds->first->title, 'Come Be Depressed With Us', 'Correct cd for artist');
use warnings;
use Test::More;
+use Test::Warn;
use Test::Exception;
use lib qw(t/lib);
use DBICTest;
is ($rs->{_stashed_rows}, undef, 'Nothing else left in $rs stash');
my $unordered_rs = $rs->search({}, { order_by => 'cds.title' });
-ok ($unordered_rs->next, 'got row 1');
+
+warnings_exist {
+ ok ($unordered_rs->next, 'got row 1');
+} qr/performed an eager cursor slurp underneath/, 'Warned on auto-eager cursor';
+
is_deeply ([$unordered_rs->cursor->next], [], 'Nothing left on cursor, eager slurp');
ok ($unordered_rs->next, "got row $_") for (2 .. $initial_artists_cnt + 3);
is ($unordered_rs->next, undef, 'End of RS reached');
use Test::More;
use Test::Deep;
+use Test::Warn;
use Test::Exception;
use lib qw(t/lib);
use DBICTest;
);
TODO: {
- my $row = $rs->next;
+ my ($row) = $rs->all;
local $TODO = 'Something is wrong with filter type rels, they throw on incomplete objects >.<';
lives_ok {
} 'no exception';
}
-is ($rs->cursor->next, undef, 'cursor exhausted');
-
-
TODO: {
local $TODO = 'this does not work at all, need to promote rsattrs to an object on its own';
# make sure has_many column redirection does not do weird stuff when collapse is requested
for my $use_next (0, 1) {
my @random_cds;
if ($use_next) {
- while (my $o = $rs_random->next) {
- push @random_cds, $o;
- }
+ warnings_exist {
+ while (my $o = $rs_random->next) {
+ push @random_cds, $o;
+ }
+ } qr/performed an eager cursor slurp underneath/,
+ 'Warned on auto-eager cursor';
}
else {
@random_cds = $rs_random->all;