import sqlite3 from datetime import datetime, timedelta, timezone from typing import Optional from storage.metrics_db import DB_PATH _TABLE = "news_cache" def _init() -> None: DB_PATH.parent.mkdir(parents=True, exist_ok=True) with sqlite3.connect(DB_PATH) as conn: conn.execute(f""" CREATE TABLE IF NOT EXISTS {_TABLE} ( ticker TEXT NOT NULL, query TEXT NOT NULL, days INTEGER NOT NULL, payload TEXT NOT NULL, fetched_at TEXT NOT NULL, PRIMARY KEY (ticker, query, days) ) """) def get(ticker: str, query: str, days: int, ttl_seconds: int = 3600) -> Optional[str]: if not DB_PATH.exists(): return None try: with sqlite3.connect(DB_PATH) as conn: row = conn.execute( f"SELECT payload, fetched_at FROM {_TABLE} WHERE ticker=? AND query=? AND days=?", (ticker, query, days), ).fetchone() if row is None: return None payload_str, fetched_at_str = row fetched_at = datetime.fromisoformat(fetched_at_str) if datetime.now(timezone.utc) - fetched_at > timedelta(seconds=ttl_seconds): return None return payload_str except Exception: return None def put(ticker: str, query: str, days: int, payload: str) -> None: _init() try: with sqlite3.connect(DB_PATH) as conn: conn.execute( f"""INSERT INTO {_TABLE} (ticker, query, days, payload, fetched_at) VALUES (?, ?, ?, ?, ?) ON CONFLICT(ticker, query, days) DO UPDATE SET payload=excluded.payload, fetched_at=excluded.fetched_at""", (ticker, query, days, payload, datetime.now(timezone.utc).isoformat()), ) except Exception: pass