Merge pull request #360 from doctrine/DDC-1840
[DDC-1840] Implemented parameters as a collection.
This commit is contained in:
commit
e4935e58f2
@ -7,3 +7,21 @@ and strip a trailing "s" character if there is one.
|
|||||||
# Merge copies non persisted properties too
|
# Merge copies non persisted properties too
|
||||||
|
|
||||||
When merging an entity in UoW not only mapped properties are copied, but also others.
|
When merging an entity in UoW not only mapped properties are copied, but also others.
|
||||||
|
|
||||||
|
# Query, QueryBuilder and NativeQuery parameters *BC break*
|
||||||
|
|
||||||
|
From now on, parameters in queries is an ArrayCollection instead of a simple array.
|
||||||
|
This affects heavily the usage of setParameters(), because it will not append anymore
|
||||||
|
parameters to query, but will actually override the already defined ones.
|
||||||
|
Whenever you are retrieving a parameter (ie. $query->getParameter(1)), you will
|
||||||
|
receive an instance of Query\Parameter, which contains the methods "getName",
|
||||||
|
"getValue" and "getType". Parameters are also only converted to when necessary, and
|
||||||
|
not when they are set.
|
||||||
|
|
||||||
|
Also, related functions were affected:
|
||||||
|
|
||||||
|
* execute($parameters, $hydrationMode) the argument $parameters can be either an key=>value array or an ArrayCollection instance
|
||||||
|
* iterate($parameters, $hydrationMode) the argument $parameters can be either an key=>value array or an ArrayCollection instance
|
||||||
|
* setParameters($parameters) the argument $parameters can be either an key=>value array or an ArrayCollection instance
|
||||||
|
* getParameters() now returns ArrayCollection instead of array
|
||||||
|
* getParameter($key) now returns Parameter instance instead of parameter value
|
@ -19,15 +19,17 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM;
|
namespace Doctrine\ORM;
|
||||||
|
|
||||||
use Doctrine\DBAL\Types\Type,
|
use Doctrine\Common\Util\ClassUtils;
|
||||||
Doctrine\DBAL\Cache\QueryCacheProfile,
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
Doctrine\ORM\Query\QueryException,
|
|
||||||
Doctrine\Common\Util\ClassUtils;
|
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.
|
* Base contract for ORM queries. Base class for Query and NativeQuery.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @link www.doctrine-project.org
|
* @link www.doctrine-project.org
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||||
@ -62,14 +64,9 @@ abstract class AbstractQuery
|
|||||||
const HYDRATE_SIMPLEOBJECT = 5;
|
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();
|
protected $parameters;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array The parameter type map of this query.
|
|
||||||
*/
|
|
||||||
protected $_paramTypes = array();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var ResultSetMapping The user-specified ResultSetMapping to use.
|
* @var ResultSetMapping The user-specified ResultSetMapping to use.
|
||||||
@ -114,8 +111,18 @@ abstract class AbstractQuery
|
|||||||
public function __construct(EntityManager $em)
|
public function __construct(EntityManager $em)
|
||||||
{
|
{
|
||||||
$this->_em = $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.
|
* Retrieves the associated EntityManager of this Query instance.
|
||||||
*
|
*
|
||||||
@ -135,8 +142,8 @@ abstract class AbstractQuery
|
|||||||
*/
|
*/
|
||||||
public function free()
|
public function free()
|
||||||
{
|
{
|
||||||
$this->_params = array();
|
$this->parameters = new ArrayCollection();
|
||||||
$this->_paramTypes = array();
|
|
||||||
$this->_hints = array();
|
$this->_hints = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,57 +154,55 @@ abstract class AbstractQuery
|
|||||||
*/
|
*/
|
||||||
public function getParameters()
|
public function getParameters()
|
||||||
{
|
{
|
||||||
return $this->_params;
|
return $this->parameters;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all defined parameter types.
|
|
||||||
*
|
|
||||||
* @return array The defined query parameter types.
|
|
||||||
*/
|
|
||||||
public function getParameterTypes()
|
|
||||||
{
|
|
||||||
return $this->_paramTypes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a query parameter.
|
* Gets a query parameter.
|
||||||
*
|
*
|
||||||
* @param mixed $key The key (index or name) of the bound parameter.
|
* @param mixed $key The key (index or name) of the bound parameter.
|
||||||
|
*
|
||||||
* @return mixed The value of the bound parameter.
|
* @return mixed The value of the bound parameter.
|
||||||
*/
|
*/
|
||||||
public function getParameter($key)
|
public function getParameter($key)
|
||||||
{
|
{
|
||||||
if (isset($this->_params[$key])) {
|
$filteredParameters = $this->parameters->filter(
|
||||||
return $this->_params[$key];
|
function ($parameter) use ($key)
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a query parameter type.
|
|
||||||
*
|
|
||||||
* @param mixed $key The key (index or name) of the bound parameter.
|
|
||||||
* @return mixed The parameter type of the bound parameter.
|
|
||||||
*/
|
|
||||||
public function getParameterType($key)
|
|
||||||
{
|
{
|
||||||
if (isset($this->_paramTypes[$key])) {
|
// Must not be identical because of string to integer conversion
|
||||||
return $this->_paramTypes[$key];
|
return ($key == $parameter->getName());
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return null;
|
return count($filteredParameters) ? $filteredParameters->first() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the SQL query that corresponds to this query object.
|
* Sets a collection of query parameters.
|
||||||
* 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
|
* @param \Doctrine\Common\Collections\ArrayCollection|array $parameters
|
||||||
|
*
|
||||||
|
* @return \Doctrine\ORM\AbstractQuery This query instance.
|
||||||
*/
|
*/
|
||||||
abstract public function getSQL();
|
public function setParameters($parameters)
|
||||||
|
{
|
||||||
|
// BC compatibility with 2.3-
|
||||||
|
if (is_array($parameters)) {
|
||||||
|
$parameterCollection = new ArrayCollection();
|
||||||
|
|
||||||
|
foreach ($parameters as $key => $value) {
|
||||||
|
$parameter = new Query\Parameter($key, $value);
|
||||||
|
|
||||||
|
$parameterCollection->add($parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
$parameters = $parameterCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->parameters = $parameters;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a query parameter.
|
* Sets a query parameter.
|
||||||
@ -207,19 +212,29 @@ abstract class AbstractQuery
|
|||||||
* @param string $type The parameter type. If specified, the given value will be run through
|
* @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
|
* the type conversion of this type. This is usually not needed for
|
||||||
* strings and numeric types.
|
* strings and numeric types.
|
||||||
|
*
|
||||||
* @return \Doctrine\ORM\AbstractQuery This query instance.
|
* @return \Doctrine\ORM\AbstractQuery This query instance.
|
||||||
*/
|
*/
|
||||||
public function setParameter($key, $value, $type = null)
|
public function setParameter($key, $value, $type = null)
|
||||||
{
|
{
|
||||||
$key = trim($key, ':');
|
$filteredParameters = $this->parameters->filter(
|
||||||
$value = $this->processParameterValue($value);
|
function ($parameter) use ($key)
|
||||||
|
{
|
||||||
|
// Must not be identical because of string to integer conversion
|
||||||
|
return ($key == $parameter->getName());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if ($type === null) {
|
if (count($filteredParameters)) {
|
||||||
$type = Query\ParameterTypeInferer::inferType($value);
|
$parameter = $filteredParameters->first();
|
||||||
|
$parameter->setValue($value, $type);
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_paramTypes[$key] = $type;
|
$parameter = new Query\Parameter($key, $value, $type);
|
||||||
$this->_params[$key] = $value;
|
|
||||||
|
$this->parameters->add($parameter);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -230,7 +245,7 @@ abstract class AbstractQuery
|
|||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
private function processParameterValue($value)
|
public function processParameterValue($value)
|
||||||
{
|
{
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case is_array($value):
|
case is_array($value):
|
||||||
@ -249,7 +264,7 @@ abstract class AbstractQuery
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function convertObjectParameterToScalarValue($value)
|
private function convertObjectParameterToScalarValue($value)
|
||||||
{
|
{
|
||||||
$class = $this->_em->getClassMetadata(get_class($value));
|
$class = $this->_em->getClassMetadata(get_class($value));
|
||||||
|
|
||||||
@ -275,22 +290,6 @@ abstract class AbstractQuery
|
|||||||
return $value;
|
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.
|
* Sets the ResultSetMapping that should be used for hydration.
|
||||||
*
|
*
|
||||||
@ -530,37 +529,37 @@ abstract class AbstractQuery
|
|||||||
/**
|
/**
|
||||||
* Gets the list of results for the query.
|
* Gets the list of results for the query.
|
||||||
*
|
*
|
||||||
* Alias for execute(array(), $hydrationMode = HYDRATE_OBJECT).
|
* Alias for execute(null, $hydrationMode = HYDRATE_OBJECT).
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getResult($hydrationMode = self::HYDRATE_OBJECT)
|
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.
|
* Gets the array of results for the query.
|
||||||
*
|
*
|
||||||
* Alias for execute(array(), HYDRATE_ARRAY).
|
* Alias for execute(null, HYDRATE_ARRAY).
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getArrayResult()
|
public function getArrayResult()
|
||||||
{
|
{
|
||||||
return $this->execute(array(), self::HYDRATE_ARRAY);
|
return $this->execute(null, self::HYDRATE_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the scalar results for the query.
|
* Gets the scalar results for the query.
|
||||||
*
|
*
|
||||||
* Alias for execute(array(), HYDRATE_SCALAR).
|
* Alias for execute(null, HYDRATE_SCALAR).
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getScalarResult()
|
public function getScalarResult()
|
||||||
{
|
{
|
||||||
return $this->execute(array(), self::HYDRATE_SCALAR);
|
return $this->execute(null, self::HYDRATE_SCALAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -572,7 +571,7 @@ abstract class AbstractQuery
|
|||||||
*/
|
*/
|
||||||
public function getOneOrNullResult($hydrationMode = null)
|
public function getOneOrNullResult($hydrationMode = null)
|
||||||
{
|
{
|
||||||
$result = $this->execute(array(), $hydrationMode);
|
$result = $this->execute(null, $hydrationMode);
|
||||||
|
|
||||||
if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) {
|
if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) {
|
||||||
return null;
|
return null;
|
||||||
@ -604,7 +603,7 @@ abstract class AbstractQuery
|
|||||||
*/
|
*/
|
||||||
public function getSingleResult($hydrationMode = null)
|
public function getSingleResult($hydrationMode = null)
|
||||||
{
|
{
|
||||||
$result = $this->execute(array(), $hydrationMode);
|
$result = $this->execute(null, $hydrationMode);
|
||||||
|
|
||||||
if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) {
|
if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) {
|
||||||
throw new NoResultException;
|
throw new NoResultException;
|
||||||
@ -673,18 +672,18 @@ abstract class AbstractQuery
|
|||||||
* Executes the query and returns an IterableResult that can be used to incrementally
|
* Executes the query and returns an IterableResult that can be used to incrementally
|
||||||
* iterate over the result.
|
* iterate over the result.
|
||||||
*
|
*
|
||||||
* @param array $params The query parameters.
|
* @param \Doctrine\Common\Collections\ArrayCollection|array $parameters The query parameters.
|
||||||
* @param integer $hydrationMode The hydration mode to use.
|
* @param integer $hydrationMode The hydration mode to use.
|
||||||
* @return \Doctrine\ORM\Internal\Hydration\IterableResult
|
* @return \Doctrine\ORM\Internal\Hydration\IterableResult
|
||||||
*/
|
*/
|
||||||
public function iterate(array $params = array(), $hydrationMode = null)
|
public function iterate($parameters = null, $hydrationMode = null)
|
||||||
{
|
{
|
||||||
if ($hydrationMode !== null) {
|
if ($hydrationMode !== null) {
|
||||||
$this->setHydrationMode($hydrationMode);
|
$this->setHydrationMode($hydrationMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($params) {
|
if ( ! empty($parameters)) {
|
||||||
$this->setParameters($params);
|
$this->setParameters($parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
$stmt = $this->_doExecute();
|
$stmt = $this->_doExecute();
|
||||||
@ -697,18 +696,18 @@ abstract class AbstractQuery
|
|||||||
/**
|
/**
|
||||||
* Executes the query.
|
* Executes the query.
|
||||||
*
|
*
|
||||||
* @param array $params Any additional query parameters.
|
* @param \Doctrine\Common\Collections\ArrayCollection|array $parameters Query parameters.
|
||||||
* @param integer $hydrationMode Processing mode to be used during the hydration process.
|
* @param integer $hydrationMode Processing mode to be used during the hydration process.
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function execute($params = array(), $hydrationMode = null)
|
public function execute($parameters = null, $hydrationMode = null)
|
||||||
{
|
{
|
||||||
if ($hydrationMode !== null) {
|
if ($hydrationMode !== null) {
|
||||||
$this->setHydrationMode($hydrationMode);
|
$this->setHydrationMode($hydrationMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($params) {
|
if ( ! empty($parameters)) {
|
||||||
$this->setParameters($params);
|
$this->setParameters($parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
$setCacheEntry = function() {};
|
$setCacheEntry = function() {};
|
||||||
@ -730,6 +729,7 @@ abstract class AbstractQuery
|
|||||||
|
|
||||||
$setCacheEntry = function($data) use ($cache, $result, $cacheKey, $realCacheKey, $queryCacheProfile) {
|
$setCacheEntry = function($data) use ($cache, $result, $cacheKey, $realCacheKey, $queryCacheProfile) {
|
||||||
$result[$realCacheKey] = $data;
|
$result[$realCacheKey] = $data;
|
||||||
|
|
||||||
$cache->save($cacheKey, $result, $queryCacheProfile->getLifetime());
|
$cache->save($cacheKey, $result, $queryCacheProfile->getLifetime());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -760,19 +760,20 @@ abstract class AbstractQuery
|
|||||||
*/
|
*/
|
||||||
protected function getHydrationCacheId()
|
protected function getHydrationCacheId()
|
||||||
{
|
{
|
||||||
$params = $this->getParameters();
|
$parameters = array();
|
||||||
|
|
||||||
foreach ($params AS $key => $value) {
|
foreach ($this->getParameters()->getIterator() as $parameter) {
|
||||||
$params[$key] = $this->processParameterValue($value);
|
$parameters[$parameter->getName()] = $this->processParameterValue($parameter->getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = $this->getSQL();
|
$sql = $this->getSQL();
|
||||||
$queryCacheProfile = $this->getHydrationCacheProfile();
|
$queryCacheProfile = $this->getHydrationCacheProfile();
|
||||||
$hints = $this->getHints();
|
$hints = $this->getHints();
|
||||||
$hints['hydrationMode'] = $this->getHydrationMode();
|
$hints['hydrationMode'] = $this->getHydrationMode();
|
||||||
|
|
||||||
ksort($hints);
|
ksort($hints);
|
||||||
|
|
||||||
return $queryCacheProfile->generateCacheKeys($sql, $params, $hints);
|
return $queryCacheProfile->generateCacheKeys($sql, $parameters, $hints);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -817,8 +818,8 @@ abstract class AbstractQuery
|
|||||||
*/
|
*/
|
||||||
public function __clone()
|
public function __clone()
|
||||||
{
|
{
|
||||||
$this->_params = array();
|
$this->parameters = new ArrayCollection();
|
||||||
$this->_paramTypes = array();
|
|
||||||
$this->_hints = array();
|
$this->_hints = array();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,19 +58,30 @@ final class NativeQuery extends AbstractQuery
|
|||||||
*/
|
*/
|
||||||
protected function _doExecute()
|
protected function _doExecute()
|
||||||
{
|
{
|
||||||
$params = $this->_params;
|
$parameters = array();
|
||||||
$types = $this->_paramTypes;
|
$types = array();
|
||||||
|
|
||||||
if ($params && is_int(key($params))) {
|
foreach ($this->getParameters()->getIterator() as $parameter) {
|
||||||
ksort($params);
|
$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);
|
ksort($types);
|
||||||
|
|
||||||
$params = array_values($params);
|
$parameters = array_values($parameters);
|
||||||
$types = array_values($types);
|
$types = array_values($types);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->_em->getConnection()->executeQuery(
|
return $this->_em->getConnection()->executeQuery(
|
||||||
$this->_sql, $params, $types, $this->_queryCacheProfile
|
$this->_sql, $parameters, $types, $this->_queryCacheProfile
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,13 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM;
|
namespace Doctrine\ORM;
|
||||||
|
|
||||||
use Doctrine\DBAL\LockMode,
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
Doctrine\ORM\Query\Parser,
|
|
||||||
Doctrine\ORM\Query\ParserResult,
|
use Doctrine\DBAL\LockMode;
|
||||||
Doctrine\ORM\Query\QueryException;
|
|
||||||
|
use Doctrine\ORM\Query\Parser;
|
||||||
|
use Doctrine\ORM\Query\ParserResult;
|
||||||
|
use Doctrine\ORM\Query\QueryException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Query object represents a DQL query.
|
* A Query object represents a DQL query.
|
||||||
@ -248,7 +251,7 @@ final class Query extends AbstractQuery
|
|||||||
// Prepare parameters
|
// Prepare parameters
|
||||||
$paramMappings = $this->_parserResult->getParameterMappings();
|
$paramMappings = $this->_parserResult->getParameterMappings();
|
||||||
|
|
||||||
if (count($paramMappings) != count($this->_params)) {
|
if (count($paramMappings) != count($this->parameters)) {
|
||||||
throw QueryException::invalidParameterNumber();
|
throw QueryException::invalidParameterNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,17 +272,23 @@ final class Query extends AbstractQuery
|
|||||||
*/
|
*/
|
||||||
private function processParameterMappings($paramMappings)
|
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])) {
|
if ( ! isset($paramMappings[$key])) {
|
||||||
throw QueryException::unknownParameter($key);
|
throw QueryException::unknownParameter($key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($this->_paramTypes[$key])) {
|
$value = $this->processParameterValue($parameter->getValue());
|
||||||
|
$type = ($parameter->getValue() === $value)
|
||||||
|
? $parameter->getType()
|
||||||
|
: Query\ParameterTypeInferer::inferType($value);
|
||||||
|
|
||||||
foreach ($paramMappings[$key] as $position) {
|
foreach ($paramMappings[$key] as $position) {
|
||||||
$types[$position] = $this->_paramTypes[$key];
|
$types[$position] = $type;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$sqlPositions = $paramMappings[$key];
|
$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
|
* Executes the query and returns an IterableResult that can be used to incrementally
|
||||||
* iterated over the result.
|
* iterated over the result.
|
||||||
*
|
*
|
||||||
* @param array $params The query parameters.
|
* @param \Doctrine\Common\Collections\ArrayCollection|array $parameters The query parameters.
|
||||||
* @param integer $hydrationMode The hydration mode to use.
|
* @param integer $hydrationMode The hydration mode to use.
|
||||||
* @return \Doctrine\ORM\Internal\Hydration\IterableResult
|
* @return \Doctrine\ORM\Internal\Hydration\IterableResult
|
||||||
*/
|
*/
|
||||||
public function iterate(array $params = array(), $hydrationMode = self::HYDRATE_OBJECT)
|
public function iterate($parameters = null, $hydrationMode = self::HYDRATE_OBJECT)
|
||||||
{
|
{
|
||||||
$this->setHint(self::HINT_INTERNAL_ITERATION, true);
|
$this->setHint(self::HINT_INTERNAL_ITERATION, true);
|
||||||
|
|
||||||
return parent::iterate($params, $hydrationMode);
|
return parent::iterate($parameters, $hydrationMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,9 +19,11 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Query\Exec;
|
namespace Doctrine\ORM\Query\Exec;
|
||||||
|
|
||||||
use Doctrine\DBAL\Connection,
|
use Doctrine\DBAL\Connection;
|
||||||
Doctrine\DBAL\Types\Type,
|
use Doctrine\DBAL\Types\Type;
|
||||||
Doctrine\ORM\Query\AST;
|
|
||||||
|
use Doctrine\ORM\Query\ParameterTypeInferer;
|
||||||
|
use Doctrine\ORM\Query\AST;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the SQL statements for bulk DQL UPDATE statements on classes in
|
* 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: parameters can be more deeply nested. traverse the tree.
|
||||||
//FIXME (URGENT): With query cache the parameter is out of date. Move to execute() stage.
|
//FIXME (URGENT): With query cache the parameter is out of date. Move to execute() stage.
|
||||||
if ($newValue instanceof AST\InputParameter) {
|
if ($newValue instanceof AST\InputParameter) {
|
||||||
$paramKey = $newValue->name;
|
$parameterName = $newValue->name;
|
||||||
$this->_sqlParameters[$i]['parameters'][] = $sqlWalker->getQuery()->getParameter($paramKey);
|
$parameter = $sqlWalker->getQuery()->getParameter($parameterName);
|
||||||
$this->_sqlParameters[$i]['types'][] = $sqlWalker->getQuery()->getParameterType($paramKey);
|
|
||||||
|
$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;
|
++$this->_numParametersInUpdateClause;
|
||||||
}
|
}
|
||||||
|
101
lib/Doctrine/ORM/Query/Parameter.php
Normal file
101
lib/Doctrine/ORM/Query/Parameter.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -1687,7 +1687,6 @@ class SqlWalker implements TreeWalker
|
|||||||
// InputParameter
|
// InputParameter
|
||||||
case ($entityExpr instanceof AST\InputParameter):
|
case ($entityExpr instanceof AST\InputParameter):
|
||||||
$dqlParamKey = $entityExpr->name;
|
$dqlParamKey = $entityExpr->name;
|
||||||
$entity = $this->_query->getParameter($dqlParamKey);
|
|
||||||
$entitySql = '?';
|
$entitySql = '?';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1853,7 +1852,6 @@ class SqlWalker implements TreeWalker
|
|||||||
|
|
||||||
$dqlAlias = $instanceOfExpr->identificationVariable;
|
$dqlAlias = $instanceOfExpr->identificationVariable;
|
||||||
$discrClass = $class = $this->_queryComponents[$dqlAlias]['metadata'];
|
$discrClass = $class = $this->_queryComponents[$dqlAlias]['metadata'];
|
||||||
$fieldName = null;
|
|
||||||
|
|
||||||
if ($class->discriminatorColumn) {
|
if ($class->discriminatorColumn) {
|
||||||
$discrClass = $this->_em->getClassMetadata($class->rootEntityName);
|
$discrClass = $this->_em->getClassMetadata($class->rootEntityName);
|
||||||
@ -1871,7 +1869,8 @@ class SqlWalker implements TreeWalker
|
|||||||
if ($parameter instanceof AST\InputParameter) {
|
if ($parameter instanceof AST\InputParameter) {
|
||||||
// We need to modify the parameter value to be its correspondent mapped value
|
// We need to modify the parameter value to be its correspondent mapped value
|
||||||
$dqlParamKey = $parameter->name;
|
$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)) {
|
if ( ! ($paramValue instanceof \Doctrine\ORM\Mapping\ClassMetadata)) {
|
||||||
throw QueryException::invalidParameterType('ClassMetadata', get_class($paramValue));
|
throw QueryException::invalidParameterType('ClassMetadata', get_class($paramValue));
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM;
|
namespace Doctrine\ORM;
|
||||||
|
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
|
||||||
use Doctrine\ORM\Query\Expr;
|
use Doctrine\ORM\Query\Expr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,14 +79,9 @@ class QueryBuilder
|
|||||||
private $_dql;
|
private $_dql;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array The query parameters.
|
* @var \Doctrine\Common\Collections\ArrayCollection The query parameters.
|
||||||
*/
|
*/
|
||||||
private $_params = array();
|
private $parameters = array();
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array The parameter type map of this query.
|
|
||||||
*/
|
|
||||||
private $_paramTypes = array();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var integer The index of the first result to retrieve.
|
* @var integer The index of the first result to retrieve.
|
||||||
@ -109,6 +106,7 @@ class QueryBuilder
|
|||||||
public function __construct(EntityManager $em)
|
public function __construct(EntityManager $em)
|
||||||
{
|
{
|
||||||
$this->_em = $em;
|
$this->_em = $em;
|
||||||
|
$this->parameters = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -218,8 +216,10 @@ class QueryBuilder
|
|||||||
*/
|
*/
|
||||||
public function getQuery()
|
public function getQuery()
|
||||||
{
|
{
|
||||||
|
$parameters = clone $this->parameters;
|
||||||
|
|
||||||
return $this->_em->createQuery($this->getDQL())
|
return $this->_em->createQuery($this->getDQL())
|
||||||
->setParameters($this->_params, $this->_paramTypes)
|
->setParameters($parameters)
|
||||||
->setFirstResult($this->_firstResult)
|
->setFirstResult($this->_firstResult)
|
||||||
->setMaxResults($this->_maxResults);
|
->setMaxResults($this->_maxResults);
|
||||||
}
|
}
|
||||||
@ -355,10 +355,7 @@ class QueryBuilder
|
|||||||
*/
|
*/
|
||||||
public function setParameter($key, $value, $type = null)
|
public function setParameter($key, $value, $type = null)
|
||||||
{
|
{
|
||||||
$key = trim($key, ':');
|
$this->parameters->add(new Query\Parameter($key, $value, $type));
|
||||||
|
|
||||||
$this->_paramTypes[$key] = $type ?: Query\ParameterTypeInferer::inferType($value);
|
|
||||||
$this->_params[$key] = $value;
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -371,20 +368,18 @@ class QueryBuilder
|
|||||||
* ->select('u')
|
* ->select('u')
|
||||||
* ->from('User', 'u')
|
* ->from('User', 'u')
|
||||||
* ->where('u.id = :user_id1 OR u.id = :user_id2')
|
* ->where('u.id = :user_id1 OR u.id = :user_id2')
|
||||||
* ->setParameters(array(
|
* ->setParameters(new ArrayCollection(array(
|
||||||
* 'user_id1' => 1,
|
* new Parameter('user_id1', 1),
|
||||||
* 'user_id2' => 2
|
* new Parameter('user_id2', 2)
|
||||||
));
|
)));
|
||||||
* </code>
|
* </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.
|
* @return QueryBuilder This QueryBuilder instance.
|
||||||
*/
|
*/
|
||||||
public function setParameters(array $params, array $types = array())
|
public function setParameters(ArrayCollection $parameters)
|
||||||
{
|
{
|
||||||
foreach ($params as $key => $value) {
|
$this->parameters = $parameters;
|
||||||
$this->setParameter($key, $value, isset($types[$key]) ? $types[$key] : null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -396,18 +391,25 @@ class QueryBuilder
|
|||||||
*/
|
*/
|
||||||
public function getParameters()
|
public function getParameters()
|
||||||
{
|
{
|
||||||
return $this->_params;
|
return $this->parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a (previously set) query parameter of the query being constructed.
|
* Gets a (previously set) query parameter of the query being constructed.
|
||||||
*
|
*
|
||||||
* @param mixed $key The key (index or name) of the bound parameter.
|
* @param mixed $key The key (index or name) of the bound parameter.
|
||||||
|
*
|
||||||
* @return mixed The value of the bound parameter.
|
* @return mixed The value of the bound parameter.
|
||||||
*/
|
*/
|
||||||
public function getParameter($key)
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,6 +14,7 @@ class HydrationCacheTest extends OrmFunctionalTestCase
|
|||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
$this->useModelSet('cms');
|
$this->useModelSet('cms');
|
||||||
|
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$user = new CmsUser;
|
$user = new CmsUser;
|
||||||
@ -78,8 +79,11 @@ class HydrationCacheTest extends OrmFunctionalTestCase
|
|||||||
->setHydrationCacheProfile(new QueryCacheProfile(null, null, $cache));
|
->setHydrationCacheProfile(new QueryCacheProfile(null, null, $cache));
|
||||||
|
|
||||||
$query->getResult();
|
$query->getResult();
|
||||||
|
|
||||||
$c = $this->getCurrentQueryCount();
|
$c = $this->getCurrentQueryCount();
|
||||||
|
|
||||||
$query->getResult();
|
$query->getResult();
|
||||||
|
|
||||||
$this->assertEquals($c, $this->getCurrentQueryCount(), "Should not execute query. Its cached!");
|
$this->assertEquals($c, $this->getCurrentQueryCount(), "Should not execute query. Its cached!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,12 @@
|
|||||||
|
|
||||||
namespace Doctrine\Tests\ORM\Functional;
|
namespace Doctrine\Tests\ORM\Functional;
|
||||||
|
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
|
||||||
use Doctrine\ORM\Query\ResultSetMapping;
|
use Doctrine\ORM\Query\ResultSetMapping;
|
||||||
use Doctrine\ORM\Query\ResultSetMappingBuilder;
|
use Doctrine\ORM\Query\ResultSetMappingBuilder;
|
||||||
|
use Doctrine\ORM\Query\Parameter;
|
||||||
|
|
||||||
use Doctrine\Tests\Models\CMS\CmsUser;
|
use Doctrine\Tests\Models\CMS\CmsUser;
|
||||||
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
|
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
|
||||||
use Doctrine\Tests\Models\CMS\CmsAddress;
|
use Doctrine\Tests\Models\CMS\CmsAddress;
|
||||||
@ -191,6 +195,10 @@ class NativeQueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
|
|
||||||
public function testFluentInterface()
|
public function testFluentInterface()
|
||||||
{
|
{
|
||||||
|
$parameters = new ArrayCollection;
|
||||||
|
$parameters->add(new Parameter(1, 'foo'));
|
||||||
|
$parameters->add(new Parameter(2, 'bar'));
|
||||||
|
|
||||||
$rsm = new ResultSetMapping;
|
$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);
|
$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)
|
->expireResultCache(true)
|
||||||
->setHint('foo', 'bar')
|
->setHint('foo', 'bar')
|
||||||
->setParameter(1, 'foo')
|
->setParameter(1, 'foo')
|
||||||
->setParameters(array(2 => 'bar'))
|
->setParameters($parameters)
|
||||||
->setResultCacheDriver(null)
|
->setResultCacheDriver(null)
|
||||||
->setResultCacheLifetime(3500);
|
->setResultCacheLifetime(3500);
|
||||||
|
|
||||||
|
@ -19,10 +19,13 @@ class QueryCacheTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
*/
|
*/
|
||||||
private $cacheDataReflection;
|
private $cacheDataReflection;
|
||||||
|
|
||||||
protected function setUp() {
|
protected function setUp()
|
||||||
|
{
|
||||||
$this->cacheDataReflection = new \ReflectionProperty("Doctrine\Common\Cache\ArrayCache", "data");
|
$this->cacheDataReflection = new \ReflectionProperty("Doctrine\Common\Cache\ArrayCache", "data");
|
||||||
$this->cacheDataReflection->setAccessible(true);
|
$this->cacheDataReflection->setAccessible(true);
|
||||||
|
|
||||||
$this->useModelSet('cms');
|
$this->useModelSet('cms');
|
||||||
|
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,11 +2,16 @@
|
|||||||
|
|
||||||
namespace Doctrine\Tests\ORM\Functional;
|
namespace Doctrine\Tests\ORM\Functional;
|
||||||
|
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
|
||||||
use Doctrine\DBAL\Connection;
|
use Doctrine\DBAL\Connection;
|
||||||
use Doctrine\Tests\Models\CMS\CmsUser,
|
|
||||||
Doctrine\Tests\Models\CMS\CmsArticle;
|
|
||||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
use Doctrine\ORM\Query;
|
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';
|
require_once __DIR__ . '/../../TestInit.php';
|
||||||
|
|
||||||
@ -149,9 +154,22 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function testSetParameters()
|
public function testSetParameters()
|
||||||
|
{
|
||||||
|
$q = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = ?1 AND u.status = ?2');
|
||||||
|
|
||||||
|
$parameters = new ArrayCollection();
|
||||||
|
$parameters->add(new Parameter(1, 'jwage'));
|
||||||
|
$parameters->add(new Parameter(2, 'active'));
|
||||||
|
|
||||||
|
$q->setParameters($parameters);
|
||||||
|
$users = $q->getResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSetParametersBackwardsCompatible()
|
||||||
{
|
{
|
||||||
$q = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = ?1 AND u.status = ?2');
|
$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'));
|
$q->setParameters(array(1 => 'jwage', 2 => 'active'));
|
||||||
|
|
||||||
$users = $q->getResult();
|
$users = $q->getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,7 +194,7 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
$articleId = $article1->id;
|
$articleId = $article1->id;
|
||||||
|
|
||||||
$query = $this->_em->createQuery("select a from Doctrine\Tests\Models\CMS\CmsArticle a WHERE a.topic = ?1");
|
$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();
|
$found = array();
|
||||||
foreach ($articles AS $article) {
|
foreach ($articles AS $article) {
|
||||||
@ -520,10 +538,10 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
$this->_em->clear();
|
$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 = $this->_em->createQuery("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.status = :a AND u.id IN (:b)");
|
||||||
$query->setParameters(array(
|
$query->setParameters(new ArrayCollection(array(
|
||||||
'b' => array($user1->id, $user2->id, $user3->id),
|
new Parameter('b', array($user1->id, $user2->id, $user3->id)),
|
||||||
'a' => 'developer',
|
new Parameter('a', 'developer')
|
||||||
));
|
)));
|
||||||
$result = $query->getResult();
|
$result = $query->getResult();
|
||||||
|
|
||||||
$this->assertEquals(3, count($result));
|
$this->assertEquals(3, count($result));
|
||||||
@ -639,7 +657,7 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
/**
|
/**
|
||||||
* @group DDC-1651
|
* @group DDC-1651
|
||||||
*/
|
*/
|
||||||
public function testSetParameterBindingSingleIdentifierObjectConverted()
|
public function testSetParameterBindingSingleIdentifierObject()
|
||||||
{
|
{
|
||||||
$userC = new CmsUser;
|
$userC = new CmsUser;
|
||||||
$userC->name = 'Jonathan';
|
$userC->name = 'Jonathan';
|
||||||
@ -653,7 +671,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 = $this->_em->createQuery("SELECT DISTINCT u from Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1");
|
||||||
$q->setParameter(1, $userC);
|
$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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
namespace Doctrine\Tests\ORM\Query;
|
namespace Doctrine\Tests\ORM\Query;
|
||||||
|
|
||||||
use Doctrine\Common\Cache\ArrayCache;
|
use Doctrine\Common\Cache\ArrayCache;
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Query\Parameter;
|
||||||
|
|
||||||
class QueryTest extends \Doctrine\Tests\OrmTestCase
|
class QueryTest extends \Doctrine\Tests\OrmTestCase
|
||||||
{
|
{
|
||||||
@ -16,21 +19,34 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
public function testGetParameters()
|
public function testGetParameters()
|
||||||
{
|
{
|
||||||
$query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1");
|
$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()
|
public function testGetParameters_HasSomeAlready()
|
||||||
{
|
{
|
||||||
$query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1");
|
$query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1");
|
||||||
$query->setParameter(2, 84);
|
$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()
|
public function testSetParameters()
|
||||||
{
|
{
|
||||||
$query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1");
|
$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()
|
public function testFree()
|
||||||
@ -40,7 +56,7 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
|
|
||||||
$query->free();
|
$query->free();
|
||||||
|
|
||||||
$this->assertEquals(array(), $query->getParameters());
|
$this->assertEquals(0, count($query->getParameters()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testClone()
|
public function testClone()
|
||||||
@ -54,7 +70,7 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
$cloned = clone $query;
|
$cloned = clone $query;
|
||||||
|
|
||||||
$this->assertEquals($dql, $cloned->getDql());
|
$this->assertEquals($dql, $cloned->getDql());
|
||||||
$this->assertEquals(array(), $cloned->getParameters());
|
$this->assertEquals(0, count($cloned->getParameters()));
|
||||||
$this->assertFalse($cloned->getHint('foo'));
|
$this->assertFalse($cloned->getHint('foo'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +84,7 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
->setHint('foo', 'bar')
|
->setHint('foo', 'bar')
|
||||||
->setHint('bar', 'baz')
|
->setHint('bar', 'baz')
|
||||||
->setParameter(1, 'bar')
|
->setParameter(1, 'bar')
|
||||||
->setParameters(array(2 => 'baz'))
|
->setParameters(new ArrayCollection(array(new Parameter(2, 'baz'))))
|
||||||
->setResultCacheDriver(null)
|
->setResultCacheDriver(null)
|
||||||
->setResultCacheId('foo')
|
->setResultCacheId('foo')
|
||||||
->setDql('foo')
|
->setDql('foo')
|
||||||
@ -129,7 +145,7 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
/**
|
/**
|
||||||
* @group DDC-1697
|
* @group DDC-1697
|
||||||
*/
|
*/
|
||||||
public function testKeyValueParameters()
|
public function testCollectionParameters()
|
||||||
{
|
{
|
||||||
$cities = array(
|
$cities = array(
|
||||||
0 => "Paris",
|
0 => "Paris",
|
||||||
@ -142,8 +158,9 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
->setParameter('cities', $cities);
|
->setParameter('cities', $cities);
|
||||||
|
|
||||||
$parameters = $query->getParameters();
|
$parameters = $query->getParameters();
|
||||||
|
$parameter = $parameters->first();
|
||||||
|
|
||||||
$this->assertArrayHasKey('cities', $parameters);
|
$this->assertEquals('cities', $parameter->getName());
|
||||||
$this->assertEquals($cities, $parameters['cities']);
|
$this->assertEquals($cities, $parameter->getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,12 @@
|
|||||||
|
|
||||||
namespace Doctrine\Tests\ORM;
|
namespace Doctrine\Tests\ORM;
|
||||||
|
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
|
||||||
use Doctrine\ORM\QueryBuilder,
|
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';
|
require_once __DIR__ . '/../TestInit.php';
|
||||||
|
|
||||||
@ -385,7 +389,9 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
->where('u.id = :id')
|
->where('u.id = :id')
|
||||||
->setParameter('id', 1);
|
->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()
|
public function testSetParameters()
|
||||||
@ -395,9 +401,13 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||||
->where($qb->expr()->orx('u.username = :username', 'u.username = :username2'));
|
->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')
|
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||||
->where('u.id = :id');
|
->where('u.id = :id');
|
||||||
|
|
||||||
$qb->setParameters(array('id' => 1));
|
$parameters = new ArrayCollection();
|
||||||
$this->assertEquals(array('id' => 1), $qb->getParameters());
|
$parameters->add(new Parameter('id', 1));
|
||||||
|
|
||||||
|
$qb->setParameters($parameters);
|
||||||
|
|
||||||
|
$this->assertEquals($parameters, $qb->getParameters());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetParameter()
|
public function testGetParameter()
|
||||||
@ -419,8 +433,12 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||||
->where('u.id = :id');
|
->where('u.id = :id');
|
||||||
|
|
||||||
$qb->setParameters(array('id' => 1));
|
$parameters = new ArrayCollection();
|
||||||
$this->assertEquals(1, $qb->getParameter('id'));
|
$parameters->add(new Parameter('id', 1));
|
||||||
|
|
||||||
|
$qb->setParameters($parameters);
|
||||||
|
|
||||||
|
$this->assertEquals($parameters->first(), $qb->getParameter('id'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMultipleWhere()
|
public function testMultipleWhere()
|
||||||
@ -536,6 +554,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
$qb->setParameter('name', 'romanb');
|
$qb->setParameter('name', 'romanb');
|
||||||
|
|
||||||
$q1 = $qb->getQuery();
|
$q1 = $qb->getQuery();
|
||||||
|
|
||||||
$this->assertEquals('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = :name', $q1->getDql());
|
$this->assertEquals('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = :name', $q1->getDql());
|
||||||
$this->assertEquals(1, count($q1->getParameters()));
|
$this->assertEquals(1, count($q1->getParameters()));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user