rebuild(stage-11): deliver deterministic heaven workflows
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
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
|
||||
Reference in New Issue
Block a user