[geary/wip/713150-conversations: 2/2] Add local_list_conversation_async to Geary.Account
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/713150-conversations: 2/2] Add local_list_conversation_async to Geary.Account
- Date: Thu, 19 Feb 2015 01:49:39 +0000 (UTC)
commit 9a80500ec1034c5e6da94ef18d02400d7941b1b7
Author: Jim Nelson <jim yorba org>
Date: Wed Feb 18 17:24:39 2015 -0800
Add local_list_conversation_async to Geary.Account
src/engine/api/geary-account.vala | 18 +++
src/engine/imap-db/imap-db-account.vala | 121 ++++++++++++++-----
.../imap-engine/imap-engine-generic-account.vala | 8 ++
3 files changed, 115 insertions(+), 32 deletions(-)
---
diff --git a/src/engine/api/geary-account.vala b/src/engine/api/geary-account.vala
index 1b5d72a..14031d6 100644
--- a/src/engine/api/geary-account.vala
+++ b/src/engine/api/geary-account.vala
@@ -332,6 +332,24 @@ public abstract class Geary.Account : BaseObject {
Cancellable? cancellable = null) throws Error;
/**
+ * Fetch all local messages associated with supplied { link EmailIdentifier}.
+ *
+ * This is usually a better choice that { link local_search_message_id_async) in the sense that
+ * the { link Account} is tasked to maintain internal lookup tables that speed lookup of
+ * associated emails. In particular, this call does ''not'' merely search for the
+ * { link RFC822.MessageID}s listed in this particular { link Email}. Rather, these lookup
+ * tables are built to index all local messages, meaning a single lookup should return the
+ * entire conversation.
+ *
+ * The particulars of the folder_blacklist and flag_blacklist parameters are the same as in
+ * local_search_message_id_async.
+ */
+ public abstract async Gee.MultiMap<Geary.Email, Geary.FolderPath?>? local_list_conversation_async(
+ Geary.EmailIdentifier email_id, Geary.Email.Field requested_fields, bool partial_ok,
+ Gee.Collection<Geary.FolderPath?> folder_blacklist, Geary.EmailFlags? flag_blacklist,
+ Cancellable? cancellable = null) throws Error;
+
+ /**
* Return a single email fulfilling the required fields. The email to pull
* is identified by an EmailIdentifier from a previous call to
* local_search_message_id_async() or local_search_async(). Throw
diff --git a/src/engine/imap-db/imap-db-account.vala b/src/engine/imap-db/imap-db-account.vala
index 9366ea0..3beee1f 100644
--- a/src/engine/imap-db/imap-db-account.vala
+++ b/src/engine/imap-db/imap-db-account.vala
@@ -659,38 +659,8 @@ private class Geary.ImapDB.Account : BaseObject {
Db.Result result = stmt.exec(cancellable);
while (!result.finished) {
- int64 id = result.int64_at(0);
- Geary.Email.Field db_fields;
- MessageRow row = Geary.ImapDB.Folder.do_fetch_message_row(
- cx, id, requested_fields, out db_fields, cancellable);
-
- // Ignore any messages that don't have the required fields.
- if (partial_ok || row.fields.fulfills(requested_fields)) {
- Geary.Email email = row.to_email(new Geary.ImapDB.EmailIdentifier(id, null));
- Geary.ImapDB.Folder.do_add_attachments(cx, email, id, cancellable);
-
- Gee.Set<Geary.FolderPath>? folders = do_find_email_folders(cx, id, true, cancellable);
- if (folders == null) {
- if (folder_blacklist == null || !folder_blacklist.contains(null))
- messages.set(email, null);
- } else {
- foreach (Geary.FolderPath path in folders) {
- // If it's in a blacklisted folder, we don't report
- // it at all.
- if (folder_blacklist != null && folder_blacklist.contains(path)) {
- messages.remove_all(email);
- break;
- } else {
- messages.set(email, path);
- }
- }
- }
-
- // Check for blacklisted flags.
- if (flag_blacklist != null && email.email_flags != null &&
- email.email_flags.contains_any(flag_blacklist))
- messages.remove_all(email);
- }
+ do_fetch_message(cx, result.int64_at(0), requested_fields, partial_ok, folder_blacklist,
+ flag_blacklist, messages, cancellable);
result.next(cancellable);
}
@@ -701,6 +671,93 @@ private class Geary.ImapDB.Account : BaseObject {
return (messages.size == 0 ? null : messages);
}
+ public async Gee.MultiMap<Geary.Email, Geary.FolderPath?>? list_conversation_async(
+ Geary.EmailIdentifier email_id, Email.Field requested_fields, bool partial_ok,
+ Gee.Collection<Geary.FolderPath?>? folder_blacklist, Geary.EmailFlags? flag_blacklist,
+ Cancellable? cancellable) throws Error {
+ check_open();
+
+ ImapDB.EmailIdentifier? imapdb_id = email_id as ImapDB.EmailIdentifier;
+ if (imapdb_id == null)
+ throw new EngineError.BAD_PARAMETERS("Invalid identifier supplied to list conversation");
+
+ Gee.HashMultiMap<Geary.Email, Geary.FolderPath?> messages
+ = new Gee.HashMultiMap<Geary.Email, Geary.FolderPath?>();
+
+ if (flag_blacklist != null)
+ requested_fields = requested_fields | Geary.Email.Field.FLAGS;
+
+ yield db.exec_transaction_async(Db.TransactionType.RO, (cx) => {
+ Db.Statement stmt = cx.prepare("""
+ SELECT conversation_id
+ FROM MessageTable
+ WHERE id = ?
+ """);
+ stmt.bind_rowid(0, imapdb_id.message_id);
+
+ Db.Result result = stmt.exec(cancellable);
+ if (result.finished || result.is_null_at(0))
+ return Db.TransactionOutcome.DONE;
+
+ int64 conversation_id = result.rowid_at(0);
+
+ stmt = cx.prepare("""
+ SELECT id
+ FROM MessageTable
+ WHERE conversation_id = ?
+ """);
+ stmt.bind_rowid(0, conversation_id);
+
+ result = stmt.exec(cancellable);
+ while (!result.finished) {
+ do_fetch_message(cx, result.int64_at(0), requested_fields, partial_ok, folder_blacklist,
+ flag_blacklist, messages, cancellable);
+
+ result.next(cancellable);
+ }
+
+ return Db.TransactionOutcome.DONE;
+ }, cancellable);
+
+ return messages.size > 0 ? messages : null;
+ }
+
+ private void do_fetch_message(Db.Connection cx, int64 message_id, Email.Field required_fields,
+ bool partial_ok, Gee.Collection<Geary.FolderPath?>? folder_blacklist, Geary.EmailFlags?
flag_blacklist,
+ Gee.HashMultiMap<Geary.Email, Geary.FolderPath?> messages, Cancellable? cancellable) throws Error {
+ Email.Field actual_fields;
+ MessageRow row = ImapDB.Folder.do_fetch_message_row(cx, message_id, required_fields,
+ out actual_fields, cancellable);
+
+ // Ignore any messages that don't have the required fields unless partial is ok
+ if (!partial_ok && !row.fields.fulfills(required_fields))
+ return;
+
+ Email email = row.to_email(new Geary.ImapDB.EmailIdentifier(message_id, null));
+ ImapDB.Folder.do_add_attachments(cx, email, message_id, cancellable);
+
+ // Add folders email is found in, respecting blacklist
+ Gee.Set<Geary.FolderPath>? folders = do_find_email_folders(cx, message_id, true, cancellable);
+ if (folders == null) {
+ if (folder_blacklist == null || !folder_blacklist.contains(null))
+ messages.set(email, null);
+ } else {
+ foreach (Geary.FolderPath path in folders) {
+ // If it's in a blacklisted folder, we don't report it at all.
+ if (folder_blacklist != null && folder_blacklist.contains(path)) {
+ messages.remove_all(email);
+ break;
+ } else {
+ messages.set(email, path);
+ }
+ }
+ }
+
+ // Check for blacklisted flags.
+ if (flag_blacklist != null && email.email_flags != null &&
email.email_flags.contains_any(flag_blacklist))
+ messages.remove_all(email);
+ }
+
private string? extract_field_from_token(string[] parts, ref string token) {
// Map of user-supplied search field names to column names.
Gee.HashMap<string, string> field_names = new Gee.HashMap<string, string>();
diff --git a/src/engine/imap-engine/imap-engine-generic-account.vala
b/src/engine/imap-engine/imap-engine-generic-account.vala
index d11f3b4..fa029e0 100644
--- a/src/engine/imap-engine/imap-engine-generic-account.vala
+++ b/src/engine/imap-engine/imap-engine-generic-account.vala
@@ -859,6 +859,14 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
message_id, requested_fields, partial_ok, folder_blacklist, flag_blacklist, cancellable);
}
+ public override async Gee.MultiMap<Geary.Email, Geary.FolderPath?>? local_list_conversation_async(
+ Geary.EmailIdentifier email_id, Geary.Email.Field requested_fields, bool partial_ok,
+ Gee.Collection<Geary.FolderPath?> folder_blacklist, Geary.EmailFlags? flag_blacklist,
+ Cancellable? cancellable = null) throws Error {
+ return yield local.list_conversation_async(email_id, requested_fields, partial_ok,
+ folder_blacklist, flag_blacklist, cancellable);
+ }
+
public override async Geary.Email local_fetch_email_async(Geary.EmailIdentifier email_id,
Geary.Email.Field required_fields, Cancellable? cancellable = null) throws Error {
return yield local.fetch_email_async(check_id(email_id), required_fields, cancellable);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]