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