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

Remove VersionAwarePlatformDriver and ServerInfoAwareConnection #4764

Merged
merged 3 commits into from
Aug 27, 2021

Conversation

morozov
Copy link
Member

@morozov morozov commented Aug 27, 2021

Q A
Type improvement
BC Break yes

See #4751.

A new ServerVersionProvider interface has been introduced to provide the server version to the driver if required to instantiate the platform.

From the wrapper connection laziness, three scenarios are possible:

  1. The driver requires a server version to instantiate a platform, and the server version isn't explicitly set in the connection parameters. In this case, a call to Driver::getDatabasePlatform() calls Connection::getServerVersion(), which in turn calls Driver::connect(), so the connection is established to instantiate the platform.
  2. The driver requires a server version to instantiate a platform, and the server version is explicitly set in the connection parameters. In this case, StaticServerVersionProvider::getServerVersion() provides the configured server version, and Driver::connect() doesn't get invoked.
  3. The driver does not require a server version to instantiate a platform. In this case, it doesn't call ServerVersionProvider::getServerVersion(), and Driver::connect() doesn't get invoked either.

The above behavior is the same as in DBAL 3.x but doesn't require runtime type checks and assertions.

@morozov morozov force-pushed the remove-server-info-aware-connection branch from 08ad421 to 288f5d6 Compare August 27, 2021 19:35
@@ -807,25 +826,6 @@ public function testThrowsExceptionWhenInValidPlatformSpecified(): void
new Connection($connectionParams, $driver);
}

public function testRethrowsOriginalExceptionOnDeterminingPlatformWhenConnectingToNonExistentDatabase(): void
Copy link
Member Author

@morozov morozov Aug 27, 2021

Choose a reason for hiding this comment

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

I wasted more than an hour trying to rework this test before I realized that the underlying implementation is pointless (originally implemented in #2671).

It only allows detection of the server version but doesn't allow anything else. If the configured database doesn't exist, the user will have to use the admin connection anyway (like the test suites do):

$connection = DriverManager::getConnection([
    'driver' => 'mysqli',
    'host'   => '127.0.0.1',
    'user'   => 'root',
    'dbname' => 'non_existing_database',
]);

echo get_class($connection->getDatabasePlatform()), PHP_EOL;
// Doctrine\DBAL\Platforms\MySQL80Platform

try {
    $connection->executeStatement('CREATE DATABASE non_existing_database');
} catch (Exception $e) {
    echo $e->getMessage(), PHP_EOL;
    // An exception occurred in the driver: Unknown database 'non_existing_database'
}

It works like above on all supported DBAL versions.

Let's leave this test removed for now. I'll gather more details to deprecate this feature and subsequently remove it. In the miraculous case, if it's still needed, we'll replace it with an integration test.

@morozov morozov marked this pull request as ready for review August 27, 2021 20:15
@morozov morozov requested a review from greg0ire August 27, 2021 20:16
@morozov morozov merged commit c178295 into doctrine:4.0.x Aug 27, 2021
@morozov morozov deleted the remove-server-info-aware-connection branch August 27, 2021 20:51
@morozov morozov mentioned this pull request Nov 16, 2021
3 tasks
@stof
Copy link
Member

stof commented Nov 23, 2021

should the main Connection class indeed implement a public method performing the version guessing (needing to connect) even when the static version is provided ? The current architecture means that Connection (the main public API of the package) implements ServerVersionProvider in a way that should not be used by users of the package (and the proof is that the Connection itself does not always uses its own implementation as the best implementation).

Maybe a ConnectionServerVersionProvider should be implemented (and not implementing the interface at all on the Connection class), or the Connection implementation should handle its own static settings directly, making it suitable for public usage.

@morozov
Copy link
Member Author

morozov commented Nov 23, 2021

Yeah, I thought of this as the next logical step. It could have been done right away but I honestly don't remember why I didn't do that.

My thinking was that the wrapper connection is quite a god object, and it should delegate certain responsibilities to specially crafted components rather than implement all the logic itself. I agree that the ability of the wrapper connection to detect the server version by connecting should not be exposed to the consumers.

Actually, one of the reasons to use the wrapper connection was the fact that it can connect lazily. Probably, the ConnectionServerVersionProvider should depend on the wrapper connection to retain this feature.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 24, 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