- def purge_deleteds(cls, conn: DbConn) -> None:
- """For all of .is_flag_set("deleted"), remove file _and_ DB entry."""
- for file in cls.get_all_deleted(conn):
- if file.present:
- file.unlink_locally()
- print(f'SYNC: purging off DB: {file.digest.b64} ({file.rel_path})')
- conn.exec(f'DELETE FROM {cls._table_name} WHERE digest =',
- (file.digest.bytes,))
+ def purge_deleteds(cls, conn: DbConn) -> list[Hash]:
+ """Purge all with .last_update < a respective entry in delete table."""
+ too_early = '2000-01-01 00:00:00.0'
+ del_req_by_timestamp: dict[Hash, DatetimeStr] = {}
+ for del_req in FileDeletionRequest.get_all(conn):
+ if del_req_by_timestamp.get(del_req.digest, too_early
+ ) < del_req.last_update:
+ del_req_by_timestamp[del_req.digest] = del_req.last_update
+ deleteds: list[Hash] = []
+ for file in [file for file in cls.get_all(conn)
+ if del_req_by_timestamp.get(file.digest, too_early
+ ) > file.last_update]:
+ deleteds += [file.digest]
+ file.purge(conn)
+ return deleteds
+
+ def delete(self, conn: DbConn) -> None:
+ """Add/update into deletion request table, then purge locally."""
+ FileDeletionRequest(self.digest, _now_string()).save(conn)
+ self.purge(conn)
+
+
+class FileDeletionRequest(DbData):
+ """Collect file deletion requests in their own table, for syncability."""
+ id_name = 'digest'
+ _table_name = 'file_deletion_requests'
+ _cols = ('digest', 'last_update')
+ digest: Hash
+ last_update: DatetimeStr
+
+ def __init__(self, digest: Hash, last_update: DatetimeStr) -> None:
+ self.digest = digest
+ self.last_update = last_update
+
+ def __str__(self) -> str:
+ return f'{self.digest.b64}:{self.last_update}'