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',
},
]
}
],
- '_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;