mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
ENHANCEMENT Changed Hierarchy->numChildren() caching to be instance specific and respect flushCache(). This increases the amount of queries on large sets, but decreases the time for a single instance call (implemented in r89999)
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@90084 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
2527b1543d
commit
5ca90fd00b
@ -6,9 +6,16 @@
|
||||
* @subpackage model
|
||||
*/
|
||||
class Hierarchy extends DataObjectDecorator {
|
||||
|
||||
protected $markedNodes;
|
||||
|
||||
protected $markingFilter;
|
||||
|
||||
/**
|
||||
* @var Int
|
||||
*/
|
||||
protected $_cache_numChildren;
|
||||
|
||||
function augmentSQL(SQLQuery &$query) {
|
||||
}
|
||||
|
||||
@ -474,32 +481,34 @@ class Hierarchy extends DataObjectDecorator {
|
||||
return Versioned::get_including_deleted($baseClass,
|
||||
"\"ParentID\" = " . (int)$this->owner->ID, "\"$baseClass\".\"ID\" ASC");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cache for numChildren().
|
||||
*/
|
||||
private static $num_children_cache = array();
|
||||
|
||||
/**
|
||||
* Return the number of children
|
||||
* Return the number of direct children.
|
||||
* By default, values are cached after the first invocation.
|
||||
* Can be augumented by {@link augmentNumChildrenCountQuery()}.
|
||||
*
|
||||
* @param Boolean $cache
|
||||
* @return int
|
||||
*/
|
||||
public function numChildren() {
|
||||
public function numChildren($cache = true) {
|
||||
$baseClass = ClassInfo::baseDataClass($this->owner->class);
|
||||
|
||||
// Build the cache for this class if it doesn't exist.
|
||||
if(!isset(self::$num_children_cache[$baseClass])) {
|
||||
if(!$cache || !is_numeric($this->_cache_numChildren)) {
|
||||
// We build the query in an extension-friendly way.
|
||||
$query = new SQLQuery("ParentID, COUNT(*)","\"$baseClass\"", "", "", "ParentID");
|
||||
$query = new SQLQuery(
|
||||
"COUNT(*)",
|
||||
"\"$baseClass\"",
|
||||
sprintf('"ParentID" = %d', $this->owner->ID)
|
||||
);
|
||||
$this->owner->extend('augmentSQL', $query);
|
||||
$this->owner->extend('augmentNumChildrenCountQuery', $query);
|
||||
|
||||
self::$num_children_cache[$baseClass] = $query->execute()->map();
|
||||
$this->_cache_numChildren = (int)$query->execute()->value();
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
return $this->_cache_numChildren;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -657,6 +666,7 @@ class Hierarchy extends DataObjectDecorator {
|
||||
$this->_cache_children = null;
|
||||
$this->_cache_allChildrenIncludingDeleted = null;
|
||||
$this->_cache_allChildren = null;
|
||||
$this->_cache_numChildren = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,11 +11,11 @@ class HierarchyTest extends SapphireTest {
|
||||
$this->objFromFixture('Page', 'page2b')->delete();
|
||||
$this->objFromFixture('Page', 'page3a')->delete();
|
||||
$this->objFromFixture('Page', 'page3')->delete();
|
||||
|
||||
|
||||
// Check that page1-3 appear at the top level of the AllHistoricalChildren tree
|
||||
$this->assertEquals(array("Page 1", "Page 2", "Page 3"),
|
||||
singleton('Page')->AllHistoricalChildren()->column('Title'));
|
||||
|
||||
|
||||
// Check that both page 2 children are returned
|
||||
$page2 = $this->objFromFixture('Page', 'page2');
|
||||
$this->assertEquals(array("Page 2a", "Page 2b"),
|
||||
@ -23,7 +23,7 @@ class HierarchyTest extends SapphireTest {
|
||||
|
||||
// Page 3 has been deleted; let's bring it back from the grave
|
||||
$page3 = Versioned::get_including_deleted("SiteTree", "\"Title\" = 'Page 3'")->First();
|
||||
|
||||
|
||||
// Check that both page 3 children are returned
|
||||
$this->assertEquals(array("Page 3a", "Page 3b"),
|
||||
$page3->AllHistoricalChildren()->column('Title'));
|
||||
@ -61,6 +61,22 @@ class HierarchyTest extends SapphireTest {
|
||||
$this->assertEquals($this->objFromFixture('Page', 'page2b')->numChildren(), 0);
|
||||
$this->assertEquals($this->objFromFixture('Page', 'page3a')->numChildren(), 0);
|
||||
$this->assertEquals($this->objFromFixture('Page', 'page3b')->numChildren(), 0);
|
||||
|
||||
$page1 = $this->objFromFixture('Page', 'page1');
|
||||
$this->assertEquals($page1->numChildren(), 0);
|
||||
$page1Child1 = new Page();
|
||||
$page1Child1->ParentID = $page1->ID;
|
||||
$page1Child1->write();
|
||||
$this->assertEquals($page1->numChildren(false), 1,
|
||||
'numChildren() caching can be disabled through method parameter'
|
||||
);
|
||||
$page1Child2 = new Page();
|
||||
$page1Child2->ParentID = $page1->ID;
|
||||
$page1Child2->write();
|
||||
$page1->flushCache();
|
||||
$this->assertEquals($page1->numChildren(), 2,
|
||||
'numChildren() caching can be disabled by flushCache()'
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user