120 lines
5.4 KiB
PHP
120 lines
5.4 KiB
PHP
<?php
|
|
|
|
namespace classes;
|
|
|
|
class module_usage_schema_bootstrap
|
|
{
|
|
private static bool $initialized = false;
|
|
|
|
public static function ensureTables(): void
|
|
{
|
|
if (self::$initialized) {
|
|
return;
|
|
}
|
|
|
|
global $db;
|
|
|
|
if (!isset($db) || !is_object($db) || !method_exists($db, 'query')) {
|
|
return;
|
|
}
|
|
|
|
$db->query(
|
|
"CREATE TABLE IF NOT EXISTS module_usage_counters (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
module_key VARCHAR(64) NOT NULL,
|
|
metric_key VARCHAR(128) NOT NULL,
|
|
scope_type VARCHAR(32) NOT NULL DEFAULT 'global',
|
|
scope_id VARCHAR(191) NOT NULL DEFAULT '',
|
|
period_key VARCHAR(32) NOT NULL DEFAULT 'all_time',
|
|
period_start DATETIME NOT NULL,
|
|
period_end DATETIME NULL,
|
|
unit VARCHAR(32) NOT NULL DEFAULT 'count',
|
|
used_quantity DECIMAL(20,4) NOT NULL DEFAULT 0,
|
|
limit_quantity DECIMAL(20,4) NULL,
|
|
status VARCHAR(32) NOT NULL DEFAULT 'ok',
|
|
metadata_json LONGTEXT NULL,
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
|
UNIQUE KEY uniq_module_usage_counter (module_key, metric_key, scope_type, scope_id, period_key, period_start),
|
|
KEY idx_module_usage_counters_module_period (module_key, period_key, period_start),
|
|
KEY idx_module_usage_counters_status (status, updated_at),
|
|
KEY idx_module_usage_counters_scope (scope_type, scope_id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
|
|
);
|
|
|
|
$db->query(
|
|
"CREATE TABLE IF NOT EXISTS module_usage_snapshots (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
module_key VARCHAR(64) NOT NULL,
|
|
metric_key VARCHAR(128) NOT NULL,
|
|
source VARCHAR(32) NOT NULL DEFAULT 'provider',
|
|
period_key VARCHAR(32) NOT NULL DEFAULT 'provider',
|
|
period_start DATETIME NULL,
|
|
period_end DATETIME NULL,
|
|
unit VARCHAR(32) NOT NULL DEFAULT 'count',
|
|
used_quantity DECIMAL(20,4) NULL,
|
|
limit_quantity DECIMAL(20,4) NULL,
|
|
remaining_quantity DECIMAL(20,4) NULL,
|
|
usage_percent DECIMAL(8,4) NULL,
|
|
status VARCHAR(32) NOT NULL DEFAULT 'unknown',
|
|
raw_payload_json LONGTEXT NULL,
|
|
checked_at DATETIME NOT NULL,
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
KEY idx_module_usage_snapshots_module_checked (module_key, metric_key, checked_at),
|
|
KEY idx_module_usage_snapshots_status (status, checked_at)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
|
|
);
|
|
|
|
$db->query(
|
|
"CREATE TABLE IF NOT EXISTS module_quota_settings (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
module_key VARCHAR(64) NOT NULL,
|
|
metric_key VARCHAR(128) NOT NULL,
|
|
enabled TINYINT(1) NOT NULL DEFAULT 1,
|
|
enforce_mode VARCHAR(16) NOT NULL DEFAULT 'observe',
|
|
soft_limit_percent DECIMAL(6,2) NOT NULL DEFAULT 90.00,
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
|
UNIQUE KEY uniq_module_quota_setting (module_key, metric_key),
|
|
KEY idx_module_quota_settings_mode (enforce_mode, enabled)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
|
|
);
|
|
|
|
$db->query(
|
|
"CREATE TABLE IF NOT EXISTS module_usage_logs (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
module VARCHAR(64) NOT NULL,
|
|
action VARCHAR(64) NOT NULL,
|
|
status_code INT NOT NULL DEFAULT 0,
|
|
data LONGTEXT NULL,
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
KEY idx_module_usage_logs_module_created (module, created_at),
|
|
KEY idx_module_usage_logs_action_created (action, created_at),
|
|
KEY idx_module_usage_logs_status_created (status_code, created_at)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
|
|
);
|
|
|
|
self::ensureColumn('module_quota_settings', 'enabled', "TINYINT(1) NOT NULL DEFAULT 1 AFTER metric_key");
|
|
self::ensureColumn('module_quota_settings', 'soft_limit_percent', "DECIMAL(6,2) NOT NULL DEFAULT 90.00 AFTER enforce_mode");
|
|
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 && $result->num_rows > 0) {
|
|
return;
|
|
}
|
|
|
|
$db->query("ALTER TABLE `{$table}` ADD COLUMN `{$column}` {$definition}");
|
|
}
|
|
}
|