2026-05-18 09:12:14 +08:00
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
2026-06-26 17:48:42 +08:00
|
|
|
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")
|
|
|
|
|
|
|
|
|
|
|
2026-05-18 09:12:14 +08:00
|
|
|
def init_db() -> None:
|
|
|
|
|
with get_connection() as connection:
|
|
|
|
|
connection.execute(
|
|
|
|
|
"""
|
|
|
|
|
CREATE TABLE IF NOT EXISTS alarm_event (
|
|
|
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
2026-06-26 17:48:42 +08:00
|
|
|
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
|
2026-05-18 09:12:14 +08:00
|
|
|
)
|
|
|
|
|
"""
|
|
|
|
|
)
|
2026-06-26 17:48:42 +08:00
|
|
|
_ensure_alarm_event_schema(connection)
|
2026-05-18 09:12:14 +08:00
|
|
|
connection.commit()
|