registerFunction($moduleName, 'table', function (string $name): string { $prefix = 'picontrol_'; $sanitized = preg_replace('/[^a-zA-Z0-9_]/', '', $name); return $prefix . $sanitized; }); modules()->registerFunction($moduleName, 'pdo', function () use ($moduleName): \PDO { $settings = modules()->settings($moduleName); $useSeparate = !empty($settings['use_separate_db']); if ($useSeparate) { // Uses module-specific DB config $module = modules()->get($moduleName); $fallback = $module['db_defaults'] ?? []; return modules()->modulePdo($moduleName, $fallback); } $base = app()->basePdo(); if (!$base) { throw new ModuleConfigException( $moduleName, 'Base-DB ist deaktiviert. Bitte Base-DB aktivieren oder eigene Modul-DB konfigurieren.' ); } return $base; }); modules()->registerFunction($moduleName, 'ensure_schema', function () use ($moduleName): void { $pdo = module_fn($moduleName, 'pdo'); $table = fn(string $name) => module_fn($moduleName, 'table', $name); $driver = (string)$pdo->getAttribute(PDO::ATTR_DRIVER_NAME); $hostTable = $table('hosts'); $cmdTable = $table('commands'); $runTable = $table('runs'); if ($driver === 'pgsql') { $pdo->exec("CREATE TABLE IF NOT EXISTS {$hostTable} ( id SERIAL PRIMARY KEY, name VARCHAR(120) NOT NULL, host VARCHAR(255) NOT NULL, port INTEGER NOT NULL DEFAULT 22, username VARCHAR(120) NOT NULL, auth_type VARCHAR(20) NOT NULL DEFAULT 'key', key_path TEXT NULL, password TEXT NULL, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP )"); $pdo->exec("CREATE TABLE IF NOT EXISTS {$cmdTable} ( id SERIAL PRIMARY KEY, label VARCHAR(160) NOT NULL, command TEXT NOT NULL, admin_only BOOLEAN NOT NULL DEFAULT false, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP )"); $pdo->exec("CREATE TABLE IF NOT EXISTS {$runTable} ( id SERIAL PRIMARY KEY, host_id INTEGER NULL, command_id INTEGER NULL, command_text TEXT NOT NULL, status VARCHAR(20) NOT NULL DEFAULT 'pending', output TEXT NULL, created_by VARCHAR(120) NULL, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP )"); } else { $pdo->exec("CREATE TABLE IF NOT EXISTS {$hostTable} ( id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(120) NOT NULL, host VARCHAR(255) NOT NULL, port INTEGER NOT NULL DEFAULT 22, username VARCHAR(120) NOT NULL, auth_type VARCHAR(20) NOT NULL DEFAULT 'key', key_path TEXT NULL, password TEXT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP )"); $pdo->exec("CREATE TABLE IF NOT EXISTS {$cmdTable} ( id INTEGER PRIMARY KEY AUTOINCREMENT, label VARCHAR(160) NOT NULL, command TEXT NOT NULL, admin_only INTEGER NOT NULL DEFAULT 0, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP )"); $pdo->exec("CREATE TABLE IF NOT EXISTS {$runTable} ( id INTEGER PRIMARY KEY AUTOINCREMENT, host_id INTEGER NULL, command_id INTEGER NULL, command_text TEXT NOT NULL, status VARCHAR(20) NOT NULL DEFAULT 'pending', output TEXT NULL, created_by VARCHAR(120) NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP )"); } });