"""SQLite 数据层:连接短生命周期(每次操作新建),线程安全。""" from __future__ import annotations import sqlite3 from pathlib import Path DATA_DIR = Path(__file__).resolve().parent.parent / "data" DB_PATH = DATA_DIR / "monitor.db" SCHEMA = """ CREATE TABLE IF NOT EXISTS platforms ( id INTEGER PRIMARY KEY AUTOINCREMENT, provider_id TEXT NOT NULL DEFAULT '', name TEXT NOT NULL UNIQUE, currency TEXT NOT NULL DEFAULT 'USD', icon TEXT NOT NULL DEFAULT '', interval_seconds INTEGER, retry_count INTEGER, timeout_seconds INTEGER, enabled INTEGER NOT NULL DEFAULT 1, note TEXT NOT NULL DEFAULT '', created_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')), updated_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')) ); CREATE TABLE IF NOT EXISTS accounts ( id INTEGER PRIMARY KEY AUTOINCREMENT, platform_id INTEGER NOT NULL REFERENCES platforms(id) ON DELETE CASCADE, name TEXT NOT NULL, api_key TEXT NOT NULL, threshold REAL NOT NULL DEFAULT 0, enabled INTEGER NOT NULL DEFAULT 1, alert_armed INTEGER NOT NULL DEFAULT 1, last_balance REAL, last_status TEXT NOT NULL DEFAULT 'pending', last_error TEXT NOT NULL DEFAULT '', last_check_at TEXT, note TEXT NOT NULL DEFAULT '', created_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')), updated_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')) ); CREATE TABLE IF NOT EXISTS balance_history ( id INTEGER PRIMARY KEY AUTOINCREMENT, account_id INTEGER NOT NULL REFERENCES accounts(id) ON DELETE CASCADE, balance REAL NOT NULL, checked_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')) ); CREATE TABLE IF NOT EXISTS alert_log ( id INTEGER PRIMARY KEY AUTOINCREMENT, account_id INTEGER NOT NULL, type TEXT NOT NULL, message TEXT NOT NULL, sent_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')) ); CREATE INDEX IF NOT EXISTS idx_accounts_platform ON accounts(platform_id); CREATE INDEX IF NOT EXISTS idx_history_account ON balance_history(account_id, id); CREATE INDEX IF NOT EXISTS idx_alert_account ON alert_log(account_id); """ def get_conn() -> sqlite3.Connection: conn = sqlite3.connect(DB_PATH, timeout=30) conn.row_factory = sqlite3.Row conn.execute("PRAGMA foreign_keys = ON") return conn def init_db() -> None: DATA_DIR.mkdir(parents=True, exist_ok=True) with get_conn() as conn: conn.executescript(SCHEMA) def rows_to_dicts(rows: list[sqlite3.Row]) -> list[dict]: return [dict(r) for r in rows]