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

Deprecate Abstraction\Result #4291

Merged

Conversation

morozov
Copy link
Member

@morozov morozov commented Sep 23, 2020

Q A
Type deprecation
BC Break no

Problem #​1: The wrapper Result methods are effectively documented as @throws Driver\Exception

In #4019 where the Result interfaces were first introduced, the idea was to have the Abstraction\Result extend Driver\Result since from the methods and parameters standpoint, the former is currently a superset of the latter.

The above didn't take into account exception handling. Specifically, the fact that the Driver\Exception is not a sub-type of Exception. It creates the following confusion:

interface Driver\Result
{
    /**
     * @throws Driver\Exception
     */
    function fetch();
}

interface Abstraction\Result extends Driver\Result
{
}

class Result implements Abstraction\Result
{
    /**
     * @throws Exception
     */
    function fetch() {
        try {
            $this->driverResult->fetch();
        } catch (Driver\Exception $e) {
             throw new Exception();
        }
    }
}

Despite the fact that Result::fetch() catches Driver\Exception from the driver result and only throws Exception, it inherits the @throws Driver\Exception annotation from Driver\Result. It means that the callers of Result::fetch() should be able to handle Exception despite the fact that it will never be thrown:

Screen Shot 2020-09-23 at 12 34 48 PM

Problem #​2: Adding fetch*() and iterate*() methods to the wrapper Result requires a breaking change

See #4293. Since the wrapper Result is exposed by the Statement as Abstraction\Result interface, making the new methods available to the consumers requires adding them to the interface which is a breaking change.

Solution

Unlike the driver level where the interfaces have multiple implementations and are meant for extensibility of the driver layer, the wrapper layer is essentially a set of convenience methods packed into a class which is not meant to have multiple implementations by definition.

The solution is to remove the interface and use the classes directly, similarly to the wrapper Connection and Statement classes.

I believe it's acceptable to introduce this deprecation in a patch release of 2.11.x:

  1. This release series is mostly about deprecations.
  2. The API being deprecated was introduced in 2.11.0, so it's unlikely that there is existing code that relies on this behavior.
  3. There's no other usage of the interface other than for forward compatibility with 3.0.
  4. If not done in 2.11.x, we'll have to release 2.12.0 or postpone the BC break until 4.0.

See the drafted removal PR for 3.0.x: #4294.

@SenseException
Copy link
Member

So the plan for 4.0 is that Abstraction\Result will be removed from Driver\Result? Or is this not planned yet?

@morozov
Copy link
Member Author

morozov commented Sep 23, 2020

If this gets merged, then the only change I want to do next is to remove the extends DriverResult from the Abstraction\Result. Both interfaces will still have the same methods defined in them. I want to do it in 3.0, not in 4.0.

UPGRADE.md Outdated
@@ -1,5 +1,9 @@
# Upgrade to 2.11

## Deprecated the usage of Abstraction\Result as Driver\Result

The usage of the `Abstraction\Result` as a sub-type of the `Driver\Result` interface is deprecated.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
The usage of the `Abstraction\Result` as a sub-type of the `Driver\Result` interface is deprecated.
The usage of the `Abstraction\Result` as a sub-type of the `Driver\Result` interface is deprecated. The interface `Driver\Result` will be removed from `Abstraction\Result` in 3.0.

Copy link
Member Author

Choose a reason for hiding this comment

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

The "will be removed" removed wording is a bit confusing: will we also remove the methods or not? Would it make sense to reword it as "the interface X will not extend Y in 3.0"?

Copy link
Member

Choose a reason for hiding this comment

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

Sounds better than my text, yes. 👍

@morozov morozov force-pushed the deprecate-result-interface-subtyping branch from 1904e15 to cf14c61 Compare September 23, 2020 23:51
@morozov morozov marked this pull request as draft September 24, 2020 01:10
@morozov morozov changed the title Deprecated usage of Abstraction\Result as Driver\Result Deprecated Abstraction\Result Sep 24, 2020
@morozov morozov force-pushed the deprecate-result-interface-subtyping branch from cf14c61 to e90de0c Compare September 24, 2020 02:25
@morozov morozov marked this pull request as ready for review September 24, 2020 02:32
@morozov morozov changed the title Deprecated Abstraction\Result Deprecate Abstraction\Result Sep 24, 2020
@morozov
Copy link
Member Author

morozov commented Sep 24, 2020

@SenseException your request for change is addressed. Although the scope of the PR has changed. Please review.

@morozov morozov added this to the 2.11.1 milestone Sep 25, 2020
@morozov morozov merged commit 2d09772 into doctrine:2.11.x Sep 25, 2020
@morozov morozov self-assigned this Sep 25, 2020
@morozov morozov deleted the deprecate-result-interface-subtyping branch September 25, 2020 20:51
rgrellmann added a commit to Rossmann-IT/dbal that referenced this pull request Mar 7, 2021
Release [2.11.1](https://github.com/doctrine/dbal/milestone/80)

2.11.1
======

- Total issues resolved: **2**
- Total pull requests resolved: **8**
- Total contributors: **6**

Documentation
-------------

 - [4299: Link to contributing guide](doctrine#4299) thanks to @greg0ire

SQLite,Test Suite,pdo_sqlite
----------------------------

 - [4297: Fix ExceptionTest::testConnectionExceptionSqLite() on macOS](doctrine#4297) thanks to @morozov

 - [4296: Increase indent in definition lists](doctrine#4296) thanks to @greg0ire

Deprecation,Prepared Statements
-------------------------------

 - [4291: Deprecate Abstraction\Result](doctrine#4291) thanks to @morozov

BC Fix,Quoting
--------------

 - [4287: Restore PDOStatement::quote() for backward compatibility](doctrine#4287) thanks to @morozov and @Shahelm

BC Fix,Query
------------

 - [4286: Fix BC break: QueryBuilder::andWhere() etc. should ignore empty strings](doctrine#4286) thanks to @BenMorel and @infabo

Bug,Documentation,Prepared Statements
-------------------------------------

 - [4285: Fix phpdoc on deprecated functions](doctrine#4285) thanks to @qdequippe

Bug,PDO,Prepared Statements
---------------------------

 - [4173: Fix Third parameter not allowed for PDO::FETCH&doctrine#95;COLUMN](doctrine#4173) thanks to @BenMorel

# gpg: Signature made Sun Sep 27 06:35:40 2020
# gpg:                using DSA key 1BEDEE0A820BC30D858F9F0C2C3A645671828132
# gpg: Can't check signature: No public key
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 29, 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

3 participants