Fixes problem Adam reported re: flag watcher failing
Problem was due to accumulation of messages marked for removal on local side not being (eventually) removed from MessageLocationTable. Can happen if folder is closed before EXPUNGE server data arrives, or if Geary is shut down or crashes before same. Folder normalization will deal with situation where locally removed message was not actually removed on server.
This commit is contained in:
parent
e8c5fc2e10
commit
85bb2ae76a
3 changed files with 32 additions and 10 deletions
|
|
@ -593,28 +593,23 @@ private class Geary.GenericImapFolder : Geary.AbstractFolder {
|
|||
to_string(), err.message);
|
||||
}
|
||||
|
||||
debug("do_replay_remove_message: remote_count=%d new_remote_count=%d local_count=%d remote_position=%d local_position=%d",
|
||||
remote_count, new_remote_count, local_count, remote_position, local_position);
|
||||
|
||||
bool marked = false;
|
||||
if (owned_id != null) {
|
||||
debug("do_replay_remove_message: removing from local store Email ID %s", owned_id.to_string());
|
||||
try {
|
||||
// Reflect change in the local store and notify subscribers
|
||||
yield local_folder.remove_marked_email_async(owned_id, out marked, null);
|
||||
|
||||
// TODO: Should move this signal to after the remote_count has changed
|
||||
if (!marked)
|
||||
notify_email_removed(new Geary.Singleton<Geary.EmailIdentifier>(owned_id));
|
||||
} catch (Error err2) {
|
||||
debug("Unable to remove message #%d from %s: %s", remote_position, to_string(),
|
||||
err2.message);
|
||||
}
|
||||
} else {
|
||||
debug("do_replay_remove_message: remote_position=%d unknown in local store (remote_count=%d new_remote_count=%d local_position=%d local_count=%d)",
|
||||
debug("do_replay_remove_message: remote_position=%d unknown in local store "
|
||||
+ "(remote_count=%d new_remote_count=%d local_position=%d local_count=%d)",
|
||||
remote_position, remote_count, new_remote_count, local_position, local_count);
|
||||
}
|
||||
|
||||
// for debugging
|
||||
int new_local_count = -1;
|
||||
try {
|
||||
new_local_count = yield local_folder.get_email_count_async();
|
||||
|
|
@ -626,11 +621,16 @@ private class Geary.GenericImapFolder : Geary.AbstractFolder {
|
|||
bool changed = (remote_count != new_remote_count);
|
||||
remote_count = new_remote_count;
|
||||
|
||||
if (!marked && owned_id != null)
|
||||
notify_email_removed(new Geary.Singleton<Geary.EmailIdentifier>(owned_id));
|
||||
|
||||
if (!marked && changed)
|
||||
notify_email_count_changed(remote_count, CountChangeReason.REMOVED);
|
||||
|
||||
debug("do_replay_remove_message: completed for %s (remote_count=%d local_count=%d new_local_count=%d marked=%s)",
|
||||
to_string(), remote_count, local_count, new_local_count, marked.to_string());
|
||||
debug("do_replay_remove_message: completed for %s "
|
||||
+ "(remote_count=%d local_count=%d new_local_count=%d remote_position=%d local_position=%d marked=%s)",
|
||||
to_string(), remote_count, local_count, new_local_count, remote_position, local_position,
|
||||
marked.to_string());
|
||||
}
|
||||
|
||||
private void on_remote_disconnected(Geary.Folder.CloseReason reason) {
|
||||
|
|
|
|||
|
|
@ -73,6 +73,13 @@ private class Geary.Sqlite.Folder : Object, Geary.ReferenceSemantics {
|
|||
throw new EngineError.ALREADY_OPEN("%s already open", to_string());
|
||||
|
||||
opened = true;
|
||||
|
||||
// Possible some messages were marked for removal in prior session and not properly deleted
|
||||
// (for example, if the EXPUNGE message didn't come back before closing the folder, or
|
||||
// the app is shut down or crashes) ... folder normalization will take care of messages that
|
||||
// are still in folder even if they're marked here, so go ahead and remove them from the
|
||||
// location table
|
||||
yield location_table.remove_all_marked_for_remove(null, folder_row.id, cancellable);
|
||||
}
|
||||
|
||||
public async void close_async(Cancellable? cancellable = null) throws Error {
|
||||
|
|
|
|||
|
|
@ -353,5 +353,20 @@ public class Geary.Sqlite.MessageLocationTable : Geary.Sqlite.Table {
|
|||
|
||||
return (bool) results.fetch_int(0);
|
||||
}
|
||||
|
||||
public async void remove_all_marked_for_remove(Transaction? transaction, int64 folder_id,
|
||||
Cancellable? cancellable) throws Error {
|
||||
Transaction locked = yield obtain_lock_async(transaction,
|
||||
"MessageLocationTable.remove_all_marked_for_remove", cancellable);
|
||||
|
||||
SQLHeavy.Query query = locked.prepare(
|
||||
"DELETE FROM MessageLocationTable WHERE folder_id=? AND remove_marker=1");
|
||||
query.bind_int64(0, folder_id);
|
||||
|
||||
yield query.execute_async(cancellable);
|
||||
locked.set_commit_required();
|
||||
|
||||
yield release_lock_async(transaction, locked, cancellable);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue