diff --git a/lib/Doctrine/ORM/AbstractQuery.php b/lib/Doctrine/ORM/AbstractQuery.php index 5ac4ffa51..bd49e30ca 100644 --- a/lib/Doctrine/ORM/AbstractQuery.php +++ b/lib/Doctrine/ORM/AbstractQuery.php @@ -56,7 +56,7 @@ abstract class AbstractQuery /** * Hydrates nothing. */ - const HYDRATE_NONE = 5; + //const HYDRATE_NONE = 5; /** * @var array $params Parameters of this query. @@ -375,27 +375,37 @@ abstract class AbstractQuery /** * Gets the single result of the query. - * Enforces the uniqueness of the result. If the result is not unique, - * a QueryException is thrown. + * + * Enforces the presence as well as the uniqueness of the result. + * + * If the result is not unique, a NonUniqueResultException is thrown. + * If there is no result, a NoResultException is thrown. * * @param integer $hydrationMode * @return mixed * @throws QueryException If the query result is not unique. + * @throws NoResultException If the query returned no result. */ public function getSingleResult($hydrationMode = null) { $result = $this->execute(array(), $hydrationMode); + + if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) { + throw new NoResultException; + } + if (is_array($result)) { if (count($result) > 1) { - throw QueryException::nonUniqueResult(); + throw new NonUniqueResultException; } return array_shift($result); } else if (is_object($result)) { if (count($result) > 1) { - throw QueryException::nonUniqueResult(); + throw new NonUniqueResultException; } return $result->first(); } + return $result; } @@ -413,8 +423,7 @@ abstract class AbstractQuery } /** - * Sets an implementation-specific hint. If the hint name is not recognized, - * it is silently ignored. + * Sets a query hint. If the hint name is not recognized, it is silently ignored. * * @param string $name The name of the hint. * @param mixed $value The value of the hint. @@ -427,8 +436,7 @@ abstract class AbstractQuery } /** - * Gets an implementation-specific hint. If the hint name is not recognized, - * FALSE is returned. + * Gets the value of a query hint. If the hint name is not recognized, FALSE is returned. * * @param string $name The name of the hint. * @return mixed The value of the hint or FALSE, if the hint name is not recognized. @@ -440,7 +448,7 @@ abstract class AbstractQuery /** * Executes the query and returns an IterableResult that can be used to incrementally - * iterated over the result. + * iterate over the result. * * @param array $params The query parameters. * @param integer $hydrationMode The hydration mode to use. diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php index c8107082f..fc2669b27 100644 --- a/lib/Doctrine/ORM/EntityManager.php +++ b/lib/Doctrine/ORM/EntityManager.php @@ -44,21 +44,25 @@ class EntityManager /** * IMMEDIATE: Flush occurs automatically after each operation that issues database * queries. No operations are queued. + * @deprecated */ const FLUSHMODE_IMMEDIATE = 1; /** * AUTO: Flush occurs automatically in the following situations: * - Before any query executions (to prevent getting stale data) * - On EntityManager#commit() + * @deprecated */ const FLUSHMODE_AUTO = 2; /** * COMMIT: Flush occurs automatically only on EntityManager#commit(). + * @deprecated */ const FLUSHMODE_COMMIT = 3; /** * MANUAL: Flush occurs never automatically. The only way to flush is * through EntityManager#flush(). + * @deprecated */ const FLUSHMODE_MANUAL = 4; @@ -94,6 +98,7 @@ class EntityManager * The currently used flush mode. Defaults to 'commit'. * * @var string + * @deprecated */ private $_flushMode = self::FLUSHMODE_COMMIT; @@ -135,7 +140,6 @@ class EntityManager * and uses the given Configuration and EventManager implementations. * * @param Doctrine\DBAL\Connection $conn - * @param string $name * @param Doctrine\ORM\Configuration $config * @param Doctrine\Common\EventManager $eventManager */ @@ -335,11 +339,12 @@ class EntityManager * Sets the flush mode to use. * * @param string $flushMode + * @deprecated */ public function setFlushMode($flushMode) { if ( ! ($flushMode >= 1 && $flushMode <= 4)) { - throw EntityManagerException::invalidFlushMode(); + throw ORMException::invalidFlushMode($flushMode); } $this->_flushMode = $flushMode; } @@ -348,6 +353,7 @@ class EntityManager * Gets the currently used flush mode. * * @return string + * @deprecated */ public function getFlushMode() { @@ -366,7 +372,7 @@ class EntityManager $this->_unitOfWork->clear(); } else { //TODO - throw DoctrineException::notImplemented(__FUNCTION__, __CLASS__); + throw new ORMException("EntityManager#clear(\$entityName) not yet implemented."); } } @@ -528,12 +534,12 @@ class EntityManager /** * Throws an exception if the EntityManager is closed or currently not active. * - * @throws EntityManagerException If the EntityManager is closed. + * @throws ORMException If the EntityManager is closed. */ private function _errorIfClosed() { if ($this->_closed) { - throw EntityManagerException::closed(); + throw ORMException::entityManagerClosed(); } } diff --git a/lib/Doctrine/ORM/EntityManagerException.php b/lib/Doctrine/ORM/EntityManagerException.php deleted file mode 100644 index cb2d9eea7..000000000 --- a/lib/Doctrine/ORM/EntityManagerException.php +++ /dev/null @@ -1,35 +0,0 @@ -. - */ - -namespace Doctrine\ORM; - -/** - * EntityManagerException - * - * @author Konsta Vesterinen - * @author Roman Borschel - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.doctrine-project.org - * @since 2.0 - * @version $Revision$ - */ -class EntityManagerException extends \Doctrine\Common\DoctrineException -{} \ No newline at end of file diff --git a/lib/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php index 325e2ed1c..67f4e9aac 100644 --- a/lib/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php +++ b/lib/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php @@ -24,9 +24,10 @@ namespace Doctrine\ORM\Internal\Hydration; use Doctrine\DBAL\Connection; /** - * Description of SingleScalarHydrator + * Hydrator that hydrates a single scalar value from the result set. * * @author Roman Borschel + * @since 2.0 */ class SingleScalarHydrator extends AbstractHydrator { @@ -35,11 +36,11 @@ class SingleScalarHydrator extends AbstractHydrator { $cache = array(); $result = $this->_stmt->fetchAll(Connection::FETCH_ASSOC); - //TODO: Let this exception be raised by Query as QueryException if (count($result) > 1 || count($result[key($result)]) > 1) { - throw HydrationException::nonUniqueResult(); + throw new \Doctrine\ORM\NonUniqueResultException; } $result = $this->_gatherScalarRowData($result[key($result)], $cache); + return array_shift($result); } } \ No newline at end of file diff --git a/lib/Doctrine/ORM/NoResultException.php b/lib/Doctrine/ORM/NoResultException.php new file mode 100644 index 000000000..e948a96c7 --- /dev/null +++ b/lib/Doctrine/ORM/NoResultException.php @@ -0,0 +1,11 @@ + + * @since 2.0 + */ class ORMException extends \Exception { public static function entityMissingAssignedId($entity) @@ -30,4 +36,14 @@ class ORMException extends \Exception { return new self("A detached entity can not be removed."); } + + public static function invalidFlushMode($mode) + { + return new self("'$mode' is an invalid flush mode."); + } + + public static function entityManagerClosed() + { + return new self("The EntityManager is closed."); + } } diff --git a/tests/Doctrine/Tests/ORM/EntityManagerTest.php b/tests/Doctrine/Tests/ORM/EntityManagerTest.php index 2d44cf8c9..65f5974d3 100644 --- a/tests/Doctrine/Tests/ORM/EntityManagerTest.php +++ b/tests/Doctrine/Tests/ORM/EntityManagerTest.php @@ -20,7 +20,7 @@ class EntityManagerTest extends \Doctrine\Tests\OrmTestCase try { $this->_em->setFlushMode('foobar'); $this->fail("Setting invalid flushmode did not trigger exception."); - } catch (\Doctrine\ORM\EntityManagerException $expected) {} + } catch (\Doctrine\ORM\ORMException $expected) {} $this->_em->setFlushMode($prev); } @@ -102,7 +102,7 @@ class EntityManagerTest extends \Doctrine\Tests\OrmTestCase */ public function testAffectedByErrorIfClosedException($methodName) { - $this->setExpectedException('Doctrine\ORM\EntityManagerException', 'Closed'); + $this->setExpectedException('Doctrine\ORM\ORMException', 'closed'); $this->_em->close(); $this->_em->$methodName(new \stdClass()); diff --git a/tests/Doctrine/Tests/ORM/Functional/QueryTest.php b/tests/Doctrine/Tests/ORM/Functional/QueryTest.php index 4565f0320..816753ca5 100644 --- a/tests/Doctrine/Tests/ORM/Functional/QueryTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/QueryTest.php @@ -2,8 +2,8 @@ namespace Doctrine\Tests\ORM\Functional; -use Doctrine\Tests\Models\CMS\CmsUser; -use Doctrine\Tests\Models\CMS\CmsArticle; +use Doctrine\Tests\Models\CMS\CmsUser, + Doctrine\Tests\Models\CMS\CmsArticle; require_once __DIR__ . '/../../TestInit.php'; @@ -204,5 +204,14 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertSame($q2, $q); } + + /** + * @expectedException Doctrine\ORM\NoResultException + */ + public function testGetSingleResultThrowsExceptionOnNoResult() + { + $this->_em->createQuery("select a from Doctrine\Tests\Models\CMS\CmsArticle a") + ->getSingleResult(); + } } diff --git a/tests/Doctrine/Tests/ORM/Hydration/SingleScalarHydratorTest.php b/tests/Doctrine/Tests/ORM/Hydration/SingleScalarHydratorTest.php index 761882868..f6abe2471 100644 --- a/tests/Doctrine/Tests/ORM/Hydration/SingleScalarHydratorTest.php +++ b/tests/Doctrine/Tests/ORM/Hydration/SingleScalarHydratorTest.php @@ -70,9 +70,9 @@ class SingleScalarHydratorTest extends HydrationTestCase $this->assertEquals(1, $result); } else if ($name == 'result3' || $name == 'result4') { try { - $result = $hydrator->hydrateall($stmt, $rsm); + $result = $hydrator->hydrateAll($stmt, $rsm); $this->fail(); - } catch (\Doctrine\ORM\Internal\Hydration\HydrationException $ex) {} + } catch (\Doctrine\ORM\NonUniqueResultException $e) {} } } } \ No newline at end of file