Skip to content

Commit

Permalink
Prep work for enabling support for foreign keys on SQLite
Browse files Browse the repository at this point in the history
  • Loading branch information
morozov authored and greg0ire committed Jun 12, 2022
1 parent e5bd086 commit a4ba98f
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 273 deletions.
40 changes: 14 additions & 26 deletions lib/Doctrine/ORM/Tools/SchemaTool.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector;
use Doctrine\DBAL\Schema\Visitor\RemoveNamespacedAssets;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata;
Expand Down Expand Up @@ -848,12 +847,9 @@ public function dropDatabase()
*/
public function getDropDatabaseSQL()
{
$schema = $this->schemaManager->createSchema();

$visitor = new DropSchemaSqlCollector($this->platform);
$schema->visit($visitor);

return $visitor->getQueries();
return $this->schemaManager
->createSchema()
->toDropSql($this->platform);
}

/**
Expand All @@ -865,45 +861,37 @@ public function getDropDatabaseSQL()
*/
public function getDropSchemaSQL(array $classes)
{
$visitor = new DropSchemaSqlCollector($this->platform);
$schema = $this->getSchemaFromMetadata($classes);
$schema = $this->getSchemaFromMetadata($classes);

$fullSchema = $this->schemaManager->createSchema();
$deployedSchema = $this->schemaManager->createSchema();

foreach ($fullSchema->getTables() as $table) {
if (! $schema->hasTable($table->getName())) {
foreach ($table->getForeignKeys() as $foreignKey) {
if ($schema->hasTable($foreignKey->getForeignTableName())) {
$visitor->acceptForeignKey($table, $foreignKey);
}
}
} else {
$visitor->acceptTable($table);
foreach ($table->getForeignKeys() as $foreignKey) {
$visitor->acceptForeignKey($table, $foreignKey);
}
foreach ($schema->getTables() as $table) {
if (! $deployedSchema->hasTable($table->getName())) {
$schema->dropTable($table->getName());
}
}

if ($this->platform->supportsSequences()) {
foreach ($schema->getSequences() as $sequence) {
$visitor->acceptSequence($sequence);
if (! $deployedSchema->hasSequence($sequence->getName())) {
$schema->dropSequence($sequence->getName());
}
}

foreach ($schema->getTables() as $table) {
if ($table->hasPrimaryKey()) {
$columns = $table->getPrimaryKey()->getColumns();
if (count($columns) === 1) {
$checkSequence = $table->getName() . '_' . $columns[0] . '_seq';
if ($fullSchema->hasSequence($checkSequence)) {
$visitor->acceptSequence($fullSchema->getSequence($checkSequence));
if ($deployedSchema->hasSequence($checkSequence) && ! $schema->hasSequence($checkSequence)) {
$schema->createSequence($checkSequence);
}
}
}
}
}

return $visitor->getQueries();
return $schema->toDropSql($this->platform);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@

namespace Doctrine\Tests\ORM\Functional\SchemaTool;

use Doctrine\DBAL\Platforms\SqlitePlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Tests\Models\Company\CompanyManager;
use Doctrine\Tests\OrmFunctionalTestCase;

/**
Expand Down Expand Up @@ -50,21 +48,4 @@ public function testSingleTableInheritance(Schema $schema): void
self::assertFalse($table->getColumn('pricePerHour')->getNotnull());
self::assertFalse($table->getColumn('maxPrice')->getNotnull());
}

/**
* @group DBAL-115
*/
public function testDropPartSchemaWithForeignKeys(): void
{
if ($this->_em->getConnection()->getDatabasePlatform() instanceof SqlitePlatform) {
self::markTestSkipped('SQLite does not support dropping foreign keys.');
}

$sql = $this->_schemaTool->getDropSchemaSQL(
[
$this->_em->getClassMetadata(CompanyManager::class),
]
);
self::assertCount(4, $sql);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
use Doctrine\Tests\OrmFunctionalTestCase;

use function array_filter;
use function array_shift;
use function implode;
use function str_starts_with;

Expand All @@ -40,94 +39,6 @@ public function testPostgresMetadataSequenceIncrementedBy10(): void
self::assertEquals(1, $address->sequenceGeneratorDefinition['allocationSize']);
}

public function testGetCreateSchemaSql(): void
{
$classes = [
$this->_em->getClassMetadata(Models\CMS\CmsAddress::class),
$this->_em->getClassMetadata(Models\CMS\CmsUser::class),
$this->_em->getClassMetadata(Models\CMS\CmsPhonenumber::class),
];

$tool = new SchemaTool($this->_em);
$sql = $tool->getCreateSchemaSql($classes);

self::assertCount(22, $sql, 'Total of 22 queries should be executed');

self::assertEquals('CREATE TABLE cms_addresses (id INT NOT NULL, user_id INT DEFAULT NULL, country VARCHAR(50) NOT NULL, zip VARCHAR(50) NOT NULL, city VARCHAR(50) NOT NULL, PRIMARY KEY(id))', array_shift($sql));
self::assertEquals('CREATE UNIQUE INDEX UNIQ_ACAC157BA76ED395 ON cms_addresses (user_id)', array_shift($sql));
self::assertEquals('CREATE TABLE cms_users (id INT NOT NULL, email_id INT DEFAULT NULL, status VARCHAR(50) DEFAULT NULL, username VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))', array_shift($sql));
self::assertEquals('CREATE UNIQUE INDEX UNIQ_3AF03EC5F85E0677 ON cms_users (username)', array_shift($sql));
self::assertEquals('CREATE UNIQUE INDEX UNIQ_3AF03EC5A832C1C9 ON cms_users (email_id)', array_shift($sql));
self::assertEquals('CREATE TABLE cms_users_groups (user_id INT NOT NULL, group_id INT NOT NULL, PRIMARY KEY(user_id, group_id))', array_shift($sql));
self::assertEquals('CREATE INDEX IDX_7EA9409AA76ED395 ON cms_users_groups (user_id)', array_shift($sql));
self::assertEquals('CREATE INDEX IDX_7EA9409AFE54D947 ON cms_users_groups (group_id)', array_shift($sql));
self::assertEquals('CREATE TABLE cms_users_tags (user_id INT NOT NULL, tag_id INT NOT NULL, PRIMARY KEY(user_id, tag_id))', array_shift($sql));
self::assertEquals('CREATE INDEX IDX_93F5A1ADA76ED395 ON cms_users_tags (user_id)', array_shift($sql));
self::assertEquals('CREATE INDEX IDX_93F5A1ADBAD26311 ON cms_users_tags (tag_id)', array_shift($sql));
self::assertEquals('CREATE TABLE cms_phonenumbers (phonenumber VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, PRIMARY KEY(phonenumber))', array_shift($sql));
self::assertEquals('CREATE INDEX IDX_F21F790FA76ED395 ON cms_phonenumbers (user_id)', array_shift($sql));
self::assertEquals('CREATE SEQUENCE cms_addresses_id_seq INCREMENT BY 1 MINVALUE 1 START 1', array_shift($sql));
self::assertEquals('CREATE SEQUENCE cms_users_id_seq INCREMENT BY 1 MINVALUE 1 START 1', array_shift($sql));
self::assertEquals('ALTER TABLE cms_addresses ADD CONSTRAINT FK_ACAC157BA76ED395 FOREIGN KEY (user_id) REFERENCES cms_users (id) NOT DEFERRABLE INITIALLY IMMEDIATE', array_shift($sql));
self::assertEquals('ALTER TABLE cms_users ADD CONSTRAINT FK_3AF03EC5A832C1C9 FOREIGN KEY (email_id) REFERENCES cms_emails (id) NOT DEFERRABLE INITIALLY IMMEDIATE', array_shift($sql));
self::assertEquals('ALTER TABLE cms_users_groups ADD CONSTRAINT FK_7EA9409AA76ED395 FOREIGN KEY (user_id) REFERENCES cms_users (id) NOT DEFERRABLE INITIALLY IMMEDIATE', array_shift($sql));
self::assertEquals('ALTER TABLE cms_users_groups ADD CONSTRAINT FK_7EA9409AFE54D947 FOREIGN KEY (group_id) REFERENCES cms_groups (id) NOT DEFERRABLE INITIALLY IMMEDIATE', array_shift($sql));
self::assertEquals('ALTER TABLE cms_users_tags ADD CONSTRAINT FK_93F5A1ADA76ED395 FOREIGN KEY (user_id) REFERENCES cms_users (id) NOT DEFERRABLE INITIALLY IMMEDIATE', array_shift($sql));
self::assertEquals('ALTER TABLE cms_users_tags ADD CONSTRAINT FK_93F5A1ADBAD26311 FOREIGN KEY (tag_id) REFERENCES cms_tags (id) NOT DEFERRABLE INITIALLY IMMEDIATE', array_shift($sql));
self::assertEquals('ALTER TABLE cms_phonenumbers ADD CONSTRAINT FK_F21F790FA76ED395 FOREIGN KEY (user_id) REFERENCES cms_users (id) NOT DEFERRABLE INITIALLY IMMEDIATE', array_shift($sql));

self::assertEquals([], $sql, 'SQL Array should be empty now.');
}

public function testGetCreateSchemaSql2(): void
{
$classes = [$this->_em->getClassMetadata(Models\Generic\DecimalModel::class)];

$tool = new SchemaTool($this->_em);
$sql = $tool->getCreateSchemaSql($classes);

self::assertCount(2, $sql);

self::assertEquals('CREATE TABLE decimal_model (id INT NOT NULL, "decimal" NUMERIC(5, 2) NOT NULL, "high_scale" NUMERIC(14, 4) NOT NULL, PRIMARY KEY(id))', $sql[0]);
self::assertEquals('CREATE SEQUENCE decimal_model_id_seq INCREMENT BY 1 MINVALUE 1 START 1', $sql[1]);
}

public function testGetCreateSchemaSql3(): void
{
$classes = [$this->_em->getClassMetadata(Models\Generic\BooleanModel::class)];

$tool = new SchemaTool($this->_em);
$sql = $tool->getCreateSchemaSql($classes);

self::assertCount(2, $sql);
self::assertEquals('CREATE TABLE boolean_model (id INT NOT NULL, booleanField BOOLEAN NOT NULL, PRIMARY KEY(id))', $sql[0]);
self::assertEquals('CREATE SEQUENCE boolean_model_id_seq INCREMENT BY 1 MINVALUE 1 START 1', $sql[1]);
}

public function testGetDropSchemaSql(): void
{
$classes = [
$this->_em->getClassMetadata(Models\CMS\CmsAddress::class),
$this->_em->getClassMetadata(Models\CMS\CmsUser::class),
$this->_em->getClassMetadata(Models\CMS\CmsPhonenumber::class),
];

$tool = new SchemaTool($this->_em);
$sql = $tool->getDropSchemaSQL($classes);

self::assertCount(17, $sql);

$dropSequenceSQLs = 0;

foreach ($sql as $stmt) {
if (str_starts_with($stmt, 'DROP SEQUENCE')) {
$dropSequenceSQLs++;
}
}

self::assertEquals(4, $dropSequenceSQLs, 'Expect 4 sequences to be dropped.');
}

/**
* @group DDC-1657
*/
Expand Down
82 changes: 0 additions & 82 deletions tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1151Test.php

This file was deleted.

57 changes: 0 additions & 57 deletions tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1360Test.php

This file was deleted.

6 changes: 6 additions & 0 deletions tests/Doctrine/Tests/ORM/Functional/Ticket/DDC832Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Doctrine\Tests\ORM\Functional\Ticket;

use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\DiscriminatorColumn;
use Doctrine\ORM\Mapping\DiscriminatorMap;
Expand Down Expand Up @@ -41,6 +42,11 @@ public function tearDown(): void
$sm->dropTable($platform->quoteIdentifier('TREE_INDEX'));
$sm->dropTable($platform->quoteIdentifier('INDEX'));
$sm->dropTable($platform->quoteIdentifier('LIKE'));

if ($platform instanceof PostgreSQLPlatform) {
$sm->dropSequence($platform->quoteIdentifier('INDEX_id_seq'));
$sm->dropSequence($platform->quoteIdentifier('LIKE_id_seq'));
}
}

/**
Expand Down

0 comments on commit a4ba98f

Please sign in to comment.