mirror of
https://github.com/Vateron-Media/XC_VM.git
synced 2026-10-26 11:03:14 +01:00
DatabaseHandler connects in its constructor, so every
DatabaseFactory::connect() in live/vod/timeshift and the shutdown handler
opened a MySQL connection to MAIN whether or not a query followed. The
cluster API plan counts every such connect before a node may leave the
legacy link.
LazyDatabaseHandler connects on the first query, simple_query, escape or
transaction and otherwise behaves like the eager handler, failure
included; DatabaseFactory::connectLazy() hands it out and keeps an
unopened one instead of replacing it. The streaming endpoints use it
(LazyDatabaseHandlerTest). Phase 0 seam.
Also replace call_user_func_array('parent::query', ...) in
DatabaseHandler::query() with parent::query(...func_get_args()): callable
strings using "parent" are deprecated since PHP 8.2.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Es8UhyPS8MNjuYTagqfGWi
75 lines
2.6 KiB
PHP
75 lines
2.6 KiB
PHP
<?php
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
use XcVm\Core\Database\LazyDatabaseHandler;
|
|
use XcVm\Infrastructure\Database\DatabaseFactory;
|
|
|
|
/**
|
|
* Streaming endpoints get a LazyDatabaseHandler: no MySQL connection to MAIN
|
|
* until the first query, so a request answered from cache or Redis opens none.
|
|
* The real connect goes through the xcvm_core extension; here it is replaced
|
|
* by an in-memory SQLite PDO that counts how often it is opened.
|
|
*/
|
|
final class LazyDatabaseHandlerTest extends TestCase {
|
|
|
|
private function handler(): LazyDatabaseHandler {
|
|
return new class extends LazyDatabaseHandler {
|
|
public int $rOpens = 0;
|
|
|
|
public function db_connect(bool $migrate = false, ?bool $graceful = null) {
|
|
$this->rOpens++;
|
|
$this->dbh = new \PDO('sqlite::memory:');
|
|
$this->dbh->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
|
$this->connected = true;
|
|
return true;
|
|
}
|
|
};
|
|
}
|
|
|
|
protected function tearDown(): void {
|
|
DatabaseFactory::reset();
|
|
unset($GLOBALS['db']);
|
|
}
|
|
|
|
public function testNothingOpensUntilTheFirstQuery(): void {
|
|
$rDb = $this->handler();
|
|
$this->assertFalse($rDb->isOpen());
|
|
$this->assertTrue($rDb->ping(), 'an unopened handle is usable, not dead');
|
|
$this->assertSame(0, $rDb->rOpens);
|
|
|
|
$this->assertTrue($rDb->query('SELECT 1 AS `one`'));
|
|
$this->assertSame(1, $rDb->rOpens);
|
|
$this->assertInstanceOf(\PDO::class, $rDb->dbh);
|
|
$rDb->query('SELECT ? AS `two`', 2);
|
|
$this->assertSame(1, $rDb->rOpens, 'opened once');
|
|
$this->assertTrue($rDb->isOpen());
|
|
}
|
|
|
|
public function testEscapeAndTransactionsOpenToo(): void {
|
|
$rDb = $this->handler();
|
|
$this->assertSame("'x'", $rDb->escape('x'));
|
|
$this->assertSame(1, $rDb->rOpens);
|
|
|
|
$rTx = $this->handler();
|
|
$this->assertTrue($rTx->beginTransaction());
|
|
$this->assertSame(1, $rTx->rOpens);
|
|
$rTx->rollback();
|
|
}
|
|
|
|
public function testConnectLazyKeepsAnUnopenedHandle(): void {
|
|
$GLOBALS['db'] = $this->handler();
|
|
DatabaseFactory::connectLazy();
|
|
$this->assertSame($GLOBALS['db'], DatabaseFactory::get());
|
|
$this->assertSame(0, $GLOBALS['db']->rOpens, 'reused, not replaced, not opened');
|
|
}
|
|
|
|
public function testStreamingEndpointsUseTheLazyHandler(): void {
|
|
$rRoot = dirname(__DIR__, 2) . '/src/';
|
|
foreach (['Public/stream/live.php', 'Public/stream/vod.php', 'Public/stream/timeshift.php', 'Streaming/Lifecycle/ShutdownHandler.php'] as $rFile) {
|
|
$rSource = (string) file_get_contents($rRoot . $rFile);
|
|
$this->assertStringContainsString('DatabaseFactory::connectLazy();', $rSource, $rFile);
|
|
$this->assertStringNotContainsString('DatabaseFactory::connect();', $rSource, $rFile);
|
|
}
|
|
}
|
|
}
|