[2.0][DDC-208] Fixed.
This commit is contained in:
parent
30ed439111
commit
c727483ad8
@ -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.
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,35 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
/**
|
||||
* EntityManagerException
|
||||
*
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @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
|
||||
{}
|
@ -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 <roman@code-factory.org>
|
||||
* @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);
|
||||
}
|
||||
}
|
11
lib/Doctrine/ORM/NoResultException.php
Normal file
11
lib/Doctrine/ORM/NoResultException.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
/**
|
||||
* Exception thrown when an ORM query unexpectedly does not return any results.
|
||||
*
|
||||
* @author robo
|
||||
* @since 2.0
|
||||
*/
|
||||
class NoResultException extends ORMException {}
|
11
lib/Doctrine/ORM/NonUniqueResultException.php
Normal file
11
lib/Doctrine/ORM/NonUniqueResultException.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
/**
|
||||
* Exception thrown when an ORM query unexpectedly returns more than one result.
|
||||
*
|
||||
* @author robo
|
||||
* @since 2.0
|
||||
*/
|
||||
class NonUniqueResultException extends ORMException {}
|
@ -2,6 +2,12 @@
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
/**
|
||||
* Base exception class for all ORM exceptions.
|
||||
*
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @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.");
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user