diff options
13 files changed, 183 insertions, 344 deletions
diff --git a/.gitattributes b/.gitattributes index e4e7fdb3..0c8dc975 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2028,7 +2028,6 @@ framework/Data/ActiveRecord/TActiveRecordConfig.php -text framework/Data/ActiveRecord/TActiveRecordCriteria.php -text framework/Data/ActiveRecord/TActiveRecordGateway.php -text framework/Data/ActiveRecord/TActiveRecordManager.php -text -framework/Data/ActiveRecord/TActiveRecordStateRegistry.php -text framework/Data/Common/IbmDb2/TIbmColumnMetaData.php -text framework/Data/Common/IbmDb2/TIbmMetaData.php -text framework/Data/Common/IbmDb2/TIbmMetaDataInspector.php -text diff --git a/framework/Data/ActiveRecord/Relations/TActiveRecordBelongsTo.php b/framework/Data/ActiveRecord/Relations/TActiveRecordBelongsTo.php index c030f2d2..565070c1 100644 --- a/framework/Data/ActiveRecord/Relations/TActiveRecordBelongsTo.php +++ b/framework/Data/ActiveRecord/Relations/TActiveRecordBelongsTo.php @@ -123,20 +123,16 @@ class TActiveRecordBelongsTo extends TActiveRecordRelation {
$obj = $this->getContext()->getSourceRecord();
$fkObject = $obj->getColumnValue($this->getContext()->getProperty());
- $registry = $fkObject->getRecordManager()->getObjectStateRegistry();
- if($registry->shouldPersistObject($fkObject))
+ if($fkObject!==null)
{
- if($fkObject!==null)
- {
- $fkObject->save();
- $source = $this->getSourceRecord();
- $fkeys = $this->findForeignKeys($source, $fkObject);
- foreach($fkeys as $srcKey => $fKey)
- $source->setColumnValue($srcKey, $fkObject->getColumnValue($fKey));
- return true;
- }
+ $fkObject->save();
+ $source = $this->getSourceRecord();
+ $fkeys = $this->findForeignKeys($source, $fkObject);
+ foreach($fkeys as $srcKey => $fKey)
+ $source->setColumnValue($srcKey, $fkObject->getColumnValue($fKey));
+ return true;
}
- return true;
+ return false;
}
}
diff --git a/framework/Data/ActiveRecord/Relations/TActiveRecordHasMany.php b/framework/Data/ActiveRecord/Relations/TActiveRecordHasMany.php index f7426862..382d9789 100644 --- a/framework/Data/ActiveRecord/Relations/TActiveRecordHasMany.php +++ b/framework/Data/ActiveRecord/Relations/TActiveRecordHasMany.php @@ -88,7 +88,7 @@ class TActiveRecordHasMany extends TActiveRecordRelation /**
* @return array foreign key field names as key and object properties as value.
* @since 3.1.2
- */
+ */
public function getRelationForeignKeys()
{
$fkObject = $this->getContext()->getForeignRecordFinder();
@@ -107,16 +107,12 @@ class TActiveRecordHasMany extends TActiveRecordRelation if(($total = count($fkObjects))> 0)
{
$source = $this->getSourceRecord();
- $registry = $source->getRecordManager()->getObjectStateRegistry();
$fkeys = $this->findForeignKeys($fkObjects[0], $source);
for($i=0;$i<$total;$i++)
{
- if($registry->shouldPersistObject($fkObjects[$i]))
- {
- foreach($fkeys as $fKey => $srcKey)
- $fkObjects[$i]->setColumnValue($fKey, $source->getColumnValue($srcKey));
- $success = $fkObjects[$i]->save() && $success;
- }
+ foreach($fkeys as $fKey => $srcKey)
+ $fkObjects[$i]->setColumnValue($fKey, $source->getColumnValue($srcKey));
+ $success = $fkObjects[$i]->save() && $success;
}
}
return $success;
diff --git a/framework/Data/ActiveRecord/Relations/TActiveRecordHasManyAssociation.php b/framework/Data/ActiveRecord/Relations/TActiveRecordHasManyAssociation.php index 564d3d22..bcda962c 100644 --- a/framework/Data/ActiveRecord/Relations/TActiveRecordHasManyAssociation.php +++ b/framework/Data/ActiveRecord/Relations/TActiveRecordHasManyAssociation.php @@ -189,7 +189,6 @@ class TActiveRecordHasManyAssociation extends TActiveRecordRelation {
$criteria = $this->getCriteria();
$finder = $this->getContext()->getForeignRecordFinder();
- $registry = $finder->getRecordManager()->getObjectStateRegistry();
$type = get_class($finder);
$command = $this->createCommand($criteria, $foreignKeys,$indexValues,$sourceKeys);
$srcProps = array_keys($sourceKeys);
@@ -201,7 +200,6 @@ class TActiveRecordHasManyAssociation extends TActiveRecordRelation unset($row[$column]);
$obj = $this->createFkObject($type,$row,$foreignKeys);
$collections[$hash][] = $obj;
- $registry->registerClean($obj);
}
$this->setResultCollection($results, $collections, array_values($sourceKeys));
}
@@ -214,7 +212,7 @@ class TActiveRecordHasManyAssociation extends TActiveRecordRelation */
protected function createFkObject($type,$row,$foreignKeys)
{
- $obj = new $type($row);
+ $obj = TActiveRecord::createRecordInstance($type, $row, TActiveRecord::STATE_LOADED);
if(count($this->_association_columns) > 0)
{
$i=0;
@@ -309,13 +307,9 @@ class TActiveRecordHasManyAssociation extends TActiveRecordRelation if(($total = count($fkObjects))> 0)
{
$source = $this->getSourceRecord();
- $registry = $source->getRecordManager()->getObjectStateRegistry();
$builder = $this->getAssociationTableCommandBuilder();
for($i=0;$i<$total;$i++)
- {
- if($registry->shouldPersistObject($fkObjects[$i]))
- $success = $fkObjects[$i]->save() && $success;
- }
+ $success = $fkObjects[$i]->save() && $success;
return $this->updateAssociationTable($obj, $fkObjects, $builder) && $success;
}
return $success;
diff --git a/framework/Data/ActiveRecord/Relations/TActiveRecordHasOne.php b/framework/Data/ActiveRecord/Relations/TActiveRecordHasOne.php index e5a36659..49119965 100644 --- a/framework/Data/ActiveRecord/Relations/TActiveRecordHasOne.php +++ b/framework/Data/ActiveRecord/Relations/TActiveRecordHasOne.php @@ -100,7 +100,7 @@ class TActiveRecordHasOne extends TActiveRecordRelation $fkObjects = $this->findForeignObjects($fields,$indexValues);
$this->populateResult($results,$properties,$fkObjects,$fields);
}
-
+
/**
* @return array foreign key field names as key and object properties as value.
* @since 3.1.2
@@ -135,16 +135,11 @@ class TActiveRecordHasOne extends TActiveRecordRelation public function updateAssociatedRecords()
{
$fkObject = $this->getContext()->getPropertyValue();
- $registry = $fkObject->getRecordManager()->getObjectStateRegistry();
- if($registry->shouldPersistObject($fkObject))
- {
- $source = $this->getSourceRecord();
- $fkeys = $this->findForeignKeys($fkObject, $source);
- foreach($fkeys as $fKey => $srcKey)
- $fkObject->setColumnValue($fKey, $source->getColumnValue($srcKey));
- return $fkObject->save();
- }
- return true;
+ $source = $this->getSourceRecord();
+ $fkeys = $this->findForeignKeys($fkObject, $source);
+ foreach($fkeys as $fKey => $srcKey)
+ $fkObject->setColumnValue($fKey, $source->getColumnValue($srcKey));
+ return $fkObject->save();
}
}
diff --git a/framework/Data/ActiveRecord/Relations/TActiveRecordRelation.php b/framework/Data/ActiveRecord/Relations/TActiveRecordRelation.php index 5bde4898..63e182ca 100644 --- a/framework/Data/ActiveRecord/Relations/TActiveRecordRelation.php +++ b/framework/Data/ActiveRecord/Relations/TActiveRecordRelation.php @@ -162,7 +162,7 @@ abstract class TActiveRecordRelation $ids=array();
foreach($properties as $property)
$ids[] = is_object($obj) ? $obj->getColumnValue($property) : $obj[$property];
- return sprintf('%x',crc32(serialize($ids)));
+ return serialize($ids);
}
/**
diff --git a/framework/Data/ActiveRecord/Relations/TActiveRecordRelationContext.php b/framework/Data/ActiveRecord/Relations/TActiveRecordRelationContext.php index 8bc4362f..d6f86a9a 100644 --- a/framework/Data/ActiveRecord/Relations/TActiveRecordRelationContext.php +++ b/framework/Data/ActiveRecord/Relations/TActiveRecordRelationContext.php @@ -182,8 +182,9 @@ class TActiveRecordRelationContext public function updateAssociatedRecords($updateBelongsTo=false)
{
$success=true;
- foreach($this->_record->getRelations() as $property=>$relation)
+ foreach($this->_record->getRelations() as $data)
{
+ list($property, $relation) = $data;
$belongsTo = $relation[0]==TActiveRecord::BELONGS_TO;
if(($updateBelongsTo && $belongsTo) || (!$updateBelongsTo && !$belongsTo))
{
diff --git a/framework/Data/ActiveRecord/TActiveRecord.php b/framework/Data/ActiveRecord/TActiveRecord.php index f5d73582..4bbee046 100644 --- a/framework/Data/ActiveRecord/TActiveRecord.php +++ b/framework/Data/ActiveRecord/TActiveRecord.php @@ -108,6 +108,27 @@ Prado::using('System.Data.ActiveRecord.Relations.TActiveRecordRelationContext'); * fetched in a lazy way, which avoids unnecessary overhead if the foreign objects are not accessed * at all. * + * Since v3.1.2, new events OnInsert, OnUpdate and OnDelete are available. + * The event OnInsert, OnUpdate and OnDelete methods are executed before + * inserting, updating, and deleting the current record, respectively. You may override + * these methods; a TActiveRecordChangeEventParameter parameter is passed to these methods. + * The property {@link TActiveRecordChangeEventParameter::setIsValid IsValid} of the parameter + * can be set to false to prevent the change action to be executed. This can be used, + * for example, to validate the record before the action is executed. For example, + * in the following the password property is hashed before a new record is inserted. + * <code> + * class UserRecord extends TActiveRecord + * { + * function OnInsert($param) + * { + * //parent method should be called to raise the event + * parent::OnInsert($param); + * $this->nounce = md5(time()); + * $this->password = md5($this->password.$this->nounce); + * } + * } + * </code> + * * @author Wei Zhuo <weizho[at]gmail[dot]com> * @version $Id$ * @package System.Data.ActiveRecord @@ -120,6 +141,16 @@ abstract class TActiveRecord extends TComponent const HAS_MANY='HAS_MANY'; const MANY_TO_MANY='MANY_TO_MANY'; + const STATE_NEW=0; + const STATE_LOADED=1; + const STATE_DELETED=2; + + /** + * @var integer object state: 0 = new, 1 = loaded, 2 = deleted. + * @since 3.1.2 + */ + private $_objectState=0; + /** * This static variable defines the column mapping. * The keys are physical column names as defined in database, @@ -177,11 +208,12 @@ abstract class TActiveRecord extends TComponent */ public function __construct($data=array(), $connection=null) { - $this->copyFrom($data); if($connection!==null) - $this->_connection=$connection; + $this->setDbConnection($connection); $this->setupColumnMapping(); $this->setupRelations(); + if(!empty($data)) //$data may be an object + $this->copyFrom($data); } /** @@ -242,7 +274,7 @@ abstract class TActiveRecord extends TComponent $class=new ReflectionClass($className); $relations=array(); foreach($class->getStaticPropertyValue('RELATIONS') as $key=>$value) - $relations[strtolower($key)]=$value; + $relations[strtolower($key)]=array($key,$value); self::$_relations[$className]=$relations; } } @@ -258,7 +290,7 @@ abstract class TActiveRecord extends TComponent if(!is_array($data)) throw new TActiveRecordException('ar_must_copy_from_array_or_object', get_class($this)); foreach($data as $name=>$value) - $this->$name = $value; + $this->setColumnValue($name,$value); return $this; } @@ -270,11 +302,7 @@ abstract class TActiveRecord extends TComponent public function getDbConnection() { if($this->_connection===null) - { - $this->setDbConnection(self::getRecordManager()->getDbConnection()); - if($this->_connection===null) //check it - throw new TActiveRecordException('ar_invalid_db_connection',get_class($this)); - } + return self::getRecordManager()->getDbConnection(); return $this->_connection; } @@ -367,19 +395,31 @@ abstract class TActiveRecord extends TComponent } /** - * Commit changes to the record, may insert, update or delete depending - * on the record state given in TObjectStateRegistery. + * Commit changes to the record: insert, update or delete depending on the object state. * @return boolean true if changes were made. */ protected function commitChanges() { - $registry = $this->getRecordManager()->getObjectStateRegistry(); $gateway = $this->getRecordGateway(); if(!$this->_readOnly) $this->_readOnly = $gateway->getRecordTableInfo($this)->getIsView(); if($this->_readOnly) throw new TActiveRecordException('ar_readonly_exception',get_class($this)); - return $registry->commit($this,$gateway); + $param = new TActiveRecordChangeEventParameter(); + switch($this->_objectState) + { + case self::STATE_NEW: + $this->onInsert($param); + return $param->getIsValid() ? $gateway->insert($this) : false; + case self::STATE_LOADED: + $this->onUpdate($param); + return $param->getIsValid() ? $gateway->update($this) : false; + case self::STATE_DELETED: + $this->onDelete($param); + return $param->getIsValid() ? $gateway->delete($this) : false; + default: + throw new TActiveRecordException('ar_invalid_state', get_class($this)); + } } /** @@ -389,8 +429,7 @@ abstract class TActiveRecord extends TComponent */ public function delete() { - $registry = $this->getRecordManager()->getObjectStateRegistry(); - $registry->registerRemoved($this); + $this->_objectState = self::STATE_DELETED; return $this->commitChanges(); } @@ -456,19 +495,22 @@ abstract class TActiveRecord extends TComponent { if(empty($data)) return null; - //create and populate the object + $obj = self::createRecordInstance($type, $data, self::STATE_LOADED); + return $obj; + } + + /** + * Create an instance of ActiveRecord class given by $type. + * This static method should only be used internally within core ActiveRecord classes. + */ + public static function createRecordInstance($type, $data=array(), $state=self::STATE_NEW) + { $obj = Prado::createComponent($type); - $tableInfo = $this->getRecordGateway()->getRecordTableInfo($obj); - foreach($data as $name=>$value) - $obj->setColumnValue($name,$value); - /* - foreach($tableInfo->getColumns()->getKeys() as $name) - { - if(isset($data[$name])) - $obj->setColumnValue($name,$data[$name]); - }*/ - $obj->_readOnly = $tableInfo->getIsView(); - $this->getRecordManager()->getObjectStateRegistry()->registerClean($obj); + $obj->_objectState=$state; + $tableInfo = $obj->getRecordGateway()->getRecordTableInfo($obj); + $obj->_readOnly=$tableInfo->getIsView(); + if(!empty($data)) + $obj->copyFrom($data); return $obj; } @@ -642,9 +684,9 @@ abstract class TActiveRecord extends TComponent * @param array method call arguments. * @return TActiveRecordRelation, null if the context or the handler doesn't exist */ - protected function getRelationHandler($property,$args=array()) + protected function getRelationHandler($name,$args=array()) { - if(($context=$this->getRelationContext($property)) !== null) + if(($context=$this->getRelationContext($name)) !== null) { $criteria = $this->getCriteria(count($args)>0 ? $args[0] : null, array_slice($args,1)); return $context->getRelationHandler($criteria); @@ -662,10 +704,10 @@ abstract class TActiveRecord extends TComponent * the active record relationships for given property, null if invalid relationship * @since 3.1.2 */ - protected function getRelationContext($property) + protected function getRelationContext($name) { - if(($relation=$this->getRelation($property))!==null) - return new TActiveRecordRelationContext($this,strtolower($property),$relation); + if(list($property, $relation) = $this->getRelation($name)) + return new TActiveRecordRelationContext($this,$property,$relation); else return null; } @@ -825,6 +867,36 @@ abstract class TActiveRecord extends TComponent } /** + * Raised before the record attempt to insert its data into the database. + * To prevent the insert operation, set the TActiveRecordChangeEventParameter::IsValid parameter to false. + * @param TActiveRecordChangeEventParameter event parameter to be passed to the event handlers + */ + public function onInsert($param) + { + $this->raiseEvent('OnInsert', $this, $param); + } + + /** + * Raised before the record attempt to delete its data from the database. + * To prevent the insert operation, set the TActiveRecordChangeEventParameter::IsValid parameter to false. + * @param TActiveRecordChangeEventParameter event parameter to be passed to the event handlers + */ + public function onDelete($param) + { + $this->raiseEvent('OnDelete', $this, $param); + } + + /** + * Raised before the record attempt to update its data in the database. + * To prevent the insert operation, set the TActiveRecordChangeEventParameter::IsValid parameter to false. + * @param TActiveRecordChangeEventParameter event parameter to be passed to the event handlers + */ + public function onUpdate($param) + { + $this->raiseEvent('OnUpdate', $this, $param); + } + + /** * Retrieves the column value according to column name. * This method is used internally. * @param string the column name (as defined in database schema) @@ -885,4 +957,41 @@ abstract class TActiveRecord extends TComponent return isset(self::$_relations[get_class($this)][strtolower($property)]); } } + +/** + * TActiveRecordChangeEventParameter class + * + * TActiveRecordChangeEventParameter encapsulates the parameter data for + * ActiveRecord change commit events that are broadcasted. The following change events + * may be raise: {@link TActiveRecord::OnInsert}, {@link TActiveRecord::OnUpdate} and + * {@link TActiveRecord::OnDelete}. The {@link setIsValid IsValid} parameter can + * be set to false to prevent the requested change event to be performed. + * + * @author Wei Zhuo<weizhuo@gmail.com> + * @version $Id$ + * @package System.Data.ActiveRecord + * @since 3.1.2 + */ + +class TActiveRecordChangeEventParameter extends TEventParameter +{ + private $_isValid=true; + + /** + * @return boolean whether the event should be performed. + */ + public function getIsValid() + { + return $this->_isValid; + } + + /** + * @param boolean set to false to prevent the event. + */ + public function setIsValid($value) + { + $this->_isValid = TPropertyValue::ensureBoolean($value); + } +} + ?>
\ No newline at end of file diff --git a/framework/Data/ActiveRecord/TActiveRecordManager.php b/framework/Data/ActiveRecord/TActiveRecordManager.php index ab6fe88d..3790773d 100644 --- a/framework/Data/ActiveRecord/TActiveRecordManager.php +++ b/framework/Data/ActiveRecord/TActiveRecordManager.php @@ -14,11 +14,10 @@ Prado::using('System.Data.TDbConnection'); Prado::using('System.Data.ActiveRecord.TActiveRecord');
Prado::using('System.Data.ActiveRecord.Exceptions.TActiveRecordException');
Prado::using('System.Data.ActiveRecord.TActiveRecordGateway');
-Prado::using('System.Data.ActiveRecord.TActiveRecordStateRegistry');
/**
- * TActiveRecordManager provides the default DB connection, default object state
- * registry, default active record gateway, and table meta data inspector.
+ * TActiveRecordManager provides the default DB connection,
+ * default active record gateway, and table meta data inspector.
*
* The default connection can be set as follows:
* <code>
@@ -38,7 +37,6 @@ Prado::using('System.Data.ActiveRecord.TActiveRecordStateRegistry'); */
class TActiveRecordManager extends TComponent
{
- private $_objectRegistry;
private $_gateway;
private $_meta=array();
private $_connection;
@@ -91,24 +89,6 @@ class TActiveRecordManager extends TComponent }
/**
- * @return TActiveRecordStateRegistry record object registry.
- */
- public function getObjectStateRegistry()
- {
- if(is_null($this->_objectRegistry))
- $this->_objectRegistry = $this->createObjectStateRegistry();
- return $this->_objectRegistry;
- }
-
- /**
- * @return TActiveRecordStateRegistry default object registry.
- */
- protected function createObjectStateRegistry()
- {
- return new TActiveRecordStateRegistry();
- }
-
- /**
* @return TActiveRecordGateway record gateway.
*/
public function getRecordGateway()
diff --git a/framework/Data/ActiveRecord/TActiveRecordStateRegistry.php b/framework/Data/ActiveRecord/TActiveRecordStateRegistry.php deleted file mode 100644 index 7a285274..00000000 --- a/framework/Data/ActiveRecord/TActiveRecordStateRegistry.php +++ /dev/null @@ -1,243 +0,0 @@ -<?php -/**
- * TActiveRecordStateRegistry class file.
- *
- * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @link http://www.pradosoft.com/
- * @copyright Copyright © 2005-2007 PradoSoft
- * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Data.ActiveRecord
- */
-
-/**
- * Active record Unit of Work class and Identity Map.
- *
- * Maintains a list of objects affected by a business transaction and
- * coordinates the writing out of changes and the resolution of concurrency problems.
- *
- * This registry keeps track of everything you do during a business transaction
- * that can affect the database. When you're done, it figures out everything that
- * needs to be done to alter the database as a result of your work.
- *
- * The object can only be in one of the four states: "new", "clean", "dirty" or "removed".
- * A "new" object is one that is created not by loading the record from database.
- * A "clean" object is one that is created by loading the record from datase.
- * A "dirty" object is one that is marked as dirty or a "clean" object that has
- * its internal state altered (done by using == object comparision).
- * A "removed" object is one that is marked for deletion.
- *
- * See the "Active Record Object States.png" in the docs directory for state
- * transition diagram.
- *
- * @author Wei Zhuo <weizho[at]gmail[dot]com>
- * @version $Id$
- * @package System.Data.ActiveRecord
- * @since 3.1
- */
-class TActiveRecordStateRegistry
-{
- private $_cleanObjects=array();
- private $_removedObjects;
- //private $_cachedObjects=array();
- /**
- * Initialize the registry.
- */
- public function __construct()
- {
- $this->_removedObjects = new TList;
- }
-
- /**
- * @return string hash of the data.
- */
- protected function getObjectDataKey($data)
- {
- return sprintf('%x',crc32(serialize($data)));
- }
-
- /**
- * Ensure that object is not null.
- */
- protected function assertNotNull($obj)
- {
- if(is_null($obj))
- throw new TActiveRecordException('ar_object_must_not_be_null');
- }
-
- /**
- * Register the object for deletion, when the object invokes its delete() method
- * the corresponding row in the database is deleted.
- * @param TActiveRecord existing active record.
- * @throws TActiveRecordException if object is null.
- */
- public function registerRemoved($obj)
- {
- $this->assertNotNull($obj);
- $found=false;
- foreach($this->_cleanObjects as $i=>$cache)
- {
- if($cache[0]===$obj)
- {
- unset($this->_cleanObjects[$i]);
- $found=true;
- }
- }
- if(!$found)
- throw new TActiveRecordException('ar_object_must_be_retrieved_before_delete');
- if(!$this->_removedObjects->contains($obj))
- $this->_removedObjects->add($obj);
- }
-
- /**
- * Register a clean object attached to a specific data that was used to
- * populate the object. This acts as an object cache.
- * @param TActiveRecord new clean object.
- */
- public function registerClean($obj)
- {
- $this->removeCleanOrDirty($obj);
- if($this->isRemovedObject($obj))
- throw new TActiveRecordException('ar_object_marked_for_removal');
- $this->_cleanObjects[] = array($obj, clone($obj));
- }
-
- /**
- * Remove the object from dirty state.
- * @param TActiveRecord object to remove.
- */
- protected function removeDirty($obj)
- {
- $this->assertNotNull($obj);
- foreach($this->_cleanObjects as $i=>$cache)
- if($cache[0]===$obj && $obj != $cache[1])
- unset($this->_cleanObjects[$i]);
- }
-
- /**
- * Remove object from clean state.
- * @param TActiveRecord object to remove.
- */
- protected function removeClean($obj)
- {
- $this->assertNotNull($obj);
- foreach($this->_cleanObjects as $i=>$cache)
- if($cache[0]===$obj && $obj == $cache[1])
- unset($this->_cleanObjects[$i]);
- }
-
- /**
- * Remove object from dirty and clean state.
- * @param TActiveRecord object to remove.
- */
- protected function removeCleanOrDirty($obj)
- {
- $this->assertNotNull($obj);
- foreach($this->_cleanObjects as $i=>$cache)
- if($cache[0]===$obj)
- unset($this->_cleanObjects[$i]);
- }
-
- /**
- * Remove object from removed state.
- * @param TActiveRecord object to remove.
- */
- protected function removeRemovedObject($obj)
- {
- $this->_removedObjects->remove($obj);
- }
-
- /**
- * Test whether an object is dirty or has been modified.
- * @param TActiveRecord object to test.
- * @return boolean true if the object is dirty, false otherwise.
- */
- public function isDirtyObject($obj)
- {
- foreach($this->_cleanObjects as $cache)
- if($cache[0] === $obj)
- return $obj != $cache[1];
- return false;
- }
-
- /**
- * Test whether an object is in the clean state.
- * @param TActiveRecord object to test.
- * @return boolean true if object is clean, false otherwise.
- */
- public function isCleanObject($obj)
- {
- foreach($this->_cleanObjects as $cache)
- if($cache[0] === $obj)
- return $obj == $cache[1];
- return false;
- }
-
- /**
- * Test whether an object is a new instance.
- * @param TActiveRecord object to test.
- * @return boolean true if object is newly created, false otherwise.
- */
- public function isNewObject($obj)
- {
- if($this->isRemovedObject($obj)) return false;
- foreach($this->_cleanObjects as $cache)
- if($cache[0] === $obj)
- return false;
- return true;
- }
-
- /**
- * @param TActiveRecord object to test.
- * @return boolean true if object is dirty or is new.
- */
- public function shouldPersistObject($obj)
- {
- return $this->isDirtyObject($obj) || $this->isNewObject($obj);
- }
-
- /**
- * Test whether an object is marked for deletion.
- * @param TActiveRecord object to test.
- * @return boolean true if object is marked for deletion, false otherwise.
- */
- public function isRemovedObject($obj)
- {
- return $this->_removedObjects->contains($obj);
- }
-
- /**
- * Commit the object to database:
- * * a new record is inserted if the object is new, object becomes clean.
- * * the record is updated if the object is dirty, object becomes clean.
- * * the record is deleted if the object is marked for removal.
- *
- * @param TActiveRecord record object.
- * @param TActiveRecordGateway database gateway
- * @return boolean true if commit was successful, false otherwise.
- */
- public function commit($record,$gateway)
- {
- $rowsAffected=false;
-
- if($this->isRemovedObject($record))
- {
- $rowsAffected = $gateway->delete($record);
- if($rowsAffected)
- $this->removeRemovedObject($record);
- }
- else
- {
- if($this->isDirtyObject($record))
- $rowsAffected = $gateway->update($record);
- else if($this->isNewObject($record))
- $rowsAffected = $gateway->insert($record);
-
- if($rowsAffected)
- $this->registerClean($record);
- }
- return (boolean)$rowsAffected;
- }
-}
- -?>
\ No newline at end of file diff --git a/framework/Web/Javascripts/source/prado/activecontrols/inlineeditor.js b/framework/Web/Javascripts/source/prado/activecontrols/inlineeditor.js index 8f480d3d..87b8ddde 100644 --- a/framework/Web/Javascripts/source/prado/activecontrols/inlineeditor.js +++ b/framework/Web/Javascripts/source/prado/activecontrols/inlineeditor.js @@ -283,7 +283,7 @@ Prado.WebUI.TInPlaceTextBox = Base.extend( }
}
},
-
+
setReadOnly : function(id, value)
{
var textbox = Prado.WebUI.TInPlaceTextBox.textboxes[id];
@@ -291,5 +291,5 @@ Prado.WebUI.TInPlaceTextBox = Base.extend( {
textbox.readOnly=value;
}
- },
+ }
});
\ No newline at end of file diff --git a/tests/simple_unit/ActiveRecord/ForeignKeyTestCase.php b/tests/simple_unit/ActiveRecord/ForeignKeyTestCase.php index 2e4bee2d..d8017aeb 100644 --- a/tests/simple_unit/ActiveRecord/ForeignKeyTestCase.php +++ b/tests/simple_unit/ActiveRecord/ForeignKeyTestCase.php @@ -159,7 +159,6 @@ class ForeignKeyTestCase extends UnitTestCase function test_self_reference_fk()
{
$item = ItemRecord::finder()->withRelated_Items()->findByPk(1);
-
$this->assertNotNull($item);
$this->assertEqual($item->name, "Professional Work Attire");
diff --git a/tests/simple_unit/ActiveRecord/MultipleForeignKeyTestCase.php b/tests/simple_unit/ActiveRecord/MultipleForeignKeyTestCase.php index 16036b9f..77408631 100644 --- a/tests/simple_unit/ActiveRecord/MultipleForeignKeyTestCase.php +++ b/tests/simple_unit/ActiveRecord/MultipleForeignKeyTestCase.php @@ -32,7 +32,7 @@ class Table1 extends MultipleFKSqliteRecord public $fk3;
public $object1;
- public $object2;
+ //public $object2; //commented out for testing __get/__set
public $object3;
public static $RELATIONS = array
@@ -57,7 +57,7 @@ class Table2 extends MultipleFKSqliteRecord public $field1;
private $_state1;
- public $state2;
+ //public $state2; //commented out for testing __get/__set
public $state3;
public static $RELATIONS = array
@@ -174,6 +174,19 @@ class MultipleForeignKeyTestCase extends UnitTestCase $this->assertEqual($obj->parent_category->cat_id, 1);
}
+
+ function testLazyLoadingGetterSetter_hasMany()
+ {
+ $arr = Table2::finder()->findByPk(2);
+
+ $this->assertNotNull($arr->state2); //lazy load
+ $this->assertEqual(count($arr->state2), 1);
+ $this->assertEqual($arr->state2[0]->id, "1");
+ $this->assertNotNull($arr->state2[0]->object2);
+ $this->assertEqual($arr->state2[0]->object2->id, "2");
+
+ $this->assertNotIdentical($arr, $arr->state2[0]->object2);
+ }
}
?>
\ No newline at end of file |