Skip to content

Loading…

DBAL-757: Add automatic platform version detection #1983

Closed
doctrinebot opened this Issue · 2 comments

2 participants

@doctrinebot

Jira issue originally created by user @doctrinebot:

This issue is created automatically through a Github pull request on behalf of deeky666:

Url: #487

Message:

As more and more vendor version specific platforms evolve, it is time to make an approach of autodetecting and using the correct platform on connection. This is done by introducing two new interfaces Doctrine\DBAL\VersionAwarePlatformDriver and Doctrine\DBAL\Driver\ServerInfoAwareConnection which are implemented by Doctrine's driver and driver connection classes. They are introduced to keep BC for custom driver / driver connection classes.
VersionAwarePlatformDriver::createDatabasePlatformForVersion($version) is responsible for evaluating a given vendor specific version number and instantiating the correct platform for it. The current implementations normalize the given version string and use version_compare() for evaluation.
ServerInfoAwareConnection::getServerVersion() is responsible for returning the normalized version string of the database server currently connected to. ServerInfoAwareConnection::requiresQueryForServerVersion() defines whether receiving that information requires an additional database query or not which is important for Doctrine\DBAL\Connection as described in the following.
Doctrine\DBAL\Connection now takes an additional (optional) connection parameter serverVersion which the user can pass to skip platform autodetection and define the desired platform version straight away. This is also required for drivers that cannot return the database server version without an additional query (performance reasons). Platform version detection is now done in the following order of precedence:

  1. Evaluate platform connection parameter and return an instance of that class if given.
  2. Evaluate if the underlying driver is capable of creating platform instances by version. If not, return the default platform instance that would be returned by the current implementation.
  3. Evaluate if serverVersion connection parameter is given and return the appropriate platform instance for that version.
  4. Evaluate if the underlying driver connection can return the server version and can return it without the need of an additional query -> return the appropriate platform instance for that version.
  5. Otherwise return the default platform instance that would be returned by the current implementation.

As a positive side effect while implementing the new interfaces, the driver classes were refactored by extracting abstract base driver classes for each vendor. This removes a lot of duplicated code in the driver classes that are related to the same database vendor. Please also note, that DrizzlePDOMySql now directly inherits from Doctrine\DBAL\Driver\PDOMySql\Driver to come around additional code duplication.

The only BC break introduced by this PR should be the visibility change of Doctrine\DBAL\Connection::$_platform from protected to private (as wished by @beberlei).
The only drawback of this implementation is that Doctrine\DBAL\Connection::getDatabasePlatform() now needs to do the real connect (if uninitialized) under some circumstances when it needs to autodetect the server version from the driver connection. Therefore I had to change the initialization of temporary connections in the functional test suite a little bit, so that calling Doctrine\DBAL\Connection::getDatabasePlatform() does not raise an error if the supplied temporary database does not exist. I think this is acceptable as it is not necessary to connect to a specific database anyways when only needing to drop and create the real test database.

As soon as the doctrine team agrees on this approach, I will add some more test and documentation for this. Until then this is a WIP PR.

@doctrinebot

Comment created by @doctrinebot:

A related Github Pull-Request [GH-487] was closed:
#487

@doctrinebot

Issue was closed with resolution "Fixed"

@deeky666 deeky666 was assigned by doctrinebot
@doctrinebot doctrinebot added this to the 2.5 milestone
@doctrinebot doctrinebot closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.