diff --git a/lib/Cake/Model/Datasource/Database/Connection.php b/lib/Cake/Model/Datasource/Database/Connection.php index efe96d8b152..e46067e140e 100644 --- a/lib/Cake/Model/Datasource/Database/Connection.php +++ b/lib/Cake/Model/Datasource/Database/Connection.php @@ -174,13 +174,13 @@ public function update($table, array $data, array $conditions = array(), $types $sql = sprintf( $sql, $table, - rtrim(',', implode(' = ?,', $keys)), + implode(', ', array_map(function($k) {return $k . ' = ?';}, $keys)), $conditions ); if (!empty($type)) { $types = $this->_mapTypes($keys, $types); } - return $this->execute($sql, array_values($data), $types); + return $this->execute($sql, array_merge(array_values($data), $params), $types); } /** @@ -298,6 +298,13 @@ protected function _mapTypes($columns, $types) { return $types; } +/** + * Simple condtions parser joind by AND + * + * @param array conditions key value array or list of conditions to be joined + * to construct a WHERE clause + * @return string + **/ protected function _parseConditions($conditions) { $params = array(); if (empty($conditions)) { @@ -310,8 +317,10 @@ protected function _parseConditions($conditions) { $conds[] = $value; continue; } - $conds[] = $key . ' = '; + $conds[] = $key . ' = ?'; + $params[] = $value; } + return array(sprintf($sql, implode(' AND ', $conds)), $params); } } diff --git a/lib/Cake/Test/TestCase/Model/Datasource/Database/ConnectionTest.php b/lib/Cake/Test/TestCase/Model/Datasource/Database/ConnectionTest.php index 0938ae11e8e..f44a9b98c9e 100644 --- a/lib/Cake/Test/TestCase/Model/Datasource/Database/ConnectionTest.php +++ b/lib/Cake/Test/TestCase/Model/Datasource/Database/ConnectionTest.php @@ -212,6 +212,11 @@ public function testInsertWithPositionalTypes() { $this->assertEquals($data, $row); } +/** + * Auxiliary function to insert a couple rows in a newly creted table + * + * @return void + **/ protected function _insertTwoRecords() { $table = 'CREATE TEMPORARY TABLE things(id int, title varchar(20), body varchar(50))'; $this->connection->execute($table); @@ -250,6 +255,11 @@ public function testStatementReusing() { $this->assertEquals('another body', $row['body']); } +/** + * Tests rows can be updated without specifying any coditions nor types + * + * @return void + **/ public function testUpdateWithoutConditionsNorTypes() { $this->_insertTwoRecords(); $title = 'changed the title!'; @@ -259,4 +269,32 @@ public function testUpdateWithoutConditionsNorTypes() { $this->assertCount(2, $result); } +/** + * Tests it is possible to use key => value conditions for update + * + * @return void + **/ + public function testUpdateWithConditionsNoTypes() { + $this->_insertTwoRecords(); + $title = 'changed the title!'; + $body = 'changed the body!'; + $this->connection->update('things', array('title' => $title, 'body' => $body), array('id' => 2)); + $result = $this->connection->execute('SELECT * FROM things WHERE title = ? AND body = ?', array($title, $body)); + $this->assertCount(1, $result); + } + +/** + * Tests it is possible to use key => value and stirng conditions for update + * + * @return void + **/ + public function testUpdateWithConditionsCombinedNoTypes() { + $this->_insertTwoRecords(); + $title = 'changed the title!'; + $body = 'changed the body!'; + $this->connection->update('things', array('title' => $title, 'body' => $body), array('id' => 2, 'body is not null')); + $result = $this->connection->execute('SELECT * FROM things WHERE title = ? AND body = ?', array($title, $body)); + $this->assertCount(1, $result); + } + }