1
0
mirror of synced 2025-01-31 04:21:44 +03:00

[2.0] DDC-176 - Disallow iterate() over fetch-join collections by the means of an exception on parsing the DQL query.

This commit is contained in:
beberlei 2009-12-08 20:53:01 +00:00
parent 03bc9350dc
commit 3e823f065a
4 changed files with 49 additions and 1 deletions

View File

@ -77,6 +77,11 @@ final class Query extends AbstractQuery
const HINT_CUSTOM_TREE_WALKERS = 'doctrine.customTreeWalkers'; const HINT_CUSTOM_TREE_WALKERS = 'doctrine.customTreeWalkers';
//const HINT_READ_ONLY = 'doctrine.readOnly'; //const HINT_READ_ONLY = 'doctrine.readOnly';
/**
* @var string
*/
const HINT_INTERNAL_ITERATION = 'doctrine.internal.iteration';
/** /**
* @var integer $_state The current state of this query. * @var integer $_state The current state of this query.
*/ */
@ -419,4 +424,18 @@ final class Query extends AbstractQuery
{ {
return $this->_maxResults; return $this->_maxResults;
} }
/**
* Executes the query and returns an IterableResult that can be used to incrementally
* iterated over the result.
*
* @param array $params The query parameters.
* @param integer $hydrationMode The hydration mode to use.
* @return IterableResult
*/
public function iterate(array $params = array(), $hydrationMode = self::HYDRATE_OBJECT)
{
$this->setHint(self::HINT_INTERNAL_ITERATION, true);
return parent::iterate($params, $hydrationMode);
}
} }

View File

@ -63,4 +63,15 @@ class QueryException extends \Doctrine\Common\DoctrineException
{ {
return new self("Invalid parameter: token ".$key." is not defined in the query."); return new self("Invalid parameter: token ".$key." is not defined in the query.");
} }
/**
* @param Doctrine\ORM\Mapping\AssociationMapping $assoc
*/
public static function iterateWithFetchJoinCollectionNotAllowed($assoc)
{
return new self(
"Invalid query operation: Not allowed to iterate over fetch join collections ".
"in class ".$assoc->sourceEntityName." assocation ".$assoc->sourceFieldName
);
}
} }

View File

@ -55,8 +55,11 @@ class SqlWalker implements TreeWalker
/** The Connection of the EntityManager. */ /** The Connection of the EntityManager. */
private $_conn; private $_conn;
/** The Query instance. */ /**
* @var AbstractQuery
*/
private $_query; private $_query;
private $_dqlToSqlAliasMap = array(); private $_dqlToSqlAliasMap = array();
/** Map from result variable names to their SQL column alias names. */ /** Map from result variable names to their SQL column alias names. */
@ -650,6 +653,12 @@ class SqlWalker implements TreeWalker
$assoc = $relation; $assoc = $relation;
} }
if ($this->_query->getHint(Query::HINT_INTERNAL_ITERATION) == true) {
if ($relation->isOneToMany() || $relation->isManyToMany()) {
throw QueryException::iterateWithFetchJoinNotAllowed($assoc);
}
}
if ($assoc->isOneToOne()) { if ($assoc->isOneToOne()) {
$sql .= $targetTableName . ' ' . $targetTableAlias . ' ON '; $sql .= $targetTableName . ' ' . $targetTableAlias . ' ON ';
$first = true; $first = true;

View File

@ -176,6 +176,15 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->_em->clear(); $this->_em->clear();
} }
/**
* @expectedException \Doctrine\ORM\Query\QueryException
*/
public function testIterateResult_FetchJoinedCollection_ThrowsException()
{
$query = $this->_em->createQuery("SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a");
$articles = $query->iterate();
}
public function testFluentQueryInterface() public function testFluentQueryInterface()
{ {
$q = $this->_em->createQuery("select a from Doctrine\Tests\Models\CMS\CmsArticle a"); $q = $this->_em->createQuery("select a from Doctrine\Tests\Models\CMS\CmsArticle a");