[geary/wip/721828-undo] Further work
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/721828-undo] Further work
- Date: Wed, 7 Jan 2015 20:24:42 +0000 (UTC)
commit 5a45ac3c7c87ee39fe736f14e32ee4f3a9b54efd
Author: Jim Nelson <jim yorba org>
Date: Wed Jan 7 12:24:31 2015 -0800
Further work
But it's a long way to go to make this work like we want it to.
src/engine/imap-db/imap-db-folder.vala | 21 +++++-
.../imap-engine/imap-engine-minimal-folder.vala | 65 +++++++++++++++++++-
.../replay-ops/imap-engine-move-email.vala | 18 +++++-
3 files changed, 97 insertions(+), 7 deletions(-)
---
diff --git a/src/engine/imap-db/imap-db-folder.vala b/src/engine/imap-db/imap-db-folder.vala
index 178fba3..1f0935e 100644
--- a/src/engine/imap-db/imap-db-folder.vala
+++ b/src/engine/imap-db/imap-db-folder.vala
@@ -732,6 +732,7 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
Cancellable? cancellable) throws Error {
// store in hash set for closure, which potentially modifies the collection
Gee.HashSet<ImapDB.EmailIdentifier> id_set = traverse<ImapDB.EmailIdentifier>(ids).to_hash_set();
+ debug("LINKING %d UIDs to %s", id_set.size, to_string());
int unread_count = 0;
yield db.exec_transaction_async(Db.TransactionType.RW, (cx) => {
@@ -740,7 +741,9 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
Gee.Iterator<ImapDB.EmailIdentifier> iter = id_set.iterator();
while (iter.next()) {
ImapDB.EmailIdentifier id = iter.get();
- if (id.uid == null) {
+ if (!id.has_uid()) {
+ debug("\nNO UID IN LINKED ID %s", id.to_string());
+
iter.remove();
continue;
@@ -758,6 +761,8 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
Db.Result result = stmt.exec(cancellable);
if (!result.finished) {
+ debug("\nUID %s ALREADY LINKED TO %s", id.uid.to_string(), to_string());
+
// clear remove marker, if set
do_mark_unmark_removed(cx, iterate<Imap.UID>(id.uid).to_array_list(), false,
cancellable);
@@ -776,6 +781,8 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
stmt.bind_bool(3, false);
stmt.exec(cancellable);
+
+ debug("\n%s: LINKED %s", to_string(), id.uid.to_string());
}
// Now with messages linked to folder, update unread count with ids that were linked
@@ -989,8 +996,7 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
properties.set_status_unseen(properties.email_unread - 1);
}
- // Mark messages as removed (but not expunged) from the folder. Marked messages are skipped
- // on most operations unless ListFlags.INCLUDE_MARKED_REMOVED is true. Use detach_email_async()
+ // Mark messages as removed (but not expunged) from the folder. Use unlink_email_async()
// to formally remove the messages from the folder.
//
// Returns a collection of ImapDB.EmailIdentifiers *with the UIDs set* for this folder.
@@ -1003,8 +1009,12 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
yield db.exec_transaction_async(Db.TransactionType.RW, (cx) => {
Gee.List<LocationIdentifier?> locs = do_get_locations_for_ids(cx, ids,
ListFlags.INCLUDE_MARKED_FOR_REMOVE, cancellable);
- if (locs == null || locs.size == 0)
+ if (locs == null || locs.size == 0) {
+ debug("\n%s: NO LOCATIONS RETURNED FOR %d IDS (%s)", to_string(), ids.size,
+ traverse<ImapDB.EmailIdentifier>(ids).first().to_string());
+
return Db.TransactionOutcome.DONE;
+ }
unread_count = do_get_unread_count_for_ids(cx, ids, cancellable);
@@ -1195,6 +1205,9 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
stmt.exec(cancellable);
+ debug("\n%s: MARKED REMOVED=%s: %s", to_string(), mark_removed.to_string(),
+ uid.to_string());
+
// keep folder_id and mark_removed, replace UID each iteration
stmt.reset(Db.ResetScope.SAVE_BINDINGS);
}
diff --git a/src/engine/imap-engine/imap-engine-minimal-folder.vala
b/src/engine/imap-engine/imap-engine-minimal-folder.vala
index d2a3e7a..96fd55f 100644
--- a/src/engine/imap-engine/imap-engine-minimal-folder.vala
+++ b/src/engine/imap-engine/imap-engine-minimal-folder.vala
@@ -45,6 +45,7 @@ private class Geary.ImapEngine.MinimalFolder : Geary.AbstractFolder, Geary.Folde
private int remote_count = -1;
private uint open_remote_timer_id = 0;
private int reestablish_delay_msec = DEFAULT_REESTABLISH_DELAY_MSEC;
+ private Gee.HashSet<ImapDB.EmailIdentifier> predicted_ids = new Gee.HashSet<ImapDB.EmailIdentifier>();
public MinimalFolder(GenericAccount account, Imap.Account remote, ImapDB.Account local,
ImapDB.Folder local_folder, SpecialFolderType special_folder_type) {
@@ -72,11 +73,71 @@ private class Geary.ImapEngine.MinimalFolder : Geary.AbstractFolder, Geary.Folde
local_folder.email_complete.disconnect(on_email_complete);
}
- public override void notify_email_removed(Gee.Collection<Geary.EmailIdentifier> ids) {
- // fire base signal first
+ internal override void notify_email_removed(Gee.Collection<Geary.EmailIdentifier> ids) {
+ predicted_ids_fulfilled(ids, false);
+
base.notify_email_removed(ids);
}
+ internal override void notify_email_appended(Gee.Collection<Geary.EmailIdentifier> ids) {
+ predicted_ids_fulfilled(ids, true);
+
+ base.notify_email_appended(ids);
+ }
+
+ internal override void notify_email_locally_appended(Gee.Collection<Geary.EmailIdentifier> ids) {
+ predicted_ids_fulfilled(ids, true);
+
+ base.notify_email_locally_appended(ids);
+ }
+
+ internal override void notify_email_inserted(Gee.Collection<Geary.EmailIdentifier> ids) {
+ predicted_ids_fulfilled(ids, true);
+
+ base.notify_email_inserted(ids);
+ }
+
+ internal override void notify_email_locally_inserted(Gee.Collection<Geary.EmailIdentifier> ids) {
+ predicted_ids_fulfilled(ids, true);
+
+ base.notify_email_locally_inserted(ids);
+ }
+
+ internal override void notify_predict_email_inserted(Gee.Collection<Geary.EmailIdentifier> ids) {
+ // Add all predicted identifiers to an internal table, indicating no UID is available yet
+ predicted_ids.add_all(traverse<Geary.EmailIdentifier>(ids)
+ .cast_object<ImapDB.EmailIdentifier>()
+ .to_array_list()
+ );
+
+ base.notify_predict_email_inserted(ids);
+ }
+
+ internal override void notify_unpredict_email_inserted(Gee.Collection<Geary.EmailIdentifier> ids) {
+ predicted_ids_fulfilled(ids, false);
+
+ base.notify_unpredict_email_inserted(ids);
+ }
+
+ private void predicted_ids_fulfilled(Gee.Collection<Geary.EmailIdentifier> ids, bool arrived) {
+ Gee.ArrayList<ImapDB.EmailIdentifier> reported_ids = traverse<Geary.EmailIdentifier>(ids)
+ .cast_object<ImapDB.EmailIdentifier>()
+ .to_array_list();
+
+ // only want to report identifiers still waiting on; all the signals that feed into this
+ // method may report the same identifier multiple times
+ Gee.Iterator<ImapDB.EmailIdentifier> iter = reported_ids.iterator();
+ while (iter.next()) {
+ if (predicted_ids.contains(iter.get())
+ predicted_ids.remove(iter.get());
+ else
+ iter.remove();
+
+ if (!iter.get().has_uid())
+ debug("%s: NO UID ON REPORTED ID %s", to_string(), iter.get().to_string());
+ }
+ }
+
public void set_special_folder_type(SpecialFolderType new_type) {
SpecialFolderType old_type = _special_folder_type;
_special_folder_type = new_type;
diff --git a/src/engine/imap-engine/replay-ops/imap-engine-move-email.vala
b/src/engine/imap-engine/replay-ops/imap-engine-move-email.vala
index 4a6c61b..71ba8b6 100644
--- a/src/engine/imap-engine/replay-ops/imap-engine-move-email.vala
+++ b/src/engine/imap-engine/replay-ops/imap-engine-move-email.vala
@@ -45,8 +45,15 @@ private class Geary.ImapEngine.MoveEmail : Geary.ImapEngine.SendReplayOperation
original_count = to_move.size;
moved_ids = yield engine.local_folder.mark_removed_async(to_move, true, cancellable);
- if (moved_ids == null || moved_ids.size == 0)
+ if (moved_ids == null || moved_ids.size == 0) {
+ debug("\n%s: not moving %d emails to %s: not found (%s)", engine.to_string(),
+ to_move.size, destination.to_string(), to_move[0].to_string());
+
return ReplayOperation.Status.COMPLETED;
+ }
+
+ debug("\n%s: MARKED %d AS REMOVED (%s)", engine.to_string(), moved_ids.size,
+ traverse<ImapDB.EmailIdentifier>(moved_ids).first().to_string());
engine.notify_email_removed(moved_ids);
@@ -79,6 +86,11 @@ private class Geary.ImapEngine.MoveEmail : Geary.ImapEngine.SendReplayOperation
if (moved_ids.size == 0)
return ReplayOperation.Status.COMPLETED;
+ //
+ // TODO: Allow for cancelling move of destination predicted id's if they're moved or removed
+ // later?
+ //
+
// don't use Cancellable throughout I/O operations in order to assure transaction completes
// fully
if (cancellable != null && cancellable.is_cancelled())
@@ -106,6 +118,8 @@ private class Geary.ImapEngine.MoveEmail : Geary.ImapEngine.SendReplayOperation
while (iter.next()) {
Imap.UID source_uid = iter.get_key();
if (source_uid_to_source_id.has_key(source_uid)) {
+ debug("\nMOVE: %s -> %s", source_uid.to_string(), iter.get_value().to_string());
+
ImapDB.EmailIdentifier source_id = source_uid_to_source_id[source_uid];
acc_ids.add(new ImapDB.EmailIdentifier(source_id.message_id, iter.get_value()));
@@ -124,6 +138,8 @@ private class Geary.ImapEngine.MoveEmail : Geary.ImapEngine.SendReplayOperation
// Note that this doesn't require dest_folder be open because we're going straight
// to the database...dest_folder will announce to its subscribers changes when
// normalization/notification occurs via IMAP
+ debug("\n\n%s: LINKING TO %s: %s", engine.local_folder.to_string(),
dest_folder.to_string(),
+ traverse<ImapDB.EmailIdentifier>(acc_ids).first().to_string());
yield dest_folder.local_folder.link_multiple_emails_async(acc_ids, null);
destination_ids = acc_ids;
} catch (Error err) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]