You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
4.5 KiB
179 lines
4.5 KiB
# ============================================================
|
|
# File: db/state_sql.py (UPDATED for book_idx-only architecture)
|
|
# Purpose:
|
|
# Low-level SQLite snapshot layer for BookScraper metadata.
|
|
# Used ONLY through db.repository façade.
|
|
# ============================================================
|
|
|
|
import sqlite3
|
|
import os
|
|
|
|
from logbus.publisher import log
|
|
|
|
# Must match db/db.py
|
|
DB_PATH = os.getenv("BOOKSCRAPER_DB", "/app/data/books.db")
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# INTERNAL HELPERS
|
|
# ------------------------------------------------------------
|
|
def _connect():
|
|
conn = sqlite3.connect(DB_PATH)
|
|
conn.row_factory = sqlite3.Row
|
|
return conn
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# FETCH
|
|
# ------------------------------------------------------------
|
|
def sql_fetch_book(book_idx):
|
|
conn = _connect()
|
|
cur = conn.cursor()
|
|
cur.execute("SELECT * FROM books WHERE book_idx = ?", (book_idx,))
|
|
row = cur.fetchone()
|
|
conn.close()
|
|
return dict(row) if row else None
|
|
|
|
|
|
def sql_fetch_all_books():
|
|
conn = _connect()
|
|
cur = conn.cursor()
|
|
cur.execute("SELECT * FROM books ORDER BY created_at DESC")
|
|
rows = cur.fetchall()
|
|
conn.close()
|
|
return [dict(r) for r in rows]
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# REGISTER / UPDATE
|
|
# ------------------------------------------------------------
|
|
def sql_register_book(book_idx, fields: dict):
|
|
"""
|
|
Insert or replace entire book record.
|
|
book_idx is the PRIMARY KEY.
|
|
"""
|
|
conn = _connect()
|
|
cur = conn.cursor()
|
|
|
|
cols = ", ".join(["book_idx"] + list(fields.keys()))
|
|
placeholders = ", ".join(["?"] * (1 + len(fields)))
|
|
values = [book_idx] + list(fields.values())
|
|
|
|
cur.execute(
|
|
f"INSERT OR REPLACE INTO books ({cols}) VALUES ({placeholders})",
|
|
values,
|
|
)
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
|
|
def sql_update_book(book_idx, fields: dict):
|
|
if not fields:
|
|
return
|
|
|
|
conn = _connect()
|
|
cur = conn.cursor()
|
|
|
|
set_clause = ", ".join([f"{k} = ?" for k in fields])
|
|
params = list(fields.values()) + [book_idx]
|
|
|
|
cur.execute(
|
|
f"UPDATE books SET {set_clause} WHERE book_idx = ?",
|
|
params,
|
|
)
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# STATUS
|
|
# ------------------------------------------------------------
|
|
def sql_set_status(book_idx, status: str):
|
|
conn = _connect()
|
|
cur = conn.cursor()
|
|
cur.execute(
|
|
"UPDATE books SET status = ? WHERE book_idx = ?",
|
|
(status, book_idx),
|
|
)
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# CHAPTER TOTAL (snapshot)
|
|
# ------------------------------------------------------------
|
|
def sql_set_chapters_total(book_idx, total: int):
|
|
conn = _connect()
|
|
cur = conn.cursor()
|
|
cur.execute(
|
|
"UPDATE books SET chapters_total = ? WHERE book_idx = ?",
|
|
(total, book_idx),
|
|
)
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# COUNTERS (SNAPSHOT-ONLY)
|
|
# ------------------------------------------------------------
|
|
def sql_inc_downloaded(book_idx, amount=1):
|
|
conn = _connect()
|
|
cur = conn.cursor()
|
|
cur.execute(
|
|
"""
|
|
UPDATE books
|
|
SET downloaded = COALESCE(downloaded,0) + ?
|
|
WHERE book_idx = ?
|
|
""",
|
|
(amount, book_idx),
|
|
)
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
|
|
def sql_inc_parsed(book_idx, amount=1):
|
|
conn = _connect()
|
|
cur = conn.cursor()
|
|
cur.execute(
|
|
"""
|
|
UPDATE books
|
|
SET parsed = COALESCE(parsed,0) + ?
|
|
WHERE book_idx = ?
|
|
""",
|
|
(amount, book_idx),
|
|
)
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
|
|
def sql_inc_audio_done(book_idx, amount=1):
|
|
log(f"[DB-SQL] Incrementing audio_done for {book_idx} by {amount}")
|
|
conn = _connect()
|
|
cur = conn.cursor()
|
|
cur.execute(
|
|
"""
|
|
UPDATE books
|
|
SET audio_done = COALESCE(audio_done,0) + ?
|
|
WHERE book_idx = ?
|
|
""",
|
|
(amount, book_idx),
|
|
)
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
|
|
def sql_inc_audio_skipped(book_idx, amount=1):
|
|
log(f"[DB-SQL] Incrementing audio_skipped for {book_idx} by {amount}")
|
|
conn = _connect()
|
|
cur = conn.cursor()
|
|
cur.execute(
|
|
"""
|
|
UPDATE books
|
|
SET audio_skipped = COALESCE(audio_skipped,0) + ?
|
|
WHERE book_idx = ?
|
|
""",
|
|
(amount, book_idx),
|
|
)
|
|
conn.commit()
|
|
conn.close()
|