Skip to content

Fix a condition that would not allow diffing of foreign keys for Sqlite#4012

Closed
camilleterol wants to merge 6 commits intodoctrine:2.12.xfrom
camilleterol:2.10.x
Closed

Fix a condition that would not allow diffing of foreign keys for Sqlite#4012
camilleterol wants to merge 6 commits intodoctrine:2.12.xfrom
camilleterol:2.10.x

Conversation

@camilleterol
Copy link

Q A
Type bug
BC Break yes
Fixed issues #4010

Summary

After the changes introduced by #1204, the SchemaDiff would throw an error when trying to diff an Sqlite-backed schema with foreign keys modifications.

@camilleterol
Copy link
Author

For safe-keeping, here is the previous PR that was not referencing the correct branch.

@greg0ire
Copy link
Member

For safe-keeping, here is the previous PR that was not referencing the correct branch.

FYI you could have just clicked the Edit button and changed your target. But that would have been confusing because of how you named your branch (or rather, did not rename it). Make sure to rename it in your future contributions 🙏

@greg0ire
Copy link
Member

Copying my comment here:

This looks a lot like #3994 … maybe there are more occurrences of supportsForeignKeyConstraints that should be re-evaluated?

In any case, please add a test.

@camilleterol
Copy link
Author

Sorry about that. I forked the whole thing instead of creating a branch for the PR because I'm lazy.

@greg0ire
Copy link
Member

greg0ire commented May 17, 2020

It's not SVN anymore, creating branches is cheap, try it next time ;)

@camilleterol
Copy link
Author

For sure! I haven't used SVN since 2008 so creating a branch is what I usually do. But I was confused by GitHub's UI.

@camilleterol
Copy link
Author

In any case, please add a test.

Today being a bank holiday, I'll try and add the test case that we mentioned above for SQLite.

Approaching the repository, though, I'm wondering if it could be of use to add a CONTRIBUTE guide and a section on how to run the tests in the README to lower the barrier of entry.

@greg0ire
Copy link
Member

Approaching the repository, though, I'm wondering if it could be of use to add a CONTRIBUTE guide and a section on how to run the tests in the README to lower the barrier of entry.

I have had the same thought in the back of my mind, I know @morozov asks for a lot of functional tests, but when I contributed as a dev rather than as a maintainer in #3994, I had a hard time figuring out where this should go and how things are organized.

@morozov , your input on this would be priceless.

@camilleterol
Copy link
Author

I wrote a failing test, then made sure that my modification in commit dd6aaea would make the test pass. TDD 🎉

Comment on lines 17 to 24
$diff = $this->createSchemaDiff();
$platform = $this->createPlatform(true);

$sql = $diff->toSql($platform);

$expected = ['create_table'];

self::assertEquals($expected, $sql);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
$diff = $this->createSchemaDiff();
$platform = $this->createPlatform(true);
$sql = $diff->toSql($platform);
$expected = ['create_table'];
self::assertEquals($expected, $sql);
self::assertEquals(
['create_table'],
$this->createSchemaDiff()->toSql($this->createPlatform(true))
);


$expected = ['create_table'];

self::assertEquals($expected, $sql);
Copy link
Member

Choose a reason for hiding this comment

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

This looks exactly as the test above. Instead of having the reader read both tests to notice that, please use one test with a data provider. The data provider should have keys describing what true and false mean.

/**
* @return AbstractPlatform|MockObject
*/
private function createPlatform(bool $unsafe)
Copy link
Member

Choose a reason for hiding this comment

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

Can be merged with the aforementioned test I suppose

use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

class SqliteSchemaDiffTest extends TestCase
Copy link
Member

Choose a reason for hiding this comment

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

Are the tests specific to Sqlite or could they apply to other platforms?

Copy link
Author

Choose a reason for hiding this comment

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

I'm not sure. They are testing a specific use case that I encountered with SQLite, it might apply to any platform where supportsForeignKeyConstraints() is true and supportsCreateDropForeignKeyConstraints() is false.

Copy link
Member

Choose a reason for hiding this comment

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

Given the number of things mocked, I can barely understand what is being tested here. Would it make sense to have an integration test instead?

Copy link
Author

Choose a reason for hiding this comment

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

I guess so. I just copied the code that was in the SchemaDiffTest. Maybe a more generic integration test could cover both cases.

->will($this->throwException(
new DBALException('Sqlite platform does not support alter foreign key, the table must be fully recreated using getAlterTableSQL.')
));
}
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 lot of mocking… why not use the real object? A cross-platform functional test should make all this a bit shorter.

Copy link
Author

Choose a reason for hiding this comment

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

My thoughts exactly. All of your above remarks apply. I just copied the SchemaDiffTest and kept the same coding style.

@greg0ire greg0ire requested a review from morozov May 21, 2020 12:25
@camilleterol
Copy link
Author

I tweaked my test case a little. My time working on this for today is up. But any feedback is welcome :) I might be able to fork on this further if need be tomorrow or Sunday.

@camilleterol
Copy link
Author

I'll have some more time to work on this tomorrow, so what do you guys prefer? Should I strive for consistency and keep the test somewhat identical to the SchemaDiffTest. Or should I refactor this test and the SchemaDiffTest, use platform classes instead of a mock and not target SQLite specifically, but all platforms that have supportsForeignKeyConstraints() === true and supportsCreateDropForeignKeyConstraints() === false?

@greg0ire
Copy link
Member

I'll have some more time to work on this tomorrow, so what do you guys prefer? Should I strive for consistency and keep the test somewhat identical to the SchemaDiffTest.

I don't think you should, or maybe be consistent with another, better test if you can find one.

but all platforms that have supportsForeignKeyConstraints() === true and supportsCreateDropForeignKeyConstraints() === false

Sounds good. You should be able to do so by using $this->markTestSkipped() in a condition.

@camilleterol
Copy link
Author

Thanks for your insight on the matter. I'll do just that. Unfortunately I have not gotten the time yet to work on this further. I will try and take a look at it in the next few days if time allows.

@morozov morozov removed their request for review October 23, 2020 16:51
@morozov morozov changed the base branch from 2.10.x to 2.12.x November 29, 2020 21:34
@morozov morozov closed this Apr 21, 2021
@morozov morozov deleted the branch doctrine:2.12.x April 21, 2021 16:25
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 22, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants