From 613d08f9caae2419efe3252298f06438b946a746 Mon Sep 17 00:00:00 2001 From: romanb Date: Sat, 17 May 2008 12:22:24 +0000 Subject: [PATCH] Merged dbal bugfixes from 0.11. --- lib/Doctrine/ClassMetadata.php | 51 +- lib/Doctrine/ClassMetadata/Factory.php | 4 +- lib/Doctrine/Collection.php | 19 +- lib/Doctrine/Connection.php | 534 ++------------------- lib/Doctrine/Connection/Db2.php | 4 +- lib/Doctrine/Connection/Mock.php | 2 +- lib/Doctrine/Connection/Oracle.php | 90 ++-- lib/Doctrine/Connection/UnitOfWork.php | 71 ++- lib/Doctrine/Entity.php | 132 ++--- lib/Doctrine/Entity/Exception.php | 5 + lib/Doctrine/EntityRepository.php | 10 +- lib/Doctrine/Hydrator/Abstract.php | 2 +- lib/Doctrine/Hydrator/RecordDriver.php | 4 +- lib/Doctrine/HydratorNew.php | 4 + lib/Doctrine/Manager.php | 2 +- lib/Doctrine/Mapper.php | 91 +--- lib/Doctrine/Query.php | 15 +- lib/Doctrine/Query/Abstract.php | 6 +- lib/Doctrine/Relation.php | 7 +- lib/Doctrine/Relation/Parser.php | 4 +- tests/Orm/Component/AccessTest.php | 14 +- tests/Orm/Component/AllTests.php | 2 - tests/Orm/Component/CollectionTest.php | 2 + tests/Orm/Component/TestTest.php | 38 -- tests/Orm/EntityManagerTest.php | 49 ++ tests/Orm/Hydration/BasicHydrationTest.php | 90 ++-- tests/Orm/UnitOfWorkTestCase.php | 3 +- tests/lib/DoctrineTestInit.php | 2 + tests/lib/Doctrine_OrmTestCase.php | 113 ----- tests/lib/Doctrine_OrmTestSuite.php | 8 +- tests/models/cms/CmsUser.php | 1 + 31 files changed, 402 insertions(+), 977 deletions(-) delete mode 100644 tests/Orm/Component/TestTest.php create mode 100644 tests/Orm/EntityManagerTest.php diff --git a/lib/Doctrine/ClassMetadata.php b/lib/Doctrine/ClassMetadata.php index 7eda783f9..ef1d28e1c 100644 --- a/lib/Doctrine/ClassMetadata.php +++ b/lib/Doctrine/ClassMetadata.php @@ -272,14 +272,12 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab * * @param string $entityName Name of the entity class the metadata info is used for. */ - public function __construct($entityName, Doctrine_Connection $conn) + public function __construct($entityName, Doctrine_EntityManager $em) { $this->_entityName = $entityName; $this->_rootEntityName = $entityName; - $this->_conn = $conn; + $this->_conn = $em; $this->_parser = new Doctrine_Relation_Parser($this); - $this->_filters[] = new Doctrine_Record_Filter_Standard(); - $this->setConfigurableParent($this->_conn); } /** @@ -289,6 +287,11 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab { return $this->_conn; } + + public function getEntityManager() + { + return $this->_conn; + } /** * getComponentName @@ -598,7 +601,13 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab $this->_columnCount++; } - + + /** + * Gets the default length for a field type. + * + * @param unknown_type $type + * @return unknown + */ private function _getDefaultLength($type) { switch ($type) { @@ -625,6 +634,16 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab return 25; } } + + /** + * Maps an embedded value object. + * + * @todo Implementation. + */ + public function mapEmbeddedValue() + { + //... + } /** * setColumn @@ -956,11 +975,16 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab return $this->getColumnDefinition($columnName); } - + + /** + * Gets the mapping information for a field. + * + * @param string $fieldName + * @return array + */ public function getMappingForField($fieldName) { $columnName = $this->getColumnName($fieldName); - return $this->getColumnDefinition($columnName); } @@ -974,7 +998,13 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab { return $this->getTypeOfColumn($this->getColumnName($fieldName)); } - + + /** + * Gets the type of a field. + * + * @param string $fieldName + * @return string + */ public function getTypeOfField($fieldName) { return $this->getTypeOfColumn($this->getColumnName($fieldName)); @@ -1022,7 +1052,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab */ public function addNamedQuery($name, $query) { - + //... } public function bindRelation($args, $type) @@ -1622,7 +1652,8 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab */ public function setTableName($tableName) { - $this->setTableOption('tableName', $this->_conn->formatter->getTableName($tableName)); + $this->setTableOption('tableName', $this->_conn->getConnection() + ->formatter->getTableName($tableName)); } /** diff --git a/lib/Doctrine/ClassMetadata/Factory.php b/lib/Doctrine/ClassMetadata/Factory.php index 7c16f9105..c26576d89 100644 --- a/lib/Doctrine/ClassMetadata/Factory.php +++ b/lib/Doctrine/ClassMetadata/Factory.php @@ -44,9 +44,9 @@ class Doctrine_ClassMetadata_Factory * @param $conn The connection to use. * @param $driver The metadata driver to use. */ - public function __construct(Doctrine_Connection $conn, $driver) + public function __construct(Doctrine_EntityManager $em, $driver) { - $this->_conn = $conn; + $this->_conn = $em; $this->_driver = $driver; } diff --git a/lib/Doctrine/Collection.php b/lib/Doctrine/Collection.php index 179327330..37a1e4e3a 100644 --- a/lib/Doctrine/Collection.php +++ b/lib/Doctrine/Collection.php @@ -31,9 +31,12 @@ * @since 1.0 * @version $Revision$ * @author Konsta Vesterinen + * @todo Rename to EntityCollection */ class Doctrine_Collection extends Doctrine_Access implements Countable, IteratorAggregate, Serializable { + protected $_entityBaseType; + /** * An array containing the records of this collection. * @@ -101,10 +104,11 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator * @param string $keyColumn The field name that will be used as the key * in the collection. */ - public function __construct($mapper, $keyField = null) + public function __construct($entityBaseType, $keyField = null) { - if (is_string($mapper)) { - $mapper = Doctrine_Manager::getInstance()->getMapper($mapper); + if (is_string($entityBaseType)) { + $this->_entityBaseType = $entityBaseType; + $mapper = Doctrine_EntityManager::getManager($entityBaseType)->getEntityPersister($entityBaseType); } $this->_mapper = $mapper; @@ -204,16 +208,16 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator */ public function unserialize($serialized) { - $manager = Doctrine_Manager::getInstance(); - $connection = $manager->getCurrentConnection(); - + $manager = Doctrine_EntityManager::getManager(); + $connection = $manager->getConnection(); + $array = unserialize($serialized); foreach ($array as $name => $values) { $this->$name = $values; } - $this->_mapper = $connection->getMapper($this->_mapper); + $this->_mapper = $manager->getEntityPersister($this->_entityBaseType); $keyColumn = isset($array['keyField']) ? $array['keyField'] : null; if ($keyColumn === null) { @@ -506,6 +510,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator */ public function add($record, $key = null) { + /** @TODO Use raw getters/setters */ if ( ! $record instanceof Doctrine_Entity) { throw new Doctrine_Record_Exception('Value variable in set is not an instance of Doctrine_Entity.'); } diff --git a/lib/Doctrine/Connection.php b/lib/Doctrine/Connection.php index 8410c5048..8be3422b5 100644 --- a/lib/Doctrine/Connection.php +++ b/lib/Doctrine/Connection.php @@ -58,11 +58,8 @@ * it sits one layer below. * Right now, this is the unification of these two classes. */ -abstract class Doctrine_Connection extends Doctrine_Configurable implements Countable, IteratorAggregate +abstract class Doctrine_Connection extends Doctrine_Configurable implements Countable { - /* - * ----------- Connection attributes --------------- - */ /** * The PDO database handle. * @@ -102,7 +99,9 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun protected $supported = array(); /** - * @var array $properties an array of connection properties + * The connection properties. + * + * @var array $properties */ protected $properties = array( 'sql_comments' => array(array('start' => '--', 'end' => "\n", 'escape' => false), @@ -139,40 +138,6 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun * @var integer */ protected $_count = 0; - - - /* - * ----------- EntityManager attributes --------------- - */ - /** - * Enter description here... - * - * @var array - */ - private static $_ems = array(); - - /** - * The metadata factory is used to retrieve the metadata of entity classes. - * - * @var Doctrine_ClassMetadata_Factory - * @todo package:orm - */ - protected $_metadataFactory; - - /** - * An array of mapper objects currently maintained by this connection. - * - * @var array - * @todo package:orm - */ - protected $_mappers = array(); - - /** - * The EntityRepository instances. - * - * @var array - */ - private $_repositories = array(); /* @@ -232,7 +197,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun * @param PDO|Doctrine_Adapter_Interface $adapter database driver * @todo Remove the dependency on the Manager for DBAL/ORM separation. */ - public function __construct(Doctrine_Manager $manager, $adapter, $user = null, $pass = null) + public function __construct($adapter, $user = null, $pass = null) { if (is_object($adapter)) { if ( ! ($adapter instanceof PDO) && ! in_array('Doctrine_Adapter_Interface', class_implements($adapter))) { @@ -254,11 +219,8 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun } - $this->setConfigurableParent($manager); - $this->setAttribute(Doctrine::ATTR_CASE, Doctrine::CASE_NATURAL); $this->setAttribute(Doctrine::ATTR_ERRMODE, Doctrine::ERRMODE_EXCEPTION); - $this->getAttribute(Doctrine::ATTR_LISTENER)->onOpen($this); } @@ -898,6 +860,28 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun $this->rethrowException($e, $this); } + + /** + * + * + * @return string + */ + public function modifyLimitQuery($query, $query, $limit = false, $offset = false, $isManip = false) + { + return $query; + } + + /** + * Creates dbms specific LIMIT/OFFSET SQL for the subqueries that are used in the + * context of the limit-subquery algorithm. + * + * @return string + */ + public function modifyLimitSubquery(Doctrine_Table $rootTable, $query, $limit = false, + $offset = false, $isManip = false) + { + return $this->modifyLimitQuery($query, $limit, $offset, $isManip); + } /** * rethrowException @@ -1141,460 +1125,6 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun * ----------- EntityManager methods --------------- */ - /** - * Gets the EntityManager that is responsible for the Entity. - * - * @param string $entityName - * @return EntityManager - */ - public static function getManagerForEntity($entityName) - { - // ... - } - - /** - * query - * queries the database using Doctrine Query Language - * returns a collection of Doctrine_Entity objects - * - * - * $users = $conn->query('SELECT u.* FROM User u'); - * - * $users = $conn->query('SELECT u.* FROM User u WHERE u.name LIKE ?', array('someone')); - * - * - * @param string $query DQL query - * @param array $params query parameters - * @param int $hydrationMode Doctrine::FETCH_ARRAY or Doctrine::FETCH_RECORD - * @see Doctrine_Query - * @return Doctrine_Collection Collection of Doctrine_Entity objects - * @todo package:orm - */ - public function query($query, array $params = array(), $hydrationMode = null) - { - $parser = new Doctrine_Query($this); - - return $parser->query($query, $params, $hydrationMode); - } - - /** - * query - * queries the database using Doctrine Query Language and returns - * the first record found - * - * - * $user = $conn->queryOne('SELECT u.* FROM User u WHERE u.id = ?', array(1)); - * - * $user = $conn->queryOne('SELECT u.* FROM User u WHERE u.name LIKE ? AND u.password = ?', - * array('someone', 'password') - * ); - * - * - * @param string $query DQL query - * @param array $params query parameters - * @see Doctrine_Query - * @return Doctrine_Entity|false Doctrine_Entity object on success, - * boolean false on failure - */ - public function queryOne($query, array $params = array()) - { - $parser = new Doctrine_Query($this); - - $coll = $parser->query($query, $params); - if ( ! $coll->contains(0)) { - return false; - } - return $coll[0]; - } - - /** - * hasTable - * whether or not this connection has table $name initialized - * - * @param mixed $name - * @return boolean - * @deprecated - * @todo package:orm - */ - public function hasTable($name) - { - return isset($this->tables[$name]); - } - - /** - * Returns the metadata for a class. - * - * @return Doctrine_Metadata - * @deprecated Use getClassMetadata() - * @todo package:orm - */ - public function getMetadata($className) - { - return $this->getClassMetadata($className); - } - - /** - * Returns the metadata for a class. - * - * @return Doctrine_Metadata - * @todo package:orm - */ - public function getClassMetadata($className) - { - if ( ! $this->_metadataFactory) { - $this->_metadataFactory = new Doctrine_ClassMetadata_Factory($this, - new Doctrine_ClassMetadata_CodeDriver()); - } - - return $this->_metadataFactory->getMetadataFor($className); - } - - /** - * Sets the driver that is used to obtain metadata informations about entity - * classes. - * - * @param $driver The driver to use. - * @todo package:orm - */ - public function setClassMetadataDriver($driver) - { - $this->_metadataFactory->setDriver($driver); - } - - /** - * Gets a mapper for the specified domain class that is used to map instances of - * the class between the relational database and their object representation. - * - * @param string $entityClassName The name of the entity class. - * @return Doctrine_Mapper The mapper object. - * @todo package:orm - */ - public function getMapper($entityName) - { - if (isset($this->_mappers[$entityName])) { - return $this->_mappers[$entityName]; - } - - $metadata = $this->getClassMetadata($entityName); - $customMapperClassName = $metadata->getCustomMapperClass(); - if ($customMapperClassName !== null) { - $mapper = new $customMapperClassName($entityName, $metadata); - } else { - $mapper = new Doctrine_Mapper($entityName, $metadata); - } - $this->_mappers[$entityName] = $mapper; - - return $mapper; - } - - /** - * Gets all mappers that are currently maintained by the connection. - * - * @todo package:orm - */ - public function getMappers() - { - return $this->_mappers; - } - - /** - * returns an iterator that iterates through all - * initialized table objects - * - * - * foreach ($conn as $index => $table) { - * print $table; // get a string representation of each table object - * } - * - * - * @return ArrayIterator SPL ArrayIterator object - */ - public function getIterator() - { - return new ArrayIterator($this->_mappers); - } - - /** - * create - * creates a record - * - * create creates a record - * @param string $name component name - * @return Doctrine_Entity Doctrine_Entity object - * @todo Any strong reasons why this should not be removed? - * @todo package:orm - */ - public function create($name) - { - return $this->getMapper($name)->create(); - } - - /** - * Creates a new Doctrine_Query object that operates on this connection. - * - * @return Doctrine_Query - * @todo package:orm - */ - public function createQuery($dql = "") - { - $query = new Doctrine_Query($this); - if ( ! empty($dql)) { - $query->parseQuery($dql); - } - - return $query; - } - - /** - * flush - * saves all the records from all tables - * this operation is isolated using a transaction - * - * @throws PDOException if something went wrong at database level - * @return void - * @todo package:orm - */ - public function flush() - { - $this->beginInternalTransaction(); - $this->unitOfWork->flush(); - $this->commit(); - } - - /** - * clear - * clears all repositories - * - * @return void - * @todo package:orm - */ - public function clear($entityName = null) - { - if ($entityName === null) { - $this->unitOfWork->detachAll(); - foreach ($this->_mappers as $mapper) { - $mapper->clear(); // clear identity map of each mapper - } - } else { - $this->getMapper($entityName)->clear(); - } - } - - /** - * evictTables - * evicts all tables - * - * @return void - * @todo package:orm - * @deprecated - */ - public function evictTables() - { - $this->clear(); - $this->tables = array(); - $this->_mappers = array(); - $this->exported = array(); - } - - public function save(Doctrine_Entity $entity, $conn = null) - { - $this->getMapper($entity->getClassName())->save($entity, $conn); - } - - public function remove(Doctrine_Entity $entity, $conn = null) - { - $this->getMapper($entity->getClassName())->delete($entity, $conn); - } - - public function createEntity($entityName, array $data = array()) - { - return $this->getMapper($entityName)->create($data); - } - - public function detach(Doctrine_Entity $entity) - { - $this->getMapper($entity->getClassName())->detach($entity); - } - - public function removeRecord(Doctrine_Entity $entity) - { - $this->getMapper($entity->getClassName())->removeRecord($entity); - } - - public function manage(Doctrine_Entity $entity) - { - $this->getMapper($entity->getClassName())->manage($entity); - } - - public function executeNamedQuery($name, $params = array(), $hydrationMode = Doctrine::HYDRATE_RECORD) - { - return Doctrine_Manager::getInstance() - ->createNamedQuery($name) - ->execute($params, $hydrationMode); - } - - - - /** - * Returns the current internal transaction nesting level. - * - * @return integer The nesting level. A value of 0 means theres no active transaction. - * @todo package:orm??? - */ - public function getInternalTransactionLevel() - { - return $this->transaction->getInternalTransactionLevel(); - } - - /** - * getCacheDriver - * - * @return Doctrine_Cache_Interface - * @deprecated Use getResultCacheDriver() - */ - public function getCacheDriver() - { - return $this->getResultCacheDriver(); - } - - /** - * getResultCacheDriver - * - * @return Doctrine_Cache_Interface - * @todo package:orm - */ - public function getResultCacheDriver() - { - if ( ! $this->getAttribute(Doctrine::ATTR_RESULT_CACHE)) { - throw new Doctrine_Exception('Result Cache driver not initialized.'); - } - - return $this->getAttribute(Doctrine::ATTR_RESULT_CACHE); - } - - /** - * getQueryCacheDriver - * - * @return Doctrine_Cache_Interface - * @todo package:orm - */ - public function getQueryCacheDriver() - { - if ( ! $this->getAttribute(Doctrine::ATTR_QUERY_CACHE)) { - throw new Doctrine_Exception('Query Cache driver not initialized.'); - } - - return $this->getAttribute(Doctrine::ATTR_QUERY_CACHE); - } - - /** - * Initiates a transaction. - * - * This method must only be used by Doctrine itself to initiate transactions. - * Userland-code must use {@link beginTransaction()}. - * - * @todo package:orm??? - */ - public function beginInternalTransaction($savepoint = null) - { - return $this->transaction->beginInternalTransaction($savepoint); - } - - /** - * Enter description here... - * - * @todo To EntityManager - */ - public function getRepository($entityName) - { - if (isset($this->_repositories[$entityName])) { - return $this->_repositories[$entityName]; - } - - $metadata = $this->getClassMetadata($entityName); - $customRepositoryClassName = $metadata->getCustomRepositoryClass(); - if ($customRepositoryClassName !== null) { - $repository = new $customRepositoryClassName($entityName, $metadata); - } else { - $repository = new Doctrine_EntityRepository($entityName, $metadata); - } - $this->_repositories[$entityName] = $repository; - - return $repository; - } - - /** - * createEntity - * First checks if record exists in identityMap, if not - * returns a new record. - * - * @return Doctrine_Entity - */ - public function createEntity2($className, array $data) - { - $className = $this->_getClassnameToReturn($data, $className); - $classMetadata = $this->getClassMetadata($className); - if ( ! empty($data)) { - $identifierFieldNames = $classMetadata->getIdentifier(); - $isNew = false; - foreach ($identifierFieldNames as $fieldName) { - if ( ! isset($data[$fieldName])) { - // id field not found return new entity - $isNew = true; - break; - } - $id[] = $data[$fieldName]; - } - if ($isNew) { - return new $className(true, $data); - } - - $idHash = $this->unitOfWork->getIdentifierHash($id); - - if ($entity = $this->unitOfWork->tryGetByIdHash($idHash, - $classMetadata->getRootClassName())) { - // @todo return $entity; the one in-memory is the most recent. - $entity->hydrate($data); - } else { - $entity = new $className(false, $data); - $this->unitOfWork->registerIdentity($entity); - } - $data = array(); - } else { - $entity = new $className(true, $data); - } - - return $entity; - } - - /** - * Check the dataset for a discriminator column to determine the correct - * class to instantiate. If no discriminator column is found, the given - * classname will be returned. - * - * @return string The name of the class to instantiate. - * @todo Can be optimized performance-wise. - * @todo Move to EntityManager::createEntity() - */ - protected function _getClassnameToReturn(array $data, $className) - { - $class = $this->getClassMetadata($className); - - $discCol = $class->getInheritanceOption('discriminatorColumn'); - if ( ! $discCol) { - return $className; - } - - $discMap = $class->getInheritanceOption('discriminatorMap'); - - if (isset($data[$discCol], $discMap[$data[$discCol]])) { - return $discMap[$data[$discCol]]; - } else { - return $className; - } - } - - /* * ----------- Mixed methods (need to figure out where they go) --------------- */ @@ -1695,14 +1225,4 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun return $this->modules[$name]; } - /** - * returns the manager that created this connection - * - * @return Doctrine_Manager - */ - public function getManager() - { - return $this->getParent(); - } - } diff --git a/lib/Doctrine/Connection/Db2.php b/lib/Doctrine/Connection/Db2.php index c7df64435..eb2c5d4c0 100644 --- a/lib/Doctrine/Connection/Db2.php +++ b/lib/Doctrine/Connection/Db2.php @@ -55,8 +55,8 @@ class Doctrine_Connection_Db2 extends Doctrine_Connection $col = explode('select', $select); $sql = 'WITH OFFSET AS(' . $select . ', ROW_NUMBER() ' . - 'OVER(ORDER BY ' . $col[1] . ') AS dctrn_rownum FROM ' . $table . ')' . - $select . 'FROM OFFSET WHERE dctrn_rownum BETWEEN ' . $offset . + 'OVER(ORDER BY ' . $col[1] . ') AS doctrine_rownum FROM ' . $table . ')' . + $select . 'FROM OFFSET WHERE doctrine_rownum BETWEEN ' . $offset . 'AND ' . ($offset + $limit - 1); return $sql; } diff --git a/lib/Doctrine/Connection/Mock.php b/lib/Doctrine/Connection/Mock.php index 1df240779..33613114b 100644 --- a/lib/Doctrine/Connection/Mock.php +++ b/lib/Doctrine/Connection/Mock.php @@ -44,7 +44,7 @@ class Doctrine_Connection_Mock extends Doctrine_Connection_Common * @param Doctrine_Manager $manager * @param PDO|Doctrine_Adapter $adapter database handler */ - public function __construct(Doctrine_Manager $manager, $adapter) + public function __construct() { } diff --git a/lib/Doctrine/Connection/Oracle.php b/lib/Doctrine/Connection/Oracle.php index 44d695dd9..837f69900 100644 --- a/lib/Doctrine/Connection/Oracle.php +++ b/lib/Doctrine/Connection/Oracle.php @@ -18,7 +18,7 @@ * and is licensed under the LGPL. For more information, see * . */ -Doctrine::autoload('Doctrine_Connection'); + /** * Doctrine_Connection_Oracle * @@ -80,39 +80,59 @@ class Doctrine_Connection_Oracle extends Doctrine_Connection $this->exec('ALTER SESSION SET NLS_DATE_FORMAT = "' . $format . '"'); } - /** - * Adds an driver-specific LIMIT clause to the query - * - * @param string $query query to modify - * @param integer $limit limit the number of rows - * @param integer $offset start reading from given offset - * @return string the modified query - */ - public function modifyLimitQuery($query, $limit, $offset) - { - /** - $e = explode("select ",strtolower($query)); - $e2 = explode(" from ",$e[1]); - $fields = $e2[0]; - */ - $limit = (int) $limit; - $offset = (int) $offset; - if (preg_match('/^\s*SELECT/i', $query)) { - if ( ! preg_match('/\sFROM\s/i', $query)) { - $query .= " FROM dual"; - } - if ($limit > 0) { - // taken from http://svn.ez.no/svn/ezcomponents/packages/Database - $max = $offset + $limit; - if ($offset > 0) { - $min = $offset + 1; - $query = 'SELECT * FROM (SELECT a.*, ROWNUM dctrn_rownum FROM (' . $query - . ') a WHERE ROWNUM <= ' . $max . ') WHERE dctrn_rownum >= ' . $min; - } else { - $query = 'SELECT a.* FROM (' . $query .') a WHERE ROWNUM <= ' . $max; - } - } - } - return $query; + /** + * Adds an driver-specific LIMIT clause to the query + * + * @param string $query query to modify + * @param integer $limit limit the number of rows + * @param integer $offset start reading from given offset + * @return string the modified query + */ + public function modifyLimitQuery($query, $limit = false, $offset = false, $isManip = false) + { + return $this->_createLimitSubquery($query, $limit, $offset); + } + + private function _createLimitSubquery($query, $limit, $offset, $column = null) + { + $limit = (int) $limit; + $offset = (int) $offset; + if (preg_match('/^\s*SELECT/i', $query)) { + if ( ! preg_match('/\sFROM\s/i', $query)) { + $query .= " FROM dual"; + } + if ($limit > 0) { + $max = $offset + $limit; + $column = $column === null ? '*' : $column; + if ($offset > 0) { + $min = $offset + 1; + $query = 'SELECT b.'.$column.' FROM ('. + 'SELECT a.*, ROWNUM AS doctrine_rownum FROM (' + . $query . ') a '. + ') b '. + 'WHERE doctrine_rownum BETWEEN ' . $min . ' AND ' . $max; + } else { + $query = 'SELECT a.'.$column.' FROM (' . $query .') a WHERE ROWNUM <= ' . $max; + } + } + } + return $query; + } + + /** + * Creates the SQL for Oracle that can be used in the subquery for the limit-subquery + * algorithm. + */ + public function modifyLimitSubquery(Doctrine_ClassMetadata $rootClass, $query, $limit = false, + $offset = false, $isManip = false) + { + // NOTE: no composite key support + $columnNames = $rootClass->getIdentifierColumnNames(); + if (count($columnNames) > 1) { + throw new Doctrine_Connection_Exception("Composite keys in LIMIT queries are " + . "currently not supported."); + } + $column = $columnNames[0]; + return $this->_createLimitSubquery($query, $limit, $offset, $column); } } \ No newline at end of file diff --git a/lib/Doctrine/Connection/UnitOfWork.php b/lib/Doctrine/Connection/UnitOfWork.php index 7d3f0cdf2..dca2d7011 100644 --- a/lib/Doctrine/Connection/UnitOfWork.php +++ b/lib/Doctrine/Connection/UnitOfWork.php @@ -25,18 +25,21 @@ * * Some terminology: * - * New entity: From the point of view of the unitOfWork is an entity that - * already has an identity but is not yet persisted into the database. This - * is usually the case for all newly saved entities that use a SEQUENCE id - * generator. Entities with an IDENTITY id generator get persisted as soon - * as they're saved in order to obtain the identifier. Therefore entities that - * use an IDENTITY id generator never appear in the list of new entities of the UoW. + * New entity: A new entity is an entity that already has an identity but + * is not yet persisted into the database. This is usually the case for all + * newly saved entities that use a SEQUENCE id generator. Entities with an + * IDENTITY id generator get persisted as soon as they're saved in order to + * obtain the identifier. Therefore entities that use an IDENTITY id generator + * never appear in the list of new entities of the UoW. * - * Dirty entity: ... + * Dirty entity: A dirty entity is a managed entity whose values have + * been altered. * - * Removed entity: ... + * Removed entity: A removed entity is a managed entity that is scheduled + * for deletion from the database. * - * Clean entity: ... + * Clean entity: A clean entity is a managed entity that has been fetched + * from the database and whose values have not yet been altered. * * @package Doctrine * @subpackage Connection @@ -226,7 +229,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module $index = max(array_keys($tree)); } - $rels = $mapper->getTable()->getRelations(); + $rels = $mapper->getClassMetadata()->getRelations(); // group relations @@ -355,7 +358,8 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module /** * @param integer $oid object identifier * @return boolean whether ot not the operation was successful - * @deprecated + * @deprecated The new implementation of detach() should remove the entity + * from the identity map. */ public function detach(Doctrine_Entity $entity) { @@ -371,6 +375,8 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module * Detaches all currently managed entities. * * @return integer The number of detached entities. + * @todo Deprecated. The new implementation should remove all entities from + * the identity map. */ public function detachAll() { @@ -401,11 +407,24 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module return true; } + /** + * Enter description here... + * + * @param unknown_type $entityName + * @todo unify with detachAll() + */ public function clearIdentitiesForEntity($entityName) { $this->_identityMap[$entityName] = array(); } + /** + * Removes an entity from the identity map. + * + * @param Doctrine_Entity $entity + * @return unknown + * @todo This will be the new detach(). + */ public function unregisterIdentity(Doctrine_Entity $entity) { $idHash = $this->getIdentifierHash($entity->identifier()); @@ -422,6 +441,13 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module return false; } + /** + * Finds an entity in the identity map by its identifier hash. + * + * @param unknown_type $idHash + * @param unknown_type $rootClassName + * @return unknown + */ public function getByIdHash($idHash, $rootClassName) { return $this->_identityMap[$rootClassName][$idHash]; @@ -435,6 +461,12 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module return false; } + /** + * Gets the identifier hash for a set of identifier values. + * + * @param array $id + * @return string + */ public function getIdentifierHash(array $id) { return implode(' ', $id); @@ -448,15 +480,22 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module */ public function contains(Doctrine_Entity $entity) { - $id = implode(' ', $entity->identifier()); - if ( ! $id) { + $idHash = $this->getIdentifierHash($entity->identifier()); + if ( ! $idHash) { return false; } - return isset($this->_identityMap[ - $entity->getClassMetadata()->getRootClassName() - ][$id]); + return isset($this->_identityMap + [$entity->getClassMetadata()->getRootClassName()] + [$idHash]); } + /** + * Checks whether an identifier hash exists in the identity map. + * + * @param string $idHash + * @param string $rootClassName + * @return boolean + */ public function containsIdHash($idHash, $rootClassName) { return isset($this->_identityMap[$rootClassName][$idHash]); diff --git a/lib/Doctrine/Entity.php b/lib/Doctrine/Entity.php index be63a8509..c0621d55f 100644 --- a/lib/Doctrine/Entity.php +++ b/lib/Doctrine/Entity.php @@ -115,6 +115,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * The metadata container that describes the entity class. * * @var Doctrine_ClassMetadata + * @todo Lazy initialization. */ protected $_class; @@ -188,6 +189,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * The EntityManager that is responsible for the persistence of the entity. * * @var Doctrine_EntityManager + * @todo Lazy initialization. */ protected $_em; @@ -214,8 +216,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite public function __construct($isNewEntry = true, array $data = array()) { $this->_entityName = get_class($this); - $this->_em = Doctrine_Manager::getInstance()->getCurrentConnection(); - // future: $this->_em = Doctrine_EntityManager::getManagerForEntity($this->_entityName); + $this->_em = Doctrine_EntityManager::getManager($this->_entityName); $this->_class = $this->_em->getClassMetadata($this->_entityName); $this->_oid = self::$_index++; @@ -227,18 +228,15 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite // get the column count $count = count($this->_data); - - $this->_values = $this->cleanData($this->_data); $this->_extractIdentifier( ! $isNewEntry); if ($isNewEntry) { - if ($count > count($this->_values)) { + if ($count > 0) { $this->_state = Doctrine_Entity::STATE_TDIRTY; } else { $this->_state = Doctrine_Entity::STATE_TCLEAN; } - // set the default values for this record $this->assignDefaultValues(); } else { @@ -251,8 +249,6 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite //-- self::$_useAutoAccessorOverride = false; // @todo read from attribute the first time - $this->_em->manage($this); // @todo Remove - $this->construct(); // @todo Remove } /** @@ -509,7 +505,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite $tmp = $data; $data = array(); - $fieldNames = $this->_em->getMapper($this->_entityName)->getFieldNames(); + $fieldNames = $this->_em->getEntityPersister($this->_entityName)->getFieldNames(); foreach ($fieldNames as $fieldName) { if (isset($tmp[$fieldName])) { $data[$fieldName] = $tmp[$fieldName]; @@ -650,13 +646,14 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite $this->preUnserialize($event); - $manager = Doctrine_Manager::getInstance(); - $connection = $manager->getConnectionForComponent(get_class($this)); + $this->_entityName = get_class($this); + $manager = Doctrine_EntityManager::getManager($this->_entityName); + $connection = $manager->getConnection(); $this->_oid = self::$_index; self::$_index++; - $this->_em = $connection; + $this->_em = $manager; $array = unserialize($serialized); @@ -664,7 +661,6 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite $this->$k = $v; } - $this->_entityName = get_class($this); $this->_class = $this->_em->getClassMetadata($this->_entityName); foreach ($this->_data as $k => $v) { @@ -683,7 +679,6 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite } } - $this->_em->manage($this); $this->cleanData($this->_data); $this->_extractIdentifier($this->exists()); @@ -997,7 +992,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @throws Doctrine_Record_Exception if trying to get a value of unknown property / related component * @return mixed */ - public function get($fieldName, $load = true) + public function get($fieldName, $load = false) { /*// check for custom accessor, if not done yet. if ( ! isset(self::$_accessorCache[$this->_entityName][$fieldName])) { @@ -1020,63 +1015,36 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite return $this->$getter(); }*/ - // Use built-in accessor functionality + // Use built-in accessor functionality $nullObj = Doctrine_Null::$INSTANCE; - $value = $nullObj; if (isset($this->_data[$fieldName])) { - if ($this->_data[$fieldName] !== $nullObj) { - return $this->_data[$fieldName]; - } - if ($this->_data[$fieldName] === $nullObj && $load) { - $this->load(); - $value = $this->_data[$fieldName]; - } - if ($value === $nullObj) { - $value = null; - } - - return $value; - } - - if (isset($this->_values[$fieldName])) { - return $this->_values[$fieldName]; - } - - try { - if ( ! isset($this->_references[$fieldName]) && $load) { - $rel = $this->_class->getRelation($fieldName); - $this->_references[$fieldName] = $rel->fetchRelatedFor($this); - } - if ($this->_references[$fieldName] === Doctrine_Null::$INSTANCE) { - return null; - } - 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; + return $this->_data[$fieldName] !== $nullObj ? + $this->_data[$fieldName] : null; + } else if (isset($this->_references[$fieldName])) { + return $this->_references[$fieldName] !== $nullObj ? + $this->_references[$fieldName] : null; + } else { + if ($this->_class->hasField($fieldName)) { + if ($load) { + $this->load(); + return $this->get($fieldName); + } else { + return null; } + } else if ($this->_class->hasRelation($fieldName)) { + if ($load) { + $rel = $this->_class->getRelation($fieldName); + $this->_references[$fieldName] = $rel->fetchRelatedFor($this); + return $this->_references[$fieldName] !== $nullObj ? + $this->_references[$fieldName] : null; + } else { + return null; + } + } else { + throw Doctrine_Entity_Exception::invalidField($fieldName); } } } - - /** - * mapValue - * This simple method is used for mapping values to $values property. - * Usually this method is used internally by Doctrine for the mapping of - * aggregate values. - * - * @param string $name the name of the mapped value - * @param mixed $value mixed value to be mapped - * @return void - * @todo Maybe better placed in the Mapper. - */ - public function mapValue($name, $value) - { - $this->_values[$name] = $value; - } public function getClassName() { @@ -1097,9 +1065,9 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * * @return Doctrine_Entity */ - public function set($fieldName, $value, $load = true) - { - if (isset($this->_data[$fieldName])) { + public function set($fieldName, $value, $load = false) + { + if ($this->_class->hasField($fieldName)) { if ($value instanceof Doctrine_Entity) { $type = $this->_class->getTypeOf($fieldName); // FIXME: composite key support @@ -1111,16 +1079,12 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite } if ($load) { - $old = $this->get($fieldName, $load); + $old = $this->get($fieldName, true); } else { - $old = $this->_data[$fieldName]; + $old = isset($this->_data[$fieldName]) ? $this->_data[$fieldName] : null; } if ($old !== $value) { - if ($value === null) { - $value = Doctrine_Null::$INSTANCE; - } - $this->_data[$fieldName] = $value; $this->_modified[] = $fieldName; @@ -1139,18 +1103,10 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite break; } } + } else if ($this->_class->hasRelation($fieldName)) { + $this->rawSetReference($fieldName, $value); } else { - try { - $this->rawSetReference($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; - } - } - } + throw Doctrine_Entity_Exception::invalidField($fieldName); } } @@ -2067,8 +2023,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite public function getEntityManager() { if ( ! $this->_em) { - $this->_em = Doctrine_Manager::getInstance()->getCurrentConnection(); - // future: $this->_em = Doctrine_EntityManager::getManagerForEntity($this->_entityName); + $this->_em = Doctrine_EntityManager::getManager($this->_entityName); } return $this->_em; } @@ -2106,7 +2061,6 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite { if ($this->_state != self::STATE_LOCKED) { $this->_em->detach($this); - $this->_em->removeRecord($this); $this->_data = array(); $this->_id = array(); diff --git a/lib/Doctrine/Entity/Exception.php b/lib/Doctrine/Entity/Exception.php index 11883bc3e..040c78cd5 100644 --- a/lib/Doctrine/Entity/Exception.php +++ b/lib/Doctrine/Entity/Exception.php @@ -23,6 +23,11 @@ class Doctrine_Entity_Exception extends Doctrine_Exception return new self("Invalid value. The value of a reference in a ManyToMany " . "association must be a Collection."); } + + public static function invalidField($field) + { + return new self("Invalid field: '$field'."); + } } ?> \ No newline at end of file diff --git a/lib/Doctrine/EntityRepository.php b/lib/Doctrine/EntityRepository.php index 5aec5c064..4d6a3c1c9 100644 --- a/lib/Doctrine/EntityRepository.php +++ b/lib/Doctrine/EntityRepository.php @@ -35,13 +35,13 @@ class Doctrine_EntityRepository { protected $_entityName; - protected $_conn; + protected $_em; protected $_classMetadata; public function __construct($entityName, Doctrine_ClassMetadata $classMetadata) { $this->_entityName = $entityName; - $this->_conn = $classMetadata->getConnection(); + $this->_em = $classMetadata->getConnection(); $this->_classMetadata = $classMetadata; } @@ -59,7 +59,7 @@ class Doctrine_EntityRepository if ( ! empty($alias)) { $alias = ' ' . trim($alias); } - return Doctrine_Query::create($this->_conn)->from($this->_entityName . $alias); + return Doctrine_Query::create($this->_em)->from($this->_entityName . $alias); } /** @@ -69,7 +69,7 @@ class Doctrine_EntityRepository */ public function clear() { - $this->_conn->unitOfWork->clearIdentitiesForEntity($this->_classMetadata->getRootClassName()); + $this->_em->unitOfWork->clearIdentitiesForEntity($this->_classMetadata->getRootClassName()); } /** @@ -170,7 +170,7 @@ class Doctrine_EntityRepository */ public function findByDql($dql, array $params = array(), $hydrationMode = null) { - $query = new Doctrine_Query($this->_conn); + $query = new Doctrine_Query($this->_em); $component = $this->getComponentName(); $dql = 'FROM ' . $component . ' WHERE ' . $dql; diff --git a/lib/Doctrine/Hydrator/Abstract.php b/lib/Doctrine/Hydrator/Abstract.php index b474f5a43..ce7558f11 100644 --- a/lib/Doctrine/Hydrator/Abstract.php +++ b/lib/Doctrine/Hydrator/Abstract.php @@ -63,7 +63,7 @@ abstract class Doctrine_Hydrator_Abstract * * @param Doctrine_Connection|null $connection */ - public function __construct(Doctrine_Connection $em) + public function __construct(Doctrine_EntityManager $em) { $this->_em = $em; $this->_nullObject = Doctrine_Null::$INSTANCE; diff --git a/lib/Doctrine/Hydrator/RecordDriver.php b/lib/Doctrine/Hydrator/RecordDriver.php index 4d34434f6..7a8a181be 100644 --- a/lib/Doctrine/Hydrator/RecordDriver.php +++ b/lib/Doctrine/Hydrator/RecordDriver.php @@ -43,7 +43,7 @@ class Doctrine_Hydrator_RecordDriver /** The EntityManager */ private $_em; - public function __construct(Doctrine_Connection $em) + public function __construct(Doctrine_EntityManager $em) { $this->_nullObject = Doctrine_Null::$INSTANCE; $this->_em = $em; @@ -93,7 +93,7 @@ class Doctrine_Hydrator_RecordDriver public function getElement(array $data, $className) { - return $this->_em->createEntity2($className, $data); + return $this->_em->createEntity($className, $data); } public function addRelatedIndexedElement(Doctrine_Entity $entity1, $property, diff --git a/lib/Doctrine/HydratorNew.php b/lib/Doctrine/HydratorNew.php index 3f2afa132..ee31f4b81 100644 --- a/lib/Doctrine/HydratorNew.php +++ b/lib/Doctrine/HydratorNew.php @@ -375,6 +375,10 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract foreach ($data as $key => $value) { // Parse each column name only once. Cache the results. if ( ! isset($cache[$key])) { + // check ignored names. fastest solution for now. if we get more we'll start + // to introduce a list. + if ($key == 'doctrine_rownum') continue; + // cache general information like the column name <-> field name mapping $e = explode('__', $key); $columnName = strtolower(array_pop($e)); diff --git a/lib/Doctrine/Manager.php b/lib/Doctrine/Manager.php index 42b205059..7ac9c8487 100644 --- a/lib/Doctrine/Manager.php +++ b/lib/Doctrine/Manager.php @@ -680,7 +680,7 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera */ public function getMapper($componentName) { - return $this->getConnectionForComponent($componentName)->getMapper($componentName); + return $this->getConnectionForComponent($componentName)->getEntityPersister($componentName); } /** diff --git a/lib/Doctrine/Mapper.php b/lib/Doctrine/Mapper.php index 5f28d6225..6a1b57182 100644 --- a/lib/Doctrine/Mapper.php +++ b/lib/Doctrine/Mapper.php @@ -30,7 +30,6 @@ * @version $Revision: 3406 $ * @link www.phpdoctrine.org * @since 2.0 - * @todo Move all finder stuff to EntityRepository. * @todo Rename to "EntityPersister" or similar. */ class Doctrine_Mapper @@ -69,6 +68,12 @@ class Doctrine_Mapper */ private $_entityListeners = array(); + /** + * Enter description here... + * + * @var unknown_type + * @todo To EntityManager. + */ private $_dataTemplate = array(); @@ -121,6 +126,7 @@ class Doctrine_Mapper * @param $array an array where keys are field names and * values representing field values * @return Doctrine_Entity the created record object + * @todo To EntityManager. */ public function create(array $array = array()) { @@ -158,25 +164,17 @@ class Doctrine_Mapper } } + /** + * Enter description here... + * + * @param Doctrine_Entity $entity + * @return unknown + * @todo To EntityManager + */ public function detach(Doctrine_Entity $entity) { return $this->_conn->unitOfWork->detach($entity); } - - /** - * Executes a named query. - * - * @param string $queryName The name that was used when storing the query. - * @param array $params The query parameters. - * @return mixed The result. - * @deprecated - */ - public function executeNamedQuery($queryName, $params = array(), $hydrationMode = Doctrine::HYDRATE_RECORD) - { - return Doctrine_Manager::getInstance() - ->createNamedQuery($queryName) - ->execute($params, $hydrationMode); - } /** * clear @@ -184,6 +182,7 @@ class Doctrine_Mapper * * @return void * @todo what about a more descriptive name? clearIdentityMap? + * @todo To EntityManager */ public function clear() { @@ -197,6 +196,7 @@ class Doctrine_Mapper * @param Doctrine_Entity $record record to be added * @return boolean * @todo Better name? registerRecord? Move elsewhere to the new location of the identity maps. + * @todo Remove. */ public function addRecord(Doctrine_Entity $record) { @@ -213,6 +213,7 @@ class Doctrine_Mapper * * @return boolean TRUE if the entity was previously not managed and is now managed, * FALSE otherwise (the entity is already managed). + * @todo Remove. */ public function manage(Doctrine_Entity $record) { @@ -244,6 +245,7 @@ class Doctrine_Mapper * returns a new record. * * @return Doctrine_Entity + * @todo To EntityManager. */ public function getRecord(array $data) { @@ -310,6 +312,7 @@ class Doctrine_Mapper * applyInheritance * @param $where query where part to be modified * @return string query where part with column aggregation inheritance added + * @todo What to do with this? Remove if possible. */ final public function applyInheritance($where) { @@ -357,6 +360,8 @@ class Doctrine_Mapper * for the field can be skipped. Used i.e. during hydration to * improve performance on large and/or complex results. * @return mixed prepared value + * @todo To EntityManager. Make private and use in createEntity(). + * .. Or, maybe better: Move to hydrator for performance reasons. */ public function prepareValue($fieldName, $value, $typeHint = null) { @@ -398,43 +403,6 @@ class Doctrine_Mapper } return $value; } - - /** - * Hydrates the given data into the entity. - * - */ - /*public function hydrate(Doctrine_Entity $entity, array $data) - { - $this->_values = array_merge($this->_values, $this->cleanData($data)); - $this->_data = array_merge($this->_data, $data); - $this->_extractIdentifier(true); - }*/ - - /** - * getTree - * - * getter for associated tree - * - * @return mixed if tree return instance of Doctrine_Tree, otherwise returns false - * @todo Part of the NestedSet Behavior plugin. Move outta here some day... - */ - public function getTree() - { - return $this->_classMetadata->getTree(); - } - - /** - * isTree - * - * determine if table acts as tree - * - * @return mixed if tree return true, otherwise returns false - * @todo Part of the NestedSet Behavior plugin. Move outta here some day... - */ - public function isTree() - { - return $this->_classMetadata->isTree(); - } /** * getComponentName @@ -729,26 +697,11 @@ class Doctrine_Mapper return true; } - public function executeQuery(Doctrine_Query $query) - { - - } - - public function getTable() - { - return $this->_classMetadata; - } - public function getClassMetadata() { return $this->_classMetadata; } - public function dump() - { - var_dump($this->_invokedMethods); - } - public function free() { $this->_mappingStrategy = null; @@ -759,8 +712,6 @@ class Doctrine_Mapper return $this->_mappingStrategy; } - - public function getFieldName($columnName) { return $this->_mappingStrategy->getFieldName($columnName); diff --git a/lib/Doctrine/Query.php b/lib/Doctrine/Query.php index f0e46e5bc..d2b3bd0df 100644 --- a/lib/Doctrine/Query.php +++ b/lib/Doctrine/Query.php @@ -1129,7 +1129,6 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria $modifyLimit = true; if ( ! empty($this->_sqlParts['limit']) || ! empty($this->_sqlParts['offset'])) { - if ($needsSubQuery) { $subquery = $this->getLimitSubquery(); // what about composite keys? @@ -1138,7 +1137,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria switch (strtolower($this->_conn->getDriverName())) { case 'mysql': // mysql doesn't support LIMIT in subqueries - $list = $this->_conn->execute($subquery, $params)->fetchAll(Doctrine::FETCH_COLUMN); + $list = $this->_conn->execute($subquery, $params)->fetchAll(Doctrine::FETCH_COLUMN); $subquery = implode(', ', array_map(array($this->_conn, 'quote'), $list)); break; case 'pgsql': @@ -1192,18 +1191,18 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria */ public function getLimitSubquery() { - $map = reset($this->_queryComponents); - $table = $map['table']; + $map = reset($this->_queryComponents); + $table = $map['table']; $componentAlias = key($this->_queryComponents); // get short alias - $alias = $this->getTableAlias($componentAlias); + $alias = $this->getTableAlias($componentAlias); // what about composite keys? $idFieldNames = (array)$table->getIdentifier(); $primaryKey = $alias . '.' . $table->getColumnName($idFieldNames[0]); // initialize the base of the subquery - $subquery = 'SELECT DISTINCT ' . $this->_conn->quoteIdentifier($primaryKey); + $subquery = 'SELECT DISTINCT ' . $this->_conn->quoteIdentifier($primaryKey); $driverName = $this->_conn->getAttribute(Doctrine::ATTR_DRIVER_NAME); @@ -1261,7 +1260,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria $subquery .= ( ! empty($this->_sqlParts['orderby']))? ' ORDER BY ' . implode(', ', $this->_sqlParts['orderby']) : ''; // add driver specific limit clause - $subquery = $this->_conn->modifyLimitQuery($subquery, $this->_sqlParts['limit'], $this->_sqlParts['offset']); + $subquery = $this->_conn->modifyLimitSubquery($table, $subquery, $this->_sqlParts['limit'], $this->_sqlParts['offset']); $parts = $this->_tokenizer->quoteExplode($subquery, ' ', "'", "'"); @@ -1643,7 +1642,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria $this->_sqlParts['from'][] = $queryPart; //echo "

" . $table->getComponentName() . "---3---" . $name . "

"; $this->_queryComponents[$componentAlias] = array( - 'table' => $table, 'mapper' => $this->_conn->getMapper($name), 'map' => null); + 'table' => $table, 'mapper' => $this->_conn->getEntityPersister($name), 'map' => null); return $table; } diff --git a/lib/Doctrine/Query/Abstract.php b/lib/Doctrine/Query/Abstract.php index a49c649a8..059229ccc 100644 --- a/lib/Doctrine/Query/Abstract.php +++ b/lib/Doctrine/Query/Abstract.php @@ -530,7 +530,7 @@ abstract class Doctrine_Query_Abstract { $table = $this->_conn->getMetadata($componentName); $tableAlias = $this->getSqlTableAlias($componentAlias, $table->getTableName()); - $customJoins = $this->_conn->getMapper($componentName)->getCustomJoins(); + $customJoins = $this->_conn->getEntityPersister($componentName)->getCustomJoins(); $sql = ''; foreach ($customJoins as $componentName => $joinType) { $joinedTable = $this->_conn->getMetadata($componentName); @@ -1051,12 +1051,12 @@ abstract class Doctrine_Query_Abstract $e = explode('.', $components[0]); if (count($e) === 1) { $queryComponents[$alias]['mapper'] = $this->_conn->getMapper($e[0]); - $queryComponents[$alias]['table'] = $queryComponents[$alias]['mapper']->getTable(); + $queryComponents[$alias]['table'] = $queryComponents[$alias]['mapper']->getClassMetadata(); } else { $queryComponents[$alias]['parent'] = $e[0]; $queryComponents[$alias]['relation'] = $queryComponents[$e[0]]['table']->getRelation($e[1]); $queryComponents[$alias]['mapper'] = $this->_conn->getMapper($queryComponents[$alias]['relation']->getForeignComponentName()); - $queryComponents[$alias]['table'] = $queryComponents[$alias]['mapper']->getTable(); + $queryComponents[$alias]['table'] = $queryComponents[$alias]['mapper']->getClassMetadata(); } if (isset($components[1])) { $queryComponents[$alias]['agg'] = $components[1]; diff --git a/lib/Doctrine/Relation.php b/lib/Doctrine/Relation.php index 03838cae8..91abfdb5b 100644 --- a/lib/Doctrine/Relation.php +++ b/lib/Doctrine/Relation.php @@ -154,7 +154,7 @@ abstract class Doctrine_Relation implements ArrayAccess } } $this->definition = $def; - $this->_foreignMapper = $this->getTable()->getConnection()->getMapper($def['class']); + $this->_foreignMapper = $this->getTable()->getConnection()->getEntityPersister($def['class']); } /** @@ -257,9 +257,8 @@ abstract class Doctrine_Relation implements ArrayAccess */ final public function getTable() { - return Doctrine_Manager::getInstance() - ->getConnectionForComponent($this->definition['class']) - ->getMetadata($this->definition['class']); + return Doctrine_EntityManager::getManager($this->definition['class']) + ->getClassMetadata($this->definition['class']); } /** diff --git a/lib/Doctrine/Relation/Parser.php b/lib/Doctrine/Relation/Parser.php index 2ff76cb4b..f3e80b1be 100644 --- a/lib/Doctrine/Relation/Parser.php +++ b/lib/Doctrine/Relation/Parser.php @@ -271,7 +271,7 @@ class Doctrine_Relation_Parser */ public function getImpl(array &$def, $key) { - $conn = $this->_table->getConnection(); + $em = $this->_table->getEntityManager(); if (in_array('Doctrine_Template', class_parents($def[$key]))) { $impl = $this->_table->getImpl($def[$key]); if ($impl === null) { @@ -280,7 +280,7 @@ class Doctrine_Relation_Parser $def[$key] = $impl; } - return $conn->getMetadata($def[$key]); + return $em->getClassMetadata($def[$key]); } protected function _isTemplate($className) diff --git a/tests/Orm/Component/AccessTest.php b/tests/Orm/Component/AccessTest.php index e5c24eab9..054feaf67 100644 --- a/tests/Orm/Component/AccessTest.php +++ b/tests/Orm/Component/AccessTest.php @@ -41,6 +41,7 @@ class Orm_Component_AccessTest extends Doctrine_OrmTestCase public function setUp() { parent::setUp(); + $em = new Doctrine_EntityManager(new Doctrine_Connection_Mock()); $this->user = new ForumUser(); } @@ -57,10 +58,10 @@ class Orm_Component_AccessTest extends Doctrine_OrmTestCase /** * @test */ - public function shouldMarkExistingFieldAsSetOnNewRecord() + public function shouldMarkEmptyFieldAsNotSetOnNewRecord() { - $this->assertTrue(isset($this->user->username)); - $this->assertTrue(isset($this->user['username'])); + $this->assertFalse(isset($this->user->username)); + $this->assertFalse(isset($this->user['username'])); } /** @@ -113,7 +114,7 @@ class Orm_Component_AccessTest extends Doctrine_OrmTestCase /** * @test - * @expectedException Doctrine_Record_Exception + * @expectedException Doctrine_Entity_Exception */ public function shouldNotBeAbleToSetNonExistantField() { @@ -122,7 +123,7 @@ class Orm_Component_AccessTest extends Doctrine_OrmTestCase /** * @test - * @expectedException Doctrine_Record_Exception + * @expectedException Doctrine_Entity_Exception */ public function shouldNotBeAbleToSetNonExistantFieldWithOffset() { @@ -131,14 +132,13 @@ class Orm_Component_AccessTest extends Doctrine_OrmTestCase /** * @test - * @expectedException Doctrine_Record_Exception + * @expectedException Doctrine_Entity_Exception */ public function shouldNotBeAbleToSetNonExistantFieldAsPartInSetArray() { $this->user->setArray(array( 'rat' => 'meus', 'id' => 22)); - } diff --git a/tests/Orm/Component/AllTests.php b/tests/Orm/Component/AllTests.php index fe9655e0e..1e4d102ff 100644 --- a/tests/Orm/Component/AllTests.php +++ b/tests/Orm/Component/AllTests.php @@ -6,7 +6,6 @@ if (!defined('PHPUnit_MAIN_METHOD')) { require_once 'lib/DoctrineTestInit.php'; // Tests -require_once 'Orm/Component/TestTest.php'; require_once 'Orm/Component/AccessTest.php'; require_once 'Orm/Component/CollectionTest.php'; @@ -21,7 +20,6 @@ class Orm_Component_AllTests { $suite = new Doctrine_TestSuite('Doctrine Orm Component'); - $suite->addTestSuite('Orm_Component_TestTest'); $suite->addTestSuite('Orm_Component_AccessTest'); $suite->addTestSuite('Orm_Component_CollectionTest'); diff --git a/tests/Orm/Component/CollectionTest.php b/tests/Orm/Component/CollectionTest.php index 153b2d6a9..223909fe3 100644 --- a/tests/Orm/Component/CollectionTest.php +++ b/tests/Orm/Component/CollectionTest.php @@ -40,6 +40,8 @@ class Orm_Component_CollectionTest extends Doctrine_OrmTestCase public function setUp() { parent::setUp(); + $em = new Doctrine_EntityManager(new Doctrine_Connection_Mock()); + $this->coll = new Doctrine_Collection('ForumUser'); //we create a CmsUser with username as key column and add a user to it diff --git a/tests/Orm/Component/TestTest.php b/tests/Orm/Component/TestTest.php deleted file mode 100644 index 86804aa09..000000000 --- a/tests/Orm/Component/TestTest.php +++ /dev/null @@ -1,38 +0,0 @@ -loadFixtures('forum', 'common', array('users', 'admins')); - } - - public function testTest() - { - $this->assertEquals(0, 0); - } - - public function testFixture() - { - $forumUsers = $this->sharedFixture['connection']->query("FROM ForumUser u"); - $this->assertEquals(2, count($forumUsers)); - $forumUsers[0]->delete(); - unset($forumUsers[0]); - $this->assertEquals(1, count($forumUsers)); - } - - public function testFixture2() - { - $forumUsers = $this->sharedFixture['connection']->query("FROM ForumUser u"); - $this->assertEquals(2, count($forumUsers)); - } - - public function testFixture3() - { - $forumAdmins = $this->sharedFixture['connection']->query("FROM ForumAdministrator adm"); - $this->assertEquals(1, count($forumAdmins)); - $forumAdmins[0]->delete(); - } -} \ No newline at end of file diff --git a/tests/Orm/EntityManagerTest.php b/tests/Orm/EntityManagerTest.php new file mode 100644 index 000000000..14fa2200b --- /dev/null +++ b/tests/Orm/EntityManagerTest.php @@ -0,0 +1,49 @@ +assertSame($em, Doctrine_EntityManager::getManager('SomeEntity')); + } + + public function testStaticGetManagerThrowsExceptionIfNoManagerAvailable() + { + try { + Doctrine_EntityManager::getManager('SomeEntity'); + $this->fail("Expected exception not thrown."); + } catch (Doctrine_EntityManager_Exception $ex) {} + } + + public function testBindingValidEntityToNamedManager() + { + $em = new Doctrine_EntityManager(new Doctrine_Connection_Mock(null), 'myEM'); + Doctrine_EntityManager::bindEntityToManager('SomeEntity', 'myEM'); + $this->assertSame($em, Doctrine_EntityManager::getManager('SomeEntity')); + } + + public function testBindingEntityToInvalidManagerThrowsExceptionOnRetrieval() + { + // will work. we don't check the existence of the EM during binding + Doctrine_EntityManager::bindEntityToManager('SomeEntity', 'myEM'); + // exception on access + try { + Doctrine_EntityManager::getManager('SomeEntity'); + $this->fail(); + } catch (Doctrine_EntityManager_Exception $ex) {} + } + +} \ No newline at end of file diff --git a/tests/Orm/Hydration/BasicHydrationTest.php b/tests/Orm/Hydration/BasicHydrationTest.php index bedba6e6f..2b8203171 100644 --- a/tests/Orm/Hydration/BasicHydrationTest.php +++ b/tests/Orm/Hydration/BasicHydrationTest.php @@ -9,7 +9,7 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase protected function setUp() { parent::setUp(); - $this->_em = $this->sharedFixture['connection']; + $this->_em = new Doctrine_EntityManager(new Doctrine_Connection_Mock()); } /** Getter for the hydration mode dataProvider */ @@ -44,8 +44,8 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase // Faked query components $queryComponents = array( 'u' => array( - 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsUser'), - 'mapper' => $this->sharedFixture['connection']->getMapper('CmsUser'), + 'table' => $this->_em->getClassMetadata('CmsUser'), + 'mapper' => $this->_em->getEntityPersister('CmsUser'), 'parent' => null, 'relation' => null, 'map' => null @@ -105,18 +105,18 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase // Faked query components $queryComponents = array( 'u' => array( - 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsUser'), - 'mapper' => $this->sharedFixture['connection']->getMapper('CmsUser'), + 'table' => $this->_em->getClassMetadata('CmsUser'), + 'mapper' => $this->_em->getEntityPersister('CmsUser'), 'parent' => null, 'relation' => null, 'map' => null, 'agg' => array('0' => 'nameUpper') ), 'p' => array( - 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsPhonenumber'), - 'mapper' => $this->sharedFixture['connection']->getMapper('CmsPhonenumber'), + 'table' => $this->_em->getClassMetadata('CmsPhonenumber'), + 'mapper' => $this->_em->getEntityPersister('CmsPhonenumber'), 'parent' => 'u', - 'relation' => $this->sharedFixture['connection']->getClassMetadata('CmsUser')->getRelation('phonenumbers'), + 'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('phonenumbers'), 'map' => null ) ); @@ -155,14 +155,16 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase $result = $hydrator->hydrateResultSet($this->_createParserResult( $stmt, $queryComponents, $tableAliasMap, $hydrationMode, true)); - //var_dump($result); + + if ($hydrationMode == Doctrine::HYDRATE_ARRAY) { + //var_dump($result); + } $this->assertEquals(2, count($result)); $this->assertTrue(is_array($result)); $this->assertTrue(is_array($result[0])); $this->assertTrue(is_array($result[1])); - $this->assertEquals(3, count($result[0][0])); // first user => 2 phonenumbers $this->assertEquals(2, count($result[0][0]['phonenumbers'])); $this->assertEquals('ROMANB', $result[0]['nameUpper']); @@ -198,17 +200,17 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase // Faked query components $queryComponents = array( 'u' => array( - 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsUser'), - 'mapper' => $this->sharedFixture['connection']->getMapper('CmsUser'), + 'table' => $this->_em->getClassMetadata('CmsUser'), + 'mapper' => $this->_em->getEntityPersister('CmsUser'), 'parent' => null, 'relation' => null, 'map' => null ), 'p' => array( - 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsPhonenumber'), - 'mapper' => $this->sharedFixture['connection']->getMapper('CmsPhonenumber'), + 'table' => $this->_em->getClassMetadata('CmsPhonenumber'), + 'mapper' => $this->_em->getEntityPersister('CmsPhonenumber'), 'parent' => 'u', - 'relation' => $this->sharedFixture['connection']->getClassMetadata('CmsUser')->getRelation('phonenumbers'), + 'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('phonenumbers'), 'map' => null, 'agg' => array('0' => 'numPhones') ) @@ -273,18 +275,18 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase // Faked query components $queryComponents = array( 'u' => array( - 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsUser'), - 'mapper' => $this->sharedFixture['connection']->getMapper('CmsUser'), + 'table' => $this->_em->getClassMetadata('CmsUser'), + 'mapper' => $this->_em->getEntityPersister('CmsUser'), 'parent' => null, 'relation' => null, 'agg' => array('0' => 'nameUpper'), 'map' => 'id' ), 'p' => array( - 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsPhonenumber'), - 'mapper' => $this->sharedFixture['connection']->getMapper('CmsPhonenumber'), + 'table' => $this->_em->getClassMetadata('CmsPhonenumber'), + 'mapper' => $this->_em->getEntityPersister('CmsPhonenumber'), 'parent' => 'u', - 'relation' => $this->sharedFixture['connection']->getClassMetadata('CmsUser')->getRelation('phonenumbers'), + 'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('phonenumbers'), 'map' => 'phonenumber' ) ); @@ -375,25 +377,25 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase // Faked query components $queryComponents = array( 'u' => array( - 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsUser'), - 'mapper' => $this->sharedFixture['connection']->getMapper('CmsUser'), + 'table' => $this->_em->getClassMetadata('CmsUser'), + 'mapper' => $this->_em->getEntityPersister('CmsUser'), 'parent' => null, 'relation' => null, 'map' => null, 'agg' => array('0' => 'nameUpper') ), 'p' => array( - 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsPhonenumber'), - 'mapper' => $this->sharedFixture['connection']->getMapper('CmsPhonenumber'), + 'table' => $this->_em->getClassMetadata('CmsPhonenumber'), + 'mapper' => $this->_em->getEntityPersister('CmsPhonenumber'), 'parent' => 'u', - 'relation' => $this->sharedFixture['connection']->getClassMetadata('CmsUser')->getRelation('phonenumbers'), + 'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('phonenumbers'), 'map' => null ), 'a' => array( - 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsArticle'), - 'mapper' => $this->sharedFixture['connection']->getMapper('CmsArticle'), + 'table' => $this->_em->getClassMetadata('CmsArticle'), + 'mapper' => $this->_em->getEntityPersister('CmsArticle'), 'parent' => 'u', - 'relation' => $this->sharedFixture['connection']->getClassMetadata('CmsUser')->getRelation('articles'), + 'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('articles'), 'map' => null ), ); @@ -528,32 +530,32 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase // Faked query components $queryComponents = array( 'u' => array( - 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsUser'), - 'mapper' => $this->sharedFixture['connection']->getMapper('CmsUser'), + 'table' => $this->_em->getClassMetadata('CmsUser'), + 'mapper' => $this->_em->getEntityPersister('CmsUser'), 'parent' => null, 'relation' => null, 'map' => null, 'agg' => array('0' => 'nameUpper') ), 'p' => array( - 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsPhonenumber'), - 'mapper' => $this->sharedFixture['connection']->getMapper('CmsPhonenumber'), + 'table' => $this->_em->getClassMetadata('CmsPhonenumber'), + 'mapper' => $this->_em->getEntityPersister('CmsPhonenumber'), 'parent' => 'u', - 'relation' => $this->sharedFixture['connection']->getClassMetadata('CmsUser')->getRelation('phonenumbers'), + 'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('phonenumbers'), 'map' => null ), 'a' => array( - 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsArticle'), - 'mapper' => $this->sharedFixture['connection']->getMapper('CmsArticle'), + 'table' => $this->_em->getClassMetadata('CmsArticle'), + 'mapper' => $this->_em->getEntityPersister('CmsArticle'), 'parent' => 'u', - 'relation' => $this->sharedFixture['connection']->getClassMetadata('CmsUser')->getRelation('articles'), + 'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('articles'), 'map' => null ), 'c' => array( - 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsComment'), - 'mapper' => $this->sharedFixture['connection']->getMapper('CmsComment'), + 'table' => $this->_em->getClassMetadata('CmsComment'), + 'mapper' => $this->_em->getEntityPersister('CmsComment'), 'parent' => 'a', - 'relation' => $this->sharedFixture['connection']->getClassMetadata('CmsArticle')->getRelation('comments'), + 'relation' => $this->_em->getClassMetadata('CmsArticle')->getRelation('comments'), 'map' => null ), ); @@ -719,17 +721,17 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase // Faked query components $queryComponents = array( 'c' => array( - 'table' => $this->sharedFixture['connection']->getClassMetadata('ForumCategory'), - 'mapper' => $this->sharedFixture['connection']->getMapper('ForumCategory'), + 'table' => $this->_em->getClassMetadata('ForumCategory'), + 'mapper' => $this->_em->getEntityPersister('ForumCategory'), 'parent' => null, 'relation' => null, 'map' => null ), 'b' => array( - 'table' => $this->sharedFixture['connection']->getClassMetadata('ForumBoard'), - 'mapper' => $this->sharedFixture['connection']->getMapper('ForumBoard'), + 'table' => $this->_em->getClassMetadata('ForumBoard'), + 'mapper' => $this->_em->getEntityPersister('ForumBoard'), 'parent' => 'c', - 'relation' => $this->sharedFixture['connection']->getClassMetadata('ForumCategory')->getRelation('boards'), + 'relation' => $this->_em->getClassMetadata('ForumCategory')->getRelation('boards'), 'map' => null ), ); diff --git a/tests/Orm/UnitOfWorkTestCase.php b/tests/Orm/UnitOfWorkTestCase.php index 178496560..b03efda2e 100644 --- a/tests/Orm/UnitOfWorkTestCase.php +++ b/tests/Orm/UnitOfWorkTestCase.php @@ -8,8 +8,9 @@ class Orm_UnitOfWorkTestCase extends Doctrine_OrmTestCase protected function setUp() { parent::setUp(); + $em = new Doctrine_EntityManager(new Doctrine_Connection_Mock()); $this->_user = new ForumUser(); - $this->_unitOfWork = $this->sharedFixture['connection']->unitOfWork; + $this->_unitOfWork = $em->getUnitOfWork(); } protected function tearDown() { diff --git a/tests/lib/DoctrineTestInit.php b/tests/lib/DoctrineTestInit.php index dc328f7d5..c535848fd 100644 --- a/tests/lib/DoctrineTestInit.php +++ b/tests/lib/DoctrineTestInit.php @@ -5,8 +5,10 @@ require_once 'Doctrine_TestCase.php'; require_once 'Doctrine_TestUtil.php'; require_once 'Doctrine_DbalTestCase.php'; require_once 'Doctrine_OrmTestCase.php'; +require_once 'Doctrine_OrmFunctionalTestCase.php'; require_once 'Doctrine_TestSuite.php'; require_once 'Doctrine_OrmTestSuite.php'; +require_once 'Doctrine_OrmFunctionalTestSuite.php'; require_once 'Doctrine_DbalTestSuite.php'; require_once '../lib/Doctrine.php'; diff --git a/tests/lib/Doctrine_OrmTestCase.php b/tests/lib/Doctrine_OrmTestCase.php index dabbd720e..3b2fbd9f5 100644 --- a/tests/lib/Doctrine_OrmTestCase.php +++ b/tests/lib/Doctrine_OrmTestCase.php @@ -5,118 +5,5 @@ */ class Doctrine_OrmTestCase extends Doctrine_TestCase { - /** - * The currently loaded model names of the fixtures for the testcase. - */ - private $_loadedFixtures = array(); - /** - * All loaded fixtures during test execution. Common fixture cache. - */ - private static $_fixtures = array(); - - /** - * The names of all tables that were already exported. Each table is exported - * only once. Then it's just filled & erased for each testmethod in a testcase - * that uses one or more fixtures. - */ - private static $_exportedTables = array(); - - /** - * setUp() - * - * Note: This setUp() and the one of DbalTestCase currently look identical. However, - * please dont pull this method up. In the future with a separation of Dbal/Orm - * this setUp() will take care of a ORM connection/session/manager initialization - * and the DBAL setUp() will take care of just a DBAL connection. - */ - protected function setUp() - { - // Setup a db connection if there is none, yet. This makes it possible - // to run tests that use a connection standalone. - if ( ! isset($this->sharedFixture['connection'])) { - $this->sharedFixture['connection'] = Doctrine_TestUtil::getConnection(); - } - } - - /** - * Loads a data fixture into the database. This method must only be called - * from within the setUp() method of testcases. The database will then be - * populated with fresh data of all loaded fixtures for each test method. - * - * WARNING: A single testcase should never load fixtures from different scenarios of - * the same package as the concistency and uniqueness of keys is not guaranteed. - * - * @param string $package The package name. Must be one of Doctrine's test model packages - * (forum, cms or ecommerce). - * @param string $scenario The fixture scenario. A model package can have many fixture - * scenarios. Within a scenario all primary keys and foreign keys - * of fixtures are consistent and unique. - * @param string $name The name of the fixture to load from the specified package. - */ - protected function loadFixture($package, $scenario, $name) - { - $uniqueName = $package . '/' . $scenario . '/' . $name; - - if ( ! isset(self::$_fixtures[$uniqueName])) { - // load fixture file - $fixtureFile = 'fixtures' - . DIRECTORY_SEPARATOR . $package - . DIRECTORY_SEPARATOR . $scenario - . DIRECTORY_SEPARATOR . $name - . '.php'; - require $fixtureFile; - self::$_fixtures[$uniqueName] = $fixture; - } - - $fixture = self::$_fixtures[$uniqueName]; - $this->_loadedFixtures[] = $fixture['model']; - - $conn = $this->sharedFixture['connection']; - $classMetadata = $conn->getClassMetadata($fixture['model']); - $tableName = $classMetadata->getTableName(); - - if ( ! in_array($tableName, self::$_exportedTables)) { - $conn->export->exportClasses(array($fixture['model'])); - self::$_exportedTables[] = $tableName; - } - - foreach ($fixture['rows'] as $row) { - $conn->insert($tableName, $row); - } - } - - /** - * Loads multiple fixtures of the same package and scenario. - * This method must only be called from within the setUp() method of testcases. - * The database will then be populated with fresh data of all loaded fixtures for each - * test method. - * - * WARNING: A single testcase should never load fixtures from different scenarios of - * the same package as the concistency and uniqueness of keys is not guaranteed. - * - * @param string $package The package name. Must be one of Doctrine's test model packages - * (forum, cms or ecommerce). - * @param string $scenario The fixture scenario. A model package can have many fixture - * scenarios. Within a scenario all primary keys and foreign keys - * of fixtures are consistent and unique. - * @param array $names The names of the fixtures to load from the specified package. - */ - protected function loadFixtures($package, $scenario, array $names) - { - foreach ($names as $name) { - $this->loadFixture($package, $scenario, $name); - } - } - - /** - * Sweeps the database tables of all used fixtures. - */ - protected function tearDown() - { - $conn = $this->sharedFixture['connection']; - foreach (array_reverse($this->_loadedFixtures) as $model) { - $conn->exec("DELETE FROM " . $conn->getClassMetadata($model)->getTableName()); - } - } } \ No newline at end of file diff --git a/tests/lib/Doctrine_OrmTestSuite.php b/tests/lib/Doctrine_OrmTestSuite.php index 7d5a41ae3..6d01925c4 100644 --- a/tests/lib/Doctrine_OrmTestSuite.php +++ b/tests/lib/Doctrine_OrmTestSuite.php @@ -8,11 +8,5 @@ */ class Doctrine_OrmTestSuite extends Doctrine_TestSuite { - protected function setUp() - { - $this->sharedFixture['connection'] = Doctrine_TestUtil::getConnection(); - } - - protected function tearDown() - {} + } \ No newline at end of file diff --git a/tests/models/cms/CmsUser.php b/tests/models/cms/CmsUser.php index 1c372db49..760049975 100644 --- a/tests/models/cms/CmsUser.php +++ b/tests/models/cms/CmsUser.php @@ -4,6 +4,7 @@ class CmsUser extends Doctrine_Entity public static function initMetadata($class) { $class->mapColumn('id', 'integer', 4, array('primary' => true, 'autoincrement' => true)); + $class->mapColumn('status', 'string', 50); $class->mapColumn('username', 'string', 255); $class->mapColumn('name', 'string', 255);