From 7e7bc9ca20dbee2e11edce1c6b0a4a35fdef69ca Mon Sep 17 00:00:00 2001 From: Colin Kuskie Date: Tue, 26 Jan 2010 12:55:40 -0800 Subject: [PATCH] Label loop inside getLineage. Drop a clause from getLineageSql, since we can use LIKE to make sure the lineage does not include the parent. Move getLineage tests to the top since downstream tests depend on getting assets in lineage order. --- lib/WebGUI/AssetLineage.pm | 37 +++--- t/Asset/AssetLineage.t | 244 +++++++++++++++++++------------------ 2 files changed, 143 insertions(+), 138 deletions(-) diff --git a/lib/WebGUI/AssetLineage.pm b/lib/WebGUI/AssetLineage.pm index 5b587b108..5ec4dcc4c 100644 --- a/lib/WebGUI/AssetLineage.pm +++ b/lib/WebGUI/AssetLineage.pm @@ -397,10 +397,10 @@ sub getLineage { return []; } - my @lineage; - my %relativeCache; - my $sth = $session->db->read($sql); - while (my ($id, $class, $parentId, $version) = $sth->array) { + my @lineage; + my %relativeCache; + my $sth = $session->db->read($sql); + ASSET: while (my ($id, $class, $parentId, $version) = $sth->array) { # create whatever type of object was requested my $asset; if ($rules->{returnObjects}) { @@ -410,23 +410,24 @@ sub getLineage { $asset = WebGUI::Asset->newById($session, $id, $version); if (!defined $asset) { # won't catch everything, but it will help some if an asset blows up $session->errorHandler->error("AssetLineage::getLineage - failed to instanciate asset with assetId $id, className $class, and revision $version"); - next; + next ASSET; } } - } else { - $asset = $id; } + else { + $asset = $id; + } # since we have the relatives info now, why not cache it - if ($rules->{returnObjects}) { - $relativeCache{$id} = $asset; - if (my $parent = $relativeCache{$parentId}) { - $asset->{_parent} = $parent; - unless ($parent->cacheChild('first')) { - $parent->cacheChild(first => $asset); - } - $parent->cacheChild(last => $asset); - } - } + if ($rules->{returnObjects}) { + $relativeCache{$id} = $asset; + if (my $parent = $relativeCache{$parentId}) { + $asset->{_parent} = $parent; + unless ($parent->cacheChild('first')) { + $parent->cacheChild(first => $asset); + } + $parent->cacheChild(last => $asset); + } + } push(@lineage,$asset); } $sth->finish; @@ -586,7 +587,7 @@ sub getLineageSql { } # we need to include descendants if (isIn("descendants",@{$relatives})) { - my $mod = "(asset.lineage like ".$db->quote($lineage.'%')." and asset.lineage<>".$db->quote($lineage); + my $mod = "(asset.lineage like ".$db->quote($lineage.'_%'); if (exists $rules->{endingLineageLength}) { $mod .= " and length(asset.lineage) <= ".($rules->{endingLineageLength}*6); } diff --git a/t/Asset/AssetLineage.t b/t/Asset/AssetLineage.t index feabb3242..e712188eb 100644 --- a/t/Asset/AssetLineage.t +++ b/t/Asset/AssetLineage.t @@ -17,7 +17,7 @@ use WebGUI::Session; use WebGUI::User; use WebGUI::Asset; -use Test::More tests => 90; # increment this value for each test you create +use Test::More tests => 91; # increment this value for each test you create use Test::Deep; use Data::Dumper; @@ -87,6 +87,115 @@ $versionTag->commit; my @snipIds; my $lineageIds; +#################################################### +# +# getLineage +# +#################################################### + +my $ids = $folder->getLineage(['self']); +cmp_deeply( + [$folder->getId], + $ids, + 'getLineage: get self' +); + +@snipIds = map { $_->getId } @snippets; +$lineageIds = $folder->getLineage(['descendants']); + +cmp_deeply($lineageIds, \@snipIds, 'default order returned by getLineage is lineage order'); + +@snipIds = map { $_->getId } @snippets; +$ids = $folder->getLineage(['descendants']); +cmp_bag( + \@snipIds, + $ids, + '... get descendants of folder' +); + +$ids = $folder->getLineage(['self','descendants']); +unshift @snipIds, $folder->getId; +cmp_bag( + \@snipIds, + $ids, + '... get descendants of folder and self' +); + +$ids = $folder->getLineage(['self','children']); +cmp_bag( + \@snipIds, + $ids, + '... descendants == children if there are no grandchildren' +); + +$ids = $topFolder->getLineage(['self','children']); +cmp_bag( + [$topFolder->getId, $folder->getId, $folder2->getId, ], + $ids, + '... children (no descendants) of topFolder', +); + +$ids = $topFolder->getLineage(['self','descendants']); +cmp_bag( + [$topFolder->getId, @snipIds, $folder2->getId, $snippet2->getId], + $ids, + '... descendants of topFolder', +); + +#################################################### +# +# getLineageIterator +# +#################################################### + +sub getListFromIterator { + my $iterator = shift; + my @items; + while (my $item = $iterator->()) { + push @items, $item->getId; + } + return \@items; +} + +@snipIds = map { $_->getId } @snippets; +my $ids = getListFromIterator($folder->getLineageIterator(['descendants'])); +cmp_bag( + \@snipIds, + $ids, + 'getLineageIterator: get descendants of folder' +); + +$ids = getListFromIterator($folder->getLineageIterator(['self','descendants'])); +unshift @snipIds, $folder->getId; +cmp_bag( + \@snipIds, + $ids, + 'getLineageIterator: get descendants of folder and self' +); +shift @snipIds; + +$ids = getListFromIterator($folder->getLineageIterator(['self','children'])); +cmp_bag( + \@snipIds, + $ids, + 'getLineageIterator: descendants == children if there are no grandchildren' +); + +$ids = getListFromIterator($topFolder->getLineageIterator(['self','children'])); +cmp_bag( + [$topFolder->getId, $folder->getId, $folder2->getId, ], + $ids, + 'getLineageIterator: children (no descendants) of topFolder', +); + +$ids = getListFromIterator($topFolder->getLineageIterator(['self','descendants'])); +cmp_bag( + [$topFolder->getId, @snipIds, $folder2->getId, $snippet2->getId], + $ids, + 'getLineageIterator: descendants of topFolder', +); + + #################################################### # # getFirstChild @@ -182,12 +291,12 @@ is( # #################################################### -#note $snippets[0]->get('lineage'); -#note $snippet2->get('lineage'); +#note $snippets[0]->lineage; +#note $snippet2->lineage; ##Uncomment me to crash the test -#$snippet2->cascadeLineage($snippets[0]->get('lineage')); -#note $snippets[0]->get('lineage'); -#note $snippet2->get('lineage'); +#$snippet2->cascadeLineage($snippets[0]->lineage); +#note $snippets[0]->lineage; +#note $snippet2->lineage; #################################################### # @@ -238,17 +347,19 @@ is($folder2->getNextChildRank, '000002', "getNextChildRank: empty folder"); # #################################################### -is($snippets[0]->swapRank($snippets[1]->get('lineage')), 1, 'swapRank: self and adjacent'); +is($snippets[0]->swapRank($snippets[1]->lineage), 1, 'swapRank: self and adjacent'); + +$folder->cloneFromDb; @snipIds[0,1] = @snipIds[1,0]; $lineageIds = $folder->getLineage(['descendants']); cmp_bag( \@snipIds, $lineageIds, - 'swapRank: swapped first and second snippets' + '... swapped first and second snippets' ); -@snippets[0..1] = map { WebGUI::Asset->newByUrl($session, "snippet$_") } 0..1; +@snippets[0..1] = map { $_->cloneFromDb } @snippets[0..1]; is( $snippets[1]->swapRank($snippets[0]->get('lineage'), $snippets[1]->get('lineage'), ), @@ -272,10 +383,10 @@ is(scalar @snippets, $folder->getChildCount, 'changing lineage does not change is(1 , $folder2->getChildCount, 'changing lineage does not change relationship in folder2'); ##Reinstance the asset object due to db manipulation -$folder = WebGUI::Asset->newById($session, $folder->getId); -$folder2 = WebGUI::Asset->newById($session, $folder2->getId); -@snippets = map { WebGUI::Asset->newById($session, $snippets[$_]->getId) } 0..6; -$snippet2 = WebGUI::Asset->newById($session, $snippet2->getId); +$folder = $folder->cloneFromDb; +$folder2 = $folder2->cloneFromDb; +@snippets = map { $_->cloneFromDb } @snippets; +$snippet2 = $snippet2->cloneFromDb; #################################################### # @@ -397,113 +508,6 @@ delete $cachedLineage->{$snippet4->get('lineage')}->{class}; my $snippet4 = WebGUI::Asset->newByLineage($session, $snippets[4]->get('lineage')); is ($snippet4->getId, $snippets[4]->getId, 'newByLineage: failing class cache forces lookup'); -#################################################### -# -# getLineage -# -#################################################### - -@snipIds = map { $_->getId } @snippets; -$lineageIds = $folder->getLineage(['descendants']); - -cmp_bag($lineageIds, \@snipIds, 'default order returned by getLineage is lineage order'); - -my $ids = $folder->getLineage(['self']); -cmp_bag( - [$folder->getId], - $ids, - 'getLineage: get self' -); - -@snipIds = map { $_->getId } @snippets; -$ids = $folder->getLineage(['descendants']); -cmp_bag( - \@snipIds, - $ids, - '... get descendants of folder' -); - -$ids = $folder->getLineage(['self','descendants']); -unshift @snipIds, $folder->getId; -cmp_bag( - \@snipIds, - $ids, - '... get descendants of folder and self' -); - -$ids = $folder->getLineage(['self','children']); -cmp_bag( - \@snipIds, - $ids, - '... descendants == children if there are no grandchildren' -); - -$ids = $topFolder->getLineage(['self','children']); -cmp_bag( - [$topFolder->getId, $folder->getId, $folder2->getId, ], - $ids, - '... children (no descendants) of topFolder', -); - -$ids = $topFolder->getLineage(['self','descendants']); -cmp_bag( - [$topFolder->getId, @snipIds, $folder2->getId, $snippet2->getId], - $ids, - '... descendants of topFolder', -); - -#################################################### -# -# getLineageIterator -# -#################################################### - -sub getListFromIterator { - my $iterator = shift; - my @items; - while (my $item = $iterator->()) { - push @items, $item->getId; - } - return \@items; -} - -@snipIds = map { $_->getId } @snippets; -my $ids = getListFromIterator($folder->getLineageIterator(['descendants'])); -cmp_bag( - \@snipIds, - $ids, - 'getLineageIterator: get descendants of folder' -); - -$ids = getListFromIterator($folder->getLineageIterator(['self','descendants'])); -unshift @snipIds, $folder->getId; -cmp_bag( - \@snipIds, - $ids, - 'getLineageIterator: get descendants of folder and self' -); - -$ids = getListFromIterator($folder->getLineageIterator(['self','children'])); -cmp_bag( - \@snipIds, - $ids, - 'getLineageIterator: descendants == children if there are no grandchildren' -); - -$ids = getListFromIterator($topFolder->getLineageIterator(['self','children'])); -cmp_bag( - [$topFolder->getId, $folder->getId, $folder2->getId, ], - $ids, - 'getLineageIterator: children (no descendants) of topFolder', -); - -$ids = getListFromIterator($topFolder->getLineageIterator(['self','descendants'])); -cmp_bag( - [$topFolder->getId, @snipIds, $folder2->getId, $snippet2->getId], - $ids, - 'getLineageIterator: descendants of topFolder', -); - #################################################### # # addChild