is ($rs->count, 10, '10 artists present');
- my $orig_debug = $schema->storage->debug;
- $schema->storage->debug(1);
- my $query_count;
- $schema->storage->debugcb(sub { $query_count++ });
-
- $query_count = 0;
- $complex_rs->delete;
-
- is ($query_count, 1, 'One delete query fired');
+ $schema->is_executed_querycount( sub {
+ $complex_rs->delete;
+ }, 1, 'One delete query fired' );
is ($rs->count, 0, '10 Artists correctly deleted');
$rs->create({
});
is ($rs->count, 1, 'Artist with cd created');
- $query_count = 0;
- $schema->resultset('CD')->search_related('artist',
- { 'artist.name' => { -like => 'baby_with_%' } }
- )->delete;
- is ($query_count, 1, 'And one more delete query fired');
- is ($rs->count, 0, 'Artist with cd deleted');
- $schema->storage->debugcb(undef);
- $schema->storage->debug($orig_debug);
+ $schema->is_executed_querycount( sub {
+ $schema->resultset('CD')->search_related('artist',
+ { 'artist.name' => { -like => 'baby_with_%' } }
+ )->delete;
+ }, 1, 'And one more delete query fired');
+ is ($rs->count, 0, 'Artist with cd deleted');
}
ZEROINSEARCH: {
lives_ok {
is_deeply (
$arr_rs->search({ arrayfield => { '=' => { -value => [3,4] }} })->first->arrayfield,
- [3,4],,
+ [3,4],
'Array value matches explicit equal'
);
} 'searching by arrayref (explicit equal sign)';
. ': https://rt.cpan.org/Ticket/Display.html?id=64206'
if $q;
- # so we can disable BLOB mega-output
- my $orig_debug = $schema->storage->debug;
-
my $id;
foreach my $size (qw( small large )) {
$id++;
- local $schema->storage->{debug} = $size eq 'large'
- ? 0
- : $orig_debug
- ;
+ local $schema->storage->{debug} = 0
+ if $size eq 'large';
my $str = $binstr{$size};
lives_ok {
@objs = $rs->search({ blob => "re-updated blob", clob => 're-updated clob' })->all;
is @objs, 0, 'row deleted successfully';
}
-
- $schema->storage->debug ($orig_debug);
}
do_clean ($dbh);
is ($limited_rs->count, 6, "$test_type: Correct count of limited right-sorted joined resultset");
is ($limited_rs->count_rs->next, 6, "$test_type: Correct count_rs of limited right-sorted joined resultset");
- my $queries;
- my $orig_debug = $schema->storage->debug;
- $schema->storage->debugcb(sub { $queries++; });
- $schema->storage->debug(1);
-
- is_deeply (
- [map { $_->owner->name } ($limited_rs->all) ],
- [@owner_names[2 .. 7]],
- "$test_type: Prefetch-limited rows were properly ordered"
- );
- is ($queries, 1, "$test_type: Only one query with prefetch");
-
- $schema->storage->debugcb(undef);
- $schema->storage->debug($orig_debug);
+ $schema->is_executed_querycount( sub {
+ is_deeply (
+ [map { $_->owner->name } ($limited_rs->all) ],
+ [@owner_names[2 .. 7]],
+ "$test_type: Prefetch-limited rows were properly ordered"
+ );
+ }, 1, "$test_type: Only one query with prefetch" );
is_deeply (
[map { $_->name } ($limited_rs->search_related ('owner')->all) ],
my $rs = $schema->resultset('VaryingMAX');
foreach my $size (qw/small large/) {
- my $orig_debug = $schema->storage->debug;
-
- $schema->storage->debug(0) if $size eq 'large';
+ local $schema->storage->{debug} = 0 if $size eq 'large';
my $str = $binstr{$size};
my $row;
cmp_ok try { $row->varchar_max }, 'eq', $str, 'VARCHAR(MAX) matches';
cmp_ok try { $row->nvarchar_max }, 'eq', $str, 'NVARCHAR(MAX) matches';
cmp_ok try { $row->varbinary_max }, 'eq', $str, 'VARBINARY(MAX) matches';
-
- $schema->storage->debug($orig_debug);
}
# test regular blobs
my $schema = DBICTest->init_schema();
-my $orig_debug = $schema->storage->debug;
-
# test the abstract join => SQL generator
-my $sa = new DBIx::Class::SQLMaker;
+my $sa = DBIx::Class::SQLMaker->new;
my @j = (
{ child => 'person' },
my $schema = DBICTest->init_schema();
-my $queries;
-my $debugcb = sub{ $queries++ };
-my $sdebug = $schema->storage->debug;
-
-plan tests => 23;
-
my $rs = $schema->resultset("Artist")->search(
{ artistid => 1 }
);
$rs->clear_cache;
-$queries = 0;
-$schema->storage->debug(1);
-$schema->storage->debugcb ($debugcb);
-
-$rs = $schema->resultset('Artist')->search( undef, { cache => 1 } );
-while( $artist = $rs->next ) {}
-$artist = $rs->first();
-
-is( $queries, 1, 'revisiting a row does not issue a query when cache => 1' );
+$schema->is_executed_querycount( sub {
-$schema->storage->debug($sdebug);
-$schema->storage->debugcb (undef);
+ $rs = $schema->resultset('Artist')->search( undef, { cache => 1 } );
+ while( $artist = $rs->next ) {}
+ $artist = $rs->first();
+}, 1, 'revisiting a row does not issue a query when cache => 1' );
my @a = $schema->resultset("Artist")->search(
{ },
}
);
-# start test for prefetch SELECT count
-$queries = 0;
-$schema->storage->debug(1);
-$schema->storage->debugcb ($debugcb);
-
-$artist = $rs->first;
-$rs->reset();
+# prefetch SELECT count
+$schema->is_executed_querycount( sub {
+ $artist = $rs->first;
+ $rs->reset();
-# make sure artist contains a related resultset for cds
-isa_ok( $artist->{related_resultsets}{cds}, 'DBIx::Class::ResultSet', 'artist has a related_resultset for cds' );
+ # make sure artist contains a related resultset for cds
+ isa_ok( $artist->{related_resultsets}{cds}, 'DBIx::Class::ResultSet', 'artist has a related_resultset for cds' );
-# check if $artist->cds->get_cache is populated
-is( scalar @{$artist->cds->get_cache}, 3, 'cache for artist->cds contains correct number of records');
+ # check if $artist->cds->get_cache is populated
+ is( scalar @{$artist->cds->get_cache}, 3, 'cache for artist->cds contains correct number of records');
-# ensure that $artist->cds returns correct number of objects
-is( scalar ($artist->cds), 3, 'artist->cds returns correct number of objects' );
+ # ensure that $artist->cds returns correct number of objects
+ is( scalar ($artist->cds), 3, 'artist->cds returns correct number of objects' );
-# ensure that $artist->cds->count returns correct value
-is( $artist->cds->count, 3, 'artist->cds->count returns correct value' );
+ # ensure that $artist->cds->count returns correct value
+ is( $artist->cds->count, 3, 'artist->cds->count returns correct value' );
-# ensure that $artist->count_related('cds') returns correct value
-is( $artist->count_related('cds'), 3, 'artist->count_related returns correct value' );
+ # ensure that $artist->count_related('cds') returns correct value
+ is( $artist->count_related('cds'), 3, 'artist->count_related returns correct value' );
-is($queries, 1, 'only one SQL statement executed');
+}, 1, 'only one SQL statement executed');
-$schema->storage->debug($sdebug);
-$schema->storage->debugcb (undef);
# make sure related_resultset is deleted after object is updated
$artist->set_column('name', 'New Name');
}
# SELECT count for nested has_many prefetch
-$queries = 0;
-$schema->storage->debug(1);
-$schema->storage->debugcb ($debugcb);
-
-$artist = ($rs->all)[0];
-
-is($queries, 1, 'only one SQL statement executed');
-
-$queries = 0;
-
-my @objs;
-my $cds = $artist->cds;
-my $tags = $cds->next->tags;
-while( my $tag = $tags->next ) {
- push @objs, $tag->tagid; #warn "tag:", $tag->ID, " => ", $tag->tag;
-}
-
-is_deeply( \@objs, [ 3 ], 'first cd has correct tags' );
-
-$tags = $cds->next->tags;
-@objs = ();
-while( my $tag = $tags->next ) {
- push @objs, $tag->id; #warn "tag: ", $tag->ID;
-}
-
-is_deeply( [ sort @objs] , [ 2, 5, 8 ], 'third cd has correct tags' );
-
-$tags = $cds->next->tags;
-@objs = ();
-while( my $tag = $tags->next ) {
- push @objs, $tag->id; #warn "tag: ", $tag->ID;
-}
-
-is_deeply( \@objs, [ 1 ], 'second cd has correct tags' );
+$schema->is_executed_querycount( sub {
+ $artist = ($rs->all)[0];
+}, 1, 'only one SQL statement executed');
+
+$schema->is_executed_querycount( sub {
+ my @objs;
+ my $cds = $artist->cds;
+ my $tags = $cds->next->tags;
+ while( my $tag = $tags->next ) {
+ push @objs, $tag->tagid; #warn "tag:", $tag->ID, " => ", $tag->tag;
+ }
-is( $queries, 0, 'no additional SQL statements while checking nested data' );
+ is_deeply( \@objs, [ 3 ], 'first cd has correct tags' );
-# start test for prefetch SELECT count
-$queries = 0;
+ $tags = $cds->next->tags;
+ @objs = ();
+ while( my $tag = $tags->next ) {
+ push @objs, $tag->id; #warn "tag: ", $tag->ID;
+ }
-$artist = $schema->resultset('Artist')->find(1, { prefetch => [qw/cds/] });
+ is_deeply( [ sort @objs] , [ 2, 5, 8 ], 'third cd has correct tags' );
-is( $queries, 1, 'only one select statement on find with inline has_many prefetch' );
+ $tags = $cds->next->tags;
+ @objs = ();
+ while( my $tag = $tags->next ) {
+ push @objs, $tag->id; #warn "tag: ", $tag->ID;
+ }
-# start test for prefetch SELECT count
-$queries = 0;
+ is_deeply( \@objs, [ 1 ], 'second cd has correct tags' );
+}, 0, 'no additional SQL statements while checking nested data' );
-$rs = $schema->resultset('Artist')->search(undef, { prefetch => [qw/cds/] });
-$artist = $rs->find(1);
+$schema->is_executed_querycount( sub {
+ $artist = $schema->resultset('Artist')->find(1, { prefetch => [qw/cds/] });
+}, 1, 'only one select statement on find with inline has_many prefetch' );
-is( $queries, 1, 'only one select statement on find with has_many prefetch on resultset' );
+$schema->is_executed_querycount( sub {
+ $rs = $schema->resultset('Artist')->search(undef, { prefetch => [qw/cds/] });
+ $artist = $rs->find(1);
+}, 1, 'only one select statement on find with has_many prefetch on resultset' );
-$schema->storage->debug($sdebug);
-$schema->storage->debugcb (undef);
+done_testing;
# Test resultsource with cached rows
- my $query_count;
- $cd_rs = $cd_rs->search ({}, { cache => 1 });
+ $schema->is_executed_querycount( sub {
+ $cd_rs = $cd_rs->search ({}, { cache => 1 });
- my $orig_debug = $schema->storage->debug;
- $schema->storage->debug(1);
- $schema->storage->debugcb(sub { $query_count++ } );
+ # this will hit the database once and prime the cache
+ my @cds = $cd_rs->all;
- # this will hit the database once and prime the cache
- my @cds = $cd_rs->all;
-
- lives_ok {
$copy = $store->($cd_rs);
ref_ne($copy, $cd_rs, 'Cached resultset cloned');
is_deeply (
);
is ($copy->count, $cd_rs->count, 'Cached count identical');
- } "serialize cached resultset lives: $name";
-
- is ($query_count, 1, 'Only one db query fired');
-
- $schema->storage->debug($orig_debug);
- $schema->storage->debugcb(undef);
+ }, 1, 'Only one db query fired');
}
# test schema-less detached thaw
my $schema = DBICTest->init_schema();
-my $queries;
-$schema->storage->debugcb( sub{ $queries++ } );
-my $sdebug = $schema->storage->debug;
-
my $cd = $schema->resultset("CD")->find(1);
$cd->title('test');
-# SELECT count
-$queries = 0;
-$schema->storage->debug(1);
-
-$cd->update;
-
-is($queries, 1, 'liner_notes (might_have) not prefetched - do not load
-liner_notes on update');
-
-$schema->storage->debug($sdebug);
-
+$schema->is_executed_querycount( sub {
+ $cd->update;
+}, {
+ BEGIN => 1,
+ UPDATE => 1,
+ COMMIT => 1,
+}, 'liner_notes (might_have) not prefetched - do not load liner_notes on update' );
my $cd2 = $schema->resultset("CD")->find(2, {prefetch => 'liner_notes'});
$cd2->title('test2');
-# SELECT count
-$queries = 0;
-$schema->storage->debug(1);
-
-$cd2->update;
-
-is($queries, 1, 'liner_notes (might_have) prefetched - do not load
-liner_notes on update');
+$schema->is_executed_querycount( sub {
+ $cd2->update;
+}, {
+ BEGIN => 1,
+ UPDATE => 1,
+ COMMIT => 1,
+}, 'liner_notes (might_have) prefetched - do not load liner_notes on update');
warning_like {
local $ENV{DBIC_DONT_VALIDATE_RELS};
'Setting DBIC_DONT_VALIDATE_RELS suppresses nullable relation warnings';
}
-$schema->storage->debug($sdebug);
done_testing();
local $self->storage->{debugobj} = my $tracer_obj = DBICTest::SQLTracerObj->new;
local $self->storage->{debug} = 1;
-
+ local $Test::Builder::Level = $Test::Builder::Level + 2;
$cref->();
return $tracer_obj->{sqlbinds} || [];
}
+sub is_executed_querycount {
+ my ($self, $cref, $exp_counts, $msg) = @_;
+
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+
+ $self->throw_exception("Expecting an hashref of counts or an integer representing total query count")
+ unless ref $exp_counts eq 'HASH' or (defined $exp_counts and ! ref $exp_counts);
+
+ my @got = map { $_->[0] } @{ $self->capture_executed_sql_bind($cref) };
+
+ return Test::More::is( @got, $exp_counts, $msg )
+ unless ref $exp_counts;
+
+ my $got_counts = { map { $_ => 0 } keys %$exp_counts };
+ $got_counts->{$_}++ for @got;
+
+ return Test::More::is_deeply(
+ $got_counts,
+ $exp_counts,
+ $msg,
+ );
+}
+
sub is_executed_sql_bind {
my ($self, $cref, $sqlbinds, $msg) = @_;
use DBIC::SqlMakerTest;
my $schema = DBICTest->init_schema();
-my $orig_debug = $schema->storage->debug;
my $cdrs = $schema->resultset('CD')->search({ 'me.artist' => { '!=', 2 }});
'Expected SQL on correlated realiased subquery'
);
-my $queries = 0;
-$schema->storage->debugcb(sub { $queries++; });
-$schema->storage->debug(1);
-
-cmp_deeply (
- { map
- { $_->cdid => {
- track_titles => [ map { $_->title } ($_->tracks->all) ],
- siblings => $_->get_column ('sibling_count'),
- } }
- $c_rs->all
- },
- $cd_data,
- 'Proper information retrieved from correlated subquery'
-);
-
-is ($queries, 1, 'Only 1 query fired to retrieve everything');
-
-$schema->storage->debug($orig_debug);
-$schema->storage->debugcb(undef);
+$schema->is_executed_querycount( sub {
+ cmp_deeply (
+ { map
+ { $_->cdid => {
+ track_titles => [ map { $_->title } ($_->tracks->all) ],
+ siblings => $_->get_column ('sibling_count'),
+ } }
+ $c_rs->all
+ },
+ $cd_data,
+ 'Proper information retrieved from correlated subquery'
+ );
+}, 1, 'Only 1 query fired to retrieve everything');
# now add an unbalanced select/as pair
$c_rs = $c_rs->search ({}, {
use DBICTest;
use DBIC::SqlMakerTest;
-plan tests => 23;
-
my $schema = DBICTest->init_schema();
my $cd_rs = $schema->resultset('CD')->search (
{ prefetch => ['tracks', 'artist'] },
);
-
is($cd_rs->count, 5, 'CDs with tracks count');
is($cd_rs->search_related('tracks')->count, 15, 'Tracks associated with CDs count (before SELECT()ing)');
=> 4 ] ],
);
-
{
local $TODO = "Chaining with prefetch is fundamentally broken";
+ $schema->is_executed_querycount( sub {
- my $queries;
- $schema->storage->debugcb ( sub { $queries++ } );
- $schema->storage->debug (1);
-
- my $cds = $cd2->search_related ('artist', {}, { prefetch => { cds => 'tracks' }, join => 'twokeys' })
+ my $cds = $cd2->search_related ('artist', {}, { prefetch => { cds => 'tracks' }, join => 'twokeys' })
->search_related ('cds');
- my $tracks = $cds->search_related ('tracks');
-
- is($tracks->count, 2, "2 Tracks counted on cd via artist via one of the cds");
- is(scalar($tracks->all), 2, "2 Tracks prefetched on cd via artist via one of the cds");
- is($tracks->count, 2, "Cached 2 Tracks counted on cd via artist via one of the cds");
+ my $tracks = $cds->search_related ('tracks');
- is($cds->count, 2, "2 CDs counted on artist via one of the cds");
- is(scalar($cds->all), 2, "2 CDs prefetched on artist via one of the cds");
- is($cds->count, 2, "Cached 2 CDs counted on artist via one of the cds");
+ is($tracks->count, 2, "2 Tracks counted on cd via artist via one of the cds");
+ is(scalar($tracks->all), 2, "2 Tracks prefetched on cd via artist via one of the cds");
+ is($tracks->count, 2, "Cached 2 Tracks counted on cd via artist via one of the cds");
- is ($queries, 3, '2 counts + 1 prefetch?');
+ is($cds->count, 2, "2 CDs counted on artist via one of the cds");
+ is(scalar($cds->all), 2, "2 CDs prefetched on artist via one of the cds");
+ is($cds->count, 2, "Cached 2 CDs counted on artist via one of the cds");
+ }, 3, '2 counts + 1 prefetch?' );
}
+
+done_testing;
},
});
-my $orig_debug = $schema->storage->debug;
-
-my $queries = 0;
-$schema->storage->debugcb(sub { $queries++; });
-$schema->storage->debug(1);
-
-my $cd = $schema->resultset('CD')->search( {}, { prefetch => 'artist' })->next;
-
-cmp_deeply
- { $cd->get_columns },
- { artist => 0, cdid => 0, genreid => 0, single_track => 0, title => '', year => 0 },
- 'Expected CD columns present',
-;
-
-cmp_deeply
- { $cd->artist->get_columns },
- { artistid => 0, charfield => 0, name => "", rank => 0 },
- 'Expected Artist columns present',
-;
-
-is $queries, 1, 'Only one query fired - prefetch worked';
-
-$schema->storage->debugcb(undef);
-$schema->storage->debug($orig_debug);
+$schema->is_executed_querycount( sub {
+ my $cd = $schema->resultset('CD')->search( {}, { prefetch => 'artist' })->next;
+
+ cmp_deeply
+ { $cd->get_columns },
+ { artist => 0, cdid => 0, genreid => 0, single_track => 0, title => '', year => 0 },
+ 'Expected CD columns present',
+ ;
+
+ cmp_deeply
+ { $cd->artist->get_columns },
+ { artistid => 0, charfield => 0, name => "", rank => 0 },
+ 'Expected Artist columns present',
+ ;
+}, 1, 'Only one query fired - prefetch worked' );
done_testing;
my $OFFSET = DBIx::Class::SQLMaker::LimitDialects->__offset_bindtype;
my $schema = DBICTest->init_schema();
-my $sdebug = $schema->storage->debug;
my $cd_rs = $schema->resultset('CD')->search (
{ 'tracks.cd' => { '!=', undef } },
is($track_rs->count, 5, 'Prefetched count with groupby');
is($track_rs->all, 5, 'Prefetched objects with groupby');
- {
- my $query_cnt = 0;
- $schema->storage->debugcb ( sub { $query_cnt++ } );
- $schema->storage->debug (1);
-
+ $schema->is_executed_querycount( sub {
while (my $collapsed_track = $track_rs->next) {
my $cdid = $collapsed_track->get_column('cd');
is($collapsed_track->get_column('track_count'), 3, "Correct count of tracks for CD $cdid" );
ok($collapsed_track->cd->title, "Prefetched title for CD $cdid" );
}
-
- is ($query_cnt, 1, 'Single query on prefetched titles');
- $schema->storage->debugcb (undef);
- $schema->storage->debug ($sdebug);
- }
+ }, 1, 'Single query on prefetched titles');
# Test sql by hand, as the sqlite db will simply paper over
# improper group/select combinations
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;
- $schema->storage->debugcb ( sub { $query_cnt++ } );
- $schema->storage->debug (1);
-
- is ($top_cd->get_column ('track_count'), 4, 'Track count fetched correctly');
- is ($top_cd->tracks->count, 4, 'Count of prefetched tracks rs still correct');
- is ($top_cd->tracks->all, 4, 'Number of prefetched track objects still correct');
- is (
- $top_cd->liner_notes->notes,
- 'Buy Whiskey!',
- 'Correct liner pre-fetched with top cd',
- );
-
- is ($query_cnt, 0, 'No queries executed during prefetched data access');
- $schema->storage->debugcb (undef);
- $schema->storage->debug ($sdebug);
+ $schema->is_executed_querycount( sub {
+ is ($top_cd->get_column ('track_count'), 4, 'Track count fetched correctly');
+ is ($top_cd->tracks->count, 4, 'Count of prefetched tracks rs still correct');
+ is ($top_cd->tracks->all, 4, 'Number of prefetched track objects still correct');
+ is (
+ $top_cd->liner_notes->notes,
+ 'Buy Whiskey!',
+ 'Correct liner pre-fetched with top cd',
+ );
+ }, 0, 'No queries executed during prefetched data access');
}
{
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;
- $schema->storage->debugcb ( sub { $query_cnt++ } );
- $schema->storage->debug (1);
-
- is ($top_cd->get_column ('track_count'), 4, 'Track count fetched correctly');
- is (
- $top_cd->liner_notes->notes,
- 'Buy Whiskey!',
- 'Correct liner pre-fetched with top cd',
- );
-
- is ($query_cnt, 0, 'No queries executed during prefetched data access');
- $schema->storage->debugcb (undef);
- $schema->storage->debug ($sdebug);
+ $schema->is_executed_querycount( sub {
+ is ($top_cd->get_column ('track_count'), 4, 'Track count fetched correctly');
+ is (
+ $top_cd->liner_notes->notes,
+ 'Buy Whiskey!',
+ 'Correct liner pre-fetched with top cd',
+ );
+ }, 0, 'No queries executed during prefetched data access');
}
for @lines;
}
-{
- my $queries = 0;
- $schema->storage->debugcb(sub { $queries++ });
- my $orig_debug = $schema->storage->debug;
- $schema->storage->debug (1);
-
+$schema->is_executed_querycount( sub {
for my $use_next (0, 1) {
my @random_cds;
+ my $rs_r = $rs_random;
if ($use_next) {
warnings_exist {
- while (my $o = $rs_random->next) {
+ while (my $o = $rs_r->next) {
push @random_cds, $o;
}
} qr/performed an eager cursor slurp underneath/,
'Warned on auto-eager cursor';
}
else {
- @random_cds = $rs_random->all;
+ @random_cds = $rs_r->all;
}
is (@random_cds, 6, 'object count matches');
}
}
}
-
- $schema->storage->debugcb(undef);
- $schema->storage->debug($orig_debug);
- is ($queries, 2, "Only two queries for two prefetch calls total");
-}
+}, 2, "Only two queries for two prefetch calls total");
# can't cmp_deeply a random set - need *some* order
my $ord_rs = $rs->search({}, {
use warnings;
use Test::More;
+use Test::Warn;
use lib qw(t/lib);
use DBICTest;
my $schema = DBICTest->init_schema();
-my $sdebug = $schema->storage->debug;
#( 1 -> M + M )
my $cd_rs = $schema->resultset('CD')->search( { 'me.title' => 'Forkful of bees' } );
my $tracks_rs = $cd_rs->first->tracks;
my $tracks_count = $tracks_rs->count;
-my ( $pr_tracks_rs, $pr_tracks_count );
+$schema->is_executed_querycount( sub {
+ my $pcr = $pr_cd_rs;
+ my $pr_tracks_rs;
-my $queries = 0;
-$schema->storage->debugcb( sub { $queries++ } );
-$schema->storage->debug(1);
+ warnings_exist {
+ $pr_tracks_rs = $pcr->first->tracks;
+ } [], 'no warning on attempt to prefetch several same level has_many\'s (1 -> M + M)' ;
-my $o_mm_warn;
-{
- local $SIG{__WARN__} = sub { $o_mm_warn = shift };
- $pr_tracks_rs = $pr_cd_rs->first->tracks;
-};
-$pr_tracks_count = $pr_tracks_rs->count;
+ is( $pr_tracks_rs->count, $tracks_count,
+ 'equal count of prefetched relations over several same level has_many\'s (1 -> M + M)'
+ );
-ok( !$o_mm_warn,
-'no warning on attempt to prefetch several same level has_many\'s (1 -> M + M)'
-);
+ is( $pr_tracks_rs->all, $tracks_count,
+ 'equal amount of objects returned with and without prefetch over several same level has_many\'s (1 -> M + M)'
+ );
-is( $queries, 1, 'prefetch one->(has_many,has_many) ran exactly 1 query' );
-$schema->storage->debugcb(undef);
-$schema->storage->debug($sdebug);
+}, 1, 'prefetch one->(has_many,has_many) ran exactly 1 query' );
-is( $pr_tracks_count, $tracks_count,
-'equal count of prefetched relations over several same level has_many\'s (1 -> M + M)'
-);
-is( $pr_tracks_rs->all, $tracks_rs->all,
-'equal amount of objects returned with and without prefetch over several same level has_many\'s (1 -> M + M)'
-);
#( M -> 1 -> M + M )
my $note_rs =
my $tags_rs = $note_rs->first->cd->tags;
my $tags_count = $tags_rs->count;
-my ( $pr_tags_rs, $pr_tags_count );
-
-$queries = 0;
-$schema->storage->debugcb( sub { $queries++ } );
-$schema->storage->debug(1);
-
-my $m_o_mm_warn;
-{
- local $SIG{__WARN__} = sub { $m_o_mm_warn = shift };
- $pr_tags_rs = $pr_note_rs->first->cd->tags;
-};
-$pr_tags_count = $pr_tags_rs->count;
-
-ok( !$m_o_mm_warn,
-'no warning on attempt to prefetch several same level has_many\'s (M -> 1 -> M + M)'
-);
-
-is( $queries, 1, 'prefetch one->(has_many,has_many) ran exactly 1 query' );
-$schema->storage->debugcb(undef);
-$schema->storage->debug($sdebug);
-
-is( $pr_tags_count, $tags_count,
-'equal count of prefetched relations over several same level has_many\'s (M -> 1 -> M + M)'
-);
-is( $pr_tags_rs->all, $tags_rs->all,
-'equal amount of objects with and without prefetch over several same level has_many\'s (M -> 1 -> M + M)'
-);
+$schema->is_executed_querycount( sub {
+ my $pnr = $pr_note_rs;
+ my $pr_tags_rs;
+
+ warnings_exist {
+ $pr_tags_rs = $pnr->first->cd->tags;
+ } [], 'no warning on attempt to prefetch several same level has_many\'s (M -> 1 -> M + M)';
+
+ is( $pr_tags_rs->count, $tags_count,
+ 'equal count of prefetched relations over several same level has_many\'s (M -> 1 -> M + M)'
+ );
+ is( $pr_tags_rs->all, $tags_count,
+ 'equal amount of objects with and without prefetch over several same level has_many\'s (M -> 1 -> M + M)'
+ );
+
+}, 1, 'prefetch one->(has_many,has_many) ran exactly 1 query' );
+
done_testing;
is ($artist->cds->count, 3, 'Correct number of CDs');
is ($artist->cds->search_related ('genre')->count, 1, 'Only one of the cds has a genre');
-my $queries = 0;
-my $orig_cb = $schema->storage->debugcb;
-$schema->storage->debugcb(sub { $queries++ });
-$schema->storage->debug(1);
-
-my $pref = $schema->resultset ('Artist')
+$schema->is_executed_querycount( sub {
+ my $pref = $schema->resultset ('Artist')
->search ({ 'me.artistid' => $artist->id }, { prefetch => { cds => 'genre' } })
->next;
-is ($pref->cds->count, 3, 'Correct number of CDs prefetched');
-is ($pref->cds->search_related ('genre')->count, 1, 'Only one of the prefetched cds has a prefetched genre');
+ is ($pref->cds->count, 3, 'Correct number of CDs prefetched');
+ is ($pref->cds->search_related ('genre')->count, 1, 'Only one of the prefetched cds has a prefetched genre');
-is ($queries, 1, 'All happened within one query only');
-$schema->storage->debugcb($orig_cb);
-$schema->storage->debug(0);
+}, 1, 'All happened within one query only');
done_testing;
);
# this still should emit no queries:
-{
- my $queries = 0;
- my $orig_debug = $schema->storage->debug;
- $schema->storage->debugcb(sub { $queries++; });
- $schema->storage->debug(1);
+$schema->is_executed_querycount( sub {
my $cds = $art->cds;
is (
);
}
- $schema->storage->debug($orig_debug);
- $schema->storage->debugcb(undef);
-
- is ($queries, 0, 'No queries on prefetched operations');
-}
+}, 0, 'No queries on prefetched operations');
done_testing;
use DBICTest;
my $schema = DBICTest->init_schema();
-my $orig_debug = $schema->storage->debug;
-my $queries = 0;
-$schema->storage->debugcb(sub { $queries++; });
-$schema->storage->debug(1);
-
-my $search = { 'artist.name' => 'Caterwauler McCrae' };
-my $attr = { prefetch => [ qw/artist liner_notes/ ],
+my $rs;
+$schema->is_executed_querycount( sub {
+ my $search = { 'artist.name' => 'Caterwauler McCrae' };
+ my $attr = { prefetch => [ qw/artist liner_notes/ ],
order_by => 'me.cdid' };
-my $rs = $schema->resultset("CD")->search($search, $attr);
-my @cd = $rs->all;
-
-is($cd[0]->title, 'Spoonful of bees', 'First record returned ok');
+ $rs = $schema->resultset("CD")->search($search, $attr);
+ my @cd = $rs->all;
-ok(!defined $cd[0]->liner_notes, 'No prefetch for NULL LEFT join');
+ is($cd[0]->title, 'Spoonful of bees', 'First record returned ok');
-is($cd[1]->{_relationship_data}{liner_notes}->notes, 'Buy Whiskey!', 'Prefetch for present LEFT JOIN');
+ ok(!defined $cd[0]->liner_notes, 'No prefetch for NULL LEFT join');
-is(ref $cd[1]->liner_notes, 'DBICTest::LinerNotes', 'Prefetch returns correct class');
+ is($cd[1]->{_relationship_data}{liner_notes}->notes, 'Buy Whiskey!', 'Prefetch for present LEFT JOIN');
-is($cd[2]->{_inflated_column}{artist}->name, 'Caterwauler McCrae', 'Prefetch on parent object ok');
+ is(ref $cd[1]->liner_notes, 'DBICTest::LinerNotes', 'Prefetch returns correct class');
-is($queries, 1, 'prefetch ran only 1 select statement');
-
-$schema->storage->debug($orig_debug);
-$schema->storage->debugobj->callback(undef);
+ is($cd[2]->{_inflated_column}{artist}->name, 'Caterwauler McCrae', 'Prefetch on parent object ok');
+}, 1, 'prefetch ran only 1 select statement');
# test for partial prefetch via columns attr
my $cd = $schema->resultset('CD')->find(1,
join => { 'artist' => {} }
}
);
-ok(eval { $cd->artist->name eq 'Caterwauler McCrae' }, 'single related column prefetched');
+is( $cd->artist->name, 'Caterwauler McCrae', 'single related column prefetched');
# start test for nested prefetch SELECT count
-$queries = 0;
-$schema->storage->debugcb(sub { $queries++ });
-$schema->storage->debug(1);
-
-$rs = $schema->resultset('Tag')->search(
- { 'me.tagid' => 1 },
- {
- prefetch => { cd => 'artist' }
- }
-);
-
-my $tag = $rs->first;
+my $tag;
+$schema->is_executed_querycount( sub {
+ $rs = $schema->resultset('Tag')->search(
+ { 'me.tagid' => 1 },
+ {
+ prefetch => { cd => 'artist' }
+ }
+ );
-is( $tag->cd->title, 'Spoonful of bees', 'step 1 ok for nested prefetch' );
+ $tag = $rs->first;
-is( $tag->cd->artist->name, 'Caterwauler McCrae', 'step 2 ok for nested prefetch');
+ is( $tag->cd->title, 'Spoonful of bees', 'step 1 ok for nested prefetch' );
-# count the SELECTs
-#$selects++ if /SELECT(?!.*WHERE 1=0.*)/;
-is($queries, 1, 'nested prefetch ran exactly 1 select statement (excluding column_info)');
+ is( $tag->cd->artist->name, 'Caterwauler McCrae', 'step 2 ok for nested prefetch');
+}, 1, 'nested prefetch ran exactly 1 select statement');
-$queries = 0;
-is($tag->search_related('cd')->search_related('artist')->first->name,
+$schema->is_executed_querycount( sub {
+ is($tag->search_related('cd')->search_related('artist')->first->name,
'Caterwauler McCrae',
'chained belongs_to->belongs_to search_related ok');
+}, 0, 'chained search_related after belongs_to->belongs_to prefetch ran no queries');
-is($queries, 0, 'chained search_related after belontgs_to->belongs_to prefetch ran no queries');
-
-$queries = 0;
-
-$cd = $schema->resultset('CD')->find(1, { prefetch => 'artist' });
-is($cd->{_inflated_column}{artist}->name, 'Caterwauler McCrae', 'artist prefetched correctly on find');
+$schema->is_executed_querycount( sub {
+ $cd = $schema->resultset('CD')->find(1, { prefetch => 'artist' });
-is($queries, 1, 'find with prefetch ran exactly 1 select statement (excluding column_info)');
+ is($cd->{_inflated_column}{artist}->name, 'Caterwauler McCrae', 'artist prefetched correctly on find');
+}, 1, 'find with prefetch ran exactly 1 select statement (excluding column_info)');
-$queries = 0;
+$schema->is_executed_querycount( sub {
+ $cd = $schema->resultset('CD')->find(1, { prefetch => { cd_to_producer => 'producer' }, order_by => 'producer.producerid' });
-$schema->storage->debugcb(sub { $queries++; });
+ is($cd->producers->first->name, 'Matt S Trout', 'many_to_many accessor ok');
+}, 1, 'many_to_many accessor with nested prefetch ran exactly 1 query');
-$cd = $schema->resultset('CD')->find(1, { prefetch => { cd_to_producer => 'producer' }, order_by => 'producer.producerid' });
+$schema->is_executed_querycount( sub {
+ my $producers = $cd->search_related('cd_to_producer')->search_related('producer');
-is($cd->producers->first->name, 'Matt S Trout', 'many_to_many accessor ok');
-
-is($queries, 1, 'many_to_many accessor with nested prefetch ran exactly 1 query');
-
-$queries = 0;
-
-my $producers = $cd->search_related('cd_to_producer')->search_related('producer');
-
-is($producers->first->name, 'Matt S Trout', 'chained many_to_many search_related ok');
-
-is($queries, 0, 'chained search_related after many_to_many prefetch ran no queries');
-
-$schema->storage->debug($orig_debug);
-$schema->storage->debugobj->callback(undef);
+ is($producers->first->name, 'Matt S Trout', 'chained many_to_many search_related ok');
+}, 0, 'chained search_related after many_to_many prefetch ran no queries');
$rs = $schema->resultset('Tag')->search(
{},
cmp_ok($left_join, '==', 1, 'prefetch with no join record present');
-$queries = 0;
-$schema->storage->debugcb(sub { $queries++ });
-$schema->storage->debug(1);
-
-my $tree_like =
- $schema->resultset('TreeLike')->find(5,
- { join => { parent => { parent => 'parent' } },
+my $tree_like;
+$schema->is_executed_querycount( sub {
+ $tree_like =
+ $schema->resultset('TreeLike')->find(5,
+ { join => { parent => { parent => 'parent' } },
prefetch => { parent => { parent => 'parent' } } });
-is($tree_like->name, 'quux', 'Bottom of tree ok');
-$tree_like = $tree_like->parent;
-is($tree_like->name, 'baz', 'First level up ok');
-$tree_like = $tree_like->parent;
-is($tree_like->name, 'bar', 'Second level up ok');
-$tree_like = $tree_like->parent;
-is($tree_like->name, 'foo', 'Third level up ok');
+ is($tree_like->name, 'quux', 'Bottom of tree ok');
+ $tree_like = $tree_like->parent;
+ is($tree_like->name, 'baz', 'First level up ok');
+ $tree_like = $tree_like->parent;
+ is($tree_like->name, 'bar', 'Second level up ok');
+ $tree_like = $tree_like->parent;
+ is($tree_like->name, 'foo', 'Third level up ok');
-$schema->storage->debug($orig_debug);
-$schema->storage->debugobj->callback(undef);
-
-cmp_ok($queries, '==', 1, 'Only one query run');
+}, 1, 'Only one query run');
$tree_like = $schema->resultset('TreeLike')->search({'me.id' => 2});
$tree_like = $tree_like->search_related('children')->search_related('children')->search_related('children')->first;
{ 'children.id' => 3, 'children_2.id' => 4 },
{ prefetch => { children => 'children' } }
)->first;
-is(eval { $tree_like->children->first->children->first->name }, 'quux',
+is( $tree_like->children->first->children->first->name, 'quux',
'Tree search_related with prefetch ok');
-$tree_like = eval { $schema->resultset('TreeLike')->search(
+$tree_like = $schema->resultset('TreeLike')->search(
{ 'children.id' => 3, 'children_2.id' => 6 },
{ join => [qw/children children children/] }
)->search_related('children', { 'children_4.id' => 7 }, { prefetch => 'children' }
- )->first->children->first; };
-is(eval { $tree_like->name }, 'fong', 'Tree with multiple has_many joins ok');
+ )->first->children->first;
+is( $tree_like->name, 'fong', 'Tree with multiple has_many joins ok');
$rs = $schema->resultset('Artist');
$rs->create({ artistid => 4, name => 'Unknown singer-songwriter' });
return $struc;
}
-$queries = 0;
-$schema->storage->debugcb(sub { $queries++ });
-$schema->storage->debug(1);
-
-my $prefetch_result = make_hash_struc($art_rs_pr);
-is($queries, 1, 'nested prefetch across has_many->has_many ran exactly 1 query');
-
-my $nonpre_result = make_hash_struc($art_rs);
+my $prefetch_result;
+$schema->is_executed_querycount( sub {
+ $prefetch_result = make_hash_struc($art_rs_pr);
+}, 1, 'nested prefetch across has_many->has_many ran exactly 1 query');
+my $nonpre_result = make_hash_struc($art_rs);
is_deeply( $prefetch_result, $nonpre_result,
'Compare 2 level prefetch result to non-prefetch result' );
-$queries = 0;
-
-is_deeply(
- [ sort map { $_->title } $art_rs_pr->search_related('cds')->search_related('tracks')->all ],
- [ 'Apiary', 'Beehind You', 'Boring Name', 'Boring Song', 'Fowlin', 'Howlin',
- 'No More Ideas', 'Sad', 'Sticky Honey', 'Stripy', 'Stung with Success',
- 'Suicidal', 'The Bees Knees', 'Under The Weather', 'Yowlin' ],
- 'chained has_many->has_many search_related ok'
-);
-
-is($queries, 0, 'chained search_related after has_many->has_many prefetch ran no queries');
-
-$schema->storage->debug($orig_debug);
-$schema->storage->debugobj->callback(undef);
+$schema->is_executed_querycount( sub {
+ is_deeply(
+ [ sort map { $_->title } $art_rs_pr->search_related('cds')->search_related('tracks')->all ],
+ [ 'Apiary', 'Beehind You', 'Boring Name', 'Boring Song', 'Fowlin', 'Howlin',
+ 'No More Ideas', 'Sad', 'Sticky Honey', 'Stripy', 'Stung with Success',
+ 'Suicidal', 'The Bees Knees', 'Under The Weather', 'Yowlin' ],
+ 'chained has_many->has_many search_related ok'
+ );
+}, 0, 'chained search_related after has_many->has_many prefetch ran no queries');
done_testing;
my $schema = DBICTest->init_schema();
-my $queries;
-my $debugcb = sub { $queries++; };
-my $orig_debug = $schema->storage->debug;
-
lives_ok ( sub {
my $no_prefetch = $schema->resultset('Track')->search_related(cd =>
{
{
my $cd = $schema->resultset('CD')->search({}, { prefetch => 'cd_to_producer' })->find(1);
- $queries = 0;
- $schema->storage->debugcb ($debugcb);
- $schema->storage->debug (1);
-
- is( $cd->cd_to_producer->count, 3 ,'Count of prefetched m2m links via accessor' );
- is( scalar $cd->cd_to_producer->all, 3, 'Amount of prefetched m2m link objects via accessor' );
- is( $cd->search_related('cd_to_producer')->count, 3, 'Count of prefetched m2m links via search_related' );
- is( scalar $cd->search_related('cd_to_producer')->all, 3, 'Amount of prefetched m2m links via search_related' );
-
- is($queries, 0, 'No queries ran so far');
+ $schema->is_executed_querycount( sub {
+ is( $cd->cd_to_producer->count, 3 ,'Count of prefetched m2m links via accessor' );
+ is( scalar $cd->cd_to_producer->all, 3, 'Amount of prefetched m2m link objects via accessor' );
+ is( $cd->search_related('cd_to_producer')->count, 3, 'Count of prefetched m2m links via search_related' );
+ is( scalar $cd->search_related('cd_to_producer')->all, 3, 'Amount of prefetched m2m links via search_related' );
+ }, 0, 'No queries ran so far');
is( scalar $cd->cd_to_producer->search_related('producer')->all, 3,
'Amount of objects via search_related off prefetched linker' );
is( $cd->producers->count, 3,
'Count via m2m accessor' );
- $queries = 0;
-
- is( $cd->cd_to_producer->count, 3 ,'Review count of prefetched m2m links via accessor' );
- is( scalar $cd->cd_to_producer->all, 3, 'Review amount of prefetched m2m link objects via accessor' );
- is( $cd->search_related('cd_to_producer')->count, 3, 'Review count of prefetched m2m links via search_related' );
- is( scalar $cd->search_related('cd_to_producer')->all, 3, 'Rreview amount of prefetched m2m links via search_related' );
-
- is($queries, 0, 'Still no queries on prefetched linker');
- $schema->storage->debugcb (undef);
- $schema->storage->debug ($orig_debug);
+ $schema->is_executed_querycount( sub {
+ is( $cd->cd_to_producer->count, 3 ,'Review count of prefetched m2m links via accessor' );
+ is( scalar $cd->cd_to_producer->all, 3, 'Review amount of prefetched m2m link objects via accessor' );
+ is( $cd->search_related('cd_to_producer')->count, 3, 'Review count of prefetched m2m links via search_related' );
+ is( scalar $cd->search_related('cd_to_producer')->all, 3, 'Rreview amount of prefetched m2m links via search_related' );
+ }, 0, 'Still no queries on prefetched linker');
}
# tests with distinct => 1
is($rs->all, 1, 'distinct with prefetch (objects)');
is($rs->count, 1, 'distinct with prefetch (count)');
- $queries = 0;
- $schema->storage->debugcb ($debugcb);
- $schema->storage->debug (1);
+ local $TODO = "This makes another 2 trips to the database, it can't be right";
+ $schema->is_executed_querycount( sub {
- # artist -> 2 cds -> 2 genres -> 2 cds for each genre + distinct = 2
- is($rs->search_related('cds')->all, 2, 'prefetched distinct with prefetch (objects)');
- is($rs->search_related('cds')->count, 2, 'prefetched distinct with prefetch (count)');
+ # the is() calls are not todoified
+ local $TODO;
- {
- local $TODO = "This makes another 2 trips to the database, it can't be right";
- is ($queries, 0, 'No extra queries fired (prefetch survives search_related)');
- }
+ # artist -> 2 cds -> 2 genres -> 2 cds for each genre + distinct = 2
+ is($rs->search_related('cds')->all, 2, 'prefetched distinct with prefetch (objects)');
+ is($rs->search_related('cds')->count, 2, 'prefetched distinct with prefetch (count)');
+
+ }, 0, 'No extra queries fired (prefetch survives search_related)');
- $schema->storage->debugcb (undef);
- $schema->storage->debug ($orig_debug);
}, 'distinct generally works with prefetch on deep search_related chains');
# pathological "user knows what they're doing" case
use DBIC::SqlMakerTest;
my $schema = DBICTest->init_schema();
-my $sdebug = $schema->storage->debug;
# has_a test
my $cd = $schema->resultset("CD")->find(4);
my $big_flop_cd = ($artist->search_related('cds'))[3];
is( $big_flop_cd->title, 'Big Flop', 'create_related ok' );
-{ # make sure we are not making pointless select queries when a FK IS NULL
- my $queries = 0;
- $schema->storage->debugcb(sub { $queries++; });
- $schema->storage->debug(1);
+# make sure we are not making pointless select queries when a FK IS NULL
+$schema->is_executed_querycount( sub {
$big_flop_cd->genre; #should not trigger a select query
- is($queries, 0, 'No SELECT made for belongs_to if key IS NULL');
+}, 0, 'No SELECT made for belongs_to if key IS NULL');
+
+$schema->is_executed_querycount( sub {
$big_flop_cd->genre_inefficient; #should trigger a select query
- is($queries, 1, 'SELECT made for belongs_to if key IS NULL when undef_on_null_fk disabled');
- $schema->storage->debug($sdebug);
- $schema->storage->debugcb(undef);
-}
+}, 1, 'SELECT made for belongs_to if key IS NULL when undef_on_null_fk disabled');
my( $rs_from_list ) = $artist->search_related_rs('cds');
isa_ok( $rs_from_list, 'DBIx::Class::ResultSet', 'search_related_rs in list context returns rs' );
use DBIC::SqlMakerTest;
my $schema = DBICTest->init_schema();
-my $sdebug = $schema->storage->debug;
my $artist = $schema->resultset ('Artist')->find(1);
# expect a create, after a failed search using *only* the
# *current* relationship and the unique column constraints
# (so no year)
-my @sql;
-$schema->storage->debugcb(sub { push @sql, $_[1] });
-$schema->storage->debug (1);
-
-$genre->update_or_create_related ('cds', {
- title => 'the best thing since vertical toasters',
- artist => $artist,
- year => 2012,
-});
-
-$schema->storage->debugcb(undef);
-$schema->storage->debug ($sdebug);
-
-my ($search_sql) = $sql[0] =~ /^(SELECT .+?)\:/;
-is_same_sql (
- $search_sql,
- 'SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track
- FROM cd me
- WHERE ( me.artist = ? AND me.genreid = ? AND me.title = ? )
- ',
- 'expected select issued',
-);
+$schema->is_executed_sql_bind( sub {
+ $genre->update_or_create_related ('cds', {
+ title => 'the best thing since vertical toasters',
+ artist => $artist,
+ year => 2012,
+ });
+}, [
+ [
+ 'SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track
+ FROM cd me
+ WHERE ( me.artist = ? AND me.genreid = ? AND me.title = ? )
+ ',
+ 1,
+ 2,
+ "the best thing since vertical toasters",
+ ],
+ [
+ 'INSERT INTO cd ( artist, genreid, title, year) VALUES ( ?, ?, ?, ? )',
+ 1,
+ 2,
+ "the best thing since vertical toasters",
+ 2012,
+ ],
+], 'expected select issued' );
# a has_many search without a unique constraint makes no sense
# but I am not sure what to test for - leaving open
'Resultset-class attributes do not seep outside of the subselect',
);
-$schema->storage->debug(1);
-
is_same_sql_bind(
$schema->resultset('CD')->search ({}, {
rows => 2,
[ [{ sqlt_datatype => 'integer' } => 2 ] ],
);
-
done_testing;