Background search table population; fix #6984
This commit is contained in:
parent
a78f0c4a5f
commit
f54ea44977
3 changed files with 83 additions and 41 deletions
|
|
@ -24,6 +24,7 @@ private class Geary.ImapDB.Account : BaseObject {
|
|||
private ImapDB.Database? db = null;
|
||||
private Gee.HashMap<Geary.FolderPath, FolderReference> folder_refs =
|
||||
new Gee.HashMap<Geary.FolderPath, FolderReference>();
|
||||
private Cancellable? background_cancellable = null;
|
||||
public ImapEngine.ContactStore contact_store { get; private set; }
|
||||
|
||||
public Account(Geary.AccountInformation account_information) {
|
||||
|
|
@ -68,6 +69,11 @@ private class Geary.ImapDB.Account : BaseObject {
|
|||
error("Error finding account from its information: %s", e.message);
|
||||
}
|
||||
|
||||
background_cancellable = new Cancellable();
|
||||
|
||||
// Kick off a background update of the search table.
|
||||
populate_search_table_async.begin(background_cancellable);
|
||||
|
||||
initialize_contacts(cancellable);
|
||||
|
||||
// ImapDB.Account holds the Outbox, which is tied to the database it maintains
|
||||
|
|
@ -93,6 +99,9 @@ private class Geary.ImapDB.Account : BaseObject {
|
|||
db = null;
|
||||
}
|
||||
|
||||
background_cancellable.cancel();
|
||||
background_cancellable = null;
|
||||
|
||||
outbox = null;
|
||||
search_folder = null;
|
||||
}
|
||||
|
|
@ -684,6 +693,65 @@ private class Geary.ImapDB.Account : BaseObject {
|
|||
debug("Deleted %d duplicate folders", count);
|
||||
}
|
||||
|
||||
private async void populate_search_table_async(Cancellable? cancellable) {
|
||||
// TODO: send processing signal upwards.
|
||||
debug("Populating search table");
|
||||
try {
|
||||
while (!yield populate_search_table_batch_async(100, cancellable))
|
||||
;
|
||||
} catch (Error e) {
|
||||
debug("Error populating search table: %s", e.message);
|
||||
}
|
||||
debug("Done populating search table");
|
||||
}
|
||||
|
||||
private async bool populate_search_table_batch_async(int limit = 100,
|
||||
Cancellable? cancellable) throws Error {
|
||||
bool done = false;
|
||||
yield db.exec_transaction_async(Db.TransactionType.RW, (cx, cancellable) => {
|
||||
Db.Statement stmt = cx.prepare("""
|
||||
SELECT id
|
||||
FROM MessageTable
|
||||
WHERE id NOT IN (
|
||||
SELECT id
|
||||
FROM MessageSearchTable
|
||||
)
|
||||
LIMIT ?
|
||||
""");
|
||||
stmt.bind_int(0, limit);
|
||||
|
||||
int count = 0;
|
||||
Db.Result result = stmt.exec(cancellable);
|
||||
while (!result.finished) {
|
||||
int64 id = result.rowid_at(0);
|
||||
|
||||
try {
|
||||
MessageRow row = Geary.ImapDB.Folder.do_fetch_message_row(
|
||||
cx, id, Geary.ImapDB.Folder.REQUIRED_FOR_SEARCH, cancellable);
|
||||
Geary.Email email = row.to_email(-1, new Geary.ImapDB.EmailIdentifier(id));
|
||||
Geary.ImapDB.Folder.do_add_attachments(cx, email, id, cancellable);
|
||||
|
||||
Geary.ImapDB.Folder.do_add_email_to_search_table(cx, id, email, cancellable);
|
||||
} catch (Error e) {
|
||||
// This is a somewhat serious issue since we rely on
|
||||
// there always being a row in the search table for
|
||||
// every message.
|
||||
warning("Error adding message %lld to the search table: %s", id, e.message);
|
||||
}
|
||||
|
||||
++count;
|
||||
result.next(cancellable);
|
||||
}
|
||||
|
||||
if (count < limit)
|
||||
done = true;
|
||||
|
||||
return Db.TransactionOutcome.DONE;
|
||||
}, cancellable);
|
||||
|
||||
return done;
|
||||
}
|
||||
|
||||
//
|
||||
// Transaction helper methods
|
||||
//
|
||||
|
|
|
|||
|
|
@ -107,44 +107,6 @@ private class Geary.ImapDB.Database : Geary.Db.VersionedDatabase {
|
|||
} catch (Error e) {
|
||||
error("Error creating search table: %s", e.message);
|
||||
}
|
||||
|
||||
bool done = false;
|
||||
int limit = 100;
|
||||
for (int offset = 0; !done; offset += limit) {
|
||||
try {
|
||||
exec_transaction(Db.TransactionType.RW, (cx) => {
|
||||
Db.Statement stmt = prepare(
|
||||
"SELECT id FROM MessageTable ORDER BY id LIMIT ? OFFSET ?");
|
||||
stmt.bind_int(0, limit);
|
||||
stmt.bind_int(1, offset);
|
||||
|
||||
Db.Result result = stmt.exec();
|
||||
if (result.finished)
|
||||
done = true;
|
||||
|
||||
while (!result.finished) {
|
||||
int64 id = result.rowid_at(0);
|
||||
|
||||
try {
|
||||
MessageRow row = Geary.ImapDB.Folder.do_fetch_message_row(
|
||||
cx, id, Geary.ImapDB.Folder.REQUIRED_FOR_SEARCH, null);
|
||||
Geary.Email email = row.to_email(-1, new Geary.ImapDB.EmailIdentifier(id));
|
||||
Geary.ImapDB.Folder.do_add_attachments(cx, email, id);
|
||||
|
||||
Geary.ImapDB.Folder.do_add_email_to_search_table(cx, id, email, null);
|
||||
} catch (Error e) {
|
||||
debug("Error adding message %lld to the search table: %s", id, e.message);
|
||||
}
|
||||
|
||||
result.next();
|
||||
}
|
||||
|
||||
return Db.TransactionOutcome.DONE;
|
||||
});
|
||||
} catch (Error e) {
|
||||
debug("Error populating search table: %s", e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void on_prepare_database_connection(Db.Connection cx) throws Error {
|
||||
|
|
|
|||
|
|
@ -953,7 +953,16 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
|
|||
stmt.bind_string(6, (email.cc != null ? email.cc.to_searchable_string() : null));
|
||||
stmt.bind_string(7, (email.bcc != null ? email.bcc.to_searchable_string() : null));
|
||||
|
||||
stmt.exec_insert();
|
||||
stmt.exec_insert(cancellable);
|
||||
}
|
||||
|
||||
private static bool do_check_for_message_search_row(Db.Connection cx, int64 message_id,
|
||||
Cancellable? cancellable) throws Error {
|
||||
Db.Statement stmt = cx.prepare("SELECT 'TRUE' FROM MessageSearchTable WHERE id=?");
|
||||
stmt.bind_rowid(0, message_id);
|
||||
|
||||
Db.Result result = stmt.exec(cancellable);
|
||||
return !result.finished;
|
||||
}
|
||||
|
||||
private Gee.List<Geary.Email>? do_list_email(Db.Connection cx, Gee.List<LocationIdentifier> locations,
|
||||
|
|
@ -1309,7 +1318,7 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
|
|||
stmt.bind_string(6, (email.bcc != null ? email.bcc.to_searchable_string() : null));
|
||||
stmt.bind_rowid(7, message_id);
|
||||
|
||||
stmt.exec();
|
||||
stmt.exec(cancellable);
|
||||
}
|
||||
|
||||
private void do_merge_email(Db.Connection cx, int64 message_id, Geary.Email email,
|
||||
|
|
@ -1344,7 +1353,10 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
|
|||
}
|
||||
}
|
||||
|
||||
do_merge_email_in_search_table(cx, message_id, combined_email, cancellable);
|
||||
if (do_check_for_message_search_row(cx, message_id, cancellable))
|
||||
do_merge_email_in_search_table(cx, message_id, combined_email, cancellable);
|
||||
else
|
||||
do_add_email_to_search_table(cx, message_id, combined_email, cancellable);
|
||||
}
|
||||
|
||||
private static Gee.List<Geary.Attachment>? do_list_attachments(Db.Connection cx, int64 message_id,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue