Skip to content

Commit

Permalink
Merge pull request #5577 from morozov/issues/5572
Browse files Browse the repository at this point in the history
Do not add artificial name to anonymous SQLite constraint
  • Loading branch information
morozov committed Aug 9, 2022
2 parents a6255b0 + 297f341 commit ff1727e
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 8 deletions.
14 changes: 7 additions & 7 deletions src/Schema/SqliteSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,8 @@ protected function _getPortableTableForeignKeysList($tableForeignKeys)
$list = [];
foreach ($tableForeignKeys as $value) {
$value = array_change_key_case($value, CASE_LOWER);
$name = $value['constraint_name'];
if (! isset($list[$name])) {
$id = $value['id'];
if (! isset($list[$id])) {
if (! isset($value['on_delete']) || $value['on_delete'] === 'RESTRICT') {
$value['on_delete'] = null;
}
Expand All @@ -453,8 +453,8 @@ protected function _getPortableTableForeignKeysList($tableForeignKeys)
$value['on_update'] = null;
}

$list[$name] = [
'name' => $name,
$list[$id] = [
'name' => $value['constraint_name'],
'local' => [],
'foreign' => [],
'foreignTable' => $value['table'],
Expand All @@ -465,13 +465,13 @@ protected function _getPortableTableForeignKeysList($tableForeignKeys)
];
}

$list[$name]['local'][] = $value['from'];
$list[$id]['local'][] = $value['from'];

if ($value['to'] === null) {
continue;
}

$list[$name]['foreign'][] = $value['to'];
$list[$id]['foreign'][] = $value['to'];
}

return parent::_getPortableTableForeignKeysList($list);
Expand Down Expand Up @@ -644,7 +644,7 @@ private function getForeignKeyDetails($table)

for ($i = 0, $count = count($match[0]); $i < $count; $i++) {
$details[] = [
'constraint_name' => isset($names[$i]) && $names[$i] !== '' ? $names[$i] : $i,
'constraint_name' => isset($names[$i]) && $names[$i] !== '' ? $names[$i] : null,
'deferrable' => isset($deferrable[$i]) && strcasecmp($deferrable[$i], 'deferrable') === 0,
'deferred' => isset($deferred[$i]) && strcasecmp($deferred[$i], 'deferred') === 0,
];
Expand Down
84 changes: 83 additions & 1 deletion tests/Functional/Schema/SqliteSchemaManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Types;

use function array_shift;
use function dirname;

class SqliteSchemaManagerTest extends SchemaManagerFunctionalTestCase
Expand Down Expand Up @@ -83,7 +84,7 @@ public function testListForeignKeysFromExistingDatabase(): void
['parent'],
'user',
['id'],
'1',
null,
['onUpdate' => 'NO ACTION', 'onDelete' => 'CASCADE', 'deferrable' => false, 'deferred' => false]
),
new ForeignKeyConstraint(
Expand Down Expand Up @@ -192,4 +193,85 @@ public function testOnlyOwnCommentIsParsed(): void
->getColumn('col1')
->getComment());
}

public function testNonSimpleAlterTableCreatedFromDDL(): void
{
$this->dropTableIfExists('nodes');

$ddl = <<<'DDL'
CREATE TABLE nodes (
id INTEGER NOT NULL,
parent_id INTEGER,
name TEXT,
PRIMARY KEY (id),
FOREIGN KEY (parent_id) REFERENCES nodes (id)
)
DDL;

$this->connection->executeStatement($ddl);

$schemaManager = $this->connection->createSchemaManager();

$table1 = $schemaManager->listTableDetails('nodes');
$table2 = clone $table1;
$table2->addIndex(['name'], 'idx_name');

$comparator = $schemaManager->createComparator();
$diff = $comparator->diffTable($table1, $table2);
self::assertNotFalse($diff);

$schemaManager->alterTable($diff);

$table = $schemaManager->listTableDetails('nodes');
$index = $table->getIndex('idx_name');
self::assertSame(['name'], $index->getColumns());
}

public function testIntrospectMultipleAnonymousForeignKeyConstraints(): void
{
$this->dropTableIfExists('album');
$this->dropTableIfExists('song');

$ddl = <<<'DDL'
CREATE TABLE artist(
id INTEGER,
name TEXT,
PRIMARY KEY(id)
);
CREATE TABLE album(
id INTEGER,
name TEXT,
PRIMARY KEY(id)
);
CREATE TABLE song(
id INTEGER,
album_id INTEGER,
artist_id INTEGER,
FOREIGN KEY(album_id) REFERENCES album(id),
FOREIGN KEY(artist_id) REFERENCES artist(id)
);
DDL;

$this->connection->executeStatement($ddl);

$schemaManager = $this->connection->createSchemaManager();

$song = $schemaManager->listTableDetails('song');
$foreignKeys = $song->getForeignKeys();
self::assertCount(2, $foreignKeys);

$foreignKey1 = array_shift($foreignKeys);
self::assertEmpty($foreignKey1->getName());

self::assertSame(['album_id'], $foreignKey1->getLocalColumns());
self::assertSame(['id'], $foreignKey1->getForeignColumns());

$foreignKey2 = array_shift($foreignKeys);
self::assertEmpty($foreignKey2->getName());

self::assertSame(['artist_id'], $foreignKey2->getLocalColumns());
self::assertSame(['id'], $foreignKey2->getForeignColumns());
}
}

0 comments on commit ff1727e

Please sign in to comment.