"""Settings repository. Provides CRUD operations for the ``settings`` key-value table in the application SQLite database. All methods are plain async functions that accept a :class:`aiosqlite.Connection` — no ORM, no HTTP exceptions. """ from __future__ import annotations from typing import TYPE_CHECKING if TYPE_CHECKING: import aiosqlite async def get_setting(db: aiosqlite.Connection, key: str) -> str | None: """Return the value for *key*, or ``None`` if it does not exist. Args: db: Active aiosqlite connection. key: The setting key to look up. Returns: The stored value string, or ``None`` if the key is absent. """ async with db.execute( "SELECT value FROM settings WHERE key = ?", (key,), ) as cursor: row = await cursor.fetchone() return str(row[0]) if row is not None else None async def set_setting(db: aiosqlite.Connection, key: str, value: str) -> None: """Insert or replace the setting identified by *key*. Args: db: Active aiosqlite connection. key: The setting key. value: The value to store. """ await db.execute( "INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)", (key, value), ) await db.commit() async def delete_setting(db: aiosqlite.Connection, key: str) -> None: """Delete the setting identified by *key* if it exists. Args: db: Active aiosqlite connection. key: The setting key to remove. """ await db.execute("DELETE FROM settings WHERE key = ?", (key,)) await db.commit() async def set_settings_batch(db: aiosqlite.Connection, settings: dict[str, str]) -> None: """Insert or replace multiple settings atomically in a single transaction. Wraps all writes in a single BEGIN IMMEDIATE ... COMMIT transaction to ensure atomicity. Either all settings are persisted or none are. This is useful for operations that must succeed as a logical unit (e.g., setup initialization). Args: db: Active aiosqlite connection. settings: A dictionary mapping setting keys to their values. Raises: Any exception from executing the SQL will cause a rollback. """ if not settings: return try: await db.execute("BEGIN IMMEDIATE;") for key, value in settings.items(): await db.execute( "INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)", (key, value), ) await db.commit() except Exception: await db.rollback() raise async def get_all_settings(db: aiosqlite.Connection) -> dict[str, str]: """Return all settings as a plain ``dict``. Args: db: Active aiosqlite connection. Returns: A dictionary mapping every stored key to its value. """ async with db.execute("SELECT key, value FROM settings") as cursor: rows = await cursor.fetchall() return {str(row[0]): str(row[1]) for row in rows}