3de15e30c096757952cbb746ac690e16de1fc444
[dbsrgits/DBIx-Class.git] / t / prefetch / _internals.t
1 use strict;
2 use warnings;
3
4 use Data::Dumper;
5 BEGIN { $Data::Dumper::Sortkeys = 1 }; # so we can compare the deparsed coderefs below
6
7 use Test::More;
8 use lib qw(t/lib);
9 use DBICTest;
10 use B::Deparse;
11
12
13 my $schema = DBICTest->init_schema(no_deploy => 1);
14
15 my ($as, $vals, @pairs);
16
17 # artwork-artist deliberately mixed around
18 @pairs = (
19   'artwork_to_artist.artist_id' => '2',
20
21   'cd_id' => '1',
22
23   'artwork_to_artist.artwork_cd_id' => '1',
24
25   'cd.artist' => '1',
26   'cd.cdid' => '1',
27   'cd.title' => 'Spoonful of bees',
28
29   'cd.artist.artistid' => '7',
30   'cd.artist.name' => 'Caterwauler McCrae',
31   'artwork_to_artist.artist.name' => 'xenowhinycide',
32 );
33 while (@pairs) {
34   push @$as, shift @pairs;
35   push @$vals, shift @pairs;
36 }
37
38 my $parser = $schema->source ('Artwork')->_mk_row_parser($as, 'collapse requested');
39
40 is_deeply (
41   $parser->($vals),
42   [
43     {
44       cd_id => 1,
45     },
46
47     {
48       artwork_to_artist => [
49         {
50           artist_id => 2,
51           artwork_cd_id => 1,
52         },
53         {
54           artist => [
55             {
56               name => 'xenowhinycide',
57             },
58             undef,
59             [ 2, 1 ], # inherited from artwork_to_artist (child-parent definition)
60           ],
61         },
62         [ 2, 1 ]  # artwork_to_artist own data, in selection order
63       ],
64
65       cd => [
66         {
67           artist => 1,
68           cdid => 1,
69           title => 'Spoonful of bees',
70         },
71         {
72           artist => [
73             {
74               artistid => 7,
75               name => 'Caterwauler McCrae',
76             },
77             undef,
78             [ 7 ], # our own id
79           ]
80         },
81         [ 1 ], # our cdid fk
82       ]
83     },
84     [ 1 ], # our id
85   ],
86   'generated row parser works as expected',
87 );
88
89 undef $_ for ($as, $vals);
90 @pairs = (
91   'name' => 'Caterwauler McCrae',
92   'cds.tracks.cd' => '3',
93   'cds.tracks.title' => 'Fowlin',
94   'cds.tracks.cd_single.title' => 'Awesome single',
95 );
96 while (@pairs) {
97   push @$as, shift @pairs;
98   push @$vals, shift @pairs;
99 }
100 $parser = $schema->source ('Artist')->_mk_row_parser($as);
101
102 is_deeply (
103   $parser->($vals),
104   [
105     {
106       name => 'Caterwauler McCrae'
107     },
108     {
109       cds => [
110         {},
111         {
112           tracks => [
113             {
114               cd => 3,
115               title => 'Fowlin'
116             },
117             {
118               cd_single => [
119                 {
120                   title => 'Awesome single',
121                 },
122               ],
123             },
124           ]
125         }
126       ]
127     }
128   ],
129   'generated parser works as expected over missing joins (no collapse)',
130 );
131
132 undef $_ for ($as, $vals);
133 @pairs = (
134     'tracks.lyrics.lyric_versions.text'                => 'unique when combined with the lyric collapsable by the 1:1 tracks-parent',
135     'existing_single_track.cd.artist.artistid'         => 'artist_id (gives uniq. to its entire parent chain)',
136     'existing_single_track.cd.artist.cds.year'         => 'non-unique cds col (year)',
137     'year'                                             => 'non unique main year',
138     'genreid'                                          => 'non-unique/nullable main genid',
139     'tracks.title'                                     => 'non-unique title (missing multicol const. part)',
140     'existing_single_track.cd.artist.cds.cdid'         => 'cds unique id col to give uniquiness to ...tracks.title below',
141     'latest_cd'                                        => 'random function (not a colname)',
142     'existing_single_track.cd.artist.cds.tracks.title' => 'unique track title (when combined with ...cds.cdid above)',
143     'existing_single_track.cd.artist.cds.genreid'      => 'nullable cds col (genreid)',
144 );
145 while (@pairs) {
146   push @$as, shift @pairs;
147   push @$vals, shift @pairs;
148 }
149
150 is_deeply (
151   $schema->source ('CD')->_resolve_collapse ( { map { $as->[$_] => $_ } (0 .. $#$as) } ),
152   {
153     -collapse_on => {
154       'existing_single_track.cd.artist.artistid' => 1,
155     },
156
157     existing_single_track => {
158       -collapse_on => {
159        'existing_single_track.cd.artist.artistid' => 1,
160       },
161
162       cd => {
163         -collapse_on => {
164           'existing_single_track.cd.artist.artistid' => 1,
165         },
166
167         artist => {
168           -collapse_on => {
169             'existing_single_track.cd.artist.artistid' => 1,
170           },
171
172           cds => {
173             -collapse_on => {
174               'existing_single_track.cd.artist.cds.cdid' => 6,
175             },
176
177             tracks => {
178               -collapse_on => {
179                 'existing_single_track.cd.artist.cds.cdid' => 6,
180                 'existing_single_track.cd.artist.cds.tracks.title' => 8,
181               }
182             }
183           }
184         }
185       }
186     },
187     tracks => {
188       -collapse_on => {
189         'existing_single_track.cd.artist.artistid' => 1,
190         'tracks.title' => 5,
191       },
192
193       lyrics => {
194         -collapse_on => {
195           'existing_single_track.cd.artist.artistid' => 1,
196           'tracks.title' => 5,
197         },
198
199         lyric_versions => {
200           -collapse_on => {
201             'existing_single_track.cd.artist.artistid' => 1,
202             'tracks.title' => 5,
203             'tracks.lyrics.lyric_versions.text' => 0,
204           },
205         },
206       },
207     }
208   },
209   'Correct collapse map constructed',
210 );
211
212
213 $parser = $schema->source ('CD')->_mk_row_parser ($as, 'add collapse data');
214
215 is_deeply (
216   $parser->($vals),
217   [
218     {
219       latest_cd => 'random function (not a colname)',
220       year => 'non unique main year',
221       genreid => 'non-unique/nullable main genid'
222     },
223     {
224       existing_single_track => [
225         {},
226         {
227           cd => [
228             {},
229             {
230               artist => [
231                 { artistid => 'artist_id (gives uniq. to its entire parent chain)' },
232                 {
233                   cds => [
234                     {
235                       cdid => 'cds unique id col to give uniquiness to ...tracks.title below',
236                       year => 'non-unique cds col (year)',
237                       genreid => 'nullable cds col (genreid)'
238                     },
239                     {
240                       tracks => [
241                         {
242                           title => 'unique track title (when combined with ...cds.cdid above)'
243                         },
244                         undef,
245                         [
246                           'cds unique id col to give uniquiness to ...tracks.title below',
247                           'unique track title (when combined with ...cds.cdid above)',
248                         ],
249                       ]
250                     },
251                     [ 'cds unique id col to give uniquiness to ...tracks.title below' ],
252                   ]
253                 },
254                 [ 'artist_id (gives uniq. to its entire parent chain)' ],
255               ]
256             },
257             [ 'artist_id (gives uniq. to its entire parent chain)' ],
258           ]
259         },
260         [ 'artist_id (gives uniq. to its entire parent chain)' ],
261       ],
262       tracks => [
263         {
264           title => 'non-unique title (missing multicol const. part)'
265         },
266         {
267           lyrics => [
268             {},
269             {
270               lyric_versions => [
271                 {
272                   text => 'unique when combined with the lyric collapsable by the 1:1 tracks-parent',
273                 },
274                 undef,
275                 [
276                   'unique when combined with the lyric collapsable by the 1:1 tracks-parent',
277                   'artist_id (gives uniq. to its entire parent chain)',
278                   'non-unique title (missing multicol const. part)',
279                 ],
280               ],
281             },
282             [
283               'artist_id (gives uniq. to its entire parent chain)',
284               'non-unique title (missing multicol const. part)',
285             ],
286           ],
287         },
288         [
289           'artist_id (gives uniq. to its entire parent chain)',
290           'non-unique title (missing multicol const. part)',
291         ],
292       ],
293     },
294     [ 'artist_id (gives uniq. to its entire parent chain)' ],
295   ],
296   'Proper row parser constructed',
297 );
298
299 # For extra insanity test/showcase the parser's guts:
300 my $deparser = B::Deparse->new;
301 is (
302   $deparser->coderef2text ($parser),
303   $deparser->coderef2text ( sub { package DBIx::Class::ResultSource;
304     [
305       {
306         genreid => $_[0][4],
307         latest_cd => $_[0][7],
308         year => $_[0][3]
309       },
310       {
311
312         existing_single_track => [
313           {},
314           {
315             cd => [
316               {},
317               {
318                 artist => [
319                   {
320                     artistid => $_[0][1]
321                   },
322                   {
323
324                     !defined($_[0][6]) ? () : (
325                     cds => [
326                       {
327                         cdid => $_[0][6],
328                         genreid => $_[0][9],
329                         year => $_[0][2]
330                       },
331                       {
332
333                         !defined($_[0][8]) ? () : (
334                         tracks => [
335                           {
336                             title => $_[0][8]
337                           },
338                           undef,
339                           [ $_[0][6], $_[0][8] ]
340                         ])
341
342                       },
343                       [ $_[0][6] ]
344                     ]),
345
346                   },
347                   [ $_[0][1] ],
348                 ],
349               },
350               [ $_[0][1] ],
351             ],
352           },
353           [ $_[0][1] ],
354         ],
355
356         !defined($_[0][5]) ? () : (
357         tracks => [
358           {
359             title => $_[0][5],
360           },
361           {
362
363             lyrics => [
364               {},
365               {
366
367                 !defined($_[0][0]) ? () : (
368                 lyric_versions => [
369                   {
370                     text => $_[0][0]
371                   },
372                   undef,
373                   [ $_[0][0], $_[0][1], $_[0][5] ],
374                 ]),
375
376               },
377               [ $_[0][1], $_[0][5] ],
378             ],
379
380           },
381           [ $_[0][1], $_[0][5] ],
382         ]),
383       },
384       [ $_[0][1] ],
385     ];
386   }),
387   'Deparsed version of the parser coderef looks correct',
388 );
389
390 done_testing;