diff --git a/UPGRADE.md b/UPGRADE.md index 679d0130fd8..d7011d21c85 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,5 +1,30 @@ # Upgrade to 2.5 +## BC BREAK: Doctrine\DBAL\Connection + +The visibility of the property ``$_platform`` in ``Doctrine\DBAL\Connection`` +was changed from protected to private. If you have subclassed ``Doctrine\DBAL\Connection`` +in your application and accessed ``$_platform`` directly, you have to change the code +portions to use ``getDatabasePlatform()`` instead to retrieve the underlying database +platform. +The reason for this change is the new automatic platform version detection feature, +which lazily evaluates the appropriate platform class to use for the underlying database +server version at runtime. +Please also note, that calling ``getDatabasePlatform()`` now needs to establish a connection +in order to evaluate the appropriate platform class if ``Doctrine\DBAL\Connection`` is not +already connected. Under the following circumstances, it is not possible anymore to retrieve +the platform instance from the connection object without having to do a real connect: + +1. ``Doctrine\DBAL\Connection`` was instantiated without the ``platform`` connection parameter. +2. ``Doctrine\DBAL\Connection`` was instantiated without the ``serverVersion`` connection parameter. +3. The underlying driver is "version aware" and can provide different platform instances + for different versions. +4. The underlying driver connection is "version aware" and can provide the database server + version without having to query for it. + +If one of the above conditions is NOT met, there is no need for ``Doctrine\DBAL\Connection`` +to do a connect when calling ``getDatabasePlatform()``. + ## datetime Type uses date_create() as fallback Before 2.5 the DateTime type always required a specific format, defined in diff --git a/docs/en/reference/configuration.rst b/docs/en/reference/configuration.rst index 139c35fedba..f8d95078135 100644 --- a/docs/en/reference/configuration.rst +++ b/docs/en/reference/configuration.rst @@ -233,6 +233,44 @@ platform version here: - `SQL Anywhere 12.0.1 `_ - `SAP Sybase SQL Anywhere 16.0 `_ +Automatic platform version detection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Doctrine ships with different database platform implementations for some vendors +to support version specific features, dialect and behaviour. +As of Doctrine DBAL 2.5 the appropriate platform implementation for the underlying +database server version can be detected at runtime automatically for nearly all drivers. +Before 2.5 you had to configure Doctrine to use a certain platform implementation +explicitly with the ``platform`` connection parameter (see section below). +Otherwise Doctrine always used a default platform implementation. For example if +your application was backed by a SQL Server 2012 database, Doctrine would still use +the SQL Server 2008 platform implementation as it is the default, unless you told +Doctrine explicitly to use the SQL Server 2012 implementation. + +The following drivers support automatic database platform detection out of the box +without any extra configuration required: + +- ``pdo_mysql`` +- ``mysqli`` +- ``pdo_pgsql`` +- ``pdo_sqlsrv`` +- ``sqlsrv`` + +Some drivers cannot provide the version of the underlying database server without +having to query for it explicitly. For performance reasons (to save one extra query +on every connect), Doctrine does not enable automatic database platform version +detection for the following drivers: + +- ``sqlanywhere`` + +If you still want to tell Doctrine which database server version you are using in +order to choose the appropriate platform implementation, you can pass the +``serverVersion`` option with a vendor specific version string that matches the +database server version you are using. +You can also pass this option if you want to disable automatic database platform +detection for a driver that natively supports it and choose the platform version +implementation explicitly. + Custom Platform ~~~~~~~~~~~~~~~ diff --git a/lib/Doctrine/DBAL/Connection.php b/lib/Doctrine/DBAL/Connection.php index 21379e6b041..3c54c18c3d6 100644 --- a/lib/Doctrine/DBAL/Connection.php +++ b/lib/Doctrine/DBAL/Connection.php @@ -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 @@ 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(); } @@ -333,7 +322,11 @@ public function getEventManager() */ public function getDatabasePlatform() { - return $this->_platform; + if (null == $this->platform) { + $this->detectDatabasePlatform(); + } + + return $this->platform; } /** @@ -365,6 +358,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(); } @@ -377,6 +374,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. * @@ -549,7 +610,7 @@ public function setTransactionIsolation($level) { $this->_transactionIsolationLevel = $level; - return $this->executeUpdate($this->_platform->getSetTransactionIsolationSQL($level)); + return $this->executeUpdate($this->getDatabasePlatform()->getSetTransactionIsolationSQL($level)); } /** @@ -559,6 +620,10 @@ public function setTransactionIsolation($level) */ public function getTransactionIsolation() { + if (null === $this->_transactionIsolationLevel) { + $this->_transactionIsolationLevel = $this->getDatabasePlatform()->getDefaultTransactionIsolationLevel(); + } + return $this->_transactionIsolationLevel; } @@ -656,7 +721,7 @@ private function extractTypeValues(array $data, array $types) */ public function quoteIdentifier($str) { - return $this->_platform->quoteIdentifier($str); + return $this->getDatabasePlatform()->quoteIdentifier($str); } /** @@ -1055,7 +1120,7 @@ public function setNestTransactionsWithSavepoints($nestTransactionsWithSavepoint throw ConnectionException::mayNotAlterNestedTransactionWithSavepointsInTransaction(); } - if ( ! $this->_platform->supportsSavepoints()) { + if ( ! $this->getDatabasePlatform()->supportsSavepoints()) { throw ConnectionException::savepointsNotSupported(); } @@ -1237,11 +1302,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)); } /** @@ -1255,12 +1320,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)); } } @@ -1275,11 +1340,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)); } /** @@ -1352,7 +1417,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()); } /** @@ -1366,7 +1431,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()); } /** @@ -1428,7 +1493,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 @@ -1524,7 +1589,7 @@ public function ping() } try { - $this->query($this->_platform->getDummySelectSQL()); + $this->query($this->platform->getDummySelectSQL()); return true; } catch (DBALException $e) { diff --git a/lib/Doctrine/DBAL/DBALException.php b/lib/Doctrine/DBAL/DBALException.php index ca99aaab4bd..d85dec8d76b 100644 --- a/lib/Doctrine/DBAL/DBALException.php +++ b/lib/Doctrine/DBAL/DBALException.php @@ -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 */ diff --git a/lib/Doctrine/DBAL/Driver/AbstractDB2Driver.php b/lib/Doctrine/DBAL/Driver/AbstractDB2Driver.php new file mode 100644 index 00000000000..baa081690c0 --- /dev/null +++ b/lib/Doctrine/DBAL/Driver/AbstractDB2Driver.php @@ -0,0 +1,60 @@ +. + */ + +namespace Doctrine\DBAL\Driver; + +use Doctrine\DBAL\Driver; +use Doctrine\DBAL\Platforms\DB2Platform; +use Doctrine\DBAL\Schema\DB2SchemaManager; + +/** + * Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for IBM DB2 based drivers. + * + * @author Steve Müller + * @link www.doctrine-project.org + * @since 2.5 + */ +abstract class AbstractDB2Driver implements Driver +{ + /** + * {@inheritdoc} + */ + public function getDatabase(\Doctrine\DBAL\Connection $conn) + { + $params = $conn->getParams(); + + return $params['dbname']; + } + + /** + * {@inheritdoc} + */ + public function getDatabasePlatform() + { + return new DB2Platform(); + } + + /** + * {@inheritdoc} + */ + public function getSchemaManager(\Doctrine\DBAL\Connection $conn) + { + return new DB2SchemaManager($conn); + } +} diff --git a/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php b/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php new file mode 100644 index 00000000000..f12eebb756e --- /dev/null +++ b/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php @@ -0,0 +1,170 @@ +. + */ + +namespace Doctrine\DBAL\Driver; + +use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Driver; +use Doctrine\DBAL\Exception; +use Doctrine\DBAL\Platforms\MySQL57Platform; +use Doctrine\DBAL\Platforms\MySqlPlatform; +use Doctrine\DBAL\Schema\MySqlSchemaManager; +use Doctrine\DBAL\VersionAwarePlatformDriver; + +/** + * Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for MySQL based drivers. + * + * @author Steve Müller + * @link www.doctrine-project.org + * @since 2.5 + */ +abstract class AbstractMySQLDriver implements Driver, ExceptionConverterDriver, VersionAwarePlatformDriver +{ + /** + * {@inheritdoc} + * + * @link http://dev.mysql.com/doc/refman/5.7/en/error-messages-client.html + * @link http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html + */ + public function convertException($message, DriverException $exception) + { + switch ($exception->getErrorCode()) { + case '1050': + return new Exception\TableExistsException($message, $exception); + + case '1051': + case '1146': + return new Exception\TableNotFoundException($message, $exception); + + case '1216': + case '1217': + case '1451': + case '1452': + return new Exception\ForeignKeyConstraintViolationException($message, $exception); + + case '1062': + case '1557': + case '1569': + case '1586': + return new Exception\UniqueConstraintViolationException($message, $exception); + + case '1054': + case '1166': + case '1611': + return new Exception\InvalidFieldNameException($message, $exception); + + case '1052': + case '1060': + case '1110': + return new Exception\NonUniqueFieldNameException($message, $exception); + + case '1064': + case '1149': + case '1287': + case '1341': + case '1342': + case '1343': + case '1344': + case '1382': + case '1479': + case '1541': + case '1554': + case '1626': + return new Exception\SyntaxErrorException($message, $exception); + + case '1044': + case '1045': + case '1046': + case '1049': + case '1095': + case '1142': + case '1143': + case '1227': + case '1370': + case '2002': + case '2005': + return new Exception\ConnectionException($message, $exception); + + case '1048': + case '1121': + case '1138': + case '1171': + case '1252': + case '1263': + case '1566': + return new Exception\NotNullConstraintViolationException($message, $exception); + } + + return new Exception\DriverException($message, $exception); + } + + /** + * {@inheritdoc} + */ + public function createDatabasePlatformForVersion($version) + { + if ( ! preg_match('/^(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+))?)?/', $version, $versionParts)) { + throw DBALException::invalidPlatformVersionSpecified( + $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} + */ + public function getDatabase(\Doctrine\DBAL\Connection $conn) + { + $params = $conn->getParams(); + + if (isset($params['dbname'])) { + return $params['dbname']; + } + + return $conn->query('SELECT DATABASE()')->fetchColumn(); + } + + /** + * {@inheritdoc} + */ + public function getDatabasePlatform() + { + return new MySqlPlatform(); + } + + /** + * {@inheritdoc} + */ + public function getSchemaManager(\Doctrine\DBAL\Connection $conn) + { + return new MySqlSchemaManager($conn); + } +} diff --git a/lib/Doctrine/DBAL/Driver/AbstractOracleDriver.php b/lib/Doctrine/DBAL/Driver/AbstractOracleDriver.php new file mode 100644 index 00000000000..68a2acc9848 --- /dev/null +++ b/lib/Doctrine/DBAL/Driver/AbstractOracleDriver.php @@ -0,0 +1,144 @@ +. + */ + +namespace Doctrine\DBAL\Driver; + +use Doctrine\DBAL\Driver; +use Doctrine\DBAL\Exception; +use Doctrine\DBAL\Platforms\OraclePlatform; +use Doctrine\DBAL\Schema\OracleSchemaManager; + +/** + * Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for Oracle based drivers. + * + * @author Steve Müller + * @link www.doctrine-project.org + * @since 2.5 + */ +abstract class AbstractOracleDriver implements Driver, ExceptionConverterDriver +{ + /** + * {@inheritdoc} + */ + public function convertException($message, DriverException $exception) + { + switch ($exception->getErrorCode()) { + case '1': + case '2299': + case '38911': + return new Exception\UniqueConstraintViolationException($message, $exception); + + case '904': + return new Exception\InvalidFieldNameException($message, $exception); + + case '918': + case '960': + return new Exception\NonUniqueFieldNameException($message, $exception); + + case '923': + return new Exception\SyntaxErrorException($message, $exception); + + case '942': + return new Exception\TableNotFoundException($message, $exception); + + case '955': + return new Exception\TableExistsException($message, $exception); + + case '1017': + case '12545': + return new Exception\ConnectionException($message, $exception); + + case '1400': + return new Exception\NotNullConstraintViolationException($message, $exception); + + case '2292': + return new Exception\ForeignKeyConstraintViolationException($message, $exception); + } + + return new Exception\DriverException($message, $exception); + } + + /** + * {@inheritdoc} + */ + public function getDatabase(\Doctrine\DBAL\Connection $conn) + { + $params = $conn->getParams(); + + return $params['user']; + } + + /** + * {@inheritdoc} + */ + public function getDatabasePlatform() + { + return new OraclePlatform(); + } + + /** + * {@inheritdoc} + */ + public function getSchemaManager(\Doctrine\DBAL\Connection $conn) + { + return new OracleSchemaManager($conn); + } + + /** + * Returns an appropriate Easy Connect String for the given parameters. + * + * @param array $params The connection parameters to return the Easy Connect STring for. + * + * @return string + * + * @link http://download.oracle.com/docs/cd/E11882_01/network.112/e10836/naming.htm + */ + protected function getEasyConnectString(array $params) + { + if ( ! empty($params['host'])) { + if ( ! isset($params['port'])) { + $params['port'] = 1521; + } + + $serviceName = $params['dbname']; + + if ( ! empty($params['servicename'])) { + $serviceName = $params['servicename']; + } + + $service = 'SID=' . $serviceName; + $pooled = ''; + + if (isset($params['service']) && $params['service'] == true) { + $service = 'SERVICE_NAME=' . $serviceName; + } + + if (isset($params['pooled']) && $params['pooled'] == true) { + $pooled = '(SERVER=POOLED)'; + } + + return '(DESCRIPTION=' . + '(ADDRESS=(PROTOCOL=TCP)(HOST=' . $params['host'] . ')(PORT=' . $params['port'] . '))' . + '(CONNECT_DATA=(' . $service . ')' . $pooled . '))'; + + } + + return isset($params['dbname']) ? $params['dbname'] : ''; + } +} diff --git a/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php b/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php new file mode 100644 index 00000000000..c8c263a89fc --- /dev/null +++ b/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php @@ -0,0 +1,139 @@ +. + */ + +namespace Doctrine\DBAL\Driver; + +use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Driver; +use Doctrine\DBAL\Exception; +use Doctrine\DBAL\Platforms\PostgreSQL91Platform; +use Doctrine\DBAL\Platforms\PostgreSQL92Platform; +use Doctrine\DBAL\Platforms\PostgreSqlPlatform; +use Doctrine\DBAL\Schema\PostgreSqlSchemaManager; +use Doctrine\DBAL\VersionAwarePlatformDriver; + +/** + * Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for PostgreSQL based drivers. + * + * @author Steve Müller + * @link www.doctrine-project.org + * @since 2.5 + */ +abstract class AbstractPostgreSQLDriver implements Driver, ExceptionConverterDriver, VersionAwarePlatformDriver +{ + /** + * {@inheritdoc} + * + * @link http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html + */ + public function convertException($message, DriverException $exception) + { + switch ($exception->getSQLState()) { + case '23502': + return new Exception\NotNullConstraintViolationException($message, $exception); + + case '23503': + return new Exception\ForeignKeyConstraintViolationException($message, $exception); + + case '23505': + return new Exception\UniqueConstraintViolationException($message, $exception); + + case '42601': + return new Exception\SyntaxErrorException($message, $exception); + + case '42702': + return new Exception\NonUniqueFieldNameException($message, $exception); + + case '42703': + return new Exception\InvalidFieldNameException($message, $exception); + + case '42P01': + return new Exception\TableNotFoundException($message, $exception); + + case '42P07': + return new Exception\TableExistsException($message, $exception); + + case '7': + // In some case (mainly connection errors) the PDO exception does not provide a SQLSTATE via its code. + // The exception code is always set to 7 here. + // We have to match against the SQLSTATE in the error message in these cases. + if (strpos($exception->getMessage(), 'SQLSTATE[08006]') !== false) { + return new Exception\ConnectionException($message, $exception); + } + break; + } + + return new Exception\DriverException($message, $exception); + } + + /** + * {@inheritdoc} + */ + public function createDatabasePlatformForVersion($version) + { + if ( ! preg_match('/^(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+))?)?/', $version, $versionParts)) { + throw DBALException::invalidPlatformVersionSpecified( + $version, + '..' + ); + } + + $majorVersion = $versionParts['major']; + $minorVersion = isset($versionParts['minor']) ? $versionParts['minor'] : 0; + $patchVersion = isset($versionParts['patch']) ? $versionParts['patch'] : 0; + $version = $majorVersion . '.' . $minorVersion . '.' . $patchVersion; + + switch(true) { + case version_compare($version, '9.2', '>='): + return new PostgreSQL92Platform(); + case version_compare($version, '9.1', '>='): + return new PostgreSQL91Platform(); + default: + return new PostgreSqlPlatform(); + } + } + + /** + * {@inheritdoc} + */ + public function getDatabase(\Doctrine\DBAL\Connection $conn) + { + $params = $conn->getParams(); + + return (isset($params['dbname'])) + ? $params['dbname'] + : $conn->query('SELECT CURRENT_DATABASE()')->fetchColumn(); + } + + /** + * {@inheritdoc} + */ + public function getDatabasePlatform() + { + return new PostgreSqlPlatform(); + } + + /** + * {@inheritdoc} + */ + public function getSchemaManager(\Doctrine\DBAL\Connection $conn) + { + return new PostgreSqlSchemaManager($conn); + } +} diff --git a/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php b/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php new file mode 100644 index 00000000000..f2cd6a8c024 --- /dev/null +++ b/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php @@ -0,0 +1,136 @@ +. + */ + +namespace Doctrine\DBAL\Driver; + +use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Driver; +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; + +/** + * Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for SAP Sybase SQL Anywhere based drivers. + * + * @author Steve Müller + * @link www.doctrine-project.org + * @since 2.5 + */ +abstract class AbstractSQLAnywhereDriver implements Driver, ExceptionConverterDriver, VersionAwarePlatformDriver +{ + /** + * {@inheritdoc} + * + * @link http://dcx.sybase.com/index.html#sa160/en/saerrors/sqlerror.html + */ + public function convertException($message, DriverException $exception) + { + switch ($exception->getErrorCode()) { + case '-100': + case '-103': + case '-832': + return new Exception\ConnectionException($message, $exception); + case '-143': + return new Exception\InvalidFieldNameException($message, $exception); + case '-193': + case '-196': + return new Exception\UniqueConstraintViolationException($message, $exception); + case '-198': + return new Exception\ForeignKeyConstraintViolationException($message, $exception); + case '-144': + return new Exception\NonUniqueFieldNameException($message, $exception); + case '-184': + case '-195': + return new Exception\NotNullConstraintViolationException($message, $exception); + case '-131': + return new Exception\SyntaxErrorException($message, $exception); + case '-110': + return new Exception\TableExistsException($message, $exception); + case '-141': + case '-1041': + return new Exception\TableNotFoundException($message, $exception); + } + + return new Exception\DriverException($message, $exception); + } + + /** + * {@inheritdoc} + */ + public function createDatabasePlatformForVersion($version) + { + if ( ! preg_match( + '/^(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+))?)?)?/', + $version, + $versionParts + )) { + throw DBALException::invalidPlatformVersionSpecified( + $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} + */ + public function getDatabase(\Doctrine\DBAL\Connection $conn) + { + $params = $conn->getParams(); + + return $params['dbname']; + } + + /** + * {@inheritdoc} + */ + public function getDatabasePlatform() + { + return new SQLAnywhere12Platform(); + } + + /** + * {@inheritdoc} + */ + public function getSchemaManager(\Doctrine\DBAL\Connection $conn) + { + return new SQLAnywhereSchemaManager($conn); + } +} diff --git a/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php b/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php new file mode 100644 index 00000000000..17e12254c6d --- /dev/null +++ b/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php @@ -0,0 +1,100 @@ +. + */ + +namespace Doctrine\DBAL\Driver; + +use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Driver; +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; + +/** + * Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for Microsoft SQL Server based drivers. + * + * @author Steve Müller + * @link www.doctrine-project.org + * @since 2.5 + */ +abstract class AbstractSQLServerDriver implements Driver, VersionAwarePlatformDriver +{ + /** + * {@inheritdoc} + */ + public function createDatabasePlatformForVersion($version) + { + if ( ! preg_match( + '/^(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+))?)?)?/', + $version, + $versionParts + )) { + throw DBALException::invalidPlatformVersionSpecified( + $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} + */ + public function getDatabase(\Doctrine\DBAL\Connection $conn) + { + $params = $conn->getParams(); + + return $params['dbname']; + } + + /** + * {@inheritdoc} + */ + public function getDatabasePlatform() + { + return new SQLServer2008Platform(); + } + + /** + * {@inheritdoc} + */ + + public function getSchemaManager(\Doctrine\DBAL\Connection $conn) + { + return new SQLServerSchemaManager($conn); + } +} diff --git a/lib/Doctrine/DBAL/Driver/AbstractSQLiteDriver.php b/lib/Doctrine/DBAL/Driver/AbstractSQLiteDriver.php new file mode 100644 index 00000000000..f1e92ffaaf1 --- /dev/null +++ b/lib/Doctrine/DBAL/Driver/AbstractSQLiteDriver.php @@ -0,0 +1,111 @@ +. + */ + +namespace Doctrine\DBAL\Driver; + +use Doctrine\DBAL\Driver; +use Doctrine\DBAL\Exception; +use Doctrine\DBAL\Platforms\SqlitePlatform; +use Doctrine\DBAL\Schema\SqliteSchemaManager; + +/** + * Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for SQLite based drivers. + * + * @author Steve Müller + * @link www.doctrine-project.org + * @since 2.5 + */ +abstract class AbstractSQLiteDriver implements Driver, ExceptionConverterDriver +{ + /** + * {@inheritdoc} + * + * @link http://www.sqlite.org/c3ref/c_abort.html + */ + public function convertException($message, DriverException $exception) + { + if (strpos($exception->getMessage(), 'must be unique') !== false) { + return new Exception\UniqueConstraintViolationException($message, $exception); + } + + if (strpos($exception->getMessage(), 'may not be NULL') !== false) { + return new Exception\NotNullConstraintViolationException($message, $exception); + } + + if (strpos($exception->getMessage(), 'is not unique') !== false) { + return new Exception\UniqueConstraintViolationException($message, $exception); + } + + if (strpos($exception->getMessage(), 'no such table:') !== false) { + return new Exception\TableNotFoundException($message, $exception); + } + + if (strpos($exception->getMessage(), 'already exists') !== false) { + return new Exception\TableExistsException($message, $exception); + } + + if (strpos($exception->getMessage(), 'has no column named') !== false) { + return new Exception\InvalidFieldNameException($message, $exception); + } + + if (strpos($exception->getMessage(), 'ambiguous column name') !== false) { + return new Exception\NonUniqueFieldNameException($message, $exception); + } + + if (strpos($exception->getMessage(), 'syntax error') !== false) { + return new Exception\SyntaxErrorException($message, $exception); + } + + if (strpos($exception->getMessage(), 'attempt to write a readonly database') !== false) { + return new Exception\ReadOnlyException($message, $exception); + } + + if (strpos($exception->getMessage(), 'unable to open database file') !== false) { + return new Exception\ConnectionException($message, $exception); + } + + return new Exception\DriverException($message, $exception); + } + + /** + * {@inheritdoc} + */ + public function getDatabase(\Doctrine\DBAL\Connection $conn) + { + $params = $conn->getParams(); + + return isset($params['path']) ? $params['path'] : null; + } + + /** + * {@inheritdoc} + */ + public function getDatabasePlatform() + { + return new SqlitePlatform(); + } + + /** + * {@inheritdoc} + */ + public function getSchemaManager(\Doctrine\DBAL\Connection $conn) + { + return new SqliteSchemaManager($conn); + } +} diff --git a/lib/Doctrine/DBAL/Driver/DrizzlePDOMySql/Driver.php b/lib/Doctrine/DBAL/Driver/DrizzlePDOMySql/Driver.php index 900d3835961..ff4cf3b83d0 100644 --- a/lib/Doctrine/DBAL/Driver/DrizzlePDOMySql/Driver.php +++ b/lib/Doctrine/DBAL/Driver/DrizzlePDOMySql/Driver.php @@ -19,9 +19,6 @@ namespace Doctrine\DBAL\Driver\DrizzlePDOMySql; -use Doctrine\DBAL\Driver\DriverException; -use Doctrine\DBAL\Driver\ExceptionConverterDriver; -use Doctrine\DBAL\Exception; use Doctrine\DBAL\Platforms\DrizzlePlatform; use Doctrine\DBAL\Schema\DrizzleSchemaManager; @@ -30,7 +27,7 @@ * * @author Kim Hemsø Rasmussen */ -class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver +class Driver extends \Doctrine\DBAL\Driver\PDOMySql\Driver { /** * {@inheritdoc} @@ -38,7 +35,7 @@ class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver public function connect(array $params, $username = null, $password = null, array $driverOptions = array()) { $conn = new Connection( - $this->_constructPdoDsn($params), + $this->constructPdoDsn($params), $username, $password, $driverOptions @@ -48,29 +45,11 @@ public function connect(array $params, $username = null, $password = null, array } /** - * Constructs the Drizzle MySql PDO DSN. - * - * @param array $params - * - * @return string The DSN. + * {@inheritdoc} */ - private function _constructPdoDsn(array $params) + public function createDatabasePlatformForVersion($version) { - $dsn = 'mysql:'; - if (isset($params['host']) && $params['host'] != '') { - $dsn .= 'host=' . $params['host'] . ';'; - } - if (isset($params['port'])) { - $dsn .= 'port=' . $params['port'] . ';'; - } - if (isset($params['dbname'])) { - $dsn .= 'dbname=' . $params['dbname'] . ';'; - } - if (isset($params['unix_socket'])) { - $dsn .= 'unix_socket=' . $params['unix_socket'] . ';'; - } - - return $dsn; + return $this->getDatabasePlatform(); } /** @@ -96,92 +75,4 @@ public function getName() { return 'drizzle_pdo_mysql'; } - - /** - * {@inheritdoc} - */ - public function getDatabase(\Doctrine\DBAL\Connection $conn) - { - $params = $conn->getParams(); - - return $params['dbname']; - } - - /** - * {@inheritdoc} - * - * @link http://dev.mysql.com/doc/refman/5.7/en/error-messages-client.html - * @link http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html - */ - public function convertException($message, DriverException $exception) - { - switch ($exception->getErrorCode()) { - case '1050': - return new Exception\TableExistsException($message, $exception); - - case '1051': - case '1146': - return new Exception\TableNotFoundException($message, $exception); - - case '1216': - case '1217': - case '1451': - case '1452': - return new Exception\ForeignKeyConstraintViolationException($message, $exception); - - case '1062': - case '1557': - case '1569': - case '1586': - return new Exception\UniqueConstraintViolationException($message, $exception); - - case '1054': - case '1166': - case '1611': - return new Exception\InvalidFieldNameException($message, $exception); - - case '1052': - case '1060': - case '1110': - return new Exception\NonUniqueFieldNameException($message, $exception); - - case '1064': - case '1149': - case '1287': - case '1341': - case '1342': - case '1343': - case '1344': - case '1382': - case '1479': - case '1541': - case '1554': - case '1626': - return new Exception\SyntaxErrorException($message, $exception); - - case '1044': - case '1045': - case '1046': - case '1049': - case '1095': - case '1142': - case '1143': - case '1227': - case '1370': - case '2002': - case '2005': - return new Exception\ConnectionException($message, $exception); - - case '1048': - case '1121': - case '1138': - case '1171': - case '1252': - case '1263': - case '1566': - return new Exception\NotNullConstraintViolationException($message, $exception); - } - - return new Exception\DriverException($message, $exception); - } } diff --git a/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php b/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php index e2695e1d9e4..1772eb56fba 100644 --- a/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php +++ b/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php @@ -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 @@ 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} */ diff --git a/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php b/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php index ce2d34fe705..8ed82e4dda2 100644 --- a/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php +++ b/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php @@ -19,10 +19,7 @@ namespace Doctrine\DBAL\Driver\IBMDB2; -use Doctrine\DBAL\Driver; -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Platforms\DB2Platform; -use Doctrine\DBAL\Schema\DB2SchemaManager; +use Doctrine\DBAL\Driver\AbstractDB2Driver; /** * IBM DB2 Driver. @@ -30,7 +27,7 @@ * @since 2.0 * @author Benjamin Eberlei */ -class DB2Driver implements Driver +class DB2Driver extends AbstractDB2Driver { /** * {@inheritdoc} @@ -60,22 +57,6 @@ public function connect(array $params, $username = null, $password = null, array return new DB2Connection($params, $username, $password, $driverOptions); } - /** - * {@inheritdoc} - */ - public function getDatabasePlatform() - { - return new DB2Platform(); - } - - /** - * {@inheritdoc} - */ - public function getSchemaManager(Connection $conn) - { - return new DB2SchemaManager($conn); - } - /** * {@inheritdoc} */ @@ -83,22 +64,4 @@ public function getName() { return 'ibm_db2'; } - - /** - * {@inheritdoc} - */ - public function getDatabase(Connection $conn) - { - $params = $conn->getParams(); - - return $params['dbname']; - } - - /** - * {@inheritdoc} - */ - public function convertExceptionCode(\Exception $exception) - { - return 0; - } } diff --git a/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php b/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php index 9046bcee2b3..8949d2b008f 100644 --- a/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php +++ b/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php @@ -19,17 +19,13 @@ namespace Doctrine\DBAL\Driver\Mysqli; -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Driver as DriverInterface; +use Doctrine\DBAL\Driver\AbstractMySQLDriver; use Doctrine\DBAL\DBALException; -use Doctrine\DBAL\Driver\ExceptionConverterDriver; -use Doctrine\DBAL\Exception; -use Doctrine\DBAL\Platforms\MySqlPlatform; /** * @author Kim Hemsø Rasmussen */ -class Driver implements DriverInterface, ExceptionConverterDriver +class Driver extends AbstractMySQLDriver { /** * {@inheritdoc} @@ -50,108 +46,4 @@ public function getName() { return 'mysqli'; } - - /** - * {@inheritdoc} - */ - public function getSchemaManager(Connection $conn) - { - return new \Doctrine\DBAL\Schema\MySqlSchemaManager($conn); - } - - /** - * {@inheritdoc} - */ - public function getDatabasePlatform() - { - return new MySqlPlatform(); - } - - /** - * {@inheritdoc} - */ - public function getDatabase(Connection $conn) - { - $params = $conn->getParams(); - - return $params['dbname']; - } - - /** - * {@inheritdoc} - * - * @link http://dev.mysql.com/doc/refman/5.7/en/error-messages-client.html - * @link http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html - */ - public function convertException($message, DriverInterface\DriverException $exception) - { - switch ($exception->getErrorCode()) { - case '1050': - return new Exception\TableExistsException($message, $exception); - - case '1051': - case '1146': - return new Exception\TableNotFoundException($message, $exception); - - case '1216': - case '1217': - case '1451': - case '1452': - return new Exception\ForeignKeyConstraintViolationException($message, $exception); - - case '1062': - case '1557': - case '1569': - case '1586': - return new Exception\UniqueConstraintViolationException($message, $exception); - - case '1054': - case '1166': - case '1611': - return new Exception\InvalidFieldNameException($message, $exception); - - case '1052': - case '1060': - case '1110': - return new Exception\NonUniqueFieldNameException($message, $exception); - - case '1064': - case '1149': - case '1287': - case '1341': - case '1342': - case '1343': - case '1344': - case '1382': - case '1479': - case '1541': - case '1554': - case '1626': - return new Exception\SyntaxErrorException($message, $exception); - - case '1044': - case '1045': - case '1046': - case '1049': - case '1095': - case '1142': - case '1143': - case '1227': - case '1370': - case '2002': - case '2005': - return new Exception\ConnectionException($message, $exception); - - case '1048': - case '1121': - case '1138': - case '1171': - case '1252': - case '1263': - case '1566': - return new Exception\NotNullConstraintViolationException($message, $exception); - } - - return new Exception\DriverException($message, $exception); - } } diff --git a/lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php b/lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php index beeb508cefa..21e2872e239 100644 --- a/lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php +++ b/lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php @@ -21,12 +21,13 @@ use Doctrine\DBAL\Driver\Connection as Connection; use Doctrine\DBAL\Driver\PingableConnection; +use Doctrine\DBAL\Driver\ServerInfoAwareConnection; /** * @author Kim Hemsø Rasmussen * @author Till Klampaeckel */ -class MysqliConnection implements Connection, PingableConnection +class MysqliConnection implements Connection, PingableConnection, ServerInfoAwareConnection { /** * @var \mysqli @@ -78,6 +79,26 @@ public function getWrappedResourceHandle() 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} */ diff --git a/lib/Doctrine/DBAL/Driver/OCI8/Driver.php b/lib/Doctrine/DBAL/Driver/OCI8/Driver.php index 2f41091432e..1aa1b876e2b 100644 --- a/lib/Doctrine/DBAL/Driver/OCI8/Driver.php +++ b/lib/Doctrine/DBAL/Driver/OCI8/Driver.php @@ -19,13 +19,8 @@ namespace Doctrine\DBAL\Driver\OCI8; -use Doctrine\DBAL\Connection; use Doctrine\DBAL\DBALException; -use Doctrine\DBAL\Driver\DriverException; -use Doctrine\DBAL\Driver\ExceptionConverterDriver; -use Doctrine\DBAL\Exception; -use Doctrine\DBAL\Platforms\OraclePlatform; -use Doctrine\DBAL\Schema\OracleSchemaManager; +use Doctrine\DBAL\Driver\AbstractOracleDriver; /** * A Doctrine DBAL driver for the Oracle OCI8 PHP extensions. @@ -33,7 +28,7 @@ * @author Roman Borschel * @since 2.0 */ -class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver +class Driver extends AbstractOracleDriver { /** * {@inheritdoc} @@ -63,56 +58,7 @@ public function connect(array $params, $username = null, $password = null, array */ protected function _constructDsn(array $params) { - $dsn = ''; - if (isset($params['host']) && $params['host'] != '') { - $dsn .= '(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)' . - '(HOST=' . $params['host'] . ')'; - - if (isset($params['port'])) { - $dsn .= '(PORT=' . $params['port'] . ')'; - } else { - $dsn .= '(PORT=1521)'; - } - - $serviceName = $params['dbname']; - - if ( ! empty($params['servicename'])) { - $serviceName = $params['servicename']; - } - - $service = 'SID=' . $serviceName; - $pooled = ''; - - if (isset($params['service']) && $params['service'] == true) { - $service = 'SERVICE_NAME=' . $serviceName; - } - - if (isset($params['pooled']) && $params['pooled'] == true) { - $pooled = '(SERVER=POOLED)'; - } - - $dsn .= '))(CONNECT_DATA=(' . $service . ')' . $pooled . '))'; - } else { - $dsn .= $params['dbname']; - } - - return $dsn; - } - - /** - * {@inheritdoc} - */ - public function getDatabasePlatform() - { - return new OraclePlatform(); - } - - /** - * {@inheritdoc} - */ - public function getSchemaManager(Connection $conn) - { - return new OracleSchemaManager($conn); + return $this->getEasyConnectString($params); } /** @@ -122,55 +68,4 @@ public function getName() { return 'oci8'; } - - /** - * {@inheritdoc} - */ - public function getDatabase(Connection $conn) - { - $params = $conn->getParams(); - - return $params['user']; - } - - /** - * {@inheritdoc} - */ - public function convertException($message, DriverException $exception) - { - switch ($exception->getErrorCode()) { - case '1': - case '2299': - case '38911': - return new Exception\UniqueConstraintViolationException($message, $exception); - - case '904': - return new Exception\InvalidFieldNameException($message, $exception); - - case '918': - case '960': - return new Exception\NonUniqueFieldNameException($message, $exception); - - case '923': - return new Exception\SyntaxErrorException($message, $exception); - - case '942': - return new Exception\TableNotFoundException($message, $exception); - - case '955': - return new Exception\TableExistsException($message, $exception); - - case '1017': - case '12545': - return new Exception\ConnectionException($message, $exception); - - case '1400': - return new Exception\NotNullConstraintViolationException($message, $exception); - - case '2292': - return new Exception\ForeignKeyConstraintViolationException($message, $exception); - } - - return new Exception\DriverException($message, $exception); - } } diff --git a/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php b/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php index cdd71463821..a919ddaab83 100644 --- a/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php +++ b/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php @@ -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 @@ * * @since 2.0 */ -class OCI8Connection implements Connection +class OCI8Connection implements Connection, ServerInfoAwareConnection { /** * @var resource @@ -66,6 +67,35 @@ public function __construct($username, $password, $db, $charset = null, $session } } + /** + * {@inheritdoc} + * + * @throws \UnexpectedValueException if the version string returned by the database server + * does not contain a parsable version number. + */ + public function getServerVersion() + { + if ( ! preg_match('/\s+(\d+\.\d+\.\d+\.\d+\.\d+)\s+/', oci_server_version($this->dbh), $version)) { + throw new \UnexpectedValueException( + sprintf( + 'Unexpected database version string "%s". Cannot parse an appropriate version number from it. ' . + 'Please report this database version string to the Doctrine team.', + oci_server_version($this->dbh) + ) + ); + } + + return $version[1]; + } + + /** + * {@inheritdoc} + */ + public function requiresQueryForServerVersion() + { + return false; + } + /** * {@inheritdoc} */ diff --git a/lib/Doctrine/DBAL/Driver/PDOConnection.php b/lib/Doctrine/DBAL/Driver/PDOConnection.php index 15af4f132c8..407267850cb 100644 --- a/lib/Doctrine/DBAL/Driver/PDOConnection.php +++ b/lib/Doctrine/DBAL/Driver/PDOConnection.php @@ -27,7 +27,7 @@ * * @since 2.0 */ -class PDOConnection extends PDO implements Connection +class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection { /** * @param string $dsn @@ -48,6 +48,14 @@ public function __construct($dsn, $user = null, $password = null, array $options } } + /** + * {@inheritdoc} + */ + public function getServerVersion() + { + return PDO::getAttribute(PDO::ATTR_SERVER_VERSION); + } + /** * {@inheritdoc} */ @@ -110,4 +118,12 @@ public function lastInsertId($name = null) throw new PDOException($exception); } } + + /** + * {@inheritdoc} + */ + public function requiresQueryForServerVersion() + { + return false; + } } diff --git a/lib/Doctrine/DBAL/Driver/PDOException.php b/lib/Doctrine/DBAL/Driver/PDOException.php index 60507110654..2650dd087af 100644 --- a/lib/Doctrine/DBAL/Driver/PDOException.php +++ b/lib/Doctrine/DBAL/Driver/PDOException.php @@ -51,6 +51,8 @@ public function __construct(\PDOException $exception) { parent::__construct($exception->getMessage(), 0, $exception->getPrevious()); + $this->code = $exception->getCode(); + $this->errorInfo = $exception->errorInfo; $this->errorCode = isset($exception->errorInfo[1]) ? $exception->errorInfo[1] : $exception->getCode(); $this->sqlState = isset($exception->errorInfo[0]) ? $exception->errorInfo[0] : $exception->getCode(); } diff --git a/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php b/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php index 462afad0dba..0b929f72007 100644 --- a/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php @@ -19,10 +19,8 @@ namespace Doctrine\DBAL\Driver\PDOIbm; -use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Driver\AbstractDB2Driver; use Doctrine\DBAL\Driver\PDOConnection; -use Doctrine\DBAL\Platforms\DB2Platform; -use Doctrine\DBAL\Schema\DB2SchemaManager; /** * Driver for the PDO IBM extension. @@ -34,7 +32,7 @@ * @author Jonathan Wage * @author Roman Borschel */ -class Driver implements \Doctrine\DBAL\Driver +class Driver extends AbstractDB2Driver { /** * {@inheritdoc} @@ -75,22 +73,6 @@ private function _constructPdoDsn(array $params) return $dsn; } - /** - * {@inheritdoc} - */ - public function getDatabasePlatform() - { - return new DB2Platform(); - } - - /** - * {@inheritdoc} - */ - public function getSchemaManager(Connection $conn) - { - return new DB2SchemaManager($conn); - } - /** * {@inheritdoc} */ @@ -98,22 +80,4 @@ public function getName() { return 'pdo_ibm'; } - - /** - * {@inheritdoc} - */ - public function getDatabase(Connection $conn) - { - $params = $conn->getParams(); - - return $params['dbname']; - } - - /** - * {@inheritdoc} - */ - public function convertExceptionCode(\Exception $exception) - { - return 0; - } } diff --git a/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php b/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php index 18ac45de3f5..7e3632dde91 100644 --- a/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php @@ -19,14 +19,9 @@ namespace Doctrine\DBAL\Driver\PDOMySql; -use Doctrine\DBAL\Connection; use Doctrine\DBAL\DBALException; -use Doctrine\DBAL\Driver\DriverException; -use Doctrine\DBAL\Driver\ExceptionConverterDriver; +use Doctrine\DBAL\Driver\AbstractMySQLDriver; use Doctrine\DBAL\Driver\PDOConnection; -use Doctrine\DBAL\Exception; -use Doctrine\DBAL\Platforms\MySqlPlatform; -use Doctrine\DBAL\Schema\MySqlSchemaManager; use PDOException; /** @@ -34,7 +29,7 @@ * * @since 2.0 */ -class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver +class Driver extends AbstractMySQLDriver { /** * {@inheritdoc} @@ -43,7 +38,7 @@ public function connect(array $params, $username = null, $password = null, array { try { $conn = new PDOConnection( - $this->_constructPdoDsn($params), + $this->constructPdoDsn($params), $username, $password, $driverOptions @@ -62,7 +57,7 @@ public function connect(array $params, $username = null, $password = null, array * * @return string The DSN. */ - private function _constructPdoDsn(array $params) + protected function constructPdoDsn(array $params) { $dsn = 'mysql:'; if (isset($params['host']) && $params['host'] != '') { @@ -84,22 +79,6 @@ private function _constructPdoDsn(array $params) return $dsn; } - /** - * {@inheritdoc} - */ - public function getDatabasePlatform() - { - return new MySqlPlatform(); - } - - /** - * {@inheritdoc} - */ - public function getSchemaManager(Connection $conn) - { - return new MySqlSchemaManager($conn); - } - /** * {@inheritdoc} */ @@ -107,95 +86,4 @@ public function getName() { return 'pdo_mysql'; } - - /** - * {@inheritdoc} - */ - public function getDatabase(Connection $conn) - { - $params = $conn->getParams(); - - if (isset($params['dbname'])) { - return $params['dbname']; - } - return $conn->query('SELECT DATABASE()')->fetchColumn(); - } - - /** - * {@inheritdoc} - * - * @link http://dev.mysql.com/doc/refman/5.7/en/error-messages-client.html - * @link http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html - */ - public function convertException($message, DriverException $exception) - { - switch ($exception->getErrorCode()) { - case '1050': - return new Exception\TableExistsException($message, $exception); - - case '1051': - case '1146': - return new Exception\TableNotFoundException($message, $exception); - - case '1216': - case '1217': - case '1451': - case '1452': - return new Exception\ForeignKeyConstraintViolationException($message, $exception); - - case '1062': - case '1557': - case '1569': - case '1586': - return new Exception\UniqueConstraintViolationException($message, $exception); - - case '1054': - case '1166': - case '1611': - return new Exception\InvalidFieldNameException($message, $exception); - - case '1052': - case '1060': - case '1110': - return new Exception\NonUniqueFieldNameException($message, $exception); - - case '1064': - case '1149': - case '1287': - case '1341': - case '1342': - case '1343': - case '1344': - case '1382': - case '1479': - case '1541': - case '1554': - case '1626': - return new Exception\SyntaxErrorException($message, $exception); - - case '1044': - case '1045': - case '1046': - case '1049': - case '1095': - case '1142': - case '1143': - case '1227': - case '1370': - case '2002': - case '2005': - return new Exception\ConnectionException($message, $exception); - - case '1048': - case '1121': - case '1138': - case '1171': - case '1252': - case '1263': - case '1566': - return new Exception\NotNullConstraintViolationException($message, $exception); - } - - return new Exception\DriverException($message, $exception); - } } diff --git a/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php b/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php index 743e94a0bfb..6e958c7448e 100644 --- a/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php @@ -19,14 +19,9 @@ namespace Doctrine\DBAL\Driver\PDOOracle; -use Doctrine\DBAL\Connection; use Doctrine\DBAL\DBALException; -use Doctrine\DBAL\Driver\DriverException; -use Doctrine\DBAL\Driver\ExceptionConverterDriver; +use Doctrine\DBAL\Driver\AbstractOracleDriver; use Doctrine\DBAL\Driver\PDOConnection; -use Doctrine\DBAL\Exception; -use Doctrine\DBAL\Platforms\OraclePlatform; -use Doctrine\DBAL\Schema\OracleSchemaManager; /** * PDO Oracle driver. @@ -36,7 +31,7 @@ * 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 extends AbstractOracleDriver { /** * {@inheritdoc} @@ -45,7 +40,7 @@ public function connect(array $params, $username = null, $password = null, array { try { return new PDOConnection( - $this->_constructPdoDsn($params), + $this->constructPdoDsn($params), $username, $password, $driverOptions @@ -62,41 +57,9 @@ public function connect(array $params, $username = null, $password = null, array * * @return string The DSN. */ - private function _constructPdoDsn(array $params) + private function constructPdoDsn(array $params) { - $dsn = 'oci:dbname='; - - if (isset($params['host']) && $params['host'] != '') { - $dsn .= '(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)' . - '(HOST=' . $params['host'] . ')'; - - if (isset($params['port'])) { - $dsn .= '(PORT=' . $params['port'] . ')'; - } else { - $dsn .= '(PORT=1521)'; - } - - $serviceName = $params['dbname']; - - if ( ! empty($params['servicename'])) { - $serviceName = $params['servicename']; - } - - $service = 'SID=' . $serviceName; - $pooled = ''; - - if (isset($params['service']) && $params['service'] == true) { - $service = 'SERVICE_NAME=' . $serviceName; - } - - if (isset($params['pooled']) && $params['pooled'] == true) { - $pooled = '(SERVER=POOLED)'; - } - - $dsn .= '))(CONNECT_DATA=(' . $service . ')' . $pooled . '))'; - } else { - $dsn .= $params['dbname']; - } + $dsn = 'oci:dbname=' . $this->getEasyConnectString($params); if (isset($params['charset'])) { $dsn .= ';charset=' . $params['charset']; @@ -105,22 +68,6 @@ private function _constructPdoDsn(array $params) return $dsn; } - /** - * {@inheritdoc} - */ - public function getDatabasePlatform() - { - return new OraclePlatform(); - } - - /** - * {@inheritdoc} - */ - public function getSchemaManager(Connection $conn) - { - return new OracleSchemaManager($conn); - } - /** * {@inheritdoc} */ @@ -128,55 +75,4 @@ public function getName() { return 'pdo_oracle'; } - - /** - * {@inheritdoc} - */ - public function getDatabase(Connection $conn) - { - $params = $conn->getParams(); - - return $params['user']; - } - - /** - * {@inheritdoc} - */ - public function convertException($message, DriverException $exception) - { - switch ($exception->getErrorCode()) { - case '1': - case '2299': - case '38911': - return new Exception\UniqueConstraintViolationException($message, $exception); - - case '904': - return new Exception\InvalidFieldNameException($message, $exception); - - case '918': - case '960': - return new Exception\NonUniqueFieldNameException($message, $exception); - - case '923': - return new Exception\SyntaxErrorException($message, $exception); - - case '942': - return new Exception\TableNotFoundException($message, $exception); - - case '955': - return new Exception\TableExistsException($message, $exception); - - case '1017': - case '12545': - return new Exception\ConnectionException($message, $exception); - - case '1400': - return new Exception\NotNullConstraintViolationException($message, $exception); - - case '2292': - return new Exception\ForeignKeyConstraintViolationException($message, $exception); - } - - return new Exception\DriverException($message, $exception); - } } diff --git a/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php b/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php index 69cec83c51a..d0ab5fe3b97 100644 --- a/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php @@ -19,22 +19,17 @@ namespace Doctrine\DBAL\Driver\PDOPgSql; -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Driver\DriverException; +use Doctrine\DBAL\Driver\AbstractPostgreSQLDriver; use Doctrine\DBAL\Driver\PDOConnection; -use Doctrine\DBAL\Exception; -use Doctrine\DBAL\Platforms\PostgreSqlPlatform; use Doctrine\DBAL\DBALException; -use Doctrine\DBAL\Schema\PostgreSqlSchemaManager; use PDOException; -use Doctrine\DBAL\Driver\ExceptionConverterDriver; /** * Driver that connects through pdo_pgsql. * * @since 2.0 */ -class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver +class Driver extends AbstractPostgreSQLDriver { /** * {@inheritdoc} @@ -48,7 +43,7 @@ public function connect(array $params, $username = null, $password = null, array $password, $driverOptions ); - } catch(PDOException $e) { + } catch (PDOException $e) { throw DBALException::driverException($this, $e); } } @@ -87,22 +82,6 @@ private function _constructPdoDsn(array $params) return $dsn; } - /** - * {@inheritdoc} - */ - public function getDatabasePlatform() - { - return new PostgreSqlPlatform(); - } - - /** - * {@inheritdoc} - */ - public function getSchemaManager(Connection $conn) - { - return new PostgreSqlSchemaManager($conn); - } - /** * {@inheritdoc} */ @@ -110,61 +89,4 @@ public function getName() { return 'pdo_pgsql'; } - - /** - * {@inheritdoc} - */ - public function getDatabase(Connection $conn) - { - $params = $conn->getParams(); - - return (isset($params['dbname'])) - ? $params['dbname'] - : $conn->query('SELECT CURRENT_DATABASE()')->fetchColumn(); - } - - /** - * {@inheritdoc} - * - * @link http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html - */ - public function convertException($message, DriverException $exception) - { - switch ($exception->getSQLState()) { - case '23502': - return new Exception\NotNullConstraintViolationException($message, $exception); - - case '23503': - return new Exception\ForeignKeyConstraintViolationException($message, $exception); - - case '23505': - return new Exception\UniqueConstraintViolationException($message, $exception); - - case '42601': - return new Exception\SyntaxErrorException($message, $exception); - - case '42702': - return new Exception\NonUniqueFieldNameException($message, $exception); - - case '42703': - return new Exception\InvalidFieldNameException($message, $exception); - - case '42P01': - return new Exception\TableNotFoundException($message, $exception); - - case '42P07': - return new Exception\TableExistsException($message, $exception); - - case '7': - // In some case (mainly connection errors) the PDO exception does not provide a SQLSTATE via its code. - // The exception code is always set to 7 here. - // We have to match against the SQLSTATE in the error message in these cases. - if (strpos($exception->getMessage(), 'SQLSTATE[08006]') !== false) { - return new Exception\ConnectionException($message, $exception); - } - break; - } - - return new Exception\DriverException($message, $exception); - } } diff --git a/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php b/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php index ec476625a70..3c5382fb5f3 100644 --- a/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php @@ -19,14 +19,9 @@ namespace Doctrine\DBAL\Driver\PDOSqlite; -use Doctrine\DBAL\Connection; use Doctrine\DBAL\DBALException; -use Doctrine\DBAL\Driver\DriverException; -use Doctrine\DBAL\Driver\ExceptionConverterDriver; +use Doctrine\DBAL\Driver\AbstractSQLiteDriver; use Doctrine\DBAL\Driver\PDOConnection; -use Doctrine\DBAL\Exception; -use Doctrine\DBAL\Platforms\SqlitePlatform; -use Doctrine\DBAL\Schema\SqliteSchemaManager; use PDOException; /** @@ -34,7 +29,7 @@ * * @since 2.0 */ -class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver +class Driver extends AbstractSQLiteDriver { /** * @var array @@ -93,22 +88,6 @@ protected function _constructPdoDsn(array $params) return $dsn; } - /** - * {@inheritdoc} - */ - public function getDatabasePlatform() - { - return new SqlitePlatform(); - } - - /** - * {@inheritdoc} - */ - public function getSchemaManager(Connection $conn) - { - return new SqliteSchemaManager($conn); - } - /** * {@inheritdoc} */ @@ -116,64 +95,4 @@ public function getName() { return 'pdo_sqlite'; } - - /** - * {@inheritdoc} - */ - public function getDatabase(Connection $conn) - { - $params = $conn->getParams(); - - return isset($params['path']) ? $params['path'] : null; - } - - /** - * {@inheritdoc} - * - * @link http://www.sqlite.org/c3ref/c_abort.html - */ - public function convertException($message, DriverException $exception) - { - if (strpos($exception->getMessage(), 'must be unique') !== false) { - return new Exception\UniqueConstraintViolationException($message, $exception); - } - - if (strpos($exception->getMessage(), 'may not be NULL') !== false) { - return new Exception\NotNullConstraintViolationException($message, $exception); - } - - if (strpos($exception->getMessage(), 'is not unique') !== false) { - return new Exception\UniqueConstraintViolationException($message, $exception); - } - - if (strpos($exception->getMessage(), 'no such table:') !== false) { - return new Exception\TableNotFoundException($message, $exception); - } - - if (strpos($exception->getMessage(), 'already exists') !== false) { - return new Exception\TableExistsException($message, $exception); - } - - if (strpos($exception->getMessage(), 'has no column named') !== false) { - return new Exception\InvalidFieldNameException($message, $exception); - } - - if (strpos($exception->getMessage(), 'ambiguous column name') !== false) { - return new Exception\NonUniqueFieldNameException($message, $exception); - } - - if (strpos($exception->getMessage(), 'syntax error') !== false) { - return new Exception\SyntaxErrorException($message, $exception); - } - - if (strpos($exception->getMessage(), 'attempt to write a readonly database') !== false) { - return new Exception\ReadOnlyException($message, $exception); - } - - if (strpos($exception->getMessage(), 'unable to open database file') !== false) { - return new Exception\ConnectionException($message, $exception); - } - - return new Exception\DriverException($message, $exception); - } } diff --git a/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php b/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php index 0812aa32839..64b91f194c0 100644 --- a/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php @@ -19,15 +19,14 @@ namespace Doctrine\DBAL\Driver\PDOSqlsrv; -use Doctrine\DBAL\Platforms\SQLServer2008Platform; -use Doctrine\DBAL\Schema\SQLServerSchemaManager; +use Doctrine\DBAL\Driver\AbstractSQLServerDriver; /** * The PDO-based Sqlsrv driver. * * @since 2.0 */ -class Driver implements \Doctrine\DBAL\Driver +class Driver extends AbstractSQLServerDriver { /** * {@inheritdoc} @@ -61,7 +60,7 @@ private function _constructPdoDsn(array $params) $dsn .= ',' . $params['port']; } - if (isset($params['dbname'])) {; + if (isset($params['dbname'])) { $dsn .= ';Database=' . $params['dbname']; } @@ -72,22 +71,6 @@ private function _constructPdoDsn(array $params) return $dsn; } - /** - * {@inheritdoc} - */ - public function getDatabasePlatform() - { - return new SQLServer2008Platform(); - } - /** - * {@inheritdoc} - */ - - public function getSchemaManager(\Doctrine\DBAL\Connection $conn) - { - return new SQLServerSchemaManager($conn); - } - /** * {@inheritdoc} */ @@ -95,22 +78,4 @@ public function getName() { return 'pdo_sqlsrv'; } - - /** - * {@inheritdoc} - */ - public function getDatabase(\Doctrine\DBAL\Connection $conn) - { - $params = $conn->getParams(); - - return $params['dbname']; - } - - /** - * {@inheritdoc} - */ - public function convertExceptionCode(\Exception $exception) - { - return 0; - } } diff --git a/lib/Doctrine/DBAL/Driver/SQLAnywhere/Driver.php b/lib/Doctrine/DBAL/Driver/SQLAnywhere/Driver.php index 051b1de91a7..da393457672 100644 --- a/lib/Doctrine/DBAL/Driver/SQLAnywhere/Driver.php +++ b/lib/Doctrine/DBAL/Driver/SQLAnywhere/Driver.php @@ -19,13 +19,8 @@ namespace Doctrine\DBAL\Driver\SQLAnywhere; -use Doctrine\DBAL\Connection; use Doctrine\DBAL\DBALException; -use Doctrine\DBAL\Driver\DriverException; -use Doctrine\DBAL\Driver\ExceptionConverterDriver; -use Doctrine\DBAL\Exception; -use Doctrine\DBAL\Platforms\SQLAnywhere12Platform; -use Doctrine\DBAL\Schema\SQLAnywhereSchemaManager; +use Doctrine\DBAL\Driver\AbstractSQLAnywhereDriver; /** * A Doctrine DBAL driver for the SAP Sybase SQL Anywhere PHP extension. @@ -34,7 +29,7 @@ * @link www.doctrine-project.org * @since 2.5 */ -class Driver implements \Doctrine\DBAL\Driver, ExceptionConverterDriver +class Driver extends AbstractSQLAnywhereDriver { /** * {@inheritdoc} @@ -74,60 +69,6 @@ public function connect(array $params, $username = null, $password = null, array } } - /** - * {@inheritdoc} - * - * @link http://dcx.sybase.com/index.html#sa160/en/saerrors/sqlerror.html - */ - public function convertException($message, DriverException $exception) - { - switch ($exception->getErrorCode()) { - case '-100': - case '-103': - case '-832': - return new Exception\ConnectionException($message, $exception); - case '-143': - return new Exception\InvalidFieldNameException($message, $exception); - case '-193': - case '-196': - return new Exception\UniqueConstraintViolationException($message, $exception); - case '-198': - return new Exception\ForeignKeyConstraintViolationException($message, $exception); - case '-144': - return new Exception\NonUniqueFieldNameException($message, $exception); - case '-184': - case '-195': - return new Exception\NotNullConstraintViolationException($message, $exception); - case '-131': - return new Exception\SyntaxErrorException($message, $exception); - case '-110': - return new Exception\TableExistsException($message, $exception); - case '-141': - case '-1041': - return new Exception\TableNotFoundException($message, $exception); - } - - return new Exception\DriverException($message, $exception); - } - - /** - * {@inheritdoc} - */ - public function getDatabase(Connection $conn) - { - $params = $conn->getParams(); - - return $params['dbname']; - } - - /** - * {@inheritdoc} - */ - public function getDatabasePlatform() - { - return new SQLAnywhere12Platform(); - } - /** * {@inheritdoc} */ @@ -136,14 +77,6 @@ public function getName() return 'sqlanywhere'; } - /** - * {@inheritdoc} - */ - public function getSchemaManager(Connection $conn) - { - return new SQLAnywhereSchemaManager($conn); - } - /** * Build the connection string for given connection parameters and driver options. * diff --git a/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereConnection.php b/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereConnection.php index eaac9a54ae6..79fbb363ce7 100644 --- a/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereConnection.php +++ b/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereConnection.php @@ -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 @@ * @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 @@ public function exec($statement) return $stmt->rowCount(); } + /** + * {@inheritdoc} + */ + public function getServerVersion() + { + return $this->query("SELECT PROPERTY('ProductVersion')")->fetchColumn(); + } + /** * {@inheritdoc} */ @@ -172,6 +181,14 @@ public function quote($input, $type = \PDO::PARAM_STR) return "'" . sasql_escape_string($this->connection, $input) . "'"; } + /** + * {@inheritdoc} + */ + public function requiresQueryForServerVersion() + { + return true; + } + /** * {@inheritdoc} * diff --git a/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php b/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php index 311d81f490f..b4ed33e630a 100644 --- a/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php +++ b/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php @@ -19,14 +19,12 @@ namespace Doctrine\DBAL\Driver\SQLSrv; -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Platforms\SQLServer2008Platform; -use Doctrine\DBAL\Schema\SQLServerSchemaManager; +use Doctrine\DBAL\Driver\AbstractSQLServerDriver; /** * Driver for ext/sqlsrv. */ -class Driver implements \Doctrine\DBAL\Driver +class Driver extends AbstractSQLServerDriver { /** * {@inheritdoc} @@ -36,15 +34,16 @@ public function connect(array $params, $username = null, $password = null, array 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']; } - $driverOptions['Database'] = $params['dbname']; + + if (isset($params['dbname'])) { + $driverOptions['Database'] = $params['dbname']; + } + $driverOptions['UID'] = $username; $driverOptions['PWD'] = $password; @@ -55,22 +54,6 @@ public function connect(array $params, $username = null, $password = null, array return new SQLSrvConnection($serverName, $driverOptions); } - /** - * {@inheritdoc} - */ - public function getDatabasePlatform() - { - return new SQLServer2008Platform(); - } - - /** - * {@inheritdoc} - */ - public function getSchemaManager(Connection $conn) - { - return new SQLServerSchemaManager($conn); - } - /** * {@inheritdoc} */ @@ -78,21 +61,4 @@ public function getName() { return 'sqlsrv'; } - - /** - * {@inheritdoc} - */ - public function getDatabase(Connection $conn) - { - $params = $conn->getParams(); - return $params['dbname']; - } - - /** - * {@inheritdoc} - */ - public function convertExceptionCode(\Exception $exception) - { - return 0; - } } diff --git a/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php b/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php index 27d934cf93d..514ae54fc54 100644 --- a/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php +++ b/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php @@ -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 @@ * @since 2.3 * @author Benjamin Eberlei */ -class SQLSrvConnection implements Connection +class SQLSrvConnection implements Connection, ServerInfoAwareConnection { /** * @var resource @@ -58,6 +59,24 @@ public function __construct($serverName, $connectionOptions) $this->lastInsertId = new LastInsertId(); } + /** + * {@inheritdoc} + */ + public function getServerVersion() + { + $serverInfo = sqlsrv_server_info($this->conn); + + return $serverInfo['SQLServerVersion']; + } + + /** + * {@inheritdoc} + */ + public function requiresQueryForServerVersion() + { + return false; + } + /** * {@inheritDoc} */ diff --git a/lib/Doctrine/DBAL/Driver/ServerInfoAwareConnection.php b/lib/Doctrine/DBAL/Driver/ServerInfoAwareConnection.php new file mode 100644 index 00000000000..f15ffefcbac --- /dev/null +++ b/lib/Doctrine/DBAL/Driver/ServerInfoAwareConnection.php @@ -0,0 +1,44 @@ +. + */ + +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 + * @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(); +} diff --git a/lib/Doctrine/DBAL/Portability/Connection.php b/lib/Doctrine/DBAL/Portability/Connection.php index 17eb2f6bbe4..0ab6589c736 100644 --- a/lib/Doctrine/DBAL/Portability/Connection.php +++ b/lib/Doctrine/DBAL/Portability/Connection.php @@ -65,19 +65,19 @@ public function connect() 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; diff --git a/lib/Doctrine/DBAL/VersionAwarePlatformDriver.php b/lib/Doctrine/DBAL/VersionAwarePlatformDriver.php new file mode 100644 index 00000000000..53e2d3ab781 --- /dev/null +++ b/lib/Doctrine/DBAL/VersionAwarePlatformDriver.php @@ -0,0 +1,47 @@ +. + */ + +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 + * @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); +} diff --git a/tests/Doctrine/Tests/DBAL/ConnectionTest.php b/tests/Doctrine/Tests/DBAL/ConnectionTest.php index 91192333eac..453eefeb913 100644 --- a/tests/Doctrine/Tests/DBAL/ConnectionTest.php +++ b/tests/Doctrine/Tests/DBAL/ConnectionTest.php @@ -8,6 +8,7 @@ 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; + protected $params = array( + 'driver' => 'pdo_mysql', + 'host' => 'localhost', + 'user' => 'root', + 'password' => 'password', + 'port' => '1234' + ); + public function setUp() { - $params = array( - 'driver' => 'pdo_mysql', - 'host' => 'localhost', - 'user' => 'root', - 'password' => 'password', - 'port' => '1234' - ); - $this->_conn = \Doctrine\DBAL\DriverManager::getConnection($params); + $this->_conn = \Doctrine\DBAL\DriverManager::getConnection($this->params); } public function testIsConnected() @@ -119,8 +121,10 @@ public function testConnectDispatchEvent() 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()); } /** diff --git a/tests/Doctrine/Tests/DBAL/Driver/AbstractDB2DriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/AbstractDB2DriverTest.php new file mode 100644 index 00000000000..3b6b9773c06 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/AbstractDB2DriverTest.php @@ -0,0 +1,25 @@ +getMockForAbstractClass('Doctrine\DBAL\Driver\AbstractDB2Driver'); + } + + protected function createPlatform() + { + return new DB2Platform(); + } + + protected function createSchemaManager(Connection $connection) + { + return new DB2SchemaManager($connection); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/AbstractDriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/AbstractDriverTest.php new file mode 100644 index 00000000000..c213d45d349 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/AbstractDriverTest.php @@ -0,0 +1,230 @@ +driver = $this->createDriver(); + } + + public function testConvertsException() + { + if ( ! $this->driver instanceof ExceptionConverterDriver) { + $this->markTestSkipped('This test is only intended for exception converter drivers.'); + } + + $data = $this->getExceptionConversions(); + + if (empty($data)) { + $this->fail( + sprintf( + 'No test data found for test %s. You have to return test data from %s.', + get_class($this) . '::' . __FUNCTION__, + get_class($this) . '::getExceptionConversionData' + ) + ); + } + + $driverException = $this->getMock('Doctrine\DBAL\Driver\DriverException'); + + $driverException->expects($this->any()) + ->method('getErrorCode') + ->will($this->returnValue('foo')); + + $driverException->expects($this->any()) + ->method('getSQLState') + ->will($this->returnValue('bar')); + + $driverException->expects($this->any()) + ->method('getMessage') + ->will($this->returnValue('baz')); + + $data[] = array($driverException, self::EXCEPTION_DRIVER); + + $message = 'DBAL exception message'; + + foreach ($data as $item) { + /** @var $driverException \Doctrine\DBAL\Driver\DriverException */ + list($driverException, $convertedExceptionClassName) = $item; + + $convertedException = $this->driver->convertException($message, $driverException); + + $this->assertSame($convertedExceptionClassName, get_class($convertedException)); + + $this->assertSame($driverException->getErrorCode(), $convertedException->getErrorCode()); + $this->assertSame($driverException->getSQLState(), $convertedException->getSQLState()); + $this->assertSame($message, $convertedException->getMessage()); + } + } + + public function testCreatesDatabasePlatformForVersion() + { + if ( ! $this->driver instanceof VersionAwarePlatformDriver) { + $this->markTestSkipped('This test is only intended for version aware platform drivers.'); + } + + $data = $this->getDatabasePlatformsForVersions(); + + if (empty($data)) { + $this->fail( + sprintf( + 'No test data found for test %s. You have to return test data from %s.', + get_class($this) . '::' . __FUNCTION__, + get_class($this) . '::getDatabasePlatformsForVersions' + ) + ); + } + + foreach ($data as $item) { + $this->assertSame($item[1], get_class($this->driver->createDatabasePlatformForVersion($item[0]))); + } + } + + /** + * @expectedException \Doctrine\DBAL\DBALException + */ + public function testThrowsExceptionOnCreatingDatabasePlatformsForInvalidVersion() + { + if ( ! $this->driver instanceof VersionAwarePlatformDriver) { + $this->markTestSkipped('This test is only intended for version aware platform drivers.'); + } + + $this->driver->createDatabasePlatformForVersion('foo'); + } + + public function testReturnsDatabaseName() + { + $params = array( + 'user' => 'foo', + 'password' => 'bar', + 'dbname' => 'baz', + ); + + $connection = $this->getConnectionMock(); + + $connection->expects($this->once()) + ->method('getParams') + ->will($this->returnValue($params)); + + $this->assertSame($params['dbname'], $this->driver->getDatabase($connection)); + } + + public function testReturnsDatabasePlatform() + { + $this->assertEquals($this->createPlatform(), $this->driver->getDatabasePlatform()); + } + + public function testReturnsSchemaManager() + { + $connection = $this->getConnectionMock(); + $schemaManager = $this->driver->getSchemaManager($connection); + + $this->assertEquals($this->createSchemaManager($connection), $schemaManager); + $this->assertAttributeSame($connection, '_conn', $schemaManager); + } + + /** + * Factory method for creating the driver instance under test. + * + * @return \Doctrine\DBAL\Driver + */ + abstract protected function createDriver(); + + /** + * Factory method for creating the the platform instance return by the driver under test. + * + * The platform instance returned by this method must be the same as returned by + * the driver's getDatabasePlatform() method. + * + * @return \Doctrine\DBAL\Platforms\AbstractPlatform + */ + abstract protected function createPlatform(); + + /** + * Factory method for creating the the schema manager instance return by the driver under test. + * + * The schema manager instance returned by this method must be the same as returned by + * the driver's getSchemaManager() method. + * + * @param Connection $connection The underlying connection to use. + * + * @return \Doctrine\DBAL\Schema\AbstractSchemaManager + */ + abstract protected function createSchemaManager(Connection $connection); + + protected function getConnectionMock() + { + return $this->getMockBuilder('Doctrine\DBAL\Connection') + ->disableOriginalConstructor() + ->getMock(); + } + + protected function getDatabasePlatformsForVersions() + { + return array(); + } + + protected function getExceptionConversionData() + { + return array(); + } + + private function getExceptionConversions() + { + $data = array(); + + foreach ($this->getExceptionConversionData() as $convertedExceptionClassName => $errors) { + foreach ($errors as $error) { + $driverException = $this->getMock('Doctrine\DBAL\Driver\DriverException'); + + $driverException->expects($this->any()) + ->method('getErrorCode') + ->will($this->returnValue($error[0])); + + $driverException->expects($this->any()) + ->method('getSQLState') + ->will($this->returnValue($error[1])); + + $driverException->expects($this->any()) + ->method('getMessage') + ->will($this->returnValue($error[2])); + + $data[] = array($driverException, $convertedExceptionClassName); + } + } + + return $data; + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/AbstractMySQLDriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/AbstractMySQLDriverTest.php new file mode 100644 index 00000000000..bbc215f2575 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/AbstractMySQLDriverTest.php @@ -0,0 +1,136 @@ + 'foo', + 'password' => 'bar', + ); + + $statement = $this->getMock('Doctrine\Tests\Mocks\DriverResultStatementMock'); + + $statement->expects($this->once()) + ->method('fetchColumn') + ->will($this->returnValue($database)); + + $connection = $this->getConnectionMock(); + + $connection->expects($this->once()) + ->method('getParams') + ->will($this->returnValue($params)); + + $connection->expects($this->once()) + ->method('query') + ->will($this->returnValue($statement)); + + $this->assertSame($database, $this->driver->getDatabase($connection)); + } + + protected function createDriver() + { + return $this->getMockForAbstractClass('Doctrine\DBAL\Driver\AbstractMySQLDriver'); + } + + protected function createPlatform() + { + return new MySqlPlatform(); + } + + protected function createSchemaManager(Connection $connection) + { + return new MySqlSchemaManager($connection); + } + + protected function getDatabasePlatformsForVersions() + { + return array( + array('5.6.9', 'Doctrine\DBAL\Platforms\MySqlPlatform'), + array('5.7', 'Doctrine\DBAL\Platforms\MySQL57Platform'), + array('5.7.0', 'Doctrine\DBAL\Platforms\MySQL57Platform'), + array('5.7.1', 'Doctrine\DBAL\Platforms\MySQL57Platform'), + array('6', 'Doctrine\DBAL\Platforms\MySQL57Platform'), + ); + } + + protected function getExceptionConversionData() + { + return array( + self::EXCEPTION_CONNECTION => array( + array('1044', null, null), + array('1045', null, null), + array('1046', null, null), + array('1049', null, null), + array('1095', null, null), + array('1142', null, null), + array('1143', null, null), + array('1227', null, null), + array('1370', null, null), + array('2002', null, null), + array('2005', null, null), + ), + self::EXCEPTION_FOREIGN_KEY_CONSTRAINT_VIOLATION => array( + array('1216', null, null), + array('1217', null, null), + array('1451', null, null), + array('1452', null, null), + ), + self::EXCEPTION_INVALID_FIELD_NAME => array( + array('1054', null, null), + array('1166', null, null), + array('1611', null, null), + ), + self::EXCEPTION_NON_UNIQUE_FIELD_NAME => array( + array('1052', null, null), + array('1060', null, null), + array('1110', null, null), + ), + self::EXCEPTION_NOT_NULL_CONSTRAINT_VIOLATION => array( + array('1048', null, null), + array('1121', null, null), + array('1138', null, null), + array('1171', null, null), + array('1252', null, null), + array('1263', null, null), + array('1566', null, null), + ), + self::EXCEPTION_SYNTAX_ERROR => array( + array('1064', null, null), + array('1149', null, null), + array('1287', null, null), + array('1341', null, null), + array('1342', null, null), + array('1343', null, null), + array('1344', null, null), + array('1382', null, null), + array('1479', null, null), + array('1541', null, null), + array('1554', null, null), + array('1626', null, null), + ), + self::EXCEPTION_TABLE_EXISTS => array( + array('1050', null, null), + ), + self::EXCEPTION_TABLE_NOT_FOUND => array( + array('1051', null, null), + array('1146', null, null), + ), + self::EXCEPTION_UNIQUE_CONSTRAINT_VIOLATION => array( + array('1062', null, null), + array('1557', null, null), + array('1569', null, null), + array('1586', null, null), + ), + ); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/AbstractOracleDriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/AbstractOracleDriverTest.php new file mode 100644 index 00000000000..96a80157116 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/AbstractOracleDriverTest.php @@ -0,0 +1,79 @@ + 'foo', + 'password' => 'bar', + 'dbname' => 'baz', + ); + + $connection = $this->getConnectionMock(); + + $connection->expects($this->once()) + ->method('getParams') + ->will($this->returnValue($params)); + + $this->assertSame($params['user'], $this->driver->getDatabase($connection)); + } + + protected function createDriver() + { + return $this->getMockForAbstractClass('Doctrine\DBAL\Driver\AbstractOracleDriver'); + } + + protected function createPlatform() + { + return new OraclePlatform(); + } + + protected function createSchemaManager(Connection $connection) + { + return new OracleSchemaManager($connection); + } + + protected function getExceptionConversionData() + { + return array( + self::EXCEPTION_CONNECTION => array( + array('1017', null, null), + array('12545', null, null), + ), + self::EXCEPTION_FOREIGN_KEY_CONSTRAINT_VIOLATION => array( + array('2292', null, null), + ), + self::EXCEPTION_INVALID_FIELD_NAME => array( + array('904', null, null), + ), + self::EXCEPTION_NON_UNIQUE_FIELD_NAME => array( + array('918', null, null), + array('960', null, null), + ), + self::EXCEPTION_NOT_NULL_CONSTRAINT_VIOLATION => array( + array('1400', null, null), + ), + self::EXCEPTION_SYNTAX_ERROR => array( + array('923', null, null), + ), + self::EXCEPTION_TABLE_EXISTS => array( + array('955', null, null), + ), + self::EXCEPTION_TABLE_NOT_FOUND => array( + array('942', null, null), + ), + self::EXCEPTION_UNIQUE_CONSTRAINT_VIOLATION => array( + array('1', null, null), + array('2299', null, null), + array('38911', null, null), + ), + ); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/AbstractPostgreSQLDriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/AbstractPostgreSQLDriverTest.php new file mode 100644 index 00000000000..b1df97f95f5 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/AbstractPostgreSQLDriverTest.php @@ -0,0 +1,102 @@ + 'foo', + 'password' => 'bar', + ); + + $statement = $this->getMock('Doctrine\Tests\Mocks\DriverResultStatementMock'); + + $statement->expects($this->once()) + ->method('fetchColumn') + ->will($this->returnValue($database)); + + $connection = $this->getConnectionMock(); + + $connection->expects($this->once()) + ->method('getParams') + ->will($this->returnValue($params)); + + $connection->expects($this->once()) + ->method('query') + ->will($this->returnValue($statement)); + + $this->assertSame($database, $this->driver->getDatabase($connection)); + } + + protected function createDriver() + { + return $this->getMockForAbstractClass('Doctrine\DBAL\Driver\AbstractPostgreSQLDriver'); + } + + protected function createPlatform() + { + return new PostgreSqlPlatform(); + } + + protected function createSchemaManager(Connection $connection) + { + return new PostgreSqlSchemaManager($connection); + } + + protected function getDatabasePlatformsForVersions() + { + return array( + array('9.0.9', 'Doctrine\DBAL\Platforms\PostgreSqlPlatform'), + array('9.1', 'Doctrine\DBAL\Platforms\PostgreSQL91Platform'), + array('9.1.0', 'Doctrine\DBAL\Platforms\PostgreSQL91Platform'), + array('9.1.1', 'Doctrine\DBAL\Platforms\PostgreSQL91Platform'), + array('9.1.9', 'Doctrine\DBAL\Platforms\PostgreSQL91Platform'), + array('9.2', 'Doctrine\DBAL\Platforms\PostgreSQL92Platform'), + array('9.2.0', 'Doctrine\DBAL\Platforms\PostgreSQL92Platform'), + array('9.2.1', 'Doctrine\DBAL\Platforms\PostgreSQL92Platform'), + array('10', 'Doctrine\DBAL\Platforms\PostgreSQL92Platform'), + ); + } + + protected function getExceptionConversionData() + { + return array( + self::EXCEPTION_CONNECTION => array( + array(null, '7', 'SQLSTATE[08006]'), + ), + self::EXCEPTION_FOREIGN_KEY_CONSTRAINT_VIOLATION => array( + array(null, '23503', null), + ), + self::EXCEPTION_INVALID_FIELD_NAME => array( + array(null, '42703', null), + ), + self::EXCEPTION_NON_UNIQUE_FIELD_NAME => array( + array(null, '42702', null), + ), + self::EXCEPTION_NOT_NULL_CONSTRAINT_VIOLATION => array( + array(null, '23502', null), + ), + self::EXCEPTION_SYNTAX_ERROR => array( + array(null, '42601', null), + ), + self::EXCEPTION_TABLE_EXISTS => array( + array(null, '42P07', null), + ), + self::EXCEPTION_TABLE_NOT_FOUND => array( + array(null, '42P01', null), + ), + self::EXCEPTION_UNIQUE_CONSTRAINT_VIOLATION => array( + array(null, '23505', null), + ), + ); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/AbstractSQLAnywhereDriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/AbstractSQLAnywhereDriverTest.php new file mode 100644 index 00000000000..1881319b907 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/AbstractSQLAnywhereDriverTest.php @@ -0,0 +1,98 @@ +getMockForAbstractClass('Doctrine\DBAL\Driver\AbstractSQLAnywhereDriver'); + } + + protected function createPlatform() + { + return new SQLAnywhere12Platform(); + } + + protected function createSchemaManager(Connection $connection) + { + return new SQLAnywhereSchemaManager($connection); + } + + protected function getDatabasePlatformsForVersions() + { + return array( + array('10', 'Doctrine\DBAL\Platforms\SQLAnywherePlatform'), + array('10.0', 'Doctrine\DBAL\Platforms\SQLAnywherePlatform'), + array('10.0.0', 'Doctrine\DBAL\Platforms\SQLAnywherePlatform'), + array('10.0.0.0', 'Doctrine\DBAL\Platforms\SQLAnywherePlatform'), + array('10.1.2.3', 'Doctrine\DBAL\Platforms\SQLAnywherePlatform'), + array('10.9.9.9', 'Doctrine\DBAL\Platforms\SQLAnywherePlatform'), + array('11', 'Doctrine\DBAL\Platforms\SQLAnywhere11Platform'), + array('11.0', 'Doctrine\DBAL\Platforms\SQLAnywhere11Platform'), + array('11.0.0', 'Doctrine\DBAL\Platforms\SQLAnywhere11Platform'), + array('11.0.0.0', 'Doctrine\DBAL\Platforms\SQLAnywhere11Platform'), + array('11.1.2.3', 'Doctrine\DBAL\Platforms\SQLAnywhere11Platform'), + array('11.9.9.9', 'Doctrine\DBAL\Platforms\SQLAnywhere11Platform'), + array('12', 'Doctrine\DBAL\Platforms\SQLAnywhere12Platform'), + array('12.0', 'Doctrine\DBAL\Platforms\SQLAnywhere12Platform'), + array('12.0.0', 'Doctrine\DBAL\Platforms\SQLAnywhere12Platform'), + array('12.0.0.0', 'Doctrine\DBAL\Platforms\SQLAnywhere12Platform'), + array('12.1.2.3', 'Doctrine\DBAL\Platforms\SQLAnywhere12Platform'), + array('12.9.9.9', 'Doctrine\DBAL\Platforms\SQLAnywhere12Platform'), + array('13', 'Doctrine\DBAL\Platforms\SQLAnywhere12Platform'), + array('14', 'Doctrine\DBAL\Platforms\SQLAnywhere12Platform'), + array('15', 'Doctrine\DBAL\Platforms\SQLAnywhere12Platform'), + array('15.9.9.9', 'Doctrine\DBAL\Platforms\SQLAnywhere12Platform'), + array('16', 'Doctrine\DBAL\Platforms\SQLAnywhere16Platform'), + array('16.0', 'Doctrine\DBAL\Platforms\SQLAnywhere16Platform'), + array('16.0.0', 'Doctrine\DBAL\Platforms\SQLAnywhere16Platform'), + array('16.0.0.0', 'Doctrine\DBAL\Platforms\SQLAnywhere16Platform'), + array('16.1.2.3', 'Doctrine\DBAL\Platforms\SQLAnywhere16Platform'), + array('16.9.9.9', 'Doctrine\DBAL\Platforms\SQLAnywhere16Platform'), + array('17', 'Doctrine\DBAL\Platforms\SQLAnywhere16Platform'), + ); + } + + protected function getExceptionConversionData() + { + return array( + self::EXCEPTION_CONNECTION => array( + array('-100', null, null), + array('-103', null, null), + array('-832', null, null), + ), + self::EXCEPTION_FOREIGN_KEY_CONSTRAINT_VIOLATION => array( + array('-198', null, null), + ), + self::EXCEPTION_INVALID_FIELD_NAME => array( + array('-143', null, null), + ), + self::EXCEPTION_NON_UNIQUE_FIELD_NAME => array( + array('-144', null, null), + ), + self::EXCEPTION_NOT_NULL_CONSTRAINT_VIOLATION => array( + array('-184', null, null), + array('-195', null, null), + ), + self::EXCEPTION_SYNTAX_ERROR => array( + array('-131', null, null), + ), + self::EXCEPTION_TABLE_EXISTS => array( + array('-110', null, null), + ), + self::EXCEPTION_TABLE_NOT_FOUND => array( + array('-141', null, null), + array('-1041', null, null), + ), + self::EXCEPTION_UNIQUE_CONSTRAINT_VIOLATION => array( + array('-193', null, null), + array('-196', null, null), + ), + ); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/AbstractSQLServerDriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/AbstractSQLServerDriverTest.php new file mode 100644 index 00000000000..35d2d721a51 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/AbstractSQLServerDriverTest.php @@ -0,0 +1,57 @@ +getMockForAbstractClass('Doctrine\DBAL\Driver\AbstractSQLServerDriver'); + } + + protected function createPlatform() + { + return new SQLServer2008Platform(); + } + + protected function createSchemaManager(Connection $connection) + { + return new SQLServerSchemaManager($connection); + } + + protected function getDatabasePlatformsForVersions() + { + return array( + array('9', 'Doctrine\DBAL\Platforms\SQLServerPlatform'), + array('9.00', 'Doctrine\DBAL\Platforms\SQLServerPlatform'), + array('9.00.0', 'Doctrine\DBAL\Platforms\SQLServerPlatform'), + array('9.00.1398', 'Doctrine\DBAL\Platforms\SQLServerPlatform'), + array('9.00.1398.99', 'Doctrine\DBAL\Platforms\SQLServerPlatform'), + array('9.00.1399', 'Doctrine\DBAL\Platforms\SQLServer2005Platform'), + array('9.00.1399.0', 'Doctrine\DBAL\Platforms\SQLServer2005Platform'), + array('9.00.1399.99', 'Doctrine\DBAL\Platforms\SQLServer2005Platform'), + array('9.00.1400', 'Doctrine\DBAL\Platforms\SQLServer2005Platform'), + array('9.10', 'Doctrine\DBAL\Platforms\SQLServer2005Platform'), + array('9.10.9999', 'Doctrine\DBAL\Platforms\SQLServer2005Platform'), + array('10.00.1599', 'Doctrine\DBAL\Platforms\SQLServer2005Platform'), + array('10.00.1599.99', 'Doctrine\DBAL\Platforms\SQLServer2005Platform'), + array('10.00.1600', 'Doctrine\DBAL\Platforms\SQLServer2008Platform'), + array('10.00.1600.0', 'Doctrine\DBAL\Platforms\SQLServer2008Platform'), + array('10.00.1600.99', 'Doctrine\DBAL\Platforms\SQLServer2008Platform'), + array('10.00.1601', 'Doctrine\DBAL\Platforms\SQLServer2008Platform'), + array('10.10', 'Doctrine\DBAL\Platforms\SQLServer2008Platform'), + array('10.10.9999', 'Doctrine\DBAL\Platforms\SQLServer2008Platform'), + array('11.00.2099', 'Doctrine\DBAL\Platforms\SQLServer2008Platform'), + array('11.00.2099.99', 'Doctrine\DBAL\Platforms\SQLServer2008Platform'), + array('11.00.2100', 'Doctrine\DBAL\Platforms\SQLServer2012Platform'), + array('11.00.2100.0', 'Doctrine\DBAL\Platforms\SQLServer2012Platform'), + array('11.00.2100.99', 'Doctrine\DBAL\Platforms\SQLServer2012Platform'), + array('11.00.2101', 'Doctrine\DBAL\Platforms\SQLServer2012Platform'), + array('12', 'Doctrine\DBAL\Platforms\SQLServer2012Platform'), + ); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/AbstractSQLiteDriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/AbstractSQLiteDriverTest.php new file mode 100644 index 00000000000..537cc48e199 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/AbstractSQLiteDriverTest.php @@ -0,0 +1,77 @@ + 'foo', + 'password' => 'bar', + 'dbname' => 'baz', + 'path' => 'bloo', + ); + + $connection = $this->getConnectionMock(); + + $connection->expects($this->once()) + ->method('getParams') + ->will($this->returnValue($params)); + + $this->assertSame($params['path'], $this->driver->getDatabase($connection)); + } + + protected function createDriver() + { + return $this->getMockForAbstractClass('Doctrine\DBAL\Driver\AbstractSQLiteDriver'); + } + + protected function createPlatform() + { + return new SqlitePlatform(); + } + + protected function createSchemaManager(Connection $connection) + { + return new SqliteSchemaManager($connection); + } + + protected function getExceptionConversionData() + { + return array( + self::EXCEPTION_CONNECTION => array( + array(null, null, 'unable to open database file'), + ), + self::EXCEPTION_INVALID_FIELD_NAME => array( + array(null, null, 'has no column named'), + ), + self::EXCEPTION_NON_UNIQUE_FIELD_NAME => array( + array(null, null, 'ambiguous column name'), + ), + self::EXCEPTION_NOT_NULL_CONSTRAINT_VIOLATION => array( + array(null, null, 'may not be NULL'), + ), + self::EXCEPTION_READ_ONLY => array( + array(null, null, 'attempt to write a readonly database'), + ), + self::EXCEPTION_SYNTAX_ERROR => array( + array(null, null, 'syntax error'), + ), + self::EXCEPTION_TABLE_EXISTS => array( + array(null, null, 'already exists'), + ), + self::EXCEPTION_TABLE_NOT_FOUND => array( + array(null, null, 'no such table:'), + ), + self::EXCEPTION_UNIQUE_CONSTRAINT_VIOLATION => array( + array(null, null, 'must be unique'), + array(null, null, 'is not unique'), + ), + ); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/DrizzlePDOMySql/DriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/DrizzlePDOMySql/DriverTest.php new file mode 100644 index 00000000000..e3b0d17e565 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/DrizzlePDOMySql/DriverTest.php @@ -0,0 +1,46 @@ +assertSame('drizzle_pdo_mysql', $this->driver->getName()); + } + + public function testThrowsExceptionOnCreatingDatabasePlatformsForInvalidVersion() + { + $this->markTestSkipped('This test does not work on Drizzle as it is not version aware.'); + } + + protected function createDriver() + { + return new Driver(); + } + + protected function createPlatform() + { + return new DrizzlePlatform(); + } + + protected function createSchemaManager(Connection $connection) + { + return new DrizzleSchemaManager($connection); + } + + protected function getDatabasePlatformsForVersions() + { + return array( + array('foo', 'Doctrine\DBAL\Platforms\DrizzlePlatform'), + array('bar', 'Doctrine\DBAL\Platforms\DrizzlePlatform'), + array('baz', 'Doctrine\DBAL\Platforms\DrizzlePlatform'), + ); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/IBMDB2/DB2ConnectionTest.php b/tests/Doctrine/Tests/DBAL/Driver/IBMDB2/DB2ConnectionTest.php new file mode 100644 index 00000000000..2042dcac803 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/IBMDB2/DB2ConnectionTest.php @@ -0,0 +1,33 @@ +markTestSkipped('ibm_db2 is not installed.'); + } + + parent::setUp(); + + $this->connectionMock = $this->getMockBuilder('Doctrine\DBAL\Driver\IBMDB2\DB2Connection') + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + } + + public function testDoesNotRequireQueryForServerVersion() + { + $this->assertFalse($this->connectionMock->requiresQueryForServerVersion()); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/IBMDB2/DB2DriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/IBMDB2/DB2DriverTest.php new file mode 100644 index 00000000000..238c2473eb3 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/IBMDB2/DB2DriverTest.php @@ -0,0 +1,19 @@ +assertSame('ibm_db2', $this->driver->getName()); + } + + protected function createDriver() + { + return new DB2Driver(); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/Mysqli/DriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/Mysqli/DriverTest.php new file mode 100644 index 00000000000..0c25a7752bf --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/Mysqli/DriverTest.php @@ -0,0 +1,19 @@ +assertSame('mysqli', $this->driver->getName()); + } + + protected function createDriver() + { + return new Driver(); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/Mysqli/MysqliConnectionTest.php b/tests/Doctrine/Tests/DBAL/Driver/Mysqli/MysqliConnectionTest.php new file mode 100644 index 00000000000..e040ede9911 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/Mysqli/MysqliConnectionTest.php @@ -0,0 +1,33 @@ +markTestSkipped('mysqli is not installed.'); + } + + parent::setUp(); + + $this->connectionMock = $this->getMockBuilder('Doctrine\DBAL\Driver\Mysqli\MysqliConnection') + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + } + + public function testDoesNotRequireQueryForServerVersion() + { + $this->assertFalse($this->connectionMock->requiresQueryForServerVersion()); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/OCI8/DriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/OCI8/DriverTest.php new file mode 100644 index 00000000000..b6a81844fbd --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/OCI8/DriverTest.php @@ -0,0 +1,19 @@ +assertSame('oci8', $this->driver->getName()); + } + + protected function createDriver() + { + return new Driver(); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/OCI8/OCI8ConnectionTest.php b/tests/Doctrine/Tests/DBAL/Driver/OCI8/OCI8ConnectionTest.php new file mode 100644 index 00000000000..658a9b96d5f --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/OCI8/OCI8ConnectionTest.php @@ -0,0 +1,33 @@ +markTestSkipped('oci8 is not installed.'); + } + + parent::setUp(); + + $this->connectionMock = $this->getMockBuilder('Doctrine\DBAL\Driver\OCI8\OCI8Connection') + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + } + + public function testDoesNotRequireQueryForServerVersion() + { + $this->assertFalse($this->connectionMock->requiresQueryForServerVersion()); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/PDOExceptionTest.php b/tests/Doctrine/Tests/DBAL/Driver/PDOExceptionTest.php new file mode 100644 index 00000000000..5d303358627 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/PDOExceptionTest.php @@ -0,0 +1,66 @@ +markTestSkipped('PDO is not installed.'); + } + + parent::setUp(); + + $this->wrappedExceptionMock = $this->getMockBuilder('\PDOException') + ->setConstructorArgs(array(self::MESSAGE, self::SQLSTATE)) + ->getMock(); + + $this->wrappedExceptionMock->errorInfo = array(self::SQLSTATE, self::ERROR_CODE); + + $this->exception = new PDOException($this->wrappedExceptionMock); + } + + public function testReturnsCode() + { + $this->assertSame(self::SQLSTATE, $this->exception->getCode()); + } + + public function testReturnsErrorCode() + { + $this->assertSame(self::ERROR_CODE, $this->exception->getErrorCode()); + } + + public function testReturnsMessage() + { + $this->assertSame(self::MESSAGE, $this->exception->getMessage()); + } + + public function testReturnsSQLState() + { + $this->assertSame(self::SQLSTATE, $this->exception->getSQLState()); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/PDOIbm/DriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/PDOIbm/DriverTest.php new file mode 100644 index 00000000000..28cf9709fee --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/PDOIbm/DriverTest.php @@ -0,0 +1,19 @@ +assertSame('pdo_ibm', $this->driver->getName()); + } + + protected function createDriver() + { + return new Driver(); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/PDOMySql/DriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/PDOMySql/DriverTest.php new file mode 100644 index 00000000000..46be71ccebf --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/PDOMySql/DriverTest.php @@ -0,0 +1,19 @@ +assertSame('pdo_mysql', $this->driver->getName()); + } + + protected function createDriver() + { + return new Driver(); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/PDOOracle/DriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/PDOOracle/DriverTest.php new file mode 100644 index 00000000000..146260524cc --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/PDOOracle/DriverTest.php @@ -0,0 +1,19 @@ +assertSame('pdo_oracle', $this->driver->getName()); + } + + protected function createDriver() + { + return new Driver(); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/PDOPgSql/DriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/PDOPgSql/DriverTest.php new file mode 100644 index 00000000000..d97eae798ce --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/PDOPgSql/DriverTest.php @@ -0,0 +1,19 @@ +assertSame('pdo_pgsql', $this->driver->getName()); + } + + protected function createDriver() + { + return new Driver(); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/PDOSqlite/DriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/PDOSqlite/DriverTest.php new file mode 100644 index 00000000000..f147845555f --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/PDOSqlite/DriverTest.php @@ -0,0 +1,19 @@ +assertSame('pdo_sqlite', $this->driver->getName()); + } + + protected function createDriver() + { + return new Driver(); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/PDOSqlsrv/DriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/PDOSqlsrv/DriverTest.php new file mode 100644 index 00000000000..6a60248a4b0 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/PDOSqlsrv/DriverTest.php @@ -0,0 +1,19 @@ +assertSame('pdo_sqlsrv', $this->driver->getName()); + } + + protected function createDriver() + { + return new Driver(); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/SQLAnywhere/DriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/SQLAnywhere/DriverTest.php new file mode 100644 index 00000000000..9053dce613c --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/SQLAnywhere/DriverTest.php @@ -0,0 +1,19 @@ +assertSame('sqlanywhere', $this->driver->getName()); + } + + protected function createDriver() + { + return new Driver(); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/SQLAnywhere/SQLAnywhereConnectionTest.php b/tests/Doctrine/Tests/DBAL/Driver/SQLAnywhere/SQLAnywhereConnectionTest.php new file mode 100644 index 00000000000..b98a0d02bcd --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/SQLAnywhere/SQLAnywhereConnectionTest.php @@ -0,0 +1,33 @@ +markTestSkipped('sqlanywhere is not installed.'); + } + + parent::setUp(); + + $this->connectionMock = $this->getMockBuilder('Doctrine\DBAL\Driver\SQLAnywhere\SQLAnywhereConnection') + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + } + + public function testRequiresQueryForServerVersion() + { + $this->assertTrue($this->connectionMock->requiresQueryForServerVersion()); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/SQLSrv/DriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/SQLSrv/DriverTest.php new file mode 100644 index 00000000000..cf9f0c08631 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/SQLSrv/DriverTest.php @@ -0,0 +1,19 @@ +assertSame('sqlsrv', $this->driver->getName()); + } + + protected function createDriver() + { + return new Driver(); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Driver/SQLSrv/SQLSrvConnectionTest.php b/tests/Doctrine/Tests/DBAL/Driver/SQLSrv/SQLSrvConnectionTest.php new file mode 100644 index 00000000000..807815a93d0 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Driver/SQLSrv/SQLSrvConnectionTest.php @@ -0,0 +1,33 @@ +markTestSkipped('sqlsrv is not installed.'); + } + + parent::setUp(); + + $this->connectionMock = $this->getMockBuilder('Doctrine\DBAL\Driver\SQLSrv\SQLSrvConnection') + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + } + + public function testDoesNotRequireQueryForServerVersion() + { + $this->assertFalse($this->connectionMock->requiresQueryForServerVersion()); + } +} diff --git a/tests/Doctrine/Tests/DBAL/Functional/Mysqli/ConnectionTest.php b/tests/Doctrine/Tests/DBAL/Functional/Driver/Mysqli/ConnectionTest.php similarity index 96% rename from tests/Doctrine/Tests/DBAL/Functional/Mysqli/ConnectionTest.php rename to tests/Doctrine/Tests/DBAL/Functional/Driver/Mysqli/ConnectionTest.php index ec25e5b78cf..8ed62711b15 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Mysqli/ConnectionTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Driver/Mysqli/ConnectionTest.php @@ -1,5 +1,5 @@ markTestSkipped('PDO is not installed.'); + } + + parent::setUp(); + + $this->driverConnection = $this->_conn->getWrappedConnection(); + + if ( ! $this->_conn->getWrappedConnection() instanceof PDOConnection) { + $this->markTestSkipped('PDO connection only test.'); + } + } + + public function testDoesNotRequireQueryForServerVersion() + { + $this->assertFalse($this->driverConnection->requiresQueryForServerVersion()); + } +} diff --git a/tests/Doctrine/Tests/Mocks/ConnectionMock.php b/tests/Doctrine/Tests/Mocks/ConnectionMock.php index 9c765dca798..6694d19f4d4 100644 --- a/tests/Doctrine/Tests/Mocks/ConnectionMock.php +++ b/tests/Doctrine/Tests/Mocks/ConnectionMock.php @@ -69,11 +69,6 @@ public function setFetchOneResult($fetchOneResult) $this->_fetchOneResult = $fetchOneResult; } - public function setDatabasePlatform($platform) - { - $this->_platformMock = $platform; - } - public function setLastInsertId($id) { $this->_lastInsertId = $id; diff --git a/tests/Doctrine/Tests/Mocks/DriverResultStatementMock.php b/tests/Doctrine/Tests/Mocks/DriverResultStatementMock.php new file mode 100644 index 00000000000..04c085c7459 --- /dev/null +++ b/tests/Doctrine/Tests/Mocks/DriverResultStatementMock.php @@ -0,0 +1,9 @@ + $GLOBALS['db_type'], 'user' => $GLOBALS['db_username'], @@ -51,7 +51,7 @@ public static function getConnection() '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 @@ public static function getConnection() $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 @@ public static function getConnection() $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); diff --git a/tests/travis/pgsql.travis.xml b/tests/travis/pgsql.travis.xml index e3bd7ead590..1c34404f76d 100644 --- a/tests/travis/pgsql.travis.xml +++ b/tests/travis/pgsql.travis.xml @@ -12,7 +12,6 @@ -