Commit 5ba5a66d authored by Benjamin Eberlei's avatar Benjamin Eberlei

Merge branch 'master' of github.com:doctrine/dbal

parents e8fa2e1f 7d746844
...@@ -39,6 +39,7 @@ use PDO, Closure, Exception, ...@@ -39,6 +39,7 @@ use PDO, Closure, Exception,
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
* @author Konsta Vesterinen <kvesteri@cc.hut.fi> * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Lukas Smith <smith@pooteeweet.org> (MDB2 library) * @author Lukas Smith <smith@pooteeweet.org> (MDB2 library)
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/ */
class Connection implements DriverConnection class Connection implements DriverConnection
{ {
...@@ -610,6 +611,8 @@ class Connection implements DriverConnection ...@@ -610,6 +611,8 @@ class Connection implements DriverConnection
*/ */
public function query() public function query()
{ {
$this->connect();
return call_user_func_array(array($this->_conn, 'query'), func_get_args()); return call_user_func_array(array($this->_conn, 'query'), func_get_args());
} }
......
...@@ -109,6 +109,7 @@ final class DriverManager ...@@ -109,6 +109,7 @@ final class DriverManager
if (isset($params['pdo']) && ! $params['pdo'] instanceof \PDO) { if (isset($params['pdo']) && ! $params['pdo'] instanceof \PDO) {
throw DBALException::invalidPdoInstance(); throw DBALException::invalidPdoInstance();
} else if (isset($params['pdo'])) { } else if (isset($params['pdo'])) {
$params['pdo']->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$params['driver'] = 'pdo_' . $params['pdo']->getAttribute(\PDO::ATTR_DRIVER_NAME); $params['driver'] = 'pdo_' . $params['pdo']->getAttribute(\PDO::ATTR_DRIVER_NAME);
} else { } else {
self::_checkParams($params); self::_checkParams($params);
......
...@@ -178,16 +178,7 @@ class Comparator ...@@ -178,16 +178,7 @@ class Comparator
} }
} }
// Try to find columns that only changed their name, rename operations maybe cheaper than add/drop $this->detectColumnRenamings($tableDifferences);
foreach ($tableDifferences->addedColumns AS $addedColumnName => $addedColumn) {
foreach ($tableDifferences->removedColumns AS $removedColumnName => $removedColumn) {
if (count($this->diffColumn($addedColumn, $removedColumn)) == 0) {
$tableDifferences->renamedColumns[$removedColumn->getName()] = $addedColumn;
unset($tableDifferences->addedColumns[$addedColumnName]);
unset($tableDifferences->removedColumns[$removedColumnName]);
}
}
}
$table1Indexes = $table1->getIndexes(); $table1Indexes = $table1->getIndexes();
$table2Indexes = $table2->getIndexes(); $table2Indexes = $table2->getIndexes();
...@@ -250,6 +241,34 @@ class Comparator ...@@ -250,6 +241,34 @@ class Comparator
return $changes ? $tableDifferences : false; return $changes ? $tableDifferences : false;
} }
/**
* Try to find columns that only changed their name, rename operations maybe cheaper than add/drop
* however ambiguouties between different possibilites should not lead to renaming at all.
*
* @param TableDiff $tableDifferences
*/
private function detectColumnRenamings(TableDiff $tableDifferences)
{
$renameCandidates = array();
foreach ($tableDifferences->addedColumns AS $addedColumnName => $addedColumn) {
foreach ($tableDifferences->removedColumns AS $removedColumnName => $removedColumn) {
if (count($this->diffColumn($addedColumn, $removedColumn)) == 0) {
$renameCandidates[$addedColumn->getName()][] = array($removedColumn, $addedColumn);
}
}
}
foreach ($renameCandidates AS $candidate => $candidateColumns) {
if (count($candidateColumns) == 1) {
list($removedColumn, $addedColumn) = $candidateColumns[0];
$tableDifferences->renamedColumns[$removedColumn->getName()] = $addedColumn;
unset($tableDifferences->addedColumns[$addedColumnName]);
unset($tableDifferences->removedColumns[$removedColumnName]);
}
}
}
/** /**
* @param ForeignKeyConstraint $key1 * @param ForeignKeyConstraint $key1
* @param ForeignKeyConstraint $key2 * @param ForeignKeyConstraint $key2
......
...@@ -85,7 +85,9 @@ class MySqlSchemaManager extends AbstractSchemaManager ...@@ -85,7 +85,9 @@ class MySqlSchemaManager extends AbstractSchemaManager
*/ */
protected function _getPortableTableColumnDefinition($tableColumn) protected function _getPortableTableColumnDefinition($tableColumn)
{ {
$dbType = strtolower($tableColumn['Type']); $tableColumn = array_change_key_case($tableColumn, CASE_LOWER);
$dbType = strtolower($tableColumn['type']);
$dbType = strtok($dbType, '(), '); $dbType = strtok($dbType, '(), ');
if (isset($tableColumn['length'])) { if (isset($tableColumn['length'])) {
$length = $tableColumn['length']; $length = $tableColumn['length'];
...@@ -114,7 +116,7 @@ class MySqlSchemaManager extends AbstractSchemaManager ...@@ -114,7 +116,7 @@ class MySqlSchemaManager extends AbstractSchemaManager
case 'real': case 'real':
case 'numeric': case 'numeric':
case 'decimal': case 'decimal':
if(preg_match('([A-Za-z]+\(([0-9]+)\,([0-9]+)\))', $tableColumn['Type'], $match)) { if(preg_match('([A-Za-z]+\(([0-9]+)\,([0-9]+)\))', $tableColumn['type'], $match)) {
$precision = $match[1]; $precision = $match[1];
$scale = $match[2]; $scale = $match[2];
$length = null; $length = null;
...@@ -149,11 +151,11 @@ class MySqlSchemaManager extends AbstractSchemaManager ...@@ -149,11 +151,11 @@ class MySqlSchemaManager extends AbstractSchemaManager
'length' => $length, 'length' => $length,
'unsigned' => (bool)$unsigned, 'unsigned' => (bool)$unsigned,
'fixed' => (bool)$fixed, 'fixed' => (bool)$fixed,
'default' => $tableColumn['Default'], 'default' => $tableColumn['default'],
'notnull' => (bool) ($tableColumn['Null'] != 'YES'), 'notnull' => (bool) ($tableColumn['null'] != 'YES'),
'scale' => null, 'scale' => null,
'precision' => null, 'precision' => null,
'autoincrement' => (bool) (strpos($tableColumn['Extra'], 'auto_increment') !== false), 'autoincrement' => (bool) (strpos($tableColumn['extra'], 'auto_increment') !== false),
); );
if ($scale !== null && $precision !== null) { if ($scale !== null && $precision !== null) {
...@@ -161,7 +163,7 @@ class MySqlSchemaManager extends AbstractSchemaManager ...@@ -161,7 +163,7 @@ class MySqlSchemaManager extends AbstractSchemaManager
$options['precision'] = $precision; $options['precision'] = $precision;
} }
return new Column($tableColumn['Field'], \Doctrine\DBAL\Types\Type::getType($type), $options); return new Column($tableColumn['field'], \Doctrine\DBAL\Types\Type::getType($type), $options);
} }
public function _getPortableTableForeignKeyDefinition($tableForeignKey) public function _getPortableTableForeignKeyDefinition($tableForeignKey)
......
...@@ -26,6 +26,21 @@ class DriverManagerTest extends \Doctrine\Tests\DbalTestCase ...@@ -26,6 +26,21 @@ class DriverManagerTest extends \Doctrine\Tests\DbalTestCase
$this->assertEquals('sqlite', $conn->getDatabasePlatform()->getName()); $this->assertEquals('sqlite', $conn->getDatabasePlatform()->getName());
} }
/**
* @group DBAL-32
*/
public function testPdoInstanceSetErrorMode()
{
$pdo = new \PDO('sqlite::memory:');
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_SILENT);
$options = array(
'pdo' => $pdo
);
$conn = \Doctrine\DBAL\DriverManager::getConnection($options);
$this->assertEquals(\PDO::ERRMODE_EXCEPTION, $pdo->getAttribute(\PDO::ATTR_ERRMODE));
}
/** /**
* @expectedException \Doctrine\DBAL\DBALException * @expectedException \Doctrine\DBAL\DBALException
*/ */
......
...@@ -581,6 +581,33 @@ class ComparatorTest extends \PHPUnit_Framework_TestCase ...@@ -581,6 +581,33 @@ class ComparatorTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('bar', $tableDiff->renamedColumns['foo']->getName()); $this->assertEquals('bar', $tableDiff->renamedColumns['foo']->getName());
} }
/**
* You can easily have ambiguouties in the column renaming. If these
* are detected no renaming should take place, instead adding and dropping
* should be used exclusively.
*
* @group DBAL-24
*/
public function testDetectRenameColumnAmbiguous()
{
$tableA = new Table("foo");
$tableA->addColumn('foo', 'integer');
$tableA->addColumn('bar', 'integer');
$tableB = new Table("foo");
$tableB->addColumn('baz', 'integer');
$c = new Comparator();
$tableDiff = $c->diffTable($tableA, $tableB);
$this->assertEquals(1, count($tableDiff->addedColumns), "'baz' should be added, not created through renaming!");
$this->assertArrayHasKey('baz', $tableDiff->addedColumns, "'baz' should be added, not created through renaming!");
$this->assertEquals(2, count($tableDiff->removedColumns), "'foo' and 'bar' should both be dropped, an ambigouty exists which one could be renamed to 'baz'.");
$this->assertArrayHasKey('foo', $tableDiff->removedColumns, "'foo' should be removed.");
$this->assertArrayHasKey('bar', $tableDiff->removedColumns, "'bar' should be removed.");
$this->assertEquals(0, count($tableDiff->renamedColumns), "no renamings should take place.");
}
public function testDetectChangeIdentifierType() public function testDetectChangeIdentifierType()
{ {
$this->markTestSkipped('DBAL-2 was reopened, this test cannot work anymore.'); $this->markTestSkipped('DBAL-2 was reopened, this test cannot work anymore.');
......
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