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, 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 ) """ async def init_db(): async with aiosqlite.connect(DB_PATH) as db: await db.execute(CREATE_TABLE) await db.commit() 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: async with aiosqlite.connect(DB_PATH) as db: await db.execute( """INSERT INTO guides (id, topic, format, status, progress, html_path, pdf_path, created_at, updated_at) VALUES (:id, :topic, :format, :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: async with aiosqlite.connect(DB_PATH) as 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]: async with aiosqlite.connect(DB_PATH) as 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 async with aiosqlite.connect(DB_PATH) as db: await db.execute(f"UPDATE guides SET {sets} WHERE id = :id", fields) await db.commit() async def delete_guide(guide_id: str) -> bool: async with aiosqlite.connect(DB_PATH) as db: cursor = await db.execute("DELETE FROM guides WHERE id = ?", (guide_id,)) await db.commit() return cursor.rowcount > 0