Functional row-parse generator - really works!!!
[dbsrgits/DBIx-Class.git] / t / prefetch / _internals.t
CommitLineData
9f6555d3 1use strict;
2use warnings;
3
3904d3c3 4use Data::Dumper;
5BEGIN { $Data::Dumper::Sortkeys = 1 }; # so we can compare the deparsed coderefs below
6
9f6555d3 7use Test::More;
8use lib qw(t/lib);
9use DBICTest;
3904d3c3 10use B::Deparse;
11
9f6555d3 12
13my $schema = DBICTest->init_schema(no_deploy => 1);
14
3904d3c3 15my ($as, $vals, @pairs);
9f6555d3 16
3904d3c3 17# artwork-artist deliberately mixed around
18@pairs = (
19 'artwork_to_artist.artist_id' => '2',
9f6555d3 20
3904d3c3 21 'cd_id' => '1',
9f6555d3 22
3904d3c3 23 'artwork_to_artist.artwork_cd_id' => '1',
9f6555d3 24
3904d3c3 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',
9f6555d3 32);
3904d3c3 33while (@pairs) {
34 push @$as, shift @pairs;
35 push @$vals, shift @pairs;
36}
37
38my $parser = $schema->source ('Artwork')->_mk_row_parser($as, 'collapse requested');
9f6555d3 39
40is_deeply (
3904d3c3 41 $parser->($vals),
9f6555d3 42 [
43 {
3904d3c3 44 cd_id => 1,
9f6555d3 45 },
3904d3c3 46
9f6555d3 47 {
3904d3c3 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
9f6555d3 63 ],
64
3904d3c3 65 cd => [
9f6555d3 66 {
3904d3c3 67 artist => 1,
68 cdid => 1,
69 title => 'Spoonful of bees',
9f6555d3 70 },
71 {
3904d3c3 72 artist => [
9f6555d3 73 {
3904d3c3 74 artistid => 7,
75 name => 'Caterwauler McCrae',
76 },
77 undef,
78 [ 7 ], # our own id
9f6555d3 79 ]
3904d3c3 80 },
81 [ 1 ], # our cdid fk
9f6555d3 82 ]
3904d3c3 83 },
84 [ 1 ], # our id
9f6555d3 85 ],
3904d3c3 86 'generated row parser works as expected',
9f6555d3 87);
88
3904d3c3 89undef $_ 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',
9f6555d3 95);
3904d3c3 96while (@pairs) {
97 push @$as, shift @pairs;
98 push @$vals, shift @pairs;
99}
100$parser = $schema->source ('Artist')->_mk_row_parser($as);
101
9f6555d3 102is_deeply (
3904d3c3 103 $parser->($vals),
9f6555d3 104 [
105 {
3904d3c3 106 name => 'Caterwauler McCrae'
9f6555d3 107 },
108 {
3904d3c3 109 cds => [
9f6555d3 110 {},
111 {
3904d3c3 112 tracks => [
9f6555d3 113 {
3904d3c3 114 cd => 3,
115 title => 'Fowlin'
9f6555d3 116 },
117 {
3904d3c3 118 cd_single => [
9f6555d3 119 {
120 title => 'Awesome single',
121 },
122 ],
123 },
124 ]
125 }
126 ]
127 }
128 ],
3904d3c3 129 'generated parser works as expected over missing joins (no collapse)',
9f6555d3 130);
131
3904d3c3 132undef $_ 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)',
d4d8e97b 144);
3904d3c3 145while (@pairs) {
146 push @$as, shift @pairs;
147 push @$vals, shift @pairs;
148}
d4d8e97b 149
150is_deeply (
3904d3c3 151 $schema->source ('CD')->_resolve_collapse ( { map { $as->[$_] => $_ } (0 .. $#$as) } ),
d4d8e97b 152 {
153 -collapse_on => {
3904d3c3 154 'existing_single_track.cd.artist.artistid' => 1,
d4d8e97b 155 },
156
3904d3c3 157 existing_single_track => {
d4d8e97b 158 -collapse_on => {
3904d3c3 159 'existing_single_track.cd.artist.artistid' => 1,
d4d8e97b 160 },
161
162 cd => {
163 -collapse_on => {
3904d3c3 164 'existing_single_track.cd.artist.artistid' => 1,
d4d8e97b 165 },
166
167 artist => {
168 -collapse_on => {
3904d3c3 169 'existing_single_track.cd.artist.artistid' => 1,
d4d8e97b 170 },
171
172 cds => {
173 -collapse_on => {
3904d3c3 174 'existing_single_track.cd.artist.cds.cdid' => 6,
d4d8e97b 175 },
176
177 tracks => {
178 -collapse_on => {
3904d3c3 179 'existing_single_track.cd.artist.cds.cdid' => 6,
180 'existing_single_track.cd.artist.cds.tracks.title' => 8,
d4d8e97b 181 }
182 }
183 }
184 }
185 }
186 },
187 tracks => {
188 -collapse_on => {
3904d3c3 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 },
d4d8e97b 207 }
208 },
3904d3c3 209 'Correct collapse map constructed',
210);
211
212
213$parser = $schema->source ('CD')->_mk_row_parser ($as, 'add collapse data');
214
215is_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:
300my $deparser = B::Deparse->new;
301is (
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',
d4d8e97b 388);
389
9f6555d3 390done_testing;