from __future__ import annotations import argparse import json import sqlite3 from pathlib import Path import sys sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from runtime_config import DB_PATH DERIVED_SIGNATURE_TABLES = ( ("wehago_compare_query_groups", "signature"), ("wehago_compare_query_rows", "signature"), ("wehago_compare_query_metrics", "signature"), ("wehago_compare_query_page_cache", "signature"), ("wehago_compare_final_status_projection", "signature"), ("wehago_metric_count_cache", "signature"), ("wehago_summary_range_cache", "signature"), ) def active_signature(conn: sqlite3.Connection, start_year: int, end_year: int) -> str: row = conn.execute( """ SELECT setting_json FROM wehago_compare_settings WHERE setting_key = ? LIMIT 1 """, (f"wehago_active_query_projection:{start_year}:{end_year}",), ).fetchone() if not row: return "" try: payload = json.loads(row[0] or "{}") except Exception: return "" return str(payload.get("signature") or "").strip() if isinstance(payload, dict) else "" def table_exists(conn: sqlite3.Connection, table_name: str) -> bool: return bool( conn.execute( "SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ? LIMIT 1", (table_name,), ).fetchone() ) def main() -> None: parser = argparse.ArgumentParser(description="Prune obsolete WEHAGO derived projection records.") parser.add_argument("--start-year", type=int, default=2025) parser.add_argument("--end-year", type=int, default=2025) parser.add_argument("--execute", action="store_true", help="Actually delete rows. Without this flag, only prints counts.") args = parser.parse_args() conn = sqlite3.connect(DB_PATH) signature = active_signature(conn, args.start_year, args.end_year) if not signature: raise SystemExit("No active projection signature was found. Refusing to prune.") results: list[dict[str, object]] = [] conn.execute("BEGIN") try: for table_name, signature_column in DERIVED_SIGNATURE_TABLES: if not table_exists(conn, table_name): continue count = int( conn.execute( f""" SELECT COUNT(*) FROM {table_name} WHERE start_year = ? AND end_year = ? AND {signature_column} <> ? """, (args.start_year, args.end_year, signature), ).fetchone()[0] or 0 ) results.append({"table": table_name, "obsolete_rows": count}) if args.execute and count: conn.execute( f""" DELETE FROM {table_name} WHERE start_year = ? AND end_year = ? AND {signature_column} <> ? """, (args.start_year, args.end_year, signature), ) if args.execute: conn.commit() else: conn.rollback() except Exception: conn.rollback() raise finally: conn.close() print( json.dumps( { "start_year": args.start_year, "end_year": args.end_year, "active_signature": signature, "execute": bool(args.execute), "tables": results, "obsolete_total": sum(int(row["obsolete_rows"]) for row in results), }, ensure_ascii=False, indent=2, ) ) if __name__ == "__main__": main()