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

Make classes final where applicable. #3590

Merged
merged 2 commits into from
Jan 12, 2020
Merged

Conversation

jwage
Copy link
Member

@jwage jwage commented Jun 4, 2019

Q A
Type improvement
BC Break yes
Fixed issues fixes #3585

Summary

@morozov
Copy link
Member

morozov commented Jun 4, 2019

FWIW, the current state is:

$ finalizer finalizer:check-final-classes lib
Following classes need to be made final:
+--------------------------------------+
| Doctrine\DBAL\Driver\Mysqli\Driver   |
| Doctrine\DBAL\Driver\PDOPgSql\Driver |
+--------------------------------------+

@jwage
Copy link
Member Author

jwage commented Jun 4, 2019

@morozov fixed. Should we add that finalizer check to ci so it fails if a new class is introduced that should be final but isn't?

@morozov
Copy link
Member

morozov commented Jun 4, 2019

This is the first time I'm using it but it looks more suitable for development, not for CI. Specifically, it also fails the build if it finds the classes mistakenly marked as final which is not what we need. I don't think we're introducing new classes that often that we need it enforced on CI.

@jwage
Copy link
Member Author

jwage commented Jun 5, 2019

I've got a few more tests to fix tomorrow.

lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php Outdated Show resolved Hide resolved
@morozov morozov force-pushed the develop branch 3 times, most recently from 10890d6 to 3836750 Compare June 27, 2019 06:29
@morozov morozov closed this Nov 3, 2019
@morozov morozov reopened this Nov 4, 2019
@morozov morozov changed the base branch from develop to master November 4, 2019 14:40
morozov added a commit to morozov/dbal that referenced this pull request Jan 3, 2020
…implementation detail

Testing the implementations of this method requires partial mocking of the implementing class which makes it impossible to make them `final` (doctrine#3590).

Additionally, this API breaks the encapsulation of the driver layer: instead of exposing the fact of whether

The rationale behind introducing this method (doctrine#487) is really questionable:

> This is also required for drivers that cannot return the database server version without an additional query (performance reasons).

1. There's no evidence that an underlying driver that exposes the server version via its API doesn't make a request of any kind to the server.
2. For an application that works with any realistic database, a query like `SELECT VERSION()` wouldn't be a performance bottleneck.
3. Even if it was, it's always possible to specify the platform version upfront.

In addition to the above, the only driver that doesn't support the platform version detection via the underlying driver API is `sqsql` which is barely supported.
morozov added a commit to morozov/dbal that referenced this pull request Jan 3, 2020
…implementation detail

Testing the implementations of this method requires partial mocking of the implementing class which makes it impossible to make them `final` (doctrine#3590).

Additionally, this API breaks the encapsulation of the driver layer: instead of exposing the fact of whether the connection will perform a query to detect the server version, the driver should just instantiate a platform corresponding to a connection.

The rationale behind introducing this method (doctrine#487) is really questionable:

> This is also required for drivers that cannot return the database server version without an additional query (performance reasons).

1. There's no evidence that an underlying driver that exposes the server version via its API doesn't make a request of any kind to the server.
2. For an application that works with any realistic database, a query like `SELECT VERSION()` wouldn't be a performance bottleneck.
3. Even if it was, it's always possible to specify the platform version upfront.

In addition to the above, the only driver that doesn't support the platform version detection via the underlying driver API is `sqsql` which is barely supported.
morozov added a commit to morozov/dbal that referenced this pull request Jan 3, 2020
…implementation detail

Testing the implementations of this method requires partial mocking of the implementing class which makes it impossible to make them `final` (doctrine#3590).

Additionally, this API breaks the encapsulation of the driver layer: instead of exposing the fact of whether the connection will perform a query to detect the server version, the driver should just instantiate a platform corresponding to a connection.

The rationale behind introducing this method (doctrine#487) is really questionable:

> This is also required for drivers that cannot return the database server version without an additional query (performance reasons).

1. There's no evidence that an underlying driver that exposes the server version via its API doesn't make a request of any kind to the server.
2. For an application that works with any realistic database, a query like `SELECT VERSION()` wouldn't be a performance bottleneck.
3. Even if it was, it's always possible to specify the platform version upfront. Otherwise, the current logic of falling back to a default platform may cause undefined behavior of the application (we don't test the compatibility of the lowest level of the DBAL platform with all supported server versions). Remember, “If it doesn’t work, it doesn’t matter how fast it doesn’t work.”

In addition to the above, the only driver that doesn't support the platform version detection via the underlying driver API is `sqsql` which is barely supported.
morozov added a commit to morozov/dbal that referenced this pull request Jan 3, 2020
…implementation detail

Testing the implementations of this method requires partial mocking of the implementing class which makes it impossible to make them `final` (doctrine#3590).

Additionally, this API breaks the encapsulation of the driver layer: instead of exposing the fact of whether the connection will perform a query to detect the server version, the driver should just instantiate a platform corresponding to a connection.

The rationale behind introducing this method (doctrine#487) is really questionable:

> This is also required for drivers that cannot return the database server version without an additional query (performance reasons).

1. There's no evidence that an underlying driver that exposes the server version via its API doesn't make a request of any kind to the server.
2. For an application that works with any realistic database, a query like `SELECT VERSION()` wouldn't be a performance bottleneck.
3. Even if it was, it's always possible to specify the platform version upfront. Otherwise, the current logic of falling back to a default platform may cause undefined behavior of the application (we don't test the compatibility of the lowest level of the DBAL platform with all supported server versions). Remember, “If it doesn’t work, it doesn’t matter how fast it doesn’t work.”

In addition to the above, the only driver that doesn't support the platform version detection via the underlying driver API is `sqsql` which is barely supported.
@morozov
Copy link
Member

morozov commented Jan 3, 2020

In addition to the already finalized classes, the following driver-level classes are meant to be final but currently cannot be declared as such:

The following classes have not been automatically finalized:

  1. MysqliConnection because of its getWrappedResourceHandle() which is not used anywhere and is not part of any API convention (see Expose the underlying statement in DBAL statements #3534 for a similar feature request).
  2. OCI8Connection because of its getExecuteMode() which is used by OCI8Statement::execute(). It indicates a violation of the ISP principle (the statement should be given an object that represents the execution mode, not the entire connection).
  3. OCI8Statement because of its static convertPositionalToNamedPlaceholders() which is public only because it's tested directly which indicates a violation of the SRP. It could be extracted to a utility class:
    * @todo extract into utility class in Doctrine\DBAL\Util namespace
  4. PDOConnection because it has child classes and the createStatement() method.
  5. PDOSqlsrv\Connection because of its createStatement().

morozov added a commit to morozov/dbal that referenced this pull request Jan 3, 2020
The existing relationship between the connection and its statement violate the ISP principle. Instead of having access only to the execution mode of the connection, statements have access to the entire connection API.

Having a method which is not defined in the driver connection interface makes it impossible to mark the method `final` (doctrine#3590).
morozov added a commit to morozov/dbal that referenced this pull request Jan 3, 2020
The existing relationship between the connection and its statement violate the ISP principle. Instead of having access only to the execution mode of the connection, statements have access to the entire connection API.

Having a method which is not defined in the driver connection interface makes it impossible to mark the method `final` (doctrine#3590).
morozov added a commit to morozov/dbal that referenced this pull request Jan 3, 2020
…implementation detail

Testing the implementations of this method requires partial mocking of the implementing class which makes it impossible to make them `final` (doctrine#3590).

Additionally, this API breaks the encapsulation of the driver layer: instead of exposing the fact of whether the connection will perform a query to detect the server version, the driver should just instantiate a platform corresponding to a connection.

The rationale behind introducing this method (doctrine#487) is really questionable:

> This is also required for drivers that cannot return the database server version without an additional query (performance reasons).

1. There's no evidence that an underlying driver that exposes the server version via its API doesn't make a request of any kind to the server.
2. For an application that works with any realistic database, a query like `SELECT VERSION()` wouldn't be a performance bottleneck.
3. Even if it was, it's always possible to specify the platform version upfront. Otherwise, the current logic of falling back to a default platform may cause undefined behavior of the application (we don't test the compatibility of the lowest level of the DBAL platform with all supported server versions). Remember, “If it doesn’t work, it doesn’t matter how fast it doesn’t work.”

In addition to the above, the only driver that doesn't support the platform version detection via the underlying driver API is `sqsql` which is barely supported.
morozov added a commit to morozov/dbal that referenced this pull request Jan 3, 2020
…implementation detail

Testing the implementations of this method requires partial mocking of the implementing class which makes it impossible to make them `final` (doctrine#3590).

Additionally, this API breaks the encapsulation of the driver layer: instead of exposing the fact of whether the connection will perform a query to detect the server version, the driver should just instantiate a platform corresponding to a connection.

The rationale behind introducing this method (doctrine#487) is really questionable:

> This is also required for drivers that cannot return the database server version without an additional query (performance reasons).

1. There's no evidence that an underlying driver that exposes the server version via its API doesn't make a request of any kind to the server.
2. For an application that works with any realistic database, a query like `SELECT VERSION()` wouldn't be a performance bottleneck.
3. Even if it was, it's always possible to specify the platform version upfront. Otherwise, the current logic of falling back to a default platform may cause undefined behavior of the application (we don't test the compatibility of the lowest level of the DBAL platform with all supported server versions). Remember, “If it doesn’t work, it doesn’t matter how fast it doesn’t work.”

In addition to the above, the only driver that doesn't support the platform version detection via the underlying driver API is `sqsql` which is barely supported.
@morozov morozov dismissed SenseException’s stale review January 9, 2020 06:12

The concern has been addressed

@morozov morozov mentioned this pull request Jan 10, 2020
@morozov morozov merged commit cc38688 into doctrine:master Jan 12, 2020
@morozov morozov self-assigned this Jan 12, 2020
@morozov
Copy link
Member

morozov commented Jan 12, 2020

Thank you @jwage 👍

morozov added a commit to morozov/dbal that referenced this pull request Jan 13, 2020
The existing relationship between the connection and its statement violate the ISP principle. Instead of having access only to the execution mode of the connection, statements have access to the entire connection API.

Having a method which is not defined in the driver connection interface makes it impossible to mark the method `final` (doctrine#3590).
morozov added a commit to morozov/dbal that referenced this pull request Jan 13, 2020
The existing relationship between the connection and its statement violate the ISP principle. Instead of having access only to the execution mode of the connection, statements have access to the entire connection API.

Having a method which is not defined in the driver connection interface makes it impossible to mark the method `final` (doctrine#3590).
morozov added a commit to morozov/dbal that referenced this pull request Jan 13, 2020
The existing relationship between the connection and its statement violate the ISP principle. Instead of having access only to the execution mode of the connection, statements have access to the entire connection API.

Having a method which is not defined in the driver connection interface makes it impossible to mark the method `final` (doctrine#3590).
morozov added a commit to morozov/dbal that referenced this pull request Jun 25, 2020
The existing relationship between the connection and its statement violate the ISP principle. Instead of having access only to the execution mode of the connection, statements have access to the entire connection API.

Having a method which is not defined in the driver connection interface makes it impossible to mark the method `final` (doctrine#3590).
morozov added a commit to morozov/dbal that referenced this pull request Jun 27, 2020
…n implementation detail

Testing the implementations of this method requires partial mocking of the implementing class which makes it impossible to make them `final` (doctrine#3590).

Additionally, this API breaks the encapsulation of the driver layer: instead of exposing the fact of whether the connection will perform a query to detect the server version, the driver should just instantiate a platform corresponding to a connection.

The rationale behind introducing this method (doctrine#487) is really questionable:

> This is also required for drivers that cannot return the database server version without an additional query (performance reasons).

1. There's no evidence that an underlying driver that exposes the server version via its API doesn't make a request of any kind to the server.
2. For an application that works with any realistic database, a query like `SELECT VERSION()` wouldn't be a performance bottleneck.
3. Even if it was, it's always possible to specify the platform version upfront. Otherwise, the current logic of falling back to a default platform may cause undefined behavior of the application (we don't test the compatibility of the lowest level of the DBAL platform with all supported server versions). Remember, “If it doesn’t work, it doesn’t matter how fast it doesn’t work.”
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 5, 2022
@morozov morozov removed this from the 4.0.0 milestone Aug 11, 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.

Mark eligible classes final
3 participants