Skip to content

Commit

Permalink
BUGFIX: make internal DataObject caches more consistent (os6175)
Browse files Browse the repository at this point in the history
  • Loading branch information
mateusz committed Apr 12, 2012
1 parent 621b2e1 commit 8ea2460
Showing 1 changed file with 35 additions and 64 deletions.
99 changes: 35 additions & 64 deletions model/DataObject.php
Expand Up @@ -85,11 +85,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
* @todo Define the options that can be set here * @todo Define the options that can be set here
*/ */
public static $api_access = false; public static $api_access = false;


public static
$cache_has_own_table = array(),
$cache_has_own_table_field = array();

/** /**
* True if this DataObject has been destroyed. * True if this DataObject has been destroyed.
* @var boolean * @var boolean
Expand Down Expand Up @@ -127,13 +123,6 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
*/ */
protected $original; protected $original;


/**
* The one-to-one, one-to-many and many-to-one components
* indexed by component name.
* @var array
*/
protected $components;

/** /**
* Used by onBeforeDelete() to ensure child classes call parent::onBeforeDelete() * Used by onBeforeDelete() to ensure child classes call parent::onBeforeDelete()
* @var boolean * @var boolean
Expand All @@ -150,7 +139,21 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
* Should dataobjects be validated before they are written? * Should dataobjects be validated before they are written?
*/ */
private static $validation_enabled = true; private static $validation_enabled = true;


/**
* Static caches used by relevant functions.
*/
public static $cache_has_own_table = array();
public static $cache_has_own_table_field = array();
protected static $_cache_get_one;
protected static $_cache_get_class_ancestry;
protected static $_cache_composite_fields = array();

/**
* Non-static relationship cache, indexed by component name.
*/
protected $components;

/** /**
* Returns when validation on DataObjects is enabled. * Returns when validation on DataObjects is enabled.
* @return bool * @return bool
Expand Down Expand Up @@ -227,9 +230,6 @@ public static function custom_database_fields($class) {
return (array)$fields; return (array)$fields;
} }


private static $_cache_custom_database_fields = array();


/** /**
* Returns the field class if the given db field on the class is a composite field. * Returns the field class if the given db field on the class is a composite field.
* Will check all applicable ancestor classes and aggregate results. * Will check all applicable ancestor classes and aggregate results.
Expand Down Expand Up @@ -283,9 +283,6 @@ private static function cache_composite_fields($class) {
self::$_cache_composite_fields[$class] = $compositeFields; self::$_cache_composite_fields[$class] = $compositeFields;
} }


private static $_cache_composite_fields = array();


/** /**
* Construct a new DataObject. * Construct a new DataObject.
* *
Expand Down Expand Up @@ -391,7 +388,7 @@ function setModel(DataModel $model) {
} }


/** /**
* Destroy all of this objects dependant objects. * Destroy all of this objects dependant objects and local caches.
* You'll need to call this to get the memory of an object that has components or extensions freed. * You'll need to call this to get the memory of an object that has components or extensions freed.
*/ */
function destroy() { function destroy() {
Expand Down Expand Up @@ -1159,10 +1156,9 @@ public function write($showDebug = false, $forceInsert = false, $forceWrite = fa
return $this->record['ID']; return $this->record['ID'];
} }



/** /**
* Write the cached components to the database. Cached components could refer to two different instances of the same record. * Write the cached components to the database. Cached components could refer to two different instances of the same record.
* *
* @param $recursive Recursively write components * @param $recursive Recursively write components
*/ */
public function writeComponents($recursive = false) { public function writeComponents($recursive = false) {
Expand Down Expand Up @@ -1224,12 +1220,6 @@ public static function delete_by_id($className, $id) {
} }
} }


/**
* A cache used by getClassAncestry()
* @var array
*/
protected static $ancestry;

/** /**
* Get the class ancestry, including the current class name. * Get the class ancestry, including the current class name.
* The ancestry will be returned as an array of class names, where the 0th element * The ancestry will be returned as an array of class names, where the 0th element
Expand All @@ -1239,13 +1229,13 @@ public static function delete_by_id($className, $id) {
* @return array Class ancestry * @return array Class ancestry
*/ */
public function getClassAncestry() { public function getClassAncestry() {
if(!isset(DataObject::$ancestry[$this->class])) { if(!isset(DataObject::$_cache_get_class_ancestry[$this->class])) {
DataObject::$ancestry[$this->class] = array($this->class); DataObject::$_cache_get_class_ancestry[$this->class] = array($this->class);
while(($class = get_parent_class(DataObject::$ancestry[$this->class][0])) != "DataObject") { while(($class = get_parent_class(DataObject::$_cache_get_class_ancestry[$this->class][0])) != "DataObject") {
array_unshift(DataObject::$ancestry[$this->class], $class); array_unshift(DataObject::$_cache_get_class_ancestry[$this->class], $class);
} }
} }
return DataObject::$ancestry[$this->class]; return DataObject::$_cache_get_class_ancestry[$this->class];
} }


/** /**
Expand Down Expand Up @@ -1292,12 +1282,6 @@ public function getComponent($componentName) {
return $component; return $component;
} }


/**
* A cache used by component getting classes
* @var array
*/
protected $componentCache;

/** /**
* Returns a one-to-many relation as a HasManyList * Returns a one-to-many relation as a HasManyList
* *
Expand Down Expand Up @@ -2487,11 +2471,6 @@ public function buildSQL($filter = "", $sort = "", $limit = "", $join = "", $res
return $this->extendedSQL($filter, $sort, $limit, $join, $having); return $this->extendedSQL($filter, $sort, $limit, $join, $having);


} }

/**
* Cache for the hairy bit of buildSQL
*/
private static $cache_buildSQL_query;


/** /**
* @deprecated 3.0 Use DataList::create and DataList to do your querying * @deprecated 3.0 Use DataList::create and DataList to do your querying
Expand Down Expand Up @@ -2611,12 +2590,6 @@ function buildDataObjectSet($records, $containerClass = "DataObjectSet", $query
} }
} }


/**
* A cache used by get_one.
* @var array
*/
protected static $cache_get_one;

/** /**
* Return the first item matching the given query. * Return the first item matching the given query.
* All calls to get_one() are cached. * All calls to get_one() are cached.
Expand All @@ -2638,28 +2611,28 @@ public static function get_one($callerClass, $filter = "", $cache = true, $order
$cacheKey = md5($cacheKey); $cacheKey = md5($cacheKey);


// Flush destroyed items out of the cache // Flush destroyed items out of the cache
if($cache && isset(DataObject::$cache_get_one[$callerClass][$cacheKey]) && DataObject::$cache_get_one[$callerClass][$cacheKey] instanceof DataObject && DataObject::$cache_get_one[$callerClass][$cacheKey]->destroyed) { if($cache && isset(DataObject::$_cache_get_one[$callerClass][$cacheKey]) && DataObject::$_cache_get_one[$callerClass][$cacheKey] instanceof DataObject && DataObject::$_cache_get_one[$callerClass][$cacheKey]->destroyed) {
DataObject::$cache_get_one[$callerClass][$cacheKey DataObject::$_cache_get_one[$callerClass][$cacheKey
] = false; ] = false;
} }
if(!$cache || !isset(DataObject::$cache_get_one[$callerClass][$cacheKey])) { if(!$cache || !isset(DataObject::$_cache_get_one[$callerClass][$cacheKey])) {
$dl = DataList::create($callerClass)->where($filter)->sort($orderby); $dl = DataList::create($callerClass)->where($filter)->sort($orderby);
$dl->setModel(DataModel::inst()); $dl->setModel(DataModel::inst());
$item = $dl->First(); $item = $dl->First();


if($cache) { if($cache) {
DataObject::$cache_get_one[$callerClass][$cacheKey] = $item; DataObject::$_cache_get_one[$callerClass][$cacheKey] = $item;
if(!DataObject::$cache_get_one[$callerClass][$cacheKey]) { if(!DataObject::$_cache_get_one[$callerClass][$cacheKey]) {
DataObject::$cache_get_one[$callerClass][$cacheKey] = false; DataObject::$_cache_get_one[$callerClass][$cacheKey] = false;
} }
} }
} }
return $cache ? DataObject::$cache_get_one[$callerClass][$cacheKey] : $item; return $cache ? DataObject::$_cache_get_one[$callerClass][$cacheKey] : $item;
} }


/** /**
* Flush the cached results for all relations (has_one, has_many, many_many) * Flush the cached results for all relations (has_one, has_many, many_many)
* Also clears any cached aggregate data * Also clears any cached aggregate data.
* *
* @param boolean $persistent When true will also clear persistent data stored in the Cache system. * @param boolean $persistent When true will also clear persistent data stored in the Cache system.
* When false will just clear session-local cached data * When false will just clear session-local cached data
Expand All @@ -2669,27 +2642,25 @@ public function flushCache($persistent = true) {
if($persistent) Aggregate::flushCache($this->class); if($persistent) Aggregate::flushCache($this->class);


if($this->class == 'DataObject') { if($this->class == 'DataObject') {
DataObject::$cache_get_one = array(); DataObject::$_cache_get_one = array();
return; return;
} }


$classes = ClassInfo::ancestry($this->class); $classes = ClassInfo::ancestry($this->class);
foreach($classes as $class) { foreach($classes as $class) {
if(isset(self::$cache_get_one[$class])) unset(self::$cache_get_one[$class]); if(isset(self::$_cache_get_one[$class])) unset(self::$_cache_get_one[$class]);
} }


$this->extend('flushCache'); $this->extend('flushCache');

$this->componentCache = array();
} }


static function flush_and_destroy_cache() { static function flush_and_destroy_cache() {
if(self::$cache_get_one) foreach(self::$cache_get_one as $class => $items) { if(self::$_cache_get_one) foreach(self::$_cache_get_one as $class => $items) {
if(is_array($items)) foreach($items as $item) { if(is_array($items)) foreach($items as $item) {
if($item) $item->destroy(); if($item) $item->destroy();
} }
} }
self::$cache_get_one = array(); self::$_cache_get_one = array();
} }


/** /**
Expand Down

0 comments on commit 8ea2460

Please sign in to comment.