from dataclasses import dataclass import asyncpg _LOAD = """ SELECT catchup_pts, catchup_qts, catchup_date FROM accounts WHERE account_id = $1 """ _SAVE = """ UPDATE accounts SET catchup_pts = $2, catchup_qts = $3, catchup_date = $4 WHERE account_id = $1 """ _CLEAR = """ UPDATE accounts SET catchup_pts = NULL, catchup_qts = NULL, catchup_date = NULL WHERE account_id = $1 """ @dataclass(frozen=True) class UpdateCursor: pts: int qts: int date: int async def load_cursor(pool: asyncpg.Pool, account_id: int) -> UpdateCursor | None: row = await pool.fetchrow(_LOAD, account_id) if row is None or row["catchup_pts"] is None: return None return UpdateCursor(row["catchup_pts"], row["catchup_qts"], row["catchup_date"]) async def save_cursor( pool: asyncpg.Pool, account_id: int, cursor: UpdateCursor ) -> None: await pool.execute(_SAVE, account_id, cursor.pts, cursor.qts, cursor.date) async def clear_cursor(pool: asyncpg.Pool, account_id: int) -> None: await pool.execute(_CLEAR, account_id)