Add annual ranking snapshot storage
This commit is contained in:
@@ -188,6 +188,39 @@ CREATE TABLE IF NOT EXISTS rcon_match_player_stats (
|
||||
UNIQUE(target_key, match_key, player_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS rcon_annual_ranking_snapshots (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
year INTEGER NOT NULL,
|
||||
server_key TEXT NOT NULL,
|
||||
metric TEXT NOT NULL,
|
||||
limit_size INTEGER NOT NULL DEFAULT 20,
|
||||
source_basis TEXT NOT NULL DEFAULT 'rcon-admin-log',
|
||||
window_start TEXT,
|
||||
window_end TEXT,
|
||||
generated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
status TEXT NOT NULL DEFAULT 'ready',
|
||||
source_matches_count INTEGER NOT NULL DEFAULT 0,
|
||||
CHECK (limit_size > 0),
|
||||
CHECK (metric IN ('kills', 'deaths', 'matches_over_100_kills', 'support')),
|
||||
UNIQUE (year, server_key, metric)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS rcon_annual_ranking_snapshot_items (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
snapshot_id BIGINT NOT NULL REFERENCES rcon_annual_ranking_snapshots(id) ON DELETE CASCADE,
|
||||
ranking_position INTEGER NOT NULL,
|
||||
player_id TEXT NOT NULL,
|
||||
player_name TEXT NOT NULL,
|
||||
metric_value BIGINT NOT NULL DEFAULT 0,
|
||||
matches_considered INTEGER NOT NULL DEFAULT 0,
|
||||
kills BIGINT NOT NULL DEFAULT 0,
|
||||
deaths BIGINT NOT NULL DEFAULT 0,
|
||||
teamkills BIGINT NOT NULL DEFAULT 0,
|
||||
kd_ratio DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
UNIQUE(snapshot_id, ranking_position),
|
||||
UNIQUE(snapshot_id, player_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS rcon_scoreboard_match_candidates (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
server_slug TEXT NOT NULL,
|
||||
@@ -219,6 +252,14 @@ CREATE INDEX IF NOT EXISTS idx_rcon_materialized_matches_recent
|
||||
ON rcon_materialized_matches(target_key, ended_at DESC, ended_server_time DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_rcon_match_player_stats_match
|
||||
ON rcon_match_player_stats(target_key, match_key);
|
||||
CREATE INDEX IF NOT EXISTS idx_rcon_annual_ranking_snapshots_year
|
||||
ON rcon_annual_ranking_snapshots(year, server_key, metric);
|
||||
CREATE INDEX IF NOT EXISTS idx_rcon_annual_ranking_snapshots_status
|
||||
ON rcon_annual_ranking_snapshots(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_rcon_annual_snapshot_items_snapshot
|
||||
ON rcon_annual_ranking_snapshot_items(snapshot_id, ranking_position);
|
||||
CREATE INDEX IF NOT EXISTS idx_rcon_annual_snapshot_items_player
|
||||
ON rcon_annual_ranking_snapshot_items(snapshot_id, player_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_rcon_scoreboard_candidates_server_end
|
||||
ON rcon_scoreboard_match_candidates(server_slug, ended_at DESC, started_at DESC);
|
||||
"""
|
||||
|
||||
@@ -83,6 +83,51 @@ def initialize_rcon_materialized_storage(*, db_path: Path | None = None) -> Path
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_rcon_match_player_stats_match
|
||||
ON rcon_match_player_stats(target_key, match_key);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS rcon_annual_ranking_snapshots (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
year INTEGER NOT NULL,
|
||||
server_key TEXT NOT NULL,
|
||||
metric TEXT NOT NULL,
|
||||
limit_size INTEGER NOT NULL DEFAULT 20,
|
||||
source_basis TEXT NOT NULL DEFAULT 'rcon-admin-log',
|
||||
window_start TEXT,
|
||||
window_end TEXT,
|
||||
generated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
status TEXT NOT NULL DEFAULT 'ready',
|
||||
source_matches_count INTEGER NOT NULL DEFAULT 0,
|
||||
CHECK (limit_size > 0),
|
||||
CHECK (metric IN ('kills', 'deaths', 'matches_over_100_kills', 'support')),
|
||||
UNIQUE (year, server_key, metric)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_rcon_annual_ranking_snapshots_year
|
||||
ON rcon_annual_ranking_snapshots(year, server_key, metric);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_rcon_annual_ranking_snapshots_status
|
||||
ON rcon_annual_ranking_snapshots(status);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS rcon_annual_ranking_snapshot_items (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
snapshot_id INTEGER NOT NULL REFERENCES rcon_annual_ranking_snapshots(id) ON DELETE CASCADE,
|
||||
ranking_position INTEGER NOT NULL,
|
||||
player_id TEXT NOT NULL,
|
||||
player_name TEXT NOT NULL,
|
||||
metric_value INTEGER NOT NULL DEFAULT 0,
|
||||
matches_considered INTEGER NOT NULL DEFAULT 0,
|
||||
kills INTEGER NOT NULL DEFAULT 0,
|
||||
deaths INTEGER NOT NULL DEFAULT 0,
|
||||
teamkills INTEGER NOT NULL DEFAULT 0,
|
||||
kd_ratio REAL NOT NULL DEFAULT 0.0,
|
||||
UNIQUE(snapshot_id, ranking_position),
|
||||
UNIQUE(snapshot_id, player_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_rcon_annual_snapshot_items_snapshot
|
||||
ON rcon_annual_ranking_snapshot_items(snapshot_id, ranking_position);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_rcon_annual_snapshot_items_player
|
||||
ON rcon_annual_ranking_snapshot_items(snapshot_id, player_id);
|
||||
"""
|
||||
)
|
||||
return resolved_path
|
||||
|
||||
@@ -28,6 +28,8 @@ RCON_TABLES = (
|
||||
"rcon_player_profile_snapshots",
|
||||
"rcon_materialized_matches",
|
||||
"rcon_match_player_stats",
|
||||
"rcon_annual_ranking_snapshots",
|
||||
"rcon_annual_ranking_snapshot_items",
|
||||
"rcon_scoreboard_match_candidates",
|
||||
)
|
||||
DISPLAY_TABLES = (
|
||||
@@ -315,6 +317,8 @@ def _sync_sequences() -> None:
|
||||
"rcon_player_profile_snapshots",
|
||||
"rcon_materialized_matches",
|
||||
"rcon_match_player_stats",
|
||||
"rcon_annual_ranking_snapshots",
|
||||
"rcon_annual_ranking_snapshot_items",
|
||||
"rcon_scoreboard_match_candidates",
|
||||
)
|
||||
with connect_display_postgres() as connection:
|
||||
|
||||
Reference in New Issue
Block a user