-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use exception in OCI8 driver, instead of relying on assert #6596
base: 4.2.x
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Doctrine\DBAL\Tests\Driver\OCI8; | ||
|
||
use Doctrine\DBAL\Exception\DriverException; | ||
use Doctrine\DBAL\Tests\FunctionalTestCase; | ||
use Doctrine\DBAL\Tests\TestUtil; | ||
use PHPUnit\Framework\Attributes\RequiresPhpExtension; | ||
use RuntimeException; | ||
use Throwable; | ||
|
||
use function is_resource; | ||
use function oci_close; | ||
use function oci_connect; | ||
use function oci_execute; | ||
use function oci_parse; | ||
|
||
#[RequiresPhpExtension('oci8')] | ||
class ConnectionTest extends FunctionalTestCase | ||
{ | ||
public function tearDown(): void | ||
{ | ||
$this->connection->close(); | ||
} | ||
|
||
public function testPrepareThrowsErrorOnConnectionLost(): void | ||
{ | ||
$this->expectException(DriverException::class); | ||
|
||
$this->killCurrentSession(); | ||
|
||
$this->connection->prepare('SELECT * FROM 1'); | ||
} | ||
|
||
/** | ||
* Get the session details | ||
* | ||
* @return array<string, mixed>|false | ||
*/ | ||
private function getCurrentSession(): array|false | ||
{ | ||
$stmt = $this->connection->prepare(" | ||
SELECT SID, SERIAL# | ||
FROM V\$SESSION | ||
WHERE AUDSID = USERENV('SESSIONID') | ||
"); | ||
|
||
return $stmt->executeQuery()->fetchAssociative(); | ||
} | ||
|
||
/** | ||
* 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 | ||
{ | ||
$secondConnection = false; | ||
|
||
try { | ||
$session = $this->getCurrentSession(); | ||
if ($session === false || ! isset($session['SID'], $session['SERIAL#'])) { | ||
return; | ||
} | ||
|
||
$params = TestUtil::getConnectionParams(); | ||
$username = $params['user'] ?? ''; | ||
$password = $params['password'] ?? ''; | ||
$host = $params['host'] ?? ''; | ||
|
||
$secondConnection = oci_connect($username, $password, $host); | ||
if ($secondConnection === false) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use DBAL, if possible. I feel like the amount of boilerplate code will reduce. |
||
throw new RuntimeException('Unable to establish secondary connection for session termination.'); | ||
} | ||
|
||
$killStmt = oci_parse( | ||
$secondConnection, | ||
'ALTER SYSTEM DISCONNECT SESSION \'' . $session['SID'] . ',' . $session['SERIAL#'] . '\' IMMEDIATE', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please bind parameters to the statement instead of concatenation. Even though it may be safe in this case, it sets a bad example. |
||
); | ||
|
||
if ($killStmt !== false) { | ||
oci_execute($killStmt); | ||
} | ||
} finally { | ||
if (is_resource($secondConnection)) { | ||
oci_close($secondConnection); | ||
} | ||
} | ||
|
||
// Trigger reconnection in OCI driver by executing invalid statement | ||
try { | ||
$stmt = $this->connection->prepare('INVALID SQL'); | ||
$stmt->executeQuery(); | ||
} catch (Throwable) { | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move under
Tests\Functional
.