1use strict; 2use warnings; 3 4use Test::More; 5use lib qw(t/lib); 6use DBICTest; 7 8my $schema = DBICTest->init_schema(); 9 10my $queries; 11my $debugcb = sub{ $queries++ }; 12my $sdebug = $schema->storage->debug; 13 14plan tests => 23; 15 16my $rs = $schema->resultset("Artist")->search( 17 { artistid => 1 } 18); 19 20my $artist = $rs->first; 21 22ok( !defined($rs->get_cache), 'cache is not populated without cache attribute' ); 23 24$rs = $schema->resultset('Artist')->search( undef, { cache => 1 } ); 25my $artists = [ $rs->all ]; 26 27is( scalar @{$rs->get_cache}, 3, 'all() populates cache for search with cache attribute' ); 28 29$rs->clear_cache; 30 31ok( !defined($rs->get_cache), 'clear_cache is functional' ); 32 33$rs->next; 34 35is( scalar @{$rs->get_cache}, 3, 'next() populates cache for search with cache attribute' ); 36 37pop( @$artists ); 38$rs->set_cache( $artists ); 39 40is( scalar @{$rs->get_cache}, 2, 'set_cache() is functional' ); 41 42my $cd = $schema->resultset('CD')->find(1); 43 44$rs->clear_cache; 45 46$queries = 0; 47$schema->storage->debug(1); 48$schema->storage->debugcb ($debugcb); 49 50$rs = $schema->resultset('Artist')->search( undef, { cache => 1 } ); 51while( $artist = $rs->next ) {} 52$artist = $rs->first(); 53 54is( $queries, 1, 'revisiting a row does not issue a query when cache => 1' ); 55 56$schema->storage->debug($sdebug); 57$schema->storage->debugcb (undef); 58 59my @a = $schema->resultset("Artist")->search( 60 { }, 61 { 62 join => [ qw/ cds /], 63 prefetch => [qw/ cds /], 64 } 65); 66 67is(scalar @a, 3, 'artist with cds: count parent objects'); 68 69$rs = $schema->resultset("Artist")->search( 70 { 'artistid' => 1 }, 71 { 72 join => [ qw/ cds /], 73 prefetch => [qw/ cds /], 74 } 75); 76 77# start test for prefetch SELECT count 78$queries = 0; 79$schema->storage->debug(1); 80$schema->storage->debugcb ($debugcb); 81 82$artist = $rs->first; 83$rs->reset(); 84 85# make sure artist contains a related resultset for cds 86isa_ok( $artist->{related_resultsets}{cds}, 'DBIx::Class::ResultSet', 'artist has a related_resultset for cds' ); 87 88# check if $artist->cds->get_cache is populated 89is( scalar @{$artist->cds->get_cache}, 3, 'cache for artist->cds contains correct number of records'); 90 91# ensure that $artist->cds returns correct number of objects 92is( scalar ($artist->cds), 3, 'artist->cds returns correct number of objects' ); 93 94# ensure that $artist->cds->count returns correct value 95is( $artist->cds->count, 3, 'artist->cds->count returns correct value' ); 96 97# ensure that $artist->count_related('cds') returns correct value 98is( $artist->count_related('cds'), 3, 'artist->count_related returns correct value' ); 99 100is($queries, 1, 'only one SQL statement executed'); 101 102$schema->storage->debug($sdebug); 103$schema->storage->debugcb (undef); 104 105# make sure related_resultset is deleted after object is updated 106$artist->set_column('name', 'New Name'); 107$artist->update(); 108 109is( scalar keys %{$artist->{related_resultsets}}, 0, 'related resultsets deleted after update' ); 110 111# todo: make sure caching works with nested prefetch e.g. $artist->cds->tracks 112$rs = $schema->resultset("Artist")->search( 113 { artistid => 1 }, 114 { 115 join => { cds => 'tags' }, 116 prefetch => { 117 cds => 'tags' 118 }, 119 } 120); 121{ 122my $artist_count_before = $schema->resultset('Artist')->count; 123$schema->resultset("Artist")->create({artistid=>4,name=>qq{Humoungous Hamsters}}); 124is($schema->resultset('Artist')->count, $artist_count_before + 1, 'count() reflects new artist'); 125my $artist = $schema->resultset("Artist")->search( 126 { artistid => 4 },{prefetch=>[qw/cds/]} 127)->first; 128 129is($artist->cds, 0, 'No cds for this artist'); 130} 131 132# SELECT count for nested has_many prefetch 133$queries = 0; 134$schema->storage->debug(1); 135$schema->storage->debugcb ($debugcb); 136 137$artist = ($rs->all)[0]; 138 139is($queries, 1, 'only one SQL statement executed'); 140 141$schema->storage->debug($sdebug); 142$schema->storage->debugcb (undef); 143 144my @objs; 145#$artist = $rs->find(1); 146 147$queries = 0; 148$schema->storage->debug(1); 149$schema->storage->debugcb ($debugcb); 150 151my $cds = $artist->cds; 152my $tags = $cds->next->tags; 153while( my $tag = $tags->next ) { 154 push @objs, $tag->tagid; #warn "tag:", $tag->ID, " => ", $tag->tag; 155} 156 157is_deeply( \@objs, [ 3 ], 'first cd has correct tags' ); 158 159$tags = $cds->next->tags; 160@objs = (); 161while( my $tag = $tags->next ) { 162 push @objs, $tag->id; #warn "tag: ", $tag->ID; 163} 164 165is_deeply( \@objs, [ 1 ], 'second cd has correct tags' ); 166 167$tags = $cds->next->tags; 168@objs = (); 169while( my $tag = $tags->next ) { 170 push @objs, $tag->id; #warn "tag: ", $tag->ID; 171} 172 173is_deeply( \@objs, [ 2, 5, 8 ], 'third cd has correct tags' ); 174 175is( $queries, 0, 'no additional SQL statements while checking nested data' ); 176 177# start test for prefetch SELECT count 178$queries = 0; 179 180$artist = $schema->resultset('Artist')->find(1, { prefetch => [qw/cds/] }); 181 182is( $queries, 1, 'only one select statement on find with inline has_many prefetch' ); 183 184# start test for prefetch SELECT count 185$queries = 0; 186 187$rs = $schema->resultset('Artist')->search(undef, { prefetch => [qw/cds/] }); 188$artist = $rs->find(1); 189 190is( $queries, 1, 'only one select statement on find with has_many prefetch on resultset' ); 191 192$schema->storage->debug($sdebug); 193$schema->storage->debugcb (undef); 194