Commit 3176f51d authored by Steve Müller's avatar Steve Müller

add support for evaluating the correct platform to use in a connection

parent 594e326b
......@@ -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;
......@@ -159,7 +159,7 @@ class Connection implements DriverConnection
*
* @var \Doctrine\DBAL\Platforms\AbstractPlatform
*/
protected $_platform;
private $platform;
/**
* The schema manager.
......@@ -222,17 +222,6 @@ class Connection implements DriverConnection
$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();
}
......@@ -333,7 +322,13 @@ class Connection implements DriverConnection
*/
public function getDatabasePlatform()
{
return $this->_platform;
if (null !== $this->platform) {
return $this->platform;
}
$this->detectDatabasePlatform();
return $this->platform;
}
/**
......@@ -365,6 +360,10 @@ class Connection implements DriverConnection
$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();
}
......@@ -377,6 +376,70 @@ class Connection implements DriverConnection
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.
*
......@@ -549,7 +612,7 @@ class Connection implements DriverConnection
{
$this->_transactionIsolationLevel = $level;
return $this->executeUpdate($this->_platform->getSetTransactionIsolationSQL($level));
return $this->executeUpdate($this->getDatabasePlatform()->getSetTransactionIsolationSQL($level));
}
/**
......@@ -559,6 +622,10 @@ class Connection implements DriverConnection
*/
public function getTransactionIsolation()
{
if (null === $this->_transactionIsolationLevel) {
$this->_transactionIsolationLevel = $this->getDatabasePlatform()->getDefaultTransactionIsolationLevel();
}
return $this->_transactionIsolationLevel;
}
......@@ -656,7 +723,7 @@ class Connection implements DriverConnection
*/
public function quoteIdentifier($str)
{
return $this->_platform->quoteIdentifier($str);
return $this->getDatabasePlatform()->quoteIdentifier($str);
}
/**
......@@ -1055,7 +1122,7 @@ class Connection implements DriverConnection
throw ConnectionException::mayNotAlterNestedTransactionWithSavepointsInTransaction();
}
if ( ! $this->_platform->supportsSavepoints()) {
if ( ! $this->getDatabasePlatform()->supportsSavepoints()) {
throw ConnectionException::savepointsNotSupported();
}
......@@ -1237,11 +1304,11 @@ class Connection implements DriverConnection
*/
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));
}
/**
......@@ -1255,12 +1322,12 @@ class Connection implements DriverConnection
*/
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));
}
}
......@@ -1275,11 +1342,11 @@ class Connection implements DriverConnection
*/
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));
}
/**
......@@ -1352,7 +1419,7 @@ class Connection implements DriverConnection
*/
public function convertToDatabaseValue($value, $type)
{
return Type::getType($type)->convertToDatabaseValue($value, $this->_platform);
return Type::getType($type)->convertToDatabaseValue($value, $this->getDatabasePlatform());
}
/**
......@@ -1366,7 +1433,7 @@ class Connection implements DriverConnection
*/
public function convertToPHPValue($value, $type)
{
return Type::getType($type)->convertToPHPValue($value, $this->_platform);
return Type::getType($type)->convertToPHPValue($value, $this->getDatabasePlatform());
}
/**
......@@ -1428,7 +1495,7 @@ class Connection implements DriverConnection
$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
......@@ -1524,7 +1591,7 @@ class Connection implements DriverConnection
}
try {
$this->query($this->_platform->getDummySelectSQL());
$this->query($this->platform->getDummySelectSQL());
return true;
} catch (DBALException $e) {
......
......@@ -44,6 +44,26 @@ class DBALException extends \Exception
"\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
*/
......
......@@ -24,13 +24,14 @@ use Doctrine\DBAL\Driver\ExceptionConverterDriver;
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}
......@@ -73,6 +74,14 @@ class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver
return $dsn;
}
/**
* {@inheritdoc}
*/
public function createDatabasePlatformForVersion($version)
{
return $this->getDatabasePlatform();
}
/**
* {@inheritdoc}
*/
......
......@@ -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
......@@ -50,6 +51,24 @@ class DB2Connection implements Connection
}
}
/**
* {@inheritdoc}
*/
public function getServerVersion()
{
$serverInfo = db2_server_info($this->_conn);
return $serverInfo->DBMS_VER;
}
/**
* {@inheritdoc}
*/
public function requiresQueryForServerVersion()
{
return false;
}
/**
* {@inheritdoc}
*/
......
......@@ -23,6 +23,7 @@ use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Platforms\DB2Platform;
use Doctrine\DBAL\Schema\DB2SchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
/**
* IBM DB2 Driver.
......@@ -30,7 +31,7 @@ use Doctrine\DBAL\Schema\DB2SchemaManager;
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class DB2Driver implements Driver
class DB2Driver implements Driver, VersionAwarePlatformDriver
{
/**
* {@inheritdoc}
......@@ -60,6 +61,14 @@ class DB2Driver implements Driver
return new DB2Connection($params, $username, $password, $driverOptions);
}
/**
* {@inheritdoc}
*/
public function createDatabasePlatformForVersion($version)
{
return $this->getDatabasePlatform();
}
/**
* {@inheritdoc}
*/
......
......@@ -24,12 +24,14 @@ use Doctrine\DBAL\Driver as DriverInterface;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\ExceptionConverterDriver;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\MySQL57Platform;
use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\DBAL\VersionAwarePlatformDriver;
/**
* @author Kim Hemsø Rasmussen <kimhemsoe@gmail.com>
*/
class Driver implements DriverInterface, ExceptionConverterDriver
class Driver implements DriverInterface, ExceptionConverterDriver, VersionAwarePlatformDriver
{
/**
* {@inheritdoc}
......@@ -59,6 +61,30 @@ class Driver implements DriverInterface, ExceptionConverterDriver
return new \Doctrine\DBAL\Schema\MySqlSchemaManager($conn);
}
/**
* {@inheritdoc}
*/
public function createDatabasePlatformForVersion($version)
{
if ( ! preg_match('/^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>\d+))?)?/', $version, $versionParts)) {
throw DBALException::invalidPlatformVersionSpecified(
$version,
'<major_version>.<minor_version>.<patch_version>'
);
}
$majorVersion = $versionParts['major'];
$minorVersion = isset($versionParts['minor']) ? $versionParts['minor'] : 0;
$patchVersion = isset($versionParts['patch']) ? $versionParts['patch'] : 0;
$version = $majorVersion . '.' . $minorVersion . '.' . $patchVersion;
if (version_compare($version, '5.7', '>=')) {
return new MySQL57Platform();
}
return $this->getDatabasePlatform();
}
/**
* {@inheritdoc}
*/
......
......@@ -21,12 +21,13 @@ namespace Doctrine\DBAL\Driver\Mysqli;
use Doctrine\DBAL\Driver\Connection as Connection;
use Doctrine\DBAL\Driver\PingableConnection;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
/**
* @author Kim Hemsø Rasmussen <kimhemsoe@gmail.com>
* @author Till Klampaeckel <till@php.net>
*/
class MysqliConnection implements Connection, PingableConnection
class MysqliConnection implements Connection, PingableConnection, ServerInfoAwareConnection
{
/**
* @var \mysqli
......@@ -78,6 +79,26 @@ class MysqliConnection implements Connection, PingableConnection
return $this->_conn;
}
/**
* {@inheritdoc}
*/
public function getServerVersion()
{
$majorVersion = floor($this->_conn->server_version / 10000);
$minorVersion = floor(($this->_conn->server_version - $majorVersion * 10000) / 100);
$patchVersion = floor(($this->_conn->server_version - $majorVersion * 10000 - $minorVersion * 100));
return $majorVersion . '.' . $minorVersion . '.' . $patchVersion;
}
/**
* {@inheritdoc}
*/
public function requiresQueryForServerVersion()
{
return false;
}
/**
* {@inheritdoc}
*/
......
......@@ -26,6 +26,7 @@ use Doctrine\DBAL\Driver\ExceptionConverterDriver;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Schema\OracleSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
/**
* A Doctrine DBAL driver for the Oracle OCI8 PHP extensions.
......@@ -33,7 +34,7 @@ use Doctrine\DBAL\Schema\OracleSchemaManager;
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
*/
class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver
class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver, VersionAwarePlatformDriver
{
/**
* {@inheritdoc}
......@@ -99,6 +100,14 @@ class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver
return $dsn;
}
/**
* {@inheritdoc}
*/
public function createDatabasePlatformForVersion($version)
{
return $this->getDatabasePlatform();
}
/**
* {@inheritdoc}
*/
......
......@@ -20,6 +20,7 @@
namespace Doctrine\DBAL\Driver\OCI8;
use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Platforms\OraclePlatform;
/**
......@@ -27,7 +28,7 @@ use Doctrine\DBAL\Platforms\OraclePlatform;
*
* @since 2.0
*/
class OCI8Connection implements Connection
class OCI8Connection implements Connection, ServerInfoAwareConnection
{
/**
* @var resource
......@@ -66,6 +67,26 @@ class OCI8Connection implements Connection
}
}
/**
* {@inheritdoc}
*/
public function getServerVersion()
{
if ( ! preg_match('/\s+(\d+\.\d+\.\d+\.\d+\.\d+)\s+/', oci_server_version($this->dbh), $version)) {
return null;
}
return $version[1];
}
/**
* {@inheritdoc}
*/
public function requiresQueryForServerVersion()
{
return false;
}
/**
* {@inheritdoc}
*/
......
......@@ -27,7 +27,7 @@ use PDO;
*
* @since 2.0
*/
class PDOConnection extends PDO implements Connection
class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection
{
/**
* @param string $dsn
......@@ -48,6 +48,14 @@ class PDOConnection extends PDO implements Connection
}
}
/**
* {@inheritdoc}
*/
public function getServerVersion()
{
return PDO::getAttribute(PDO::ATTR_SERVER_VERSION);
}
/**
* {@inheritdoc}
*/
......@@ -110,4 +118,12 @@ class PDOConnection extends PDO implements Connection
throw new PDOException($exception);
}
}
/**
* {@inheritdoc}
*/
public function requiresQueryForServerVersion()
{
return false;
}
}
......@@ -25,7 +25,9 @@ use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\ExceptionConverterDriver;
use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\MySQL57Platform;
use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\DBAL\VersionAwarePlatformDriver;
use Doctrine\DBAL\Schema\MySqlSchemaManager;
use PDOException;
......@@ -34,7 +36,7 @@ use PDOException;
*
* @since 2.0
*/
class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver
class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver, VersionAwarePlatformDriver
{
/**
* {@inheritdoc}
......@@ -84,6 +86,30 @@ class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver
return $dsn;
}
/**
* {@inheritdoc}
*/
public function createDatabasePlatformForVersion($version)
{
if ( ! preg_match('/^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>\d+))?)?/', $version, $versionParts)) {
throw DBALException::invalidPlatformVersionSpecified(
$version,
'<major_version>.<minor_version>.<patch_version>'
);
}
$majorVersion = $versionParts['major'];
$minorVersion = isset($versionParts['minor']) ? $versionParts['minor'] : 0;
$patchVersion = isset($versionParts['patch']) ? $versionParts['patch'] : 0;
$version = $majorVersion . '.' . $minorVersion . '.' . $patchVersion;
if (version_compare($version, '5.7', '>=')) {
return new MySQL57Platform();
}
return $this->getDatabasePlatform();
}
/**
* {@inheritdoc}
*/
......
......@@ -27,6 +27,7 @@ use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Schema\OracleSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
/**
* PDO Oracle driver.
......@@ -36,7 +37,7 @@ use Doctrine\DBAL\Schema\OracleSchemaManager;
* which leads us to the recommendation to use the "oci8" driver to connect
* to Oracle instead.
*/
class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver
class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver, VersionAwarePlatformDriver
{
/**
* {@inheritdoc}
......@@ -105,6 +106,14 @@ class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver
return $dsn;
}
/**
* {@inheritdoc}
*/
public function createDatabasePlatformForVersion($version)
{
return $this->getDatabasePlatform();
}
/**
* {@inheritdoc}
*/
......
......@@ -23,9 +23,11 @@ use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\PostgreSQL92Platform;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Schema\PostgreSqlSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
use PDOException;
use Doctrine\DBAL\Driver\ExceptionConverterDriver;
......@@ -34,7 +36,7 @@ use Doctrine\DBAL\Driver\ExceptionConverterDriver;
*
* @since 2.0
*/
class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver
class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver, VersionAwarePlatformDriver
{
/**
* {@inheritdoc}
......@@ -87,6 +89,30 @@ class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver
return $dsn;
}
/**
* {@inheritdoc}
*/
public function createDatabasePlatformForVersion($version)
{
if ( ! preg_match('/^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>\d+))?)?/', $version, $versionParts)) {
throw DBALException::invalidPlatformVersionSpecified(
$version,
'<major_version>.<minor_version>.<patch_version>'
);
}
$majorVersion = $versionParts['major'];
$minorVersion = isset($versionParts['minor']) ? $versionParts['minor'] : 0;
$patchVersion = isset($versionParts['patch']) ? $versionParts['patch'] : 0;
$version = $majorVersion . '.' . $minorVersion . '.' . $patchVersion;
if (version_compare($version, '9.2', '>=')) {
return new PostgreSQL92Platform();
}
return $this->getDatabasePlatform();
}
/**
* {@inheritdoc}
*/
......
......@@ -27,6 +27,7 @@ use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\SqlitePlatform;
use Doctrine\DBAL\Schema\SqliteSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
use PDOException;
/**
......@@ -34,7 +35,7 @@ use PDOException;
*
* @since 2.0
*/
class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver
class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver, VersionAwarePlatformDriver
{
/**
* @var array
......@@ -93,6 +94,14 @@ class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver
return $dsn;
}
/**
* {@inheritdoc}
*/
public function createDatabasePlatformForVersion($version)
{
return $this->getDatabasePlatform();
}
/**
* {@inheritdoc}
*/
......
......@@ -19,15 +19,20 @@
namespace Doctrine\DBAL\Driver\PDOSqlsrv;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Platforms\SQLServer2005Platform;
use Doctrine\DBAL\Platforms\SQLServer2008Platform;
use Doctrine\DBAL\Platforms\SQLServer2012Platform;
use Doctrine\DBAL\Platforms\SQLServerPlatform;
use Doctrine\DBAL\Schema\SQLServerSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
/**
* The PDO-based Sqlsrv driver.
*
* @since 2.0
*/
class Driver implements \Doctrine\DBAL\Driver
class Driver implements \Doctrine\DBAL\Driver, VersionAwarePlatformDriver
{
/**
* {@inheritdoc}
......@@ -72,6 +77,40 @@ class Driver implements \Doctrine\DBAL\Driver
return $dsn;
}
/**
* {@inheritdoc}
*/
public function createDatabasePlatformForVersion($version)
{
if ( ! preg_match(
'/^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>\d+)(?:\.(?P<build>\d+))?)?)?/',
$version,
$versionParts
)) {
throw DBALException::invalidPlatformVersionSpecified(
$version,
'<major_version>.<minor_version>.<patch_version>.<build_version>'
);
}
$majorVersion = $versionParts['major'];
$minorVersion = isset($versionParts['minor']) ? $versionParts['minor'] : 0;
$patchVersion = isset($versionParts['patch']) ? $versionParts['patch'] : 0;
$buildVersion = isset($versionParts['build']) ? $versionParts['build'] : 0;
$version = $majorVersion . '.' . $minorVersion . '.' . $patchVersion . $buildVersion;
switch(true) {
case version_compare($version, '11.00.2100', '>='):
return new SQLServer2012Platform();
case version_compare($version, '10.00.1600', '>='):
return new SQLServer2008Platform();
case version_compare($version, '9.00.1399', '>='):
return new SQLServer2005Platform();
default:
return new SQLServerPlatform();
}
}
/**
* {@inheritdoc}
*/
......
......@@ -24,8 +24,12 @@ use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\ExceptionConverterDriver;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\SQLAnywhere11Platform;
use Doctrine\DBAL\Platforms\SQLAnywhere12Platform;
use Doctrine\DBAL\Platforms\SQLAnywhere16Platform;
use Doctrine\DBAL\Platforms\SQLAnywherePlatform;
use Doctrine\DBAL\Schema\SQLAnywhereSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
/**
* A Doctrine DBAL driver for the SAP Sybase SQL Anywhere PHP extension.
......@@ -34,7 +38,7 @@ use Doctrine\DBAL\Schema\SQLAnywhereSchemaManager;
* @link www.doctrine-project.org
* @since 2.5
*/
class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver
class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver, VersionAwarePlatformDriver
{
/**
* {@inheritdoc}
......@@ -74,6 +78,40 @@ class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver
}
}
/**
* {@inheritdoc}
*/
public function createDatabasePlatformForVersion($version)
{
if ( ! preg_match(
'/^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>\d+)(?:\.(?P<build>\d+))?)?)?/',
$version,
$versionParts
)) {
throw DBALException::invalidPlatformVersionSpecified(
$version,
'<major_version>.<minor_version>.<patch_version>.<build_version>'
);
}
$majorVersion = $versionParts['major'];
$minorVersion = isset($versionParts['minor']) ? $versionParts['minor'] : 0;
$patchVersion = isset($versionParts['patch']) ? $versionParts['patch'] : 0;
$buildVersion = isset($versionParts['build']) ? $versionParts['build'] : 0;
$version = $majorVersion . '.' . $minorVersion . '.' . $patchVersion . '.' . $buildVersion;
switch(true) {
case version_compare($version, '16', '>='):
return new SQLAnywhere16Platform();
case version_compare($version, '12', '>='):
return new SQLAnywhere12Platform();
case version_compare($version, '11', '>='):
return new SQLAnywhere11Platform();
default:
return new SQLAnywherePlatform();
}
}
/**
* {@inheritdoc}
*
......
......@@ -20,6 +20,7 @@
namespace Doctrine\DBAL\Driver\SQLAnywhere;
use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
/**
* SAP Sybase SQL Anywhere implementation of the Connection interface.
......@@ -28,7 +29,7 @@ use Doctrine\DBAL\Driver\Connection;
* @link www.doctrine-project.org
* @since 2.5
*/
class SQLAnywhereConnection implements Connection
class SQLAnywhereConnection implements Connection, ServerInfoAwareConnection
{
/**
* @var resource The SQL Anywhere connection resource.
......@@ -127,6 +128,14 @@ class SQLAnywhereConnection implements Connection
return $stmt->rowCount();
}
/**
* {@inheritdoc}
*/
public function getServerVersion()
{
return $this->query("SELECT PROPERTY('ProductVersion')")->fetchColumn();
}
/**
* {@inheritdoc}
*/
......@@ -172,6 +181,14 @@ class SQLAnywhereConnection implements Connection
return "'" . sasql_escape_string($this->connection, $input) . "'";
}
/**
* {@inheritdoc}
*/
public function requiresQueryForServerVersion()
{
return true;
}
/**
* {@inheritdoc}
*
......
......@@ -20,13 +20,18 @@
namespace Doctrine\DBAL\Driver\SQLSrv;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Platforms\SQLServer2005Platform;
use Doctrine\DBAL\Platforms\SQLServer2008Platform;
use Doctrine\DBAL\Platforms\SQLServer2012Platform;
use Doctrine\DBAL\Platforms\SQLServerPlatform;
use Doctrine\DBAL\Schema\SQLServerSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
/**
* Driver for ext/sqlsrv.
*/
class Driver implements \Doctrine\DBAL\Driver
class Driver implements \Doctrine\DBAL\Driver, VersionAwarePlatformDriver
{
/**
* {@inheritdoc}
......@@ -36,15 +41,16 @@ class Driver implements \Doctrine\DBAL\Driver
if (!isset($params['host'])) {
throw new SQLSrvException("Missing 'host' in configuration for sqlsrv driver.");
}
if (!isset($params['dbname'])) {
throw new SQLSrvException("Missing 'dbname' in configuration for sqlsrv driver.");
}
$serverName = $params['host'];
if (isset($params['port'])) {
$serverName .= ', ' . $params['port'];
}
if (isset($params['dbname'])) {
$driverOptions['Database'] = $params['dbname'];
}
$driverOptions['UID'] = $username;
$driverOptions['PWD'] = $password;
......@@ -55,6 +61,40 @@ class Driver implements \Doctrine\DBAL\Driver
return new SQLSrvConnection($serverName, $driverOptions);
}
/**
* {@inheritdoc}
*/
public function createDatabasePlatformForVersion($version)
{
if ( ! preg_match(
'/^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>\d+)(?:\.(?P<build>\d+))?)?)?/',
$version,
$versionParts
)) {
throw DBALException::invalidPlatformVersionSpecified(
$version,
'<major_version>.<minor_version>.<patch_version>.<build_version>'
);
}
$majorVersion = $versionParts['major'];
$minorVersion = isset($versionParts['minor']) ? $versionParts['minor'] : 0;
$patchVersion = isset($versionParts['patch']) ? $versionParts['patch'] : 0;
$buildVersion = isset($versionParts['build']) ? $versionParts['build'] : 0;
$version = $majorVersion . '.' . $minorVersion . '.' . $patchVersion . $buildVersion;
switch(true) {
case version_compare($version, '11.00.2100', '>='):
return new SQLServer2012Platform();
case version_compare($version, '10.00.1600', '>='):
return new SQLServer2008Platform();
case version_compare($version, '9.00.1399', '>='):
return new SQLServer2005Platform();
default:
return new SQLServerPlatform();
}
}
/**
* {@inheritdoc}
*/
......
......@@ -20,6 +20,7 @@
namespace Doctrine\DBAL\Driver\SQLSrv;
use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
/**
* SQL Server implementation for the Connection interface.
......@@ -27,7 +28,7 @@ use Doctrine\DBAL\Driver\Connection;
* @since 2.3
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class SQLSrvConnection implements Connection
class SQLSrvConnection implements Connection, ServerInfoAwareConnection
{
/**
* @var resource
......@@ -58,6 +59,24 @@ class SQLSrvConnection implements Connection
$this->lastInsertId = new LastInsertId();
}
/**
* {@inheritdoc}
*/
public function getServerVersion()
{
$serverInfo = sqlsrv_server_info($this->conn);
return $serverInfo['SQLServerVersion'];
}
/**
* {@inheritdoc}
*/
public function requiresQueryForServerVersion()
{
return false;
}
/**
* {@inheritDoc}
*/
......
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Driver;
/**
* Contract for a connection that is able to provide information about the server it is connected to.
*
* @author Steve Müller <st.mueller@dzh-online.de>
* @link www.doctrine-project.org
* @since 2.5
*/
interface ServerInfoAwareConnection
{
/**
* Returns the version number of the database server connected to.
*
* @return string
*/
public function getServerVersion();
/**
* Checks whether a query is required to retrieve the database server version.
*
* @return boolean True if a query is required to retrieve the database server version, false otherwise.
*/
public function requiresQueryForServerVersion();
}
......@@ -65,19 +65,19 @@ class Connection extends \Doctrine\DBAL\Connection
if ($ret) {
$params = $this->getParams();
if (isset($params['portability'])) {
if ($this->_platform->getName() === "oracle") {
if ($this->getDatabasePlatform()->getName() === "oracle") {
$params['portability'] = $params['portability'] & self::PORTABILITY_ORACLE;
} elseif ($this->_platform->getName() === "postgresql") {
} elseif ($this->getDatabasePlatform()->getName() === "postgresql") {
$params['portability'] = $params['portability'] & self::PORTABILITY_POSTGRESQL;
} elseif ($this->_platform->getName() === "sqlite") {
} elseif ($this->getDatabasePlatform()->getName() === "sqlite") {
$params['portability'] = $params['portability'] & self::PORTABILITY_SQLITE;
} elseif ($this->_platform->getName() === "drizzle") {
} elseif ($this->getDatabasePlatform()->getName() === "drizzle") {
$params['portability'] = self::PORTABILITY_DRIZZLE;
} elseif ($this->_platform->getName() === 'sqlanywhere') {
} elseif ($this->getDatabasePlatform()->getName() === 'sqlanywhere') {
$params['portability'] = self::PORTABILITY_SQLANYWHERE;
} elseif ($this->_platform->getName() === 'db2') {
} elseif ($this->getDatabasePlatform()->getName() === 'db2') {
$params['portability'] = self::PORTABILITY_DB2;
} elseif ($this->_platform->getName() === 'mssql') {
} elseif ($this->getDatabasePlatform()->getName() === 'mssql') {
$params['portability'] = $params['portability'] & self::PORTABILITY_SQLSRV;
} else {
$params['portability'] = $params['portability'] & self::PORTABILITY_OTHERVENDORS;
......
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL;
/**
* Contract for a driver that is able to create platform instances by version.
*
* Doctrine uses different platform classes for different vendor versions to
* support the correct features and SQL syntax of each version.
* This interface should be implemented by drivers that are capable to do this
* distinction.
*
* @author Steve Müller <st.mueller@dzh-online.de>
* @link www.doctrine-project.org
* @since 2.5
*/
interface VersionAwarePlatformDriver
{
/**
* Factory method for creating the appropriate platform instance for the given version.
*
* @param string $version The platform/server version string to evaluate. This should be given in the notation
* the underlying database vendor uses.
*
* @return \Doctrine\DBAL\Platforms\AbstractPlatform
*
* @throws DBALException if the given version string could not be evaluated.
*/
public function createDatabasePlatformForVersion($version);
}
......@@ -8,6 +8,7 @@ use Doctrine\DBAL\Connection;
use Doctrine\Common\EventManager;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Events;
use Doctrine\Tests\Mocks\DriverMock;
use Doctrine\Tests\Mocks\DriverConnectionMock;
class ConnectionTest extends \Doctrine\Tests\DbalTestCase
......@@ -17,16 +18,17 @@ class ConnectionTest extends \Doctrine\Tests\DbalTestCase
*/
protected $_conn = null;
public function setUp()
{
$params = array(
protected $params = array(
'driver' => 'pdo_mysql',
'host' => 'localhost',
'user' => 'root',
'password' => 'password',
'port' => '1234'
);
$this->_conn = \Doctrine\DBAL\DriverManager::getConnection($params);
public function setUp()
{
$this->_conn = \Doctrine\DBAL\DriverManager::getConnection($this->params);
}
public function testIsConnected()
......@@ -119,8 +121,10 @@ class ConnectionTest extends \Doctrine\Tests\DbalTestCase
public function testEventManagerPassedToPlatform()
{
$this->assertInstanceOf('Doctrine\Common\EventManager', $this->_conn->getDatabasePlatform()->getEventManager());
$this->assertSame($this->_conn->getEventManager(), $this->_conn->getDatabasePlatform()->getEventManager());
$driverMock = new DriverMock();
$connection = new Connection($this->params, $driverMock);
$this->assertInstanceOf('Doctrine\Common\EventManager', $connection->getDatabasePlatform()->getEventManager());
$this->assertSame($connection->getEventManager(), $connection->getDatabasePlatform()->getEventManager());
}
/**
......
......@@ -69,11 +69,6 @@ class ConnectionMock extends \Doctrine\DBAL\Connection
$this->_fetchOneResult = $fetchOneResult;
}
public function setDatabasePlatform($platform)
{
$this->_platformMock = $platform;
}
public function setLastInsertId($id)
{
$this->_lastInsertId = $id;
......
......@@ -37,7 +37,7 @@ class TestUtil
if (isset($GLOBALS['db_type'], $GLOBALS['db_username'], $GLOBALS['db_password'],
$GLOBALS['db_host'], $GLOBALS['db_name'], $GLOBALS['db_port']) &&
isset($GLOBALS['tmpdb_type'], $GLOBALS['tmpdb_username'], $GLOBALS['tmpdb_password'],
$GLOBALS['tmpdb_host'], $GLOBALS['tmpdb_name'], $GLOBALS['tmpdb_port'])) {
$GLOBALS['tmpdb_host'], $GLOBALS['tmpdb_port'])) {
$realDbParams = array(
'driver' => $GLOBALS['db_type'],
'user' => $GLOBALS['db_username'],
......@@ -51,7 +51,7 @@ class TestUtil
'user' => $GLOBALS['tmpdb_username'],
'password' => $GLOBALS['tmpdb_password'],
'host' => $GLOBALS['tmpdb_host'],
'dbname' => $GLOBALS['tmpdb_name'],
'dbname' => null,
'port' => $GLOBALS['tmpdb_port']
);
......@@ -63,6 +63,10 @@ class TestUtil
$realDbParams['unix_socket'] = $GLOBALS['db_unix_socket'];
}
if (isset($GLOBALS['tmpdb_name'])) {
$tmpDbParams['dbname'] = $GLOBALS['tmpdb_name'];
}
if (isset($GLOBALS['tmpdb_server'])) {
$tmpDbParams['server'] = $GLOBALS['tmpdb_server'];
}
......@@ -73,12 +77,13 @@ class TestUtil
$realConn = \Doctrine\DBAL\DriverManager::getConnection($realDbParams);
$platform = $realConn->getDatabasePlatform();
// Connect to tmpdb in order to drop and create the real test db.
$tmpConn = \Doctrine\DBAL\DriverManager::getConnection($tmpDbParams);
$platform = $tmpConn->getDatabasePlatform();
if ($platform->supportsCreateDropDatabase()) {
$dbname = $realConn->getDatabase();
// Connect to tmpdb in order to drop and create the real test db.
$tmpConn = \Doctrine\DBAL\DriverManager::getConnection($tmpDbParams);
$realConn->close();
$tmpConn->getSchemaManager()->dropAndCreateDatabase($dbname);
......
......@@ -12,7 +12,6 @@
<var name="tmpdb_host" value="localhost" />
<var name="tmpdb_username" value="postgres" />
<var name="tmpdb_password" value="" />
<var name="tmpdb_name" value="doctrine_tests_tmp" />
<var name="tmpdb_port" value="5432"/>
</php>
<testsuites>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment