From df24a014b8bc205e6bc047ead2af393b3e169542 Mon Sep 17 00:00:00 2001 From: Bernhard Posselt Date: Thu, 19 Mar 2015 14:55:21 +0100 Subject: [PATCH] If the execute method on the mapper receives an assoc array, it binds by value instead of index --- lib/public/appframework/db/mapper.php | 55 ++++++++++----- tests/lib/appframework/db/mappertest.php | 10 +++ .../lib/appframework/db/mappertestutility.php | 69 ++++++++++++------- 3 files changed, 90 insertions(+), 44 deletions(-) diff --git a/lib/public/appframework/db/mapper.php b/lib/public/appframework/db/mapper.php index aaef0f79d2..9a5d6e819b 100644 --- a/lib/public/appframework/db/mapper.php +++ b/lib/public/appframework/db/mapper.php @@ -184,6 +184,31 @@ abstract class Mapper { return $entity; } + /** + * Checks if an array is associative + * @param array $array + * @return bool true if associative + */ + private function isAssocArray(array $array) { + return array_values($array) !== $array; + } + + /** + * Returns the correct PDO constant based on the value type + * @param $value + * @return PDO constant + */ + private function getPDOType($value) { + switch (gettype($value)) { + case 'integer': + return \PDO::PARAM_INT; + case 'boolean': + return \PDO::PARAM_BOOL; + default: + return \PDO::PARAM_STR; + } + } + /** * Runs an sql query @@ -200,26 +225,18 @@ abstract class Mapper { $query = $this->db->prepare($sql, $limit, $offset); } - $index = 1; // bindParam is 1 indexed - foreach($params as $param) { - - switch (gettype($param)) { - case 'integer': - $pdoConstant = \PDO::PARAM_INT; - break; - - case 'boolean': - $pdoConstant = \PDO::PARAM_BOOL; - break; - - default: - $pdoConstant = \PDO::PARAM_STR; - break; + if ($this->isAssocArray($params)) { + foreach ($params as $key => $param) { + $pdoConstant = $this->getPDOType($param); + $query->bindValue($key, $param, $pdoConstant); + } + } else { + $index = 1; // bindParam is 1 indexed + foreach ($params as $param) { + $pdoConstant = $this->getPDOType($param); + $query->bindValue($index, $param, $pdoConstant); + $index++; } - - $query->bindValue($index, $param, $pdoConstant); - - $index++; } $result = $query->execute(); diff --git a/tests/lib/appframework/db/mappertest.php b/tests/lib/appframework/db/mappertest.php index 8e585c479b..c8b999ad62 100644 --- a/tests/lib/appframework/db/mappertest.php +++ b/tests/lib/appframework/db/mappertest.php @@ -47,6 +47,7 @@ class ExampleMapper extends Mapper { public function findOneEntity($table, $id){ return $this->findEntity($table, $id); } public function findAllEntities($table){ return $this->findEntities($table); } public function mapRow($row){ return $this->mapRowToEntity($row); } + public function execSql($sql, $params){ return $this->execute($sql, $params); } } @@ -187,6 +188,15 @@ class MapperTest extends MapperTestUtility { } + public function testAssocParameters() { + $sql = 'test'; + $params = [':test' => 1, ':a' => 2]; + + $this->setMapperResult($sql, $params); + $this->mapper->execSql($sql, $params); + } + + public function testUpdate(){ $sql = 'UPDATE `*PREFIX*table` ' . 'SET ' . diff --git a/tests/lib/appframework/db/mappertestutility.php b/tests/lib/appframework/db/mappertestutility.php index c87ad528c0..818e4a59b2 100644 --- a/tests/lib/appframework/db/mappertestutility.php +++ b/tests/lib/appframework/db/mappertestutility.php @@ -56,7 +56,30 @@ abstract class MapperTestUtility extends \Test\TestCase { $this->fetchAt = 0; } + /** + * Checks if an array is associative + * @param array $array + * @return bool true if associative + */ + private function isAssocArray(array $array) { + return array_values($array) !== $array; + } + /** + * Returns the correct PDO constant based on the value type + * @param $value + * @return PDO constant + */ + private function getPDOType($value) { + switch (gettype($value)) { + case 'integer': + return \PDO::PARAM_INT; + case 'boolean': + return \PDO::PARAM_BOOL; + default: + return \PDO::PARAM_STR; + } + } /** * Create mocks and set expected results for database queries @@ -117,32 +140,28 @@ abstract class MapperTestUtility extends \Test\TestCase { } )); - $index = 1; - foreach($arguments as $argument) { - switch (gettype($argument)) { - case 'integer': - $pdoConstant = \PDO::PARAM_INT; - break; - - case 'NULL': - $pdoConstant = \PDO::PARAM_NULL; - break; - - case 'boolean': - $pdoConstant = \PDO::PARAM_BOOL; - break; - - default: - $pdoConstant = \PDO::PARAM_STR; - break; + if ($this->isAssocArray($arguments)) { + foreach($arguments as $key => $argument) { + $pdoConstant = $this->getPDOType($argument); + $this->query->expects($this->at($this->queryAt)) + ->method('bindValue') + ->with($this->equalTo($key), + $this->equalTo($argument), + $this->equalTo($pdoConstant)); + $this->queryAt++; + } + } else { + $index = 1; + foreach($arguments as $argument) { + $pdoConstant = $this->getPDOType($argument); + $this->query->expects($this->at($this->queryAt)) + ->method('bindValue') + ->with($this->equalTo($index), + $this->equalTo($argument), + $this->equalTo($pdoConstant)); + $index++; + $this->queryAt++; } - $this->query->expects($this->at($this->queryAt)) - ->method('bindValue') - ->with($this->equalTo($index), - $this->equalTo($argument), - $this->equalTo($pdoConstant)); - $index++; - $this->queryAt++; } $this->query->expects($this->at($this->queryAt))