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
15 $Data::Dumper::Sortkeys = 1;
17 my $schema = DBICTest->init_schema(no_deploy => 1);
18 my $infmap = [qw/single_track.cd.artist.name year/];
21 $schema->source ('CD')->_mk_row_parser({
22 inflate_map => $infmap,
36 'Simple 1:1 descending non-collapsing parser',
40 single_track.cd.artist.artistid
42 single_track.cd.artist.cds.tracks.title
43 single_track.cd.artist.cds.cdid
48 $schema->source ('CD')->_mk_row_parser({
49 inflate_map => $infmap,
52 { artist => $_->[5], title => $_->[4], year => $_->[1] },
58 { artistid => $_->[0] },
69 '1:1 descending non-collapsing parser terminating with chained 1:M:M',
73 $schema->source('CD')->_resolve_collapse({map { $infmap->[$_] => $_ } 0 .. $#$infmap}),
77 -branch_id => [ 0, 2, 3, 4, 5 ],
82 -branch_id => [ 0, 2, 3, 4, 5],
89 -branch_id => [ 0, 2, 3, 4, 5 ],
95 -branch_id => [ 0, 2, 3 ],
101 -branch_id => [ 2, 3 ],
106 -node_id => [ 2, 3 ],
107 -branch_id => [ 2, 3 ],
115 'Correct collapse map for 1:1 descending chain terminating with chained 1:M:M'
119 $schema->source ('CD')->_mk_row_parser({
120 inflate_map => $infmap,
123 ' my($rows_pos, $result_pos, $cur_row, @cur_row_ids, @collapse_idx, $is_new_res) = (0, 0);
126 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
128 ( $_[1] and $_[1]->() )
131 $cur_row_ids[$_] = defined $cur_row->[$_] ? $cur_row->[$_] : "\xFF\xFFN\xFFU\xFFL\xFFL\xFF\xFF"
134 # a present cref implies lazy prefetch, implies a supplied stash in $_[2]
135 $_[1] and $result_pos and unshift(@{$_[2]}, $cur_row) and last
136 if $is_new_res = ! $collapse_idx[1]{$cur_row_ids[4]}{$cur_row_ids[5]};
138 $collapse_idx[1]{$cur_row_ids[4]}{$cur_row_ids[5]} ||= [{ artist => $cur_row->[5], title => $cur_row->[4], year => $cur_row->[1] }];
139 $collapse_idx[1]{$cur_row_ids[4]}{$cur_row_ids[5]}[1]{single_track} ||= $collapse_idx[2]{$cur_row_ids[4]}{$cur_row_ids[5]};
140 $collapse_idx[2]{$cur_row_ids[4]}{$cur_row_ids[5]}[1]{cd} ||= $collapse_idx[3]{$cur_row_ids[4]}{$cur_row_ids[5]};
141 $collapse_idx[3]{$cur_row_ids[4]}{$cur_row_ids[5]}[1]{artist} ||= $collapse_idx[4]{$cur_row_ids[0]} ||= [{ artistid => $cur_row->[0] }];
143 $collapse_idx[4]{$cur_row_ids[0]}[1]{cds} ||= [];
144 push @{$collapse_idx[4]{$cur_row_ids[0]}[1]{cds}}, $collapse_idx[5]{$cur_row_ids[3]} ||= [{ cdid => $cur_row->[3] }]
145 unless $collapse_idx[5]{$cur_row_ids[3]};
147 $collapse_idx[5]{$cur_row_ids[3]}[1]{tracks} ||= [];
148 push @{$collapse_idx[5]{$cur_row_ids[3]}[1]{tracks}}, $collapse_idx[6]{$cur_row_ids[2]}{$cur_row_ids[3]} ||= [{ title => $cur_row->[2] }]
149 unless $collapse_idx[6]{$cur_row_ids[2]}{$cur_row_ids[3]};
151 $_[0][$result_pos++] = $collapse_idx[1]{$cur_row_ids[4]}{$cur_row_ids[5]}
154 splice @{$_[0]}, $result_pos;
156 'Same 1:1 descending terminating with chained 1:M:M but with collapse',
160 tracks.lyrics.lyric_versions.text
161 existing_single_track.cd.artist.artistid
162 existing_single_track.cd.artist.cds.year
166 existing_single_track.cd.artist.cds.cdid
168 existing_single_track.cd.artist.cds.tracks.title
169 existing_single_track.cd.artist.cds.genreid
173 $schema->source('CD')->_resolve_collapse({map { $infmap->[$_] => $_ } 0 .. $#$infmap}),
176 -node_id => [ 1 ], # existing_single_track.cd.artist.artistid
177 -branch_id => [ 0, 1, 5, 6, 8 ],
179 existing_single_track => {
181 -node_id => [ 1 ], # existing_single_track.cd.artist.artistid
182 -branch_id => [ 1, 6, 8 ],
187 -node_id => [ 1 ], # existing_single_track.cd.artist.artistid
188 -branch_id => [ 1, 6, 8 ],
193 -node_id => [ 1 ], # existing_single_track.cd.artist.artistid
194 -branch_id => [ 1, 6, 8 ],
199 -node_id => [ 6 ], # existing_single_track.cd.artist.cds.cdid
200 -branch_id => [ 6, 8 ],
205 -node_id => [ 6, 8 ], # existing_single_track.cd.artist.cds.cdid, existing_single_track.cd.artist.cds.tracks.title
206 -branch_id => [ 6, 8 ],
215 -node_id => [ 1, 5 ], # existing_single_track.cd.artist.artistid, tracks.title
216 -branch_id => [ 0, 1, 5 ],
221 -node_id => [ 1, 5 ], # existing_single_track.cd.artist.artistid, tracks.title
222 -branch_id => [ 0, 1, 5 ],
228 -node_id => [ 0, 1, 5 ], # tracks.lyrics.lyric_versions.text, existing_single_track.cd.artist.artistid, tracks.title
229 -branch_id => [ 0, 1, 5 ],
235 'Correct collapse map constructed',
239 $schema->source ('CD')->_mk_row_parser({
240 inflate_map => $infmap,
243 ' my ($rows_pos, $result_pos, $cur_row, @cur_row_ids, @collapse_idx, $is_new_res) = (0,0);
246 ( $rows_pos >= 0 and $_[0][$rows_pos++] ) or do { $rows_pos = -1; undef } )
248 ( $_[1] and $_[1]->() )
251 $cur_row_ids[$_] = defined $cur_row->[$_] ? $cur_row->[$_] : "\xFF\xFFN\xFFU\xFFL\xFFL\xFF\xFF"
254 $is_new_res = ! $collapse_idx[1]{$cur_row_ids[1]} and (
255 $_[1] and $result_pos and (unshift @{$_[2]}, $cur_row) and last
258 $collapse_idx[1]{$cur_row_ids[1]} ||= [{ genreid => $cur_row->[4], latest_cd => $cur_row->[7], year => $cur_row->[3] }];
260 $collapse_idx[1]{$cur_row_ids[1]}[1]{existing_single_track} ||= $collapse_idx[2]{$cur_row_ids[1]};
261 $collapse_idx[2]{$cur_row_ids[1]}[1]{cd} ||= $collapse_idx[3]{$cur_row_ids[1]};
262 $collapse_idx[3]{$cur_row_ids[1]}[1]{artist} ||= $collapse_idx[4]{$cur_row_ids[1]} ||= [{ artistid => $cur_row->[1] }];
264 $collapse_idx[4]{$cur_row_ids[1]}[1]{cds} ||= [];
265 push @{ $collapse_idx[4]{$cur_row_ids[1]}[1]{cds} }, $collapse_idx[5]{$cur_row_ids[6]} ||= [{ cdid => $cur_row->[6], genreid => $cur_row->[9], year => $cur_row->[2] }]
266 unless $collapse_idx[5]{$cur_row_ids[6]};
268 $collapse_idx[5]{$cur_row_ids[6]}[1]{tracks} ||= [];
269 push @{ $collapse_idx[5]{$cur_row_ids[6]}[1]{tracks} }, $collapse_idx[6]{$cur_row_ids[6]}{$cur_row_ids[8]} ||= [{ title => $cur_row->[8] }]
270 unless $collapse_idx[6]{$cur_row_ids[6]}{$cur_row_ids[8]};
272 $collapse_idx[1]{$cur_row_ids[1]}[1]{tracks} ||= [];
273 push @{ $collapse_idx[1]{$cur_row_ids[1]}[1]{tracks} }, $collapse_idx[7]{$cur_row_ids[1]}{$cur_row_ids[5]} ||= [{ title => $cur_row->[5] }]
274 unless $collapse_idx[7]{$cur_row_ids[1]}{$cur_row_ids[5]};
276 $collapse_idx[7]{$cur_row_ids[1]}{$cur_row_ids[5]}[1]{lyrics} ||= $collapse_idx[8]{$cur_row_ids[1]}{$cur_row_ids[5] };
278 $collapse_idx[8]{$cur_row_ids[1]}{$cur_row_ids[5]}[1]{lyric_versions} ||= [];
279 push @{ $collapse_idx[8]{$cur_row_ids[1]}{$cur_row_ids[5]}[1]{lyric_versions} }, $collapse_idx[9]{$cur_row_ids[0]}{$cur_row_ids[1]}{$cur_row_ids[5]} ||= [{ text => $cur_row->[0] }]
280 unless $collapse_idx[9]{$cur_row_ids[0]}{$cur_row_ids[1]}{$cur_row_ids[5]};
282 $_[0][$result_pos++] = $collapse_idx[1]{$cur_row_ids[1]}
286 splice @{$_[0]}, $result_pos;
288 'Multiple has_many on multiple branches torture test',
295 $deparser ||= B::Deparse->new;
296 local $Test::Builder::Level = $Test::Builder::Level + 1;
298 my ($got, $expect) = map {
299 my $cref = eval "sub { $_ }" or do {
300 fail "Coderef does not compile!\n\n$@\n\n$_";
303 $deparser->coderef2text($cref);
306 is ($got, $expect, $_[2]||() )
307 or note ("Originals source:\n\n$_[0]\n\n$_[1]\n");