"""Async SQLite database layer for BadNote.""" import aiosqlite from .config import settings _db: aiosqlite.Connection | None = None async def get_db() -> aiosqlite.Connection: """Return the global database connection.""" global _db if _db is None: _db = await aiosqlite.connect(settings.db_path) _db.row_factory = aiosqlite.Row await _db.execute("PRAGMA journal_mode=WAL") await _db.execute("PRAGMA foreign_keys=ON") return _db async def close_db() -> None: """Close the global database connection.""" global _db if _db is not None: await _db.close() _db = None async def init_db() -> None: """Create all tables if they do not exist.""" db = await get_db() await db.executescript(""" CREATE TABLE IF NOT EXISTS users ( id TEXT PRIMARY KEY, username TEXT UNIQUE NOT NULL, password_hash TEXT NOT NULL, created_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS notes ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL REFERENCES users(id), title TEXT NOT NULL, created_at TEXT NOT NULL, updated_at TEXT NOT NULL, tags TEXT NOT NULL DEFAULT '[]', strokes_json TEXT NOT NULL DEFAULT '[]' ); CREATE TABLE IF NOT EXISTS documents ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL REFERENCES users(id), filename TEXT NOT NULL, doc_type TEXT NOT NULL, file_path TEXT NOT NULL, page_count INTEGER NOT NULL DEFAULT 0, created_at TEXT NOT NULL, updated_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS annotations ( id TEXT PRIMARY KEY, document_id TEXT NOT NULL REFERENCES documents(id) ON DELETE CASCADE, page_number INTEGER NOT NULL, annotation_json TEXT NOT NULL, created_at TEXT NOT NULL, updated_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS bookmarks ( id TEXT PRIMARY KEY, document_id TEXT NOT NULL REFERENCES documents(id) ON DELETE CASCADE, page_number INTEGER NOT NULL, label TEXT NOT NULL DEFAULT '', color INTEGER NOT NULL DEFAULT 4283215696, created_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS ocr_jobs ( id TEXT PRIMARY KEY, note_id TEXT, document_id TEXT, page_number INTEGER, status TEXT NOT NULL DEFAULT 'pending', result_text TEXT, error_message TEXT, created_at TEXT NOT NULL, completed_at TEXT ); """) await db.commit()