from __future__ import annotations import json import sqlite3 from typing import Any class HeavenRepository: def add( self, connection: sqlite3.Connection, *, user_id: int, mode: str, reading_date: str, subject_key: str, result: dict[str, Any], created_at: str, ) -> int: cursor = connection.execute( """ INSERT INTO heaven_readings ( user_id, mode, reading_date, subject_key, result_json, interpretation_status, created_at, updated_at ) VALUES (?, ?, ?, ?, ?, 'pending', ?, ?) """, ( user_id, mode, reading_date, subject_key, json.dumps(result, ensure_ascii=False, separators=(",", ":")), created_at, created_at, ), ) return int(cursor.lastrowid) def get( self, connection: sqlite3.Connection, user_id: int, reading_id: int ) -> sqlite3.Row | None: return connection.execute( "SELECT * FROM heaven_readings WHERE id = ? AND user_id = ?", (reading_id, user_id), ).fetchone() def latest_fortune( self, connection: sqlite3.Connection, user_id: int, reading_date: str ) -> sqlite3.Row | None: return connection.execute( """ SELECT * FROM heaven_readings WHERE user_id = ? AND mode = 'fortune' AND reading_date = ? ORDER BY id DESC LIMIT 1 """, (user_id, reading_date), ).fetchone() def ensure_fortune( self, connection: sqlite3.Connection, *, user_id: int, reading_date: str, result: dict[str, Any], created_at: str, ) -> tuple[sqlite3.Row, bool]: cursor = connection.execute( """ INSERT OR IGNORE INTO heaven_readings ( user_id, mode, reading_date, subject_key, result_json, interpretation_status, created_at, updated_at ) VALUES (?, 'fortune', ?, '', ?, 'pending', ?, ?) """, ( user_id, reading_date, json.dumps(result, ensure_ascii=False, separators=(",", ":")), created_at, created_at, ), ) row = self.latest_fortune(connection, user_id, reading_date) if row is None: raise RuntimeError("每日解运记录写入失败") return row, cursor.rowcount == 0 def list( self, connection: sqlite3.Connection, user_id: int, mode: str | None, reading_date: str | None, limit: int = 60, ) -> tuple[sqlite3.Row, ...]: clauses = ["user_id = ?"] values: list[Any] = [user_id] if mode: clauses.append("mode = ?") values.append(mode) if reading_date: clauses.append("reading_date = ?") values.append(reading_date) values.append(limit) statement = ( f"SELECT * FROM heaven_readings WHERE {' AND '.join(clauses)} ORDER BY id DESC LIMIT ?" ) return tuple( connection.execute( statement, values, ).fetchall() ) def update_interpretation( self, connection: sqlite3.Connection, reading_id: int, user_id: int, content: str, status: str, request_id: str | None, updated_at: str, ) -> None: connection.execute( """ UPDATE heaven_readings SET interpretation = ?, interpretation_status = ?, request_id = ?, updated_at = ? WHERE id = ? AND user_id = ? """, (content, status, request_id, updated_at, reading_id, user_id), ) def delete(self, connection: sqlite3.Connection, user_id: int, reading_id: int) -> int: cursor = connection.execute( "DELETE FROM heaven_readings WHERE id = ? AND user_id = ?", (reading_id, user_id), ) return cursor.rowcount