import Database from "better-sqlite3"; import { mkdirSync } from "node:fs"; import { dirname } from "node:path"; import type { Env } from "../env.js"; export function openDb(env: Env): Database.Database { mkdirSync(dirname(env.DB_PATH), { recursive: true }); const db = new Database(env.DB_PATH); db.pragma("journal_mode = WAL"); migrate(db, env); return db; } function migrate(db: Database.Database, env: Env): void { db.exec(` CREATE TABLE IF NOT EXISTS devices ( id INTEGER PRIMARY KEY AUTOINCREMENT, entity_id TEXT NOT NULL UNIQUE, name TEXT NOT NULL, kind TEXT NOT NULL CHECK (kind IN ('switch', 'number')), priority INTEGER NOT NULL, min_value REAL NOT NULL DEFAULT 0, max_value REAL NOT NULL DEFAULT 1, dwell_seconds INTEGER NOT NULL DEFAULT 300, manual_override INTEGER NOT NULL DEFAULT 0, shed INTEGER NOT NULL DEFAULT 0, last_changed_at TEXT ); CREATE TABLE IF NOT EXISTS settings ( key TEXT PRIMARY KEY, value TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS control_actions ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp_ms INTEGER NOT NULL, entity_id TEXT NOT NULL, action TEXT NOT NULL CHECK (action IN ('shed', 'restore')), reason TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS block_history ( block_start_ms INTEGER PRIMARY KEY, average_w REAL NOT NULL ); `); const existingTarget = db.prepare("SELECT value FROM settings WHERE key = 'target_kw'").get(); if (!existingTarget) { db.prepare("INSERT INTO settings (key, value) VALUES ('target_kw', ?)").run(String(env.TARGET_KW)); } const deviceColumns = new Set( (db.prepare("PRAGMA table_info(devices)").all() as { name: string }[]).map((c) => c.name), ); if (!deviceColumns.has("only_when_sun")) { db.exec("ALTER TABLE devices ADD COLUMN only_when_sun INTEGER NOT NULL DEFAULT 0"); } if (!deviceColumns.has("from_time")) { db.exec("ALTER TABLE devices ADD COLUMN from_time TEXT"); } if (!deviceColumns.has("to_time")) { db.exec("ALTER TABLE devices ADD COLUMN to_time TEXT"); } if (!deviceColumns.has("enable_url")) { db.exec("ALTER TABLE devices ADD COLUMN enable_url TEXT"); } if (!deviceColumns.has("disable_url")) { db.exec("ALTER TABLE devices ADD COLUMN disable_url TEXT"); } }