Fix dropping foreign key multiple times with test #212

Merged
merged 3 commits into from Oct 5, 2012

Conversation

Projects
None yet
5 participants
Contributor

sdepablos commented Oct 4, 2012

In some cases the Comparator class returns multiple drops for the same foreign key.
Specifically, in case you have two tables, A & B, with A having a foreign key FK
referencing B, if you drop table B, the resulting diff shows this FK twice,
once on the diff->orphanedForeignKeys array as we're deleting B, and another on
the diff->changedTables array as table A is also being modified. As a result of this you
get the DROP FOREIGN KEY instruction twice in the final SQL.

Fix dropping foreign key multiple times with test
In some cases the Comparator class returns multiple drops for the same foreign key.
Specifically, in case you have two tables, A & B, with A having a foreign key FK
referencing B, if you drop table B, the resulting diff shows this FK twice,
once on the diff->orphanedForeignKeys array as we're deleting B, and another on
the diff->changedTables array as table A is also being modified. As a result of this you
get the DROP FOREIGN KEY instruction twice in the final SQL.

Hello,

thank you for positing this Pull Request. I have automatically opened an issue on our Jira Bug Tracker for you with the details of this Pull-Request. See the Link:

http://doctrine-project.org/jira/browse/DBAL-360

lib/Doctrine/DBAL/Schema/Comparator.php
@@ -46,7 +46,7 @@ static public function compareSchemas( Schema $fromSchema, Schema $toSchema )
/**
* Returns a SchemaDiff object containing the differences between the schemas $fromSchema and $toSchema.
*
- * The returned differences are returned in such a way that they contain the
+ * The returned diferences are returned in such a way that they contain the
@stof

stof Oct 4, 2012

Member

Please revert this typo

lib/Doctrine/DBAL/Schema/Comparator.php
@@ -262,7 +272,7 @@ public function diffTable(Table $table1, Table $table2)
/**
* Try to find columns that only changed their name, rename operations maybe cheaper than add/drop
- * however ambiguities between different possibilities should not lead to renaming at all.
+ * however ambiguouties between different possibilites should not lead to renaming at all.
@stof

stof Oct 4, 2012

Member

please revert this

@@ -781,6 +781,32 @@ public function testAutoIncremenetSequences()
$this->assertCount(0, $diff->removedSequences);
}
+
+ /**
+ * You can get multiple drops for a FK when
@stof

stof Oct 4, 2012

Member

the end is missing

Contributor

sdepablos commented Oct 5, 2012

I provide an example of the bug. Having the following Foo entity

namespace Test\HelloBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Test\HelloBundle\Entity\foo
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class Foo
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
}

we add a new table ForeignTable

namespace Test\HelloBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Test\HelloBundle\Entity\ForeignTable
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class ForeignTable
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
}

referenced by Foo

namespace Test\HelloBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Test\HelloBundle\Entity\foo
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class Foo
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="ForeignTable")
     */
    private $fk;
}

When executing the diff, before the changes we got

public function down(Schema $schema)
{
    // this down() migration is autogenerated, please modify it to your needs
    $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql");

    $this->addSql("ALTER TABLE Foo DROP FOREIGN KEY FK_B43E23C1A57719D0");
    $this->addSql("DROP TABLE ForeignTable");
    $this->addSql("ALTER TABLE Foo DROP FOREIGN KEY FK_B43E23C1A57719D0");
    $this->addSql("DROP INDEX IDX_B43E23C1A57719D0 ON Foo");
    $this->addSql("ALTER TABLE Foo DROP fk_id");
}

with the ALTER TABLE Foo DROP FOREIGN KEY FK_B43E23C1A57719D0 twice, but applying this changes we now correctly get

public function down(Schema $schema)
{
    // this down() migration is autogenerated, please modify it to your needs
    $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql");

    $this->addSql("ALTER TABLE Foo DROP FOREIGN KEY FK_B43E23C1A57719D0");
    $this->addSql("DROP TABLE ForeignTable");
    $this->addSql("DROP INDEX IDX_B43E23C1A57719D0 ON Foo");
    $this->addSql("ALTER TABLE Foo DROP fk_id");
}

beberlei added a commit that referenced this pull request Oct 5, 2012

Merge pull request #212 from sdepablos/master
Fix dropping foreign key multiple times with test

@beberlei beberlei merged commit 9a467f1 into doctrine:master Oct 5, 2012

1 check failed

default The Travis build failed
Details

Coverage Status

Changes Unknown when pulling 283ff9b on sdepablos:master into * on doctrine:master*.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment