rebuild to module

This commit is contained in:
2026-03-03 02:13:17 +01:00
parent ffb52c6789
commit e61f9fb889
23 changed files with 7618 additions and 73 deletions

View File

@@ -11,39 +11,14 @@ final class Database
return null;
}
$db = $config->db;
$driver = (string)($db['driver'] ?? '');
if ($driver === '') {
throw new \RuntimeException('DB enabled but config/db.php missing "driver"');
}
$dsn = match ($driver) {
'mysql' => self::buildMysqlDsn($db),
'pgsql' => self::buildPgsqlDsn($db),
'sqlite' => self::buildSqliteDsn($db),
default => throw new \RuntimeException('Unsupported PDO driver: ' . $driver),
};
try {
$pdo = new \PDO(
$dsn,
// sqlite braucht user/pass nicht, PDO ignoriert es aber; wir geben leer zurück
(string)($db['user'] ?? ''),
(string)($db['password'] ?? ''),
(array)($db['options'] ?? [])
);
// Optional: PostgreSQL schema/search_path setzen
if ($driver === 'pgsql' && !empty($db['schema'])) {
// Minimaler Schutz gegen Injection über schema
$schema = preg_replace('/[^a-zA-Z0-9_]/', '', (string)$db['schema']);
if ($schema !== '') {
$pdo->exec('SET search_path TO ' . $schema);
}
}
self::ensureSchema($pdo, $config);
$pdo = self::createFromArray($config->db);
self::ensureKeaSchema($pdo, [
'auto_init' => $config->dbAutoInit,
'init_cmd' => $config->dbInitCmd,
'init_script' => $config->dbInitScript,
'kea_db_version' => $config->keaDbVersion,
]);
return $pdo;
} catch (\PDOException $e) {
@@ -63,7 +38,55 @@ final class Database
}
}
private static function ensureSchema(\PDO $pdo, Config $config): void
public static function createBasePdo(Config $config): ?\PDO
{
if (!$config->baseDbEnabled || empty($config->baseDb)) {
return null;
}
try {
return self::createFromArray($config->baseDb);
} catch (\PDOException $e) {
http_response_code(500);
$details = 'Base database connection error.';
error_log('[Base DB] ' . $e->getMessage());
echo $details;
exit;
}
}
public static function createFromArray(array $db): \PDO
{
$driver = (string)($db['driver'] ?? '');
if ($driver === '') {
throw new \RuntimeException('DB config missing "driver"');
}
$dsn = match ($driver) {
'mysql' => self::buildMysqlDsn($db),
'pgsql' => self::buildPgsqlDsn($db),
'sqlite' => self::buildSqliteDsn($db),
default => throw new \RuntimeException('Unsupported PDO driver: ' . $driver),
};
$pdo = new \PDO(
$dsn,
(string)($db['user'] ?? ''),
(string)($db['password'] ?? ''),
(array)($db['options'] ?? [])
);
if ($driver === 'pgsql' && !empty($db['schema'])) {
$schema = preg_replace('/[^a-zA-Z0-9_]/', '', (string)$db['schema']);
if ($schema !== '') {
$pdo->exec('SET search_path TO ' . $schema);
}
}
return $pdo;
}
public static function ensureKeaSchema(\PDO $pdo, array $options): void
{
$driver = (string)$pdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
if ($driver !== 'pgsql') {
@@ -71,8 +94,8 @@ final class Database
}
if (!self::tableExists($pdo, 'hosts')) {
if ($config->dbAutoInit) {
self::initKeaSchema($pdo, $config);
if (!empty($options['auto_init'])) {
self::initKeaSchema($pdo, $options);
}
}
@@ -95,15 +118,20 @@ final class Database
return (bool)$stmt->fetchColumn();
}
private static function initKeaSchema(\PDO $pdo, Config $config): void
private static function initKeaSchema(\PDO $pdo, array $options): void
{
if ($config->dbInitCmd) {
self::runInitCommand($config->dbInitCmd);
if (!empty($options['init_cmd'])) {
self::runInitCommand((string)$options['init_cmd']);
return;
}
if ($config->dbInitScript) {
self::execSqlFile($pdo, $config->dbInitScript);
$script = $options['init_script'] ?? null;
if (!$script && !empty($options['kea_db_version'])) {
$script = __DIR__ . '/../../tools/sql/kea/' . $options['kea_db_version'] . '/dhcpdb_create.pgsql';
}
if ($script) {
self::execSqlFile($pdo, (string)$script);
return;
}