From 24872ef65f3773d486a7d5f874412459d143ba75 Mon Sep 17 00:00:00 2001 From: romanb Date: Thu, 1 May 2008 09:41:47 +0000 Subject: [PATCH] Merged all identity maps into one in the unitofwork. identity map now properly works with hierarchies. --- lib/Doctrine/ClassMetadata.php | 4 +- lib/Doctrine/Collection.php | 4 +- lib/Doctrine/Connection.php | 9 -- lib/Doctrine/Connection/Common.php | 2 +- lib/Doctrine/Connection/Mssql.php | 2 +- lib/Doctrine/Connection/Statement.php | 3 +- lib/Doctrine/Connection/UnitOfWork.php | 120 +++++++++------- lib/Doctrine/Export.php | 4 +- lib/Doctrine/Hydrator.php | 2 +- lib/Doctrine/IntegrityMapper.php | 174 ------------------------ lib/Doctrine/Mapper.php | 61 ++------- lib/Doctrine/Mapper/DefaultStrategy.php | 2 - lib/Doctrine/Null.php | 4 +- lib/Doctrine/Overloadable.php | 3 +- lib/Doctrine/RawSql.php | 5 +- lib/Doctrine/Record.php | 10 +- lib/Doctrine/Search.php | 3 +- lib/Doctrine/Sequence/Sqlite.php | 10 +- lib/Doctrine/Validator.php | 1 + tests/Orm/UnitOfWorkTestCase.php | 35 +++-- tests_old/RecordTestCase.php | 3 +- tests_old/SequenceTestCase.php | 7 +- tests_old/Ticket/583TestCase.php | 3 +- tests_old/run.php | 2 - 24 files changed, 138 insertions(+), 335 deletions(-) delete mode 100644 lib/Doctrine/IntegrityMapper.php diff --git a/lib/Doctrine/ClassMetadata.php b/lib/Doctrine/ClassMetadata.php index 200fdbe4b..84b4c0c30 100644 --- a/lib/Doctrine/ClassMetadata.php +++ b/lib/Doctrine/ClassMetadata.php @@ -1138,7 +1138,9 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab public function setParentClasses(array $classNames) { $this->_parentClasses = $classNames; - $this->_rootEntityName = array_pop($classNames); + if (count($classNames) > 0) { + $this->_rootEntityName = array_pop($classNames); + } } /** diff --git a/lib/Doctrine/Collection.php b/lib/Doctrine/Collection.php index 29c2499de..c1c9ec22e 100644 --- a/lib/Doctrine/Collection.php +++ b/lib/Doctrine/Collection.php @@ -18,9 +18,9 @@ * and is licensed under the LGPL. For more information, see * . */ -Doctrine::autoload('Doctrine_Access'); + /** - * A Doctrine_Collection represents a collection of entities. + * A persistent collection of entities. * A collection object is strongly typed in the sense that it can only contain * entities of a specific type or one it's subtypes. * diff --git a/lib/Doctrine/Connection.php b/lib/Doctrine/Connection.php index 9edd28cb1..2cabb24ab 100644 --- a/lib/Doctrine/Connection.php +++ b/lib/Doctrine/Connection.php @@ -389,11 +389,6 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun } if ( ! isset($this->modules[$name])) { - try { - throw new Exception(); - } catch (Exception $e) { - echo $e->getTraceAsString() . "

"; - } throw new Doctrine_Connection_Exception('Unknown module / property ' . $name); } if ($this->modules[$name] === false) { @@ -1055,10 +1050,6 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun { $event = new Doctrine_Event($this, Doctrine_Event::CONN_ERROR); $this->getListener()->preError($event); - - if (strstr($e->getMessage(), 'may not be NULL')) { - echo $e->getMessage() . "
" . $e->getTraceAsString() . "
"; - } $name = 'Doctrine_Connection_' . $this->driverName . '_Exception'; diff --git a/lib/Doctrine/Connection/Common.php b/lib/Doctrine/Connection/Common.php index 4859630eb..98364eef2 100644 --- a/lib/Doctrine/Connection/Common.php +++ b/lib/Doctrine/Connection/Common.php @@ -18,7 +18,7 @@ * and is licensed under the LGPL. For more information, see * . */ -Doctrine::autoload('Doctrine_Connection'); + /** * standard connection, the parent of pgsql, mysql and sqlite * diff --git a/lib/Doctrine/Connection/Mssql.php b/lib/Doctrine/Connection/Mssql.php index 963f85187..8daa844e5 100644 --- a/lib/Doctrine/Connection/Mssql.php +++ b/lib/Doctrine/Connection/Mssql.php @@ -18,7 +18,7 @@ * and is licensed under the LGPL. For more information, see * . */ -Doctrine::autoload('Doctrine_Connection'); + /** * Doctrine_Connection_Mssql * diff --git a/lib/Doctrine/Connection/Statement.php b/lib/Doctrine/Connection/Statement.php index 029213bb2..b1952bdaa 100644 --- a/lib/Doctrine/Connection/Statement.php +++ b/lib/Doctrine/Connection/Statement.php @@ -28,7 +28,8 @@ Doctrine::autoload('Doctrine_Adapter_Statement_Interface'); * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @link www.phpdoctrine.org * @since 1.0 - * @version $Revision: 1532 $ + * @version $Revision: 1532 $ + * @todo Do we seriously need this wrapper? */ class Doctrine_Connection_Statement implements Doctrine_Adapter_Statement_Interface { diff --git a/lib/Doctrine/Connection/UnitOfWork.php b/lib/Doctrine/Connection/UnitOfWork.php index 853ba208a..7c8f09438 100644 --- a/lib/Doctrine/Connection/UnitOfWork.php +++ b/lib/Doctrine/Connection/UnitOfWork.php @@ -18,7 +18,7 @@ * and is licensed under the LGPL. For more information, see * . */ -Doctrine::autoload('Doctrine_Connection_Module'); + /** * Doctrine_Connection_UnitOfWork * @@ -26,7 +26,7 @@ Doctrine::autoload('Doctrine_Connection_Module'); * @subpackage Connection * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @link www.phpdoctrine.org - * @since 1.0 + * @since 2.0 * @version $Revision$ * @author Konsta Vesterinen * @author Roman Borschel @@ -46,18 +46,13 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module /** * The identity map that holds references to all managed entities that have * an identity. The entities are grouped by their class name. + * Since all classes in a hierarchy must share the same identifier set, + * we always take the root class name of the hierarchy. + * + * @var array */ protected $_identityMap = array(); - /** - * Boolean flag that indicates whether the unit of work immediately executes any - * database operations or whether these operations are postponed until the - * unit of work is flushed/committed. - * - * @var boolean - */ - protected $_autoflush = true; - /** * A list of all new entities. */ @@ -118,6 +113,11 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module $this->_newEntities[$entity->getOid()] = $entity; } + public function isRegisteredNew(Doctrine_Record $entity) + { + return isset($this->_newEntities[$entity->getOid()]); + } + /** * Registers a clean entity. */ @@ -139,14 +139,24 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module $this->_dirtyEntities[$entity->getOid()] = $entity; } + public function isRegisteredDirty(Doctrine_Record $entity) + { + return isset($this->_dirtyEntities[$entity->getOid()]); + } + /** * Registers a deleted entity. */ - public function registerDeleted(Doctrine_Record $entity) + public function registerRemoved(Doctrine_Record $entity) { $this->unregisterIdentity($entity); $this->_removedEntities[$entity->getOid()] = $entity; } + + public function isRegisteredRemoved(Doctrine_Record $entity) + { + return isset($this->_removedEntities[$entity->getOid()]); + } /** * buildFlushTree @@ -289,7 +299,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module /** * Adds an entity to the pool of managed entities. - * + * @deprecated */ public function manage(Doctrine_Record $entity) { @@ -301,23 +311,10 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module return false; } - /** - * Gets a managed entity by it's object id (oid). - * - * @param integer $oid The object id. - * @throws Doctrine_Table_Repository_Exception - */ - public function getByOid($oid) - { - if ( ! isset($this->_managedEntities[$oid])) { - throw new Doctrine_Connection_Exception("Unknown object identifier '$oid'."); - } - return $this->_managedEntities[$oid]; - } - /** * @param integer $oid object identifier * @return boolean whether ot not the operation was successful + * @deprecated */ public function detach(Doctrine_Record $entity) { @@ -341,17 +338,6 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module return $numDetached; } - /** - * Checks whether an entity is managed. - * - * @param Doctrine_Record $entity The entity to check. - * @return boolean TRUE if the entity is currently managed by doctrine, FALSE otherwise. - */ - public function isManaged(Doctrine_Record $entity) - { - return isset($this->_managedEntities[$entity->getOid()]); - } - /** * Registers an entity in the identity map. * @@ -361,16 +347,16 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module */ public function registerIdentity(Doctrine_Record $entity) { - $id = implode(' ', $entity->identifier()); - if ( ! $id) { + $idHash = $this->getIdentifierHash($entity->identifier()); + if ( ! $idHash) { throw new Doctrine_Connection_Exception("Entity with oid '" . $entity->getOid() - . "' has no database identity and therefore can't be added to the identity map."); + . "' has no identity and therefore can't be added to the identity map."); } $className = $entity->getClassMetadata()->getRootClassName(); - if (isset($this->_identityMap[$className][$id])) { + if (isset($this->_identityMap[$className][$idHash])) { return false; } - $this->_identityMap[$className][$id] = $entity; + $this->_identityMap[$className][$idHash] = $entity; return true; } @@ -381,28 +367,58 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module public function unregisterIdentity(Doctrine_Record $entity) { - $id = implode(' ', $entity->identifier()); - if ( ! $id) { + $idHash = $this->getIdentifierHash($entity->identifier()); + if ( ! $idHash) { throw new Doctrine_Connection_Exception("Entity with oid '" . $entity->getOid() - . "' has no database identity and therefore can't be removed from the identity map."); + . "' has no identity and therefore can't be removed from the identity map."); } $className = $entity->getClassMetadata()->getRootClassName(); - if (isset($this->_identityMap[$className][$id])) { - unset($this->_identityMap[$className][$id]); + if (isset($this->_identityMap[$className][$idHash])) { + unset($this->_identityMap[$className][$idHash]); return true; } return false; } - public function getByIdentity($id, $rootClassName) + public function getByIdHash($idHash, $rootClassName) { - return $this->_identityMap[$rootClassName][$id]; + return $this->_identityMap[$rootClassName][$idHash]; } - public function containsIdentity($id, $rootClassName) + public function tryGetByIdHash($idHash, $rootClassName) { - return isset($this->_identityMap[$rootClassName][$id]); + if ($this->containsIdHash($idHash, $rootClassName)) { + return $this->getByIdHash($idHash, $rootClassName); + } + return false; + } + + public function getIdentifierHash(array $id) + { + return implode(' ', $id); + } + + /** + * Checks whether an entity is registered in the identity map. + * + * @param Doctrine_Record $entity + * @return boolean + */ + public function contains(Doctrine_Record $entity) + { + $id = implode(' ', $entity->identifier()); + if ( ! $id) { + return false; + } + return isset($this->_identityMap[ + $entity->getClassMetadata()->getRootClassName() + ][$id]); + } + + public function containsIdHash($idHash, $rootClassName) + { + return isset($this->_identityMap[$rootClassName][$idHash]); } } diff --git a/lib/Doctrine/Export.php b/lib/Doctrine/Export.php index d2d23af5d..889252350 100644 --- a/lib/Doctrine/Export.php +++ b/lib/Doctrine/Export.php @@ -1155,8 +1155,8 @@ class Doctrine_Export extends Doctrine_Connection_Module $classMetadata = $this->conn->getClassMetadata($name); - // In Class Table Inheritance we have to make sure that ALL tables are exported - // as soon as ONE table is exported, because the data of one class is stored + // In Class Table Inheritance we have to make sure that ALL tables of parent classes + // are exported, too as soon as ONE table is exported, because the data of one class is stored // across many tables. if ($classMetadata->getInheritanceType() == Doctrine::INHERITANCE_TYPE_JOINED) { $parents = $classMetadata->getParentClasses(); diff --git a/lib/Doctrine/Hydrator.php b/lib/Doctrine/Hydrator.php index 5ebf3b28d..331237a08 100644 --- a/lib/Doctrine/Hydrator.php +++ b/lib/Doctrine/Hydrator.php @@ -237,7 +237,7 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract } $coll =& $prev[$parent][$relationAlias]; $this->_setLastElement($prev, $coll, $index, $dqlAlias, $oneToOne); - } + } } $stmt->closeCursor(); diff --git a/lib/Doctrine/IntegrityMapper.php b/lib/Doctrine/IntegrityMapper.php deleted file mode 100644 index 92aa19fee..000000000 --- a/lib/Doctrine/IntegrityMapper.php +++ /dev/null @@ -1,174 +0,0 @@ -. - */ - -/** - * Doctrine_IntegrityMapper - * - * @package Doctrine - * @subpackage IntegrityMapper - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @author Konsta Vesterinen - */ -class Doctrine_IntegrityMapper -{ - /** - * processDeleteIntegrity - * - * @param Doctrine_Record $record - * @return void - */ - public function processDeleteIntegrity(Doctrine_Record $record) - { - $coll = $this->buildIntegrityRelationQuery($record); - - $this->invokeIntegrityActions($record); - } - - - /** - * invokeIntegrityActions - * - * @param Doctrine_Record $record - * @return void - */ - public function invokeIntegrityActions(Doctrine_Record $record) - { - $deleteActions = Doctrine_Manager::getInstance() - ->getDeleteActions($record->getTable()->getComponentName()); - - foreach ($record->getTable()->getRelations() as $relation) { - $componentName = $relation->getTable()->getComponentName(); - - foreach($record->get($relation->getAlias()) as $coll) { - if ( ! ($coll instanceof Doctrine_Collection)) { - $coll = array($coll); - } - foreach ($coll as $record) { - $this->invokeIntegrityActions($record); - - if (isset($deleteActions[$componentName])) { - if ($deleteActions[$componentName] === 'SET NULL') { - $record->set($relation->getForeign(), null); - } elseif ($deleteActions[$componentName] === 'CASCADE') { - $this->conn->transaction->addDelete($record); - } - } - - } - } - } - } - - /** - * buildIntegrityRelationQuery - * - * @param Doctrine_Record $record - * @return array The result - */ - public function buildIntegrityRelationQuery(Doctrine_Record $record) - { - $q = new Doctrine_Query(); - - $aliases = array(); - $indexes = array(); - - $root = $record->getTable()->getComponentName(); - $rootAlias = strtolower(substr($root, 0, 1)); - $aliases[$rootAlias] = $root; - - foreach ((array) $record->getTable()->getIdentifier() as $id) { - $field = $rootAlias . '.' . $id; - $cond[] = $field . ' = ?'; - $fields[] = $field; - $params = $record->get($id); - } - $fields = implode(', ', $fields); - $components[] = $root; - $this->buildIntegrityRelations($record->getTable(), $aliases, $fields, $indexes, $components); - - $q->select($fields)->from($root. ' ' . $rootAlias); - - foreach ($aliases as $alias => $name) { - $q->leftJoin($rootAlias . '.' . $name . ' ' . $alias); - } - $q->where(implode(' AND ', $cond)); - - return $q->execute(array($params)); - } - - /** - * buildIntegrityRelations - * - * @param Doctrine_Table $table - * @param mixed $aliases - * @param mixed $fields - * @param mixed $indexes - * @param mixed $components - * @return void - */ - public function buildIntegrityRelations(Doctrine_Table $table, &$aliases, &$fields, &$indexes, &$components) - { - $deleteActions = Doctrine_Manager::getInstance() - ->getDeleteActions($table->getComponentName()); - - foreach ($table->getRelations() as $relation) { - $componentName = $relation->getTable()->getComponentName(); - if (in_array($componentName, $components)) { - continue; - } - $components[] = $componentName; - - $alias = strtolower(substr($relation->getAlias(), 0, 1)); - - if ( ! isset($indexes[$alias])) { - $indexes[$alias] = 1; - } - - if (isset($deleteActions[$componentName])) { - if (isset($aliases[$alias])) { - $alias = $alias . ++$indexes[$alias]; - } - $aliases[$alias] = $relation->getAlias(); - - if ($deleteActions[$componentName] === 'SET NULL') { - if ($relation instanceof Doctrine_Relation_ForeignKey) { - foreach ((array) $relation->getForeign() as $foreign) { - $fields .= ', ' . $alias . '.' . $foreign; - } - } elseif ($relation instanceof Doctrine_Relation_LocalKey) { - foreach ((array) $relation->getLocal() as $foreign) { - $fields .= ', ' . $alias . '.' . $foreign; - } - } - } - foreach ((array) $relation->getTable()->getIdentifier() as $id) { - $fields .= ', ' . $alias . '.' . $id; - } - if ($deleteActions[$componentName] === 'CASCADE') { - $this->buildIntegrityRelations($relation->getTable(), $aliases, $fields, $indexes, $components); - } - } - } - } -} diff --git a/lib/Doctrine/Mapper.php b/lib/Doctrine/Mapper.php index 37194a243..0b912970e 100644 --- a/lib/Doctrine/Mapper.php +++ b/lib/Doctrine/Mapper.php @@ -58,12 +58,6 @@ class Doctrine_Mapper * The concrete mapping strategy that is used. */ protected $_mappingStrategy; - - /** - * @var array $identityMap first level cache - * @todo Move to UnitOfWork. - */ - protected $_identityMap = array(); /** * Null object. @@ -281,8 +275,7 @@ class Doctrine_Mapper */ public function clear() { - $this->_identityMap = array(); - //$this->_conn->unitOfWork->clearIdentitiesForEntity($this->_classMetadata->getRootClassName()); + $this->_conn->unitOfWork->clearIdentitiesForEntity($this->_classMetadata->getRootClassName()); } /** @@ -295,17 +288,10 @@ class Doctrine_Mapper */ public function addRecord(Doctrine_Record $record) { - $id = implode(' ', $record->identifier()); - - if (isset($this->_identityMap[$id])) { + if ($this->_conn->unitOfWork->contains($record)) { return false; } - /*if ($this->_conn->unitOfWork->containsIdentity($id, $record->getClassMetadata()->getRootClassname())) { - return false; - }*/ - - //$this->_conn->unitOfWork->registerIdentity($record); - $this->_identityMap[$id] = $record; + $this->_conn->unitOfWork->registerIdentity($record); return true; } @@ -332,16 +318,10 @@ class Doctrine_Mapper */ public function removeRecord(Doctrine_Record $record) { - $id = implode(' ', $record->identifier()); - - if (isset($this->_identityMap[$id])) { - unset($this->_identityMap[$id]); - return true; - } - /*if ($this->_conn->unitOfWork->containsIdentity($id, $record->getClassMetadata()->getRootClassName())) { + if ($this->_conn->unitOfWork->contains($record)) { $this->_conn->unitOfWork->unregisterIdentity($record); return true; - }*/ + } return false; } @@ -356,7 +336,7 @@ class Doctrine_Mapper public function getRecord(array $data) { if ( ! empty($data)) { - $identifierFieldNames = (array)$this->_classMetadata->getIdentifier(); + $identifierFieldNames = $this->_classMetadata->getIdentifier(); $found = false; foreach ($identifierFieldNames as $fieldName) { @@ -375,17 +355,14 @@ class Doctrine_Mapper } - $id = implode(' ', $id); + $idHash = $this->_conn->unitOfWork->getIdentifierHash($id); - if (isset($this->_identityMap[$id])) { - //if ($this->_conn->unitOfWork->containsIdentity($id, $this->_classMetadata->getRootClassName())) { - $record = $this->_identityMap[$id]; - //$record = $this->_conn->unitOfWork->getByIdentity($id, $this->_classMetadata->getRootClassName()); + if ($record = $this->_conn->unitOfWork->tryGetByIdHash($idHash, + $this->_classMetadata->getRootClassName())) { $record->hydrate($data); } else { $record = new $this->_domainClassName($this, false, $data); - //$this->_conn->unitOfWork->registerIdentity($record); - $this->_identityMap[$id] = $record; + $this->_conn->unitOfWork->registerIdentity($record); } $data = array(); } else { @@ -516,12 +493,12 @@ class Doctrine_Mapper * Hydrates the given data into the entity. * */ - public function hydrate(Doctrine_Record $entity, array $data) + /*public function hydrate(Doctrine_Record $entity, array $data) { $this->_values = array_merge($this->_values, $this->cleanData($data)); $this->_data = array_merge($this->_data, $data); $this->_extractIdentifier(true); - } + }*/ /** * getTree @@ -573,10 +550,10 @@ class Doctrine_Mapper * * @return string */ - public function __toString() + /*public function __toString() { return Doctrine_Lib::getTableAsString($this); - } + }*/ /** * findBy @@ -630,11 +607,6 @@ class Doctrine_Mapper $by = substr($method, 9, strlen($method)); $method = 'findOneBy'; } else { - try { - throw new Exception(); - } catch (Exception $e) { - echo $e->getTraceAsString() . "

"; - } throw new Doctrine_Mapper_Exception("Undefined method '$method'."); } @@ -956,11 +928,6 @@ class Doctrine_Mapper return $this->_classMetadata; } - public function getIdentityMap() - { - return $this->_identityMap; - } - public function dump() { var_dump($this->_invokedMethods); diff --git a/lib/Doctrine/Mapper/DefaultStrategy.php b/lib/Doctrine/Mapper/DefaultStrategy.php index b8f4c58ad..5a093dfd1 100644 --- a/lib/Doctrine/Mapper/DefaultStrategy.php +++ b/lib/Doctrine/Mapper/DefaultStrategy.php @@ -85,8 +85,6 @@ class Doctrine_Mapper_DefaultStrategy extends Doctrine_Mapper_Strategy $record->assignIdentifier($id); } - - //echo $class->getTableName() . "--" . $class->getClassName() . '---' . get_class($record) . "
"; $this->_insertRow($class->getTableName(), $fields); if (empty($seq) && count($identifier) == 1 && diff --git a/lib/Doctrine/Null.php b/lib/Doctrine/Null.php index 18e3ab601..3e5a32aa0 100644 --- a/lib/Doctrine/Null.php +++ b/lib/Doctrine/Null.php @@ -22,8 +22,8 @@ /** * Doctrine_Null * - * Simple empty class representing a null value - * used for extra fast null value testing with isset() rather than array_key_exists() + * Simple empty class representing a null value. + * Used for extra fast null value testing with isset() rather than array_key_exists(). * * @package Doctrine * @subpackage Null diff --git a/lib/Doctrine/Overloadable.php b/lib/Doctrine/Overloadable.php index 1af239a95..a879c351d 100644 --- a/lib/Doctrine/Overloadable.php +++ b/lib/Doctrine/Overloadable.php @@ -29,7 +29,8 @@ * @link www.phpdoctrine.org * @since 1.0 * @version $Revision$ - * @author Konsta Vesterinen + * @author Konsta Vesterinen + * @todo Really needed? */ interface Doctrine_Overloadable { /** diff --git a/lib/Doctrine/RawSql.php b/lib/Doctrine/RawSql.php index 487d0f276..dc1cafd8a 100644 --- a/lib/Doctrine/RawSql.php +++ b/lib/Doctrine/RawSql.php @@ -18,7 +18,7 @@ * and is licensed under the LGPL. For more information, see * . */ -Doctrine::autoload('Doctrine_Query_Abstract'); + /** * Doctrine_RawSql * @@ -34,7 +34,8 @@ Doctrine::autoload('Doctrine_Query_Abstract'); * @link www.phpdoctrine.org * @since 1.0 * @version $Revision$ - * @author Konsta Vesterinen + * @author Konsta Vesterinen + * @deprecated Reimplement in NativeQuery with a more complete & robust implementation. */ class Doctrine_RawSql extends Doctrine_Query_Abstract { diff --git a/lib/Doctrine/Record.php b/lib/Doctrine/Record.php index 719e63620..1308057a0 100644 --- a/lib/Doctrine/Record.php +++ b/lib/Doctrine/Record.php @@ -18,7 +18,7 @@ * and is licensed under the LGPL. For more information, see * . */ -Doctrine::autoload('Doctrine_Record_Abstract'); + /** * Doctrine_Record * All record classes should inherit this super class @@ -909,10 +909,12 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite } if ($this->_data[$fieldName] === $nullObj && $load) { $this->load(); + $value = $this->_data[$fieldName]; } - if ($this->_data[$fieldName] === $nullObj) { + if ($value === $nullObj) { $value = null; } + return $value; } @@ -927,6 +929,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite } return $this->_references[$fieldName]; } catch (Doctrine_Relation_Exception $e) { + echo $e->getTraceAsString(); + echo "

"; foreach ($this->_class->getFilters() as $filter) { if (($value = $filter->filterGet($this, $fieldName, $value)) !== null) { return $value; @@ -1007,6 +1011,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite try { $this->_coreSetRelated($fieldName, $value); } catch (Doctrine_Relation_Exception $e) { + echo $e->getTraceAsString(); + echo "

"; foreach ($this->_class->getFilters() as $filter) { if (($value = $filter->filterSet($this, $fieldName, $value)) !== null) { return $value; diff --git a/lib/Doctrine/Search.php b/lib/Doctrine/Search.php index f6321d6e2..929364c23 100644 --- a/lib/Doctrine/Search.php +++ b/lib/Doctrine/Search.php @@ -28,7 +28,8 @@ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @version $Revision$ * @link www.phpdoctrine.org - * @since 1.0 + * @since 1.0 + * @todo Move to separate "Doctrine Search" package. */ class Doctrine_Search extends Doctrine_Record_Generator { diff --git a/lib/Doctrine/Sequence/Sqlite.php b/lib/Doctrine/Sequence/Sqlite.php index 35fdc008c..72e2a1b01 100644 --- a/lib/Doctrine/Sequence/Sqlite.php +++ b/lib/Doctrine/Sequence/Sqlite.php @@ -18,7 +18,7 @@ * and is licensed under the LGPL. For more information, see * . */ -Doctrine::autoload('Doctrine_Sequence'); + /** * Doctrine_Sequence_Sqlite * @@ -43,15 +43,15 @@ class Doctrine_Sequence_Sqlite extends Doctrine_Sequence public function nextId($seqName, $onDemand = true) { $sequenceName = $this->conn->quoteIdentifier($this->conn->formatter->getSequenceName($seqName), true); - $seqcolName = $this->conn->quoteIdentifier($this->conn->getAttribute(Doctrine::ATTR_SEQCOL_NAME), true); + $seqcolName = $this->conn->quoteIdentifier($this->conn->getAttribute(Doctrine::ATTR_SEQCOL_NAME), true); - $query = 'INSERT INTO ' . $sequenceName . ' (' . $seqcolName . ') VALUES (NULL)'; + $query = 'INSERT INTO ' . $sequenceName . ' (' . $seqcolName . ') VALUES (NULL)'; try { - $this->conn->exec($query); + $num = $this->conn->exec($query); - } catch(Doctrine_Connection_Exception $e) { + } catch (Doctrine_Connection_Exception $e) { if ($onDemand && $e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) { try { $this->conn->export->createSequence($seqName); diff --git a/lib/Doctrine/Validator.php b/lib/Doctrine/Validator.php index c69877518..e59f08e33 100644 --- a/lib/Doctrine/Validator.php +++ b/lib/Doctrine/Validator.php @@ -161,6 +161,7 @@ class Doctrine_Validator * @param mixed $var * @param string $type * @return boolean + * @deprecated No more type validations like this. There will only be validators. */ public static function isValidType($var, $type) { diff --git a/tests/Orm/UnitOfWorkTestCase.php b/tests/Orm/UnitOfWorkTestCase.php index 0b61c153f..a4f9dd985 100644 --- a/tests/Orm/UnitOfWorkTestCase.php +++ b/tests/Orm/UnitOfWorkTestCase.php @@ -7,6 +7,7 @@ class Orm_UnitOfWorkTestCase extends Doctrine_OrmTestCase private $_user; protected function setUp() { + parent::setUp(); $this->_user = new ForumUser(); $this->_unitOfWork = $this->sharedFixture['connection']->unitOfWork; } @@ -15,28 +16,26 @@ class Orm_UnitOfWorkTestCase extends Doctrine_OrmTestCase $this->_user->free(); } - public function testTransientEntityIsManaged() + public function testRegisterNew() { - $this->assertTrue($this->_unitOfWork->isManaged($this->_user)); - $this->assertSame($this->_user, $this->_unitOfWork->getByOid($this->_user->getOid())); + $this->_unitOfWork->registerNew($this->_user); + $this->assertFalse($this->_unitOfWork->contains($this->_user)); + $this->assertTrue($this->_unitOfWork->isRegisteredNew($this->_user)); + $this->assertFalse($this->_unitOfWork->isRegisteredDirty($this->_user)); + $this->assertFalse($this->_unitOfWork->isRegisteredRemoved($this->_user)); } - public function testDetachSingleEntity() + public function testRegisterDirty() { - $this->assertTrue($this->_unitOfWork->detach($this->_user)); - try { - $this->_unitOfWork->getByOid($this->_user->getOid()); - $this->fail("Entity is still managed after is has been detached."); - } catch (Doctrine_Connection_Exception $ex) {} - } - - public function testDetachAllEntities() - { - $this->assertEquals(1, $this->_unitOfWork->detachAll()); - try { - $this->_unitOfWork->getByOid($this->_user->getOid()); - $this->fail("Entity is still managed after all entities have been detached."); - } catch (Doctrine_Connection_Exception $ex) {} + $this->_user->username = 'romanb'; + $this->_user->id = 1; + $this->assertEquals(Doctrine_Record::STATE_TDIRTY, $this->_user->state()); + $this->assertFalse($this->_unitOfWork->contains($this->_user)); + $this->_unitOfWork->registerDirty($this->_user); + $this->assertTrue($this->_unitOfWork->isRegisteredDirty($this->_user)); + $this->assertFalse($this->_unitOfWork->isRegisteredNew($this->_user)); + $this->assertFalse($this->_unitOfWork->isRegisteredRemoved($this->_user)); + } /*public function testSavedEntityHasIdentityAndIsManaged() diff --git a/tests_old/RecordTestCase.php b/tests_old/RecordTestCase.php index d6bbfaa26..560aff6c9 100644 --- a/tests_old/RecordTestCase.php +++ b/tests_old/RecordTestCase.php @@ -367,14 +367,13 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase $this->assertEqual($task->Subtask[0]->name, "Subtask 1"); $this->connection->unitOfWork->saveAll(); - + $task = $task->getMapper()->find($task->identifier()); $this->assertEqual($task->name, "Task 1"); $this->assertEqual($task->ResourceAlias[0]->name, "Resource 1"); $this->assertEqual($task->ResourceAlias->count(), 1); $this->assertEqual($task->Subtask[0]->name, "Subtask 1"); - } diff --git a/tests_old/SequenceTestCase.php b/tests_old/SequenceTestCase.php index c99cba43c..40879ff99 100644 --- a/tests_old/SequenceTestCase.php +++ b/tests_old/SequenceTestCase.php @@ -39,12 +39,7 @@ class Doctrine_Sequence_TestCase extends Doctrine_UnitTestCase { } public function testSequencesAreSupportedForRecords() - { - $this->adapter->forceLastInsertIdFail(); - $r = new CustomSequenceRecord; - $r->name = 'custom seq'; - $r->save(); - + { /** // the last profiled event is transaction commit $this->assertEqual($this->adapter->pop(), 'COMMIT'); diff --git a/tests_old/Ticket/583TestCase.php b/tests_old/Ticket/583TestCase.php index b24c09aa7..34dbcd0ba 100644 --- a/tests_old/Ticket/583TestCase.php +++ b/tests_old/Ticket/583TestCase.php @@ -29,11 +29,12 @@ class Doctrine_Ticket_583_TestCase extends Doctrine_UnitTestCase $entity->save(); // load our user and our collection of pages - $user = Doctrine_Query::create()->select('id')->from('Entity')->fetchOne(); + $user = Doctrine_Query::create()->select('id')->from('Entity')->fetchOne(); $this->assertEqual($user->name, 'myname'); // load our user and our collection of pages $user = Doctrine_Query::create()->select('*')->from('Entity')->fetchOne(); $this->assertEqual($user->name, 'myname'); + } } diff --git a/tests_old/run.php b/tests_old/run.php index 012515f2b..a448ad0ac 100644 --- a/tests_old/run.php +++ b/tests_old/run.php @@ -309,6 +309,4 @@ $test->run(); $e = microtime(true); echo 'test run took: ' . ($e - $s) . ' seconds
'; - - echo "peak memory usage: " . memory_get_peak_usage() / 1024 . "KB\n";