bc035de9c1561fcaf1e4b1ee5c431f9537816886
[dbsrgits/DBIx-Class.git] / t / prefetch / with_limit.t
1 # Test to ensure we get a consistent result set wether or not we use the
2 # prefetch option in combination rows (LIMIT).
3 use strict;
4 use warnings;
5
6 use Test::More;
7 use Test::Exception;
8 use lib qw(t/lib);
9 use DBICTest;
10 use DBIC::SqlMakerTest;
11
12 my $schema = DBICTest->init_schema();
13
14
15 my $no_prefetch = $schema->resultset('Artist')->search(
16   [   # search deliberately contrived
17     { 'artwork.cd_id' => undef },
18     { 'tracks.title' => { '!=' => 'blah-blah-1234568' }}
19   ],
20   { rows => 3, join => { cds => [qw/artwork tracks/] },
21  }
22 );
23
24 my $use_prefetch = $no_prefetch->search(
25   {},
26   {
27     select => ['me.artistid', 'me.name'],
28     as => ['artistid', 'name'],
29     prefetch => 'cds',
30     order_by => { -desc => 'name' },
31   }
32 );
33
34 is($no_prefetch->count, $use_prefetch->count, '$no_prefetch->count == $use_prefetch->count');
35 is(
36   scalar ($no_prefetch->all),
37   scalar ($use_prefetch->all),
38   "Amount of returned rows is right"
39 );
40
41 my $artist_many_cds = $schema->resultset('Artist')->search ( {}, {
42   join => 'cds',
43   group_by => 'me.artistid',
44   having => \ 'count(cds.cdid) > 1',
45 })->first;
46
47
48 $no_prefetch = $schema->resultset('Artist')->search(
49   { artistid => $artist_many_cds->id },
50   { rows => 1 }
51 );
52
53 $use_prefetch = $no_prefetch->search ({}, { prefetch => 'cds' });
54
55 my $normal_artist = $no_prefetch->single;
56 my $prefetch_artist = $use_prefetch->find({ name => $artist_many_cds->name });
57 my $prefetch2_artist = $use_prefetch->first;
58
59 is(
60   $prefetch_artist->cds->count,
61   $normal_artist->cds->count,
62   "Count of child rel with prefetch + rows => 1 is right (find)"
63 );
64 is(
65   $prefetch2_artist->cds->count,
66   $normal_artist->cds->count,
67   "Count of child rel with prefetch + rows => 1 is right (first)"
68 );
69
70 is (
71   scalar ($prefetch_artist->cds->all),
72   scalar ($normal_artist->cds->all),
73   "Amount of child rel rows with prefetch + rows => 1 is right (find)"
74 );
75 is (
76   scalar ($prefetch2_artist->cds->all),
77   scalar ($normal_artist->cds->all),
78   "Amount of child rel rows with prefetch + rows => 1 is right (first)"
79 );
80
81 throws_ok (
82   sub { $use_prefetch->single },
83   qr/resultsets prefetching has_many/,
84   'single() with multiprefetch is illegal',
85 );
86
87 my $artist = $use_prefetch->search({'cds.title' => $artist_many_cds->cds->first->title })->next;
88 is($artist->cds->count, 1, "count on search limiting prefetched has_many");
89
90 # try with double limit
91 my $artist2 = $use_prefetch->search({'cds.title' => { '!=' => $artist_many_cds->cds->first->title } })->slice (0,0)->next;
92 is($artist2->cds->count, 2, "count on search limiting prefetched has_many");
93
94 # make sure 1:1 joins do not force a subquery (no point to exercise the optimizer, if at all available)
95 # get cd's that have any tracks and their artists
96 my $single_prefetch_rs = $schema->resultset ('CD')->search (
97   { 'me.year' => 2010, 'artist.name' => 'foo' },
98   { prefetch => ['tracks', 'artist'], rows => 15 },
99 );
100 is_same_sql_bind (
101   $single_prefetch_rs->as_query,
102   '(
103     SELECT
104         me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track,
105         tracks.trackid, tracks.cd, tracks.position, tracks.title, tracks.last_updated_on, tracks.last_updated_at,
106         artist.artistid, artist.name, artist.rank, artist.charfield
107       FROM (
108         SELECT
109             me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track
110           FROM cd me
111           JOIN artist artist ON artist.artistid = me.artist
112         WHERE ( ( artist.name = ? AND me.year = ? ) )
113         LIMIT 15
114       ) me
115       LEFT JOIN track tracks
116         ON tracks.cd = me.cdid
117       JOIN artist artist
118         ON artist.artistid = me.artist
119     WHERE ( ( artist.name = ? AND me.year = ? ) )
120     ORDER BY tracks.cd
121   )',
122   [
123     [ 'artist.name' => 'foo' ],
124     [ 'me.year'     => 2010  ],
125     [ 'artist.name' => 'foo' ],
126     [ 'me.year'     => 2010  ],
127   ],
128   'No grouping of non-multiplying resultsets',
129 );
130
131 done_testing;