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

[Cache] Support decorated Dbal drivers in PdoAdapter #42011

Merged
merged 1 commit into from Jul 14, 2021
Merged

Conversation

Jeroeny
Copy link
Contributor

@Jeroeny Jeroeny commented Jul 7, 2021

Q A
Branch? 4.4
Bug fix? yes
New feature? no
Deprecations? no
Tickets Explanation in this PR
License MIT

Doctrine v3 supports middleware for Drivers. Upon creating the Connection, middleware->wrap(Driver): Driver is called, in which the middleware can wrap/decorate the Driver class. So that it can perform tracing for example.

When this happens, the Driver class inside the Connection is no longer one of Doctrine's well known Driver classes. The PdoAdapter uses this class to determine the database platform. Which breaks once the Driver is decorated and no longer one of the classes listed in the PdoAdapter.

Since Dbal exposes this middleware as a feature, I think it would be nice for the PdoAdapter to support this.

To solve this, the getDatabasePlatform can be used. This returns a Doctrine\DBAL\Platforms\AbstractPlatform which defines the abstract method getName. This returns a value very similar to the list in the PdoAdapter. The names don't match exactly, so therefor a small mapping is done to get right the name used in the adapter. As far as a I know, there'd be no other implications with this change.

Related: getsentry/sentry-symfony#530

@derrabus
Copy link
Member

derrabus commented Jul 7, 2021

Can you provide a test for this change, please? I think we should target 4.4 and file this as a bugfix.

@derrabus derrabus added this to the 4.4 milestone Jul 7, 2021
@Jeroeny Jeroeny changed the base branch from 5.4 to 4.4 July 7, 2021 12:25
@Jeroeny
Copy link
Contributor Author

Jeroeny commented Jul 7, 2021

Can you provide a test for this change, please? I think we should target 4.4 and file this as a bugfix.

Test added and rebased on 4.4.

$config->setMiddlewares([$middleware]);

$connection = DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile], $config);
} else {
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 for doctrine/dbal v2, which doesn't have the middleware. Not sure if the test should cover this or something like a SkippedTestSuiteError should be thrown.

Copy link
Member

Choose a reason for hiding this comment

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

I'd rather call $this->markTestSkipped as the feature does not exist properly for v2

Copy link
Member

Choose a reason for hiding this comment

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

I agree. If the test is irrelevant for DBAL 2, just skip it if we‘re not testing against DBAL 3.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree. If the test is irrelevant for DBAL 2, just skip it if we‘re not testing against DBAL 3.

I don't think that this fix is irrelevant for DBAL 2, because you could still decorate/wrap the driver manually anyway, see #42022 and the originating issue getsentry/sentry-symfony#530.

In general, I think we should change the switch to use $this->conn->getDatabasePlatform()->getName() as a reliable source of information.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

because you could still decorate/wrap the driver manually anyway

But not as official dbal v2 functionality right? You can pass a driverClass to the configuration, which is then constructed without arguments, making it less usable to function as decorator. Or it'd be via Reflection changing the private property _driver to public at runtime. Which is in my opinion already such an edge case, that Symfony shouldn't have to test against that.

Copy link
Contributor

@Jean85 Jean85 left a comment

Choose a reason for hiding this comment

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

Thanks for this PR! This should fix #42022

I don't understand why you didn't use $this->conn->getDatabasePlatform()->getName() as you suggested yourself though...

$config->setMiddlewares([$middleware]);

$connection = DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile], $config);
} else {
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree. If the test is irrelevant for DBAL 2, just skip it if we‘re not testing against DBAL 3.

I don't think that this fix is irrelevant for DBAL 2, because you could still decorate/wrap the driver manually anyway, see #42022 and the originating issue getsentry/sentry-symfony#530.

In general, I think we should change the switch to use $this->conn->getDatabasePlatform()->getName() as a reliable source of information.

@Jeroeny
Copy link
Contributor Author

Jeroeny commented Jul 8, 2021

I don't understand why you didn't use $this->conn->getDatabasePlatform()->getName() as you suggested yourself though...

I did though? See PdoTrait:458

Edit: I see there's a slight difference ($driver->getDatabasePlatform()->getName()), but I'm not sure how important that difference is?

@Jean85
Copy link
Contributor

Jean85 commented Jul 8, 2021

I don't understand why you didn't use $this->conn->getDatabasePlatform()->getName() as you suggested yourself though...

I did though? See PdoTrait:458

Edit: I see there's a slight difference ($driver->getDatabasePlatform()->getName()), but I'm not sure how important that difference is?

My suggestion is to change the whole switch to drive the choice using $driver->getDatabasePlatform()->getName(), because the instaceof will be broken by wrappers.

@Jeroeny
Copy link
Contributor Author

Jeroeny commented Jul 12, 2021

My suggestion is to change the whole switch to drive the choice using $driver->getDatabasePlatform()->getName(), because the instaceof will be broken by wrappers.

That's good feedback 👍 . Though I'd like to get some feedback on that from a Symfony maintainer as well, if possible. They're the ones to approve the PR after all.

@Jean85
Copy link
Contributor

Jean85 commented Jul 12, 2021

My suggestion is to change the whole switch to drive the choice using $driver->getDatabasePlatform()->getName(), because the instaceof will be broken by wrappers.

That's good feedback +1 . Though I'd like to get some feedback on that from a Symfony maintainer as well, if possible. They're the ones to approve the PR after all.

@nicolas-grekas already weighed in in #42022 (comment), but I'm not sure if he got the full implication of my suggestion.

@nicolas-grekas
Copy link
Member

change the whole switch

That works for me if the resulting code remains compatible with the range of dbal versions we support currently.

Copy link
Member

@derrabus derrabus left a comment

Choose a reason for hiding this comment

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

In patch-types.php, we maintain a list of files that should be ignored by that script. Please add your new DriverWrapper fixture there to make the tests pass.

@derrabus
Copy link
Member

LGTM, but I'd turn the @return annotations of the DriverWrapper fixture into proper return types. This way, it does not matter that much if we exclude it from the patch-types script.

@Tobion
Copy link
Member

Tobion commented Jul 14, 2021

Thank you @Jeroeny.

@Tobion Tobion merged commit e5c96c4 into symfony:4.4 Jul 14, 2021
This was referenced Jul 26, 2021
derrabus added a commit that referenced this pull request Oct 4, 2021
This PR was squashed before being merged into the 5.4 branch.

Discussion
----------

[Lock] Use platform to identify the PDO driver

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #43048
| License       | MIT

This should fix the issue in the same way we did for #42011. I'm not sure if I should add/change any test...

Commits
-------

687a7ed [Lock] Use platform to identify the PDO driver
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.

None yet

7 participants