Commit 0d2f8187 authored by Marco Pivetta's avatar Marco Pivetta

Merge branch...

Merge branch 'fix/#2511-#2609-correct-identifier-and-data-type-collisions-in-list-type-extraction' into 2.5

Close #2511
Close #2609
parents 79f74d85 7068f208
...@@ -580,18 +580,20 @@ class Connection implements DriverConnection ...@@ -580,18 +580,20 @@ class Connection implements DriverConnection
throw InvalidArgumentException::fromEmptyCriteria(); throw InvalidArgumentException::fromEmptyCriteria();
} }
$this->connect(); $columnList = array();
$criteria = array(); $criteria = array();
$paramValues = array();
foreach (array_keys($identifier) as $columnName) { foreach ($identifier as $columnName => $value) {
$columnList[] = $columnName;
$criteria[] = $columnName . ' = ?'; $criteria[] = $columnName . ' = ?';
$paramValues[] = $value;
} }
return $this->executeUpdate( return $this->executeUpdate(
'DELETE FROM ' . $tableExpression . ' WHERE ' . implode(' AND ', $criteria), 'DELETE FROM ' . $tableExpression . ' WHERE ' . implode(' AND ', $criteria),
array_values($identifier), $paramValues,
is_string(key($types)) ? $this->extractTypeValues($identifier, $types) : $types is_string(key($types)) ? $this->extractTypeValues($columnList, $types) : $types
); );
} }
...@@ -649,24 +651,31 @@ class Connection implements DriverConnection ...@@ -649,24 +651,31 @@ class Connection implements DriverConnection
*/ */
public function update($tableExpression, array $data, array $identifier, array $types = array()) public function update($tableExpression, array $data, array $identifier, array $types = array())
{ {
$this->connect(); $columnList = array();
$set = array(); $set = array();
$criteria = array();
$paramValues = array();
foreach ($data as $columnName => $value) { foreach ($data as $columnName => $value) {
$columnList[] = $columnName;
$set[] = $columnName . ' = ?'; $set[] = $columnName . ' = ?';
$paramValues[] = $value;
} }
if (is_string(key($types))) { foreach ($identifier as $columnName => $value) {
$types = $this->extractTypeValues(array_merge($data, $identifier), $types); $columnList[] = $columnName;
$criteria[] = $columnName . ' = ?';
$paramValues[] = $value;
} }
$params = array_merge(array_values($data), array_values($identifier)); if (is_string(key($types))) {
$types = $this->extractTypeValues($columnList, $types);
}
$sql = 'UPDATE ' . $tableExpression . ' SET ' . implode(', ', $set) $sql = 'UPDATE ' . $tableExpression . ' SET ' . implode(', ', $set)
. ' WHERE ' . implode(' = ? AND ', array_keys($identifier)) . ' WHERE ' . implode(' AND ', $criteria);
. ' = ?';
return $this->executeUpdate($sql, $params, $types); return $this->executeUpdate($sql, $paramValues, $types);
} }
/** /**
...@@ -688,29 +697,39 @@ class Connection implements DriverConnection ...@@ -688,29 +697,39 @@ class Connection implements DriverConnection
return $this->executeUpdate('INSERT INTO ' . $tableExpression . ' ()' . ' VALUES ()'); return $this->executeUpdate('INSERT INTO ' . $tableExpression . ' ()' . ' VALUES ()');
} }
$columnList = array();
$paramPlaceholders = array();
$paramValues = array();
foreach ($data as $columnName => $value) {
$columnList[] = $columnName;
$paramPlaceholders[] = '?';
$paramValues[] = $value;
}
return $this->executeUpdate( return $this->executeUpdate(
'INSERT INTO ' . $tableExpression . ' (' . implode(', ', array_keys($data)) . ')' . 'INSERT INTO ' . $tableExpression . ' (' . implode(', ', $columnList) . ')' .
' VALUES (' . implode(', ', array_fill(0, count($data), '?')) . ')', ' VALUES (' . implode(', ', $paramPlaceholders) . ')',
array_values($data), $paramValues,
is_string(key($types)) ? $this->extractTypeValues($data, $types) : $types is_string(key($types)) ? $this->extractTypeValues($columnList, $types) : $types
); );
} }
/** /**
* Extract ordered type list from two associate key lists of data and types. * Extract ordered type list from an ordered column list and type map.
* *
* @param array $data * @param array $columnList
* @param array $types * @param array $types
* *
* @return array * @return array
*/ */
private function extractTypeValues(array $data, array $types) private function extractTypeValues(array $columnList, array $types)
{ {
$typeValues = array(); $typeValues = array();
foreach ($data as $k => $_) { foreach ($columnList as $columnIndex => $columnName) {
$typeValues[] = isset($types[$k]) $typeValues[] = isset($types[$columnName])
? $types[$k] ? $types[$columnName]
: \PDO::PARAM_STR; : \PDO::PARAM_STR;
} }
......
...@@ -300,6 +300,111 @@ SQLSTATE[HY000]: General error: 1 near \"MUUHAAAAHAAAA\""); ...@@ -300,6 +300,111 @@ SQLSTATE[HY000]: General error: 1 near \"MUUHAAAAHAAAA\"");
$conn->insert('footable', array()); $conn->insert('footable', array());
} }
/**
* @group DBAL-2511
*/
public function testUpdateWithDifferentColumnsInDataAndIdentifiers()
{
$driverMock = $this->getMock('Doctrine\DBAL\Driver');
$driverMock->expects($this->any())
->method('connect')
->will($this->returnValue(new DriverConnectionMock()));
$conn = $this->getMockBuilder('Doctrine\DBAL\Connection')
->setMethods(array('executeUpdate'))
->setConstructorArgs(array(array('platform' => new Mocks\MockPlatform()), $driverMock))
->getMock();
$conn->expects($this->once())
->method('executeUpdate')
->with(
'UPDATE TestTable SET text = ?, is_edited = ? WHERE id = ? AND name = ?',
[
'some text',
true,
1,
'foo',
],
[
'string',
'boolean',
'integer',
'string',
]
);
$conn->update(
'TestTable',
[
'text' => 'some text',
'is_edited' => true,
],
[
'id' => 1,
'name' => 'foo',
],
[
'text' => 'string',
'is_edited' => 'boolean',
'id' => 'integer',
'name' => 'string',
]
);
}
/**
* @group DBAL-2511
*/
public function testUpdateWithSameColumnInDataAndIdentifiers()
{
$driverMock = $this->getMock('Doctrine\DBAL\Driver');
$driverMock->expects($this->any())
->method('connect')
->will($this->returnValue(new DriverConnectionMock()));
$conn = $this->getMockBuilder('Doctrine\DBAL\Connection')
->setMethods(array('executeUpdate'))
->setConstructorArgs(array(array('platform' => new Mocks\MockPlatform()), $driverMock))
->getMock();
$conn->expects($this->once())
->method('executeUpdate')
->with(
'UPDATE TestTable SET text = ?, is_edited = ? WHERE id = ? AND is_edited = ?',
[
'some text',
true,
1,
false,
],
[
'string',
'boolean',
'integer',
'boolean',
]
);
$conn->update(
'TestTable',
[
'text' => 'some text',
'is_edited' => true,
],
[
'id' => 1,
'is_edited' => false,
],
[
'text' => 'string',
'is_edited' => 'boolean',
'id' => 'integer',
]
);
}
public function testFetchAssoc() public function testFetchAssoc()
{ {
$statement = 'SELECT * FROM foo WHERE bar = ?'; $statement = 'SELECT * FROM foo WHERE bar = ?';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment