Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
113 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
<?php | ||
|
||
abstract class AActiveRecord extends CActiveRecord { | ||
/** | ||
* The identity map | ||
* @var AIdentityMap | ||
*/ | ||
private $_identityMap; | ||
|
||
/** | ||
* Creates an active record with the given attributes. | ||
* This method is internally used by the find methods. | ||
* @param array $attributes attribute values (column name=>column value) | ||
* @param boolean $callAfterFind whether to call {@link afterFind} after the record is populated. | ||
* This parameter is added in version 1.0.3. | ||
* @return CActiveRecord the newly created active record. The class of the object is the same as the model class. | ||
* Null is returned if the input data is false. | ||
*/ | ||
public function populateRecord($attributes,$callAfterFind=true) | ||
{ | ||
if($attributes!==false) | ||
{ | ||
$identityMap = $this->getIdentityMap(); | ||
if (!$identityMap->enabled) { | ||
return parent::populateRecord($attributes,$callAfterFind); | ||
} | ||
$pk = $this->getMetaData()->tableSchema->primaryKey; | ||
$key = $identityMap->getKey($pk, $attributes); | ||
|
||
if (!$identityMap->contains($key)) { | ||
$identityMap->add($key, parent::populateRecord($attributes,$callAfterFind)); | ||
} | ||
else { | ||
Yii::log("Loading ".get_class($identityMap->itemAt($key))."#$key from identity map"); | ||
} | ||
return $identityMap->itemAt($key); | ||
} | ||
else | ||
return null; | ||
} | ||
|
||
/** | ||
* Gets the identity map for this model class | ||
* @return AIdentityMap the identity map | ||
*/ | ||
public function getIdentityMap() { | ||
$class = get_class($this); | ||
if ($this !== $class::model()) { | ||
return $class::model()->getIdentityMap(); | ||
} | ||
if ($this->_identityMap === null) { | ||
$this->_identityMap = new AIdentityMap; | ||
} | ||
return $this->_identityMap; | ||
} | ||
/** | ||
* Sets the identity map for this model class | ||
* @param AIdentityMap|array $identityMap the identity map | ||
*/ | ||
public function setIdentityMap($identityMap) { | ||
$class = get_class($this); | ||
if ($this !== $class::model()) { | ||
return $class::model()->setIdentityMap($identityMap); | ||
} | ||
if (!($identityMap instanceof AIdentityMap)) { | ||
$identityMap = new AIdentityMap($identityMap); | ||
} | ||
$this->_identityMap = $identityMap; | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<?php | ||
/** | ||
* Ensures that each model gets loaded only once by keeping every loaded model in a map. | ||
* | ||
* @author Charles Pick | ||
* @package packages.identityMap | ||
*/ | ||
class AIdentityMap extends CTypedMap { | ||
/** | ||
* Constructor, sets the type for the map | ||
*/ | ||
public function __construct() { | ||
parent::__construct("CActiveRecord"); | ||
} | ||
|
||
/** | ||
* Whether the map is enabled or not | ||
* @var boolean | ||
*/ | ||
public $enabled = true; | ||
/** | ||
* Gets a key to use to store models with the given attributes | ||
* @param string|array $pk the name of the primary key attribute(s) | ||
* @param array $attributes the attributes that contain the keys | ||
* @return string the key key to use when storing and retrieving models with these attributes | ||
*/ | ||
public function getKey($pk, array $attributes) { | ||
if (is_array($pk)) { | ||
$limit = count($pk); | ||
$key = array(); | ||
for($i = 0; $i < $limit; $i++) { | ||
$key[] = $attributes[$pk[$i]]; | ||
} | ||
$pk = implode(":",$key); | ||
} | ||
else { | ||
$pk = $attributes[$pk]; | ||
} | ||
return $pk; | ||
} | ||
} |