diff --git a/src/db.rs b/src/db.rs index 85d8a4f..29ad0e4 100644 --- a/src/db.rs +++ b/src/db.rs @@ -536,14 +536,27 @@ impl Db { pub fn prune_entries(&self, older_than: i64) -> Result { let conn = self.conn.lock().unwrap(); let n = conn.execute( - "DELETE FROM entries WHERE flagged = 0 - AND coalesce(published, first_seen) < ?1 - AND NOT EXISTS ( - SELECT 1 FROM enclosures e - WHERE e.feed_id = entries.feed_id AND e.guid = entries.guid - AND e.path IS NOT NULL)", + "DELETE FROM entries + WHERE coalesce(published, first_seen) < ?1 + AND NOT EXISTS ( + SELECT 1 FROM enclosures e + WHERE e.feed_id = entries.feed_id AND e.guid = entries.guid + AND e.path IS NOT NULL) + -- Starred by anyone keeps it, the same rule the reaper follows. + AND NOT EXISTS ( + SELECT 1 FROM entry_state s + WHERE s.feed_id = entries.feed_id AND s.guid = entries.guid + AND s.flagged = 1)", [older_than], )?; + // Whatever went takes everyone's read state with it, rather than leaving rows + // pointing at an item that no longer exists. + conn.execute( + "DELETE FROM entry_state WHERE NOT EXISTS ( + SELECT 1 FROM entries e + WHERE e.feed_id = entry_state.feed_id AND e.guid = entry_state.guid)", + [], + )?; Ok(n) } } diff --git a/src/retention.rs b/src/retention.rs index de9b296..6ff3306 100644 --- a/src/retention.rs +++ b/src/retention.rs @@ -189,11 +189,13 @@ mod tests { fn prune_keeps_entries_that_still_have_a_file() { let db = Db::memory().unwrap(); db.exec_for_test( - "INSERT INTO entries (feed_id, guid, first_seen, read, flagged) VALUES - ('f', 'has-file', 100, 1, 0), - ('f', 'no-file', 100, 1, 0), - ('f', 'flagged', 100, 1, 1), - ('f', 'recent', 900, 1, 0); + "INSERT INTO users (id, name, is_admin, created) VALUES (1,'ray',1,0); + INSERT INTO entry_state (user_id, feed_id, guid, flagged) VALUES (1,'f','flagged',1); + INSERT INTO entries (feed_id, guid, first_seen) VALUES + ('f', 'has-file', 100), + ('f', 'no-file', 100), + ('f', 'flagged', 100), + ('f', 'recent', 900); INSERT INTO enclosures (id, feed_id, guid, url, path, state) VALUES (1, 'f', 'has-file', 'u1', '/tmp/x', 'done');", )