113 lines
2.9 KiB
Python
113 lines
2.9 KiB
Python
from __future__ import annotations
|
|
|
|
import sqlite3
|
|
from pathlib import Path
|
|
|
|
from app.config import settings
|
|
|
|
|
|
SCHEMA = """
|
|
PRAGMA journal_mode = WAL;
|
|
PRAGMA foreign_keys = ON;
|
|
|
|
CREATE TABLE IF NOT EXISTS tasks (
|
|
id TEXT PRIMARY KEY,
|
|
type TEXT NOT NULL,
|
|
app_id TEXT,
|
|
app_name TEXT,
|
|
status TEXT NOT NULL,
|
|
progress INTEGER DEFAULT 0,
|
|
current_step TEXT,
|
|
current_component_id TEXT,
|
|
error_message TEXT,
|
|
created_at TEXT NOT NULL,
|
|
started_at TEXT,
|
|
finished_at TEXT
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS task_logs (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
task_id TEXT NOT NULL,
|
|
timestamp TEXT NOT NULL,
|
|
level TEXT NOT NULL,
|
|
message TEXT NOT NULL,
|
|
FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS installed_apps (
|
|
app_id TEXT PRIMARY KEY,
|
|
app_name TEXT NOT NULL,
|
|
version TEXT NOT NULL,
|
|
open_url TEXT,
|
|
manifest_hash TEXT,
|
|
status TEXT NOT NULL,
|
|
installed_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS installed_components (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
app_id TEXT NOT NULL,
|
|
component_id TEXT NOT NULL,
|
|
type TEXT NOT NULL,
|
|
install_order INTEGER NOT NULL,
|
|
status TEXT NOT NULL,
|
|
package_name TEXT,
|
|
package_version TEXT,
|
|
service_name TEXT,
|
|
docker_image TEXT,
|
|
docker_digest TEXT,
|
|
container_name TEXT,
|
|
compose_project_name TEXT,
|
|
installed_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
UNIQUE(app_id, component_id)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS task_components (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
task_id TEXT NOT NULL,
|
|
app_id TEXT NOT NULL,
|
|
component_id TEXT NOT NULL,
|
|
type TEXT NOT NULL,
|
|
install_order INTEGER NOT NULL,
|
|
status TEXT NOT NULL,
|
|
progress INTEGER DEFAULT 0,
|
|
current_step TEXT,
|
|
error_message TEXT,
|
|
started_at TEXT,
|
|
finished_at TEXT,
|
|
FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS agent_config (
|
|
key TEXT PRIMARY KEY,
|
|
value TEXT NOT NULL
|
|
);
|
|
"""
|
|
|
|
|
|
def _ensure_column(connection: sqlite3.Connection, table: str, column: str, definition: str) -> None:
|
|
columns = {
|
|
row["name"]
|
|
for row in connection.execute(f"PRAGMA table_info({table})").fetchall()
|
|
}
|
|
if column not in columns:
|
|
connection.execute(f"ALTER TABLE {table} ADD COLUMN {column} {definition}")
|
|
|
|
|
|
def get_connection() -> sqlite3.Connection:
|
|
connection = sqlite3.connect(settings.db_path, timeout=30)
|
|
connection.row_factory = sqlite3.Row
|
|
return connection
|
|
|
|
|
|
def initialize_database() -> None:
|
|
db_path = Path(settings.db_path)
|
|
db_path.parent.mkdir(parents=True, exist_ok=True)
|
|
settings.cache_dir.mkdir(parents=True, exist_ok=True)
|
|
settings.log_dir.mkdir(parents=True, exist_ok=True)
|
|
with get_connection() as connection:
|
|
connection.executescript(SCHEMA)
|
|
_ensure_column(connection, "installed_apps", "open_url", "TEXT")
|