fix: DockerSecretsResolver - don't normalize absolute paths like /var/www/html/...
Some checks failed
Deploy Application / deploy (push) Has been cancelled

This commit is contained in:
2025-11-24 21:28:25 +01:00
parent 4eb7134853
commit 77abc65cd7
1327 changed files with 91915 additions and 9909 deletions

View File

@@ -5,15 +5,20 @@ declare(strict_types=1);
namespace App\Framework\Database\Browser\Discovery;
use App\Framework\Database\Browser\ValueObjects\TableMetadata;
use App\Framework\Database\ConnectionInterface;
use App\Framework\Database\DatabaseManager;
use App\Framework\Database\ValueObjects\SqlQuery;
final readonly class TableDiscovery
{
public function __construct(
private ConnectionInterface $connection
private DatabaseManager $databaseManager
) {
}
private function getConnection(): \App\Framework\Database\ConnectionInterface
{
return $this->databaseManager->getConnection();
}
/**
* Discover all tables in the current database
@@ -21,6 +26,72 @@ final readonly class TableDiscovery
* @return array<TableMetadata>
*/
public function discoverAllTables(): array
{
$driver = $this->getDriver();
if ($driver === 'pgsql') {
return $this->discoverPostgreSQLTables();
}
return $this->discoverMySQLTables();
}
/**
* Discover PostgreSQL tables
*/
private function discoverPostgreSQLTables(): array
{
$sql = "
SELECT
t.tablename as table_name,
COALESCE(s.n_live_tup::bigint, 0) as estimated_rows,
ROUND(pg_total_relation_size('public.'||t.tablename) / 1024.0 / 1024.0, 2) as size_mb,
NULL as engine,
NULL as table_collation
FROM pg_tables t
LEFT JOIN pg_stat_user_tables s ON s.relname = t.tablename
WHERE t.schemaname = 'public'
ORDER BY t.tablename
";
$query = SqlQuery::create($sql, []);
$result = $this->getConnection()->query($query);
$tables = $result->fetchAll();
$tableMetadata = [];
foreach ($tables as $tableData) {
$estimatedRows = isset($tableData['estimated_rows']) && $tableData['estimated_rows'] !== null ? (int) $tableData['estimated_rows'] : 0;
// For small tables (< 1000 estimated rows), get exact count
// This ensures accuracy for small tables where pg_stat_user_tables might be outdated
$rowCount = $estimatedRows;
if ($estimatedRows < 1000) {
try {
$countQuery = SqlQuery::create("SELECT COUNT(*) FROM \"{$tableData['table_name']}\"", []);
$exactCount = $this->getConnection()->queryScalar($countQuery);
$rowCount = $exactCount !== null ? (int) $exactCount : $estimatedRows;
} catch (\Throwable $e) {
// If exact count fails, fall back to estimated count
$rowCount = $estimatedRows;
}
}
$tableMetadata[] = new TableMetadata(
name: $tableData['table_name'],
rowCount: $rowCount,
sizeMb: isset($tableData['size_mb']) ? (float) $tableData['size_mb'] : null,
engine: null, // PostgreSQL doesn't have engine concept
collation: null, // PostgreSQL collation is per-column, not per-table
);
}
return $tableMetadata;
}
/**
* Discover MySQL tables
*/
private function discoverMySQLTables(): array
{
$databaseName = $this->getCurrentDatabase();
@@ -38,7 +109,7 @@ final readonly class TableDiscovery
";
$query = SqlQuery::create($sql, [$databaseName]);
$result = $this->connection->query($query);
$result = $this->getConnection()->query($query);
$tables = $result->fetchAll();
$tableMetadata = [];
@@ -59,6 +130,55 @@ final readonly class TableDiscovery
* Discover a specific table by name
*/
public function discoverTable(string $tableName): ?TableMetadata
{
$driver = $this->getDriver();
if ($driver === 'pgsql') {
return $this->discoverPostgreSQLTable($tableName);
}
return $this->discoverMySQLTable($tableName);
}
/**
* Discover a specific PostgreSQL table
*/
private function discoverPostgreSQLTable(string $tableName): ?TableMetadata
{
$sql = "
SELECT
t.tablename as table_name,
COALESCE(s.n_live_tup::bigint, 0) as table_rows,
ROUND(pg_total_relation_size('public.'||?) / 1024.0 / 1024.0, 2) as size_mb,
NULL as engine,
NULL as table_collation
FROM pg_tables t
LEFT JOIN pg_stat_user_tables s ON s.relname = t.tablename
WHERE t.schemaname = 'public'
AND t.tablename = ?
";
$query = SqlQuery::create($sql, [$tableName, $tableName]);
$result = $this->getConnection()->query($query);
$row = $result->fetch();
if ($row === null) {
return null;
}
return new TableMetadata(
name: $row['table_name'],
rowCount: isset($row['table_rows']) && $row['table_rows'] !== null ? (int) $row['table_rows'] : null,
sizeMb: isset($row['size_mb']) ? (float) $row['size_mb'] : null,
engine: null,
collation: null,
);
}
/**
* Discover a specific MySQL table
*/
private function discoverMySQLTable(string $tableName): ?TableMetadata
{
$databaseName = $this->getCurrentDatabase();
@@ -75,7 +195,7 @@ final readonly class TableDiscovery
";
$query = SqlQuery::create($sql, [$databaseName, $tableName]);
$result = $this->connection->query($query);
$result = $this->getConnection()->query($query);
$row = $result->fetch();
if ($row === null) {
@@ -96,12 +216,28 @@ final readonly class TableDiscovery
*/
private function getCurrentDatabase(): string
{
$sql = "SELECT DATABASE() as db";
$driver = $this->getDriver();
if ($driver === 'pgsql') {
$sql = "SELECT current_database() as db";
} else {
$sql = "SELECT DATABASE() as db";
}
$query = SqlQuery::create($sql, []);
$result = $this->connection->query($query);
$result = $this->getConnection()->query($query);
$row = $result->fetch();
return $row['db'] ?? 'unknown';
}
/**
* Get database driver name
*/
private function getDriver(): string
{
$pdo = $this->getConnection()->getPdo();
return $pdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
}
}