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 = ( |
8e06d750 |
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 | |
d43f1734 |
268 | ( @cur_row_ids{0,1,3,4,5} = ( |
beb858a3 |
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" ), |
d43f1734 |
274 | ) ), |
4e9fc3f3 |
275 | |
3faac878 |
276 | # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2] |
d43f1734 |
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 |
d43f1734 |
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) |
d43f1734 |
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}} = [] ), |
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) |
d43f1734 |
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) |
d43f1734 |
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) |
d43f1734 |
293 | ( |
294 | (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} ) |
295 | and |
296 | push @{$collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{cds}}, ( |
297 | $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} = [{ cdid => $cur_row_data->[3] }] |
298 | ) |
299 | ), |
300 | ( 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 |
301 | |
3faac878 |
302 | # prefetch data of tracks (if available) |
d43f1734 |
303 | ( |
304 | (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} ) |
305 | and |
306 | push @{$collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}}[1]{tracks}}, ( |
307 | $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] }] |
308 | ) |
309 | ), |
310 | ( 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 |
311 | |
4e9fc3f3 |
312 | } |
aa1d8a87 |
313 | $#{$_[0]} = $result_pos - 1; |
4e9fc3f3 |
314 | ', |
315 | 'Same 1:1 descending terminating with chained 1:M:M but with collapse', |
316 | ); |
317 | |
ce556881 |
318 | is_same_src ( |
02a73c96 |
319 | ($schema->source ('CD')->_mk_row_parser({ |
ce556881 |
320 | inflate_map => $infmap, |
321 | collapse => 1, |
ce556881 |
322 | hri_style => 1, |
79adc44f |
323 | prune_null_branches => 1, |
02a73c96 |
324 | }))[0], |
aa1d8a87 |
325 | ' my $rows_pos = 0; |
beb858a3 |
326 | my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids); |
ce556881 |
327 | |
328 | while ($cur_row_data = ( |
8e06d750 |
329 | ( |
330 | $rows_pos >= 0 |
331 | and |
332 | ( |
333 | $_[0][$rows_pos++] |
334 | or |
335 | ( ($rows_pos = -1), undef ) |
336 | ) |
337 | ) |
338 | or |
339 | ( $_[1] and $_[1]->() ) |
3b4cd124 |
340 | ) ) { |
ce556881 |
341 | |
d43f1734 |
342 | ( @cur_row_ids{0, 1, 3, 4, 5} = @{$cur_row_data}[0, 1, 3, 4, 5] ), |
beb858a3 |
343 | |
ce556881 |
344 | # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2] |
d43f1734 |
345 | ( $_[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 |
346 | |
347 | # the rowdata itself for root node |
d43f1734 |
348 | ( $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 |
349 | |
350 | # prefetch data of single_track (placed in root) |
d43f1734 |
351 | ( (! defined($cur_row_data->[1]) ) ? $collapse_idx[0]{$cur_row_ids{4}}{$cur_row_ids{5}}{single_track} = undef : do { |
352 | ( $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 |
353 | |
7596ddca |
354 | # prefetch data of cd (placed in single_track) |
d43f1734 |
355 | ( $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 |
356 | |
7596ddca |
357 | # prefetch data of artist ( placed in single_track->cd) |
d43f1734 |
358 | ( $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 |
359 | |
7596ddca |
360 | # prefetch data of cds (if available) |
d43f1734 |
361 | ( (! defined $cur_row_data->[3] ) ? $collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}{cds} = [] : do { |
ce556881 |
362 | |
d43f1734 |
363 | ( |
364 | (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} ) |
365 | and |
366 | push @{$collapse_idx[3]{$cur_row_ids{1}}{$cur_row_ids{4}}{$cur_row_ids{5}}{cds}}, ( |
367 | $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} = { cdid => $cur_row_data->[3] } |
368 | ) |
369 | ), |
ce556881 |
370 | |
7596ddca |
371 | # prefetch data of tracks (if available) |
d43f1734 |
372 | (( ! 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 { |
373 | |
374 | ( |
375 | (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}} ) |
376 | and |
377 | push @{$collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{3}}{$cur_row_ids{4}}{$cur_row_ids{5}}{tracks}}, ( |
378 | $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] } |
379 | ) |
380 | ), |
381 | } ), |
382 | } ), |
383 | } ), |
ce556881 |
384 | } |
aa1d8a87 |
385 | $#{$_[0]} = $result_pos - 1; |
ce556881 |
386 | ', |
52864fbd |
387 | 'Same 1:1 descending terminating with chained 1:M:M but with collapse, HRI-direct', |
ce556881 |
388 | ); |
389 | |
4e9fc3f3 |
390 | $infmap = [qw/ |
3d8caf63 |
391 | tracks.lyrics.existing_lyric_versions.text |
4e9fc3f3 |
392 | existing_single_track.cd.artist.artistid |
393 | existing_single_track.cd.artist.cds.year |
394 | year |
395 | genreid |
396 | tracks.title |
397 | existing_single_track.cd.artist.cds.cdid |
398 | latest_cd |
399 | existing_single_track.cd.artist.cds.tracks.title |
400 | existing_single_track.cd.artist.cds.genreid |
3d8caf63 |
401 | tracks.lyrics.existing_lyric_versions.lyric_id |
4e9fc3f3 |
402 | /]; |
403 | |
404 | is_deeply ( |
82f0e0aa |
405 | $schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} }), |
4e9fc3f3 |
406 | { |
9f98c4b2 |
407 | -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid |
4e9fc3f3 |
408 | |
409 | existing_single_track => { |
9f98c4b2 |
410 | -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid |
4e9fc3f3 |
411 | -is_single => 1, |
412 | |
413 | cd => { |
9f98c4b2 |
414 | -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid |
4e9fc3f3 |
415 | -is_single => 1, |
416 | |
417 | artist => { |
9f98c4b2 |
418 | -identifying_columns => [ 1 ], # existing_single_track.cd.artist.artistid |
4e9fc3f3 |
419 | -is_single => 1, |
420 | |
421 | cds => { |
9f98c4b2 |
422 | -identifying_columns => [ 1, 6 ], # existing_single_track.cd.artist.cds.cdid |
4e9fc3f3 |
423 | -is_optional => 1, |
424 | |
425 | tracks => { |
9f98c4b2 |
426 | -identifying_columns => [ 1, 6, 8 ], # existing_single_track.cd.artist.cds.cdid, existing_single_track.cd.artist.cds.tracks.title |
4e9fc3f3 |
427 | -is_optional => 1, |
428 | } |
429 | } |
430 | } |
431 | } |
432 | }, |
433 | tracks => { |
9f98c4b2 |
434 | -identifying_columns => [ 1, 5 ], # existing_single_track.cd.artist.artistid, tracks.title |
4e9fc3f3 |
435 | -is_optional => 1, |
436 | |
437 | lyrics => { |
3d8caf63 |
438 | -identifying_columns => [ 1, 5, 10 ], # existing_single_track.cd.artist.artistid, tracks.title, tracks.lyrics.existing_lyric_versions.lyric_id |
4e9fc3f3 |
439 | -is_single => 1, |
440 | -is_optional => 1, |
441 | |
3d8caf63 |
442 | existing_lyric_versions => { |
443 | -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 |
444 | }, |
445 | }, |
446 | } |
447 | }, |
448 | 'Correct collapse map constructed', |
449 | ); |
450 | |
451 | is_same_src ( |
02a73c96 |
452 | ($schema->source ('CD')->_mk_row_parser({ |
4e9fc3f3 |
453 | inflate_map => $infmap, |
454 | collapse => 1, |
02a73c96 |
455 | }))[0], |
aa1d8a87 |
456 | ' my $rows_pos = 0; |
457 | my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids); |
4e9fc3f3 |
458 | |
9f98c4b2 |
459 | while ($cur_row_data = ( |
8e06d750 |
460 | ( |
461 | $rows_pos >= 0 |
462 | and |
463 | ( |
464 | $_[0][$rows_pos++] |
465 | or |
466 | ( ($rows_pos = -1), undef ) |
467 | ) |
468 | ) |
469 | or |
470 | ( $_[1] and $_[1]->() ) |
3b4cd124 |
471 | ) ) { |
4e9fc3f3 |
472 | |
d43f1734 |
473 | ( @cur_row_ids{0, 1, 5, 6, 8, 10} = ( |
beb858a3 |
474 | $cur_row_data->[0] // "\0NULL\xFF$rows_pos\xFF0\0", |
475 | $cur_row_data->[1] // "\0NULL\xFF$rows_pos\xFF1\0", |
476 | $cur_row_data->[5] // "\0NULL\xFF$rows_pos\xFF5\0", |
477 | $cur_row_data->[6] // "\0NULL\xFF$rows_pos\xFF6\0", |
478 | $cur_row_data->[8] // "\0NULL\xFF$rows_pos\xFF8\0", |
479 | $cur_row_data->[10] // "\0NULL\xFF$rows_pos\xFF10\0", |
d43f1734 |
480 | ) ), |
4e9fc3f3 |
481 | |
9f98c4b2 |
482 | # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2] |
d43f1734 |
483 | ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{1}} and (unshift @{$_[2]}, $cur_row_data) and last ), |
484 | |
485 | ( $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] }] ), |
486 | |
487 | ( $collapse_idx[0]{$cur_row_ids{1}}[1]{existing_single_track} //= $collapse_idx[1]{$cur_row_ids{1}} = [] ), |
488 | ( $collapse_idx[1]{$cur_row_ids{1}}[1]{cd} //= $collapse_idx[2]{$cur_row_ids{1}} = [] ), |
489 | ( $collapse_idx[2]{$cur_row_ids{1}}[1]{artist} //= $collapse_idx[3]{$cur_row_ids{1}} = [{ artistid => $cur_row_data->[1] }] ), |
490 | |
491 | ( |
492 | (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} ) |
493 | and |
494 | push @{ $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} }, ( |
495 | $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] }] |
496 | ) |
497 | ), |
498 | ( defined($cur_row_data->[6]) or bless( $collapse_idx[3]{$cur_row_ids{1}}[1]{cds}, __NBC__ ) ), |
499 | |
500 | ( |
501 | (! $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} ) |
502 | and |
503 | push @{ $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} }, ( |
504 | $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }] |
505 | ) |
506 | ), |
507 | ( defined($cur_row_data->[8]) or bless( $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks}, __NBC__ ) ), |
508 | |
509 | ( |
510 | (! $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} ) |
511 | and |
512 | push @{ $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} }, ( |
513 | $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[5] }] |
514 | ) |
515 | ), |
516 | ( defined($cur_row_data->[5]) or bless( $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks}, __NBC__ ) ), |
517 | |
518 | ( $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}} = [] ), |
519 | ( defined($cur_row_data->[10]) or bless( $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics}, __NBC__ ) ), |
520 | |
521 | ( |
522 | (! $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} ) |
523 | and |
524 | push @{ $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}}[1]{existing_lyric_versions} }, ( |
525 | $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] }] |
526 | ) |
527 | ), |
4e9fc3f3 |
528 | } |
529 | |
aa1d8a87 |
530 | $#{$_[0]} = $result_pos - 1; |
4e9fc3f3 |
531 | ', |
532 | 'Multiple has_many on multiple branches torture test', |
533 | ); |
534 | |
ce556881 |
535 | is_same_src ( |
02a73c96 |
536 | ($schema->source ('CD')->_mk_row_parser({ |
ce556881 |
537 | inflate_map => $infmap, |
538 | collapse => 1, |
79adc44f |
539 | prune_null_branches => 1, |
02a73c96 |
540 | }))[0], |
aa1d8a87 |
541 | ' my $rows_pos = 0; |
beb858a3 |
542 | my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids); |
ce556881 |
543 | |
544 | while ($cur_row_data = ( |
8e06d750 |
545 | ( |
546 | $rows_pos >= 0 |
547 | and |
548 | ( |
549 | $_[0][$rows_pos++] |
550 | or |
551 | ( ($rows_pos = -1), undef ) |
552 | ) |
553 | ) |
554 | or |
555 | ( $_[1] and $_[1]->() ) |
3b4cd124 |
556 | ) ) { |
ce556881 |
557 | |
d43f1734 |
558 | ( @cur_row_ids{( 0, 1, 5, 6, 8, 10 )} = @{$cur_row_data}[( 0, 1, 5, 6, 8, 10 )] ), |
beb858a3 |
559 | |
ce556881 |
560 | # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2] |
d43f1734 |
561 | ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{1}} and (unshift @{$_[2]}, $cur_row_data) and last ), |
ce556881 |
562 | |
d43f1734 |
563 | ( $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 |
564 | |
d43f1734 |
565 | ( $collapse_idx[0]{$cur_row_ids{1}}[1]{existing_single_track} //= $collapse_idx[1]{$cur_row_ids{1}} = [] ), |
566 | ( $collapse_idx[1]{$cur_row_ids{1}}[1]{cd} //= $collapse_idx[2]{$cur_row_ids{1}} = [] ), |
567 | ( $collapse_idx[2]{$cur_row_ids{1}}[1]{artist} //= $collapse_idx[3]{$cur_row_ids{1}} = [{ artistid => $cur_row_data->[1] }] ), |
ce556881 |
568 | |
d43f1734 |
569 | ( (! defined($cur_row_data->[6])) ? $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} = [] : do { |
570 | ( |
571 | (! $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}} ) |
79adc44f |
572 | and |
d43f1734 |
573 | push @{ $collapse_idx[3]{$cur_row_ids{1}}[1]{cds} }, ( |
574 | $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] }] |
575 | ) |
576 | ), |
577 | |
578 | ( (! defined($cur_row_data->[8]) ) ? $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} = [] : do { |
579 | ( |
580 | (! $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} ) |
581 | and |
582 | push @{ $collapse_idx[4]{$cur_row_ids{1}}{$cur_row_ids{6}}[1]{tracks} }, ( |
583 | $collapse_idx[5]{$cur_row_ids{1}}{$cur_row_ids{6}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }] |
584 | ) |
585 | ), |
586 | } ), |
587 | } ), |
ce556881 |
588 | |
d43f1734 |
589 | ( (! defined($cur_row_data->[5]) ) ? $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} = [] : do { |
ce556881 |
590 | |
d43f1734 |
591 | ( |
592 | (! $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} ) |
593 | and |
594 | push @{ $collapse_idx[0]{$cur_row_ids{1}}[1]{tracks} }, ( |
595 | $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}} = [{ title => $cur_row_data->[5] }] |
596 | ) |
597 | ), |
79adc44f |
598 | |
d43f1734 |
599 | ( (! defined($cur_row_data->[10]) ) ? $collapse_idx[6]{$cur_row_ids{1}}{$cur_row_ids{5}}[1]{lyrics} = [] : do { |
79adc44f |
600 | |
d43f1734 |
601 | ( $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 |
602 | |
d43f1734 |
603 | ( |
604 | (! $collapse_idx[8]{$cur_row_ids{0}}{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}} ) |
605 | and |
606 | push @{ $collapse_idx[7]{$cur_row_ids{1}}{$cur_row_ids{5}}{$cur_row_ids{10}}[1]{existing_lyric_versions} }, ( |
607 | $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] }] |
608 | ) |
609 | ), |
610 | } ), |
611 | } ), |
ce556881 |
612 | } |
613 | |
aa1d8a87 |
614 | $#{$_[0]} = $result_pos - 1; |
ce556881 |
615 | ', |
79adc44f |
616 | 'Multiple has_many on multiple branches with branch pruning torture test', |
ce556881 |
617 | ); |
618 | |
fcf32d04 |
619 | $infmap = [ |
620 | 'single_track.trackid', # (0) definitive link to root from 1:1:1:1:M:M chain |
621 | 'year', # (1) non-unique |
622 | 'tracks.cd', # (2) \ together both uniqueness for second multirel |
623 | 'tracks.title', # (3) / and definitive link back to root |
624 | 'single_track.cd.artist.cds.cdid', # (4) to give uniquiness to ...tracks.title below |
625 | 'single_track.cd.artist.cds.year', # (5) non-unique |
626 | 'single_track.cd.artist.artistid', # (6) uniqufies entire parental chain |
627 | 'single_track.cd.artist.cds.genreid', # (7) nullable |
628 | 'single_track.cd.artist.cds.tracks.title',# (8) unique when combined with ...cds.cdid above |
629 | ]; |
630 | |
631 | is_deeply ( |
632 | $schema->source('CD')->_resolve_collapse({ as => {map { $infmap->[$_] => $_ } 0 .. $#$infmap} }), |
633 | { |
9f98c4b2 |
634 | -identifying_columns => [], |
635 | -identifying_columns_variants => [ |
fcf32d04 |
636 | [ 0 ], [ 2 ], |
637 | ], |
638 | single_track => { |
9f98c4b2 |
639 | -identifying_columns => [ 0 ], |
fcf32d04 |
640 | -is_optional => 1, |
641 | -is_single => 1, |
fcf32d04 |
642 | cd => { |
9f98c4b2 |
643 | -identifying_columns => [ 0 ], |
fcf32d04 |
644 | -is_single => 1, |
fcf32d04 |
645 | artist => { |
9f98c4b2 |
646 | -identifying_columns => [ 0 ], |
fcf32d04 |
647 | -is_single => 1, |
fcf32d04 |
648 | cds => { |
9f98c4b2 |
649 | -identifying_columns => [ 0, 4 ], |
fcf32d04 |
650 | -is_optional => 1, |
fcf32d04 |
651 | tracks => { |
9f98c4b2 |
652 | -identifying_columns => [ 0, 4, 8 ], |
fcf32d04 |
653 | -is_optional => 1, |
fcf32d04 |
654 | } |
655 | } |
656 | } |
657 | } |
658 | }, |
659 | tracks => { |
9f98c4b2 |
660 | -identifying_columns => [ 2, 3 ], |
fcf32d04 |
661 | -is_optional => 1, |
fcf32d04 |
662 | } |
663 | }, |
664 | 'Correct underdefined root collapse map constructed' |
665 | ); |
666 | |
667 | is_same_src ( |
02a73c96 |
668 | ($schema->source ('CD')->_mk_row_parser({ |
fcf32d04 |
669 | inflate_map => $infmap, |
670 | collapse => 1, |
02a73c96 |
671 | }))[0], |
aa1d8a87 |
672 | ' my $rows_pos = 0; |
673 | my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids); |
fcf32d04 |
674 | |
9f98c4b2 |
675 | while ($cur_row_data = ( |
8e06d750 |
676 | ( |
677 | $rows_pos >= 0 |
678 | and |
679 | ( |
680 | $_[0][$rows_pos++] |
681 | or |
682 | ( ($rows_pos = -1), undef ) |
683 | ) |
684 | ) |
685 | or |
686 | ( $_[1] and $_[1]->() ) |
3b4cd124 |
687 | ) ) { |
fcf32d04 |
688 | |
d43f1734 |
689 | ( @cur_row_ids{( 0, 2, 3, 4, 8 )} = ( |
beb858a3 |
690 | $cur_row_data->[0] // "\0NULL\xFF$rows_pos\xFF0\0", |
691 | $cur_row_data->[2] // "\0NULL\xFF$rows_pos\xFF2\0", |
692 | $cur_row_data->[3] // "\0NULL\xFF$rows_pos\xFF3\0", |
693 | $cur_row_data->[4] // "\0NULL\xFF$rows_pos\xFF4\0", |
694 | $cur_row_data->[8] // "\0NULL\xFF$rows_pos\xFF8\0", |
d43f1734 |
695 | )), |
fcf32d04 |
696 | |
697 | # cache expensive set of ops in a non-existent rowid slot |
d43f1734 |
698 | ( $cur_row_ids{10} = ( |
beb858a3 |
699 | ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_ids{0}, q{} )) |
fcf32d04 |
700 | or |
beb858a3 |
701 | ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_ids{2}, q{} )) |
fcf32d04 |
702 | or |
703 | "\0$rows_pos\0" |
d43f1734 |
704 | )), |
fcf32d04 |
705 | |
9f98c4b2 |
706 | # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2] |
d43f1734 |
707 | ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{10}} and (unshift @{$_[2]}, $cur_row_data) and last ), |
fcf32d04 |
708 | |
d43f1734 |
709 | ( $collapse_idx[0]{$cur_row_ids{10}} //= $_[0][$result_pos++] = [{ year => $$cur_row_data[1] }] ), |
fcf32d04 |
710 | |
d43f1734 |
711 | ( $collapse_idx[0]{$cur_row_ids{10}}[1]{single_track} //= ($collapse_idx[1]{$cur_row_ids{0}} = [{ trackid => $cur_row_data->[0] }]) ), |
712 | ( defined($cur_row_data->[0]) or bless ( $collapse_idx[0]{$cur_row_ids{10}}[1]{single_track}, __NBC__ ) ), |
fcf32d04 |
713 | |
d43f1734 |
714 | ( $collapse_idx[1]{$cur_row_ids{0}}[1]{cd} //= $collapse_idx[2]{$cur_row_ids{0}} = [] ), |
fcf32d04 |
715 | |
d43f1734 |
716 | ( $collapse_idx[2]{$cur_row_ids{0}}[1]{artist} //= ($collapse_idx[3]{$cur_row_ids{0}} = [{ artistid => $cur_row_data->[6] }]) ), |
fcf32d04 |
717 | |
d43f1734 |
718 | ( |
719 | (! $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} ) |
720 | and |
721 | push @{$collapse_idx[3]{$cur_row_ids{0}}[1]{cds}}, ( |
52864fbd |
722 | $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] }] |
d43f1734 |
723 | ) |
724 | ), |
725 | ( defined($cur_row_data->[4]) or bless ( $collapse_idx[3]{$cur_row_ids{0}}[1]{cds}, __NBC__ ) ), |
726 | |
727 | ( |
728 | (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} ) |
729 | and |
730 | push @{$collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}[1]{tracks}}, ( |
731 | $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} = [{ title => $cur_row_data->[8] }] |
732 | ) |
733 | ), |
734 | ( defined($cur_row_data->[8]) or bless ( $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}[1]{tracks}, __NBC__ ) ), |
735 | |
736 | ( |
737 | (! $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} ) |
738 | and |
739 | push @{$collapse_idx[0]{$cur_row_ids{10}}[1]{tracks}}, ( |
52864fbd |
740 | $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} = [{ cd => $$cur_row_data[2], title => $cur_row_data->[3] }] |
d43f1734 |
741 | ) |
742 | ), |
743 | ( defined($cur_row_data->[2]) or bless ( $collapse_idx[0]{$cur_row_ids{10}}[1]{tracks}, __NBC__ ) ), |
fcf32d04 |
744 | } |
745 | |
aa1d8a87 |
746 | $#{$_[0]} = $result_pos - 1; |
fcf32d04 |
747 | ', |
748 | 'Multiple has_many on multiple branches with underdefined root torture test', |
749 | ); |
750 | |
ce556881 |
751 | is_same_src ( |
02a73c96 |
752 | ($schema->source ('CD')->_mk_row_parser({ |
ce556881 |
753 | inflate_map => $infmap, |
754 | collapse => 1, |
ce556881 |
755 | hri_style => 1, |
79adc44f |
756 | prune_null_branches => 1, |
02a73c96 |
757 | }))[0], |
aa1d8a87 |
758 | ' my $rows_pos = 0; |
06b3406d |
759 | my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids); |
ce556881 |
760 | |
761 | while ($cur_row_data = ( |
8e06d750 |
762 | ( |
763 | $rows_pos >= 0 |
764 | and |
765 | ( |
766 | $_[0][$rows_pos++] |
767 | or |
768 | ( ($rows_pos = -1), undef ) |
769 | ) |
770 | ) |
771 | or |
772 | ( $_[1] and $_[1]->() ) |
3b4cd124 |
773 | ) ) { |
774 | |
5e6d06f4 |
775 | # do not care about nullability here |
d43f1734 |
776 | ( @cur_row_ids{( 0, 2, 3, 4, 8 )} = @{$cur_row_data}[( 0, 2, 3, 4, 8 )] ), |
06b3406d |
777 | |
ce556881 |
778 | # cache expensive set of ops in a non-existent rowid slot |
d43f1734 |
779 | ( $cur_row_ids{10} = ( |
beb858a3 |
780 | ( ( defined $cur_row_data->[0] ) && (join "\xFF", q{}, $cur_row_ids{0}, q{} )) |
ce556881 |
781 | or |
beb858a3 |
782 | ( ( defined $cur_row_data->[2] ) && (join "\xFF", q{}, $cur_row_ids{2}, q{} )) |
ce556881 |
783 | or |
784 | "\0$rows_pos\0" |
d43f1734 |
785 | )), |
ce556881 |
786 | |
787 | # a present cref in $_[1] implies lazy prefetch, implies a supplied stash in $_[2] |
d43f1734 |
788 | ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{10}} and (unshift @{$_[2]}, $cur_row_data) and last ), |
ce556881 |
789 | |
d43f1734 |
790 | ( $collapse_idx[0]{$cur_row_ids{10}} //= $_[0][$result_pos++] = { year => $$cur_row_data[1] } ), |
ce556881 |
791 | |
d43f1734 |
792 | ( (! defined $cur_row_data->[0] ) ? $collapse_idx[0]{$cur_row_ids{10}}{single_track} = undef : do { |
ce556881 |
793 | |
d43f1734 |
794 | ( $collapse_idx[0]{$cur_row_ids{10}}{single_track} //= ($collapse_idx[1]{$cur_row_ids{0}} = { trackid => $$cur_row_data[0] }) ), |
ce556881 |
795 | |
d43f1734 |
796 | ( $collapse_idx[1]{$cur_row_ids{0}}{cd} //= $collapse_idx[2]{$cur_row_ids{0}} ), |
ce556881 |
797 | |
d43f1734 |
798 | ( $collapse_idx[2]{$cur_row_ids{0}}{artist} //= ($collapse_idx[3]{$cur_row_ids{0}} = { artistid => $$cur_row_data[6] }) ), |
ce556881 |
799 | |
d43f1734 |
800 | ( (! defined $cur_row_data->[4] ) ? $collapse_idx[3]{$cur_row_ids{0}}{cds} = [] : do { |
ce556881 |
801 | |
d43f1734 |
802 | ( |
803 | (! $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}} ) |
804 | and |
805 | push @{$collapse_idx[3]{$cur_row_ids{0}}{cds}}, ( |
806 | $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] } |
807 | ) |
808 | ), |
ce556881 |
809 | |
d43f1734 |
810 | ( (! defined $cur_row_data->[8] ) ? $collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}{tracks} = [] : do { |
7596ddca |
811 | |
06b3406d |
812 | (! $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} ) |
7596ddca |
813 | and |
06b3406d |
814 | push @{$collapse_idx[4]{$cur_row_ids{0}}{$cur_row_ids{4}}{tracks}}, ( |
815 | $collapse_idx[5]{$cur_row_ids{0}}{$cur_row_ids{4}}{$cur_row_ids{8}} = { title => $$cur_row_data[8] } |
d43f1734 |
816 | ), |
817 | } ), |
818 | } ), |
819 | } ), |
7596ddca |
820 | |
d43f1734 |
821 | ( (! defined $cur_row_data->[2] ) ? $collapse_idx[0]{$cur_row_ids{10}}{tracks} = [] : do { |
822 | ( |
823 | (! $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} ) |
824 | and |
825 | push @{$collapse_idx[0]{$cur_row_ids{10}}{tracks}}, ( |
06b3406d |
826 | $collapse_idx[6]{$cur_row_ids{2}}{$cur_row_ids{3}} = { cd => $$cur_row_data[2], title => $$cur_row_data[3] } |
d43f1734 |
827 | ) |
828 | ), |
829 | } ), |
ce556881 |
830 | } |
831 | |
aa1d8a87 |
832 | $#{$_[0]} = $result_pos - 1; |
ce556881 |
833 | ', |
52864fbd |
834 | 'Multiple has_many on multiple branches with underdefined root, HRI-direct torture test', |
ce556881 |
835 | ); |
836 | |
beb858a3 |
837 | is_same_src ( |
838 | ($schema->source ('Owners')->_mk_row_parser({ |
839 | inflate_map => [qw( books.title books.owner )], |
840 | collapse => 1, |
841 | prune_null_branches => 1, |
842 | }))[0], |
843 | ' my $rows_pos = 0; |
844 | my ($result_pos, @collapse_idx, $cur_row_data, %cur_row_ids ); |
845 | |
846 | while ($cur_row_data = ( |
8e06d750 |
847 | ( |
848 | $rows_pos >= 0 |
849 | and |
850 | ( |
851 | $_[0][$rows_pos++] |
852 | or |
853 | ( ($rows_pos = -1), undef ) |
854 | ) |
855 | ) |
beb858a3 |
856 | or |
8e06d750 |
857 | ( $_[1] and $_[1]->() ) |
beb858a3 |
858 | ) ) { |
859 | |
d43f1734 |
860 | ( @cur_row_ids{0,1} = @{$cur_row_data}[0,1] ), |
beb858a3 |
861 | |
d43f1734 |
862 | ( $cur_row_ids{3} = ( |
beb858a3 |
863 | ( ( defined $cur_row_data->[1] ) && (join "\xFF", q{}, $cur_row_ids{1}, q{} )) |
864 | or |
865 | "\0${rows_pos}\0" |
d43f1734 |
866 | )), |
beb858a3 |
867 | |
d43f1734 |
868 | ( $_[1] and $result_pos and ! $collapse_idx[0]{$cur_row_ids{3}} and (unshift @{$_[2]}, $cur_row_data) and last ), |
beb858a3 |
869 | |
870 | # empty data for the root node |
d43f1734 |
871 | ( $collapse_idx[0]{$cur_row_ids{3}} //= $_[0][$result_pos++] = [] ), |
beb858a3 |
872 | |
d43f1734 |
873 | ( ( ! defined $cur_row_data->[0] ) ? $collapse_idx[0]{$cur_row_ids{3}}[1]{"books"} = [] : do { |
beb858a3 |
874 | ( ! $collapse_idx[1]{$cur_row_ids{0}} ) |
875 | and |
876 | push @{$collapse_idx[0]{$cur_row_ids{3}}[1]{books}}, |
877 | $collapse_idx[1]{$cur_row_ids{0}} = [ { owner => $cur_row_data->[1], title => $cur_row_data->[0] } ] |
d43f1734 |
878 | } ), |
beb858a3 |
879 | } |
880 | |
881 | $#{$_[0]} = $result_pos - 1; # truncate the passed in array to where we filled it with results |
882 | ', |
883 | 'Non-premultiplied implicit collapse with missing join columns', |
884 | ); |
885 | |
4e9fc3f3 |
886 | done_testing; |
887 | |
888 | my $deparser; |
cd784aab |
889 | sub is_same_src { SKIP: { |
2fdeef65 |
890 | |
891 | skip "Skipping comparison of unicode-posioned source", 1 |
892 | if DBIx::Class::_ENV_::STRESSTEST_UTF8_UPGRADE_GENERATED_COLLAPSER_SOURCE; |
893 | |
4e9fc3f3 |
894 | $deparser ||= B::Deparse->new; |
895 | local $Test::Builder::Level = $Test::Builder::Level + 1; |
896 | |
52864fbd |
897 | my ($got, $expect) = @_; |
898 | |
cd784aab |
899 | skip "Not testing equality of source containing defined-or operator on this perl $]", 1 |
900 | if ($] < 5.010 and$expect =~ m!\Q//=!); |
901 | |
01b25f12 |
902 | $expect =~ s/__NBC__/perlstring($DBIx::Class::ResultSource::RowParser::Util::null_branch_class)/ge; |
52864fbd |
903 | |
9f7d5590 |
904 | $expect = " { use strict; use warnings FATAL => 'uninitialized';\n$expect\n }"; |
bdbd2ae8 |
905 | |
52864fbd |
906 | my @normalized = map { |
4e9fc3f3 |
907 | my $cref = eval "sub { $_ }" or do { |
908 | fail "Coderef does not compile!\n\n$@\n\n$_"; |
909 | return undef; |
910 | }; |
911 | $deparser->coderef2text($cref); |
52864fbd |
912 | } ($got, $expect); |
913 | |
914 | &is (@normalized, $_[2]||() ) or do { |
915 | eval { require Test::Differences } |
916 | ? &Test::Differences::eq_or_diff( @normalized, $_[2]||() ) |
e81b50f4 |
917 | : note ("Original sources:\n\n$got\n\n$expect\n") |
918 | ; |
919 | exit 1; |
52864fbd |
920 | }; |
cd784aab |
921 | } } |