mirror of https://github.com/flightphp/core
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
212 lines
7.5 KiB
212 lines
7.5 KiB
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace tests;
|
|
|
|
use flight\database\PdoWrapper;
|
|
use flight\core\EventDispatcher;
|
|
use PDOStatement;
|
|
use PHPUnit\Framework\TestCase;
|
|
use ReflectionClass;
|
|
|
|
class PdoWrapperTest extends TestCase
|
|
{
|
|
private PdoWrapper $pdo_wrapper;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->pdo_wrapper = new PdoWrapper('sqlite::memory:');
|
|
// create a test table and insert 3 rows of data
|
|
$this->pdo_wrapper->exec('CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)');
|
|
$this->pdo_wrapper->exec('INSERT INTO test (name) VALUES ("one")');
|
|
$this->pdo_wrapper->exec('INSERT INTO test (name) VALUES ("two")');
|
|
$this->pdo_wrapper->exec('INSERT INTO test (name) VALUES ("three")');
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
// delete the test table
|
|
$this->pdo_wrapper->exec('DROP TABLE test');
|
|
}
|
|
|
|
public function testRunQuerySelectAllStatement()
|
|
{
|
|
$statement = $this->pdo_wrapper->runQuery('SELECT * FROM test');
|
|
$this->assertInstanceOf(PDOStatement::class, $statement);
|
|
$this->assertCount(3, $statement->fetchAll());
|
|
}
|
|
|
|
public function testRunQuerySelectOneStatement()
|
|
{
|
|
$statement = $this->pdo_wrapper->runQuery('SELECT * FROM test WHERE id = 1');
|
|
$this->assertInstanceOf(PDOStatement::class, $statement);
|
|
$this->assertCount(1, $statement->fetchAll());
|
|
}
|
|
|
|
public function testRunQueryInsertStatement()
|
|
{
|
|
$statement = $this->pdo_wrapper->runQuery('INSERT INTO test (name) VALUES ("four")');
|
|
$this->assertInstanceOf(PDOStatement::class, $statement);
|
|
$this->assertEquals(1, $statement->rowCount());
|
|
}
|
|
|
|
public function testRunQueryUpdateStatement()
|
|
{
|
|
$statement = $this->pdo_wrapper->runQuery('UPDATE test SET name = "something" WHERE name LIKE ?', ['%t%']);
|
|
$this->assertInstanceOf(PDOStatement::class, $statement);
|
|
$this->assertEquals(2, $statement->rowCount());
|
|
}
|
|
|
|
public function testRunQueryDeleteStatement()
|
|
{
|
|
$statement = $this->pdo_wrapper->runQuery('DELETE FROM test WHERE name LIKE ?', ['%t%']);
|
|
$this->assertInstanceOf(PDOStatement::class, $statement);
|
|
$this->assertEquals(2, $statement->rowCount());
|
|
}
|
|
|
|
public function testFetchField()
|
|
{
|
|
$id = $this->pdo_wrapper->fetchField('SELECT id FROM test WHERE name = ?', ['two']);
|
|
$this->assertEquals(2, $id);
|
|
}
|
|
|
|
public function testFetchRow()
|
|
{
|
|
$row = $this->pdo_wrapper->fetchRow('SELECT * FROM test WHERE name = ?', ['two']);
|
|
$this->assertEquals(2, $row['id']);
|
|
$this->assertEquals('two', $row['name']);
|
|
}
|
|
|
|
public function testFetchAll()
|
|
{
|
|
$rows = $this->pdo_wrapper->fetchAll('SELECT * FROM test');
|
|
$this->assertCount(3, $rows);
|
|
$this->assertEquals(1, $rows[0]['id']);
|
|
$this->assertEquals('one', $rows[0]['name']);
|
|
$this->assertEquals(2, $rows[1]['id']);
|
|
$this->assertEquals('two', $rows[1]['name']);
|
|
$this->assertEquals(3, $rows[2]['id']);
|
|
$this->assertEquals('three', $rows[2]['name']);
|
|
}
|
|
|
|
public function testFetchAllNoRows()
|
|
{
|
|
$rows = $this->pdo_wrapper->fetchAll('SELECT * FROM test WHERE 1 = 2');
|
|
$this->assertCount(0, $rows);
|
|
$this->assertSame([], $rows);
|
|
}
|
|
|
|
public function testFetchAllWithNamedParams()
|
|
{
|
|
$rows = $this->pdo_wrapper->fetchAll('SELECT * FROM test WHERE name = :name', [ 'name' => 'two']);
|
|
$this->assertCount(1, $rows);
|
|
$this->assertEquals(2, $rows[0]['id']);
|
|
$this->assertEquals('two', $rows[0]['name']);
|
|
}
|
|
|
|
public function testFetchAllWithInInt()
|
|
{
|
|
$rows = $this->pdo_wrapper->fetchAll('SELECT id FROM test WHERE id IN(? )', [ [1,2 ]]);
|
|
$this->assertEquals(2, count($rows));
|
|
}
|
|
|
|
public function testFetchAllWithInString()
|
|
{
|
|
$rows = $this->pdo_wrapper->fetchAll('SELECT id FROM test WHERE name IN(?)', [ ['one','two' ]]);
|
|
$this->assertEquals(2, count($rows));
|
|
}
|
|
|
|
public function testFetchAllWithInStringCommas()
|
|
{
|
|
$rows = $this->pdo_wrapper->fetchAll('SELECT id FROM test WHERE id > ? AND name IN( ?) ', [ 0, 'one,two' ]);
|
|
$this->assertEquals(2, count($rows));
|
|
}
|
|
|
|
public function testPullDataFromDsn()
|
|
{
|
|
// Testing protected method using reflection
|
|
$reflection = new ReflectionClass($this->pdo_wrapper);
|
|
$method = $reflection->getMethod('pullDataFromDsn');
|
|
$method->setAccessible(true);
|
|
|
|
// Test SQLite DSN
|
|
$sqliteDsn = 'sqlite::memory:';
|
|
$sqliteResult = $method->invoke($this->pdo_wrapper, $sqliteDsn);
|
|
$this->assertEquals([
|
|
'engine' => 'sqlite',
|
|
'database' => ':memory:',
|
|
'host' => 'localhost'
|
|
], $sqliteResult);
|
|
|
|
// Test MySQL DSN
|
|
$mysqlDsn = 'mysql:host=localhost;dbname=testdb;charset=utf8';
|
|
$mysqlResult = $method->invoke($this->pdo_wrapper, $mysqlDsn);
|
|
$this->assertEquals([
|
|
'engine' => 'mysql',
|
|
'database' => 'testdb',
|
|
'host' => 'localhost'
|
|
], $mysqlResult);
|
|
|
|
// Test PostgreSQL DSN
|
|
$pgsqlDsn = 'pgsql:host=127.0.0.1;dbname=postgres';
|
|
$pgsqlResult = $method->invoke($this->pdo_wrapper, $pgsqlDsn);
|
|
$this->assertEquals([
|
|
'engine' => 'pgsql',
|
|
'database' => 'postgres',
|
|
'host' => '127.0.0.1'
|
|
], $pgsqlResult);
|
|
}
|
|
|
|
public function testLogQueries()
|
|
{
|
|
// Create a new PdoWrapper with tracking enabled
|
|
$trackingPdo = new PdoWrapper('sqlite::memory:', null, null, null, true);
|
|
|
|
// Create test table
|
|
$trackingPdo->exec('CREATE TABLE test_log (id INTEGER PRIMARY KEY, name TEXT)');
|
|
|
|
// Run some queries to populate metrics
|
|
$trackingPdo->runQuery('INSERT INTO test_log (name) VALUES (?)', ['test1']);
|
|
$trackingPdo->fetchAll('SELECT * FROM test_log');
|
|
|
|
// Setup event listener to capture triggered event
|
|
$eventTriggered = false;
|
|
$connectionData = null;
|
|
$queriesData = null;
|
|
|
|
$dispatcher = EventDispatcher::getInstance();
|
|
$dispatcher->on('flight.db.queries', function ($conn, $queries) use (&$eventTriggered, &$connectionData, &$queriesData) {
|
|
$eventTriggered = true;
|
|
$connectionData = $conn;
|
|
$queriesData = $queries;
|
|
});
|
|
|
|
// Call the logQueries method
|
|
$trackingPdo->logQueries();
|
|
|
|
// Assert that event was triggered
|
|
$this->assertTrue($eventTriggered);
|
|
$this->assertIsArray($connectionData);
|
|
$this->assertEquals('sqlite', $connectionData['engine']);
|
|
$this->assertIsArray($queriesData);
|
|
$this->assertCount(2, $queriesData); // Should have 2 queries (INSERT and SELECT)
|
|
|
|
// Verify query metrics structure for the first query
|
|
$this->assertArrayHasKey('sql', $queriesData[0]);
|
|
$this->assertArrayHasKey('params', $queriesData[0]);
|
|
$this->assertArrayHasKey('execution_time', $queriesData[0]);
|
|
$this->assertArrayHasKey('row_count', $queriesData[0]);
|
|
$this->assertArrayHasKey('memory_usage', $queriesData[0]);
|
|
|
|
// Clean up
|
|
$trackingPdo->exec('DROP TABLE test_log');
|
|
|
|
// Verify metrics are reset after logging
|
|
$reflection = new ReflectionClass($trackingPdo);
|
|
$property = $reflection->getProperty('queryMetrics');
|
|
$property->setAccessible(true);
|
|
$this->assertCount(0, $property->getValue($trackingPdo));
|
|
}
|
|
}
|