Commit 47411d33 authored by Benjamin Eberlei's avatar Benjamin Eberlei

[DBAL-445] Add support for key-value based $types maps in

    Connection#insert(),  Connection#update() and Connection#delete(). Closes GH-271
parent 411d38f1
......@@ -433,9 +433,10 @@ class Connection implements DriverConnection
*
* @param string $tableName The name of the table on which to delete.
* @param array $identifier The deletion criteria. An associative array containing column-value pairs.
* @param array $types The types of identifiers
* @return integer The number of affected rows.
*/
public function delete($tableName, array $identifier)
public function delete($tableName, array $identifier, array $types = array())
{
$this->connect();
......@@ -445,9 +446,13 @@ class Connection implements DriverConnection
$criteria[] = $columnName . ' = ?';
}
if ( ! is_int(key($types))) {
$types = $this->extractTypeValues($identifier, $types);
}
$query = 'DELETE FROM ' . $tableName . ' WHERE ' . implode(' AND ', $criteria);
return $this->executeUpdate($query, array_values($identifier));
return $this->executeUpdate($query, array_values($identifier), $types);
}
/**
......@@ -498,10 +503,15 @@ class Connection implements DriverConnection
{
$this->connect();
$set = array();
foreach ($data as $columnName => $value) {
$set[] = $columnName . ' = ?';
}
if ( ! is_int(key($types))) {
$types = $this->extractTypeValues(array_merge($data, $identifier), $types);
}
$params = array_merge(array_values($data), array_values($identifier));
$sql = 'UPDATE ' . $tableName . ' SET ' . implode(', ', $set)
......@@ -532,6 +542,10 @@ class Connection implements DriverConnection
$placeholders[] = '?';
}
if ( ! is_int(key($types))) {
$types = $this->extractTypeValues($data, $types);
}
$query = 'INSERT INTO ' . $tableName
. ' (' . implode(', ', $cols) . ')'
. ' VALUES (' . implode(', ', $placeholders) . ')';
......@@ -539,6 +553,27 @@ class Connection implements DriverConnection
return $this->executeUpdate($query, array_values($data), $types);
}
/**
* Extract ordered type list from two associate key lists of data and types.
*
* @param array $data
* @param array $types
*
* @return array
*/
private function extractTypeValues(array $data, array $types)
{
$typeValues = array();
foreach ($data as $k => $_) {
$typeValues[] = isset($types[$k])
? $types[$k]
: \PDO::PARAM_STR;
}
return $typeValues;
}
/**
* Quote a string so it can be safely used as a table or column name, even if
* it is a reserved name.
......
......@@ -182,4 +182,62 @@ class WriteTest extends \Doctrine\Tests\DbalFunctionalTestCase
$this->assertFalse($this->_conn->lastInsertId( null ));
}
/**
* @group DBAL-445
*/
public function testInsertWithKeyValueTypes()
{
$this->_conn->insert(
'write_table',
array('test_int' => '30', 'test_string' => new \DateTime('2013-04-14 10:10:10')),
array('test_string' => 'datetime', 'test_int' => 'integer')
);
$data = $this->_conn->fetchColumn('SELECT test_string FROM write_table WHERE test_int = 30');
$this->assertEquals('2013-04-14 10:10:10', $data);
}
/**
* @group DBAL-445
*/
public function testUpdateWithKeyValueTypes()
{
$this->_conn->insert(
'write_table',
array('test_int' => '30', 'test_string' => new \DateTime('2013-04-14 10:10:10')),
array('test_string' => 'datetime', 'test_int' => 'integer')
);
$this->_conn->update(
'write_table',
array('test_string' => new \DateTime('2013-04-15 10:10:10')),
array('test_int' => '30'),
array('test_string' => 'datetime', 'test_int' => 'integer')
);
$data = $this->_conn->fetchColumn('SELECT test_string FROM write_table WHERE test_int = 30');
$this->assertEquals('2013-04-15 10:10:10', $data);
}
/**
* @group DBAL-445
*/
public function testDeleteWithKeyValueTypes()
{
$val = new \DateTime('2013-04-14 10:10:10');
$this->_conn->insert(
'write_table',
array('test_int' => '30', 'test_string' => $val),
array('test_string' => 'datetime', 'test_int' => 'integer')
);
$this->_conn->delete('write_table', array('test_int' => 30, 'test_string' => $val), array('test_string' => 'datetime', 'test_int' => 'integer'));
$data = $this->_conn->fetchColumn('SELECT test_string FROM write_table WHERE test_int = 30');
$this->assertFalse($data);
}
}
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