Handle outbox email ids properly; fix #7453

This commit is contained in:
Charles Lindsay 2013-09-11 12:03:52 -07:00
parent adf9b4dad5
commit f91ad80283
4 changed files with 55 additions and 32 deletions

View file

@ -603,9 +603,9 @@ public class Geary.App.ConversationMonitor : BaseObject {
}
private async void process_email_complete_async(ProcessJobContext job) {
Gee.Collection<Geary.App.Conversation> added;
Gee.MultiMap<Geary.App.Conversation, Geary.Email> appended;
Gee.Collection<Conversation> removed_due_to_merge;
Gee.Collection<Geary.App.Conversation>? added = null;
Gee.MultiMap<Geary.App.Conversation, Geary.Email>? appended = null;
Gee.Collection<Conversation>? removed_due_to_merge = null;
try {
yield conversations.add_all_emails_async(job.emails.values, this, folder.path, out added, out appended,
out removed_due_to_merge, null);
@ -615,14 +615,18 @@ public class Geary.App.ConversationMonitor : BaseObject {
// fall-through
}
foreach (Conversation conversation in removed_due_to_merge)
notify_conversation_removed(conversation);
if (removed_due_to_merge != null) {
foreach (Conversation conversation in removed_due_to_merge)
notify_conversation_removed(conversation);
}
if (added.size > 0)
if (added != null && added.size > 0)
notify_conversations_added(added);
foreach (Geary.App.Conversation conversation in appended.get_keys())
notify_conversation_appended(conversation, appended.get(conversation));
if (appended != null) {
foreach (Geary.App.Conversation conversation in appended.get_keys())
notify_conversation_appended(conversation, appended.get(conversation));
}
if (job.inside_scan)
notify_scan_completed();

View file

@ -867,15 +867,20 @@ private class Geary.ImapDB.Account : BaseObject {
* would be empty. Only throw database errors et al., not errors due to
* the email id not being found.
*/
public async Gee.MultiMap<Geary.ImapDB.EmailIdentifier, Geary.FolderPath>? get_containing_folders_async(
Gee.Collection<Geary.ImapDB.EmailIdentifier> ids, Cancellable? cancellable) throws Error {
Gee.HashMultiMap<Geary.ImapDB.EmailIdentifier, Geary.FolderPath> map
= new Gee.HashMultiMap<Geary.ImapDB.EmailIdentifier, Geary.FolderPath>();
public async Gee.MultiMap<Geary.EmailIdentifier, Geary.FolderPath>? get_containing_folders_async(
Gee.Collection<Geary.EmailIdentifier> ids, Cancellable? cancellable) throws Error {
Gee.HashMultiMap<Geary.EmailIdentifier, Geary.FolderPath> map
= new Gee.HashMultiMap<Geary.EmailIdentifier, Geary.FolderPath>();
yield db.exec_transaction_async(Db.TransactionType.RO, (cx, cancellable) => {
foreach (Geary.ImapDB.EmailIdentifier id in ids) {
Gee.Set<Geary.FolderPath>? folders = do_find_email_folders(cx, id.message_id, cancellable);
foreach (Geary.EmailIdentifier id in ids) {
ImapDB.EmailIdentifier? imap_db_id = id as ImapDB.EmailIdentifier;
if (imap_db_id == null)
continue;
Gee.Set<Geary.FolderPath>? folders = do_find_email_folders(
cx, imap_db_id.message_id, cancellable);
if (folders != null) {
Geary.Collection.multi_map_set_all<Geary.ImapDB.EmailIdentifier,
Geary.Collection.multi_map_set_all<Geary.EmailIdentifier,
Geary.FolderPath>(map, id, folders);
}
}
@ -883,6 +888,8 @@ private class Geary.ImapDB.Account : BaseObject {
return Db.TransactionOutcome.DONE;
}, cancellable);
yield outbox.add_to_containing_folders_async(ids, map, cancellable);
return (map.size == 0 ? null : map);
}

View file

@ -101,6 +101,25 @@ private class Geary.SmtpOutboxFolder : Geary.AbstractLocalFolder, Geary.FolderSu
high = outbox_high;
}
public async void add_to_containing_folders_async(Gee.Collection<Geary.EmailIdentifier> ids,
Gee.HashMultiMap<Geary.EmailIdentifier, Geary.FolderPath> map, Cancellable? cancellable) throws Error {
yield db.exec_transaction_async(Db.TransactionType.RO, (cx, cancellable) => {
foreach (Geary.EmailIdentifier id in ids) {
SmtpOutboxEmailIdentifier? outbox_id = id as SmtpOutboxEmailIdentifier;
if (outbox_id == null)
continue;
OutboxRow? row = do_fetch_row_by_ordering(cx, outbox_id.ordering, cancellable);
if (row == null)
continue;
map.set(id, path);
}
return Db.TransactionOutcome.DONE;
}, cancellable);
}
// Used solely for debugging, hence "(no subject)" not marked for translation
private static string message_subject(RFC822.Message message) {
return (message.subject != null && !String.is_empty(message.subject.to_string()))
@ -290,15 +309,12 @@ private class Geary.SmtpOutboxFolder : Geary.AbstractLocalFolder, Geary.FolderSu
// immediately add to outbox queue for delivery
outbox_queue.send(row);
// notify only if opened
if (is_open()) {
Gee.List<SmtpOutboxEmailIdentifier> list = new Gee.ArrayList<SmtpOutboxEmailIdentifier>();
list.add(row.outbox_id);
notify_email_appended(list);
notify_email_locally_appended(list);
notify_email_count_changed(email_count, CountChangeReason.APPENDED);
}
Gee.List<SmtpOutboxEmailIdentifier> list = new Gee.ArrayList<SmtpOutboxEmailIdentifier>();
list.add(row.outbox_id);
notify_email_appended(list);
notify_email_locally_appended(list);
notify_email_count_changed(email_count, CountChangeReason.APPENDED);
return row.outbox_id;
}
@ -339,7 +355,7 @@ private class Geary.SmtpOutboxFolder : Geary.AbstractLocalFolder, Geary.FolderSu
} else {
stmt = cx.prepare(
"SELECT id, ordering, message FROM SmtpOutboxTable ORDER BY ordering %s LIMIT ?".printf(dir));
stmt.bind_int(1, count);
stmt.bind_int(0, count);
}
Db.Result results = stmt.exec(cancellable);
@ -474,11 +490,8 @@ private class Geary.SmtpOutboxFolder : Geary.AbstractLocalFolder, Geary.FolderSu
if (removed.size == 0)
return false;
// notify only if opened
if (is_open()) {
notify_email_removed(removed);
notify_email_count_changed(final_count, CountChangeReason.REMOVED);
}
notify_email_removed(removed);
notify_email_count_changed(final_count, CountChangeReason.REMOVED);
return true;
}

View file

@ -591,8 +591,7 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount {
public override async Gee.MultiMap<Geary.EmailIdentifier, Geary.FolderPath>? get_containing_folders_async(
Gee.Collection<Geary.EmailIdentifier> ids, Cancellable? cancellable) throws Error {
// TODO: also handle other types of EmailIdentifiers, not just ImapDB.
return yield local.get_containing_folders_async(check_ids(ids), cancellable);
return yield local.get_containing_folders_async(ids, cancellable);
}
private void on_login_failed(Geary.Credentials? credentials) {