Skip to content

Commit bed0b34

Browse files
committed
DiffGenerator: fixes circular references for removed tables
1 parent 47f931a commit bed0b34

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed

src/DiffGenerator.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ private function prepareChanges()
9191
$this->updatedTables = $this->prepareUpdatedTables();
9292
$this->removedTables = $this->prepareRemovedTables();
9393
$this->fixCreatedCircularReferences();
94+
$this->fixRemovedCircularReferences();
9495
$this->prepared = TRUE;
9596
}
9697

@@ -501,6 +502,59 @@ private function fixCreatedCircularReferences()
501502
}
502503

503504

505+
/**
506+
* @return void
507+
*/
508+
private function fixRemovedCircularReferences()
509+
{
510+
$sortedTables = $this->sortTables($this->old->getTables(), $this->removedTables);
511+
$exists = [];
512+
513+
foreach ($sortedTables as $sortedTable) {
514+
$exists[$sortedTable->getTableName()] = TRUE;
515+
}
516+
517+
$removedNames = [];
518+
519+
foreach ($sortedTables as $removedTable) {
520+
$tableName = $removedTable->getTableName();
521+
522+
if (!isset($exists[$tableName])) {
523+
$removedNames[$tableName] = [];
524+
continue;
525+
}
526+
527+
$definition = $this->old->getTable($removedTable->getTableName());
528+
529+
if ($definition === NULL) {
530+
continue;
531+
}
532+
533+
$updates = [];
534+
535+
foreach ($definition->getForeignKeys() as $foreignKey) {
536+
$targetTable = $foreignKey->getTargetTable();
537+
538+
if (!isset($exists[$targetTable])) {
539+
continue;
540+
}
541+
542+
if (!isset($removedNames[$targetTable])) { // circular reference
543+
$updates[] = new Diffs\RemovedForeignKey($tableName, $foreignKey->getName());
544+
}
545+
}
546+
547+
$removedNames[$tableName] = $updates;
548+
}
549+
550+
foreach ($removedNames as $tableName => $updates) {
551+
if (count($updates) > 0) {
552+
$this->updatedTables[] = new Diffs\UpdatedTable($tableName, $updates);
553+
}
554+
}
555+
}
556+
557+
504558
private function sortTables(array $allTables, array $tablesToSort)
505559
{
506560
$tableOrder = $this->resolveOrder($allTables);

tests/SchemaGenerator/diffs/removed-table.phpt

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,52 @@ test(function () {
1717
$generator->generator->generate();
1818
Assert::same("DROP TABLE `book`;\n", $generator->dumper->getSql());
1919
});
20+
21+
22+
test(function () { // circular dependency
23+
$old = new SqlSchema\Schema;
24+
$new = new SqlSchema\Schema;
25+
26+
$oldGallery = $old->addTable('gallery');
27+
$oldGallery->addColumn('id', 'INT');
28+
$oldGallery->addColumn('primaryPhoto_id', 'INT');
29+
$oldGallery->addForeignKey('fk_primaryPhoto', 'primaryPhoto_id', 'photo', 'id');
30+
31+
$oldPhoto = $old->addTable('photo');
32+
$oldPhoto->addColumn('id', 'INT');
33+
$oldPhoto->addColumn('gallery_id', 'INT');
34+
$oldPhoto->addForeignKey('fk_gallery', 'gallery_id', 'gallery', 'id');
35+
36+
$newGallery = $new->addTable('gallery');
37+
$newGallery->addColumn('id', 'INT');
38+
39+
$generator = Test\TestGenerator::create($old, $new);
40+
$generator->generator->generate();
41+
Assert::same(implode("\n", [
42+
'ALTER TABLE `gallery`',
43+
'DROP FOREIGN KEY `fk_primaryPhoto`,',
44+
'DROP COLUMN `primaryPhoto_id`;',
45+
'',
46+
"DROP TABLE `photo`;",
47+
]) . "\n", $generator->dumper->getSql());
48+
});
49+
50+
51+
test(function () { // circular dependency - self reference
52+
$old = new SqlSchema\Schema;
53+
$new = new SqlSchema\Schema;
54+
55+
$oldGallery = $old->addTable('gallery');
56+
$oldGallery->addColumn('id', 'INT');
57+
$oldGallery->addColumn('parent_id', 'INT');
58+
$oldGallery->addForeignKey('fk_parent', 'parent_id', 'gallery', 'id');
59+
60+
$generator = Test\TestGenerator::create($old, $new);
61+
$generator->generator->generate();
62+
Assert::same(implode("\n", [
63+
'ALTER TABLE `gallery`',
64+
'DROP FOREIGN KEY `fk_parent`;',
65+
'',
66+
"DROP TABLE `gallery`;",
67+
]) . "\n", $generator->dumper->getSql());
68+
});

0 commit comments

Comments
 (0)