Skip to content

Commit

Permalink
DDC-887 - Fix problem with MySQL renaming of foreign keys columns. Th…
Browse files Browse the repository at this point in the history
…e FK has to be dropped, then column renamed, then readded
  • Loading branch information
beberlei committed Jun 19, 2011
1 parent 983dd1d commit 0a1d8b8
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 16 deletions.
51 changes: 36 additions & 15 deletions lib/Doctrine/DBAL/Platforms/AbstractPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -1174,13 +1174,31 @@ public function getAlterTableSQL(TableDiff $diff)
throw DBALException::notSupported(__METHOD__);
}

/**
* Common code for alter table statement generation that updates the changed Index and Foreign Key definitions.
*
* @param TableDiff $diff
* @return array
*/
protected function _getAlterTableIndexForeignKeySQL(TableDiff $diff)
protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff)
{
$tableName = $diff->name;

$sql = array();
if ($this->supportsForeignKeyConstraints()) {
foreach ($diff->removedForeignKeys AS $foreignKey) {
$sql[] = $this->getDropForeignKeySQL($foreignKey, $tableName);
}
foreach ($diff->changedForeignKeys AS $foreignKey) {
$sql[] = $this->getDropForeignKeySQL($foreignKey, $tableName);
}
}

foreach ($diff->removedIndexes AS $index) {
$sql[] = $this->getDropIndexSQL($index, $tableName);
}
foreach ($diff->changedIndexes AS $index) {
$sql[] = $this->getDropIndexSQL($index, $tableName);
}

return $sql;
}

protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff)
{
if ($diff->newName !== false) {
$tableName = $diff->newName;
Expand All @@ -1190,31 +1208,34 @@ protected function _getAlterTableIndexForeignKeySQL(TableDiff $diff)

$sql = array();
if ($this->supportsForeignKeyConstraints()) {
foreach ($diff->removedForeignKeys AS $foreignKey) {
$sql[] = $this->getDropForeignKeySQL($foreignKey, $tableName);
}
foreach ($diff->addedForeignKeys AS $foreignKey) {
$sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableName);
}
foreach ($diff->changedForeignKeys AS $foreignKey) {
$sql[] = $this->getDropForeignKeySQL($foreignKey, $tableName);
$sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableName);
}
}

foreach ($diff->addedIndexes AS $index) {
$sql[] = $this->getCreateIndexSQL($index, $tableName);
}
foreach ($diff->removedIndexes AS $index) {
$sql[] = $this->getDropIndexSQL($index, $tableName);
}
foreach ($diff->changedIndexes AS $index) {
$sql[] = $this->getDropIndexSQL($index, $tableName);
$sql[] = $this->getCreateIndexSQL($index, $tableName);
}

return $sql;
}

/**
* Common code for alter table statement generation that updates the changed Index and Foreign Key definitions.
*
* @param TableDiff $diff
* @return array
*/
protected function _getAlterTableIndexForeignKeySQL(TableDiff $diff)
{
return array_merge($this->getPreAlterTableIndexForeignKeySQL($diff), $this->getPostAlterTableIndexForeignKeySQL($diff));
}

/**
* Get declaration of a number of fields in bulk
Expand Down
6 changes: 5 additions & 1 deletion lib/Doctrine/DBAL/Platforms/MySqlPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,11 @@ public function getAlterTableSQL(TableDiff $diff)
if (count($queryParts) > 0) {
$sql[] = 'ALTER TABLE ' . $diff->name . ' ' . implode(", ", $queryParts);
}
$sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff));
$sql = array_merge(
$this->getPreAlterTableIndexForeignKeySQL($diff),
$sql,
$this->getPostAlterTableIndexForeignKeySQL($diff)
);
return $sql;
}

Expand Down
21 changes: 21 additions & 0 deletions run-all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

# This script is a small convenience wrapper for running the doctrine testsuite against a large bunch of databases.
# Just create the phpunit.xmls as described in the array below and configure the specific files <php /> section
# to connect to that database. Just omit a file if you dont have that database and the tests will be skipped.

configs[1]="mysql.phpunit.xml"
configs[2]='postgres.phpunit.xml'
configs[3]='sqlite.phpunit.xml'
configs[4]='oracle.phpunit.xml'
configs[5]='db2.phpunit.xml'
configs[6]='pdo-ibm.phpunit.xml'
configs[7]='sqlsrv.phpunit.xml'

for i in "${configs[@]}"; do
if [ -f "$i" ];
then
echo "RUNNING TESTS WITH CONFIG $i"
phpunit -c "$i" "$@"
fi;
done
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Doctrine\DBAL\Types\Type,
Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\Platforms\AbstractPlatform;

require_once __DIR__ . '/../../../TestInit.php';

Expand Down Expand Up @@ -398,6 +399,44 @@ public function testAutoincrementDetection()
$this->assertTrue($inferredTable->hasColumn('id'));
$this->assertTrue($inferredTable->getColumn('id')->getAutoincrement());
}

/**
* @group DDC-887
*/
public function testUpdateSchemaWithForeignKeyRenaming()
{
if (!$this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$this->markTestSkipped('This test is only supported on platforms that have foreign keys.');
}

$table = new \Doctrine\DBAL\Schema\Table('test_fk_base');
$table->addColumn('id', 'integer');
$table->setPrimaryKey(array('id'));

$tableFK = new \Doctrine\DBAL\Schema\Table('test_fk_rename');
$tableFK->setSchemaConfig($this->_sm->createSchemaConfig());
$tableFK->addColumn('id', 'integer');
$tableFK->addColumn('fk_id', 'integer');
$tableFK->setPrimaryKey(array('id'));
$tableFK->addIndex(array('fk_id'), 'fk_idx');
$tableFK->addForeignKeyConstraint('test_fk_base', array('fk_id'), array('id'));

$this->_sm->createTable($table);
$this->_sm->createTable($tableFK);

$tableFKNew = new \Doctrine\DBAL\Schema\Table('test_fk_rename');
$tableFKNew->setSchemaConfig($this->_sm->createSchemaConfig());
$tableFKNew->addColumn('id', 'integer');
$tableFKNew->addColumn('rename_fk_id', 'integer');
$tableFKNew->setPrimaryKey(array('id'));
$tableFKNew->addIndex(array('rename_fk_id'), 'fk_idx');
$tableFKNew->addForeignKeyConstraint('test_fk_base', array('rename_fk_id'), array('id'));

$c = new \Doctrine\DBAL\Schema\Comparator();
$tableDiff = $c->diffTable($tableFK, $tableFKNew);

$this->_sm->alterTable($tableDiff);
}

/**
* @group DBAL-42
Expand Down

0 comments on commit 0a1d8b8

Please sign in to comment.