[geary/wip/720361-stemming] Small updates in preparation for landing this.
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/720361-stemming] Small updates in preparation for landing this.
- Date: Mon, 15 Dec 2014 23:35:27 +0000 (UTC)
commit 4b0a0e99c87b67c26e33682e27fd77953cd6d34a
Author: Jim Nelson <jim yorba org>
Date: Mon Dec 15 15:35:15 2014 -0800
Small updates in preparation for landing this.
src/client/application/geary-controller.vala | 2 +-
.../conversation-viewer/conversation-viewer.vala | 29 +++++++++++--
src/engine/abstract/geary-abstract-account.vala | 2 +-
src/engine/api/geary-account.vala | 4 +-
src/engine/api/geary-search-folder.vala | 14 +++---
src/engine/imap-db/imap-db-account.vala | 46 ++++----------------
.../imap-engine/imap-engine-generic-account.vala | 2 +-
7 files changed, 47 insertions(+), 52 deletions(-)
---
diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala
index 97bbeec..39f5c75 100644
--- a/src/client/application/geary-controller.vala
+++ b/src/client/application/geary-controller.vala
@@ -2512,7 +2512,7 @@ public class GearyController : Geary.BaseObject {
cancel_search(); // Stop any search in progress.
- folder.set_search_query(search_text, GearyApplication.instance.config.get_search_strategy(),
+ folder.search(search_text, GearyApplication.instance.config.get_search_strategy(),
cancellable_search);
main_window.folder_list.set_search(folder);
diff --git a/src/client/conversation-viewer/conversation-viewer.vala
b/src/client/conversation-viewer/conversation-viewer.vala
index ce113eb..5bb4847 100644
--- a/src/client/conversation-viewer/conversation-viewer.vala
+++ b/src/client/conversation-viewer/conversation-viewer.vala
@@ -457,11 +457,28 @@ public class ConversationViewer : Gtk.Box {
}
}
- private void on_search_text_changed(string? query) {
+ private void on_search_text_changed(Geary.SearchQuery? query) {
if (query != null)
highlight_search_terms.begin();
}
+ // This applies a fudge-factor set of matches when the database results
+ // aren't entirely satisfactory, such as when you search for an email
+ // address and the database tokenizes out the @ and ., etc. It's not meant
+ // to be comprehensive, just a little extra highlighting applied to make
+ // the results look a little closer to what you typed.
+ private void add_literal_matches(string raw_query, Gee.Set<string>? search_matches) {
+ foreach (string word in raw_query.split(" ")) {
+ if (word.has_suffix("\""))
+ word = word.substring(0, word.length - 1);
+ if (word.has_prefix("\""))
+ word = word.substring(1);
+
+ if (!Geary.String.is_empty_or_whitespace(word))
+ search_matches.add(word);
+ }
+ }
+
private async void highlight_search_terms() {
if (search_folder == null)
return;
@@ -475,8 +492,13 @@ public class ConversationViewer : Gtk.Box {
ids.add(email.id);
try {
- Gee.Collection<string>? search_matches = yield search_folder.get_search_matches_async(
+ Gee.Set<string>? search_matches = yield search_folder.get_search_matches_async(
ids, cancellable_fetch);
+ if (search_matches == null)
+ search_matches = new Gee.HashSet<string>();
+
+ if (search_folder.search_query != null)
+ add_literal_matches(search_folder.search_query.raw, search_matches);
// Webkit's highlighting is ... weird. In order to actually see
// all the highlighting you're applying, it seems necessary to
@@ -484,8 +506,7 @@ public class ConversationViewer : Gtk.Box {
// seems that shorter strings will overwrite longer ones, and
// you're left with incomplete highlighting.
Gee.ArrayList<string> ordered_matches = new Gee.ArrayList<string>();
- if (search_matches != null)
- ordered_matches.add_all(search_matches);
+ ordered_matches.add_all(search_matches);
ordered_matches.sort((a, b) => a.length - b.length);
foreach(string match in ordered_matches)
diff --git a/src/engine/abstract/geary-abstract-account.vala b/src/engine/abstract/geary-abstract-account.vala
index 4a224ca..ea24d18 100644
--- a/src/engine/abstract/geary-abstract-account.vala
+++ b/src/engine/abstract/geary-abstract-account.vala
@@ -124,7 +124,7 @@ public abstract class Geary.AbstractAccount : BaseObject, Geary.Account {
int limit = 100, int offset = 0, Gee.Collection<Geary.FolderPath?>? folder_blacklist = null,
Gee.Collection<Geary.EmailIdentifier>? search_ids = null, Cancellable? cancellable = null) throws
Error;
- public abstract async Gee.Collection<string>? get_search_matches_async(Geary.SearchQuery query,
+ public abstract async Gee.Set<string>? get_search_matches_async(Geary.SearchQuery query,
Gee.Collection<Geary.EmailIdentifier> ids, Cancellable? cancellable = null) throws Error;
public abstract async Gee.MultiMap<Geary.EmailIdentifier, Geary.FolderPath>?
get_containing_folders_async(
diff --git a/src/engine/api/geary-account.vala b/src/engine/api/geary-account.vala
index c579461..369bf04 100644
--- a/src/engine/api/geary-account.vala
+++ b/src/engine/api/geary-account.vala
@@ -352,9 +352,9 @@ public interface Geary.Account : BaseObject {
Gee.Collection<Geary.EmailIdentifier>? search_ids = null, Cancellable? cancellable = null) throws
Error;
/**
- * Given a list of mail IDs, returns a list of words that match for the query.
+ * Given a list of mail IDs, returns a set of casefolded words that match for the query.
*/
- public abstract async Gee.Collection<string>? get_search_matches_async(Geary.SearchQuery query,
+ public abstract async Gee.Set<string>? get_search_matches_async(Geary.SearchQuery query,
Gee.Collection<Geary.EmailIdentifier> ids, Cancellable? cancellable = null) throws Error;
/**
diff --git a/src/engine/api/geary-search-folder.vala b/src/engine/api/geary-search-folder.vala
index 4f51e43..c064a62 100644
--- a/src/engine/api/geary-search-folder.vala
+++ b/src/engine/api/geary-search-folder.vala
@@ -49,6 +49,8 @@ public class Geary.SearchFolder : Geary.AbstractLocalFolder, Geary.FolderSupport
}
}
+ public Geary.SearchQuery? search_query { get; private set; default = null; }
+
private Gee.HashSet<Geary.FolderPath?> exclude_folders = new Gee.HashSet<Geary.FolderPath?>();
private Geary.SpecialFolderType[] exclude_types = {
Geary.SpecialFolderType.SPAM,
@@ -56,7 +58,6 @@ public class Geary.SearchFolder : Geary.AbstractLocalFolder, Geary.FolderSupport
Geary.SpecialFolderType.DRAFTS,
// Orphan emails (without a folder) are also excluded; see ctor.
};
- private Geary.SearchQuery? search_query = null;
private Gee.TreeSet<ImapDB.SearchEmailIdentifier> search_results;
private Geary.Nonblocking.Mutex result_mutex = new Geary.Nonblocking.Mutex();
@@ -64,7 +65,7 @@ public class Geary.SearchFolder : Geary.AbstractLocalFolder, Geary.FolderSupport
* Fired when the search query has changed. This signal is fired *after* the search
* has completed.
*/
- public signal void search_query_changed(string? query);
+ public signal void search_query_changed(Geary.SearchQuery? query);
public SearchFolder(Account account) {
base();
@@ -203,7 +204,7 @@ public class Geary.SearchFolder : Geary.AbstractLocalFolder, Geary.FolderSupport
/**
* Sets the keyword string for this search.
*/
- public void set_search_query(string query, SearchQuery.Strategy strategy, Cancellable? cancellable =
null) {
+ public void search(string query, SearchQuery.Strategy strategy, Cancellable? cancellable = null) {
set_search_query_async.begin(query, strategy, cancellable, on_set_search_query_complete);
}
@@ -231,7 +232,7 @@ public class Geary.SearchFolder : Geary.AbstractLocalFolder, Geary.FolderSupport
result_mutex.release(ref result_mutex_token);
this.search_query = search_query;
- search_query_changed(search_query.raw);
+ search_query_changed(search_query);
if (error != null)
throw error;
@@ -426,13 +427,14 @@ public class Geary.SearchFolder : Geary.AbstractLocalFolder, Geary.FolderSupport
}
/**
- * Given a list of mail IDs, returns a list of words that match for the current
+ * Given a list of mail IDs, returns a set of casefolded words that match for the current
* search query.
*/
- public async Gee.Collection<string>? get_search_matches_async(
+ public async Gee.Set<string>? get_search_matches_async(
Gee.Collection<Geary.EmailIdentifier> ids, Cancellable? cancellable = null) throws Error {
if (search_query == null)
return null;
+
return yield account.get_search_matches_async(search_query, ids, cancellable);
}
diff --git a/src/engine/imap-db/imap-db-account.vala b/src/engine/imap-db/imap-db-account.vala
index ac20f8d..9a184d5 100644
--- a/src/engine/imap-db/imap-db-account.vala
+++ b/src/engine/imap-db/imap-db-account.vala
@@ -853,7 +853,7 @@ private class Geary.ImapDB.Account : BaseObject {
// some common search phrases we don't respect and therefore don't want to fall
// through to search results
string lower = s.down();
- switch (s.down()) {
+ switch (lower) {
case "":
case "and":
case "or":
@@ -886,6 +886,7 @@ private class Geary.ImapDB.Account : BaseObject {
// [archive* OR archiv*] when that's the same as [archiv*]), otherwise search for
// both
string? stemmed = stem_search_term(query, s);
+
string? sql_stemmed = null;
if (stemmed != null) {
sql_stemmed = "%s*".printf(stemmed);
@@ -930,7 +931,9 @@ private class Geary.ImapDB.Account : BaseObject {
//
// Note that this uses SQLite's "standard" query syntax for MATCH, where AND is implied
// (and would be treated as search term if included), parentheses are not allowed, and
- // OR has a higher precendence than AND.
+ // OR has a higher precendence than AND. So the above example in standard syntax is:
+ //
+ // party* OR parti* eventful* OR event*
StringBuilder builder = new StringBuilder();
foreach (SearchTerm term in terms) {
if (term.sql.size == 0)
@@ -1055,12 +1058,6 @@ private class Geary.ImapDB.Account : BaseObject {
if (limit > 0)
sql.append(" LIMIT ? OFFSET ?");
- StringBuilder builder = new StringBuilder();
- foreach (string key in query_phrases.keys)
- builder.append_printf("%s ", query_phrases[key]);
-
- debug("\nSEARCH:\n%s\nPHRASES:%s\n", sql.str, builder.str);
-
Db.Statement stmt = cx.prepare(sql.str);
int bind_index = sql_bind_query_phrases(stmt, 0, query_phrases);
if (limit > 0) {
@@ -1151,28 +1148,8 @@ private class Geary.ImapDB.Account : BaseObject {
return (search_results.size == 0 ? null : search_results);
}
- // This applies a fudge-factor set of matches when the database results
- // aren't entirely satisfactory, such as when you search for an email
- // address and the database tokenizes out the @ and ., etc. It's not meant
- // to be comprehensive, just a little extra highlighting applied to make
- // the results look a little closer to what you typed.
- //
- // TODO: This needs to be done by the client, not the library.
- /*
- private void add_literal_matches(string raw_query, Gee.Set<string> search_matches) {
- foreach (string word in raw_query.split(" ")) {
- if (word.has_suffix("\""))
- word = word.substring(0, word.length - 1);
- if (word.has_prefix("\""))
- word = word.substring(1);
-
- if (!String.is_empty_or_whitespace(word))
- search_matches.add(word);
- }
- }
- */
-
- public async Gee.Collection<string>? get_search_matches_async(Geary.SearchQuery q,
+ // See add_literal_matches() for explanation of include_literal_matches
+ public async Gee.Set<string>? get_search_matches_async(Geary.SearchQuery q,
Gee.Collection<ImapDB.EmailIdentifier> ids, Cancellable? cancellable = null) throws Error {
check_open();
ImapDB.SearchQuery query = check_search_query(q);
@@ -1195,10 +1172,6 @@ private class Geary.ImapDB.Account : BaseObject {
sql.append(")");
sql_add_query_phrases(sql, query_phrases);
- StringBuilder builder = new StringBuilder();
- foreach (string key in query_phrases.keys)
- builder.append_printf("%s ", query_phrases[key]);
-
Db.Statement stmt = cx.prepare(sql.str);
sql_bind_query_phrases(stmt, 0, query_phrases);
@@ -1206,6 +1179,7 @@ private class Geary.ImapDB.Account : BaseObject {
while (!result.finished) {
// Build a list of search offsets.
string[] offset_array = result.nonnull_string_at(0).split(" ");
+
Gee.ArrayList<SearchOffset> all_offsets = new Gee.ArrayList<SearchOffset>();
int j = 0;
while (true) {
@@ -1219,7 +1193,7 @@ private class Geary.ImapDB.Account : BaseObject {
// Iterate over the offset list, scrape strings from the database, and push
// the results into our return set.
foreach(SearchOffset offset in all_offsets) {
- string text = result.nonnull_string_at(offset.column + 1);
+ unowned string text = result.nonnull_string_at(offset.column + 1);
search_matches.add(text[offset.byte_offset : offset.byte_offset + offset.size].down());
}
@@ -1229,8 +1203,6 @@ private class Geary.ImapDB.Account : BaseObject {
return Db.TransactionOutcome.DONE;
}, cancellable);
- //add_literal_matches(query.raw, search_matches);
-
return (search_matches.size == 0 ? null : search_matches);
}
diff --git a/src/engine/imap-engine/imap-engine-generic-account.vala
b/src/engine/imap-engine/imap-engine-generic-account.vala
index 3e6911d..fc7c7e5 100644
--- a/src/engine/imap-engine/imap-engine-generic-account.vala
+++ b/src/engine/imap-engine/imap-engine-generic-account.vala
@@ -837,7 +837,7 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount {
return yield local.search_async(query, limit, offset, folder_blacklist, search_ids, cancellable);
}
- public override async Gee.Collection<string>? get_search_matches_async(Geary.SearchQuery query,
+ public override async Gee.Set<string>? get_search_matches_async(Geary.SearchQuery query,
Gee.Collection<Geary.EmailIdentifier> ids, Cancellable? cancellable = null) throws Error {
return yield local.get_search_matches_async(query, check_ids(ids), cancellable);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]