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