from __future__ import annotations import sqlite3 from pathlib import Path from typing import Optional from app.core.config import settings def get_connection(db_path: Optional[Path] = None) -> sqlite3.Connection: path = db_path or settings.alarm_db_path path.parent.mkdir(parents=True, exist_ok=True) connection = sqlite3.connect(path) connection.row_factory = sqlite3.Row return connection def _alarm_event_columns(connection: sqlite3.Connection) -> list[str]: rows = connection.execute("PRAGMA table_info(alarm_event)").fetchall() return [str(row["name"]) for row in rows] def _ensure_alarm_event_schema(connection: sqlite3.Connection) -> None: expected_columns = [ "id", "event_time", "line_code", "event_type", "event_code", "event_value", "content", ] current_columns = _alarm_event_columns(connection) if not current_columns: return if current_columns == expected_columns: return connection.execute("ALTER TABLE alarm_event RENAME TO alarm_event_legacy") connection.execute( """ CREATE TABLE alarm_event ( id INTEGER PRIMARY KEY AUTOINCREMENT, event_time TEXT NOT NULL, line_code INTEGER NOT NULL DEFAULT 0, event_type INTEGER NOT NULL DEFAULT 0, event_code INTEGER NOT NULL DEFAULT 0, event_value INTEGER NOT NULL DEFAULT 0, content TEXT NOT NULL ) """ ) legacy_columns = set(current_columns) if {"time", "content"}.issubset(legacy_columns): connection.execute( """ INSERT INTO alarm_event (event_time, line_code, event_type, event_code, event_value, content) SELECT time, CASE WHEN typeof(no) IN ('integer', 'real') THEN CAST(no AS INTEGER) WHEN trim(COALESCE(no, '')) GLOB '[0-9]*' AND trim(COALESCE(no, '')) <> '' THEN CAST(trim(no) AS INTEGER) ELSE 0 END, 0, 0, 0, content FROM alarm_event_legacy """ ) connection.execute("DROP TABLE alarm_event_legacy") def init_db() -> None: with get_connection() as connection: connection.execute( """ CREATE TABLE IF NOT EXISTS alarm_event ( id INTEGER PRIMARY KEY AUTOINCREMENT, event_time TEXT NOT NULL, line_code INTEGER NOT NULL DEFAULT 0, event_type INTEGER NOT NULL DEFAULT 0, event_code INTEGER NOT NULL DEFAULT 0, event_value INTEGER NOT NULL DEFAULT 0, content TEXT NOT NULL ) """ ) _ensure_alarm_event_schema(connection) connection.commit()