1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\Tests\Functional\Driver\OCI8;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Exception\DriverException;
use Doctrine\DBAL\Tests\FunctionalTestCase;
use Doctrine\DBAL\Tests\TestUtil;
use Throwable;
class ConnectionTest extends FunctionalTestCase
{
public static function setUpBeforeClass(): void
{
if (TestUtil::isDriverOneOf('oci8')) {
return;
}
self::markTestSkipped('This test requires the oci8 driver.');
}
public function testPrepareThrowsErrorOnConnectionLost(): void
{
$this->markConnectionNotReusable();
$this->killCurrentSession();
$this->expectException(DriverException::class);
$this->connection->prepare('SELECT * FROM 1');
}
/**
* Kill the current session, by using another connection
* Oracle doesn't allow you to terminate the current session, so we use a second connection
*/
private function killCurrentSession(): void
{
$row = $this->connection->fetchNumeric(
<<<'SQL'
SELECT SID, SERIAL#
FROM V$SESSION
WHERE AUDSID = USERENV('SESSIONID')
SQL,
);
self::assertNotFalse($row);
[$sid, $serialNumber] = $row;
self::assertNotNull($sid, 'SID is missing.');
self::assertNotNull($serialNumber, 'Serial number is missing.');
$params = TestUtil::getConnectionParams();
$params['driverOptions']['exclusive'] = true;
$secondConnection = DriverManager::getConnection($params);
$sessionParam = $this->connection->quote($sid . ', ' . $serialNumber);
$secondConnection->executeStatement('ALTER SYSTEM DISCONNECT SESSION ' . $sessionParam . ' IMMEDIATE');
// Ensure OCI driver is aware of connection state change by executing any statement
try {
$this->connection->executeStatement('INVALID SQL');
} catch (Throwable) {
}
}
}
|