Skip to content

Commit

Permalink
fixes doctrine#990: try platform detection without database name as f…
Browse files Browse the repository at this point in the history
…allback
  • Loading branch information
deeky666 committed May 10, 2017
1 parent c48effb commit d458023
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 1 deletion.
44 changes: 43 additions & 1 deletion lib/Doctrine/DBAL/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -425,9 +425,51 @@ private function getDatabasePlatformVersion()

// If not connected, we need to connect now to determine the platform version.
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.
if ($this->_conn instanceof ServerInfoAwareConnection &&
! $this->_conn->requiresQueryForServerVersion()
Expand Down
26 changes: 26 additions & 0 deletions tests/Doctrine/Tests/DBAL/ConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Doctrine\Tests\Mocks\DriverConnectionMock;
use Doctrine\Tests\Mocks\DriverMock;
use Doctrine\DBAL\Cache\ArrayStatement;
use Doctrine\Tests\Mocks\VersionAwarePlatformDriverMock;

class ConnectionTest extends \Doctrine\Tests\DbalTestCase
{
Expand Down Expand Up @@ -712,4 +713,29 @@ public function testConnectionParamsArePassedToTheQueryCacheProfileInExecuteCach
(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();
}
}
26 changes: 26 additions & 0 deletions tests/Doctrine/Tests/DBAL/Functional/ConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Doctrine\DBAL\ConnectionException;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type;

class ConnectionTest extends \Doctrine\Tests\DbalFunctionalTestCase
Expand Down Expand Up @@ -272,4 +273,29 @@ public function testConnectWithoutExplicitDatabaseName()

$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();
}
}

0 comments on commit d458023

Please sign in to comment.