MOAR optimization - tracking is_new_res is double work
[dbsrgits/DBIx-Class.git] / t / resultset / inflate_result_api.t
1 use strict;
2 use warnings;
3
4 use Test::More;
5 use Test::Deep;
6 use lib qw(t/lib);
7 use DBICTest;
8
9 my $schema = DBICTest->init_schema(no_populate => 1);
10
11 $schema->resultset('Artist')->create({ name => 'JMJ', cds => [{
12   title => 'Magnetic Fields',
13   year => 1981,
14   genre => { name => 'electro' },
15   tracks => [
16     { title => 'm1' },
17     { title => 'm2' },
18     { title => 'm3' },
19     { title => 'm4' },
20   ],
21 } ] });
22
23 $schema->resultset('CD')->create({
24   title => 'Equinoxe',
25   year => 1978,
26   artist => { name => 'JMJ' },
27   genre => { name => 'electro' },
28   tracks => [
29     { title => 'e1' },
30     { title => 'e2' },
31     { title => 'e3' },
32   ],
33   single_track => {
34     title => 'o1',
35     cd => {
36       title => 'Oxygene',
37       year => 1976,
38       artist => { name => 'JMJ' },
39       tracks => [
40         { title => 'o2', position => 2},  # the position should not be needed here, bug in MC
41       ],
42     },
43   },
44 });
45
46 $schema->resultset('CD')->create({ artist => 1, year => 1977, title => "fuzzy_1" });
47
48 {
49   package DBICTest::_IRCapture;
50   sub inflate_result { [@_[2,3]] };
51 }
52
53 {
54   package DBICTest::_IRCaptureAround;
55   use base 'DBIx::Class::Row';
56   sub inflate_result { [@_[2,3]] };
57 }
58
59 cmp_structures(
60   ([$schema->resultset ('CD')->search ({}, {
61     result_class => 'DBICTest::_IRCapture',
62     prefetch => { single_track => { cd => 'artist' } },
63     order_by => 'me.cdid',
64   })->all]),
65   [
66     [
67       { cdid => 1, single_track => undef, artist => 1, genreid => 1, year => 1981, title => "Magnetic Fields" },
68       { single_track => bless( [
69         { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
70         {  cd => bless ( [
71           { cdid => undef, single_track => undef, artist => undef, genreid => undef, year => undef, title => undef },
72           {
73             artist => bless ( [
74               { artistid => undef, name => undef, charfield => undef, rank => undef }
75             ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class )
76           }
77         ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) }
78       ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) }
79     ],
80     [
81       { cdid => 2, single_track => undef, artist => 1, genreid => undef, year => 1976, title => "Oxygene" },
82       { single_track => bless( [
83         { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
84         {  cd => bless ( [
85           { cdid => undef, single_track => undef, artist => undef, genreid => undef, year => undef, title => undef },
86           {
87             artist => bless ( [
88               { artistid => undef, name => undef, charfield => undef, rank => undef }
89             ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class )
90           }
91         ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) }
92       ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) }
93     ],
94     [
95       { cdid => 3, single_track => 6, artist => 1, genreid => 1, year => 1978, title => "Equinoxe" },
96       { single_track => [
97         { trackid => 6, title => 'o1', position => 1, cd => 2, last_updated_at => undef, last_updated_on => undef },
98         {  cd => [
99           { cdid => 2, single_track => undef, artist => 1, genreid => undef, year => 1976, title => "Oxygene" },
100           {
101             artist => [
102               { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 }
103             ]
104           }
105         ] }
106       ] }
107     ],
108     [
109       { cdid => 4, single_track => undef, artist => 1, genreid => undef, year => 1977, title => "fuzzy_1" },
110       { single_track => bless( [
111         { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
112         {  cd => bless ( [
113           { cdid => undef, single_track => undef, artist => undef, genreid => undef, year => undef, title => undef },
114           {
115             artist => bless ( [
116               { artistid => undef, name => undef, charfield => undef, rank => undef }
117             ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class )
118           }
119         ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) }
120       ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) }
121     ],
122   ],
123   'Simple 1:1 descend with classic prefetch'
124 );
125
126 cmp_structures(
127   [$schema->resultset ('CD')->search ({}, {
128     result_class => 'DBICTest::_IRCapture',
129     join => { single_track => { cd => 'artist' } },
130     columns => [
131       { 'year'                                    => 'me.year' },
132       { 'genreid'                                 => 'me.genreid' },
133       { 'single_track.cd.artist.artistid'         => 'artist.artistid' },
134       { 'title'                                   => 'me.title' },
135       { 'artist'                                  => 'me.artist' },
136     ],
137     order_by => 'me.cdid',
138   })->all],
139   [
140     [
141       { artist => 1, genreid => 1, year => 1981, title => "Magnetic Fields" },
142       { single_track => bless( [
143         undef,
144         {  cd => [
145           undef,
146           {
147             artist => [
148               { artistid => undef }
149             ]
150           }
151         ] }
152       ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) }
153     ],
154     [
155       { artist => 1, genreid => undef, year => 1976, title => "Oxygene" },
156       { single_track => bless( [
157         undef,
158         {  cd => [
159           undef,
160           {
161             artist => [
162               { artistid => undef }
163             ]
164           }
165         ] }
166       ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) }
167     ],
168     [
169       { artist => 1, genreid => 1, year => 1978, title => "Equinoxe" },
170       { single_track => [
171         undef,
172         {  cd => [
173           undef,
174           {
175             artist => [
176               { artistid => 1 }
177             ]
178           }
179         ] }
180       ] }
181     ],
182     [
183       { artist => 1, genreid => undef, year => 1977, title => "fuzzy_1" },
184       { single_track => bless( [
185         undef,
186         {  cd => [
187           undef,
188           {
189             artist => [
190               { artistid => undef }
191             ]
192           }
193         ] }
194       ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) }
195     ],
196   ],
197   'Simple 1:1 descend with missing selectors'
198 );
199
200 cmp_structures(
201   ([$schema->resultset ('CD')->search ({}, {
202     result_class => 'DBICTest::_IRCapture',
203     prefetch => [ { single_track => { cd => { artist => { cds => 'tracks' } } } } ],
204     order_by => [qw/me.cdid tracks.trackid/],
205   })->all]),
206   [
207     [
208       { cdid => 1, single_track => undef, artist => 1, genreid => 1, year => 1981, title => "Magnetic Fields" },
209       { single_track => bless( [
210         { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
211         {  cd => [
212           { cdid => undef, single_track => undef, artist => undef, genreid => undef, year => undef, title => undef },
213           {
214             artist => [
215               { artistid => undef, name => undef, charfield => undef, rank => undef },
216               { cds => bless( [ [
217                 { cdid => undef, single_track => undef, artist => undef, genreid => undef, year => undef, title => undef },
218                 { tracks => bless( [ [
219                   { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
220                 ] ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
221               ] ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
222             ],
223           },
224         ] },
225       ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
226     ],
227     [
228       { cdid => 2, single_track => undef, artist => 1, genreid => undef, year => 1976, title => "Oxygene" },
229       { single_track => bless( [
230         { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
231         {  cd => [
232           { cdid => undef, single_track => undef, artist => undef, genreid => undef, year => undef, title => undef },
233           {
234             artist => [
235               { artistid => undef, name => undef, charfield => undef, rank => undef },
236               { cds => bless( [ [
237                 { cdid => undef, single_track => undef, artist => undef, genreid => undef, year => undef, title => undef },
238                 { tracks => bless( [ [
239                   { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
240                 ] ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
241               ] ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
242             ],
243           },
244         ] },
245       ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
246     ],
247     [
248       { cdid => 3, single_track => 6, artist => 1, genreid => 1, year => 1978, title => "Equinoxe" },
249       { single_track => [
250         { trackid => 6, title => 'o1', position => 1, cd => 2, last_updated_at => undef, last_updated_on => undef },
251         {  cd => [
252           { cdid => 2, single_track => undef, artist => 1, genreid => undef, year => 1976, title => "Oxygene" },
253           {
254             artist => [
255               { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
256               { cds => [
257                 [
258                   { cdid => 4, single_track => undef, artist => 1, genreid => undef, year => 1977, title => "fuzzy_1" },
259                   { tracks => bless( [
260                     [ { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef } ],
261                   ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
262                 ],
263                 [
264                   { cdid => 1, single_track => undef, artist => 1, genreid => 1, year => 1981, title => "Magnetic Fields" },
265                   { tracks => [
266                     [ { trackid => 1, title => 'm1', position => 1, cd => 1, last_updated_at => undef, last_updated_on => undef } ],
267                     [ { trackid => 2, title => 'm2', position => 2, cd => 1, last_updated_at => undef, last_updated_on => undef } ],
268                     [ { trackid => 3, title => 'm3', position => 3, cd => 1, last_updated_at => undef, last_updated_on => undef } ],
269                     [ { trackid => 4, title => 'm4', position => 4, cd => 1, last_updated_at => undef, last_updated_on => undef } ],
270                   ]},
271                 ],
272                 [
273                   { cdid => 2, single_track => undef, artist => 1, genreid => undef, year => 1976, title => "Oxygene" },
274                   { tracks => [
275                     [ { trackid => 5, title => 'o2', position => 2, cd => 2, last_updated_at => undef, last_updated_on => undef } ],
276                     [ { trackid => 6, title => 'o1', position => 1, cd => 2, last_updated_at => undef, last_updated_on => undef } ],
277                   ]},
278                 ],
279                 [
280                   { cdid => 3, single_track => 6, artist => 1, genreid => 1, year => 1978, title => "Equinoxe" },
281                   { tracks => [
282                     [ { trackid => 7, title => 'e1', position => 1, cd => 3, last_updated_at => undef, last_updated_on => undef } ],
283                     [ { trackid => 8, title => 'e2', position => 2, cd => 3, last_updated_at => undef, last_updated_on => undef } ],
284                     [ { trackid => 9, title => 'e3', position => 3, cd => 3, last_updated_at => undef, last_updated_on => undef } ],
285                   ]},
286                 ],
287               ]},
288             ]
289           }
290         ] }
291       ] }
292     ],
293     [
294       { cdid => 4, single_track => undef, artist => 1, genreid => undef, year => 1977, title => "fuzzy_1" },
295       { single_track => bless( [
296         { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
297         {  cd => [
298           { cdid => undef, single_track => undef, artist => undef, genreid => undef, year => undef, title => undef },
299           {
300             artist => [
301               { artistid => undef, name => undef, charfield => undef, rank => undef },
302               { cds => bless( [ [
303                 { cdid => undef, single_track => undef, artist => undef, genreid => undef, year => undef, title => undef },
304                 { tracks => bless( [ [
305                   { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
306                 ] ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
307               ] ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
308             ],
309           },
310         ] },
311       ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
312     ],
313   ],
314   'Collapsing 1:1 ending in chained has_many with classic prefetch'
315 );
316
317 cmp_structures (
318   ([$schema->resultset ('Artist')->search ({}, {
319     result_class => 'DBICTest::_IRCapture',
320     join => { cds => 'tracks' },
321     '+columns' => [
322       (map { "cds.$_" } $schema->source('CD')->columns),
323       (map { +{ "cds.tracks.$_" => "tracks.$_" } } $schema->source('Track')->columns),
324     ],
325     order_by => [qw/cds.cdid tracks.trackid/],
326   })->all]),
327   [
328     [
329       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
330       { cds => [
331         { cdid => 1, single_track => undef, artist => 1, genreid => 1, year => 1981, title => "Magnetic Fields" },
332         { tracks => [
333           { trackid => 1, title => 'm1', position => 1, cd => 1, last_updated_at => undef, last_updated_on => undef },
334         ]},
335       ]},
336     ],
337     [
338       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
339       { cds => [
340         { cdid => 1, single_track => undef, artist => 1, genreid => 1, year => 1981, title => "Magnetic Fields" },
341         { tracks => [
342           { trackid => 2, title => 'm2', position => 2, cd => 1, last_updated_at => undef, last_updated_on => undef },
343         ]},
344       ]},
345     ],
346     [
347       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
348       { cds => [
349         { cdid => 1, single_track => undef, artist => 1, genreid => 1, year => 1981, title => "Magnetic Fields" },
350         { tracks => [
351           { trackid => 3, title => 'm3', position => 3, cd => 1, last_updated_at => undef, last_updated_on => undef },
352         ]},
353       ]},
354     ],
355     [
356       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
357       { cds => [
358         { cdid => 1, single_track => undef, artist => 1, genreid => 1, year => 1981, title => "Magnetic Fields" },
359         { tracks => [
360           { trackid => 4, title => 'm4', position => 4, cd => 1, last_updated_at => undef, last_updated_on => undef },
361         ]},
362       ]},
363     ],
364     [
365       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
366       { cds => [
367         { cdid => 2, single_track => undef, artist => 1, genreid => undef, year => 1976, title => "Oxygene" },
368         { tracks => [
369           { trackid => 5, title => 'o2', position => 2, cd => 2, last_updated_at => undef, last_updated_on => undef },
370         ]},
371       ]},
372     ],
373     [
374       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
375       { cds => [
376         { cdid => 2, single_track => undef, artist => 1, genreid => undef, year => 1976, title => "Oxygene" },
377         { tracks => [
378           { trackid => 6, title => 'o1', position => 1, cd => 2, last_updated_at => undef, last_updated_on => undef },
379         ]},
380       ]},
381     ],
382     [
383       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
384       { cds => [
385         { cdid => 3, single_track => 6, artist => 1, genreid => 1, year => 1978, title => "Equinoxe" },
386         { tracks => [
387           { trackid => 7, title => 'e1', position => 1, cd => 3, last_updated_at => undef, last_updated_on => undef },
388         ]},
389       ]},
390     ],
391     [
392       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
393       { cds => [
394         { cdid => 3, single_track => 6, artist => 1, genreid => 1, year => 1978, title => "Equinoxe" },
395         { tracks => [
396           { trackid => 8, title => 'e2', position => 2, cd => 3, last_updated_at => undef, last_updated_on => undef },
397         ]},
398       ]},
399     ],
400     [
401       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
402       { cds => [
403         { cdid => 3, single_track => 6, artist => 1, genreid => 1, year => 1978, title => "Equinoxe" },
404         { tracks => [
405           { trackid => 9, title => 'e3', position => 3, cd => 3, last_updated_at => undef, last_updated_on => undef },
406         ]},
407       ]},
408     ],
409     [
410       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
411       { cds => [
412         { cdid => 4, single_track => undef, artist => 1, genreid => undef, year => 1977, title => "fuzzy_1" },
413         { tracks => bless( [
414           { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
415         ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
416       ]},
417     ],
418   ],
419   'Non-Collapsing chained has_many'
420 );
421
422 $schema->resultset('Artist')->create({ name => "${_}_cdless" })
423   for (qw( Z A ));
424
425 cmp_structures (
426   [$schema->resultset ('Artist')->search ({}, {
427     result_class => 'DBICTest::_IRCapture',
428     collapse => 1,
429     join => 'cds',
430     columns => [qw( cds.title cds.artist )],
431     order_by => [qw( me.name cds.title )],
432   })->all],
433   [
434     [
435       undef,
436       { cds => bless( [
437         [ { artist => undef, title => undef } ]
438       ], 'DBIx::ResultParser::RelatedNullBranch' ) },
439     ],
440     [
441       undef,
442       { cds => [
443         [ { artist => 1, title => "Equinoxe" } ],
444         [ { artist => 1, title => "Magnetic Fields" } ],
445         [ { artist => 1, title => "Oxygene" } ],
446         [ { artist => 1, title => "fuzzy_1" } ],
447       ] }
448     ],
449     [
450       undef,
451       { cds => bless( [
452         [ { artist => undef, title => undef } ]
453       ], 'DBIx::ResultParser::RelatedNullBranch' ) },
454     ],
455   ],
456   'Expected output of collapsing 1:M with empty root selection',
457 );
458
459 sub cmp_structures {
460   my ($left, $right, $msg) = @_;
461
462   local $Test::Builder::Level = $Test::Builder::Level + 1;
463   cmp_deeply($left, $right, $msg||());
464 }
465
466 done_testing;