X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=t%2Fprefetch%2F_internals.t;h=c7f7dd9c7820dadcd96011ddb81458b95fc55c50;hb=76031e147d6f0d80ab3ec73a12d373962ade1252;hp=d9e9575a09708bdb5a7d16ee98efd35615b5b86f;hpb=d4d8e97b662ae1c136b092bba2fa87dbab2bb8f7;p=dbsrgits%2FDBIx-Class.git diff --git a/t/prefetch/_internals.t b/t/prefetch/_internals.t index d9e9575..c7f7dd9 100644 --- a/t/prefetch/_internals.t +++ b/t/prefetch/_internals.t @@ -4,88 +4,122 @@ use warnings; use Test::More; use lib qw(t/lib); use DBICTest; +use B::Deparse; + my $schema = DBICTest->init_schema(no_deploy => 1); +my ($as, $vals, @pairs); -my $irow = $schema->source ('Artwork')->_parse_row ( - { - 'cd_id' => '1', +# artwork-artist deliberately mixed around +@pairs = ( + 'artwork_to_artist.artist_id' => '2', - 'artwork_to_artist.artist_id' => '2', - 'artwork_to_artist.artwork_cd_id' => '1', + 'cd_id' => '1', - 'cd.artist' => '1', - 'cd.cdid' => '1', - 'cd.title' => 'Spoonful of bees', + 'artwork_to_artist.artwork_cd_id' => '1', - 'cd.artist.artistid' => '1', - 'cd.artist.name' => 'Caterwauler McCrae', - }, - 'will collapse' + 'cd.artist' => '1', + 'cd.cdid' => '1', + 'cd.title' => 'Spoonful of bees', + + 'cd.artist.artistid' => '7', + 'cd.artist.name' => 'Caterwauler McCrae', + 'artwork_to_artist.artist.name' => 'xenowhinycide', ); +while (@pairs) { + push @$as, shift @pairs; + push @$vals, shift @pairs; +} + +=begin + +my $parser = $schema->source ('Artwork')->_mk_row_parser({ + inflate_map => $as, + collapse => 1, +}); is_deeply ( - $irow, + $parser->($vals), [ { - 'cd_id' => '1' + cd_id => 1, }, + { - 'artwork_to_artist' => [ - [ - { - 'artist_id' => '2', - 'artwork_cd_id' => '1' - } - ] + artwork_to_artist => [ + { + artist_id => 2, + artwork_cd_id => 1, + }, + { + artist => [ + { + name => 'xenowhinycide', + }, + undef, + [ 2, 1 ], # inherited from artwork_to_artist (child-parent definition) + ], + }, + [ 2, 1 ] # artwork_to_artist own data, in selection order ], - 'cd' => [ + cd => [ { - 'artist' => '1', - 'cdid' => '1', - 'title' => 'Spoonful of bees', + artist => 1, + cdid => 1, + title => 'Spoonful of bees', }, { - 'artist' => [ + artist => [ { - 'artistid' => '1', - 'name' => 'Caterwauler McCrae', - } + artistid => 7, + name => 'Caterwauler McCrae', + }, + undef, + [ 7 ], # our own id ] - } + }, + [ 1 ], # our cdid fk ] - } + }, + [ 1 ], # our id ], - '_parse_row works as expected with expected collapse', + 'generated row parser works as expected', ); -$irow = $schema->source ('Artist')->_parse_row ( - { - 'name' => 'Caterwauler McCrae', - 'cds.tracks.cd' => '3', - 'cds.tracks.title' => 'Fowlin', - 'cds.tracks.cd_single.title' => 'Awesome single', - } +#=begin + +undef $_ for ($as, $vals); +@pairs = ( + 'name' => 'Caterwauler McCrae', + 'cds.tracks.cd' => '3', + 'cds.tracks.title' => 'Fowlin', + 'cds.tracks.cd_single.title' => 'Awesome single', ); +while (@pairs) { + push @$as, shift @pairs; + push @$vals, shift @pairs; +} +$parser = $schema->source ('Artist')->_mk_row_parser($as); + is_deeply ( - $irow, + $parser->($vals), [ { - 'name' => 'Caterwauler McCrae' + name => 'Caterwauler McCrae' }, { - 'cds' => [ + cds => [ {}, { - 'tracks' => [ + tracks => [ { - 'cd' => '3', - 'title' => 'Fowlin' + cd => 3, + title => 'Fowlin' }, { - 'cd_single' => [ + cd_single => [ { title => 'Awesome single', }, @@ -96,68 +130,286 @@ is_deeply ( ] } ], - '_parse_row works over missing joins without collapse', + 'generated parser works as expected over missing joins (no collapse)', ); -my ($collapse_map, $order) = $schema->source ('CD')->_resolve_collapse ( - [ - 'year', # non-unique - 'genreid', # nullable - 'tracks.title', # non-unique (no me.id) - 'single_track.cd.artist.cds.cdid', # to give uniquiness to ...tracks.title below - 'single_track.cd.artist.cds.artist', # non-unique - 'single_track.cd.artist.cds.year', # non-unique - 'single_track.cd.artist.cds.genreid', # nullable - 'single_track.cd.artist.cds.tracks.title',# unique when combined with ...cds.cdid above - 'latest_cd', # random function - ], +=cut + +undef $_ for ($as, $vals); +@pairs = ( + 'tracks.lyrics.lyric_versions.text' => 'unique when combined with the lyric collapsable by the 1:1 tracks-parent', + 'existing_single_track.cd.artist.artistid' => 'artist_id (gives uniq. to its entire parent chain)', + 'existing_single_track.cd.artist.cds.year' => 'non-unique cds col (year)', + 'year' => 'non unique main year', + 'genreid' => 'non-unique/nullable main genid', + 'tracks.title' => 'non-unique title (missing multicol const. part)', + 'existing_single_track.cd.artist.cds.cdid' => 'cds unique id col to give uniquiness to ...tracks.title below', + 'latest_cd' => 'random function (not a colname)', + 'existing_single_track.cd.artist.cds.tracks.title' => 'unique track title (when combined with ...cds.cdid above)', + 'existing_single_track.cd.artist.cds.genreid' => 'nullable cds col (genreid)', ); +while (@pairs) { + push @$as, shift @pairs; + push @$vals, shift @pairs; +} is_deeply ( - $collapse_map, + $schema->source ('CD')->_resolve_collapse ( { map { $as->[$_] => $_ } (0 .. $#$as) } ), { - -collapse_on => { - "single_track.cd.artist.cds.artist" => 1 - }, + -node_index => 1, + -node_id => [ 1 ], # existing_single_track.cd.artist.artistid + -branch_id => [ 0, 1, 5, 6, 8 ], - single_track => { - -collapse_on => { - "single_track.cd.artist.cds.artist" => 1 - }, + existing_single_track => { + -node_index => 2, + -node_id => [ 1 ], # existing_single_track.cd.artist.artistid + -branch_id => [ 1, 6, 8 ], + -is_single => 1, cd => { - -collapse_on => { - "single_track.cd.artist.cds.artist" => 1 - }, + -node_index => 3, + -node_id => [ 1 ], # existing_single_track.cd.artist.artistid + -branch_id => [ 1, 6, 8 ], + -is_single => 1, artist => { - -collapse_on => { - "single_track.cd.artist.cds.artist" => 1 - }, + -node_index => 4, + -node_id => [ 1 ], # existing_single_track.cd.artist.artistid + -branch_id => [ 1, 6, 8 ], + -is_single => 1, cds => { - -collapse_on => { - "single_track.cd.artist.cds.cdid" => 1 - }, + -node_index => 5, + -node_id => [ 6 ], # existing_single_track.cd.artist.cds.cdid + -branch_id => [ 6, 8 ], + -is_optional => 1, tracks => { - -collapse_on => { - "single_track.cd.artist.cds.cdid" => 1, - "single_track.cd.artist.cds.tracks.title" => 1 - } + -node_index => 6, + -node_id => [ 6, 8 ], # existing_single_track.cd.artist.cds.cdid, existing_single_track.cd.artist.cds.tracks.title + -branch_id => [ 6, 8 ], + -is_optional => 1, } } } } }, tracks => { - -collapse_on => { - "single_track.cd.artist.cds.artist" => 1, - "tracks.title" => 1 - } + -node_index => 7, + -node_id => [ 1, 5 ], # existing_single_track.cd.artist.artistid, tracks.title + -branch_id => [ 0, 1, 5 ], + -is_optional => 1, + + lyrics => { + -node_index => 8, + -node_id => [ 1, 5 ], # existing_single_track.cd.artist.artistid, tracks.title + -branch_id => [ 0, 1, 5 ], + -is_single => 1, + -is_optional => 1, + + lyric_versions => { + -node_index => 9, + -node_id => [ 0, 1, 5 ], # tracks.lyrics.lyric_versions.text, existing_single_track.cd.artist.artistid, tracks.title + -branch_id => [ 0, 1, 5 ], + -is_optional => 1, + }, + }, } }, - "Proper collapse map constructed", + 'Correct collapse map constructed', +); + +done_testing; +__END__ +=cut + +my $parser = $schema->source ('CD')->_mk_row_parser ({ inflate_map => $as, collapse => 1 }); + +=begin + +is_deeply ( + $parser->($vals), + [ + { + latest_cd => 'random function (not a colname)', + year => 'non unique main year', + genreid => 'non-unique/nullable main genid' + }, + { + existing_single_track => [ + {}, + { + cd => [ + {}, + { + artist => [ + { artistid => 'artist_id (gives uniq. to its entire parent chain)' }, + { + cds => [ + { + cdid => 'cds unique id col to give uniquiness to ...tracks.title below', + year => 'non-unique cds col (year)', + genreid => 'nullable cds col (genreid)' + }, + { + tracks => [ + { + title => 'unique track title (when combined with ...cds.cdid above)' + }, + undef, + [ + 'cds unique id col to give uniquiness to ...tracks.title below', + 'unique track title (when combined with ...cds.cdid above)', + ], + ] + }, + [ 'cds unique id col to give uniquiness to ...tracks.title below' ], + ] + }, + [ 'artist_id (gives uniq. to its entire parent chain)' ], + ] + }, + [ 'artist_id (gives uniq. to its entire parent chain)' ], + ] + }, + [ 'artist_id (gives uniq. to its entire parent chain)' ], + ], + tracks => [ + { + title => 'non-unique title (missing multicol const. part)' + }, + { + lyrics => [ + {}, + { + lyric_versions => [ + { + text => 'unique when combined with the lyric collapsable by the 1:1 tracks-parent', + }, + undef, + [ + 'unique when combined with the lyric collapsable by the 1:1 tracks-parent', + 'artist_id (gives uniq. to its entire parent chain)', + 'non-unique title (missing multicol const. part)', + ], + ], + }, + [ + 'artist_id (gives uniq. to its entire parent chain)', + 'non-unique title (missing multicol const. part)', + ], + ], + }, + [ + 'artist_id (gives uniq. to its entire parent chain)', + 'non-unique title (missing multicol const. part)', + ], + ], + }, + [ 'artist_id (gives uniq. to its entire parent chain)' ], + ], + 'Proper row parser constructed', +); + +=cut + +# For extra insanity test/showcase the parser's guts: +my $deparser = B::Deparse->new; +is ( + $deparser->coderef2text ($parser), + $deparser->coderef2text ( sub { package DBIx::Class::ResultSource; + my $rows = []; + while (1) { + my $r = (shift @{$_[0]->{row_stash}}) || ($_[0]->{next_row} and $_[0]->{next_row}->()) || last; + + } + return $rows + + + [ + { + genreid => $_[0][4], + latest_cd => $_[0][7], + year => $_[0][3] + }, + { + + existing_single_track => [ + {}, + { + cd => [ + {}, + { + artist => [ + { + artistid => $_[0][1] + }, + { + + !defined($_[0][6]) ? () : ( + cds => [ + { + cdid => $_[0][6], + genreid => $_[0][9], + year => $_[0][2] + }, + { + + !defined($_[0][8]) ? () : ( + tracks => [ + { + title => $_[0][8] + }, + undef, + [ $_[0][6], $_[0][8] ] + ]) + + }, + [ $_[0][6] ] + ]), + + }, + [ $_[0][1] ], + ], + }, + [ $_[0][1] ], + ], + }, + [ $_[0][1] ], + ], + + !defined($_[0][5]) ? () : ( + tracks => [ + { + title => $_[0][5], + }, + { + + lyrics => [ + {}, + { + + !defined($_[0][0]) ? () : ( + lyric_versions => [ + { + text => $_[0][0] + }, + undef, + [ $_[0][0], $_[0][1], $_[0][5] ], + ]), + + }, + [ $_[0][1], $_[0][5] ], + ], + + }, + [ $_[0][1], $_[0][5] ], + ]), + }, + [ $_[0][1] ], + ]; + }), + 'Deparsed version of the parser coderef looks correct', ); done_testing;