-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Do not implement driver-level interfaces by wrapper-level classes #4159
Conversation
692f299
to
6bcc08b
Compare
There was a problem hiding this 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.
6bcc08b
to
6d2b649
Compare
Yeah, this is no longer true, so I'll just remove it. There are some other bits outdated as of |
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
There are certain downsides of having the wrapper-level classes have to implement the driver-level interfaces:
Alongside the
executeQuery()
andexecuteUpdate()
methods, the wrapper connection has to implementquery()
andexec()
just because the interface declares them. Although, API-wise the latter two are just the subset of the former.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.
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.
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:
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:
2.11.x
(Deprecated usage of wrapper components as implementations of driver-level interfaces #4165).