Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Fix AlterTable::dropConstraint() by allowing the use of decorator #247

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from

Conversation

nanawel
Copy link
Contributor

@nanawel nanawel commented May 22, 2017

Fixes a broken implementation under MySQL: DROP CONSTRAINT is not supported, you have to use DROP [FOREIGN KEY | INDEX | KEY] instead.

See issue #36

Warning: introduces a potential breaking change (string parameter is now a typed object).

@@ -74,7 +75,7 @@ class AlterTable extends AbstractSql implements SqlInterface
],
self::DROP_CONSTRAINTS => [
"%1\$s" => [
[1 => "DROP CONSTRAINT %1\$s,\n", 'combinedby' => ""],
[2 => "DROP %1\$s %2\$s,\n", 'combinedby' => ""],
Copy link
Contributor

Choose a reason for hiding this comment

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

Do not modify generic syntax from abstract classes other adapters inherit from for engine specific fixes. Fixing one engine breaks assumptions of others within this library or others making custom adapters.

$sqls[] = $adapterPlatform->quoteIdentifier($constraint);
$sqls[] = [
'CONSTRAINT',
$adapterPlatform->quoteIdentifier($constraint->getName())
Copy link
Contributor

@alextech alextech May 22, 2017

Choose a reason for hiding this comment

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

Until this #233 goes through that fixes bugs in quoteIdentifier vs quoteIdentifierChain this will break PostgreSQL and MSSQL. If lucky and that PR gets merged prior to this, then its fine.

foreach ($this->dropConstraints as $constraint) {
$sqls[] = [
$constraint->getType(),
$adapterPlatform->quoteIdentifier($constraint->getName())
Copy link
Contributor

Choose a reason for hiding this comment

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

As above

use \Zend\Db\Metadata\Object\ConstraintObject;

$fkConstraint = new ConstraintObject('my_fk', null);
$fkConstraint->setType('FOREIGN KEY');
Copy link
Contributor

Choose a reason for hiding this comment

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

Disagree. If you want your constraint to represent foreign key, then use ForeignKey class that already does this.

Copy link
Contributor Author

@nanawel nanawel May 22, 2017

Choose a reason for hiding this comment

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

Sure, I can do that. But as I said on issue #36, I thought it was better because it describes an existing constraint (metadata) that can be retrieved by analyzing the database, hence programatically.

Also, \Zend\Db\Sql\Ddl\Constraint\ForeignKey requires a lot of arguments, which are useless for dropping.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh I just noticed how ConstraintObject lets you do that... Why such duality... :( I guess at the moment both would work, but to go forward initiative to migrate to PHP 7.1 and all related type inconsistency fixes as discussed on development channel, this lose handling needs to go away. Imagine others who will not notice this duplication of functionality in ConstraintObject and ForeignKey.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see... In that case metadata analyzer is broken not assigning foreign key constraint to ForeignKey constraint object. I should not be penalized for wanting to use given by the framework ForeignKey object to describe foreign key constraint. I suppose that means both need to be handled by the Decorator at this point since that's what the library gives us. Or clean creation of ConstraintObject to create ForeignKey, which would be further reaching change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Or clean creation of ConstraintObject to create ForeignKey, which would be further reaching change.

\Zend\Db\Metadata\Source\AbstractSource::getConstraint() seems to be doing its job when analyzing the table and assigns the type of constraints correctly.

But yeah, when you dig that down you realize there are some nasty inconsistencies to take care of ahead of that bug.

Anyway, I'll take your remarks into account and I'll make some changes, hopefully for the best. But I'm not going to rewrite half of the framework either.

Copy link
Contributor

@alextech alextech May 22, 2017

Choose a reason for hiding this comment

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

Was about to suggest to let dropConstraint method take in AbstractConstraint so you have access to best of both ConstraintObject and ForeignKey, but what do you know, ConstraintObject does not inherit from AbstractConstraint or ConstraintInterface as name would imply!
Just cannot win here without

rewrite half of the framework either.

But that's too much to ask for at this time ...

Great job on moving specifications to decorators. Those are tough to do.

For version 3, which according to discussions all new versions want to target PHP 7.1 strict type system, it would be needed to rewrite to tighten up the types allowed per method to weed out those

nasty inconsistencies to take care of ahead of that bug.

I would have fun doing it, but a little discouraging based on rate of PR reviews.

nanawel added 3 commits May 22, 2017 21:13
…rface and \Zend\Db\Metadata\Object\ConstraintObject when dropping a constraint (thanks @alextech)
@ezimuel ezimuel added this to the 3.0.0 milestone Dec 4, 2017
…raint

# Conflicts:
#	test/Sql/Ddl/AlterTableTest.php
#	test/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php
@nanawel
Copy link
Contributor Author

nanawel commented Dec 27, 2017

Fixed errors after merge with master. Ready for integration in 3.0.0 if everything's ok for you.

@nanawel
Copy link
Contributor Author

nanawel commented Aug 12, 2018

I've updated my branch with the latest revision from develop.

Unfortunately it shows a failure with code coverage which is in fact invalid. The file /src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php should be almost entirely covered (tested in local with a good old die() to be sure) but it's shown as only 2% covered in Travis.

@alextech Have you ever had this issue?
BTW, this coverage problem is already present in earlier revisions, it's just that my commit increased a bit the reported missing coverage ratio.

@alextech
Copy link
Contributor

@nanawel I too have this issue. (dont want to put in PR ID here to confuse the issue tracker relevancy, search "coverage" in open PRs where I point it out). Was passing then suddenly dropped. There was an effort to upgrade travis config files across all of ZF repositories to make it more strict and after it there was more failings here in unexpected commits. I think I see why mine failed (though its a bit stretched) where I formatted my error output and so travis wants me to tests the full formatting logic, which is just a printf() XD ....

According to the report there is unexercised "processDropConstraints" function. Line was added there but none of your tests seem to cover it. Even if the whole file has coverage by previous commits, that does not mean this particular commit is covered, therefore travis thinks it is new untested BC break (which makes sense). That is, travis checks that this set of commits is fully covering all of changes.

Do your new tests execute that line 234 or only old ones?

@nanawel
Copy link
Contributor Author

nanawel commented Aug 12, 2018

There are actually 2 tests related to processDropConstraints() which are the drop of the FK and the index. I added those lines way before today's merge so nothing has changed there. In fact, the only changes required after the merge were code style related, to match how the strings are split up on develop, which is slightly different from how they were when I submitted the PR.

@nanawel
Copy link
Contributor Author

nanawel commented Dec 18, 2018

Hi, still looking forward to seeing this in the upcoming 3.0.0. Thanks!

@nanawel
Copy link
Contributor Author

nanawel commented Jul 1, 2019

Hi,
just bumping this PR, in case it got forgotten :)

@binal-7span
Copy link

@alexdenvir — Can you please provide an update on this?

I have a CMS and I am using Zend-DB. Right now I am not able to use the drop constraint functionality. I can use this code directly in my fork repo, but before that, I want to know the reason behind not letting this PR merged.

Update on this PR will be very helpful. So can you please provide it ASAP?

@alexdenvir
Copy link
Contributor

@alexdenvir — Can you please provide an update on this?

Sorry, but no. Maybe try pinging @alextech instead?

@alextech
Copy link
Contributor

I am just a contributor level :-)

@alexdenvir
Copy link
Contributor

Same here, although never to zend-db specifically. I saw you had left a review and assumed @BJGajjar meant to ping you instead. My bad

@michalbundyra
Copy link
Member

I see it's marked as BC Break so planned for v3 release. I guess it will be much easier to get it in without BC Break (if possible?)

@michalbundyra
Copy link
Member

@alextech @nanawel @alexdenvir @BJGajjar
I think it is possible to change the code to keep BC.
We can accept both - string and ConstraintInterface, and deprecate on string.
If string provided we can create ConstraintObject internally so behaviour should really stay the same. Then for v3 we will accept only ConstraintInterface.

What do you think?

@binal-7span
Copy link

@alexdenvir

Maybe try pinging @alextech instead?

Yeah. Sorry for the inconvenience.

@webimpress

We can accept both - string and ConstraintInterface, and deprecate on the string.

Agree we can do that way also.

@nanawel

It seems like there is some issue with this PR. I tried to use this code in my fork repo and use the dropConstraint for Unique constraint as well as PrimaryKey. But not able to drop it.
When I print the SQL query it is returning "" as a constraint.

                    DROP CONSTRAINT ""

For your reference;
You have been added getConstraintType function in src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php and when I alter the table it is using the processDropConstraints function of src/Sql/Ddl/AlterTable.php

@michalbundyra
Copy link
Member

michalbundyra commented Aug 28, 2019

@BJGajjar would you be able to provide PR based on that with changes I've described above, fixes of the issue you found, and tests to cover changes, please?

@itsmerhp
Copy link

@nanawel @webimpress @BJGajjar @alextech @alexdenvir

We can accept both - string and ConstraintInterface, and deprecate on string.
If string provided we can create ConstraintObject internally so behaviour should really stay the same.

As suggested by @webimpress, I think we can provide BC(accept both - string and ConstraintInterface) by below change :

public function dropConstraint($constraint) {
	$constraint = is_object($constraint) ? $constraint : new ConstraintObject($constraint, NULL);
	$this->dropConstraints[] = $constraint;
	return $this;
}

Please share your thoughts on it.

@weierophinney
Copy link
Member

This repository has been moved to laminas/laminas-db. If you feel that this patch is still relevant, please re-open against that repository, and reference this issue. To re-open, we suggest the following workflow:

  • Squash all commits in your branch (git rebase -i origin/{branch})
  • Make a note of all changed files (`git diff --name-only origin/{branch}...HEAD
  • Run the laminas/laminas-migration tool on the code.
  • Clone laminas/laminas-db to another directory.
  • Copy the files from the second bullet point to the clone of laminas/laminas-db.
  • In your clone of laminas/laminas-db, commit the files, push to your fork, and open the new PR.
    We will be providing tooling via laminas/laminas-migration soon to help automate the process.

@michalbundyra
Copy link
Member

This repository has been closed and moved to laminas/laminas-db; a new issue has been opened at laminas/laminas-db#72.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants