Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate modified foreign keys in TableDiff #6827

Merged
merged 1 commit into from
Mar 9, 2025

Conversation

morozov
Copy link
Member

@morozov morozov commented Mar 8, 2025

Constraints cannot be modified neither in the DBAL Schema API, nor in databases – they can be dropped and added. However, Comparator and TableDiff represent non-equal foreign key constraints with the same name as "modified".

This requires the consumer of the diff to implement additional processing of the "modified foreign keys" alongside the dropped and added ones:

foreach ($diff->getModifiedForeignKeys() as $foreignKey) {
$sql[] = $this->getDropForeignKeySQL($foreignKey->getQuotedName($this), $tableNameSQL);
}
foreach ($diff->getModifiedForeignKeys() as $foreignKey) {
$sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableNameSQL);
}
foreach (array_merge($diff->getModifiedForeignKeys(), $diff->getAddedForeignKeys()) as $constraint) {

The changes

As part of the deprecation, the Comparator will stop passing $modifiedForeignKeys to the TableDiff constructor and instead will start including the dropped and added constraint to $droppedForeignKeys and $addedForeignKeys respectively. I don't think that this is a breaking change assuming that the consumer of the diff processes it in full (not just the modified keys).

I coulnd't find any Doctrine (other than DBAL) and other open-source code that would use TableDiff#getModifiedForeignKeys() at all.

If we believe the shape of the diff should remain intact, then instead of deprecating the method, we need to introduce a comparator configuration parameter for producing the diff the new way and then deprecating it. This would be overkill.

@morozov morozov added this to the 4.3.0 milestone Mar 8, 2025
@morozov morozov requested a review from greg0ire March 8, 2025 01:04
@morozov morozov marked this pull request as ready for review March 8, 2025 02:38
@@ -44,6 +44,17 @@ public function __construct(
private readonly array $modifiedForeignKeys = [],
private readonly array $droppedForeignKeys = [],
) {
if (count($this->modifiedForeignKeys) < 1) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a convoluted way to check for 0, or am I missing something?

Copy link
Member Author

@morozov morozov Mar 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it checks if the array is empty. In general, the value under count() could be any Countable, and its count() could be negative, so checking for < 1 feels safer. But if it feels odd, we can agree on some other standard.

Personally for me, === 0 and !== 0 looks too strict (both from the standpoints of requiring a strict type match and a strict value match). The value is guaranteed to be of type int but isn't guaranteed to be non-negative.

This is all purely aesthetic (or it's "defensive programming"?), so I'm fine with using whatever others are good with (except for === [] and !== []).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would you want to silently return for negative values? Semantically, I'd lean towards === [] , we want to detect if the value differs from the default value (regardless of what it is), right? I mean, we want to deprecate this parameter, don't we?

Copy link
Member Author

@morozov morozov Mar 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Semantically, I'd lean towards === [] ,

This is a PHP-ism. See #6621 (comment) for more details. Let's stick with count($array) === 0 for "is array empty?" and count($array) !== 0 for "is array not empty?".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works for me

@@ -44,6 +44,17 @@ public function __construct(
private readonly array $modifiedForeignKeys = [],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this property be deprecated, BTW?

Copy link
Member Author

@morozov morozov Mar 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to deprecate a promoted property? In #6728, in order to deprecate ForeignKeyConstraint#$options, I had to replace a promoted constructor parameter with a parameter and property.

But in this case, the property is private, nobody can use it outside of the class anyways.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right, forget it then. And to answer your question, I thought it was possible to annotate them, but can't check right now.

@morozov morozov force-pushed the deprecate-modified-foreign-keys branch from f179488 to d965128 Compare March 9, 2025 01:00
@morozov morozov merged commit 22978f1 into doctrine:4.3.x Mar 9, 2025
68 checks passed
@morozov morozov deleted the deprecate-modified-foreign-keys branch March 9, 2025 08:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants