1
0
mirror of synced 2024-12-05 03:06:05 +03:00

Merge pull request #1339 from BenMorel/dqlcustomtype

[DDC-2224] Honor convertToDatabaseValueSQL() in DQL query parameters
This commit is contained in:
Marco Pivetta 2015-03-25 01:27:05 +00:00
commit cf1ecffb14
3 changed files with 111 additions and 4 deletions

View File

@ -130,6 +130,13 @@ final class Query extends AbstractQuery
*/
private $_state = self::STATE_CLEAN;
/**
* A snapshot of the parameter types the query was parsed with.
*
* @var array
*/
private $_parsedTypes = array();
/**
* Cached DQL query.
*
@ -234,12 +241,20 @@ final class Query extends AbstractQuery
*/
private function _parse()
{
$types = array();
foreach ($this->parameters as $parameter) {
/** @var Query\Parameter $parameter */
$types[$parameter->getName()] = $parameter->getType();
}
// Return previous parser result if the query and the filter collection are both clean
if ($this->_state === self::STATE_CLEAN && $this->_em->isFiltersStateClean()) {
if ($this->_state === self::STATE_CLEAN && $this->_parsedTypes === $types && $this->_em->isFiltersStateClean()) {
return $this->_parserResult;
}
$this->_state = self::STATE_CLEAN;
$this->_parsedTypes = $types;
// Check query cache.
if ( ! ($this->_useQueryCache && ($queryCache = $this->getQueryCacheDriver()))) {
@ -678,8 +693,6 @@ final class Query extends AbstractQuery
/**
* Generate a cache id for the query cache - reusing the Result-Cache-Id generator.
*
* The query cache
*
* @return string
*/
protected function _getQueryCacheId()
@ -696,7 +709,7 @@ final class Query extends AbstractQuery
'&platform=' . $platform .
($this->_em->hasFilters() ? $this->_em->getFilters()->getHash() : '') .
'&firstResult=' . $this->_firstResult . '&maxResult=' . $this->_maxResults .
'&hydrationMode='.$this->_hydrationMode.'DOCTRINE_QUERY_CACHE_SALT'
'&hydrationMode=' . $this->_hydrationMode . '&types=' . serialize($this->_parsedTypes) . 'DOCTRINE_QUERY_CACHE_SALT'
);
}

View File

@ -2203,6 +2203,12 @@ class SqlWalker implements TreeWalker
{
$this->parserResult->addParameterMapping($inputParam->name, $this->sqlParamIndex++);
$parameter = $this->query->getParameter($inputParam->name);
if ($parameter && Type::hasType($type = $parameter->getType())) {
return Type::getType($type)->convertToDatabaseValueSQL('?', $this->platform);
}
return '?';
}

View File

@ -0,0 +1,88 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Common\Cache\ArrayCache;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\ORM\Query;
/**
* @group DDC-2224
*/
class DDC2224Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public static function setUpBeforeClass()
{
\Doctrine\DBAL\Types\Type::addType('DDC2224Type', __NAMESPACE__ . '\DDC2224Type');
}
public function testIssue()
{
$dql = 'SELECT e FROM ' . __NAMESPACE__ . '\DDC2224Entity e WHERE e.field = :field';
$query = $this->_em->createQuery($dql);
$query->setQueryCacheDriver(new ArrayCache());
$query->setParameter('field', 'test', 'DDC2224Type');
$this->assertStringEndsWith('.field = FUNCTION(?)', $query->getSQL());
return $query;
}
/**
* @depends testIssue
*/
public function testCacheMissWhenTypeChanges(Query $query)
{
$query->setParameter('field', 'test', 'string');
$this->assertStringEndsWith('.field = ?', $query->getSQL());
}
}
class DDC2224Type extends Type
{
/**
* {@inheritdoc}
*/
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
return $platform->getVarcharTypeDeclarationSQL($fieldDeclaration);
}
public function getName()
{
return 'DDC2224Type';
}
/**
* {@inheritdoc}
*/
public function canRequireSQLConversion()
{
return true;
}
/**
* {@inheritdoc}
*/
public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform)
{
return sprintf('FUNCTION(%s)', $sqlExpr);
}
}
/**
* @Entity
*/
class DDC2224Entity
{
/**
* @Id @GeneratedValue @Column(type="integer")
*/
public $id;
/**
* @Column(type="DDC2224Type")
*/
public $field;
}