From 00599a80d422f83b3693684966fbfe80164d65fe Mon Sep 17 00:00:00 2001 From: romanb Date: Mon, 3 Aug 2009 13:25:56 +0000 Subject: [PATCH] [2.0] Streamlined result structures. Hydration improvements: Small overall improvements, large improvement for (joined) fetched collections (~60%). --- lib/Doctrine/Common/Cache/ApcCache.php | 10 -- lib/Doctrine/Common/Cache/MemcacheCache.php | 10 -- lib/Doctrine/Common/Cache/XcacheCache.php | 10 -- .../Common/Collections/ArrayCollection.php | 45 +++++---- .../Common/Collections/Collection.php | 46 +++++++--- lib/Doctrine/DBAL/Types/DateTimeType.php | 2 +- lib/Doctrine/DBAL/Types/TimeType.php | 2 +- lib/Doctrine/ORM/AbstractQuery.php | 8 +- .../Internal/Hydration/AbstractHydrator.php | 2 +- .../ORM/Internal/Hydration/ArrayHydrator.php | 4 +- .../ORM/Internal/Hydration/ObjectHydrator.php | 79 +++++----------- .../ORM/Internal/Hydration/ScalarHydrator.php | 2 +- .../ORM/Mapping/ClassMetadataFactory.php | 1 - lib/Doctrine/ORM/PersistentCollection.php | 28 ++++-- lib/Doctrine/ORM/Query.php | 4 +- lib/Doctrine/ORM/Query/ResultSetMapping.php | 92 ++++++++++--------- .../Common/Collections/CollectionTest.php | 4 +- .../ORM/Functional/BasicFunctionalTest.php | 6 +- .../Tests/ORM/Functional/QueryCacheTest.php | 4 +- .../ORM/Hydration/ObjectHydratorTest.php | 1 + .../ORM/Hydration/ResultSetMappingTest.php | 2 +- .../Performance/HydrationPerformanceTest.php | 6 +- .../Tests/ORM/PersistentCollectionTest.php | 9 +- 23 files changed, 185 insertions(+), 192 deletions(-) diff --git a/lib/Doctrine/Common/Cache/ApcCache.php b/lib/Doctrine/Common/Cache/ApcCache.php index 53a4bc844..1ee31410b 100644 --- a/lib/Doctrine/Common/Cache/ApcCache.php +++ b/lib/Doctrine/Common/Cache/ApcCache.php @@ -33,16 +33,6 @@ namespace Doctrine\Common\Cache; */ class ApcCache implements Cache { - /** - * {@inheritdoc} - */ - public function __construct() - { - if ( ! extension_loaded('apc')) { - \Doctrine\Common\DoctrineException::updateMe('The apc extension must be loaded in order to use the ApcCache.'); - } - } - /** * {@inheritdoc} */ diff --git a/lib/Doctrine/Common/Cache/MemcacheCache.php b/lib/Doctrine/Common/Cache/MemcacheCache.php index 06984ff44..8525231f2 100644 --- a/lib/Doctrine/Common/Cache/MemcacheCache.php +++ b/lib/Doctrine/Common/Cache/MemcacheCache.php @@ -39,16 +39,6 @@ class MemcacheCache implements Cache */ private $_memcache; - /** - * {@inheritdoc} - */ - public function __construct() - { - if ( ! extension_loaded('memcache')) { - throw \Doctrine\Common\DoctrineException::updateMe('In order to use Memcache driver, the memcache extension must be loaded.'); - } - } - /** * Sets the memcache instance to use. * diff --git a/lib/Doctrine/Common/Cache/XcacheCache.php b/lib/Doctrine/Common/Cache/XcacheCache.php index 207fb29d7..c788f0535 100644 --- a/lib/Doctrine/Common/Cache/XcacheCache.php +++ b/lib/Doctrine/Common/Cache/XcacheCache.php @@ -32,16 +32,6 @@ namespace Doctrine\Common\Cache; */ class XcacheCache implements Cache { - /** - * {@inheritdoc} - */ - public function __construct() - { - if ( ! extension_loaded('xcache')) { - throw \Doctrine\Common\DoctrineException::updateMe('In order to use Xcache driver, the xcache extension must be loaded.'); - } - } - /** * {@inheritdoc} */ diff --git a/lib/Doctrine/Common/Collections/ArrayCollection.php b/lib/Doctrine/Common/Collections/ArrayCollection.php index c1167127d..abf3fbc65 100644 --- a/lib/Doctrine/Common/Collections/ArrayCollection.php +++ b/lib/Doctrine/Common/Collections/ArrayCollection.php @@ -24,8 +24,8 @@ namespace Doctrine\Common\Collections; use \Closure, \ArrayIterator; /** - * A Collection is a thin wrapper around a php array. Like a php array it is essentially - * an ordered map. + * An ArrayCollection is a Collection implementation that uses a regular PHP array + * internally. * * @author Roman S. Borschel * @since 2.0 @@ -34,7 +34,7 @@ class ArrayCollection implements Collection { /** * An array containing the entries of this collection. - * This is the wrapped php array. + * This is the internal php array. * * @var array */ @@ -49,24 +49,20 @@ class ArrayCollection implements Collection { $this->_elements = $elements; } - - /** - * Unwraps the array contained in the Collection instance. - * - * @return array The wrapped array. - */ - public function unwrap() - { - return $this->_elements; - } + /** + * Gets the PHP array representation of this collection. + * + * @return array The PHP array representation of this collection. + */ public function toArray() { return $this->_elements; } /** - * Gets the first element in the collection. + * Sets the internal iterator to the first element in the collection and + * returns this element. * * @return mixed */ @@ -76,7 +72,8 @@ class ArrayCollection implements Collection } /** - * Gets the last element in the collection. + * Sets the internal iterator to the last element in the collection and + * returns this element. * * @return mixed */ @@ -86,7 +83,7 @@ class ArrayCollection implements Collection } /** - * Gets the current key. + * Gets the current key/index at the current internal iterator position. * * @return mixed */ @@ -94,6 +91,22 @@ class ArrayCollection implements Collection { return key($this->_elements); } + + /** + * Moves the internal iterator position to the next element. + */ + public function next() + { + next($this->_elements); + } + + /** + * Gets the element of the collection at the current internal iterator position. + */ + public function current() + { + return current($this->_elements); + } /** * Removes an element with a specific key/index from the collection. diff --git a/lib/Doctrine/Common/Collections/Collection.php b/lib/Doctrine/Common/Collections/Collection.php index 0e71bc55b..b2e42c0b7 100644 --- a/lib/Doctrine/Common/Collections/Collection.php +++ b/lib/Doctrine/Common/Collections/Collection.php @@ -4,10 +4,22 @@ namespace Doctrine\Common\Collections; /** * The missing (SPL) Collection/Array interface. + * * A Collection resembles the nature of a regular PHP array. That is, * it is essentially an ordered map that can syntactically also be used * like a list. * + * A Collection has an internal iterator just like a PHP array. In addition + * a Collection can be iterated with external iterators, which is preferrable. + * To use an external iterator simply use the foreach language construct to + * iterator over the collection (which canns getIterator() internally) or + * explicitly retrieve an iterator though getIterator() which can then be + * used to iterate over the collection. + * + * You can not rely on the internal iterator of the collection being at a certain + * position unless you explicitly positioned it before. Prefer iteration with + * external iterators. + * * @author Roman Borschel * @since 2.0 */ @@ -99,13 +111,6 @@ interface Collection extends \Countable, \IteratorAggregate, \ArrayAccess */ function set($key, $value); - /** - * Counts the elements in the collection. - * - * @return integer The number of elements in the collection. - */ - //function count(); - /** * Gets a plain PHP array representation of the collection. * @@ -114,16 +119,33 @@ interface Collection extends \Countable, \IteratorAggregate, \ArrayAccess function toArray(); /** - * Gets the first element of the collection. - * + * Sets the internal iterator to the first element in the collection and + * returns this element. + * * @return mixed */ function first(); /** - * Gets the last element of the collection. - * + * Sets the internal iterator to the last element in the collection and + * returns this element. + * * @return mixed */ - function last(); + function last(); + + /** + * Gets the key/index of the element at the current iterator position. + */ + function key(); + + /** + * Gets the element of the collection at the current iterator position. + */ + function current(); + + /** + * Moves the internal iterator position to the next element. + */ + function next(); } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Types/DateTimeType.php b/lib/Doctrine/DBAL/Types/DateTimeType.php index 50d9a2c04..ee2475624 100644 --- a/lib/Doctrine/DBAL/Types/DateTimeType.php +++ b/lib/Doctrine/DBAL/Types/DateTimeType.php @@ -5,7 +5,7 @@ namespace Doctrine\DBAL\Types; use Doctrine\DBAL\Platforms\AbstractPlatform; /** - * Type that maps an SQL DATETIME to a PHP DateTime object. + * Type that maps an SQL DATETIME/TIMESTAMP to a PHP DateTime object. * * @since 2.0 */ diff --git a/lib/Doctrine/DBAL/Types/TimeType.php b/lib/Doctrine/DBAL/Types/TimeType.php index ddd13be41..8256a5570 100644 --- a/lib/Doctrine/DBAL/Types/TimeType.php +++ b/lib/Doctrine/DBAL/Types/TimeType.php @@ -5,7 +5,7 @@ namespace Doctrine\DBAL\Types; use Doctrine\DBAL\Platforms\AbstractPlatform; /** - * Type that maps an SQL DATETIME to a PHP Date object. + * Type that maps an SQL TIME to a PHP DateTime object. * * @since 2.0 */ diff --git a/lib/Doctrine/ORM/AbstractQuery.php b/lib/Doctrine/ORM/AbstractQuery.php index 95c383051..3cf0fae1e 100644 --- a/lib/Doctrine/ORM/AbstractQuery.php +++ b/lib/Doctrine/ORM/AbstractQuery.php @@ -305,7 +305,8 @@ abstract class AbstractQuery * * Alias for execute(array(), HYDRATE_OBJECT). * - * @return Collection + * @return array + * @todo getResult() */ public function getResultList() { @@ -318,6 +319,7 @@ abstract class AbstractQuery * Alias for execute(array(), HYDRATE_ARRAY). * * @return array + * @todo getArrayResult() */ public function getResultArray() { @@ -449,12 +451,12 @@ abstract class AbstractQuery $stmt, $this->_resultSetMapping, $this->_hints ); - $cacheDriver->save($hash, serialize($result), $this->_resultCacheTTL); + $cacheDriver->save($hash, $result, $this->_resultCacheTTL); return $result; } else { // Cache hit. - return unserialize($cached); + return $cached; } } diff --git a/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php index 8c70f4481..6a05e5c1a 100644 --- a/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php +++ b/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php @@ -149,7 +149,7 @@ abstract class AbstractHydrator * @param array $cache The cache to use. * @param mixed $result The result to fill. */ - protected function _hydrateRow(array &$data, array &$cache, &$result) + protected function _hydrateRow(array &$data, array &$cache, array &$result) { throw new DoctrineException("_hydrateRow() not implemented by this hydrator."); } diff --git a/lib/Doctrine/ORM/Internal/Hydration/ArrayHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/ArrayHydrator.php index 495135c43..f7ec56491 100644 --- a/lib/Doctrine/ORM/Internal/Hydration/ArrayHydrator.php +++ b/lib/Doctrine/ORM/Internal/Hydration/ArrayHydrator.php @@ -67,7 +67,7 @@ class ArrayHydrator extends AbstractHydrator } /** @override */ - protected function _hydrateRow(array &$data, array &$cache, &$result) + protected function _hydrateRow(array &$data, array &$cache, array &$result) { // 1) Initialize $id = $this->_idTemplate; // initialize the id-memory @@ -201,7 +201,7 @@ class ArrayHydrator extends AbstractHydrator * @param string $dqlAlias * @param boolean $oneToOne Whether it is a single-valued association or not. */ - private function updateResultPointer(&$coll, $index, $dqlAlias, $oneToOne) + private function updateResultPointer(array &$coll, $index, $dqlAlias, $oneToOne) { if ($coll === null) { unset($this->_resultPointers[$dqlAlias]); // Ticket #1228 diff --git a/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php index c13f8d107..d97c22377 100644 --- a/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php +++ b/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php @@ -114,8 +114,7 @@ class ObjectHydrator extends AbstractHydrator */ protected function _hydrateAll() { - $result = $this->_rsm->isMixed ? array() : new ArrayCollection; - + $result = array(); $cache = array(); while ($data = $this->_stmt->fetch(Connection::FETCH_ASSOC)) { $this->_hydrateRow($data, $cache, $result); @@ -130,33 +129,6 @@ class ObjectHydrator extends AbstractHydrator return $result; } - /** - * Updates the result pointer for an entity. The result pointers point to the - * last seen instance of each entity type. This is used for graph construction. - * - * @param Collection $coll The element. - * @param boolean|integer $index Index of the element in the collection. - * @param string $dqlAlias - */ - private function updateResultPointer(&$coll, $index, $dqlAlias) - { - if ($index !== false) { - $this->_resultPointers[$dqlAlias] = $coll[$index]; - return; - } - - if ( ! is_object($coll)) { - end($coll); - $this->_resultPointers[$dqlAlias] =& $coll[key($coll)]; - } else if ($coll instanceof Collection) { - //if ( ! $coll->isEmpty()) { - $this->_resultPointers[$dqlAlias] = $coll->last(); - //} - } else { - $this->_resultPointers[$dqlAlias] = $coll; - } - } - /** * Initializes a related collection. * @@ -179,25 +151,6 @@ class ObjectHydrator extends AbstractHydrator return $pColl; } - - /** - * Gets the last key of a collection/array. - * - * @param Collection|array $coll - * @return string|integer - */ - private function getLastKey($coll) - { - // Check needed because of mixed results. - // is_object instead of is_array because is_array is slow on large arrays. - if (is_object($coll)) { - $coll->last(); - return $coll->key(); - } else { - end($coll); - return key($coll); - } - } /** * Gets an entity instance. @@ -280,7 +233,7 @@ class ObjectHydrator extends AbstractHydrator * * @override */ - protected function _hydrateRow(array &$data, array &$cache, &$result) + protected function _hydrateRow(array &$data, array &$cache, array &$result) { // 1) Initialize $id = $this->_idTemplate; // initialize the id-memory @@ -368,7 +321,8 @@ class ObjectHydrator extends AbstractHydrator $reflFieldValue->hydrateAdd($element); } - $this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]] = $this->getLastKey($reflFieldValue); + $reflFieldValue->last(); + $this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]] = $reflFieldValue->key(); } } else if ( ! $reflFieldValue) { $coll = new PersistentCollection($this->_em, $this->_ce[$entityName], new ArrayCollection); @@ -377,7 +331,9 @@ class ObjectHydrator extends AbstractHydrator $this->_uow->setOriginalEntityProperty($oid, $relationField, $coll); } - $this->updateResultPointer($reflFieldValue, $index, $dqlAlias); + // Update result pointer + $this->_resultPointers[$dqlAlias] = $index === false ? + $reflFieldValue->last() : $reflFieldValue[$index]; } else { // Single-valued association $reflFieldValue = $reflField->getValue($baseElement); @@ -403,8 +359,9 @@ class ObjectHydrator extends AbstractHydrator } } + // Update result pointer if ($reflFieldValue !== null) { - $this->updateResultPointer($reflFieldValue, $index, $dqlAlias); + $this->_resultPointers[$dqlAlias] = $reflFieldValue; } } } else { @@ -423,23 +380,29 @@ class ObjectHydrator extends AbstractHydrator ); ++$this->_resultCounter; } else { - $result->set($element, $this->_ce[$entityName] + $result[$this->_ce[$entityName] ->reflFields[$field] - ->getValue($element)); + ->getValue($element)] = $element; } } else { if ($this->_rsm->isMixed) { $result[] = array($element); ++$this->_resultCounter; } else { - $result->add($element); + $result[] = $element; } } - $this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = $this->getLastKey($result); + + $last = end($result); + $this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = key($result); + + // Update result pointer + $this->_resultPointers[$dqlAlias] = $last; } else { + // Update result pointer $index = $this->_identifierMap[$dqlAlias][$id[$dqlAlias]]; + $this->_resultPointers[$dqlAlias] = $result[$index]; } - $this->updateResultPointer($result, $index, $dqlAlias); } } @@ -454,6 +417,6 @@ class ObjectHydrator extends AbstractHydrator /** {@inheritdoc} */ protected function _getRowContainer() { - return new \Doctrine\Common\Collections\ArrayCollection; + return array(); } } diff --git a/lib/Doctrine/ORM/Internal/Hydration/ScalarHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/ScalarHydrator.php index 612352406..762933c53 100644 --- a/lib/Doctrine/ORM/Internal/Hydration/ScalarHydrator.php +++ b/lib/Doctrine/ORM/Internal/Hydration/ScalarHydrator.php @@ -45,7 +45,7 @@ class ScalarHydrator extends AbstractHydrator } /** @override */ - protected function _hydrateRow(array &$data, array &$cache, &$result) + protected function _hydrateRow(array &$data, array &$cache, array &$result) { $result[] = $this->_gatherScalarRowData($data, $cache); } diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php index ca0c85e28..903c69f4c 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -35,7 +35,6 @@ use Doctrine\Common\DoctrineException, * @version $Revision$ * @link www.doctrine-project.org * @since 2.0 - * @todo Support for mapped superclasses (@MappedSuperclass) */ class ClassMetadataFactory { diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/lib/Doctrine/ORM/PersistentCollection.php index 0f4040f4f..4bbe69ac5 100644 --- a/lib/Doctrine/ORM/PersistentCollection.php +++ b/lib/Doctrine/ORM/PersistentCollection.php @@ -33,9 +33,6 @@ use Doctrine\Common\DoctrineException, * entities from the collection, only the links in the relation table are removed (on flush). * Similarly, if you remove entities from a collection that is part of a one-many * mapping this will only result in the nulling out of the foreign keys on flush. - * If you want entities in a one-many collection to be removed when - * they're removed from the collection, use deleteOrphans => true on the one-many - * mapping. * * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @since 2.0 @@ -224,7 +221,7 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect */ public function takeSnapshot() { - $this->_snapshot = $this->_coll->unwrap(); + $this->_snapshot = $this->_coll->toArray(); } /** @@ -246,7 +243,7 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect */ public function getDeleteDiff() { - return array_udiff($this->_snapshot, $this->_coll->unwrap(), array($this, '_compareRecords')); + return array_udiff($this->_snapshot, $this->_coll->toArray(), array($this, '_compareRecords')); } /** @@ -256,7 +253,7 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect */ public function getInsertDiff() { - return array_udiff($this->_coll->unwrap(), $this->_snapshot, array($this, '_compareRecords')); + return array_udiff($this->_coll->toArray(), $this->_snapshot, array($this, '_compareRecords')); } /** @@ -593,6 +590,25 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect return $this->_coll->key(); } + /** + * Gets the element of the collection at the current iterator position. + */ + public function current() + { + return $this->_coll->current(); + } + + /** + * Moves the internal iterator position to the next element. + */ + public function next() + { + return $this->_coll->next(); + } + + /** + * Retrieves the wrapped Collection instance. + */ public function unwrap() { return $this->_coll; diff --git a/lib/Doctrine/ORM/Query.php b/lib/Doctrine/ORM/Query.php index d6ab24cec..403f9488f 100644 --- a/lib/Doctrine/ORM/Query.php +++ b/lib/Doctrine/ORM/Query.php @@ -175,10 +175,10 @@ final class Query extends AbstractQuery if ($cached === false) { // Cache miss. $executor = $this->_parse()->getSqlExecutor(); - $queryCache->save($hash, serialize($this->_parserResult), null); + $queryCache->save($hash, $this->_parserResult, null); } else { // Cache hit. - $this->_parserResult = unserialize($cached); + $this->_parserResult = $cached; $executor = $this->_parserResult->getSqlExecutor(); } } else { diff --git a/lib/Doctrine/ORM/Query/ResultSetMapping.php b/lib/Doctrine/ORM/Query/ResultSetMapping.php index 607619e5a..247de1397 100644 --- a/lib/Doctrine/ORM/Query/ResultSetMapping.php +++ b/lib/Doctrine/ORM/Query/ResultSetMapping.php @@ -62,9 +62,11 @@ class ResultSetMapping //public $ignoredColumns = array(); /** + * Adds an entity result to this ResultSetMapping. * - * @param string $class The class name. - * @param string $alias The alias for this class. The alias must be unique within this ResultSetMapping. + * @param string $class The class name of the entity. + * @param string $alias The alias for the class. The alias must be unique among all entity + * results or joined entity results within this ResultSetMapping. */ public function addEntityResult($class, $alias) { @@ -72,9 +74,13 @@ class ResultSetMapping } /** + * Sets a discriminator column for an entity result or joined entity result. + * The discriminator column will be used to determine the concrete class name to + * instantiate. * - * @param string $alias - * @param string $discrColumn + * @param string $alias The alias of the entity result or joined entity result the discriminator + * column should be used for. + * @param string $discrColumn The name of the discriminator column in the SQL result set. */ public function setDiscriminatorColumn($alias, $discrColumn) { @@ -83,20 +89,10 @@ class ResultSetMapping } /** + * Sets a field to use for indexing an entity result or joined entity result. * - * @param string $className - * @return string - */ - public function getDiscriminatorColumn($className) - { - return isset($this->discriminatorColumns[$className]) ? - $this->discriminatorColumns[$className] : null; - } - - /** - * - * @param string $alias - * @param string $fieldName + * @param string $alias The alias of an entity result or joined entity result. + * @param string $fieldName The name of the field to use for indexing. */ public function addIndexBy($alias, $fieldName) { @@ -104,6 +100,8 @@ class ResultSetMapping } /** + * Checks whether an entity result or joined entity result with a given alias has + * a field set for indexing. * * @param string $alias * @return boolean @@ -114,18 +112,10 @@ class ResultSetMapping } /** + * Checks whether the column with the given name is mapped as a field result + * as part of an entity result or joined entity result. * - * @param string $alias - * @return string - */ - public function getIndexByField($alias) - { - return $this->indexByMap[$alias]; - } - - /** - * - * @param string $columnName + * @param string $columnName The name of the column in the SQL result set. * @return boolean */ public function isFieldResult($columnName) @@ -134,10 +124,11 @@ class ResultSetMapping } /** + * Adds a field result that is part of an entity result or joined entity result. * - * @param string $alias - * @param string $columnName - * @param string $fieldName + * @param string $alias The alias of the entity result or joined entity result. + * @param string $columnName The name of the column in the SQL result set. + * @param string $fieldName The name of the field on the (joined) entity. */ public function addFieldResult($alias, $columnName, $fieldName) { @@ -149,11 +140,12 @@ class ResultSetMapping } /** + * Adds a joined entity result. * - * @param string $class - * @param string $alias - * @param string $parentAlias - * @param object $relation + * @param string $class The class name of the joined entity. + * @param string $alias The unique alias to use for the joined entity. + * @param string $parentAlias The alias of the entity result that is the parent of this joined result. + * @param object $relation The association that connects the parent entity result with the joined entity result. */ public function addJoinedEntityResult($class, $alias, $parentAlias, $relation) { @@ -163,9 +155,10 @@ class ResultSetMapping } /** + * Adds a scalar result mapping. * - * @param string $columnName - * @param string $alias + * @param string $columnName The name of the column in the SQL result set. + * @param string $alias The field alias with which the scalar result should be placed in the result structure. */ public function addScalarResult($columnName, $alias) { @@ -176,6 +169,9 @@ class ResultSetMapping } /** + * Checks whether a column with a given name is mapped as a scalar result. + * + * @param string $columName The name of the column in the SQL result set. * @return boolean */ public function isScalarResult($columnName) @@ -184,18 +180,21 @@ class ResultSetMapping } /** + * Gets the name of the class of an entity result or joined entity result, + * identified by the given unique alias. * - * @param $alias + * @param string $alias + * @return string */ - public function getClass($alias) + public function getClassName($alias) { return $this->aliasMap[$alias]; } /** - * Gets the alias for a column that is mapped as a scalar value. + * Gets the field alias for a column that is mapped as a scalar value. * - * @param string $columnName + * @param string $columnName The name of the column in the SQL result set. * @return string */ public function getScalarAlias($columnName) @@ -204,9 +203,10 @@ class ResultSetMapping } /** - * Gets the class that owns the specified column. + * Gets the name of the class that owns a field mapping for the specified column. * * @param string $columnName + * @return string */ public function getOwningClass($columnName) { @@ -234,9 +234,10 @@ class ResultSetMapping } /** + * Gets the alias of the class that owns a field mapping for the specified column. * - * @param $columnName - * @return + * @param string $columnName + * @return string */ public function getEntityAlias($columnName) { @@ -244,6 +245,7 @@ class ResultSetMapping } /** + * Gets the parent alias of the given alias. * * @param string $alias * @return string @@ -254,6 +256,7 @@ class ResultSetMapping } /** + * Checks whether the given alias has a parent alias. * * @param string $alias * @return boolean @@ -284,6 +287,7 @@ class ResultSetMapping } /** + * Gets the number of different entities that appear in the mapped result. * * @return integer */ diff --git a/tests/Doctrine/Tests/Common/Collections/CollectionTest.php b/tests/Doctrine/Tests/Common/Collections/CollectionTest.php index ff4fdc490..4e642905f 100644 --- a/tests/Doctrine/Tests/Common/Collections/CollectionTest.php +++ b/tests/Doctrine/Tests/Common/Collections/CollectionTest.php @@ -50,7 +50,7 @@ class CollectionTest extends \Doctrine\Tests\DoctrineTestCase $this->_coll->add(1); $this->_coll->add(2); $res = $this->_coll->map(function($e) { return $e * 2; }); - $this->assertEquals(array(2, 4), $res->unwrap()); + $this->assertEquals(array(2, 4), $res->toArray()); } public function testFilter() @@ -59,7 +59,7 @@ class CollectionTest extends \Doctrine\Tests\DoctrineTestCase $this->_coll->add("foo"); $this->_coll->add(3); $res = $this->_coll->filter(function($e) { return is_numeric($e); }); - $this->assertEquals(array(0 => 1, 2 => 3), $res->unwrap()); + $this->assertEquals(array(0 => 1, 2 => 3), $res->toArray()); } public function testFirstAndLast() diff --git a/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php b/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php index 17637fdeb..0277c69e0 100644 --- a/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php @@ -225,7 +225,7 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase $users = $query->getResultList(); - $this->assertEquals(1, $users->count()); + $this->assertEquals(1, count($users)); $this->assertEquals('Guilherme', $users[0]->name); $this->assertEquals('gblanco', $users[0]->username); $this->assertEquals('developer', $users[0]->status); @@ -262,7 +262,7 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase $users = $query->getResultList(); - $this->assertEquals(0, $users->count()); + $this->assertEquals(0, count($users)); } public function testBasicOneToManyLeftJoin() @@ -278,7 +278,7 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase $users = $query->getResultList(); - $this->assertEquals(1, $users->count()); + $this->assertEquals(1, count($users)); $this->assertEquals('Guilherme', $users[0]->name); $this->assertEquals('gblanco', $users[0]->username); $this->assertEquals('developer', $users[0]->status); diff --git a/tests/Doctrine/Tests/ORM/Functional/QueryCacheTest.php b/tests/Doctrine/Tests/ORM/Functional/QueryCacheTest.php index 68e21bd5d..4b0c9aa7c 100644 --- a/tests/Doctrine/Tests/ORM/Functional/QueryCacheTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/QueryCacheTest.php @@ -21,6 +21,8 @@ class QueryCacheTest extends \Doctrine\Tests\OrmFunctionalTestCase public function testQueryCache() { + $this->_em->getConfiguration()->setQueryCacheImpl(null); + $user = new CmsUser; $user->name = 'Roman'; $user->username = 'romanb'; @@ -47,7 +49,7 @@ class QueryCacheTest extends \Doctrine\Tests\OrmFunctionalTestCase $query2->setQueryCacheDriver($cache); $users = $query2->getResultList(); - + $this->assertEquals(1, $cache->count()); $this->assertTrue($cache->contains(md5('select ux from Doctrine\Tests\Models\CMS\CmsUser uxDOCTRINE_QUERY_CACHE_SALT'))); $this->assertEquals(1, count($users)); diff --git a/tests/Doctrine/Tests/ORM/Hydration/ObjectHydratorTest.php b/tests/Doctrine/Tests/ORM/Hydration/ObjectHydratorTest.php index c06ae69f2..f1fd95627 100644 --- a/tests/Doctrine/Tests/ORM/Hydration/ObjectHydratorTest.php +++ b/tests/Doctrine/Tests/ORM/Hydration/ObjectHydratorTest.php @@ -677,6 +677,7 @@ class ObjectHydratorTest extends HydrationTestCase $this->assertEquals(2, count($result)); $this->assertTrue($result[0] instanceof \Doctrine\Tests\Models\Forum\ForumCategory); $this->assertTrue($result[1] instanceof \Doctrine\Tests\Models\Forum\ForumCategory); + $this->assertTrue($result[0] !== $result[1]); $this->assertEquals(1, $result[0]->getId()); $this->assertEquals(2, $result[1]->getId()); $this->assertTrue(isset($result[0]->boards)); diff --git a/tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php b/tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php index 8f7d2930b..8155dbd51 100644 --- a/tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php +++ b/tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php @@ -42,7 +42,7 @@ class ResultSetMappingTest extends \Doctrine\Tests\OrmTestCase $this->assertFalse($this->_rsm->isScalarResult('username')); $this->assertFalse($this->_rsm->isScalarResult('name')); - $this->assertTrue($this->_rsm->getClass('u') == 'Doctrine\Tests\Models\CMS\CmsUser'); + $this->assertTrue($this->_rsm->getClassName('u') == 'Doctrine\Tests\Models\CMS\CmsUser'); $class = $this->_rsm->getOwningClass('id'); $this->assertTrue($class == 'Doctrine\Tests\Models\CMS\CmsUser'); diff --git a/tests/Doctrine/Tests/ORM/Performance/HydrationPerformanceTest.php b/tests/Doctrine/Tests/ORM/Performance/HydrationPerformanceTest.php index 57f6bb45f..9d01b88b7 100644 --- a/tests/Doctrine/Tests/ORM/Performance/HydrationPerformanceTest.php +++ b/tests/Doctrine/Tests/ORM/Performance/HydrationPerformanceTest.php @@ -206,9 +206,9 @@ class HydrationPerformanceTest extends \Doctrine\Tests\OrmPerformanceTestCase } /** - * [romanb: 2000 rows => 1 second] + * [romanb: 2000 rows => 0.4 seconds] * - * MAXIMUM TIME: 2 seconds + * MAXIMUM TIME: 1 second */ public function testMixedQueryFetchJoinObjectHydrationPerformance() { @@ -270,7 +270,7 @@ class HydrationPerformanceTest extends \Doctrine\Tests\OrmPerformanceTestCase $stmt = new HydratorMockStatement($resultSet); $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em); - $this->setMaxRunningTime(2); + $this->setMaxRunningTime(1); $s = microtime(true); $result = $hydrator->hydrateAll($stmt, $rsm); $e = microtime(true); diff --git a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php index c332a24e3..79a7443c7 100644 --- a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php @@ -2,6 +2,7 @@ namespace Doctrine\Tests\ORM; +use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\PersistentCollection; use Doctrine\Tests\Mocks\ConnectionMock; use Doctrine\Tests\Mocks\EntityManagerMock; @@ -29,15 +30,15 @@ class PersistentCollectionTest extends \Doctrine\Tests\OrmTestCase public function testCanBePutInLazyLoadingMode() { $class = $this->_emMock->getClassMetadata('Doctrine\Tests\Models\ECommerce\ECommerceProduct'); - $collection = new PersistentCollection($this->_emMock, $class); - $collection->setLazyInitialization(); + $collection = new PersistentCollection($this->_emMock, $class, new ArrayCollection); + $collection->setInitialized(false); } public function testQueriesAssociationToLoadItself() { $class = $this->_emMock->getClassMetadata('Doctrine\Tests\Models\ECommerce\ECommerceProduct'); - $collection = new PersistentCollection($this->_emMock, $class); - $collection->setLazyInitialization(); + $collection = new PersistentCollection($this->_emMock, $class, new ArrayCollection); + $collection->setInitialized(false); $association = $this->getMock('Doctrine\ORM\Mapping\OneToManyMapping', array('load'), array(), '', false, false, false); $association->targetEntityName = 'Doctrine\Tests\Models\ECommerce\ECommerceFeature';