From 8e3fdc5adc0facd4b44f9054ab3681e46131ba8a Mon Sep 17 00:00:00 2001 From: Guilherme Blanco Date: Thu, 12 May 2011 23:05:45 -0300 Subject: [PATCH] [DDC-1148] Implement auto-inference of types in setParameter. --- lib/Doctrine/ORM/AbstractQuery.php | 7 +- .../ORM/Query/ParameterTypeInferer.php | 72 +++++++++++++++++++ lib/Doctrine/ORM/QueryBuilder.php | 7 +- .../Tests/ORM/Functional/QueryTest.php | 32 +++++++++ .../Tests/ORM/Tools/EntityGeneratorTest.php | 2 +- 5 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 lib/Doctrine/ORM/Query/ParameterTypeInferer.php diff --git a/lib/Doctrine/ORM/AbstractQuery.php b/lib/Doctrine/ORM/AbstractQuery.php index 5ed1ef9e5..26eee1fb8 100644 --- a/lib/Doctrine/ORM/AbstractQuery.php +++ b/lib/Doctrine/ORM/AbstractQuery.php @@ -195,10 +195,13 @@ abstract class AbstractQuery */ public function setParameter($key, $value, $type = null) { - if ($type !== null) { - $this->_paramTypes[$key] = $type; + if ($type === null) { + $type = Query\ParameterTypeInferer::inferType($value); } + + $this->_paramTypes[$key] = $type; $this->_params[$key] = $value; + return $this; } diff --git a/lib/Doctrine/ORM/Query/ParameterTypeInferer.php b/lib/Doctrine/ORM/Query/ParameterTypeInferer.php new file mode 100644 index 000000000..d0e3e24b5 --- /dev/null +++ b/lib/Doctrine/ORM/Query/ParameterTypeInferer.php @@ -0,0 +1,72 @@ +. + */ + +namespace Doctrine\ORM\Query; + +use Doctrine\DBAL\Connection, + Doctrine\DBAL\Types\Type; + +/** + * Provides an enclosed support for parameter infering. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ParameterTypeInferer +{ + /** + * Infer type of a given value, returning a compatible constant: + * - Type (Doctrine\DBAL\Types\Type::*) + * - Connection (Doctrine\DBAL\Connection::PARAM_*) + * + * @param mixed $value Parameter value + * + * @return mixed Parameter type constant + */ + public static function inferType($value) + { + switch (true) { + case is_integer($value): + return Type::INTEGER; + + case ($value instanceof \DateTime): + return Type::DATETIME; + + case is_array($value): + $key = key($value); + + if (is_integer($value[$key])) { + return Connection::PARAM_INT_ARRAY; + } + + return Connection::PARAM_STR_ARRAY; + + default: + // Do nothing + break; + } + + return \PDO::PARAM_STR; + } +} \ No newline at end of file diff --git a/lib/Doctrine/ORM/QueryBuilder.php b/lib/Doctrine/ORM/QueryBuilder.php index 74782702d..ded27bdd8 100644 --- a/lib/Doctrine/ORM/QueryBuilder.php +++ b/lib/Doctrine/ORM/QueryBuilder.php @@ -256,10 +256,13 @@ class QueryBuilder */ public function setParameter($key, $value, $type = null) { - if ($type !== null) { - $this->_paramTypes[$key] = $type; + if ($type === null) { + $type = Query\ParameterTypeInferer::inferType($value); } + + $this->_paramTypes[$key] = $type; $this->_params[$key] = $value; + return $this; } diff --git a/tests/Doctrine/Tests/ORM/Functional/QueryTest.php b/tests/Doctrine/Tests/ORM/Functional/QueryTest.php index 323d0e88f..ac05749be 100644 --- a/tests/Doctrine/Tests/ORM/Functional/QueryTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/QueryTest.php @@ -2,6 +2,7 @@ namespace Doctrine\Tests\ORM\Functional; +use Doctrine\DBAL\Connection; use Doctrine\Tests\Models\CMS\CmsUser, Doctrine\Tests\Models\CMS\CmsArticle; use Doctrine\ORM\Mapping\ClassMetadata; @@ -455,4 +456,35 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase $query = $this->_em->createQuery("select u.username from Doctrine\Tests\Models\CMS\CmsUser u where u.username = 'gblanco'"); $this->assertNull($query->getOneOrNullResult(Query::HYDRATE_SCALAR)); } + + public function testDqlWithAutoInferOfParameters() + { + $user = new CmsUser; + $user->name = 'Benjamin'; + $user->username = 'beberlei'; + $user->status = 'developer'; + $this->_em->persist($user); + + $user = new CmsUser; + $user->name = 'Roman'; + $user->username = 'romanb'; + $user->status = 'developer'; + $this->_em->persist($user); + + $user = new CmsUser; + $user->name = 'Jonathan'; + $user->username = 'jwage'; + $user->status = 'developer'; + $this->_em->persist($user); + + $this->_em->flush(); + $this->_em->clear(); + + $query = $this->_em->createQuery("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username IN (?0)"); + $query->setParameter(0, array('beberlei', 'jwage')); + + $users = $query->execute(); + + $this->assertEquals(2, count($users)); + } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php b/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php index 5a9c5d7eb..d7cd56132 100644 --- a/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php @@ -122,7 +122,7 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase $this->_generator->writeEntityClass($metadata, $this->_tmpDir); - $this->assertFileExists($this->_tmpDir . "/" . $this->_namespace . "/~EntityGeneratorBook.php"); + $this->assertFileExists($this->_tmpDir . "/" . $this->_namespace . "/EntityGeneratorBook.php~"); $book = $this->newInstance($metadata); $reflClass = new \ReflectionClass($metadata->name);