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

Do not implement driver-level interfaces by wrapper-level classes #4159

Merged
merged 1 commit into from Jul 10, 2020

Conversation

morozov
Copy link
Member

@morozov morozov commented Jul 10, 2020

Q A
Type improvement
BC Break yes

There are certain downsides of having the wrapper-level classes have to implement the driver-level interfaces:

  1. Alongside the executeQuery() and executeUpdate() methods, the wrapper connection has to implement query() and exec() just because the interface declares them. Although, API-wise the latter two are just the subset of the former.

  2. Prior to PHP 7.4, the return type contravariance is not supported (https://3v4l.org/dNsho) which means that the wrapper-level classes cannot declare their return type specifically enough and have to declare the type just as prescribed by the lower-level interface.

  3. The fact that the wrappers implement the driver interfaces makes it harder to evolve the wrapper layer independently of the driver one. E.g. we cannot add a new (even optional) argument to any of the wrapper methods that are declared in the driver interface without a BC break.

  4. Unlike the driver-level classes that are allowed to throw driver exceptions and only them, the wrapper-level classes are not allowed to throw driver-level exceptions but are allowed to throw wrapper-level exceptions. This leads to the following issues:

    1. If a consumer uses a wrapper class as a driver interface implementation, it will expect a driver-level exception to be thrown but will get a wrapper-level one.
    2. If a consumer uses a wrapper class as such, it will expect a wrapper-level exception to be thrown but the static analysis will identify it as not handling the driver-level exceptions that are allowed by the driver-level interfaces but in fact never happen.

    Strictly speaking, at this point the wrapper layer violates the interface that it's forced to implement.

As for the upsides, I haven't seen a case where a consumer should be able to use a wrapper connection as a driver one. The fact that not a single test had to be changed confirms that.

TODO:

greg0ire
greg0ire previously approved these changes Jul 10, 2020
Copy link
Member

@greg0ire greg0ire left a comment

Choose a reason for hiding this comment

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

Hold on, I think https://github.com/doctrine/dbal/blob/3.0.x/docs/en/reference/architecture.rst has to be changed, for instance this sentence:

Even more, a Doctrine\DBAL\Connection is a Doctrine\DBAL\Driver\Connection and a Doctrine\DBAL\Statement is a Doctrine\DBAL\Driver\Statement.

@greg0ire greg0ire dismissed their stale review July 10, 2020 07:18

missing doc changes

@morozov morozov force-pushed the wrapper-apis-are-not-driver-apis branch from 6bcc08b to 6d2b649 Compare July 10, 2020 14:28
@morozov
Copy link
Member Author

morozov commented Jul 10, 2020

[…] https://github.com/doctrine/dbal/blob/3.0.x/docs/en/reference/architecture.rst has to be changed, for instance this sentence:

Even more, a Doctrine\DBAL\Connection is a Doctrine\DBAL\Driver\Connection and a Doctrine\DBAL\Statement is a Doctrine\DBAL\Driver\Statement.

Yeah, this is no longer true, so I'll just remove it. There are some other bits outdated as of 3.0.0-dev but I'll update them in a separate PR (#4164).

@morozov morozov requested a review from greg0ire July 10, 2020 14:32
@morozov morozov merged commit d415d04 into doctrine:3.0.x Jul 10, 2020
@morozov morozov deleted the wrapper-apis-are-not-driver-apis branch July 10, 2020 15:01
@morozov morozov self-assigned this Jul 10, 2020
This was referenced Sep 23, 2020
javiereguiluz added a commit to symfony/symfony-docs that referenced this pull request Nov 8, 2021
This PR was merged into the 5.3 branch.

Discussion
----------

Update type declaration for Doctrine DBAL Connection

In doctrine/dbal 3.0.0 Doctrine\DBAL\Driver\Connection has become an
internal interface and the wrapper-level Doctrine\DBAL\Connection should
be used.

Related:

https://github.com/doctrine/dbal/releases/tag/3.0.0
doctrine/dbal#4159

Commits
-------

3e4c7d7 Update type declaration for Doctrine DBAL Connection
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 31, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants