Files
api/services/nginx/app/classes/replication_schema_bootstrap.php
T

123 lines
5.4 KiB
PHP

<?php
namespace classes;
class replication_schema_bootstrap
{
private static bool $initialized = false;
public static function ensureTables(): void
{
if (self::$initialized) {
return;
}
global $db;
$queries = [
"CREATE TABLE IF NOT EXISTS replication_hosts (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
kind VARCHAR(16) NOT NULL,
label VARCHAR(128) NOT NULL,
host VARCHAR(255) NOT NULL,
port INT UNSIGNED NOT NULL,
database_name VARCHAR(128) NULL,
database_index INT NULL,
username VARCHAR(128) NULL,
password_secret TEXT NULL,
admin_username VARCHAR(128) NULL,
admin_password_secret TEXT NULL,
replication_username VARCHAR(128) NULL,
replication_password_secret TEXT NULL,
role VARCHAR(16) NOT NULL DEFAULT 'replica',
status VARCHAR(16) NOT NULL DEFAULT 'unknown',
replication_source_id BIGINT UNSIGNED NULL,
ssl_mode VARCHAR(32) NULL,
options_json LONGTEXT NULL,
last_status_json LONGTEXT NULL,
last_checked_at DATETIME NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at DATETIME NULL,
INDEX idx_replication_hosts_kind_role (kind, role),
INDEX idx_replication_hosts_kind_status (kind, status),
INDEX idx_replication_hosts_source (replication_source_id),
INDEX idx_replication_hosts_deleted_at (deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
"CREATE TABLE IF NOT EXISTS replication_operations (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
kind VARCHAR(16) NOT NULL,
host_id BIGINT UNSIGNED NOT NULL,
operation VARCHAR(32) NOT NULL,
status VARCHAR(16) NOT NULL,
progress_percent DECIMAL(5,2) NOT NULL DEFAULT 0.00,
message VARCHAR(512) NULL,
error_message TEXT NULL,
context_json LONGTEXT NULL,
actor_user_id INT NULL,
started_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
completed_at DATETIME NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_replication_operations_host (host_id),
INDEX idx_replication_operations_kind_status (kind, status),
INDEX idx_replication_operations_operation (operation)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
"CREATE TABLE IF NOT EXISTS replication_status_snapshots (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
host_id BIGINT UNSIGNED NOT NULL,
kind VARCHAR(16) NOT NULL,
status VARCHAR(16) NOT NULL,
replication_percent DECIMAL(5,2) NOT NULL DEFAULT 0.00,
lag_seconds INT NULL,
blockers_json LONGTEXT NULL,
raw_status_json LONGTEXT NULL,
checked_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_replication_status_host_checked (host_id, checked_at),
INDEX idx_replication_status_kind_checked (kind, checked_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
"CREATE TABLE IF NOT EXISTS replication_audit_logs (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
kind VARCHAR(16) NOT NULL,
host_id BIGINT UNSIGNED NULL,
action VARCHAR(64) NOT NULL,
actor_user_id INT NULL,
severity VARCHAR(16) NOT NULL DEFAULT 'info',
context_json LONGTEXT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_replication_audit_kind_host (kind, host_id),
INDEX idx_replication_audit_action (action),
INDEX idx_replication_audit_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
];
foreach ($queries as $sql) {
$db->query($sql);
}
self::ensureColumn('replication_operations', 'progress_percent', "DECIMAL(5,2) NOT NULL DEFAULT 0.00");
self::ensureColumn('replication_operations', 'message', 'VARCHAR(512) NULL');
self::ensureColumn('replication_operations', 'context_json', 'LONGTEXT NULL');
self::$initialized = true;
}
private static function ensureColumn(string $table, string $column, string $definition): void
{
global $db;
$table = preg_replace('/[^a-zA-Z0-9_]/', '', $table);
$column = preg_replace('/[^a-zA-Z0-9_]/', '', $column);
if ($table === '' || $column === '') {
return;
}
$result = $db->query("SHOW COLUMNS FROM `$table` LIKE '$column'");
if ($result !== false && $result->num_rows > 0) {
return;
}
$db->query("ALTER TABLE `$table` ADD COLUMN `$column` $definition");
}
}