From 783c53d57c622b10a182a2db99dab322296b4556 Mon Sep 17 00:00:00 2001 From: Josiah Truasheim Date: Fri, 31 Aug 2012 17:52:46 +0700 Subject: [PATCH 1/6] Added a failing test for DDC-2003 --- .../EntityRepositoryCriteriaTest.php | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 tests/Doctrine/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php new file mode 100644 index 000000000..3f37a2307 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php @@ -0,0 +1,71 @@ + + */ +class EntityRepositoryCriteriaTest extends \Doctrine\Tests\OrmFunctionalTestCase +{ + protected function setUp() { + $this->useModelSet('generic'); + parent::setUp(); + } + + public function tearDown() + { + if ($this->_em) { + $this->_em->getConfiguration()->setEntityNamespaces(array()); + } + parent::tearDown(); + } + + public function loadFixture() + { + $today = new DateTimeModel(); + $today->datetime = + $today->date = + $today->time = + new \DateTime('today'); + $this->_em->persist($today); + + $tomorrow = new DateTimeModel(); + $tomorrow->datetime = + $tomorrow->date = + $tomorrow->time = + new \DateTime('tomorrow'); + $this->_em->persist($tomorrow); + + $yesterday = new DateTimeModel(); + $yesterday->datetime = + $yesterday->date = + $yesterday->time = + new \DateTime('yesterday'); + $this->_em->persist($yesterday); + + $this->_em->flush(); + + unset($today); + unset($tomorrow); + unset($yesterday); + + $this->_em->clear(); + } + + public function testLteDateComparison() + { + $this->loadFixture(); + + $repository = $this->_em->getRepository('Doctrine\Tests\Models\Generic\DateTimeModel'); + $dates = $repository->matching(new Criteria( + Criteria::expr()->lte('datetime', new \DateTime('today')) + )); + + $this->assertEquals(2, count($dates)); + } +} From c7f5d9d77de7c3ffde23e841d815bb2440b994bf Mon Sep 17 00:00:00 2001 From: Josiah Truasheim Date: Fri, 31 Aug 2012 18:12:44 +0700 Subject: [PATCH 2/6] Fixed DDC-2003 using closures to reference the functionality of the calling entity persister from the SQL value visitor. --- .../ORM/Persisters/BasicEntityPersister.php | 10 +++- .../ORM/Persisters/SqlValueVisitor.php | 51 +++++++++++-------- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php index ed3485386..b96aec46c 100644 --- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php @@ -808,7 +808,15 @@ class BasicEntityPersister return array(array(), array()); } - $valueVisitor = new SqlValueVisitor($this->_class); + $persister = $this; + $valueVisitor = new SqlValueVisitor( + function ($field, $value) use($persister) { + return $persister->getType($field, $value); + }, + function ($value) use($persister) { + return $persister->getValue($value); + } + ); $valueVisitor->dispatch($expression); return $valueVisitor->getParamsAndTypes(); diff --git a/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php b/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php index 043be12b8..beb41d9a6 100644 --- a/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php +++ b/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php @@ -47,16 +47,35 @@ class SqlValueVisitor extends ExpressionVisitor private $types = array(); /** - * @var \Doctrine\ORM\Mapping\ClassMetadata + * Type Callback + * + * Called by this visitor to determine the type of a value + * + * @var callable */ - private $class; + private $typeCallback; /** - * @param \Doctrine\ORM\Mapping\ClassMetadata + * Value Callback + * + * Called by this visitor to generate a sql value from the given value + * + * Callback is passed two parameters: + * - `Field` name of the field in a comparison + * - `Value` value in a comparison + * + * @var callable */ - public function __construct(ClassMetadata $class) + private $valueCallback; + + /** + * @param callable $typeCallback Type Resolution Callback + * @param callable $valueCallback Value Resolution Callback + */ + public function __construct(callable $typeCallback, callable $valueCallback) { - $this->class = $class; + $this->typeCallback = $typeCallback; + $this->valueCallback = $valueCallback; } /** @@ -68,11 +87,14 @@ class SqlValueVisitor extends ExpressionVisitor */ public function walkComparison(Comparison $comparison) { + $typeCallback = $this->typeCallback; + $valueCallback = $this->valueCallback; + $value = $comparison->getValue()->getValue(); $field = $comparison->getField(); - - $this->values[] = $value; - $this->types[] = $this->getType($field, $value); + + $this->values[] = $valueCallback($value); + $this->types[] = $typeCallback($field, $value); } /** @@ -110,17 +132,4 @@ class SqlValueVisitor extends ExpressionVisitor { return array($this->values, $this->types); } - - private function getType($field, $value) - { - $type = isset($this->class->fieldMappings[$field]) - ? Type::getType($this->class->fieldMappings[$field]['type'])->getBindingType() - : \PDO::PARAM_STR; - - if (is_array($value)) { - $type += Connection::ARRAY_PARAM_OFFSET; - } - - return $type; - } } From a6b6b2526783a791ffa35c6811c7e220a375c7df Mon Sep 17 00:00:00 2001 From: Josiah Truasheim Date: Fri, 31 Aug 2012 18:16:02 +0700 Subject: [PATCH 3/6] Removed the closure keyword as it isn't supported in PHP 5.3 --- lib/Doctrine/ORM/Persisters/SqlValueVisitor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php b/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php index beb41d9a6..ac07f827a 100644 --- a/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php +++ b/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php @@ -72,7 +72,7 @@ class SqlValueVisitor extends ExpressionVisitor * @param callable $typeCallback Type Resolution Callback * @param callable $valueCallback Value Resolution Callback */ - public function __construct(callable $typeCallback, callable $valueCallback) + public function __construct($typeCallback, $valueCallback) { $this->typeCallback = $typeCallback; $this->valueCallback = $valueCallback; From e0d16331a49d1146f66d04eab23df23cf0daa412 Mon Sep 17 00:00:00 2001 From: Josiah Truasheim Date: Fri, 31 Aug 2012 19:51:22 +0700 Subject: [PATCH 4/6] Fixed formatting issues identified by Stof --- .../EntityRepositoryCriteriaTest.php | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php index 3f37a2307..8631e529d 100644 --- a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php @@ -1,18 +1,34 @@ . + */ namespace Doctrine\Tests\ORM\Functional; use Doctrine\Tests\Models\Generic\DateTimeModel; use Doctrine\Common\Collections\Criteria; -require_once __DIR__ . '/../../TestInit.php'; - /** * @author Josiah */ class EntityRepositoryCriteriaTest extends \Doctrine\Tests\OrmFunctionalTestCase { - protected function setUp() { + protected function setUp() + { $this->useModelSet('generic'); parent::setUp(); } From 959c4f026f93aadbcf985a6eff47e56b445d6ebe Mon Sep 17 00:00:00 2001 From: Josiah Truasheim Date: Fri, 31 Aug 2012 20:58:16 +0700 Subject: [PATCH 5/6] Refactored the SqlValueVisitor to move all type processing to the entity persister. --- .../ORM/Persisters/BasicEntityPersister.php | 24 +++++++----- .../ORM/Persisters/SqlValueVisitor.php | 39 +------------------ 2 files changed, 17 insertions(+), 46 deletions(-) diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php index b96aec46c..2ec9ac30c 100644 --- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php @@ -809,17 +809,23 @@ class BasicEntityPersister } $persister = $this; - $valueVisitor = new SqlValueVisitor( - function ($field, $value) use($persister) { - return $persister->getType($field, $value); - }, - function ($value) use($persister) { - return $persister->getValue($value); - } - ); + $valueVisitor = new SqlValueVisitor(); $valueVisitor->dispatch($expression); - return $valueVisitor->getParamsAndTypes(); + list($values, $types) = $valueVisitor->getParamsAndTypes(); + + $sqlValues = array(); + foreach ($values as $value) { + $sqlValues[] = $this->getValue($value); + } + + $sqlTypes = array(); + foreach ($types as $type) { + list($field, $value) = $type; + $sqlTypes[] = $this->getType($field, $value); + } + + return array($sqlValues, $sqlTypes); } /** diff --git a/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php b/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php index ac07f827a..aa4d68d39 100644 --- a/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php +++ b/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php @@ -46,38 +46,6 @@ class SqlValueVisitor extends ExpressionVisitor */ private $types = array(); - /** - * Type Callback - * - * Called by this visitor to determine the type of a value - * - * @var callable - */ - private $typeCallback; - - /** - * Value Callback - * - * Called by this visitor to generate a sql value from the given value - * - * Callback is passed two parameters: - * - `Field` name of the field in a comparison - * - `Value` value in a comparison - * - * @var callable - */ - private $valueCallback; - - /** - * @param callable $typeCallback Type Resolution Callback - * @param callable $valueCallback Value Resolution Callback - */ - public function __construct($typeCallback, $valueCallback) - { - $this->typeCallback = $typeCallback; - $this->valueCallback = $valueCallback; - } - /** * Convert a comparison expression into the target query language output * @@ -87,14 +55,11 @@ class SqlValueVisitor extends ExpressionVisitor */ public function walkComparison(Comparison $comparison) { - $typeCallback = $this->typeCallback; - $valueCallback = $this->valueCallback; - $value = $comparison->getValue()->getValue(); $field = $comparison->getField(); - $this->values[] = $valueCallback($value); - $this->types[] = $typeCallback($field, $value); + $this->values[] = $value; + $this->types[] = array($field, $value); } /** From 2c99f97c8bc053250397d1a0354282664f416865 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Wed, 5 Sep 2012 19:28:32 +0200 Subject: [PATCH 6/6] [DDC-2003] Remove unused variable --- lib/Doctrine/ORM/Persisters/BasicEntityPersister.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php index 2ec9ac30c..d73983c36 100644 --- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php @@ -808,7 +808,6 @@ class BasicEntityPersister return array(array(), array()); } - $persister = $this; $valueVisitor = new SqlValueVisitor(); $valueVisitor->dispatch($expression);