Commit 0a1d8b83 authored by Benjamin Eberlei's avatar Benjamin Eberlei

DDC-887 - Fix problem with MySQL renaming of foreign keys columns. The FK has...

DDC-887 - Fix problem with MySQL renaming of foreign keys columns. The FK has to be dropped, then column renamed, then readded
parent 983dd1d1
......@@ -1174,13 +1174,31 @@ abstract class AbstractPlatform
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;
......@@ -1190,14 +1208,10 @@ abstract class AbstractPlatform
$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);
}
}
......@@ -1205,16 +1219,23 @@ abstract class AbstractPlatform
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
......
......@@ -487,7 +487,11 @@ class MySqlPlatform extends AbstractPlatform
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;
}
......
#!/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
......@@ -4,6 +4,7 @@ namespace Doctrine\Tests\DBAL\Functional\Schema;
use Doctrine\DBAL\Types\Type,
Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\Platforms\AbstractPlatform;
require_once __DIR__ . '/../../../TestInit.php';
......@@ -398,6 +399,44 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
$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
......
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