Skip to content

Commit

Permalink
fixes #990: try platform detection without database name as fallback
Browse files Browse the repository at this point in the history
  • Loading branch information
deeky666 committed Mar 9, 2017
1 parent c2bf5fb commit b3a9479
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 1 deletion.
39 changes: 38 additions & 1 deletion lib/Doctrine/DBAL/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -425,9 +425,46 @@ 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();
}

private function getServerVersion()
{
// Automatic platform version detection.
if ($this->_conn instanceof ServerInfoAwareConnection &&
! $this->_conn->requiresQueryForServerVersion()
Expand Down
25 changes: 25 additions & 0 deletions tests/Doctrine/Tests/DBAL/ConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -670,4 +670,29 @@ public function testPlatformDetectionIsTriggerOnlyOnceOnRetrievingPlatform()

$this->assertSame($platformMock, $connection->getDatabasePlatform());
}

/**
* @group DBAL-990
*/
public function testRethrowsOriginalExceptionOnDeterminingPlatformWhenConnectingToNonExistentDatabase()
{
/** @var \Doctrine\Tests\Mocks\VersionAwarePlatformDriverMock|\PHPUnit_Framework_MockObject_MockObject $driverMock */
$driverMock = $this->createMock('Doctrine\Tests\Mocks\VersionAwarePlatformDriverMock');

$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();
}
}
25 changes: 25 additions & 0 deletions tests/Doctrine/Tests/DBAL/Functional/ConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -272,4 +272,29 @@ public function testConnectWithoutExplicitDatabaseName()

$connection->close();
}

/**
* @group DBAL-990
*/
public function testDeterminesDatabasePlatformWhenConnectingToNonExistentDatabase()
{
if (in_array($this->_conn->getDatabasePlatform()->getName(), array('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('Doctrine\DBAL\Platforms\AbstractPlatform', $connection->getDatabasePlatform());
$this->assertFalse($connection->isConnected());
$this->assertSame($params, $connection->getParams());

$connection->close();
}
}

0 comments on commit b3a9479

Please sign in to comment.