|
@@ -168,10 +168,15 @@ class SQLiteClusterStore:
|
|
|
CREATE TABLE IF NOT EXISTS feed_state (
|
|
CREATE TABLE IF NOT EXISTS feed_state (
|
|
|
feed_key TEXT PRIMARY KEY,
|
|
feed_key TEXT PRIMARY KEY,
|
|
|
last_hash TEXT NOT NULL,
|
|
last_hash TEXT NOT NULL,
|
|
|
|
|
+ last_item_count INTEGER,
|
|
|
updated_at TEXT NOT NULL
|
|
updated_at TEXT NOT NULL
|
|
|
)
|
|
)
|
|
|
"""
|
|
"""
|
|
|
)
|
|
)
|
|
|
|
|
+ try:
|
|
|
|
|
+ conn.execute("ALTER TABLE feed_state ADD COLUMN last_item_count INTEGER")
|
|
|
|
|
+ except sqlite3.OperationalError:
|
|
|
|
|
+ pass
|
|
|
|
|
|
|
|
conn.execute(
|
|
conn.execute(
|
|
|
"""
|
|
"""
|
|
@@ -335,12 +340,15 @@ class SQLiteClusterStore:
|
|
|
return row[0] if row else None
|
|
return row[0] if row else None
|
|
|
|
|
|
|
|
def set_feed_hash(self, feed_key: str, last_hash: str) -> None:
|
|
def set_feed_hash(self, feed_key: str, last_hash: str) -> None:
|
|
|
|
|
+ self.set_feed_state(feed_key, last_hash, None)
|
|
|
|
|
+
|
|
|
|
|
+ def set_feed_state(self, feed_key: str, last_hash: str, last_item_count: int | None = None) -> None:
|
|
|
now = datetime.now(timezone.utc).isoformat()
|
|
now = datetime.now(timezone.utc).isoformat()
|
|
|
with self._conn() as conn:
|
|
with self._conn() as conn:
|
|
|
conn.execute(
|
|
conn.execute(
|
|
|
- "INSERT INTO feed_state(feed_key, last_hash, updated_at) VALUES(?,?,?) "
|
|
|
|
|
- "ON CONFLICT(feed_key) DO UPDATE SET last_hash=excluded.last_hash, updated_at=excluded.updated_at",
|
|
|
|
|
- (feed_key, last_hash, now),
|
|
|
|
|
|
|
+ "INSERT INTO feed_state(feed_key, last_hash, last_item_count, updated_at) VALUES(?,?,?,?) "
|
|
|
|
|
+ "ON CONFLICT(feed_key) DO UPDATE SET last_hash=excluded.last_hash, last_item_count=excluded.last_item_count, updated_at=excluded.updated_at",
|
|
|
|
|
+ (feed_key, last_hash, last_item_count, now),
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
def get_feed_state(self, feed_key: str) -> dict | None:
|
|
def get_feed_state(self, feed_key: str) -> dict | None:
|
|
@@ -355,18 +363,13 @@ class SQLiteClusterStore:
|
|
|
return {"last_hash": row[0], "updated_at": row[1]}
|
|
return {"last_hash": row[0], "updated_at": row[1]}
|
|
|
|
|
|
|
|
def get_all_feed_states(self) -> list[dict[str, Any]]:
|
|
def get_all_feed_states(self) -> list[dict[str, Any]]:
|
|
|
- """All feed_state rows.
|
|
|
|
|
-
|
|
|
|
|
- The live writer keys feed state as ``newsfeeds:<sha1(comma_joined_urls)>``,
|
|
|
|
|
- so a hardcoded literal lookup never matches when more than one feed is
|
|
|
|
|
- configured. Use this for surfacing health information.
|
|
|
|
|
- """
|
|
|
|
|
|
|
+ """All feed_state rows."""
|
|
|
with self._conn() as conn:
|
|
with self._conn() as conn:
|
|
|
cur = conn.execute(
|
|
cur = conn.execute(
|
|
|
- "SELECT feed_key, last_hash, updated_at FROM feed_state ORDER BY updated_at DESC"
|
|
|
|
|
|
|
+ "SELECT feed_key, last_hash, last_item_count, updated_at FROM feed_state ORDER BY updated_at DESC"
|
|
|
)
|
|
)
|
|
|
return [
|
|
return [
|
|
|
- {"feed_key": row[0], "last_hash": row[1], "updated_at": row[2]}
|
|
|
|
|
|
|
+ {"feed_key": row[0], "last_hash": row[1], "last_item_count": row[2], "updated_at": row[3]}
|
|
|
for row in cur.fetchall()
|
|
for row in cur.fetchall()
|
|
|
]
|
|
]
|
|
|
|
|
|
|
@@ -548,8 +551,8 @@ class SQLiteClusterStore:
|
|
|
).fetchall())
|
|
).fetchall())
|
|
|
last_refresh = self.get_meta("last_refresh_at")
|
|
last_refresh = self.get_meta("last_refresh_at")
|
|
|
feeds = {}
|
|
feeds = {}
|
|
|
- for row in conn.execute("SELECT feed_key, last_hash, updated_at FROM feed_state"):
|
|
|
|
|
- feeds[row[0]] = {"last_hash": row[1], "updated_at": row[2]}
|
|
|
|
|
|
|
+ for row in conn.execute("SELECT feed_key, last_hash, last_item_count, updated_at FROM feed_state"):
|
|
|
|
|
+ feeds[row[0]] = {"last_hash": row[1], "last_item_count": row[2], "updated_at": row[3]}
|
|
|
last_prune = self.get_meta(META_LAST_PRUNE_AT)
|
|
last_prune = self.get_meta(META_LAST_PRUNE_AT)
|
|
|
prune_state = self.get_prune_state(
|
|
prune_state = self.get_prune_state(
|
|
|
pruning_enabled=NEWS_PRUNING_ENABLED,
|
|
pruning_enabled=NEWS_PRUNING_ENABLED,
|