[geary/wip/search-fixes: 4/14] Mark Geary.Account.open_search as async and throwing an error
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/search-fixes: 4/14] Mark Geary.Account.open_search as async and throwing an error
- Date: Tue, 13 Aug 2019 21:39:53 +0000 (UTC)
commit d96f909fa9821f5a8bfcab7a1d787fcbd046fb46
Author: Michael Gratton <mike vee net>
Date: Sun Aug 4 21:35:46 2019 +1000
Mark Geary.Account.open_search as async and throwing an error
This lets us make the DB stemmer lookup async when constructing a
search query async and cancellable. Fix call sites.
.../conversation-viewer/conversation-viewer.vala | 53 ++++++++++++++++------
src/engine/api/geary-account.vala | 5 +-
.../imap-db/search/imap-db-search-folder.vala | 10 ++--
.../imap-db/search/imap-db-search-query.vala | 51 ++++++++++++---------
.../imap-engine/imap-engine-generic-account.vala | 7 ++-
test/engine/api/geary-account-mock.vala | 5 +-
6 files changed, 88 insertions(+), 43 deletions(-)
---
diff --git a/src/client/conversation-viewer/conversation-viewer.vala
b/src/client/conversation-viewer/conversation-viewer.vala
index dd3efb89..02af3646 100644
--- a/src/client/conversation-viewer/conversation-viewer.vala
+++ b/src/client/conversation-viewer/conversation-viewer.vala
@@ -27,7 +27,7 @@ public class ConversationViewer : Gtk.Stack, Geary.BaseInterface {
private Configuration config;
private Gee.Set<Geary.App.Conversation>? selection_while_composing = null;
-
+ private GLib.Cancellable? find_cancellable = null;
// Stack pages
[GtkChild]
@@ -269,8 +269,8 @@ public class ConversationViewer : Gtk.Stack, Geary.BaseInterface {
// Highlight matching terms from find if active, otherwise
// from the search folder if that's where we are at
- Geary.SearchQuery? query = get_find_search_query(
- conversation.base_folder.account
+ Geary.SearchQuery? query = yield get_find_search_query(
+ conversation.base_folder.account, null
);
if (query == null) {
Geary.SearchFolder? search_folder =
@@ -301,6 +301,11 @@ public class ConversationViewer : Gtk.Stack, Geary.BaseInterface {
// Remove any existing conversation list, cancelling its loading
private void remove_current_list() {
+ if (this.find_cancellable != null) {
+ this.find_cancellable.cancel();
+ this.find_cancellable = null;
+ }
+
if (this.current_list != null) {
this.current_list.cancel_conversation_load();
this.conversation_removed(this.current_list);
@@ -357,7 +362,34 @@ public class ConversationViewer : Gtk.Stack, Geary.BaseInterface {
base.set_visible_child(widget);
}
- private Geary.SearchQuery? get_find_search_query(Geary.Account account) {
+ private async void update_find_results() {
+ ConversationListBox? list = this.current_list;
+ if (list != null) {
+ if (this.find_cancellable != null) {
+ this.find_cancellable.cancel();
+ }
+ GLib.Cancellable cancellable = new GLib.Cancellable();
+ cancellable.cancelled.connect(() => {
+ list.search.cancel();
+ });
+ this.find_cancellable = cancellable;
+ try {
+ Geary.SearchQuery? query = yield get_find_search_query(
+ list.conversation.base_folder.account,
+ cancellable
+ );
+ if (query != null) {
+ yield list.search.highlight_matching_email(query);
+ }
+ } catch (GLib.Error err) {
+ warning("Error updating find results: %s", err.message);
+ }
+ }
+ }
+
+ private async Geary.SearchQuery? get_find_search_query(Geary.Account account,
+ GLib.Cancellable? cancellable)
+ throws GLib.Error {
Geary.SearchQuery? query = null;
if (this.conversation_find_bar.get_search_mode()) {
string text = this.conversation_find_entry.get_text().strip();
@@ -365,8 +397,8 @@ public class ConversationViewer : Gtk.Stack, Geary.BaseInterface {
// opening every message in the conversation as soon as
// the user presses a key
if (text.length >= 2) {
- query = account.open_search(
- text, this.config.get_search_strategy()
+ query = yield account.open_search(
+ text, this.config.get_search_strategy(), cancellable
);
}
}
@@ -412,14 +444,7 @@ public class ConversationViewer : Gtk.Stack, Geary.BaseInterface {
private void on_find_text_changed(Gtk.SearchEntry entry) {
this.conversation_find_next.set_sensitive(false);
this.conversation_find_prev.set_sensitive(false);
- if (this.current_list != null) {
- Geary.SearchQuery? query = get_find_search_query(
- this.current_list.conversation.base_folder.account
- );
- if (query != null) {
- this.current_list.search.highlight_matching_email.begin(query);
- }
- }
+ this.update_find_results.begin();
}
[GtkCallback]
diff --git a/src/engine/api/geary-account.vala b/src/engine/api/geary-account.vala
index ad368170..af97bfb1 100644
--- a/src/engine/api/geary-account.vala
+++ b/src/engine/api/geary-account.vala
@@ -457,7 +457,10 @@ public abstract class Geary.Account : BaseObject, Loggable {
*
* Dropping the last reference to the SearchQuery will close it.
*/
- public abstract Geary.SearchQuery open_search(string query, Geary.SearchQuery.Strategy strategy);
+ public abstract async Geary.SearchQuery open_search(string query,
+ SearchQuery.Strategy strategy,
+ GLib.Cancellable? cancellable)
+ throws GLib.Error;
/**
* Performs a search with the given query. Optionally, a list of folders not to search
diff --git a/src/engine/imap-db/search/imap-db-search-folder.vala
b/src/engine/imap-db/search/imap-db-search-folder.vala
index d387e0fa..b01d2575 100644
--- a/src/engine/imap-db/search/imap-db-search-folder.vala
+++ b/src/engine/imap-db/search/imap-db-search-folder.vala
@@ -159,9 +159,13 @@ private class Geary.ImapDB.SearchFolder : Geary.SearchFolder, Geary.FolderSuppor
}
}
- private async void set_search_query_async(string query, Geary.SearchQuery.Strategy strategy,
- Cancellable? cancellable) throws Error {
- Geary.SearchQuery search_query = account.open_search(query, strategy);
+ private async void set_search_query_async(string query,
+ Geary.SearchQuery.Strategy strategy,
+ Cancellable? cancellable)
+ throws GLib.Error {
+ Geary.SearchQuery search_query = yield account.open_search(
+ query, strategy, cancellable
+ );
int result_mutex_token = yield result_mutex.claim_async();
diff --git a/src/engine/imap-db/search/imap-db-search-query.vala
b/src/engine/imap-db/search/imap-db-search-query.vala
index 543eec18..35c71d7c 100644
--- a/src/engine/imap-db/search/imap-db-search-query.vala
+++ b/src/engine/imap-db/search/imap-db-search-query.vala
@@ -261,11 +261,11 @@ private class Geary.ImapDB.SearchQuery : Geary.SearchQuery {
// A list of all search terms, regardless of search op field name
private Gee.ArrayList<SearchTerm> all = new Gee.ArrayList<SearchTerm>();
- public SearchQuery(ImapDB.Account account,
- string query,
- Geary.SearchQuery.Strategy strategy) {
- base (query, strategy);
-
+ public async SearchQuery(ImapDB.Account account,
+ string query,
+ Geary.SearchQuery.Strategy strategy,
+ GLib.Cancellable? cancellable) {
+ base(query, strategy);
this.account = account;
switch (strategy) {
@@ -298,7 +298,7 @@ private class Geary.ImapDB.SearchQuery : Geary.SearchQuery {
break;
}
- prepare();
+ yield prepare(cancellable);
}
public Gee.Collection<string?> get_fields() {
@@ -403,7 +403,7 @@ private class Geary.ImapDB.SearchQuery : Geary.SearchQuery {
return phrases;
}
- private void prepare() {
+ private async void prepare(GLib.Cancellable? cancellable) {
// A few goals here:
// 1) Append an * after every term so it becomes a prefix search
// (see <https://www.sqlite.org/fts3.html#section_3>)
@@ -490,7 +490,7 @@ private class Geary.ImapDB.SearchQuery : Geary.SearchQuery {
// searching for [archive* OR archiv*] when that's
// the same as [archiv*]), otherwise search for
// both
- string? stemmed = stem_search_term(s);
+ string? stemmed = yield stem_search_term(s, cancellable);
string? sql_stemmed = null;
if (stemmed != null) {
@@ -580,7 +580,8 @@ private class Geary.ImapDB.SearchQuery : Geary.SearchQuery {
*
* Otherwise, the stem for the term is returned.
*/
- private string? stem_search_term(string term) {
+ private async string? stem_search_term(string term,
+ GLib.Cancellable? cancellable) {
if (!this.allow_stemming)
return null;
@@ -590,19 +591,25 @@ private class Geary.ImapDB.SearchQuery : Geary.SearchQuery {
string? stemmed = null;
try {
- Db.Statement stmt = this.account.db.prepare("""
- SELECT token
- FROM TokenizerTable
- WHERE input=?
- """);
- stmt.bind_string(0, term);
-
- // get stemmed string; if no result, fall through
- Db.Result result = stmt.exec();
- if (!result.finished)
- stemmed = result.string_at(0);
- else
- debug("No stemmed term returned for \"%s\"", term);
+ yield this.account.db.exec_transaction_async(RO,
+ (cx, cancellable) => {
+ Db.Statement stmt = cx.prepare("""
+ SELECT token
+ FROM TokenizerTable
+ WHERE input=?
+ """);
+ stmt.bind_string(0, term);
+
+ // get stemmed string; if no result, fall through
+ Db.Result result = stmt.exec(cancellable);
+ if (!result.finished) {
+ stemmed = result.string_at(0);
+ } else {
+ debug("No stemmed term returned for \"%s\"", term);
+ }
+ return COMMIT;
+ }, cancellable
+ );
} catch (Error err) {
debug("Unable to query tokenizer table for stemmed term for \"%s\": %s", term, err.message);
diff --git a/src/engine/imap-engine/imap-engine-generic-account.vala
b/src/engine/imap-engine/imap-engine-generic-account.vala
index 19c97f67..c5ada125 100644
--- a/src/engine/imap-engine/imap-engine-generic-account.vala
+++ b/src/engine/imap-engine/imap-engine-generic-account.vala
@@ -547,8 +547,11 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
return yield local.fetch_email_async(check_id(email_id), required_fields, cancellable);
}
- public override Geary.SearchQuery open_search(string query, SearchQuery.Strategy strategy) {
- return new ImapDB.SearchQuery(local, query, strategy);
+ public override async Geary.SearchQuery open_search(string query,
+ SearchQuery.Strategy strategy,
+ GLib.Cancellable? cancellable)
+ throws GLib.Error {
+ return yield new ImapDB.SearchQuery(local, query, strategy, cancellable);
}
public override async Gee.Collection<Geary.EmailIdentifier>? local_search_async(Geary.SearchQuery query,
diff --git a/test/engine/api/geary-account-mock.vala b/test/engine/api/geary-account-mock.vala
index 2159df5a..e2fc7f4f 100644
--- a/test/engine/api/geary-account-mock.vala
+++ b/test/engine/api/geary-account-mock.vala
@@ -213,7 +213,10 @@ public class Geary.MockAccount : Account, MockObject {
);
}
- public override SearchQuery open_search(string query, SearchQuery.Strategy strategy) {
+ public override async SearchQuery open_search(string query,
+ SearchQuery.Strategy strategy,
+ GLib.Cancellable? cancellable)
+ throws GLib.Error {
return new MockSearchQuery();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]