Commit 77ba61e5 authored by Marco Pivetta's avatar Marco Pivetta Committed by GitHub

Merge pull request #2671 from deeky666/DBAL-990

[DBAL-990] Try platform detection without database name as fallback
parents c48effb6 d4580237
...@@ -425,9 +425,51 @@ class Connection implements DriverConnection ...@@ -425,9 +425,51 @@ class Connection implements DriverConnection
// If not connected, we need to connect now to determine the platform version. // If not connected, we need to connect now to determine the platform version.
if (null === $this->_conn) { if (null === $this->_conn) {
$this->connect(); try {
$this->connect();
} catch (\Exception $originalException) {
if (empty($this->_params['dbname'])) {
throw $originalException;
}
// The database to connect to might not yet exist.
// Retry detection without database name connection parameter.
$databaseName = $this->_params['dbname'];
$this->_params['dbname'] = null;
try {
$this->connect();
} catch (\Exception $fallbackException) {
// Either the platform does not support database-less connections
// or something else went wrong.
// Reset connection parameters and rethrow the original exception.
$this->_params['dbname'] = $databaseName;
throw $originalException;
}
// Reset connection parameters.
$this->_params['dbname'] = $databaseName;
$serverVersion = $this->getServerVersion();
// Close "temporary" connection to allow connecting to the real database again.
$this->close();
return $serverVersion;
}
} }
return $this->getServerVersion();
}
/**
* Returns the database server version if the underlying driver supports it.
*
* @return string|null
*/
private function getServerVersion()
{
// Automatic platform version detection. // Automatic platform version detection.
if ($this->_conn instanceof ServerInfoAwareConnection && if ($this->_conn instanceof ServerInfoAwareConnection &&
! $this->_conn->requiresQueryForServerVersion() ! $this->_conn->requiresQueryForServerVersion()
......
...@@ -12,6 +12,7 @@ use Doctrine\DBAL\Events; ...@@ -12,6 +12,7 @@ use Doctrine\DBAL\Events;
use Doctrine\Tests\Mocks\DriverConnectionMock; use Doctrine\Tests\Mocks\DriverConnectionMock;
use Doctrine\Tests\Mocks\DriverMock; use Doctrine\Tests\Mocks\DriverMock;
use Doctrine\DBAL\Cache\ArrayStatement; use Doctrine\DBAL\Cache\ArrayStatement;
use Doctrine\Tests\Mocks\VersionAwarePlatformDriverMock;
class ConnectionTest extends \Doctrine\Tests\DbalTestCase class ConnectionTest extends \Doctrine\Tests\DbalTestCase
{ {
...@@ -712,4 +713,29 @@ class ConnectionTest extends \Doctrine\Tests\DbalTestCase ...@@ -712,4 +713,29 @@ class ConnectionTest extends \Doctrine\Tests\DbalTestCase
(new Connection($this->params, $driver))->executeCacheQuery($query, $params, $types, $queryCacheProfileMock) (new Connection($this->params, $driver))->executeCacheQuery($query, $params, $types, $queryCacheProfileMock)
); );
} }
/**
* @group DBAL-990
*/
public function testRethrowsOriginalExceptionOnDeterminingPlatformWhenConnectingToNonExistentDatabase()
{
/** @var \Doctrine\Tests\Mocks\VersionAwarePlatformDriverMock|\PHPUnit_Framework_MockObject_MockObject $driverMock */
$driverMock = $this->createMock(VersionAwarePlatformDriverMock::class);
$connection = new Connection(array('dbname' => 'foo'), $driverMock);
$originalException = new \Exception('Original exception');
$fallbackException = new \Exception('Fallback exception');
$driverMock->expects($this->at(0))
->method('connect')
->willThrowException($originalException);
$driverMock->expects($this->at(1))
->method('connect')
->willThrowException($fallbackException);
$this->expectExceptionMessage($originalException->getMessage());
$connection->getDatabasePlatform();
}
} }
...@@ -4,6 +4,7 @@ namespace Doctrine\Tests\DBAL\Functional; ...@@ -4,6 +4,7 @@ namespace Doctrine\Tests\DBAL\Functional;
use Doctrine\DBAL\ConnectionException; use Doctrine\DBAL\ConnectionException;
use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Type;
class ConnectionTest extends \Doctrine\Tests\DbalFunctionalTestCase class ConnectionTest extends \Doctrine\Tests\DbalFunctionalTestCase
...@@ -272,4 +273,29 @@ class ConnectionTest extends \Doctrine\Tests\DbalFunctionalTestCase ...@@ -272,4 +273,29 @@ class ConnectionTest extends \Doctrine\Tests\DbalFunctionalTestCase
$connection->close(); $connection->close();
} }
/**
* @group DBAL-990
*/
public function testDeterminesDatabasePlatformWhenConnectingToNonExistentDatabase()
{
if (in_array($this->_conn->getDatabasePlatform()->getName(), ['oracle', 'db2'], true)) {
$this->markTestSkipped('Platform does not support connecting without database name.');
}
$params = $this->_conn->getParams();
$params['dbname'] = 'foo_bar';
$connection = DriverManager::getConnection(
$params,
$this->_conn->getConfiguration(),
$this->_conn->getEventManager()
);
$this->assertInstanceOf(AbstractPlatform::class, $connection->getDatabasePlatform());
$this->assertFalse($connection->isConnected());
$this->assertSame($params, $connection->getParams());
$connection->close();
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment