Skip to content

Conversation

@alexander-schranz
Copy link
Contributor

@alexander-schranz alexander-schranz commented Mar 2, 2022

The $driver variable can return Doctrine\DBAL\Logging\Driver which is not instance of AbstractMySQLDriver. So it need to be via the platform.

Sadly AbstractMySQLDriver is not available on prefer lowest so we need to check on the deprecated getName method on the platform.

fixes #1480

@alexander-schranz alexander-schranz force-pushed the bugfix/fix-driver-check-utf8mb4 branch 2 times, most recently from 3c23123 to 5340e68 Compare March 2, 2022 19:14
@alexander-schranz alexander-schranz changed the base branch from 2.5.x to 2.6.x March 2, 2022 19:16
@alexander-schranz alexander-schranz force-pushed the bugfix/fix-driver-check-utf8mb4 branch from 5340e68 to b78ad6b Compare March 2, 2022 19:17

$this->assertInstanceof(FakeConnection::class, $connection);
$this->assertSame('utf8', $connection->getParams()['charset']);
$this->assertSame('utf8mb4', $connection->getParams()['charset']);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

the FakeDriver is actually a MysqlPlatform that is why this test changees now.


if (! isset($params['charset'])) {
if ($driver instanceof AbstractMySQLDriver) {
if ($driver->getDatabasePlatform()->getName() === 'mysql') {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is sadly calling a deprecated method but I could not find another method which works on this range of supported doctrine/dbal versions.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe by performing several instanceof checks?


$this->assertInstanceof(FakeConnection::class, $connection);
$this->assertSame('utf8', $connection->getParams()['charset']);
$this->assertSame('utf8mb4', $connection->getParams()['charset']);
Copy link
Member

Choose a reason for hiding this comment

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

Are you sure this is OK? It does not look OK to change that default value like that (I know it's a bad default, but it might result in a lot of migrations for a lot of people).

Copy link
Contributor Author

@alexander-schranz alexander-schranz Mar 2, 2022

Choose a reason for hiding this comment

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

The fake driver ist actually a mysqlplatform that is why it is changing :

return static::$platform ?? new MySQLPlatform();

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Before the check was on the driver not on the platform.

Copy link
Member

@greg0ire greg0ire Mar 2, 2022

Choose a reason for hiding this comment

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

🤔 in fact, I think it might be fine, since people using MySQL ended up with utf8mb4 before #1456, but maybe we should rename the test to testDefaultCharsetForMySQL, and duplicate it with testDefaultCharsetForNonMySQL to test the other codepath with utf8

@alexander-schranz
Copy link
Contributor Author

@greg0ire any idea how we can get the testContainer working when we now access the getDatabasePlatform in the factory?


if (! isset($params['charset'])) {
if ($driver instanceof AbstractMySQLDriver) {
if ($driver->getDatabasePlatform() instanceof AbstractMySQLPlatform
Copy link
Member

Choose a reason for hiding this comment

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

The resulting Psalm error will have to be ignored through configuration I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not familiar with psalm do I need to ignore the whole file or is there another way?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

okay seems @psalm-suppress UndefinedClass does the job

@greg0ire
Copy link
Member

greg0ire commented Mar 2, 2022

@greg0ire any idea how we can get the testContainer working when we now access the getDatabasePlatform in the factory?

Let's improve the error message in the test first? "Failed asserting that false is true." is not very helpful

@alexander-schranz
Copy link
Contributor Author

Improved the message by using assertStringContainsString instead of some strpos() > 0

@alexander-schranz
Copy link
Contributor Author

alexander-schranz commented Mar 2, 2022

Is it maybe to early to access the platform because the platform is validated later here:

$platform = $this->getDatabasePlatform($connection);

Which is the method the testContainer test is testing. I'm a little bit stuck now.

@dmaicher
Copy link
Contributor

dmaicher commented Mar 2, 2022

The $driver variable can return Doctrine\DBAL\Logging\Driver which is not instance of AbstractMySQLDriver. So it need to be via the platform.

Ah nice catch. So this is caused by wiring the logging middlewares

@ostrolucky
Copy link
Member

should target 2.5.x branch

@greg0ire
Copy link
Member

greg0ire commented Mar 3, 2022

At that point I'm starting to think the way forward would be to make the middlewares opt-in, and throw if the charset is not specified when using them.
From my point of view, a lot of the code in ConnectionFactory should go as it seems like hacks to fix issues that should either be fixed in DBAL, or defaults that should come from the framework (typically from Symfony recipes). Recipes are IMO the correct place to set defaults, because you can change the defaults there without that being a BC-break.

So I think we should also deprecate not specifying the charset.

Maybe @ostrolucky has an opinion to share on this as well?

@ostrolucky
Copy link
Member

I share same opinion

@alexander-schranz alexander-schranz force-pushed the bugfix/fix-driver-check-utf8mb4 branch from bf7ecc5 to fbdd14a Compare March 3, 2022 10:08
@alexander-schranz alexander-schranz changed the base branch from 2.6.x to 2.5.x March 3, 2022 10:08
@ostrolucky ostrolucky force-pushed the bugfix/fix-driver-check-utf8mb4 branch from 2150f08 to efa6531 Compare March 5, 2022 10:18
@ostrolucky ostrolucky force-pushed the bugfix/fix-driver-check-utf8mb4 branch from efa6531 to ee6f1ee Compare March 5, 2022 10:23
@ostrolucky ostrolucky changed the title Fix driver check for utf8mb4 Fix default MySQL charset with doctrine/dbal > 2 Mar 5, 2022
@ostrolucky ostrolucky merged commit 1e0d1d7 into doctrine:2.5.x Mar 5, 2022
@ostrolucky ostrolucky added this to the 2.5.7 milestone Mar 5, 2022
@alexander-schranz alexander-schranz deleted the bugfix/fix-driver-check-utf8mb4 branch March 5, 2022 11:52
@alexander-schranz
Copy link
Contributor Author

Thank you all 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

False collation on current 2.6.x-dev 89b7ed6 version

4 participants