diff --git a/src/app/core/database/db.py b/src/app/core/database/db.py index 2d1d6b5..d0f20b8 100644 --- a/src/app/core/database/db.py +++ b/src/app/core/database/db.py @@ -33,6 +33,13 @@ CREATE TABLE IF NOT EXISTS playlist_items ( class Database: + """Thin SQLite persistence layer for playlists and playlist items. + + The database stores the local synchronization state so the sync pipeline + can compare remote playlist data with what has already been downloaded, + renamed, or marked as removed. + """ + def __init__(self, db_path: Path) -> None: self.path = db_path self.path.parent.mkdir(parents=True, exist_ok=True) @@ -41,10 +48,12 @@ class Database: self._migrate() def _migrate(self) -> None: + """Create the schema if this database has not been initialized yet.""" with self._conn: self._conn.executescript(SCHEMA) def upsert_playlist_items(self, rows: Iterable[tuple]): + """Insert or refresh the cached metadata for playlist entries.""" sql = ( "INSERT INTO playlist_items (playlist_id, video_id, title, playlist_index, local_filename, downloaded, last_seen) " "VALUES (?, ?, ?, ?, ?, ?, datetime('now')) " @@ -56,6 +65,7 @@ class Database: self._conn.executemany(sql, rows) def get_items_index(self, playlist_id: str) -> dict[str, sqlite3.Row]: + """Return all cached items for a playlist keyed by video id.""" cur = self._conn.execute( "SELECT * FROM playlist_items WHERE playlist_id = ?", (playlist_id,), @@ -63,6 +73,7 @@ class Database: return {row["video_id"]: row for row in cur.fetchall()} def upsert_playlist(self, *, id: str, name: str | None, url: str, path: str, mode: str, auto_sync: int = 0, sync_interval_minutes: int = 0) -> None: + """Insert or update the playlist configuration row.""" sql = ( "INSERT INTO playlists (id, name, url, path, mode, auto_sync, sync_interval_minutes, last_sync) " "VALUES (?, ?, ?, ?, ?, ?, ?, NULL) " @@ -73,6 +84,7 @@ class Database: self._conn.execute(sql, (id, name, url, path, mode, auto_sync, sync_interval_minutes)) def update_local_filename(self, playlist_id: str, video_id: str, local_filename: str | None) -> None: + """Record the current filename associated with a playlist item.""" with self._conn: self._conn.execute( "UPDATE playlist_items SET local_filename = ?, last_seen = datetime('now') WHERE playlist_id = ? AND video_id = ?", @@ -80,6 +92,7 @@ class Database: ) def mark_downloaded(self, playlist_id: str, video_id: str, downloaded: bool) -> None: + """Mark whether a playlist item is present on disk.""" with self._conn: self._conn.execute( "UPDATE playlist_items SET downloaded = ?, last_seen = datetime('now') WHERE playlist_id = ? AND video_id = ?", @@ -87,6 +100,7 @@ class Database: ) def clear_file_state(self, playlist_id: str, video_id: str) -> None: + """Clear filename and downloaded flags after a deletion or recycle.""" with self._conn: self._conn.execute( "UPDATE playlist_items SET local_filename = NULL, downloaded = 0, last_seen = datetime('now') WHERE playlist_id = ? AND video_id = ?", @@ -94,6 +108,7 @@ class Database: ) def set_playlist_last_sync(self, playlist_id: str) -> None: + """Store the timestamp of the most recent successful sync.""" with self._conn: self._conn.execute( "UPDATE playlists SET last_sync = datetime('now') WHERE id = ?", @@ -101,6 +116,7 @@ class Database: ) def get_playlist_last_sync(self, playlist_id: str) -> str | None: + """Return the last sync timestamp for a playlist, if any.""" cur = self._conn.execute("SELECT last_sync FROM playlists WHERE id = ?", (playlist_id,)) row = cur.fetchone() if not row: