[geary/wip/cx-reestablish] Don't require network access to open folder
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/cx-reestablish] Don't require network access to open folder
- Date: Fri, 23 Jan 2015 00:51:57 +0000 (UTC)
commit 9cfa626cda2154470921550a919faed18b864f68
Author: Jim Nelson <jim yorba org>
Date: Thu Jan 22 15:42:37 2015 -0800
Don't require network access to open folder
src/engine/imap-db/imap-db-folder.vala | 35 ++++++++++++++++++++
.../imap-engine/imap-engine-generic-account.vala | 4 +-
.../imap-engine/imap-engine-minimal-folder.vala | 8 +++-
src/engine/imap/api/imap-account.vala | 17 ++++++++-
4 files changed, 58 insertions(+), 6 deletions(-)
---
diff --git a/src/engine/imap-db/imap-db-folder.vala b/src/engine/imap-db/imap-db-folder.vala
index e1b5abe..1919515 100644
--- a/src/engine/imap-db/imap-db-folder.vala
+++ b/src/engine/imap-db/imap-db-folder.vala
@@ -173,6 +173,41 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
properties.set_select_examine_message_count(count);
}
+ public async Imap.StatusData fetch_status_data(ListFlags flags, Cancellable? cancellable) throws Error {
+ Imap.StatusData? status_data = null;
+ yield db.exec_transaction_async(Db.TransactionType.RO, (cx) => {
+ Db.Statement stmt = cx.prepare("""
+ SELECT uid_next, uid_validity, unread_count
+ FROM FolderTable
+ WHERE id = ?
+ """);
+ stmt.bind_rowid(0, folder_id);
+
+ Db.Result result = stmt.exec(cancellable);
+ if (result.finished)
+ return Db.TransactionOutcome.DONE;
+
+ int messages = do_get_email_count(cx, flags, cancellable);
+ Imap.UID? uid_next = !result.is_null_for("uid_next")
+ ? new Imap.UID(result.int64_for("uid_next"))
+ : null;
+ Imap.UIDValidity? uid_validity = !result.is_null_for("uid_validity")
+ ? new Imap.UIDValidity(result.int64_for("uid_validity"))
+ : null;
+
+ // Note that recent is not stored
+ status_data = new Imap.StatusData(new Imap.MailboxSpecifier.from_folder_path(path, null),
+ messages, 0, uid_next, uid_validity, result.int_for("unread_count"));
+
+ return Db.TransactionOutcome.DONE;
+ }, cancellable);
+
+ if (status_data == null)
+ throw new EngineError.NOT_FOUND("%s STATUS not found in database", path.to_string());
+
+ return status_data;
+ }
+
// Returns a Map with the created or merged email as the key and the result of the operation
// (true if created, false if merged) as the value. Note that every email
// object passed in's EmailIdentifier will be fully filled out by this
diff --git a/src/engine/imap-engine/imap-engine-generic-account.vala
b/src/engine/imap-engine/imap-engine-generic-account.vala
index ff441f2..9c4361c 100644
--- a/src/engine/imap-engine/imap-engine-generic-account.vala
+++ b/src/engine/imap-engine/imap-engine-generic-account.vala
@@ -340,7 +340,7 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
bool folder_created;
Imap.Folder remote_folder = yield remote.fetch_folder_async(folder.path,
- out folder_created, cancellable);
+ out folder_created, null, cancellable);
if (!folder_created) {
int unseen_count = yield remote.fetch_unseen_count_async(folder.path, cancellable);
@@ -517,7 +517,7 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
continue;
Imap.Folder remote_folder = (Imap.Folder) yield remote.fetch_folder_async(folder,
- null, cancellable);
+ null, null, cancellable);
yield local.clone_folder_async(remote_folder, cancellable);
}
diff --git a/src/engine/imap-engine/imap-engine-minimal-folder.vala
b/src/engine/imap-engine/imap-engine-minimal-folder.vala
index 19a2e37..66d39b7 100644
--- a/src/engine/imap-engine/imap-engine-minimal-folder.vala
+++ b/src/engine/imap-engine/imap-engine-minimal-folder.vala
@@ -608,9 +608,13 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
// carefully back out and possibly retry
Imap.Folder? opening_folder = null;
try {
+ debug("Fetching STATUS for remote %s from local", to_string());
+ Imap.StatusData local_status = yield local_folder.fetch_status_data(
+ ImapDB.Folder.ListFlags.NONE, cancellable);
+
debug("Fetching information for remote folder %s", to_string());
- opening_folder = yield remote.fetch_folder_async(local_folder.get_path(),
- null, cancellable);
+ opening_folder = yield remote.fetch_folder_async(local_folder.get_path(), null, local_status,
+ cancellable);
debug("Opening remote folder %s", opening_folder.to_string());
yield opening_folder.open_async(cancellable);
diff --git a/src/engine/imap/api/imap-account.vala b/src/engine/imap/api/imap-account.vala
index b7de768..42bbf71 100644
--- a/src/engine/imap/api/imap-account.vala
+++ b/src/engine/imap/api/imap-account.vala
@@ -219,8 +219,10 @@ private class Geary.Imap.Account : BaseObject {
}
}
+ // By supplying fallback STATUS, the Folder may be fetched if a network error occurs; if null,
+ // the network error is thrown
public async Imap.Folder fetch_folder_async(FolderPath path, out bool created,
- Cancellable? cancellable) throws Error {
+ StatusData? fallback_status_data, Cancellable? cancellable) throws Error {
check_open();
created = false;
@@ -245,7 +247,18 @@ private class Geary.Imap.Account : BaseObject {
Imap.Folder folder;
if (!mailbox_info.attrs.is_no_select) {
- StatusData status = yield fetch_status_async(folder_path, StatusDataType.all(), cancellable);
+ StatusData status;
+ try {
+ status = yield fetch_status_async(folder_path, StatusDataType.all(), cancellable);
+ } catch (Error err) {
+ if (fallback_status_data == null)
+ throw err;
+
+ debug("Unable to fetch STATUS for %s, using fallback from local: %s",
folder_path.to_string(),
+ err.message);
+
+ status = fallback_status_data;
+ }
folder = new Imap.Folder(folder_path, session_mgr, status, mailbox_info);
} else {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]