Skip to content

Commit

Permalink
Merge branch '3.5.x' into 4.0.x
Browse files Browse the repository at this point in the history
  • Loading branch information
morozov committed Oct 15, 2022
2 parents 7289470 + de5042f commit 73fa2c8
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 28 deletions.
21 changes: 21 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,11 @@ Relying on the availability of the `LOCATE()` on SQLite deprecated. SQLite does
but the function `INSTR()` can be a drop-in replacement in most situations. Use
`AbstractPlatform::getLocateExpression()` if you need a portable solution.

## Deprecated `SchemaDiff::$orphanedForeignKeys`

Relying on the schema diff tracking foreign keys referencing the tables that have been dropped is deprecated.
Before dropping a table referenced by foreign keys, drop the foreign keys first.

## Deprecated the `userDefinedFunctions` driver option for `pdo_sqlite`

Instead of funneling custom functions through the `userDefinedFunctions` option, use `getNativeConnection()`
Expand Down Expand Up @@ -958,6 +963,22 @@ The following `Comparator` methods have been marked as internal:

The `diffColumn()` method has been deprecated. Use `diffTable()` instead.

## Marked `SchemaDiff` public properties as internal.

The public properties of the `SchemaDiff` class have been marked as internal. Use the following corresponding methods
instead:

| Property | Method |
|----------------------|-------------------------|
| `$newNamespaces` | `getCreatedSchemas()` |
| `$removedNamespaces` | `getDroppedSchemas()` |
| `$newTables` | `getCreatedTables()` |
| `$changedTables` | `getAlteredTables()` |
| `$removedTables` | `getDroppedTables()` |
| `$newSequences` | `getCreatedSequences()` |
| `$changedSequences` | `getAlteredSequence()` |
| `$removedSequences` | `getDroppedSequences()` |

## Marked `TableDiff` public properties as internal.

The public properties of the `TableDiff` class have been marked as internal. Use the following corresponding methods
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"php": "^8.1",
"composer-runtime-api": "^2",
"doctrine/deprecations": "^0.5.3|^1",
"doctrine/event-manager": "^1.0",
"doctrine/event-manager": "^1|^2",
"psr/cache": "^1|^2|^3",
"psr/log": "^1|^2|^3"
},
Expand Down
8 changes: 8 additions & 0 deletions psalm.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@
<referencedMethod name="Doctrine\DBAL\Schema\Table::changeColumn"/>
</errorLevel>
</DeprecatedMethod>
<DeprecatedProperty>
<errorLevel type="suppress">
<!--
TODO: remove in 4.0.0
-->
<referencedProperty name="Doctrine\DBAL\Schema\SchemaDiff::$orphanedForeignKeys"/>
</errorLevel>
</DeprecatedProperty>
<DocblockTypeContradiction>
<errorLevel type="suppress">
<!--
Expand Down
52 changes: 37 additions & 15 deletions src/Schema/Comparator.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,16 @@ public function __construct(private readonly AbstractPlatform $platform)
*/
public function compareSchemas(Schema $fromSchema, Schema $toSchema): SchemaDiff
{
$diff = new SchemaDiff();
$createdSchemas = [];
$droppedSchemas = [];
$createdTables = [];
$alteredTables = [];
$droppedTables = [];
$createdSequences = [];
$alteredSequences = [];
$droppedSequences = [];

$orphanedForeignKeys = [];

/** @var array<string,list<array{ForeignKeyConstraint,string}>> $foreignKeysToTable */
$foreignKeysToTable = [];
Expand All @@ -40,29 +49,29 @@ public function compareSchemas(Schema $fromSchema, Schema $toSchema): SchemaDiff
continue;
}

$diff->newNamespaces[$namespace] = $namespace;
$createdSchemas[$namespace] = $namespace;
}

foreach ($fromSchema->getNamespaces() as $namespace) {
if ($toSchema->hasNamespace($namespace)) {
continue;
}

$diff->removedNamespaces[$namespace] = $namespace;
$droppedSchemas[$namespace] = $namespace;
}

foreach ($toSchema->getTables() as $table) {
$tableName = $table->getShortestName($toSchema->getName());
if (! $fromSchema->hasTable($tableName)) {
$diff->newTables[$tableName] = $toSchema->getTable($tableName);
$createdTables[$tableName] = $toSchema->getTable($tableName);
} else {
$tableDifferences = $this->diffTable(
$fromSchema->getTable($tableName),
$toSchema->getTable($tableName),
);

if ($tableDifferences !== null) {
$diff->changedTables[$tableName] = $tableDifferences;
$alteredTables[$tableName] = $tableDifferences;
}
}
}
Expand All @@ -73,7 +82,7 @@ public function compareSchemas(Schema $fromSchema, Schema $toSchema): SchemaDiff

$table = $fromSchema->getTable($tableName);
if (! $toSchema->hasTable($tableName)) {
$diff->removedTables[$tableName] = $table;
$droppedTables[$tableName] = $table;
}

// also remember all foreign keys that point to a specific table
Expand All @@ -85,33 +94,33 @@ public function compareSchemas(Schema $fromSchema, Schema $toSchema): SchemaDiff
}
}

foreach ($diff->removedTables as $tableName => $table) {
foreach ($droppedTables as $tableName => $table) {
if (! isset($foreignKeysToTable[$tableName])) {
continue;
}

foreach ($foreignKeysToTable[$tableName] as [$foreignKey, $localTableName]) {
if (isset($diff->removedTables[strtolower($localTableName)])) {
if (isset($droppedTables[strtolower($localTableName)])) {
continue;
}

$diff->orphanedForeignKeys[$tableName][] = $foreignKey;
$orphanedForeignKeys[$tableName][] = $foreignKey;
}

// deleting duplicated foreign keys present on both on the orphanedForeignKey
// and the removedForeignKeys from changedTables
foreach ($localTablesByForeignTable[$tableName] as $localTableName => $_) {
if (! isset($diff->changedTables[$localTableName])) {
if (! isset($alteredTables[$localTableName])) {
continue;
}

foreach ($diff->changedTables[$localTableName]->getDroppedForeignKeys() as $droppedForeignKey) {
foreach ($alteredTables[$localTableName]->getDroppedForeignKeys() as $droppedForeignKey) {
// We check if the key is from the removed table if not we skip.
if ($tableName !== strtolower($droppedForeignKey->getForeignTableName())) {
continue;
}

$diff->changedTables[$localTableName]->unsetDroppedForeignKey($droppedForeignKey);
$alteredTables[$localTableName]->unsetDroppedForeignKey($droppedForeignKey);
}
}
}
Expand All @@ -120,11 +129,11 @@ public function compareSchemas(Schema $fromSchema, Schema $toSchema): SchemaDiff
$sequenceName = $sequence->getShortestName($toSchema->getName());
if (! $fromSchema->hasSequence($sequenceName)) {
if (! $this->isAutoIncrementSequenceInSchema($fromSchema, $sequence)) {
$diff->newSequences[] = $sequence;
$createdSequences[] = $sequence;
}
} else {
if ($this->diffSequence($sequence, $fromSchema->getSequence($sequenceName))) {
$diff->changedSequences[] = $toSchema->getSequence($sequenceName);
$alteredSequences[] = $toSchema->getSequence($sequenceName);
}
}
}
Expand All @@ -140,9 +149,22 @@ public function compareSchemas(Schema $fromSchema, Schema $toSchema): SchemaDiff
continue;
}

$diff->removedSequences[] = $sequence;
$droppedSequences[] = $sequence;
}

$diff = new SchemaDiff(
$createdTables,
$alteredTables,
$droppedTables,
$createdSchemas,
$droppedSchemas,
$createdSequences,
$alteredSequences,
$droppedSequences,
);

$diff->orphanedForeignKeys = $orphanedForeignKeys;

return $diff;
}

Expand Down
106 changes: 94 additions & 12 deletions src/Schema/SchemaDiff.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,44 @@ class SchemaDiff
/**
* All added namespaces.
*
* @internal Use {@link getCreatedSchemas()} instead.
*
* @var array<string, string>
*/
public array $newNamespaces = [];

/**
* All removed namespaces.
*
* @internal Use {@link getDroppedSchemas()} instead.
*
* @var array<string, string>
*/
public array $removedNamespaces = [];

/** @var array<int, Sequence> */
/**
* @internal Use {@link getCreatedSequences()} instead.
*
* @var array<int, Sequence>
*/
public array $newSequences = [];

/** @var array<int, Sequence> */
/**
* @internal Use {@link getAlteredSequences()} instead.
*
* @var array<int, Sequence>
*/
public array $changedSequences = [];

/** @var array<int, Sequence> */
/**
* @internal Use {@link getDroppedSequences()} instead.
*
* @var array<int, Sequence>
*/
public array $removedSequences = [];

/**
* Map of table names to their list of orphaned foreign keys.
* @deprecated
*
* @var array<string,list<ForeignKeyConstraint>>
*/
Expand All @@ -52,12 +68,78 @@ class SchemaDiff
* @param array<string, Table> $newTables
* @param array<string, TableDiff> $changedTables
* @param array<string, Table> $removedTables
* @param array<string> $createdSchemas
* @param array<string> $droppedSchemas
* @param array<Sequence> $createdSequences
* @param array<Sequence> $alteredSequences
* @param array<Sequence> $droppedSequences
*/
public function __construct(
/** @internal Use {@link getCreatedTables()} instead. */
public array $newTables = [],
/** @internal Use {@link getAlteredTables()} instead. */
public array $changedTables = [],
/** @internal Use {@link getDroppedTables()} instead. */
public array $removedTables = [],
array $createdSchemas = [],
array $droppedSchemas = [],
array $createdSequences = [],
array $alteredSequences = [],
array $droppedSequences = [],
) {
$this->newNamespaces = $createdSchemas;
$this->removedNamespaces = $droppedSchemas;
$this->newSequences = $createdSequences;
$this->changedSequences = $alteredSequences;
$this->removedSequences = $droppedSequences;
}

/** @return array<string> */
public function getCreatedSchemas(): array
{
return $this->newNamespaces;
}

/** @return array<string> */
public function getDroppedSchemas(): array
{
return $this->removedNamespaces;
}

/** @return array<Table> */
public function getCreatedTables(): array
{
return $this->newTables;
}

/** @return array<TableDiff> */
public function getAlteredTables(): array
{
return $this->changedTables;
}

/** @return array<Table> */
public function getDroppedTables(): array
{
return $this->removedTables;
}

/** @return array<Sequence> */
public function getCreatedSequences(): array
{
return $this->newSequences;
}

/** @return array<Sequence> */
public function getAlteredSequences(): array
{
return $this->changedSequences;
}

/** @return array<Sequence> */
public function getDroppedSequences(): array
{
return $this->removedSequences;
}

/**
Expand Down Expand Up @@ -88,8 +170,8 @@ protected function _toSql(AbstractPlatform $platform, bool $saveMode = false): a
$sql = [];

if ($platform->supportsSchemas()) {
foreach ($this->newNamespaces as $newNamespace) {
$sql[] = $platform->getCreateSchemaSQL($newNamespace);
foreach ($this->getCreatedSchemas() as $schema) {
$sql[] = $platform->getCreateSchemaSQL($schema);
}
}

Expand All @@ -105,28 +187,28 @@ protected function _toSql(AbstractPlatform $platform, bool $saveMode = false): a
}

if ($platform->supportsSequences()) {
foreach ($this->changedSequences as $sequence) {
foreach ($this->getAlteredSequences() as $sequence) {
$sql[] = $platform->getAlterSequenceSQL($sequence);
}

if ($saveMode === false) {
foreach ($this->removedSequences as $sequence) {
foreach ($this->getDroppedSequences() as $sequence) {
$sql[] = $platform->getDropSequenceSQL($sequence->getQuotedName($platform));
}
}

foreach ($this->newSequences as $sequence) {
foreach ($this->getCreatedSequences() as $sequence) {
$sql[] = $platform->getCreateSequenceSQL($sequence);
}
}

$sql = array_merge($sql, $platform->getCreateTablesSQL(array_values($this->newTables)));
$sql = array_merge($sql, $platform->getCreateTablesSQL(array_values($this->getCreatedTables())));

if ($saveMode === false) {
$sql = array_merge($sql, $platform->getDropTablesSQL(array_values($this->removedTables)));
$sql = array_merge($sql, $platform->getDropTablesSQL(array_values($this->getDroppedTables())));
}

foreach ($this->changedTables as $tableDiff) {
foreach ($this->getAlteredTables() as $tableDiff) {
$sql = array_merge($sql, $platform->getAlterTableSQL($tableDiff));
}

Expand Down

0 comments on commit 73fa2c8

Please sign in to comment.