Add Geary.Account::list_local_email_async
Add new method and implementation to support breaking search folder impl out of the ImapDb package.
This commit is contained in:
parent
cb16bdc59d
commit
b3488f6cf9
5 changed files with 144 additions and 6 deletions
|
|
@ -425,6 +425,22 @@ public abstract class Geary.Account : BaseObject, Logging.Source {
|
|||
public abstract async Geary.Email local_fetch_email_async(Geary.EmailIdentifier email_id,
|
||||
Geary.Email.Field required_fields, Cancellable? cancellable = null) throws Error;
|
||||
|
||||
/**
|
||||
* Return a collection of email with the given identifiers.
|
||||
*
|
||||
* The returned collection will be in the same order as the
|
||||
* natural ordering of the given identifiers.
|
||||
*
|
||||
* Throws {@link EngineError.NOT_FOUND} if any email is not found
|
||||
* and {@link EngineError.INCOMPLETE_MESSAGE} if the fields aren't
|
||||
* available.
|
||||
*/
|
||||
public abstract async Gee.List<Email> list_local_email_async(
|
||||
Gee.Collection<EmailIdentifier> ids,
|
||||
Email.Field required_fields,
|
||||
GLib.Cancellable? cancellable = null
|
||||
) throws GLib.Error;
|
||||
|
||||
/**
|
||||
* Create a new {@link SearchQuery} for this {@link Account}.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -804,6 +804,48 @@ private class Geary.ImapDB.Account : BaseObject {
|
|||
return search_matches;
|
||||
}
|
||||
|
||||
public async Gee.List<Email>? list_email(Gee.Collection<EmailIdentifier> ids,
|
||||
Email.Field required_fields,
|
||||
GLib.Cancellable? cancellable = null)
|
||||
throws GLib.Error {
|
||||
check_open();
|
||||
|
||||
var results = new Gee.ArrayList<Email>();
|
||||
yield db.exec_transaction_async(Db.TransactionType.RO, (cx) => {
|
||||
foreach (var id in ids) {
|
||||
// TODO: once we have a way of deleting messages, we won't be able
|
||||
// to assume that a row id will point to the same email outside of
|
||||
// transactions, because SQLite will reuse row ids.
|
||||
Geary.Email.Field db_fields;
|
||||
MessageRow row = Geary.ImapDB.Folder.do_fetch_message_row(
|
||||
cx, id.message_id, required_fields, out db_fields, cancellable
|
||||
);
|
||||
if (!row.fields.fulfills(required_fields)) {
|
||||
throw new EngineError.INCOMPLETE_MESSAGE(
|
||||
"Message %s only fulfills %Xh fields (required: %Xh)",
|
||||
id.to_string(), row.fields, required_fields
|
||||
);
|
||||
}
|
||||
|
||||
Email email = row.to_email(id);
|
||||
Attachment.add_attachments(
|
||||
cx,
|
||||
this.db.attachments_path,
|
||||
email,
|
||||
id.message_id,
|
||||
cancellable
|
||||
);
|
||||
|
||||
results.add(email);
|
||||
}
|
||||
return Db.TransactionOutcome.DONE;
|
||||
},
|
||||
cancellable
|
||||
);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public async Geary.Email fetch_email_async(ImapDB.EmailIdentifier email_id,
|
||||
Geary.Email.Field required_fields, Cancellable? cancellable = null) throws Error {
|
||||
check_open();
|
||||
|
|
|
|||
|
|
@ -512,6 +512,16 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
|
|||
return (Gee.Collection<ImapDB.EmailIdentifier>) ids;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public override async SearchQuery new_search_query(string query,
|
||||
SearchQuery.Strategy strategy,
|
||||
GLib.Cancellable? cancellable)
|
||||
throws GLib.Error {
|
||||
return yield new ImapDB.SearchQuery(
|
||||
this, local, query, strategy, cancellable
|
||||
);
|
||||
}
|
||||
|
||||
public override async Gee.MultiMap<Geary.Email, Geary.FolderPath?>? local_search_message_id_async(
|
||||
Geary.RFC822.MessageID message_id, Geary.Email.Field requested_fields, bool partial_ok,
|
||||
Gee.Collection<Geary.FolderPath?>? folder_blacklist, Geary.EmailFlags? flag_blacklist,
|
||||
|
|
@ -526,12 +536,13 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
|
|||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public override async SearchQuery new_search_query(string query,
|
||||
SearchQuery.Strategy strategy,
|
||||
GLib.Cancellable? cancellable)
|
||||
throws GLib.Error {
|
||||
return yield new ImapDB.SearchQuery(
|
||||
this, local, query, strategy, cancellable
|
||||
public override async Gee.List<Email> list_local_email_async(
|
||||
Gee.Collection<EmailIdentifier> ids,
|
||||
Email.Field required_fields,
|
||||
GLib.Cancellable? cancellable = null
|
||||
) throws GLib.Error {
|
||||
return yield local.list_email(
|
||||
check_ids(ids), required_fields, cancellable
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -204,6 +204,18 @@ public class Geary.MockAccount : Account, MockObject {
|
|||
);
|
||||
}
|
||||
|
||||
public override async Gee.List<Email> list_local_email_async(
|
||||
Gee.Collection<EmailIdentifier> ids,
|
||||
Email.Field required_fields,
|
||||
GLib.Cancellable? cancellable = null
|
||||
) throws GLib.Error {
|
||||
return object_or_throw_call<Gee.List<Email>>(
|
||||
"list_local_email_async",
|
||||
{ids, box_arg(required_fields), cancellable},
|
||||
new EngineError.NOT_FOUND("Mock call")
|
||||
);
|
||||
}
|
||||
|
||||
public override async Email local_fetch_email_async(EmailIdentifier email_id,
|
||||
Email.Field required_fields,
|
||||
Cancellable? cancellable = null)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ class Geary.ImapDB.AccountTest : TestCase {
|
|||
add_test("fetch_base_folder", fetch_base_folder);
|
||||
add_test("fetch_child_folder", fetch_child_folder);
|
||||
add_test("fetch_nonexistent_folder", fetch_nonexistent_folder);
|
||||
add_test("list_local_email", list_local_email);
|
||||
}
|
||||
|
||||
public override void set_up() throws GLib.Error {
|
||||
|
|
@ -310,4 +311,60 @@ class Geary.ImapDB.AccountTest : TestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void list_local_email() throws GLib.Error {
|
||||
Email.Field fixture_fields = Email.Field.RECEIVERS;
|
||||
string fixture_to = "test1@example.com";
|
||||
this.account.db.exec(
|
||||
"INSERT INTO MessageTable (id, fields, to_field) " +
|
||||
"VALUES (1, %d, '%s');".printf(fixture_fields, fixture_to)
|
||||
);
|
||||
this.account.db.exec(
|
||||
"INSERT INTO MessageTable (id, fields, to_field) " +
|
||||
"VALUES (2, %d, '%s');".printf(fixture_fields, fixture_to)
|
||||
);
|
||||
|
||||
this.account.list_email.begin(
|
||||
iterate_array<Geary.ImapDB.EmailIdentifier>({
|
||||
new EmailIdentifier(1, null),
|
||||
new EmailIdentifier(2, null)
|
||||
}).to_linked_list(),
|
||||
Email.Field.RECEIVERS,
|
||||
null,
|
||||
(obj, ret) => { async_complete(ret); }
|
||||
);
|
||||
Gee.List<Email> result = this.account.list_email.end(
|
||||
async_result()
|
||||
);
|
||||
|
||||
assert_int(2, result.size, "Not enough email listed");
|
||||
assert_true(new EmailIdentifier(1, null).equal_to(result[0].id));
|
||||
assert_true(new EmailIdentifier(2, null).equal_to(result[1].id));
|
||||
|
||||
this.account.list_email.begin(
|
||||
Collection.single(new EmailIdentifier(3, null)),
|
||||
Email.Field.RECEIVERS,
|
||||
null,
|
||||
(obj, ret) => { async_complete(ret); }
|
||||
);
|
||||
try {
|
||||
this.account.list_email.end(async_result());
|
||||
assert_not_reached();
|
||||
} catch (EngineError.NOT_FOUND error) {
|
||||
// All good
|
||||
}
|
||||
|
||||
this.account.list_email.begin(
|
||||
Collection.single(new EmailIdentifier(1, null)),
|
||||
Email.Field.BODY,
|
||||
null,
|
||||
(obj, ret) => { async_complete(ret); }
|
||||
);
|
||||
try {
|
||||
this.account.list_email.end(async_result());
|
||||
assert_not_reached();
|
||||
} catch (EngineError.INCOMPLETE_MESSAGE error) {
|
||||
// All good
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue