import aiosqlite from config import DB_PATH CREATE_TABLE = """ CREATE TABLE IF NOT EXISTS guides ( id TEXT PRIMARY KEY, topic TEXT NOT NULL, format TEXT NOT NULL, instructions TEXT NOT NULL DEFAULT '', status TEXT NOT NULL DEFAULT 'queued', progress TEXT, error_msg TEXT, html_path TEXT, pdf_path TEXT, created_at TEXT NOT NULL, updated_at TEXT NOT NULL ) """ _db: aiosqlite.Connection | None = None async def get_db() -> aiosqlite.Connection: global _db if _db is None: _db = await aiosqlite.connect(DB_PATH) _db.row_factory = None return _db async def init_db(): db = await get_db() await db.execute(CREATE_TABLE) cursor = await db.execute("PRAGMA table_info(guides)") columns = {row[1] for row in await cursor.fetchall()} if "instructions" not in columns: await db.execute("ALTER TABLE guides ADD COLUMN instructions TEXT NOT NULL DEFAULT ''") await db.execute( "UPDATE guides SET status = 'error', progress = NULL, error_msg = 'Server-Neustart' " "WHERE status IN ('queued', 'generating')" ) await db.commit() async def close_db(): global _db if _db is not None: await _db.close() _db = None def _row_to_dict(row, cursor): columns = [d[0] for d in cursor.description] return dict(zip(columns, row)) async def create_guide(guide: dict) -> dict: db = await get_db() await db.execute( """INSERT INTO guides (id, topic, format, instructions, status, progress, html_path, pdf_path, created_at, updated_at) VALUES (:id, :topic, :format, :instructions, :status, :progress, :html_path, :pdf_path, :created_at, :updated_at)""", guide, ) await db.commit() return guide async def get_guide(guide_id: str) -> dict | None: db = await get_db() cursor = await db.execute("SELECT * FROM guides WHERE id = ?", (guide_id,)) row = await cursor.fetchone() if row is None: return None return _row_to_dict(row, cursor) async def list_guides() -> list[dict]: db = await get_db() cursor = await db.execute("SELECT * FROM guides ORDER BY created_at DESC") rows = await cursor.fetchall() return [_row_to_dict(row, cursor) for row in rows] async def update_guide(guide_id: str, **fields) -> None: sets = ", ".join(f"{k} = :{k}" for k in fields) fields["id"] = guide_id db = await get_db() await db.execute(f"UPDATE guides SET {sets} WHERE id = :id", fields) await db.commit() async def delete_guide(guide_id: str) -> bool: db = await get_db() cursor = await db.execute("DELETE FROM guides WHERE id = ?", (guide_id,)) await db.commit() return cursor.rowcount > 0