1
0
mirror of synced 2025-01-29 19:41:45 +03:00

[DDC-1840] Implemented parameters as a collection.

This commit is contained in:
Guilherme Blanco 2012-05-28 12:16:42 -04:00
parent 1f2ce21b56
commit 1635e0af4b
12 changed files with 357 additions and 179 deletions

View File

@ -19,15 +19,17 @@
namespace Doctrine\ORM;
use Doctrine\DBAL\Types\Type,
Doctrine\DBAL\Cache\QueryCacheProfile,
Doctrine\ORM\Query\QueryException,
Doctrine\Common\Util\ClassUtils;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\ORM\Query\QueryException;
/**
* Base contract for ORM queries. Base class for Query and NativeQuery.
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
@ -62,14 +64,9 @@ abstract class AbstractQuery
const HYDRATE_SIMPLEOBJECT = 5;
/**
* @var array The parameter map of this query.
* @var \Doctrine\Common\Collections\ArrayCollection The parameter map of this query.
*/
protected $_params = array();
/**
* @var array The parameter type map of this query.
*/
protected $_paramTypes = array();
protected $parameters;
/**
* @var ResultSetMapping The user-specified ResultSetMapping to use.
@ -114,8 +111,18 @@ abstract class AbstractQuery
public function __construct(EntityManager $em)
{
$this->_em = $em;
$this->parameters = new ArrayCollection();
}
/**
* Gets the SQL query that corresponds to this query object.
* The returned SQL syntax depends on the connection driver that is used
* by this query object at the time of this method call.
*
* @return string SQL query
*/
abstract public function getSQL();
/**
* Retrieves the associated EntityManager of this Query instance.
*
@ -135,8 +142,8 @@ abstract class AbstractQuery
*/
public function free()
{
$this->_params = array();
$this->_paramTypes = array();
$this->parameters = new ArrayCollection();
$this->_hints = array();
}
@ -147,58 +154,42 @@ abstract class AbstractQuery
*/
public function getParameters()
{
return $this->_params;
}
/**
* Get all defined parameter types.
*
* @return array The defined query parameter types.
*/
public function getParameterTypes()
{
return $this->_paramTypes;
return $this->parameters;
}
/**
* Gets a query parameter.
*
* @param mixed $key The key (index or name) of the bound parameter.
*
* @return mixed The value of the bound parameter.
*/
public function getParameter($key)
{
if (isset($this->_params[$key])) {
return $this->_params[$key];
foreach ($this->parameters->getIterator() as $parameter) {
// Must not be identical because of string to integer conversion
if ($parameter->getName() == $key) {
return $parameter;
}
}
return null;
}
/**
* Gets a query parameter type.
* Sets a collection of query parameters.
*
* @param mixed $key The key (index or name) of the bound parameter.
* @return mixed The parameter type of the bound parameter.
* @param \Doctrine\Common\Collections\ArrayCollection $parameters
*
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function getParameterType($key)
public function setParameters(ArrayCollection $parameters)
{
if (isset($this->_paramTypes[$key])) {
return $this->_paramTypes[$key];
}
$this->parameters = $parameters;
return null;
return $this;
}
/**
* Gets the SQL query that corresponds to this query object.
* The returned SQL syntax depends on the connection driver that is used
* by this query object at the time of this method call.
*
* @return string SQL query
*/
abstract public function getSQL();
/**
* Sets a query parameter.
*
@ -207,19 +198,29 @@ abstract class AbstractQuery
* @param string $type The parameter type. If specified, the given value will be run through
* the type conversion of this type. This is usually not needed for
* strings and numeric types.
*
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function setParameter($key, $value, $type = null)
{
$key = trim($key, ':');
$value = $this->processParameterValue($value);
$filteredParameters = $this->parameters->filter(
function ($parameter) use ($key)
{
// Must not be identical because of string to integer conversion
return ($key == $parameter->getName());
}
);
if ($type === null) {
$type = Query\ParameterTypeInferer::inferType($value);
if (count($filteredParameters)) {
$parameter = $filteredParameters->first();
$parameter->setValue($value, $type);
return $this;
}
$this->_paramTypes[$key] = $type;
$this->_params[$key] = $value;
$parameter = new Query\Parameter($key, $value, $type);
$this->parameters->add($parameter);
return $this;
}
@ -230,7 +231,7 @@ abstract class AbstractQuery
* @param mixed $value
* @return array
*/
private function processParameterValue($value)
public function processParameterValue($value)
{
switch (true) {
case is_array($value):
@ -249,7 +250,7 @@ abstract class AbstractQuery
}
}
protected function convertObjectParameterToScalarValue($value)
private function convertObjectParameterToScalarValue($value)
{
$class = $this->_em->getClassMetadata(get_class($value));
@ -275,22 +276,6 @@ abstract class AbstractQuery
return $value;
}
/**
* Sets a collection of query parameters.
*
* @param array $params
* @param array $types
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function setParameters(array $params, array $types = array())
{
foreach ($params as $key => $value) {
$this->setParameter($key, $value, isset($types[$key]) ? $types[$key] : null);
}
return $this;
}
/**
* Sets the ResultSetMapping that should be used for hydration.
*
@ -530,37 +515,37 @@ abstract class AbstractQuery
/**
* Gets the list of results for the query.
*
* Alias for execute(array(), $hydrationMode = HYDRATE_OBJECT).
* Alias for execute(null, $hydrationMode = HYDRATE_OBJECT).
*
* @return array
*/
public function getResult($hydrationMode = self::HYDRATE_OBJECT)
{
return $this->execute(array(), $hydrationMode);
return $this->execute(null, $hydrationMode);
}
/**
* Gets the array of results for the query.
*
* Alias for execute(array(), HYDRATE_ARRAY).
* Alias for execute(null, HYDRATE_ARRAY).
*
* @return array
*/
public function getArrayResult()
{
return $this->execute(array(), self::HYDRATE_ARRAY);
return $this->execute(null, self::HYDRATE_ARRAY);
}
/**
* Gets the scalar results for the query.
*
* Alias for execute(array(), HYDRATE_SCALAR).
* Alias for execute(null, HYDRATE_SCALAR).
*
* @return array
*/
public function getScalarResult()
{
return $this->execute(array(), self::HYDRATE_SCALAR);
return $this->execute(null, self::HYDRATE_SCALAR);
}
/**
@ -572,7 +557,7 @@ abstract class AbstractQuery
*/
public function getOneOrNullResult($hydrationMode = null)
{
$result = $this->execute(array(), $hydrationMode);
$result = $this->execute(null, $hydrationMode);
if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) {
return null;
@ -604,7 +589,7 @@ abstract class AbstractQuery
*/
public function getSingleResult($hydrationMode = null)
{
$result = $this->execute(array(), $hydrationMode);
$result = $this->execute(null, $hydrationMode);
if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) {
throw new NoResultException;
@ -673,18 +658,18 @@ abstract class AbstractQuery
* Executes the query and returns an IterableResult that can be used to incrementally
* iterate over the result.
*
* @param array $params The query parameters.
* @param \Doctrine\Common\Collections\ArrayCollection $parameters The query parameters.
* @param integer $hydrationMode The hydration mode to use.
* @return \Doctrine\ORM\Internal\Hydration\IterableResult
*/
public function iterate(array $params = array(), $hydrationMode = null)
public function iterate(ArrayCollection $parameters = null, $hydrationMode = null)
{
if ($hydrationMode !== null) {
$this->setHydrationMode($hydrationMode);
}
if ($params) {
$this->setParameters($params);
if ($parameters) {
$this->setParameters($parameters);
}
$stmt = $this->_doExecute();
@ -697,18 +682,18 @@ abstract class AbstractQuery
/**
* Executes the query.
*
* @param array $params Any additional query parameters.
* @param \Doctrine\Common\Collections\ArrayCollection $parameters Query parameters.
* @param integer $hydrationMode Processing mode to be used during the hydration process.
* @return mixed
*/
public function execute($params = array(), $hydrationMode = null)
public function execute(ArrayCollection $parameters = null, $hydrationMode = null)
{
if ($hydrationMode !== null) {
$this->setHydrationMode($hydrationMode);
}
if ($params) {
$this->setParameters($params);
if ($parameters) {
$this->setParameters($parameters);
}
$setCacheEntry = function() {};
@ -730,6 +715,7 @@ abstract class AbstractQuery
$setCacheEntry = function($data) use ($cache, $result, $cacheKey, $realCacheKey, $queryCacheProfile) {
$result[$realCacheKey] = $data;
$cache->save($cacheKey, $result, $queryCacheProfile->getLifetime());
};
}
@ -760,19 +746,20 @@ abstract class AbstractQuery
*/
protected function getHydrationCacheId()
{
$params = $this->getParameters();
$parameters = array();
foreach ($params AS $key => $value) {
$params[$key] = $this->processParameterValue($value);
foreach ($this->getParameters()->getIterator() as $parameter) {
$parameters[$parameter->getName()] = $this->processParameterValue($parameter->getValue());
}
$sql = $this->getSQL();
$queryCacheProfile = $this->getHydrationCacheProfile();
$hints = $this->getHints();
$hints['hydrationMode'] = $this->getHydrationMode();
ksort($hints);
return $queryCacheProfile->generateCacheKeys($sql, $params, $hints);
return $queryCacheProfile->generateCacheKeys($sql, $parameters, $hints);
}
/**
@ -817,8 +804,8 @@ abstract class AbstractQuery
*/
public function __clone()
{
$this->_params = array();
$this->_paramTypes = array();
$this->parameters = new ArrayCollection();
$this->_hints = array();
}
}

View File

@ -58,19 +58,30 @@ final class NativeQuery extends AbstractQuery
*/
protected function _doExecute()
{
$params = $this->_params;
$types = $this->_paramTypes;
$parameters = array();
$types = array();
if ($params && is_int(key($params))) {
ksort($params);
foreach ($this->getParameters()->getIterator() as $parameter) {
$name = $parameter->getName();
$value = $this->processParameterValue($parameter->getValue());
$type = ($parameter->getValue() === $value)
? $parameter->getType()
: Query\ParameterTypeInferer::inferType($value);
$parameters[$name] = $value;
$types[$name] = $type;
}
if ($parameters && is_int(key($parameters))) {
ksort($parameters);
ksort($types);
$params = array_values($params);
$types = array_values($types);
$parameters = array_values($parameters);
$types = array_values($types);
}
return $this->_em->getConnection()->executeQuery(
$this->_sql, $params, $types, $this->_queryCacheProfile
$this->_sql, $parameters, $types, $this->_queryCacheProfile
);
}
}

View File

@ -19,10 +19,13 @@
namespace Doctrine\ORM;
use Doctrine\DBAL\LockMode,
Doctrine\ORM\Query\Parser,
Doctrine\ORM\Query\ParserResult,
Doctrine\ORM\Query\QueryException;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\DBAL\LockMode;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\ParserResult;
use Doctrine\ORM\Query\QueryException;
/**
* A Query object represents a DQL query.
@ -248,7 +251,7 @@ final class Query extends AbstractQuery
// Prepare parameters
$paramMappings = $this->_parserResult->getParameterMappings();
if (count($paramMappings) != count($this->_params)) {
if (count($paramMappings) != count($this->parameters)) {
throw QueryException::invalidParameterNumber();
}
@ -269,17 +272,23 @@ final class Query extends AbstractQuery
*/
private function processParameterMappings($paramMappings)
{
$sqlParams = $types = array();
$sqlParams = array();
$types = array();
foreach ($this->parameters->getIterator() as $parameter) {
$key = $parameter->getName();
foreach ($this->_params as $key => $value) {
if ( ! isset($paramMappings[$key])) {
throw QueryException::unknownParameter($key);
}
if (isset($this->_paramTypes[$key])) {
foreach ($paramMappings[$key] as $position) {
$types[$position] = $this->_paramTypes[$key];
}
$value = $this->processParameterValue($parameter->getValue());
$type = ($parameter->getValue() === $value)
? $parameter->getType()
: Query\ParameterTypeInferer::inferType($value);
foreach ($paramMappings[$key] as $position) {
$types[$position] = $type;
}
$sqlPositions = $paramMappings[$key];
@ -517,15 +526,15 @@ final class Query extends AbstractQuery
* Executes the query and returns an IterableResult that can be used to incrementally
* iterated over the result.
*
* @param array $params The query parameters.
* @param \Doctrine\Common\Collections\ArrayCollection $parameters The query parameters.
* @param integer $hydrationMode The hydration mode to use.
* @return \Doctrine\ORM\Internal\Hydration\IterableResult
*/
public function iterate(array $params = array(), $hydrationMode = self::HYDRATE_OBJECT)
public function iterate(ArrayCollection $parameters = null, $hydrationMode = self::HYDRATE_OBJECT)
{
$this->setHint(self::HINT_INTERNAL_ITERATION, true);
return parent::iterate($params, $hydrationMode);
return parent::iterate($parameters, $hydrationMode);
}
/**

View File

@ -19,9 +19,11 @@
namespace Doctrine\ORM\Query\Exec;
use Doctrine\DBAL\Connection,
Doctrine\DBAL\Types\Type,
Doctrine\ORM\Query\AST;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Query\ParameterTypeInferer;
use Doctrine\ORM\Query\AST;
/**
* Executes the SQL statements for bulk DQL UPDATE statements on classes in
@ -105,9 +107,16 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor
//FIXME: parameters can be more deeply nested. traverse the tree.
//FIXME (URGENT): With query cache the parameter is out of date. Move to execute() stage.
if ($newValue instanceof AST\InputParameter) {
$paramKey = $newValue->name;
$this->_sqlParameters[$i]['parameters'][] = $sqlWalker->getQuery()->getParameter($paramKey);
$this->_sqlParameters[$i]['types'][] = $sqlWalker->getQuery()->getParameterType($paramKey);
$parameterName = $newValue->name;
$parameter = $sqlWalker->getQuery()->getParameter($parameterName);
$value = $sqlWalker->getQuery()->processParameterValue($parameter->getValue());
$type = ($parameter->getValue() === $value)
? $parameter->getType()
: ParameterTypeInferer::inferType($value);
$this->_sqlParameters[$i]['parameters'][] = $value;
$this->_sqlParameters[$i]['types'][] = $type;
++$this->_numParametersInUpdateClause;
}

View File

@ -0,0 +1,101 @@
<?php
/*
* 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 MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Query;
/**
* Define a Query Parameter
*
* @link www.doctrine-project.org
* @since 2.3
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
*/
class Parameter
{
/**
* @var string Parameter name
*/
private $name;
/**
* @var mixed Parameter value
*/
private $value;
/**
* @var mixed Parameter type
*/
private $type;
/**
* Constructor.
*
* @param string $name Parameter name
* @param mixed $value Parameter value
* @param mixed $type Parameter type
*/
public function __construct($name, $value, $type = null)
{
$this->name = trim($name, ':');
$this->setValue($value);
}
/**
* Retrieve the Parameter name.
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Retrieve the Parameter value.
*
* @return mixed
*/
public function getValue()
{
return $this->value;
}
/**
* Retrieve the Parameter type.
*
* @return mixed
*/
public function getType()
{
return $this->type;
}
/**
* Define the Parameter value.
*
* @param mixed $value Parameter value
* @param mixed $type Parameter type
*/
public function setValue($value, $type = null)
{
$this->value = $value;
$this->type = $type ?: ParameterTypeInferer::inferType($value);
}
}

View File

@ -1687,7 +1687,6 @@ class SqlWalker implements TreeWalker
// InputParameter
case ($entityExpr instanceof AST\InputParameter):
$dqlParamKey = $entityExpr->name;
$entity = $this->_query->getParameter($dqlParamKey);
$entitySql = '?';
break;
@ -1853,8 +1852,7 @@ class SqlWalker implements TreeWalker
$dqlAlias = $instanceOfExpr->identificationVariable;
$discrClass = $class = $this->_queryComponents[$dqlAlias]['metadata'];
$fieldName = null;
if ($class->discriminatorColumn) {
$discrClass = $this->_em->getClassMetadata($class->rootEntityName);
}
@ -1871,7 +1869,8 @@ class SqlWalker implements TreeWalker
if ($parameter instanceof AST\InputParameter) {
// We need to modify the parameter value to be its correspondent mapped value
$dqlParamKey = $parameter->name;
$paramValue = $this->_query->getParameter($dqlParamKey);
$dqlParam = $this->_query->getParameter($dqlParamKey);
$paramValue = $this->_query->processParameterValue($dqlParam->getValue());
if ( ! ($paramValue instanceof \Doctrine\ORM\Mapping\ClassMetadata)) {
throw QueryException::invalidParameterType('ClassMetadata', get_class($paramValue));

View File

@ -19,6 +19,8 @@
namespace Doctrine\ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Query\Expr;
/**
@ -77,14 +79,9 @@ class QueryBuilder
private $_dql;
/**
* @var array The query parameters.
* @var \Doctrine\Common\Collections\ArrayCollection The query parameters.
*/
private $_params = array();
/**
* @var array The parameter type map of this query.
*/
private $_paramTypes = array();
private $parameters = array();
/**
* @var integer The index of the first result to retrieve.
@ -109,6 +106,7 @@ class QueryBuilder
public function __construct(EntityManager $em)
{
$this->_em = $em;
$this->parameters = new ArrayCollection();
}
/**
@ -218,8 +216,10 @@ class QueryBuilder
*/
public function getQuery()
{
$parameters = clone $this->parameters;
return $this->_em->createQuery($this->getDQL())
->setParameters($this->_params, $this->_paramTypes)
->setParameters($parameters)
->setFirstResult($this->_firstResult)
->setMaxResults($this->_maxResults);
}
@ -355,10 +355,7 @@ class QueryBuilder
*/
public function setParameter($key, $value, $type = null)
{
$key = trim($key, ':');
$this->_paramTypes[$key] = $type ?: Query\ParameterTypeInferer::inferType($value);
$this->_params[$key] = $value;
$this->parameters->add(new Query\Parameter($key, $value, $type));
return $this;
}
@ -371,20 +368,18 @@ class QueryBuilder
* ->select('u')
* ->from('User', 'u')
* ->where('u.id = :user_id1 OR u.id = :user_id2')
* ->setParameters(array(
* 'user_id1' => 1,
* 'user_id2' => 2
));
* ->setParameters(new ArrayCollection(array(
* new Parameter('user_id1', 1),
* new Parameter('user_id2', 2)
)));
* </code>
*
* @param array $params The query parameters to set.
* @param \Doctrine\Common\Collections\ArrayCollections $params The query parameters to set.
* @return QueryBuilder This QueryBuilder instance.
*/
public function setParameters(array $params, array $types = array())
public function setParameters(ArrayCollection $parameters)
{
foreach ($params as $key => $value) {
$this->setParameter($key, $value, isset($types[$key]) ? $types[$key] : null);
}
$this->parameters = $parameters;
return $this;
}
@ -396,18 +391,25 @@ class QueryBuilder
*/
public function getParameters()
{
return $this->_params;
return $this->parameters;
}
/**
* Gets a (previously set) query parameter of the query being constructed.
*
* @param mixed $key The key (index or name) of the bound parameter.
*
* @return mixed The value of the bound parameter.
*/
public function getParameter($key)
{
return isset($this->_params[$key]) ? $this->_params[$key] : null;
foreach ($this->parameters->getIterator() as $parameter) {
if ($parameter->getName() === $key) {
return $parameter;
}
}
return null;
}
/**

View File

@ -2,8 +2,12 @@
namespace Doctrine\Tests\ORM\Functional;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
use Doctrine\ORM\Query\Parameter;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
use Doctrine\Tests\Models\CMS\CmsAddress;
@ -191,6 +195,10 @@ class NativeQueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testFluentInterface()
{
$parameters = new ArrayCollection;
$parameters->add(new Parameter(1, 'foo'));
$parameters->add(new Parameter(2, 'bar'));
$rsm = new ResultSetMapping;
$q = $this->_em->createNativeQuery('SELECT id, name, status, phonenumber FROM cms_users INNER JOIN cms_phonenumbers ON id = user_id WHERE username = ?', $rsm);
@ -199,7 +207,7 @@ class NativeQueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
->expireResultCache(true)
->setHint('foo', 'bar')
->setParameter(1, 'foo')
->setParameters(array(2 => 'bar'))
->setParameters($parameters)
->setResultCacheDriver(null)
->setResultCacheLifetime(3500);
@ -362,7 +370,7 @@ class NativeQueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
$repository = $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsAddress');
$query = $repository->createNativeNamedQuery('find-all');
$result = $query->getResult();
$this->assertCount(1, $result);
$this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsAddress', $result[0]);
$this->assertEquals($addr->id, $result[0]->id);
@ -396,7 +404,7 @@ class NativeQueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
$result = $repository->createNativeNamedQuery('fetchIdAndUsernameWithResultClass')
->setParameter(1, 'FabioBatSilva')->getResult();
$this->assertEquals(1, count($result));
$this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[0]);
$this->assertNull($result[0]->name);
@ -511,7 +519,7 @@ class NativeQueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
$user2->name = 'test tester';
$user2->username = 'test';
$user2->status = 'tester';
$phone1 = new CmsPhonenumber;
$phone2 = new CmsPhonenumber;
$phone3 = new CmsPhonenumber;
@ -528,7 +536,7 @@ class NativeQueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->_em->flush();
$this->_em->clear();
$repository = $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsUser');
$result = $repository->createNativeNamedQuery('fetchUserPhonenumberCount')
@ -583,7 +591,7 @@ class NativeQueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->_em->clear();
$result = $repository->createNativeNamedQuery('fetchAllWithResultClass')
->getResult();

View File

@ -19,10 +19,13 @@ class QueryCacheTest extends \Doctrine\Tests\OrmFunctionalTestCase
*/
private $cacheDataReflection;
protected function setUp() {
protected function setUp()
{
$this->cacheDataReflection = new \ReflectionProperty("Doctrine\Common\Cache\ArrayCache", "data");
$this->cacheDataReflection->setAccessible(true);
$this->useModelSet('cms');
parent::setUp();
}

View File

@ -2,11 +2,16 @@
namespace Doctrine\Tests\ORM\Functional;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\DBAL\Connection;
use Doctrine\Tests\Models\CMS\CmsUser,
Doctrine\Tests\Models\CMS\CmsArticle;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\Parameter;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\Models\CMS\CmsArticle;
require_once __DIR__ . '/../../TestInit.php';
@ -151,7 +156,12 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testSetParameters()
{
$q = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = ?1 AND u.status = ?2');
$q->setParameters(array(1 => 'jwage', 2 => 'active'));
$parameters = new ArrayCollection();
$parameters->add(new Parameter(1, 'jwage'));
$parameters->add(new Parameter(2, 'active'));
$q->setParameters($parameters);
$users = $q->getResult();
}
@ -176,7 +186,7 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
$articleId = $article1->id;
$query = $this->_em->createQuery("select a from Doctrine\Tests\Models\CMS\CmsArticle a WHERE a.topic = ?1");
$articles = $query->iterate(array(1 => 'Doctrine 2'), Query::HYDRATE_ARRAY);
$articles = $query->iterate(new ArrayCollection(array(new Parameter(1, 'Doctrine 2'))), Query::HYDRATE_ARRAY);
$found = array();
foreach ($articles AS $article) {
@ -520,10 +530,10 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->_em->clear();
$query = $this->_em->createQuery("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.status = :a AND u.id IN (:b)");
$query->setParameters(array(
'b' => array($user1->id, $user2->id, $user3->id),
'a' => 'developer',
));
$query->setParameters(new ArrayCollection(array(
new Parameter('b', array($user1->id, $user2->id, $user3->id)),
new Parameter('a', 'developer')
)));
$result = $query->getResult();
$this->assertEquals(3, count($result));
@ -639,7 +649,7 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
/**
* @group DDC-1651
*/
public function testSetParameterBindingSingleIdentifierObjectConverted()
public function testSetParameterBindingSingleIdentifierObject()
{
$userC = new CmsUser;
$userC->name = 'Jonathan';
@ -653,7 +663,10 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
$q = $this->_em->createQuery("SELECT DISTINCT u from Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1");
$q->setParameter(1, $userC);
$this->assertEquals($userC->id, $q->getParameter(1));
$this->assertEquals($userC, $q->getParameter(1)->getValue());
// Parameter is not converted before, but it should be converted during execution. Test should not fail here
$q->getResult();
}

View File

@ -3,6 +3,9 @@
namespace Doctrine\Tests\ORM\Query;
use Doctrine\Common\Cache\ArrayCache;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Query\Parameter;
class QueryTest extends \Doctrine\Tests\OrmTestCase
{
@ -16,21 +19,34 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
public function testGetParameters()
{
$query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1");
$this->assertEquals(array(), $query->getParameters());
$parameters = new ArrayCollection();
$this->assertEquals($parameters, $query->getParameters());
}
public function testGetParameters_HasSomeAlready()
{
$query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1");
$query->setParameter(2, 84);
$this->assertEquals(array(2 => 84), $query->getParameters());
$parameters = new ArrayCollection();
$parameters->add(new Parameter(2, 84));
$this->assertEquals($parameters, $query->getParameters());
}
public function testSetParameters()
{
$query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1");
$query->setParameters(array(1 => 'foo', 2 => 'bar'));
$this->assertEquals(array(1 => 'foo', 2 => 'bar'), $query->getParameters());
$parameters = new ArrayCollection();
$parameters->add(new Parameter(1, 'foo'));
$parameters->add(new Parameter(2, 'bar'));
$query->setParameters($parameters);
$this->assertEquals($parameters, $query->getParameters());
}
public function testFree()
@ -40,7 +56,7 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
$query->free();
$this->assertEquals(array(), $query->getParameters());
$this->assertEquals(0, count($query->getParameters()));
}
public function testClone()
@ -54,7 +70,7 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
$cloned = clone $query;
$this->assertEquals($dql, $cloned->getDql());
$this->assertEquals(array(), $cloned->getParameters());
$this->assertEquals(0, count($cloned->getParameters()));
$this->assertFalse($cloned->getHint('foo'));
}
@ -68,7 +84,7 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
->setHint('foo', 'bar')
->setHint('bar', 'baz')
->setParameter(1, 'bar')
->setParameters(array(2 => 'baz'))
->setParameters(new ArrayCollection(array(new Parameter(2, 'baz'))))
->setResultCacheDriver(null)
->setResultCacheId('foo')
->setDql('foo')
@ -129,7 +145,7 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
/**
* @group DDC-1697
*/
public function testKeyValueParameters()
public function testCollectionParameters()
{
$cities = array(
0 => "Paris",
@ -142,8 +158,9 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
->setParameter('cities', $cities);
$parameters = $query->getParameters();
$parameter = $parameters->first();
$this->assertArrayHasKey('cities', $parameters);
$this->assertEquals($cities, $parameters['cities']);
$this->assertEquals('cities', $parameter->getName());
$this->assertEquals($cities, $parameter->getValue());
}
}

View File

@ -19,8 +19,12 @@
namespace Doctrine\Tests\ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\QueryBuilder,
Doctrine\ORM\Query\Expr;
Doctrine\ORM\Query\Expr,
Doctrine\ORM\Query\Parameter,
Doctrine\ORM\Query\ParameterTypeInferer;
require_once __DIR__ . '/../TestInit.php';
@ -385,7 +389,9 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
->where('u.id = :id')
->setParameter('id', 1);
$this->assertEquals(array('id' => 1), $qb->getParameters());
$parameter = new Parameter('id', 1, ParameterTypeInferer::inferType(1));
$this->assertEquals($parameter, $qb->getParameter('id'));
}
public function testSetParameters()
@ -395,9 +401,13 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
->where($qb->expr()->orx('u.username = :username', 'u.username = :username2'));
$qb->setParameters(array('username' => 'jwage', 'username2' => 'jonwage'));
$parameters = new ArrayCollection();
$parameters->add(new Parameter('username', 'jwage'));
$parameters->add(new Parameter('username2', 'jonwage'));
$this->assertEquals(array('username' => 'jwage', 'username2' => 'jonwage'), $qb->getQuery()->getParameters());
$qb->setParameters($parameters);
$this->assertEquals($parameters, $qb->getQuery()->getParameters());
}
@ -408,8 +418,12 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
->where('u.id = :id');
$qb->setParameters(array('id' => 1));
$this->assertEquals(array('id' => 1), $qb->getParameters());
$parameters = new ArrayCollection();
$parameters->add(new Parameter('id', 1));
$qb->setParameters($parameters);
$this->assertEquals($parameters, $qb->getParameters());
}
public function testGetParameter()
@ -419,8 +433,12 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
->where('u.id = :id');
$qb->setParameters(array('id' => 1));
$this->assertEquals(1, $qb->getParameter('id'));
$parameters = new ArrayCollection();
$parameters->add(new Parameter('id', 1));
$qb->setParameters($parameters);
$this->assertEquals($parameters->first(), $qb->getParameter('id'));
}
public function testMultipleWhere()
@ -536,6 +554,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
$qb->setParameter('name', 'romanb');
$q1 = $qb->getQuery();
$this->assertEquals('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = :name', $q1->getDql());
$this->assertEquals(1, count($q1->getParameters()));