Commit | Line | Data |
4e9fc3f3 |
1 | use strict; |
2 | use warnings; |
3 | |
4 | use Test::More; |
5 | use lib qw(t/lib); |
6 | use DBICTest; |
7 | use B::Deparse; |
01b25f12 |
8 | use DBIx::Class::_Util 'perlstring'; |
4e9fc3f3 |
9 | |
7d5371dc |
10 | # globally set for the rest of test |
11 | # the rowparser maker does not order its hashes by default for the miniscule |
12 | # speed gain. But it does not disable sorting either - for this test |
13 | # everything will be ordered nicely, and the hash randomization of 5.18 |
14 | # will not trip up anything |
15 | use Data::Dumper; |
16 | $Data::Dumper::Sortkeys = 1; |
17 | |
4e9fc3f3 |
18 | my $schema = DBICTest->init_schema(no_deploy => 1); |
ce556881 |
19 | my $infmap = [qw/ |
20 | single_track.cd.artist.name |
21 | year |
22 | /]; |
4e9fc3f3 |
23 | |
24 | is_same_src ( |
02a73c96 |
25 | ($schema->source ('CD')->_mk_row_parser({ |
4e9fc3f3 |
26 | inflate_map => $infmap, |
02a73c96 |
27 | }))[0], |
4e9fc3f3 |
28 | '$_ = [ |
29 | { year => $_->[1] }, |
52864fbd |
30 | { single_track => ( ! defined( $_->[0]) ) |
31 | ? bless( [ |
4e9fc3f3 |
32 | undef, |
52864fbd |
33 | { cd => [ |
34 | undef, |
35 | { artist => [ |
36 | { name => $_->[0] }, |
37 | ] }, |
4e9fc3f3 |
38 | ] }, |
52864fbd |
39 | ], __NBC__ ) |
40 | : [ |
41 | undef, |
42 | { cd => [ |
43 | undef, |
44 | { artist => [ |
45 | { name => $_->[0] }, |
46 | ] }, |
47 | ] }, |
48 | ] |
49 | }, |
4e9fc3f3 |
50 | ] for @{$_[0]}', |
51 | 'Simple 1:1 descending non-collapsing parser', |
52 | ); |
53 | |
54 | $infmap = [qw/ |
3faac878 |
55 | single_track.cd.artist.cds.tracks.title |
4e9fc3f3 |
56 | single_track.cd.artist.artistid |
57 | year |
4e9fc3f3 |
58 | single_track.cd.artist.cds.cdid |
59 | title |
60 | artist |
61 | /]; |
4e9fc3f3 |
62 | |
ce556881 |
63 | is_same_src ( |
02a73c96 |
64 | ($schema->source ('CD')->_mk_row_parser({ |
ce556881 |
65 | inflate_map => $infmap, |
02a73c96 |
66 | }))[0], |
ce556881 |
67 | '$_ = [ |
68 | { artist => $_->[5], title => $_->[4], year => $_->[2] }, |
69 | { |
52864fbd |
70 | single_track => ( (! defined $_->[0] ) && (! defined $_->[1]) && (! defined $_->[3] ) ) |
71 | ? bless( [ |
72 | undef, |
73 | { |
74 | cd => [ |
75 | undef, |
76 | { |
77 | artist => [ |
78 | { artistid => $_->[1] }, |
79 | { |
80 | cds => ( (! defined $_->[0] ) && ( ! defined $_->[3] ) ) |
81 | ? bless ([ |
82 | { cdid => $_->[3] }, |
83 | { |
84 | tracks => ( ! defined $_->[0] ) |
85 | ? bless ( [{ title => $_->[0] }], __NBC__ ) |
86 | : [{ title => $_->[0] }] |
87 | } |
88 | ], __NBC__) |
89 | : [ |
90 | { cdid => $_->[3] }, |
91 | { |
92 | tracks => ( ! defined $_->[0] ) |
93 | ? bless ( [{ title => $_->[0] }], __NBC__ ) |
94 | : [{ title => $_->[0] }] |
95 | } |
96 | ] |
97 | } |
98 | ] |
99 | } |
100 | ] |
101 | } |
102 | ], __NBC__) |
103 | : [ |
ce556881 |
104 | undef, |
105 | { |
106 | cd => [ |
107 | undef, |
108 | { |
109 | artist => [ |
110 | { artistid => $_->[1] }, |
111 | { |
52864fbd |
112 | cds => ( (! defined $_->[0] ) && ( ! defined $_->[3] ) ) |
113 | ? bless ([ |
114 | { cdid => $_->[3] }, |
115 | { |
116 | tracks => ( ! defined $_->[0] ) |
117 | ? bless ( [{ title => $_->[0] }], __NBC__ ) |
118 | : [{ title => $_->[0] }] |
119 | } |
120 | ], __NBC__) |
121 | : [ |
ce556881 |
122 | { cdid => $_->[3] }, |
123 | { |
52864fbd |
124 | tracks => ( ! defined $_->[0] ) |
125 | ? bless ( [{ title => $_->[0] }], __NBC__ ) |
126 | : [{ title => $_->[0] }] |
ce556881 |
127 | } |
52864fbd |
128 | ] |
ce556881 |
129 | } |
130 | ] |
131 | } |
132 | ] |
133 | } |
52864fbd |
134 | ] |
ce556881 |
135 | } |
136 | ] for @{$_[0]}', |
52864fbd |
137 | '1:1 descending non-collapsing parser terminating with chained 1:M:M', |
ce556881 |
138 | ); |
139 | |
140 | is_same_src ( |
02a73c96 |
141 | ($schema->source ('CD')->_mk_row_parser({ |
79adc44f |
142 | prune_null_branches => 1, |
143 | inflate_map => $infmap, |
02a73c96 |
144 | }))[0], |
79adc44f |
145 | '$_ = [ |
146 | { artist => $_->[5], title => $_->[4], year => $_->[2] }, |
147 | { |
148 | single_track => ( (! defined $_->[0] ) && (! defined $_->[1]) && (! defined $_->[3] ) ) ? undef : [ |
149 | undef, |
150 | { |
151 | cd => [ |
152 | undef, |
153 | { |
154 | artist => [ |
155 | { artistid => $_->[1] }, |
156 | { |
157 | cds => ( (! defined $_->[0] ) && ( ! defined $_->[3] ) ) ? undef : [ |
158 | { cdid => $_->[3] }, |
159 | { |
160 | tracks => ( ! defined $_->[0] ) ? undef : [ |
161 | { title => $_->[0] }, |
162 | ] |
163 | } |
164 | ] |
165 | } |
166 | ] |
167 | } |
168 | ] |
169 | } |
170 | ] |
171 | } |
172 | ] for @{$_[0]}', |
173 | '1:1 descending non-collapsing pruning parser terminating with chained 1:M:M', |
174 | ); |
175 | |
176 | is_same_src ( |
02a73c96 |
177 | ($schema->source ('CD')->_mk_row_parser({ |
ce556881 |
178 | hri_style => 1, |
79adc44f |
179 | prune_null_branches => 1, |
ce556881 |
180 | inflate_map => $infmap, |
02a73c96 |
181 | }))[0], |
ce556881 |
182 | '$_ = { |
183 | artist => $_->[5], title => $_->[4], year => $_->[2], |
184 | |
52864fbd |
185 | ( single_track => ( (! defined $_->[0] ) && (! defined $_->[1]) && (! defined $_->[3] ) ) |
186 | ? undef |
187 | : { |
ce556881 |
188 | cd => |
189 | { |
190 | artist => { |
191 | artistid => $_->[1], |
52864fbd |
192 | ( cds => ( (! defined $_->[0] ) && ( ! defined $_->[3] ) ) |
193 | ? undef |
194 | : { |
ce556881 |
195 | cdid => $_->[3], |
52864fbd |
196 | ( tracks => ( ! defined $_->[0] ) |
197 | ? undef |
198 | : { title => $_->[0] } |
199 | ) |
ce556881 |
200 | } |
52864fbd |
201 | ) |
ce556881 |
202 | } |
203 | } |
204 | } |
52864fbd |
205 | ) |
ce556881 |
206 | } for @{$_[0]}', |
52864fbd |
207 | '1:1 descending non-collapsing HRI-direct parser terminating with chained 1:M:M', |
ce556881 |
208 | ); |
209 | |
210 | |
211 | |
4e9fc3f3 |
212 | is_deeply ( |
3faac878 |
213 | ($schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} })), |
4e9fc3f3 |
214 | { |
9f98c4b2 |
215 | -identifying_columns => [ 4, 5 ], |
4e9fc3f3 |
216 | |
217 | single_track => { |
a0726a33 |
218 | -identifying_columns => [ 1, 4, 5 ], |
4e9fc3f3 |
219 | -is_optional => 1, |
220 | -is_single => 1, |
221 | |
222 | cd => { |
a0726a33 |
223 | -identifying_columns => [ 1, 4, 5 ], |
4e9fc3f3 |
224 | -is_single => 1, |
225 | |
226 | artist => { |
a0726a33 |
227 | -identifying_columns => [ 1, 4, 5 ], |
4e9fc3f3 |
228 | -is_single => 1, |
229 | |
230 | cds => { |
a0726a33 |
231 | -identifying_columns => [ 1, 3, 4, 5 ], |
4e9fc3f3 |
232 | -is_optional => 1, |
233 | |
234 | tracks => { |
a0726a33 |
235 | -identifying_columns => [ 0, 1, 3, 4, 5 ], |
4e9fc3f3 |
236 | -is_optional => 1, |
237 | }, |
238 | }, |
239 | }, |
240 | }, |
241 | }, |
242 | }, |
243 | 'Correct collapse map for 1:1 descending chain terminating with chained 1:M:M' |
244 | ); |
245 | |
246 | is_same_src ( |
02a73c96 |
247 | ($schema->source ('CD')->_mk_row_parser({ |
4e9fc3f3 |
248 | inflate_map => $infmap, |
249 | collapse => 1, |
02a73c96 |
250 | }))[0], |
aa1d8a87 |
251 | ' my $rows_pos = 0; |
252 | my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids); |
4e9fc3f3 |
253 | |
9f98c4b2 |
254 | while ($cur_row_data = ( |
164aab8c |
255 | ( |
256 | $rows_pos >= 0 |
257 | and |
258 | ( |
259 | $_[0][$rows_pos++] |
260 | or |
261 | ( ($rows_pos = -1), undef ) |
262 | ) |
263 | ) |
264 | or |
265 | ( $_[1] and $_[1]->() ) |
3b4cd124 |
266 | ) ) { |
4e9fc3f3 |
267 | |
c863e102 |
268 | @cur_row_ids{0,1,3,4,5} = ( |
269 | ( $cur_row_data->[0] // "\0NULL\xFF$rows_pos\xFF0\0" ), |
270 | ( $cur_row_data->[1] // "\0NULL\xFF$rows_pos\xFF1\0" ), |
271 | ( $cur_row_data->[3] // "\0NULL\xFF$rows_pos\xFF3\0" ), |
272 | ( $cur_row_data->[4] // "\0NULL\xFF$rows_pos\xFF4\0" ), |
273 | ( $cur_row_data->[5] // "\0NULL\xFF$rows_pos\xFF5\0" ), |
274 | ); |
4e9fc3f3 |
275 | |
3faac878 |
276 | # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2] |
aa1d8a87 |
277 | $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}} and (unshift @{$_[2]}, $cur_row_data) and last; |
4e9fc3f3 |
278 | |
3faac878 |
279 | # the rowdata itself for root node |
cd784aab |
280 | $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}} //= $_[0][$result_pos++] = [{ artist => $cur_row_data->[5], title => $cur_row_data->[4], year => $cur_row_data->[2] }]; |
3faac878 |
281 | |
282 | # prefetch data of single_track (placed in root) |
cd784aab |
283 | $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{single_track} //= $collapse_idx[1]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}} = []; |
52864fbd |
284 | defined($cur_row_data->[1]) or bless( $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{single_track}, __NBC__ ); |
3faac878 |
285 | |
286 | # prefetch data of cd (placed in single_track) |
cd784aab |
287 | $collapse_idx[1]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{cd} //= $collapse_idx[2]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}} = []; |
4e9fc3f3 |
288 | |
3faac878 |
289 | # prefetch data of artist ( placed in single_track->cd) |
cd784aab |
290 | $collapse_idx[2]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{artist} //= $collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}} = [{ artistid => $cur_row_data->[1] }]; |
3faac878 |
291 | |
292 | # prefetch data of cds (if available) |
ce556881 |
293 | (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} ) |
294 | and |
295 | push @{$collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{cds}}, ( |
296 | $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} = [{ cdid => $cur_row_data->[3] }] |
297 | ); |
52864fbd |
298 | defined($cur_row_data->[3]) or bless( $collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{cds}, __NBC__ ); |
4e9fc3f3 |
299 | |
3faac878 |
300 | # prefetch data of tracks (if available) |
ce556881 |
301 | (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} ) |
302 | and |
303 | push @{$collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{tracks}}, ( |
304 | $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[0] }] |
305 | ); |
52864fbd |
306 | defined($cur_row_data->[0]) or bless( $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{tracks}, __NBC__ ); |
4e9fc3f3 |
307 | |
4e9fc3f3 |
308 | } |
aa1d8a87 |
309 | $#{$_[0]} = $result_pos - 1; |
4e9fc3f3 |
310 | ', |
311 | 'Same 1:1 descending terminating with chained 1:M:M but with collapse', |
312 | ); |
313 | |
ce556881 |
314 | is_same_src ( |
02a73c96 |
315 | ($schema->source ('CD')->_mk_row_parser({ |
ce556881 |
316 | inflate_map => $infmap, |
317 | collapse => 1, |
ce556881 |
318 | hri_style => 1, |
79adc44f |
319 | prune_null_branches => 1, |
02a73c96 |
320 | }))[0], |
aa1d8a87 |
321 | ' my $rows_pos = 0; |
c863e102 |
322 | my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids); |
ce556881 |
323 | |
324 | while ($cur_row_data = ( |
164aab8c |
325 | ( |
326 | $rows_pos >= 0 |
327 | and |
328 | ( |
329 | $_[0][$rows_pos++] |
330 | or |
331 | ( ($rows_pos = -1), undef ) |
332 | ) |
333 | ) |
334 | or |
335 | ( $_[1] and $_[1]->() ) |
3b4cd124 |
336 | ) ) { |
ce556881 |
337 | |
c863e102 |
338 | @cur_row_ids{0, 1, 3, 4, 5} = @{$cur_row_data}[0, 1, 3, 4, 5]; |
339 | |
ce556881 |
340 | # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2] |
c863e102 |
341 | $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}} and (unshift @{$_[2]}, $cur_row_data) and last; |
ce556881 |
342 | |
343 | # the rowdata itself for root node |
c863e102 |
344 | $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}} //= $_[0][$result_pos++] = { artist => $cur_row_data->[5], title => $cur_row_data->[4], year => $cur_row_data->[2] }; |
ce556881 |
345 | |
346 | # prefetch data of single_track (placed in root) |
c863e102 |
347 | (! defined($cur_row_data->[1]) ) ? $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}}{single_track} = undef : do { |
348 | $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}}{single_track} //= $collapse_idx[1]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}; |
ce556881 |
349 | |
7596ddca |
350 | # prefetch data of cd (placed in single_track) |
c863e102 |
351 | $collapse_idx[1]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}{cd} //= $collapse_idx[2]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}; |
ce556881 |
352 | |
7596ddca |
353 | # prefetch data of artist ( placed in single_track->cd) |
c863e102 |
354 | $collapse_idx[2]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}{artist} //= $collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}} = { artistid => $cur_row_data->[1] }; |
ce556881 |
355 | |
7596ddca |
356 | # prefetch data of cds (if available) |
c863e102 |
357 | (! defined $cur_row_data->[3] ) ? $collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}{cds} = [] : do { |
ce556881 |
358 | |
c863e102 |
359 | (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} ) |
7596ddca |
360 | and |
c863e102 |
361 | push @{$collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}{cds}}, ( |
362 | $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} = { cdid => $cur_row_data->[3] } |
7596ddca |
363 | ); |
ce556881 |
364 | |
7596ddca |
365 | # prefetch data of tracks (if available) |
c863e102 |
366 | ( ! defined $cur_row_data->[0] ) ? $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}}{tracks} = [] : do { |
7596ddca |
367 | |
c863e102 |
368 | (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} ) |
7596ddca |
369 | and |
c863e102 |
370 | push @{$collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}}{tracks}}, ( |
371 | $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} = { title => $cur_row_data->[0] } |
7596ddca |
372 | ); |
373 | }; |
374 | }; |
375 | }; |
ce556881 |
376 | } |
aa1d8a87 |
377 | $#{$_[0]} = $result_pos - 1; |
ce556881 |
378 | ', |
52864fbd |
379 | 'Same 1:1 descending terminating with chained 1:M:M but with collapse, HRI-direct', |
ce556881 |
380 | ); |
381 | |
4e9fc3f3 |
382 | $infmap = [qw/ |
3d8caf63 |
383 | tracks.lyrics.existing_lyric_versions.text |
4e9fc3f3 |
384 | existing_single_track.cd.artist.artistid |
385 | existing_single_track.cd.artist.cds.year |
386 | year |
387 | genreid |
388 | tracks.title |
389 | existing_single_track.cd.artist.cds.cdid |
390 | latest_cd |
391 | existing_single_track.cd.artist.cds.tracks.title |
392 | existing_single_track.cd.artist.cds.genreid |
3d8caf63 |
393 | tracks.lyrics.existing_lyric_versions.lyric_id |
4e9fc3f3 |
394 | /]; |
395 | |
396 | is_deeply ( |
82f0e0aa |
397 | $schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} }), |
4e9fc3f3 |
398 | { |
9f98c4b2 |
399 | -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid |
4e9fc3f3 |
400 | |
401 | existing_single_track => { |
9f98c4b2 |
402 | -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid |
4e9fc3f3 |
403 | -is_single => 1, |
404 | |
405 | cd => { |
9f98c4b2 |
406 | -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid |
4e9fc3f3 |
407 | -is_single => 1, |
408 | |
409 | artist => { |
9f98c4b2 |
410 | -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid |
4e9fc3f3 |
411 | -is_single => 1, |
412 | |
413 | cds => { |
9f98c4b2 |
414 | -identifying_columns => [ 1, 6 ], # existing_single_track.cd.artist.cds.cdid |
4e9fc3f3 |
415 | -is_optional => 1, |
416 | |
417 | tracks => { |
9f98c4b2 |
418 | -identifying_columns => [ 1, 6, 8 ], # existing_single_track.cd.artist.cds.cdid, existing_single_track.cd.artist.cds.tracks.title |
4e9fc3f3 |
419 | -is_optional => 1, |
420 | } |
421 | } |
422 | } |
423 | } |
424 | }, |
425 | tracks => { |
9f98c4b2 |
426 | -identifying_columns => [ 1, 5 ], # existing_single_track.cd.artist.artistid, tracks.title |
4e9fc3f3 |
427 | -is_optional => 1, |
428 | |
429 | lyrics => { |
3d8caf63 |
430 | -identifying_columns => [ 1, 5, 10 ], # existing_single_track.cd.artist.artistid, tracks.title, tracks.lyrics.existing_lyric_versions.lyric_id |
4e9fc3f3 |
431 | -is_single => 1, |
432 | -is_optional => 1, |
433 | |
3d8caf63 |
434 | existing_lyric_versions => { |
435 | -identifying_columns => [ 0, 1, 5, 10 ], # tracks.lyrics.existing_lyric_versions.text, existing_single_track.cd.artist.artistid, tracks.title, tracks.lyrics.existing_lyric_versions.lyric_id |
4e9fc3f3 |
436 | }, |
437 | }, |
438 | } |
439 | }, |
440 | 'Correct collapse map constructed', |
441 | ); |
442 | |
443 | is_same_src ( |
02a73c96 |
444 | ($schema->source ('CD')->_mk_row_parser({ |
4e9fc3f3 |
445 | inflate_map => $infmap, |
446 | collapse => 1, |
02a73c96 |
447 | }))[0], |
aa1d8a87 |
448 | ' my $rows_pos = 0; |
449 | my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids); |
4e9fc3f3 |
450 | |
9f98c4b2 |
451 | while ($cur_row_data = ( |
164aab8c |
452 | ( |
453 | $rows_pos >= 0 |
454 | and |
455 | ( |
456 | $_[0][$rows_pos++] |
457 | or |
458 | ( ($rows_pos = -1), undef ) |
459 | ) |
460 | ) |
461 | or |
462 | ( $_[1] and $_[1]->() ) |
3b4cd124 |
463 | ) ) { |
4e9fc3f3 |
464 | |
c863e102 |
465 | @cur_row_ids{0, 1, 5, 6, 8, 10} = ( |
466 | $cur_row_data->[0] // "\0NULL\xFF$rows_pos\xFF0\0", |
467 | $cur_row_data->[1] // "\0NULL\xFF$rows_pos\xFF1\0", |
468 | $cur_row_data->[5] // "\0NULL\xFF$rows_pos\xFF5\0", |
469 | $cur_row_data->[6] // "\0NULL\xFF$rows_pos\xFF6\0", |
470 | $cur_row_data->[8] // "\0NULL\xFF$rows_pos\xFF8\0", |
471 | $cur_row_data->[10] // "\0NULL\xFF$rows_pos\xFF10\0", |
472 | ); |
4e9fc3f3 |
473 | |
9f98c4b2 |
474 | # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2] |
aa1d8a87 |
475 | $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{1}} and (unshift @{$_[2]}, $cur_row_data) and last; |
4e9fc3f3 |
476 | |
cd784aab |
477 | $collapse_idx[0]{$cur_row_ids{1}} //= $_[0][$result_pos++] = [{ genreid => $cur_row_data->[4], latest_cd => $cur_row_data->[7], year => $cur_row_data->[3] }]; |
4e9fc3f3 |
478 | |
cd784aab |
479 | $collapse_idx[0]{$cur_row_ids{1}}[1]{existing_single_track} //= $collapse_idx[1]{$cur_row_ids{1}} = []; |
480 | $collapse_idx[1]{$cur_row_ids{1}}[1]{cd} //= $collapse_idx[2]{$cur_row_ids{1}} = []; |
481 | $collapse_idx[2]{$cur_row_ids{1}}[1]{artist} //= $collapse_idx[3]{$cur_row_ids{1}} = [{ artistid => $cur_row_data->[1] }]; |
4e9fc3f3 |
482 | |
ce556881 |
483 | (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} ) |
484 | and |
485 | push @{ $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} }, ( |
486 | $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} = [{ cdid => $cur_row_data->[6], genreid => $cur_row_data->[9], year => $cur_row_data->[2] }] |
487 | ); |
52864fbd |
488 | defined($cur_row_data->[6]) or bless( $collapse_idx[3]{$cur_row_ids{1}}[1]{cds}, __NBC__ ); |
4e9fc3f3 |
489 | |
ce556881 |
490 | (! $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} ) |
491 | and |
492 | push @{ $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} }, ( |
493 | $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }] |
494 | ); |
52864fbd |
495 | defined($cur_row_data->[8]) or bless( $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks}, __NBC__ ); |
4e9fc3f3 |
496 | |
ce556881 |
497 | (! $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} ) |
498 | and |
499 | push @{ $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} }, ( |
500 | $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[5] }] |
501 | ); |
52864fbd |
502 | defined($cur_row_data->[5]) or bless( $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks}, __NBC__ ); |
4e9fc3f3 |
503 | |
cd784aab |
504 | $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics} //= $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} = []; |
52864fbd |
505 | defined($cur_row_data->[10]) or bless( $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics}, __NBC__ ); |
4e9fc3f3 |
506 | |
ce556881 |
507 | (! $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} ) |
508 | and |
509 | push @{ $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}}[1]{existing_lyric_versions} }, ( |
510 | $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} = [{ lyric_id => $cur_row_data->[10], text => $cur_row_data->[0] }] |
511 | ); |
4e9fc3f3 |
512 | } |
513 | |
aa1d8a87 |
514 | $#{$_[0]} = $result_pos - 1; |
4e9fc3f3 |
515 | ', |
516 | 'Multiple has_many on multiple branches torture test', |
517 | ); |
518 | |
ce556881 |
519 | is_same_src ( |
02a73c96 |
520 | ($schema->source ('CD')->_mk_row_parser({ |
ce556881 |
521 | inflate_map => $infmap, |
522 | collapse => 1, |
79adc44f |
523 | prune_null_branches => 1, |
02a73c96 |
524 | }))[0], |
aa1d8a87 |
525 | ' my $rows_pos = 0; |
c863e102 |
526 | my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids); |
ce556881 |
527 | |
528 | while ($cur_row_data = ( |
164aab8c |
529 | ( |
530 | $rows_pos >= 0 |
531 | and |
532 | ( |
533 | $_[0][$rows_pos++] |
534 | or |
535 | ( ($rows_pos = -1), undef ) |
536 | ) |
537 | ) |
538 | or |
539 | ( $_[1] and $_[1]->() ) |
3b4cd124 |
540 | ) ) { |
ce556881 |
541 | |
c863e102 |
542 | @cur_row_ids{( 0, 1, 5, 6, 8, 10 )} = @{$cur_row_data}[( 0, 1, 5, 6, 8, 10 )]; |
543 | |
ce556881 |
544 | # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2] |
c863e102 |
545 | $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{1}} and (unshift @{$_[2]}, $cur_row_data) and last; |
ce556881 |
546 | |
c863e102 |
547 | $collapse_idx[0]{$cur_row_ids{1}} //= $_[0][$result_pos++] = [{ genreid => $cur_row_data->[4], latest_cd => $cur_row_data->[7], year => $cur_row_data->[3] }]; |
ce556881 |
548 | |
c863e102 |
549 | $collapse_idx[0]{$cur_row_ids{1}}[1]{existing_single_track} //= $collapse_idx[1]{$cur_row_ids{1}} = []; |
550 | $collapse_idx[1]{$cur_row_ids{1}}[1]{cd} //= $collapse_idx[2]{$cur_row_ids{1}} = []; |
551 | $collapse_idx[2]{$cur_row_ids{1}}[1]{artist} //= $collapse_idx[3]{$cur_row_ids{1}} = [{ artistid => $cur_row_data->[1] }]; |
ce556881 |
552 | |
c863e102 |
553 | (! defined($cur_row_data->[6])) ? $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} = [] : do { |
554 | (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} ) |
79adc44f |
555 | and |
c863e102 |
556 | push @{ $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} }, ( |
557 | $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} = [{ cdid => $cur_row_data->[6], genreid => $cur_row_data->[9], year => $cur_row_data->[2] }] |
79adc44f |
558 | ); |
ce556881 |
559 | |
c863e102 |
560 | (! defined($cur_row_data->[8]) ) ? $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} = [] : do { |
ce556881 |
561 | |
c863e102 |
562 | (! $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} ) |
79adc44f |
563 | and |
c863e102 |
564 | push @{ $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} }, ( |
565 | $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }] |
79adc44f |
566 | ); |
567 | }; |
568 | }; |
ce556881 |
569 | |
c863e102 |
570 | (! defined($cur_row_data->[5]) ) ? $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} = [] : do { |
ce556881 |
571 | |
c863e102 |
572 | (! $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} ) |
79adc44f |
573 | and |
c863e102 |
574 | push @{ $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} }, ( |
575 | $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[5] }] |
79adc44f |
576 | ); |
577 | |
c863e102 |
578 | (! defined($cur_row_data->[10]) ) ? $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics} = [] : do { |
79adc44f |
579 | |
c863e102 |
580 | $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics} //= $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} = []; |
79adc44f |
581 | |
c863e102 |
582 | (! $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} ) |
79adc44f |
583 | and |
c863e102 |
584 | push @{ $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}}[1]{existing_lyric_versions} }, ( |
585 | $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} = [{ lyric_id => $cur_row_data->[10], text => $cur_row_data->[0] }] |
79adc44f |
586 | ); |
587 | }; |
588 | }; |
ce556881 |
589 | } |
590 | |
aa1d8a87 |
591 | $#{$_[0]} = $result_pos - 1; |
ce556881 |
592 | ', |
79adc44f |
593 | 'Multiple has_many on multiple branches with branch pruning torture test', |
ce556881 |
594 | ); |
595 | |
fcf32d04 |
596 | $infmap = [ |
597 | 'single_track.trackid', # (0) definitive link to root from 1:1:1:1:M:M chain |
598 | 'year', # (1) non-unique |
599 | 'tracks.cd', # (2) \ together both uniqueness for second multirel |
600 | 'tracks.title', # (3) / and definitive link back to root |
601 | 'single_track.cd.artist.cds.cdid', # (4) to give uniquiness to ...tracks.title below |
602 | 'single_track.cd.artist.cds.year', # (5) non-unique |
603 | 'single_track.cd.artist.artistid', # (6) uniqufies entire parental chain |
604 | 'single_track.cd.artist.cds.genreid', # (7) nullable |
605 | 'single_track.cd.artist.cds.tracks.title',# (8) unique when combined with ...cds.cdid above |
606 | ]; |
607 | |
608 | is_deeply ( |
609 | $schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} }), |
610 | { |
9f98c4b2 |
611 | -identifying_columns => [], |
612 | -identifying_columns_variants => [ |
fcf32d04 |
613 | [ 0 ], [ 2 ], |
614 | ], |
615 | single_track => { |
9f98c4b2 |
616 | -identifying_columns => [ 0 ], |
fcf32d04 |
617 | -is_optional => 1, |
618 | -is_single => 1, |
fcf32d04 |
619 | cd => { |
9f98c4b2 |
620 | -identifying_columns => [ 0 ], |
fcf32d04 |
621 | -is_single => 1, |
fcf32d04 |
622 | artist => { |
9f98c4b2 |
623 | -identifying_columns => [ 0 ], |
fcf32d04 |
624 | -is_single => 1, |
fcf32d04 |
625 | cds => { |
9f98c4b2 |
626 | -identifying_columns => [ 0, 4 ], |
fcf32d04 |
627 | -is_optional => 1, |
fcf32d04 |
628 | tracks => { |
9f98c4b2 |
629 | -identifying_columns => [ 0, 4, 8 ], |
fcf32d04 |
630 | -is_optional => 1, |
fcf32d04 |
631 | } |
632 | } |
633 | } |
634 | } |
635 | }, |
636 | tracks => { |
9f98c4b2 |
637 | -identifying_columns => [ 2, 3 ], |
fcf32d04 |
638 | -is_optional => 1, |
fcf32d04 |
639 | } |
640 | }, |
641 | 'Correct underdefined root collapse map constructed' |
642 | ); |
643 | |
644 | is_same_src ( |
02a73c96 |
645 | ($schema->source ('CD')->_mk_row_parser({ |
fcf32d04 |
646 | inflate_map => $infmap, |
647 | collapse => 1, |
02a73c96 |
648 | }))[0], |
aa1d8a87 |
649 | ' my $rows_pos = 0; |
650 | my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids); |
fcf32d04 |
651 | |
9f98c4b2 |
652 | while ($cur_row_data = ( |
164aab8c |
653 | ( |
654 | $rows_pos >= 0 |
655 | and |
656 | ( |
657 | $_[0][$rows_pos++] |
658 | or |
659 | ( ($rows_pos = -1), undef ) |
660 | ) |
661 | ) |
662 | or |
663 | ( $_[1] and $_[1]->() ) |
3b4cd124 |
664 | ) ) { |
fcf32d04 |
665 | |
c863e102 |
666 | @cur_row_ids{( 0, 2, 3, 4, 8 )} = ( |
667 | $cur_row_data->[0] // "\0NULL\xFF$rows_pos\xFF0\0", |
668 | $cur_row_data->[2] // "\0NULL\xFF$rows_pos\xFF2\0", |
669 | $cur_row_data->[3] // "\0NULL\xFF$rows_pos\xFF3\0", |
670 | $cur_row_data->[4] // "\0NULL\xFF$rows_pos\xFF4\0", |
671 | $cur_row_data->[8] // "\0NULL\xFF$rows_pos\xFF8\0", |
672 | ); |
fcf32d04 |
673 | |
674 | # cache expensive set of ops in a non-existent rowid slot |
9f98c4b2 |
675 | $cur_row_ids{10} = ( |
c863e102 |
676 | ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_ids{0}, q{} )) |
fcf32d04 |
677 | or |
c863e102 |
678 | ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_ids{2}, q{} )) |
fcf32d04 |
679 | or |
680 | "\0$rows_pos\0" |
681 | ); |
682 | |
9f98c4b2 |
683 | # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2] |
aa1d8a87 |
684 | $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{10}} and (unshift @{$_[2]}, $cur_row_data) and last; |
fcf32d04 |
685 | |
cd784aab |
686 | $collapse_idx[0]{$cur_row_ids{10}} //= $_[0][$result_pos++] = [{ year => $$cur_row_data[1] }]; |
fcf32d04 |
687 | |
cd784aab |
688 | $collapse_idx[0]{$cur_row_ids{10}}[1]{single_track} //= ($collapse_idx[1]{$cur_row_ids{0}} = [{ trackid => $cur_row_data->[0] }]); |
52864fbd |
689 | defined($cur_row_data->[0]) or bless ( $collapse_idx[0]{$cur_row_ids{10}}[1]{single_track}, __NBC__ ); |
fcf32d04 |
690 | |
cd784aab |
691 | $collapse_idx[1]{$cur_row_ids{0}}[1]{cd} //= $collapse_idx[2]{$cur_row_ids{0}} = []; |
fcf32d04 |
692 | |
cd784aab |
693 | $collapse_idx[2]{$cur_row_ids{0}}[1]{artist} //= ($collapse_idx[3]{$cur_row_ids{0}} = [{ artistid => $cur_row_data->[6] }]); |
fcf32d04 |
694 | |
ce556881 |
695 | (! $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} ) |
696 | and |
697 | push @{$collapse_idx[3]{$cur_row_ids{0}}[1]{cds}}, ( |
52864fbd |
698 | $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} = [{ cdid => $cur_row_data->[4], genreid => $cur_row_data->[7], year => $cur_row_data->[5] }] |
ce556881 |
699 | ); |
52864fbd |
700 | defined($cur_row_data->[4]) or bless ( $collapse_idx[3]{$cur_row_ids{0}}[1]{cds}, __NBC__ ); |
fcf32d04 |
701 | |
ce556881 |
702 | (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} ) |
703 | and |
704 | push @{$collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}[1]{tracks}}, ( |
52864fbd |
705 | $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }] |
ce556881 |
706 | ); |
52864fbd |
707 | defined($cur_row_data->[8]) or bless ( $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}[1]{tracks}, __NBC__ ); |
fcf32d04 |
708 | |
ce556881 |
709 | (! $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} ) |
710 | and |
711 | push @{$collapse_idx[0]{$cur_row_ids{10}}[1]{tracks}}, ( |
52864fbd |
712 | $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} = [{ cd => $$cur_row_data[2], title => $cur_row_data->[3] }] |
ce556881 |
713 | ); |
52864fbd |
714 | defined($cur_row_data->[2]) or bless ( $collapse_idx[0]{$cur_row_ids{10}}[1]{tracks}, __NBC__ ); |
fcf32d04 |
715 | } |
716 | |
aa1d8a87 |
717 | $#{$_[0]} = $result_pos - 1; |
fcf32d04 |
718 | ', |
719 | 'Multiple has_many on multiple branches with underdefined root torture test', |
720 | ); |
721 | |
ce556881 |
722 | is_same_src ( |
02a73c96 |
723 | ($schema->source ('CD')->_mk_row_parser({ |
ce556881 |
724 | inflate_map => $infmap, |
725 | collapse => 1, |
ce556881 |
726 | hri_style => 1, |
79adc44f |
727 | prune_null_branches => 1, |
02a73c96 |
728 | }))[0], |
aa1d8a87 |
729 | ' my $rows_pos = 0; |
06b3406d |
730 | my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids); |
ce556881 |
731 | |
732 | while ($cur_row_data = ( |
164aab8c |
733 | ( |
734 | $rows_pos >= 0 |
735 | and |
736 | ( |
737 | $_[0][$rows_pos++] |
738 | or |
739 | ( ($rows_pos = -1), undef ) |
740 | ) |
741 | ) |
742 | or |
743 | ( $_[1] and $_[1]->() ) |
3b4cd124 |
744 | ) ) { |
745 | |
5e6d06f4 |
746 | # do not care about nullability here |
c863e102 |
747 | @cur_row_ids{( 0, 2, 3, 4, 8 )} = @{$cur_row_data}[( 0, 2, 3, 4, 8 )]; |
06b3406d |
748 | |
ce556881 |
749 | # cache expensive set of ops in a non-existent rowid slot |
06b3406d |
750 | $cur_row_ids{10} = ( |
c863e102 |
751 | ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_ids{0}, q{} )) |
ce556881 |
752 | or |
c863e102 |
753 | ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_ids{2}, q{} )) |
ce556881 |
754 | or |
755 | "\0$rows_pos\0" |
756 | ); |
757 | |
758 | # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2] |
06b3406d |
759 | $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{10}} and (unshift @{$_[2]}, $cur_row_data) and last; |
ce556881 |
760 | |
cd784aab |
761 | $collapse_idx[0]{$cur_row_ids{10}} //= $_[0][$result_pos++] = { year => $$cur_row_data[1] }; |
ce556881 |
762 | |
06b3406d |
763 | (! defined $cur_row_data->[0] ) ? $collapse_idx[0]{$cur_row_ids{10}}{single_track} = undef : do { |
ce556881 |
764 | |
cd784aab |
765 | $collapse_idx[0]{$cur_row_ids{10}}{single_track} //= ($collapse_idx[1]{$cur_row_ids{0}} = { trackid => $$cur_row_data[0] }); |
ce556881 |
766 | |
cd784aab |
767 | $collapse_idx[1]{$cur_row_ids{0}}{cd} //= $collapse_idx[2]{$cur_row_ids{0}}; |
ce556881 |
768 | |
cd784aab |
769 | $collapse_idx[2]{$cur_row_ids{0}}{artist} //= ($collapse_idx[3]{$cur_row_ids{0}} = { artistid => $$cur_row_data[6] }); |
ce556881 |
770 | |
06b3406d |
771 | (! defined $cur_row_data->[4] ) ? $collapse_idx[3]{$cur_row_ids{0}}{cds} = [] : do { |
ce556881 |
772 | |
06b3406d |
773 | (! $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} ) |
7596ddca |
774 | and |
06b3406d |
775 | push @{$collapse_idx[3]{$cur_row_ids{0}}{cds}}, ( |
776 | $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} = { cdid => $$cur_row_data[4], genreid => $$cur_row_data[7], year => $$cur_row_data[5] } |
7596ddca |
777 | ); |
ce556881 |
778 | |
06b3406d |
779 | (! defined $cur_row_data->[8] ) ? $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}{tracks} = [] : do { |
7596ddca |
780 | |
06b3406d |
781 | (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} ) |
7596ddca |
782 | and |
06b3406d |
783 | push @{$collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}{tracks}}, ( |
784 | $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} = { title => $$cur_row_data[8] } |
7596ddca |
785 | ); |
786 | }; |
787 | }; |
788 | }; |
789 | |
06b3406d |
790 | (! defined $cur_row_data->[2] ) ? $collapse_idx[0]{$cur_row_ids{10}}{tracks} = [] : do { |
791 | (! $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} ) |
7596ddca |
792 | and |
06b3406d |
793 | push @{$collapse_idx[0]{$cur_row_ids{10}}{tracks}}, ( |
794 | $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} = { cd => $$cur_row_data[2], title => $$cur_row_data[3] } |
7596ddca |
795 | ); |
796 | }; |
ce556881 |
797 | } |
798 | |
aa1d8a87 |
799 | $#{$_[0]} = $result_pos - 1; |
ce556881 |
800 | ', |
52864fbd |
801 | 'Multiple has_many on multiple branches with underdefined root, HRI-direct torture test', |
ce556881 |
802 | ); |
803 | |
c863e102 |
804 | is_same_src ( |
805 | ($schema->source ('Owners')->_mk_row_parser({ |
806 | inflate_map => [qw( books.title books.owner )], |
807 | collapse => 1, |
808 | prune_null_branches => 1, |
809 | }))[0], |
810 | ' my $rows_pos = 0; |
811 | my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids ); |
812 | |
813 | while ($cur_row_data = ( |
164aab8c |
814 | ( |
815 | $rows_pos >= 0 |
816 | and |
817 | ( |
818 | $_[0][$rows_pos++] |
819 | or |
820 | ( ($rows_pos = -1), undef ) |
821 | ) |
822 | ) |
c863e102 |
823 | or |
164aab8c |
824 | ( $_[1] and $_[1]->() ) |
c863e102 |
825 | ) ) { |
826 | |
827 | @cur_row_ids{0,1} = @{$cur_row_data}[0,1]; |
828 | |
829 | $cur_row_ids{3} = ( |
830 | ( ( defined $cur_row_data->[1] ) && (join "\xFF", q{}, $cur_row_ids{1}, q{} )) |
831 | or |
832 | "\0${rows_pos}\0" |
833 | ); |
834 | |
835 | $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{3}} and (unshift @{$_[2]}, $cur_row_data) and last; |
836 | |
837 | # empty data for the root node |
838 | $collapse_idx[0]{$cur_row_ids{3}} //= $_[0][$result_pos++] = []; |
839 | |
840 | ( ! defined $cur_row_data->[0] ) ? $collapse_idx[0]{$cur_row_ids{3}}[1]{"books"} = [] : do { |
841 | push @{$collapse_idx[0]{$cur_row_ids{3}}[1]{books}}, |
842 | $collapse_idx[1]{$cur_row_ids{0}} = [ { owner => $cur_row_data->[1], title => $cur_row_data->[0] } ] |
843 | unless $collapse_idx[1]{$cur_row_ids{0}} |
844 | }; |
845 | } |
846 | |
847 | $#{$_[0]} = $result_pos - 1; # truncate the passed in array to where we filled it with results |
848 | ', |
849 | 'Non-premultiplied implicit collapse with missing join columns', |
850 | ); |
851 | |
4e9fc3f3 |
852 | done_testing; |
853 | |
854 | my $deparser; |
cd784aab |
855 | sub is_same_src { SKIP: { |
2fdeef65 |
856 | |
857 | skip "Skipping comparison of unicode-posioned source", 1 |
858 | if DBIx::Class::_ENV_::STRESSTEST_UTF8_UPGRADE_GENERATED_COLLAPSER_SOURCE; |
859 | |
4e9fc3f3 |
860 | $deparser ||= B::Deparse->new; |
861 | local $Test::Builder::Level = $Test::Builder::Level + 1; |
862 | |
52864fbd |
863 | my ($got, $expect) = @_; |
864 | |
cd784aab |
865 | skip "Not testing equality of source containing defined-or operator on this perl $]", 1 |
866 | if ($] < 5.010 and$expect =~ m!\Q//=!); |
867 | |
01b25f12 |
868 | $expect =~ s/__NBC__/perlstring($DBIx::Class::ResultSource::RowParser::Util::null_branch_class)/ge; |
52864fbd |
869 | |
9f7d5590 |
870 | $expect = " { use strict; use warnings FATAL => 'uninitialized';\n$expect\n }"; |
bdbd2ae8 |
871 | |
52864fbd |
872 | my @normalized = map { |
4e9fc3f3 |
873 | my $cref = eval "sub { $_ }" or do { |
874 | fail "Coderef does not compile!\n\n$@\n\n$_"; |
875 | return undef; |
876 | }; |
877 | $deparser->coderef2text($cref); |
52864fbd |
878 | } ($got, $expect); |
879 | |
880 | &is (@normalized, $_[2]||() ) or do { |
881 | eval { require Test::Differences } |
882 | ? &Test::Differences::eq_or_diff( @normalized, $_[2]||() ) |
e81b50f4 |
883 | : note ("Original sources:\n\n$got\n\n$expect\n") |
884 | ; |
885 | exit 1; |
52864fbd |
886 | }; |
cd784aab |
887 | } } |