Mark messages as read when clicked. Closes #4476
This commit is contained in:
parent
2109708146
commit
fe099d9fb9
16 changed files with 297 additions and 21 deletions
|
|
@ -203,7 +203,7 @@ public class GearyController {
|
|||
|
||||
current_folder = folder;
|
||||
|
||||
yield current_folder.open_async(true, cancellable_folder);
|
||||
yield current_folder.open_async(false, cancellable_folder);
|
||||
|
||||
current_conversations = new Geary.Conversations(current_folder,
|
||||
MessageListStore.REQUIRED_FIELDS);
|
||||
|
|
@ -351,6 +351,7 @@ public class GearyController {
|
|||
private async void do_select_message(Geary.Conversation conversation, Cancellable?
|
||||
cancellable = null) throws Error {
|
||||
|
||||
Gee.List<Geary.EmailIdentifier> messages = new Gee.ArrayList<Geary.EmailIdentifier>();
|
||||
if (current_folder == null) {
|
||||
debug("Conversation selected with no folder selected");
|
||||
|
||||
|
|
@ -366,7 +367,15 @@ public class GearyController {
|
|||
break;
|
||||
|
||||
main_window.message_viewer.add_message(full_email);
|
||||
|
||||
if (full_email.properties.email_flags.is_unread())
|
||||
messages.add(full_email.id);
|
||||
}
|
||||
|
||||
// Mark as read.
|
||||
if (messages.size > 0)
|
||||
yield current_folder.mark_email_async(messages, Geary.EmailProperties.EmailFlags.NONE,
|
||||
Geary.EmailProperties.EmailFlags.UNREAD, cancellable);
|
||||
}
|
||||
|
||||
private void on_select_message_completed(Object? source, AsyncResult result) {
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ public class MessageListStore : Gtk.TreeStore {
|
|||
|
||||
// If it exists, return oldest unread message.
|
||||
foreach (Geary.Email email in pool)
|
||||
if (email.properties.is_unread())
|
||||
if (email.properties.email_flags.is_unread())
|
||||
return email;
|
||||
|
||||
// All e-mail was read, so return the newest one.
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ public class MessageViewer : Gtk.Viewport {
|
|||
header.column_spacing = HEADER_COL_SPACING;
|
||||
header.row_spacing = HEADER_ROW_SPACING;
|
||||
|
||||
if (email.properties.is_unread())
|
||||
if (email.properties.email_flags.is_unread())
|
||||
icon_area.add(new Gtk.Image.from_pixbuf(IconFactory.instance.unread));
|
||||
|
||||
int header_height = 0;
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ public abstract class Geary.Conversation : Object {
|
|||
return false;
|
||||
|
||||
foreach (Geary.Email email in list) {
|
||||
if (email.properties.is_unread())
|
||||
if (email.properties.email_flags.is_unread())
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,33 @@
|
|||
*/
|
||||
|
||||
public abstract class Geary.EmailProperties : Object {
|
||||
public EmailProperties() {
|
||||
// Flags that can be set or cleared on a given e-mail.
|
||||
public enum EmailFlags {
|
||||
NONE = 0,
|
||||
UNREAD = 1 << 0;
|
||||
|
||||
public inline bool is_all_set(EmailFlags required_flags) {
|
||||
return (this & required_flags) == required_flags;
|
||||
}
|
||||
|
||||
public inline EmailFlags set(EmailFlags flags) {
|
||||
return (this | flags);
|
||||
}
|
||||
|
||||
public inline EmailFlags clear(EmailFlags flags) {
|
||||
return (this & ~(flags));
|
||||
}
|
||||
|
||||
// Convenience method to check if the unread flag is set.
|
||||
public inline bool is_unread() {
|
||||
return is_all_set(UNREAD);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract bool is_unread();
|
||||
// Flags se on the email object.
|
||||
public EmailFlags email_flags { get; protected set; default = EmailFlags.NONE; }
|
||||
|
||||
public EmailProperties() {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -348,6 +348,15 @@ public interface Geary.Folder : Object {
|
|||
public abstract async void remove_email_async(Geary.EmailIdentifier email_id,
|
||||
Cancellable? cancellable = null) throws Error;
|
||||
|
||||
/**
|
||||
* Adds or removes a flag from a list of messages.
|
||||
*
|
||||
* The Folder must be opened prior to attempting this operation.
|
||||
*/
|
||||
public abstract async void mark_email_async(Gee.List<Geary.EmailIdentifier> to_mark,
|
||||
Geary.EmailProperties.EmailFlags flags_to_add, Geary.EmailProperties.EmailFlags
|
||||
flags_to_remove, Cancellable? cancellable = null) throws Error;
|
||||
|
||||
/**
|
||||
* check_span_specifiers() verifies that the span specifiers match the requirements set by
|
||||
* list_email_async() and lazy_list_email_async(). If not, this method throws
|
||||
|
|
|
|||
|
|
@ -26,10 +26,9 @@ public class Geary.Imap.EmailProperties : Geary.EmailProperties, Equalable {
|
|||
flagged = flags.contains(MessageFlag.FLAGGED);
|
||||
recent = flags.contains(MessageFlag.RECENT);
|
||||
seen = flags.contains(MessageFlag.SEEN);
|
||||
}
|
||||
|
||||
public override bool is_unread() {
|
||||
return !flags.contains(MessageFlag.SEEN);
|
||||
|
||||
if (!seen)
|
||||
email_flags = email_flags.set(Geary.EmailProperties.EmailFlags.UNREAD);
|
||||
}
|
||||
|
||||
public bool equals(Equalable e) {
|
||||
|
|
|
|||
|
|
@ -191,5 +191,23 @@ private class Geary.Imap.Folder : Geary.AbstractFolder, Geary.RemoteFolder {
|
|||
|
||||
throw new EngineError.READONLY("IMAP currently read-only");
|
||||
}
|
||||
|
||||
public override async void mark_email_async(Gee.List<Geary.EmailIdentifier> to_mark,
|
||||
Geary.EmailProperties.EmailFlags flags_to_add, Geary.EmailProperties.EmailFlags
|
||||
flags_to_remove, Cancellable? cancellable = null) throws Error {
|
||||
if (mailbox == null)
|
||||
throw new EngineError.OPEN_REQUIRED("%s not opened", to_string());
|
||||
|
||||
// Build an array of UIDs.
|
||||
Geary.Imap.UID[] sparse_set = new Geary.Imap.UID[to_mark.size];
|
||||
int i = 0;
|
||||
foreach(Geary.EmailIdentifier id in to_mark) {
|
||||
sparse_set[i] = ((Geary.Imap.EmailIdentifier) id).uid;
|
||||
i++;
|
||||
}
|
||||
|
||||
MessageSet message_set = new MessageSet.uid_sparse(sparse_set);
|
||||
mailbox.mark_email_async(message_set, flags_to_add, flags_to_remove, cancellable);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ public class Geary.Imap.StatusCommand : Command {
|
|||
public StatusCommand(string mailbox, StatusDataType[] data_items) {
|
||||
base (NAME);
|
||||
|
||||
add (new StringParameter(mailbox));
|
||||
add(new StringParameter(mailbox));
|
||||
|
||||
assert(data_items.length > 0);
|
||||
ListParameter data_item_list = new ListParameter(this);
|
||||
|
|
@ -105,3 +105,24 @@ public class Geary.Imap.StatusCommand : Command {
|
|||
}
|
||||
}
|
||||
|
||||
public class Geary.Imap.StoreCommand : Command {
|
||||
public const string NAME = "store";
|
||||
public const string UID_NAME = "uid store";
|
||||
|
||||
public StoreCommand(MessageSet message_set, Gee.List<MessageFlag> flag_list, bool add_flag,
|
||||
bool silent) {
|
||||
base (message_set.is_uid ? UID_NAME : NAME);
|
||||
|
||||
add(message_set.to_parameter());
|
||||
add(new StringParameter("%sflags%s".printf(add_flag ? "+" : "-", silent ? ".silent" : "")));
|
||||
|
||||
ListParameter list = new ListParameter(this);
|
||||
foreach(MessageFlag flag in flag_list)
|
||||
list.add(new StringParameter(flag.value));
|
||||
|
||||
add(list);
|
||||
|
||||
debug("command: %s", this.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,21 @@ public class Geary.Imap.MessageFlag : Geary.Imap.Flag {
|
|||
public MessageFlag(string value) {
|
||||
base (value);
|
||||
}
|
||||
|
||||
// Converts a list of email flags to add and remove to a list of message
|
||||
// flags to add and remove.
|
||||
public static void from_email_flags(Geary.EmailProperties.EmailFlags email_flags_add,
|
||||
Geary.EmailProperties.EmailFlags email_flags_remove, out Gee.List<MessageFlag> msg_flags_add,
|
||||
out Gee.List<MessageFlag> msg_flags_remove) {
|
||||
msg_flags_add = new Gee.ArrayList<MessageFlag>();
|
||||
msg_flags_remove = new Gee.ArrayList<MessageFlag>();
|
||||
|
||||
if (email_flags_add.is_all_set(Geary.EmailProperties.EmailFlags.UNREAD))
|
||||
msg_flags_remove.add(MessageFlag.SEEN);
|
||||
|
||||
if (email_flags_remove.is_all_set(Geary.EmailProperties.EmailFlags.UNREAD))
|
||||
msg_flags_add.add(MessageFlag.SEEN);
|
||||
}
|
||||
}
|
||||
|
||||
public class Geary.Imap.MailboxAttribute : Geary.Imap.Flag {
|
||||
|
|
|
|||
|
|
@ -84,11 +84,16 @@ public class Geary.Imap.MessageSet {
|
|||
}
|
||||
|
||||
public MessageSet.sparse(int[] msg_nums) {
|
||||
value = build_sparse_range(msg_nums);
|
||||
value = build_sparse_range(msg_array_to_int64(msg_nums));
|
||||
}
|
||||
|
||||
public MessageSet.uid_sparse(UID[] msg_uids) {
|
||||
value = build_sparse_range(uid_array_to_int64(msg_uids));
|
||||
is_uid = true;
|
||||
}
|
||||
|
||||
public MessageSet.sparse_to_highest(int[] msg_nums) {
|
||||
value = "%s:*".printf(build_sparse_range(msg_nums));
|
||||
value = "%s:*".printf(build_sparse_range(msg_array_to_int64(msg_nums)));
|
||||
}
|
||||
|
||||
public MessageSet.multirange(MessageSet[] msg_sets) {
|
||||
|
|
@ -128,25 +133,42 @@ public class Geary.Imap.MessageSet {
|
|||
is_uid = true;
|
||||
}
|
||||
|
||||
// Builds sparse range of either UID values or message numbers.
|
||||
// TODO: It would be more efficient to look for runs in the numbers and form the set specifier
|
||||
// with them.
|
||||
private static string build_sparse_range(int[] msg_nums) {
|
||||
private static string build_sparse_range(int64[] msg_nums) {
|
||||
assert(msg_nums.length > 0);
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int ctr = 0; ctr < msg_nums.length; ctr++) {
|
||||
int msg_num = msg_nums[ctr];
|
||||
int64 msg_num = msg_nums[ctr];
|
||||
assert(msg_num >= 0);
|
||||
|
||||
if (ctr < (msg_nums.length - 1))
|
||||
builder.append_printf("%d,", msg_num);
|
||||
builder.append_printf("%lld,", msg_num);
|
||||
else
|
||||
builder.append_printf("%d", msg_num);
|
||||
builder.append_printf("%lld", msg_num);
|
||||
}
|
||||
|
||||
return builder.str;
|
||||
}
|
||||
|
||||
private static int64[] msg_array_to_int64(int[] msg_nums) {
|
||||
int64[] ret = new int64[0];
|
||||
foreach (int num in msg_nums)
|
||||
ret += (int64) num;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static int64[] uid_array_to_int64(UID[] msg_uids) {
|
||||
int64[] ret = new int64[0];
|
||||
foreach (UID uid in msg_uids)
|
||||
ret += uid.value;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Parameter to_parameter() {
|
||||
// Message sets are not quoted, even if they use an atom-special character (this *might*
|
||||
// be a Gmailism...)
|
||||
|
|
|
|||
|
|
@ -89,10 +89,21 @@ public class Geary.Imap.Mailbox : Geary.SmartReference {
|
|||
|
||||
int plain_id = batch.add(new MailboxOperation(context, fetch_cmd));
|
||||
|
||||
int body_id = NonblockingBatch.INVALID_ID;
|
||||
int preview_id = NonblockingBatch.INVALID_ID;
|
||||
int preview_charset_id = NonblockingBatch.INVALID_ID;
|
||||
int properties_id = NonblockingBatch.INVALID_ID;
|
||||
|
||||
if (fields.require(Geary.Email.Field.BODY)) {
|
||||
// Fetch the body.
|
||||
Gee.List<FetchBodyDataType> types = new Gee.ArrayList<FetchBodyDataType>();
|
||||
types.add(new FetchBodyDataType.peek(
|
||||
FetchBodyDataType.SectionPart.TEXT, null, -1, -1, null));
|
||||
FetchCommand fetch_body = new FetchCommand(msg_set, null, types);
|
||||
|
||||
body_id = batch.add(new MailboxOperation(context, fetch_body));
|
||||
}
|
||||
|
||||
if (fields.require(Geary.Email.Field.PREVIEW)) {
|
||||
// Preview text.
|
||||
FetchBodyDataType fetch_preview = new FetchBodyDataType.peek(FetchBodyDataType.SectionPart.NONE,
|
||||
|
|
@ -155,6 +166,26 @@ public class Geary.Imap.Mailbox : Geary.SmartReference {
|
|||
map.set(plain_res.msg_num, email);
|
||||
}
|
||||
|
||||
// Process body results.
|
||||
if (body_id != NonblockingBatch.INVALID_ID) {
|
||||
MailboxOperation body_op = (MailboxOperation) batch.get_operation(body_id);
|
||||
CommandResponse body_resp = (CommandResponse) batch.get_result(body_id);
|
||||
|
||||
if (body_resp.status_response.status != Status.OK) {
|
||||
throw new ImapError.SERVER_ERROR("Server error for %s: %s",
|
||||
body_op.cmd.to_string(), body_resp.to_string());
|
||||
}
|
||||
|
||||
FetchResults[] body_results = FetchResults.decode(body_resp);
|
||||
foreach (FetchResults body_res in body_results) {
|
||||
Geary.Email? body_email = map.get(body_res.msg_num);
|
||||
if (body_email == null)
|
||||
continue;
|
||||
|
||||
body_email.set_message_body(new Geary.RFC822.Text(body_res.get_body_data().get(0)));
|
||||
}
|
||||
}
|
||||
|
||||
// Process properties results.
|
||||
if (properties_id != NonblockingBatch.INVALID_ID) {
|
||||
MailboxOperation properties_op = (MailboxOperation) batch.get_operation(properties_id);
|
||||
|
|
@ -291,13 +322,10 @@ public class Geary.Imap.Mailbox : Geary.SmartReference {
|
|||
break;
|
||||
|
||||
case Geary.Email.Field.BODY:
|
||||
data_types_list.add(FetchDataType.RFC822_TEXT);
|
||||
break;
|
||||
|
||||
case Geary.Email.Field.PROPERTIES:
|
||||
case Geary.Email.Field.NONE:
|
||||
case Geary.Email.Field.PREVIEW:
|
||||
// not set (or, for previews and properties, fetched separately)
|
||||
// not set (or, for body previews and properties, fetched separately)
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -467,6 +495,61 @@ public class Geary.Imap.Mailbox : Geary.SmartReference {
|
|||
if (fields.require(Geary.Email.Field.REFERENCES))
|
||||
email.set_full_references(message_id, in_reply_to, references);
|
||||
}
|
||||
|
||||
public async void mark_email_async(MessageSet to_mark, Geary.EmailProperties.EmailFlags
|
||||
flags_to_add, Geary.EmailProperties.EmailFlags flags_to_remove,
|
||||
Cancellable? cancellable = null) throws Error {
|
||||
|
||||
if (context.is_closed())
|
||||
throw new ImapError.NOT_SELECTED("Mailbox %s closed", name);
|
||||
|
||||
Gee.List<MessageFlag> msg_flags_add = new Gee.ArrayList<MessageFlag>();
|
||||
Gee.List<MessageFlag> msg_flags_remove = new Gee.ArrayList<MessageFlag>();
|
||||
MessageFlag.from_email_flags(flags_to_add, flags_to_remove, out msg_flags_add,
|
||||
out msg_flags_remove);
|
||||
|
||||
NonblockingBatch batch = new NonblockingBatch();
|
||||
int add_flags_id = NonblockingBatch.INVALID_ID;
|
||||
int remove_flags_id = NonblockingBatch.INVALID_ID;
|
||||
|
||||
if (msg_flags_add.size > 0)
|
||||
add_flags_id = batch.add(new MailboxOperation(context, new StoreCommand(
|
||||
to_mark, msg_flags_add, true, true)));
|
||||
|
||||
if (msg_flags_remove.size > 0)
|
||||
remove_flags_id = batch.add(new MailboxOperation(context, new StoreCommand(
|
||||
to_mark, msg_flags_remove, false, true)));
|
||||
|
||||
yield batch.execute_all_async(cancellable);
|
||||
|
||||
if (add_flags_id != NonblockingBatch.INVALID_ID) {
|
||||
MailboxOperation add_op = (MailboxOperation) batch.get_operation(add_flags_id);
|
||||
CommandResponse add_resp = (CommandResponse) batch.get_result(add_flags_id);
|
||||
|
||||
if (add_resp.status_response == null)
|
||||
throw new ImapError.SERVER_ERROR("Server error. Command: %s No status response. %s",
|
||||
add_op.cmd.to_string(), add_resp.to_string());
|
||||
|
||||
if (add_resp.status_response.status != Status.OK)
|
||||
throw new ImapError.SERVER_ERROR("Server error. Command: %s Response: %s Error: %s",
|
||||
add_op.cmd.to_string(), add_resp.to_string(),
|
||||
add_resp.status_response.status.to_string());
|
||||
}
|
||||
|
||||
if (remove_flags_id != NonblockingBatch.INVALID_ID) {
|
||||
MailboxOperation remove_op = (MailboxOperation) batch.get_operation(remove_flags_id);
|
||||
CommandResponse remove_resp = (CommandResponse) batch.get_result(remove_flags_id);
|
||||
|
||||
if (remove_resp.status_response == null)
|
||||
throw new ImapError.SERVER_ERROR("Server error. Command: %s No status response. %s",
|
||||
remove_op.cmd.to_string(), remove_resp.to_string());
|
||||
|
||||
if (remove_resp.status_response.status != Status.OK)
|
||||
throw new ImapError.SERVER_ERROR("Server error. Command: %s Response: %s Error: %s",
|
||||
remove_op.cmd.to_string(), remove_resp.to_string(),
|
||||
remove_resp.status_response.status.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A SelectedContext is a ReferenceSemantics object wrapping a ClientSession that is in a SELECTED
|
||||
|
|
|
|||
|
|
@ -122,6 +122,10 @@ public abstract class Geary.AbstractFolder : Object, Geary.Folder {
|
|||
public abstract async void remove_email_async(Geary.EmailIdentifier email_id, Cancellable? cancellable = null)
|
||||
throws Error;
|
||||
|
||||
public abstract async void mark_email_async(Gee.List<Geary.EmailIdentifier> to_mark,
|
||||
Geary.EmailProperties.EmailFlags flags_to_add, Geary.EmailProperties.EmailFlags
|
||||
flags_to_remove, Cancellable? cancellable = null) throws Error;
|
||||
|
||||
public virtual string to_string() {
|
||||
return get_path().to_string();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -939,5 +939,15 @@ private class Geary.EngineFolder : Geary.AbstractFolder {
|
|||
|
||||
debug("prefetched %d for %s", prefetch_count, to_string());
|
||||
}
|
||||
|
||||
public override async void mark_email_async(Gee.List<Geary.EmailIdentifier> to_mark,
|
||||
Geary.EmailProperties.EmailFlags flags_to_add, Geary.EmailProperties.EmailFlags
|
||||
flags_to_remove, Cancellable? cancellable = null) throws Error {
|
||||
if (!yield wait_for_remote_to_open())
|
||||
throw new EngineError.SERVER_UNAVAILABLE("No connection to %s", remote.to_string());
|
||||
|
||||
yield remote_folder.mark_email_async(to_mark, flags_to_add, flags_to_remove, cancellable);
|
||||
yield local_folder.mark_email_async(to_mark, flags_to_add, flags_to_remove, cancellable);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -471,6 +471,52 @@ private class Geary.Sqlite.Folder : Geary.AbstractFolder, Geary.LocalFolder, Gea
|
|||
notify_message_removed(id);
|
||||
}
|
||||
|
||||
public override async void mark_email_async(Gee.List<Geary.EmailIdentifier> to_mark,
|
||||
Geary.EmailProperties.EmailFlags flags_to_add, Geary.EmailProperties.EmailFlags
|
||||
flags_to_remove, Cancellable? cancellable = null) throws Error {
|
||||
check_open();
|
||||
|
||||
Transaction transaction = yield db.begin_transaction_async("Folder.mark_email_async",
|
||||
cancellable);
|
||||
|
||||
Gee.List<Geary.Imap.MessageFlag> msg_flags_add = new Gee.ArrayList<Geary.Imap.MessageFlag>();
|
||||
Gee.List<Geary.Imap.MessageFlag> msg_flags_remove =
|
||||
new Gee.ArrayList<Geary.Imap.MessageFlag>();
|
||||
Geary.Imap.MessageFlag.from_email_flags(flags_to_add, flags_to_remove, out msg_flags_add,
|
||||
out msg_flags_remove);
|
||||
|
||||
foreach (Geary.EmailIdentifier id in to_mark) {
|
||||
MessageLocationRow? location_row = yield location_table.fetch_by_ordering_async(
|
||||
transaction, folder_row.id, ((Geary.Imap.EmailIdentifier) id).uid.value, cancellable);
|
||||
if (location_row == null) {
|
||||
throw new EngineError.NOT_FOUND("No message with ID %s in folder %s", id.to_string(),
|
||||
to_string());
|
||||
}
|
||||
|
||||
ImapMessagePropertiesRow? row = yield imap_message_properties_table.fetch_async(
|
||||
transaction, location_row.id, cancellable);
|
||||
|
||||
if (row == null) {
|
||||
warning("Message not found in database: %lld", location_row.id);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create new set of message flags with the appropriate flags added and/or removed.
|
||||
Gee.HashSet<Geary.Imap.MessageFlag> mutable_copy =
|
||||
new Gee.HashSet<Geary.Imap.MessageFlag>();
|
||||
mutable_copy.add_all(Geary.Imap.MessageFlags.deserialize(row.flags).get_all());
|
||||
mutable_copy.remove_all(msg_flags_remove);
|
||||
mutable_copy.add_all(msg_flags_add);
|
||||
|
||||
Geary.Imap.MessageFlags new_flags = new Geary.Imap.MessageFlags(mutable_copy);
|
||||
|
||||
yield imap_message_properties_table.update_flags_async(transaction, location_row.id,
|
||||
new_flags.serialize(), cancellable);
|
||||
}
|
||||
|
||||
yield transaction.commit_async(cancellable);
|
||||
}
|
||||
|
||||
public async bool is_email_present_async(Geary.EmailIdentifier id, out Geary.Email.Field available_fields,
|
||||
Cancellable? cancellable = null) throws Error {
|
||||
check_open();
|
||||
|
|
|
|||
|
|
@ -76,6 +76,22 @@ public class Geary.Sqlite.ImapMessagePropertiesTable : Geary.Sqlite.Table {
|
|||
yield release_lock_async(transaction, locked, cancellable);
|
||||
}
|
||||
|
||||
public async void update_flags_async(Transaction? transaction, int64 message_id, string? flags,
|
||||
Cancellable? cancellable) throws Error {
|
||||
Transaction locked = yield obtain_lock_async(transaction,
|
||||
"ImapMessagePropertiesTable.update_flags_async", cancellable);
|
||||
|
||||
SQLHeavy.Query query = locked.prepare(
|
||||
"UPDATE ImapMessagePropertiesTable SET flags = ? WHERE message_id = ?");
|
||||
query.bind_string(0, flags);
|
||||
query.bind_int64(1, message_id);
|
||||
|
||||
yield query.execute_async(cancellable);
|
||||
locked.set_commit_required();
|
||||
|
||||
yield release_lock_async(transaction, locked, cancellable);
|
||||
}
|
||||
|
||||
public async Gee.List<int64?>? search_for_duplicates_async(Transaction? transaction, string? internaldate,
|
||||
long rfc822_size, Cancellable? cancellable) throws Error {
|
||||
bool has_internaldate = !String.is_empty(internaldate);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue