From 39ea24675da38a160cecf2a131b6917ea0bbde3d Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sun, 17 Mar 2013 16:59:33 -0300 Subject: [PATCH] Fix DDC-2090 --- .../Query/Exec/MultiTableUpdateExecutor.php | 29 ++--- .../ORM/Functional/Ticket/DDC2090Test.php | 110 ++++++++++++++++++ 2 files changed, 120 insertions(+), 19 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2090Test.php diff --git a/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php b/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php index cc15cea92..8ceefe3a9 100644 --- a/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php +++ b/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php @@ -124,19 +124,8 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor $updateSql .= $sqlWalker->walkUpdateItem($updateItem); - //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) { - $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->_sqlParameters[$i][] = $newValue->name; ++$this->_numParametersInUpdateClause; } @@ -188,16 +177,18 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor ); // Execute UPDATE statements - for ($i=0, $count=count($this->_sqlStatements); $i<$count; ++$i) { - $parameters = array(); - $types = array(); + foreach ($this->_sqlStatements as $key => $statement) { + $paramValues = array(); + $paramTypes = array(); - if (isset($this->_sqlParameters[$i])) { - $parameters = isset($this->_sqlParameters[$i]['parameters']) ? $this->_sqlParameters[$i]['parameters'] : array(); - $types = isset($this->_sqlParameters[$i]['types']) ? $this->_sqlParameters[$i]['types'] : array(); + if (isset($this->_sqlParameters[$key])) { + foreach ($this->_sqlParameters[$key] as $parameterKey => $parameterName) { + $paramValues[] = $params[$parameterKey]; + $paramTypes[] = isset($types[$parameterKey]) ? $types[$parameterKey] : ParameterTypeInferer::inferType($params[$parameterKey]); + } } - $conn->executeUpdate($this->_sqlStatements[$i], $parameters, $types); + $conn->executeUpdate($statement, $paramValues, $paramTypes); } } catch (\Exception $exception) { // FAILURE! Drop temporary table to avoid possible collisions diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2090Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2090Test.php new file mode 100644 index 000000000..c5da3deae --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2090Test.php @@ -0,0 +1,110 @@ +useModelSet('company'); + parent::setUp(); + } + + public function testIssue() + { + $className = 'Doctrine\Tests\Models\Company\CompanyEmployee'; + $date1 = new \DateTime('2011-11-11 11:11:11'); + $date2 = new \DateTime('2012-12-12 12:12:12'); + $employee1 = new CompanyEmployee; + $employee2 = new CompanyEmployee; + + $employee1->setName("Fabio B. Silva"); + $employee1->setStartDate(new \DateTime('yesterday')); + $employee1->setDepartment("R&D"); + $employee1->setSalary(100); + + $employee2->setName("Doctrine Bot"); + $employee1->setStartDate(new \DateTime('yesterday')); + $employee2->setDepartment("QA"); + $employee2->setSalary(100); + + $this->_em->persist($employee1); + $this->_em->persist($employee2); + $this->_em->flush(); + $this->_em->clear(); + + $this->_em->createQueryBuilder() + ->update($className, 'e') + ->set('e.startDate', ':date') + ->set('e.salary', ':salary') + ->where('e = :e') + ->setParameters(array( + 'e' => $employee1, + 'date' => $date1, + 'salary' => 101, + )) + ->getQuery() + ->useQueryCache(true) + ->execute(); + + $this->_em->createQueryBuilder() + ->update($className, 'e') + ->set('e.startDate', ':date') + ->set('e.salary', ':salary') + ->where('e = :e') + ->setParameters(array( + 'e' => $employee2, + 'date' => $date2, + 'salary' => 102, + )) + ->getQuery() + ->useQueryCache(true) + ->execute(); + + $this->_em->clear(); + + $e1 = $this->_em->find($className, $employee1->getId()); + $e2 = $this->_em->find($className, $employee2->getId()); + + $this->assertEquals(101, $e1->getSalary()); + $this->assertEquals(102, $e2->getSalary()); + $this->assertEquals($date1, $e1->getStartDate()); + $this->assertEquals($date2, $e2->getStartDate()); + + $this->_em->createQueryBuilder() + ->update($className, 'e') + ->set('e.startDate', '?1') + ->set('e.salary', '?2') + ->where('e = ?0') + ->setParameters(array($employee1, $date1, 101)) + ->getQuery() + ->useQueryCache(true) + ->execute(); + + $this->_em->createQueryBuilder() + ->update($className, 'e') + ->set('e.startDate', '?1') + ->set('e.salary', '?2') + ->where('e = ?0') + ->setParameters(array($employee2, $date2, 102)) + ->getQuery() + ->useQueryCache(true) + ->execute(); + + + $this->_em->clear(); + + $e1 = $this->_em->find($className, $employee1->getId()); + $e2 = $this->_em->find($className, $employee2->getId()); + + $this->assertEquals(101, $e1->getSalary()); + $this->assertEquals(102, $e2->getSalary()); + $this->assertEquals($date1, $e1->getStartDate()); + $this->assertEquals($date2, $e2->getStartDate()); + } +} \ No newline at end of file