ENHANCEMENT: Only run a single query per class for Hierarchy::numChildren()

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@89999 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Andrew O'Neil 2009-10-22 22:18:02 +00:00
parent 96736eea50
commit f02e8803b1
2 changed files with 31 additions and 8 deletions

View File

@ -475,17 +475,31 @@ class Hierarchy extends DataObjectDecorator {
"\"ParentID\" = " . (int)$this->owner->ID, "\"$baseClass\".\"ID\" ASC");
}
/**
* Cache for numChildren().
*/
private static $num_children_cache = array();
/**
* Return the number of children
* @return int
*/
public function numChildren() {
$baseClass = ClassInfo::baseDataClass($this->owner->class);
// We build the query in an extension-friendly way.
$query = new SQLQuery("COUNT(*)","\"$baseClass\"","\"ParentID\" = " . (int)$this->owner->ID);
$this->owner->extend('augmentSQL', $query);
$this->owner->extend('augmentNumChildrenCountQuery', $query);
return $query->execute()->value();
// Build the cache for this class if it doesn't exist.
if(!isset(self::$num_children_cache[$baseClass])) {
// We build the query in an extension-friendly way.
$query = new SQLQuery("ParentID, COUNT(*)","\"$baseClass\"", "", "", "ParentID");
$this->owner->extend('augmentSQL', $query);
$this->owner->extend('augmentNumChildrenCountQuery', $query);
self::$num_children_cache[$baseClass] = $query->execute()->map();
}
// If theres no value in the cache, it just means that it doesn't have any children.
return isset(self::$num_children_cache[$baseClass][$this->owner->ID]) ? self::$num_children_cache[$baseClass][$this->owner->ID] : 0;
}
/**

View File

@ -51,7 +51,16 @@ class HierarchyTest extends SapphireTest {
$this->assertEquals(array('Page 2', 'Page 3', 'Page 2a', 'Page 2b'), $marked);
$this->assertEquals(array('Page 2', 'Page 2a', 'Page 2b'), $expanded);
}
function testNumChildren() {
$this->assertEquals($this->objFromFixture('Page', 'page1')->numChildren(), 0);
$this->assertEquals($this->objFromFixture('Page', 'page2')->numChildren(), 2);
$this->assertEquals($this->objFromFixture('Page', 'page3')->numChildren(), 2);
$this->assertEquals($this->objFromFixture('Page', 'page2a')->numChildren(), 0);
$this->assertEquals($this->objFromFixture('Page', 'page2b')->numChildren(), 0);
$this->assertEquals($this->objFromFixture('Page', 'page3a')->numChildren(), 0);
$this->assertEquals($this->objFromFixture('Page', 'page3b')->numChildren(), 0);
}
}
}
}