Skip to content

Commit

Permalink
add support for evaluating the correct platform to use in a connection
Browse files Browse the repository at this point in the history
  • Loading branch information
deeky666 committed Feb 12, 2014
1 parent 594e326 commit 3176f51
Show file tree
Hide file tree
Showing 26 changed files with 611 additions and 77 deletions.
123 changes: 95 additions & 28 deletions lib/Doctrine/DBAL/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@

namespace Doctrine\DBAL;

use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use PDO;
use Closure;
use Exception;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Driver\Connection as DriverConnection;
use Doctrine\Common\EventManager;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Cache\ResultCacheStatement;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\Cache\ArrayStatement;
Expand Down Expand Up @@ -159,7 +159,7 @@ class Connection implements DriverConnection
*
* @var \Doctrine\DBAL\Platforms\AbstractPlatform
*/
protected $_platform;
private $platform;

/**
* The schema manager.
Expand Down Expand Up @@ -222,17 +222,6 @@ public function __construct(array $params, Driver $driver, Configuration $config

$this->_expr = new Query\Expression\ExpressionBuilder($this);

if ( ! isset($params['platform'])) {
$this->_platform = $driver->getDatabasePlatform();
} elseif ($params['platform'] instanceof Platforms\AbstractPlatform) {
$this->_platform = $params['platform'];
} else {
throw DBALException::invalidPlatformSpecified();
}

$this->_platform->setEventManager($eventManager);

$this->_transactionIsolationLevel = $this->_platform->getDefaultTransactionIsolationLevel();
$this->autoCommit = $config->getAutoCommit();
}

Expand Down Expand Up @@ -333,7 +322,13 @@ public function getEventManager()
*/
public function getDatabasePlatform()
{
return $this->_platform;
if (null !== $this->platform) {
return $this->platform;
}

$this->detectDatabasePlatform();

return $this->platform;
}

/**
Expand Down Expand Up @@ -365,6 +360,10 @@ public function connect()
$this->_conn = $this->_driver->connect($this->_params, $user, $password, $driverOptions);
$this->_isConnected = true;

if (null === $this->platform) {
$this->detectDatabasePlatform();
}

if (false === $this->autoCommit) {
$this->beginTransaction();
}
Expand All @@ -377,6 +376,70 @@ public function connect()
return true;
}

/**
* Detects and sets the database platform.
*
* Evaluates custom platform class and version in order to set the correct platform.
*
* @throws DBALException if an invalid platform was specified for this connection.
*/
private function detectDatabasePlatform()
{
if ( ! isset($this->_params['platform'])) {
$version = $this->getDatabasePlatformVersion();

if (null !== $version) {
$this->platform = $this->_driver->createDatabasePlatformForVersion($version);
} else {
$this->platform = $this->_driver->getDatabasePlatform();
}
} elseif ($this->_params['platform'] instanceof Platforms\AbstractPlatform) {
$this->platform = $this->_params['platform'];
} else {
throw DBALException::invalidPlatformSpecified();
}

$this->platform->setEventManager($this->_eventManager);
}

/**
* Returns the version of the related platform if applicable.
*
* Returns null if either the driver is not capable to create version
* specific platform instances, no explicit server version was specified
* or the underlying driver connection cannot determine the platform
* version without having to query it (performance reasons).
*
* @return string|null
*/
private function getDatabasePlatformVersion()
{
// Driver does not support version specific platforms.
if ( ! $this->_driver instanceof VersionAwarePlatformDriver) {
return null;
}

// Explicit platform version requested (supersedes auto-detection).
if (isset($this->_params['serverVersion'])) {
return $this->_params['serverVersion'];
}

// If not connected, we need to connect now to determine the platform version.
if (null === $this->_conn) {
$this->connect();
}

// Automatic platform version detection.
if ($this->_conn instanceof ServerInfoAwareConnection &&
! $this->_conn->requiresQueryForServerVersion()
) {
return $this->_conn->getServerVersion();
}

// Unable to detect platform version.
return null;
}

/**
* Returns the current auto-commit mode for this connection.
*
Expand Down Expand Up @@ -549,7 +612,7 @@ public function setTransactionIsolation($level)
{
$this->_transactionIsolationLevel = $level;

return $this->executeUpdate($this->_platform->getSetTransactionIsolationSQL($level));
return $this->executeUpdate($this->getDatabasePlatform()->getSetTransactionIsolationSQL($level));
}

/**
Expand All @@ -559,6 +622,10 @@ public function setTransactionIsolation($level)
*/
public function getTransactionIsolation()
{
if (null === $this->_transactionIsolationLevel) {
$this->_transactionIsolationLevel = $this->getDatabasePlatform()->getDefaultTransactionIsolationLevel();
}

return $this->_transactionIsolationLevel;
}

Expand Down Expand Up @@ -656,7 +723,7 @@ private function extractTypeValues(array $data, array $types)
*/
public function quoteIdentifier($str)
{
return $this->_platform->quoteIdentifier($str);
return $this->getDatabasePlatform()->quoteIdentifier($str);
}

/**
Expand Down Expand Up @@ -1055,7 +1122,7 @@ public function setNestTransactionsWithSavepoints($nestTransactionsWithSavepoint
throw ConnectionException::mayNotAlterNestedTransactionWithSavepointsInTransaction();
}

if ( ! $this->_platform->supportsSavepoints()) {
if ( ! $this->getDatabasePlatform()->supportsSavepoints()) {
throw ConnectionException::savepointsNotSupported();
}

Expand Down Expand Up @@ -1237,11 +1304,11 @@ public function rollBack()
*/
public function createSavepoint($savepoint)
{
if ( ! $this->_platform->supportsSavepoints()) {
if ( ! $this->getDatabasePlatform()->supportsSavepoints()) {
throw ConnectionException::savepointsNotSupported();
}

$this->_conn->exec($this->_platform->createSavePoint($savepoint));
$this->_conn->exec($this->platform->createSavePoint($savepoint));
}

/**
Expand All @@ -1255,12 +1322,12 @@ public function createSavepoint($savepoint)
*/
public function releaseSavepoint($savepoint)
{
if ( ! $this->_platform->supportsSavepoints()) {
if ( ! $this->getDatabasePlatform()->supportsSavepoints()) {
throw ConnectionException::savepointsNotSupported();
}

if ($this->_platform->supportsReleaseSavepoints()) {
$this->_conn->exec($this->_platform->releaseSavePoint($savepoint));
if ($this->platform->supportsReleaseSavepoints()) {
$this->_conn->exec($this->platform->releaseSavePoint($savepoint));
}
}

Expand All @@ -1275,11 +1342,11 @@ public function releaseSavepoint($savepoint)
*/
public function rollbackSavepoint($savepoint)
{
if ( ! $this->_platform->supportsSavepoints()) {
if ( ! $this->getDatabasePlatform()->supportsSavepoints()) {
throw ConnectionException::savepointsNotSupported();
}

$this->_conn->exec($this->_platform->rollbackSavePoint($savepoint));
$this->_conn->exec($this->platform->rollbackSavePoint($savepoint));
}

/**
Expand Down Expand Up @@ -1352,7 +1419,7 @@ public function isRollbackOnly()
*/
public function convertToDatabaseValue($value, $type)
{
return Type::getType($type)->convertToDatabaseValue($value, $this->_platform);
return Type::getType($type)->convertToDatabaseValue($value, $this->getDatabasePlatform());
}

/**
Expand All @@ -1366,7 +1433,7 @@ public function convertToDatabaseValue($value, $type)
*/
public function convertToPHPValue($value, $type)
{
return Type::getType($type)->convertToPHPValue($value, $this->_platform);
return Type::getType($type)->convertToPHPValue($value, $this->getDatabasePlatform());
}

/**
Expand Down Expand Up @@ -1428,7 +1495,7 @@ private function getBindingInfo($value, $type)
$type = Type::getType($type);
}
if ($type instanceof Type) {
$value = $type->convertToDatabaseValue($value, $this->_platform);
$value = $type->convertToDatabaseValue($value, $this->getDatabasePlatform());
$bindingType = $type->getBindingType();
} else {
$bindingType = $type; // PDO::PARAM_* constants
Expand Down Expand Up @@ -1524,7 +1591,7 @@ public function ping()
}

try {
$this->query($this->_platform->getDummySelectSQL());
$this->query($this->platform->getDummySelectSQL());

return true;
} catch (DBALException $e) {
Expand Down
20 changes: 20 additions & 0 deletions lib/Doctrine/DBAL/DBALException.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,26 @@ public static function invalidPlatformSpecified()
"\Doctrine\DBAL\Platforms\AbstractPlatform.");
}

/**
* Returns a new instance for an invalid specified platform version.
*
* @param string $version The invalid platform version given.
* @param string $expectedFormat The expected platform version format.
*
* @return DBALException
*/
public static function invalidPlatformVersionSpecified($version, $expectedFormat)
{
return new self(
sprintf(
'Invalid platform version "%s" specified. ' .
'The platform version has to be specified in the format: "%s".',
$version,
$expectedFormat
)
);
}

/**
* @return \Doctrine\DBAL\DBALException
*/
Expand Down
11 changes: 10 additions & 1 deletion lib/Doctrine/DBAL/Driver/DrizzlePDOMySql/Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\DrizzlePlatform;
use Doctrine\DBAL\Schema\DrizzleSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;

/**
* Drizzle driver using PDO MySql.
*
* @author Kim Hemsø Rasmussen <kimhemsoe@gmail.com>
*/
class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver
class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver, VersionAwarePlatformDriver
{
/**
* {@inheritdoc}
Expand Down Expand Up @@ -73,6 +74,14 @@ private function _constructPdoDsn(array $params)
return $dsn;
}

/**
* {@inheritdoc}
*/
public function createDatabasePlatformForVersion($version)
{
return $this->getDatabasePlatform();
}

/**
* {@inheritdoc}
*/
Expand Down
21 changes: 20 additions & 1 deletion lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
namespace Doctrine\DBAL\Driver\IBMDB2;

use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;

class DB2Connection implements Connection
class DB2Connection implements Connection, ServerInfoAwareConnection
{
/**
* @var resource
Expand Down Expand Up @@ -50,6 +51,24 @@ public function __construct(array $params, $username, $password, $driverOptions
}
}

/**
* {@inheritdoc}
*/
public function getServerVersion()
{
$serverInfo = db2_server_info($this->_conn);

return $serverInfo->DBMS_VER;
}

/**
* {@inheritdoc}
*/
public function requiresQueryForServerVersion()
{
return false;
}

/**
* {@inheritdoc}
*/
Expand Down
11 changes: 10 additions & 1 deletion lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Platforms\DB2Platform;
use Doctrine\DBAL\Schema\DB2SchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;

/**
* IBM DB2 Driver.
*
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class DB2Driver implements Driver
class DB2Driver implements Driver, VersionAwarePlatformDriver
{
/**
* {@inheritdoc}
Expand Down Expand Up @@ -60,6 +61,14 @@ public function connect(array $params, $username = null, $password = null, array
return new DB2Connection($params, $username, $password, $driverOptions);
}

/**
* {@inheritdoc}
*/
public function createDatabasePlatformForVersion($version)
{
return $this->getDatabasePlatform();
}

/**
* {@inheritdoc}
*/
Expand Down
Loading

0 comments on commit 3176f51

Please sign in to comment.