feat: local delete with seen marking for reader-side removal
This commit is contained in:
parent
234b75651f
commit
1ae2752eb0
1 changed files with 35 additions and 0 deletions
|
|
@ -571,6 +571,23 @@ impl Store {
|
|||
.is_some())
|
||||
}
|
||||
|
||||
/// Removes one message from the local store — the reader's delete, which
|
||||
/// the server-side DELETE (sec 6.1) knows nothing about. The id is marked
|
||||
/// seen (sec 10), so a copy still sitting on the server is fetched again
|
||||
/// without being re-stored: deleting locally must not resurrect the
|
||||
/// message on the next fetch.
|
||||
pub fn delete_local(&self, folder: &str, id: &[u8; ID_LEN]) -> Result<(), Error> {
|
||||
let table = match folder {
|
||||
"sent" => "sent",
|
||||
_ => "inbox",
|
||||
};
|
||||
self.db()
|
||||
.execute(&format!("DELETE FROM {table} WHERE id = ?1"), params![id])?;
|
||||
self.db()
|
||||
.execute("INSERT OR IGNORE INTO seen (id, at) VALUES (?1, ?2)", params![id, now()])?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// One folder, ordered by arrival or sending time. `folder` is "inbox",
|
||||
/// "requests", "sent" or "all".
|
||||
pub fn mail(&self, folder: &str) -> Result<Vec<Stored>, Error> {
|
||||
|
|
@ -887,6 +904,24 @@ mod tests {
|
|||
assert!(store.history("b@example.org").unwrap().is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn local_delete_marks_seen_so_a_refetch_does_not_restore() {
|
||||
let store = temp_store("delete-local");
|
||||
let id = [3u8; 32];
|
||||
store.store_inbox(&id, b"envelope", 100, false, true).unwrap();
|
||||
store.delete_local("inbox", &id).unwrap();
|
||||
assert!(store.mail("all").unwrap().is_empty());
|
||||
// Sec 10: the id is seen, so the fetch pipeline will not re-store
|
||||
// the still-kept server copy. (The dedupe is the pipeline's seen
|
||||
// check, not store_inbox's — a direct insert is a caller override.)
|
||||
assert!(store.seen(&id).unwrap());
|
||||
// Sent copies delete locally too, with the same protection.
|
||||
let sent_id = [4u8; 32];
|
||||
store.store_sent(&sent_id, "bob@example.org", b"sent", 50).unwrap();
|
||||
store.delete_local("sent", &sent_id).unwrap();
|
||||
assert!(store.mail("sent").unwrap().is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn in_memory_store_round_trips() {
|
||||
let store = Store::open_in_memory().expect("memory store opens");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue