Moved FLAGS out of PROPERTIES (email fields)

EmailFlags seemed to be a natural fit for EmailProperties, but
it became apparent that EmailFlags change all the time (and must
be polled to notice changes) while other properties are immutable.
For efficiency, moved EmailFlags out of EmailProperties and made
them their own Email.Field.  EmailProperties may expand later to
supply user-visible information; for now, only used internally by
the IMAP stack.
This commit is contained in:
Jim Nelson 2012-06-01 11:42:04 -07:00
parent bf961172d6
commit a15cef4b82
18 changed files with 148 additions and 108 deletions

View file

@ -587,7 +587,7 @@ public class GearyController {
messages_to_add.add(full_email);
if (full_email.properties.email_flags.is_unread())
if (full_email.email_flags.is_unread())
ids.add(full_email.id);
}

View file

@ -13,10 +13,10 @@ public enum TreeSortable {
public class MessageListStore : Gtk.TreeStore {
public const Geary.Email.Field REQUIRED_FIELDS =
Geary.Email.Field.ENVELOPE | Geary.Email.Field.PROPERTIES;
Geary.Email.Field.ENVELOPE | Geary.Email.Field.FLAGS;
public const Geary.Email.Field WITH_PREVIEW_FIELDS =
Geary.Email.Field.ENVELOPE | Geary.Email.Field.PROPERTIES | Geary.Email.Field.PREVIEW;
Geary.Email.Field.ENVELOPE | Geary.Email.Field.FLAGS | Geary.Email.Field.PREVIEW;
public enum Column {
MESSAGE_DATA,

View file

@ -12,7 +12,7 @@ public class MessageViewer : WebKit.WebView {
| Geary.Email.Field.RECEIVERS
| Geary.Email.Field.SUBJECT
| Geary.Email.Field.DATE
| Geary.Email.Field.PROPERTIES
| Geary.Email.Field.FLAGS
| Geary.Email.Field.PREVIEW;
private const string MESSAGE_CONTAINER_ID = "message_container";
@ -712,7 +712,7 @@ public class MessageViewer : WebKit.WebView {
return;
}
Geary.EmailFlags flags = email.properties.email_flags;
Geary.EmailFlags flags = email.email_flags;
// Update the flags in out message set.
foreach (Geary.Email message in messages) {

View file

@ -28,7 +28,7 @@ public class Geary.DBus.Conversations : Object {
public Conversations(Geary.Folder folder) {
this.folder = folder;
conversations = new Geary.ConversationMonitor(folder, false, Geary.Email.Field.ENVELOPE |
Geary.Email.Field.PROPERTIES);
Geary.Email.Field.FLAGS);
start_monitoring_async.begin();
}

View file

@ -27,7 +27,7 @@ public class Geary.DBus.Email : Object {
cc = email.cc != null ? email.cc.to_string() : "";
subject = email.subject != null ? email.subject.to_string() : "";
date = email.date != null ? email.date.as_time_t : 0;
read = email.properties != null ? email.properties.email_flags.contains(EmailFlags.UNREAD)
read = email.email_flags != null ? email.email_flags.contains(EmailFlags.UNREAD)
: true;
}

View file

@ -12,8 +12,7 @@ public class Geary.ComposedEmail : Object {
| Geary.Email.Field.RECEIVERS
| Geary.Email.Field.REFERENCES
| Geary.Email.Field.SUBJECT
| Geary.Email.Field.DATE
| Geary.Email.Field.PROPERTIES;
| Geary.Email.Field.DATE;
public DateTime date { get; set; }
public RFC822.MailboxAddresses from { get; set; }

View file

@ -10,7 +10,7 @@ public class Geary.ConversationMonitor : Object {
* be retrieved irregardless of the Field parameter passed to the constructor.
*/
public const Geary.Email.Field REQUIRED_FIELDS = Geary.Email.Field.REFERENCES |
Geary.Email.Field.PROPERTIES | Geary.Email.Field.DATE;
Geary.Email.Field.FLAGS | Geary.Email.Field.DATE;
private const int RETRY_CONNECTION_SEC = 15;

View file

@ -52,7 +52,7 @@ public abstract class Geary.Conversation : Object {
private bool has_flag(Geary.EmailFlag flag) {
foreach (Geary.Email email in get_email(Ordering.NONE)) {
if (email.properties != null && email.properties.email_flags.contains(flag))
if (email.email_flags != null && email.email_flags.contains(flag))
return true;
}

View file

@ -4,15 +4,20 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
/**
* EmailProperties holds (in general) immutable metadata about an Email. EmailFlags used to be
* held here and retrieved via Email.Field.PROPERTIES, but as they're mutable, they were broken out
* for efficiency reasons.
*
* Currently EmailProperties offers nothing to clients of the Geary engine. In the future it may
* be expanded to supply details like when the message was added to the local store, checksums,
* and so forth.
*/
public abstract class Geary.EmailProperties : Object {
// Flags set on the email object.
public EmailFlags email_flags { get; set; }
public EmailProperties() {
}
public virtual string to_string() {
return "EmailProperties:%s".printf(email_flags.to_string());
}
public abstract string to_string();
}

View file

@ -21,6 +21,7 @@ public class Geary.Email : Object {
BODY = 1 << 6,
PROPERTIES = 1 << 7,
PREVIEW = 1 << 8,
FLAGS = 1 << 9,
ENVELOPE = DATE | ORIGINATORS | RECEIVERS | REFERENCES | SUBJECT,
ALL = 0xFFFFFFFF;
@ -35,7 +36,8 @@ public class Geary.Email : Object {
HEADER,
BODY,
PROPERTIES,
PREVIEW
PREVIEW,
FLAGS
};
}
@ -118,6 +120,9 @@ public class Geary.Email : Object {
// PREVIEW
public RFC822.PreviewText? preview { get; private set; default = null; }
// FLAGS
public Geary.EmailFlags? email_flags { get; private set; default = null; }
public Geary.Email.Field fields { get; private set; default = Field.NONE; }
private Geary.RFC822.Message? message = null;
@ -136,23 +141,11 @@ public class Geary.Email : Object {
}
public inline Trillian is_unread() {
return properties == null ? Trillian.UNKNOWN :
Trillian.from_boolean(properties.email_flags.is_unread());
return email_flags != null ? Trillian.from_boolean(email_flags.is_unread()) : Trillian.UNKNOWN;
}
public inline Trillian is_flagged() {
return properties == null ? Trillian.UNKNOWN :
Trillian.from_boolean(properties.email_flags.is_flagged());
}
public inline EmailFlags? get_flags() {
return properties == null ? null : properties.email_flags;
}
public void set_flags(Geary.EmailFlags flags) {
if (properties != null) {
properties.email_flags = flags;
}
return email_flags != null ? Trillian.from_boolean(email_flags.is_flagged()) : Trillian.UNKNOWN;
}
public void set_send_date(Geary.RFC822.Date? date) {
@ -224,6 +217,12 @@ public class Geary.Email : Object {
fields |= Field.PREVIEW;
}
public void set_flags(Geary.EmailFlags email_flags) {
this.email_flags = email_flags;
fields |= Field.FLAGS;
}
/**
* This method requires Geary.Email.Field.HEADER and Geary.Email.Field.BODY be present.
* If not, EngineError.INCOMPLETE_MESSAGE is thrown.

View file

@ -5,26 +5,12 @@
*/
public class Geary.Imap.EmailProperties : Geary.EmailProperties, Equalable {
public bool answered { get; private set; }
public bool deleted { get; private set; }
public bool draft { get; private set; }
public bool flagged { get; private set; }
public bool recent { get; private set; }
public bool seen { get; private set; }
public InternalDate? internaldate { get; private set; }
public RFC822.Size? rfc822_size { get; private set; }
public EmailProperties(MessageFlags flags, InternalDate? internaldate, RFC822.Size? rfc822_size) {
email_flags = new Geary.Imap.EmailFlags(flags);
public EmailProperties(InternalDate? internaldate, RFC822.Size? rfc822_size) {
this.internaldate = internaldate;
this.rfc822_size = rfc822_size;
answered = flags.contains(MessageFlag.ANSWERED);
deleted = flags.contains(MessageFlag.DELETED);
draft = flags.contains(MessageFlag.DRAFT);
flagged = flags.contains(MessageFlag.FLAGGED);
recent = flags.contains(MessageFlag.RECENT);
seen = flags.contains(MessageFlag.SEEN);
}
public bool equals(Equalable e) {
@ -43,19 +29,11 @@ public class Geary.Imap.EmailProperties : Geary.EmailProperties, Equalable {
if (rfc822_size == null || other.rfc822_size == null)
return false;
return get_message_flags().equals(other.get_message_flags()) &&
internaldate.equals(other.internaldate) &&
rfc822_size.equals(other.rfc822_size);
}
public Geary.Imap.MessageFlags get_message_flags() {
return ((Geary.Imap.EmailFlags) this.email_flags).message_flags;
return true;
}
public override string to_string() {
return base.to_string() + "/answered:%s/deleted:%s/draft:%s/flagged:%s/seen:%s/internaldate:%s/size:%s".printf(
answered.to_string(), deleted.to_string(), draft.to_string(), flagged.to_string(),
seen.to_string(), (internaldate != null) ? internaldate.to_string() : "(none)",
return "internaldate:%s/size:%s".printf((internaldate != null) ? internaldate.to_string() : "(none)",
(rfc822_size != null) ? rfc822_size.to_string() : "(none)");
}
}

View file

@ -148,7 +148,6 @@ public class Geary.Imap.Mailbox : Geary.SmartReference {
if (fields.require(Geary.Email.Field.PROPERTIES)) {
// Properties.
Gee.List<FetchDataType> properties_data_types_list = new Gee.ArrayList<FetchDataType>();
properties_data_types_list.add(FetchDataType.FLAGS);
properties_data_types_list.add(FetchDataType.INTERNALDATE);
properties_data_types_list.add(FetchDataType.RFC822_SIZE);
@ -158,6 +157,17 @@ public class Geary.Imap.Mailbox : Geary.SmartReference {
properties_id = batch.add(new MailboxOperation(context, properties_cmd));
}
int flags_id = NonblockingBatch.INVALID_ID;
if (fields.require(Geary.Email.Field.FLAGS)) {
// Flags
FetchDataType[] flags_data_types = new FetchDataType[1];
flags_data_types[0] = FetchDataType.FLAGS;
FetchCommand flags_cmd = new FetchCommand(msg_set, flags_data_types, null);
flags_id = batch.add(new MailboxOperation(context, flags_cmd));
}
yield batch.execute_all_async(cancellable);
// Keep list of generated messages (which are returned) and a map of the messages according
@ -228,6 +238,25 @@ public class Geary.Imap.Mailbox : Geary.SmartReference {
}
}
if (flags_id != NonblockingBatch.INVALID_ID) {
MailboxOperation flags_op = (MailboxOperation) batch.get_operation(flags_id);
CommandResponse flags_resp = (CommandResponse) batch.get_result(flags_id);
if (flags_resp.status_response.status != Status.OK) {
throw new ImapError.SERVER_ERROR("Server error for %s: %s",
flags_op.cmd.to_string(), flags_resp.to_string());
}
FetchResults[] flags_results = FetchResults.decode(flags_resp);
foreach (FetchResults flags_res in flags_results) {
Geary.Email? flags_email = pos_map.get(flags_res.msg_num);
if (flags_email == null)
flags_email = accumulate_email(flags_res, msgs, pos_map);
fetch_results_to_email(flags_res, Geary.Email.Field.FLAGS, flags_email);
}
}
// process preview FETCH results
if (preview_id != NonblockingBatch.INVALID_ID &&
preview_charset_id != NonblockingBatch.INVALID_ID) {
@ -348,6 +377,7 @@ public class Geary.Imap.Mailbox : Geary.SmartReference {
case Geary.Email.Field.BODY:
case Geary.Email.Field.PROPERTIES:
case Geary.Email.Field.FLAGS:
case Geary.Email.Field.NONE:
case Geary.Email.Field.PREVIEW:
// not set (or, for body previews and properties, fetched separately)
@ -366,8 +396,9 @@ public class Geary.Imap.Mailbox : Geary.SmartReference {
private static void fetch_results_to_email(FetchResults res, Geary.Email.Field fields,
Geary.Email email) throws Error {
// accumulate these to submit Imap.EmailProperties all at once
Geary.Imap.MessageFlags? flags = null;
// accumulate these to submit Imap.EmailProperties all at once
InternalDate? internaldate = null;
RFC822.Size? rfc822_size = null;
@ -430,8 +461,11 @@ public class Geary.Imap.Mailbox : Geary.SmartReference {
}
// Only set PROPERTIES if all have been found
if (flags != null && internaldate != null && rfc822_size != null)
email.set_email_properties(new Geary.Imap.EmailProperties(flags, internaldate, rfc822_size));
if (internaldate != null && rfc822_size != null)
email.set_email_properties(new Geary.Imap.EmailProperties(internaldate, rfc822_size));
if (flags != null)
email.set_flags(new Geary.Imap.EmailFlags(flags));
// fields_to_fetch_data_types() will always generate a single FetchBodyDataType for all
// the header fields it needs

View file

@ -83,9 +83,9 @@ private class Geary.EmailFlagWatcher : Object {
private async void do_flag_watch_async() throws Error {
debug("do_flag_watch_async begin %s", folder.to_string());
// Fetch all email properties in local folder.
// Fetch all email flags in local folder.
Gee.List<Geary.Email>? list_local = yield folder.list_email_async(-1, int.MAX,
Email.Field.PROPERTIES, Geary.Folder.ListFlags.LOCAL_ONLY, cancellable);
Email.Field.FLAGS, Geary.Folder.ListFlags.LOCAL_ONLY, cancellable);
if (list_local == null || list_local.size == 0) {
debug("do_flag_watch_async: no local email in %s", folder.to_string());
@ -96,12 +96,12 @@ private class Geary.EmailFlagWatcher : Object {
Gee.HashMap<Geary.EmailIdentifier, Geary.EmailFlags> local_map = new Gee.HashMap<
Geary.EmailIdentifier, Geary.EmailFlags>(Geary.Hashable.hash_func, Geary.Equalable.equal_func);
foreach (Geary.Email e in list_local)
local_map.set(e.id, e.properties.email_flags);
local_map.set(e.id, e.email_flags);
// Fetch e-mail from folder using force update, which will cause the cache to be bypassed
// and the latest to be gotten from the server (updating the cache in the process)
Gee.List<Geary.Email>? list_remote = yield folder.list_email_by_sparse_id_async(local_map.keys,
Email.Field.PROPERTIES, Geary.Folder.ListFlags.FORCE_UPDATE, cancellable);
Email.Field.FLAGS, Geary.Folder.ListFlags.FORCE_UPDATE, cancellable);
if (list_remote == null || list_remote.size == 0) {
debug("do_flag_watch_async: no remote mail in %s", folder.to_string());
@ -116,8 +116,8 @@ private class Geary.EmailFlagWatcher : Object {
if (!local_map.has_key(e.id))
continue;
if (!local_map.get(e.id).equals(e.properties.email_flags))
changed_map.set(e.id, e.properties.email_flags);
if (!local_map.get(e.id).equals(e.email_flags))
changed_map.set(e.id, e.email_flags);
}
if (!cancellable.is_cancelled() && changed_map.size > 0) {

View file

@ -7,7 +7,8 @@
private class Geary.GenericImapFolder : Geary.AbstractFolder {
internal const int REMOTE_FETCH_CHUNK_COUNT = 50;
private const Geary.Email.Field NORMALIZATION_FIELDS = Geary.Email.Field.PROPERTIES;
private const Geary.Email.Field NORMALIZATION_FIELDS = Geary.Email.Field.PROPERTIES
| Geary.Email.Field.FLAGS;
internal Sqlite.Folder local_folder { get; protected set; }
internal Imap.Folder? remote_folder { get; protected set; default = null; }
@ -208,15 +209,13 @@ private class Geary.GenericImapFolder : Geary.AbstractFolder {
if (remote_uid.value == local_uid.value) {
// same, update flags (if changed) and move on
// Because local is PARTIAL_OK, EmailProperties may not be present
Geary.Imap.EmailProperties? local_email_properties =
(Geary.Imap.EmailProperties) local_email.properties;
Geary.Imap.EmailProperties remote_email_properties =
(Geary.Imap.EmailProperties) remote_email.properties;
// Because local is PARTIAL_OK, EmailFlags may not be present
Geary.Imap.EmailFlags? local_email_flags = (Geary.Imap.EmailFlags) local_email.email_flags;
Geary.Imap.EmailFlags remote_email_flags = (Geary.Imap.EmailFlags) remote_email.email_flags;
if ((local_email_properties == null) || !local_email_properties.equals(remote_email_properties)) {
if ((local_email_flags == null) || !local_email_flags.equals(remote_email_flags)) {
batch.add(new CreateLocalEmailOperation(local_folder, remote_email, NORMALIZATION_FIELDS));
flags_changed.set(remote_email.id, remote_email.properties.email_flags);
flags_changed.set(remote_email.id, remote_email.email_flags);
}
remote_ctr++;

View file

@ -236,9 +236,12 @@ private class Geary.Sqlite.Folder : Object, Geary.ReferenceSemantics {
// only write out the IMAP email properties if they're supplied and there's something to
// write out -- no need to create an empty row
Geary.Imap.EmailProperties? properties = (Geary.Imap.EmailProperties?) email.properties;
if (email.fields.fulfills(Geary.Email.Field.PROPERTIES) && properties != null) {
Geary.Imap.EmailFlags? email_flags = (Geary.Imap.EmailFlags?) email.email_flags;
if (email.fields.is_any_set(Geary.Email.Field.PROPERTIES | Geary.Email.Field.FLAGS)) {
ImapMessagePropertiesRow properties_row = new ImapMessagePropertiesRow.from_imap_properties(
imap_message_properties_table, message_id, properties);
imap_message_properties_table, message_id, properties,
(email_flags != null) ? email_flags.message_flags : null);
yield imap_message_properties_table.create_async(transaction, properties_row, cancellable);
}
@ -333,7 +336,8 @@ private class Geary.Sqlite.Folder : Object, Geary.ReferenceSemantics {
foreach (MessageLocationRow location_row in list) {
// fetch the message itself
MessageRow? message_row = null;
if (required_fields != Geary.Email.Field.NONE && required_fields != Geary.Email.Field.PROPERTIES) {
if (required_fields != Geary.Email.Field.NONE
&& required_fields.clear(Geary.Email.Field.PROPERTIES | Geary.Email.Field.FLAGS) != 0) {
message_row = yield message_table.fetch_async(transaction, location_row.message_id,
required_fields, cancellable);
assert(message_row != null);
@ -345,7 +349,8 @@ private class Geary.Sqlite.Folder : Object, Geary.ReferenceSemantics {
}
ImapMessagePropertiesRow? properties = null;
if (required_fields.require(Geary.Email.Field.PROPERTIES)) {
if (required_fields.require(Geary.Email.Field.PROPERTIES)
|| required_fields.require(Geary.Email.Field.FLAGS)) {
properties = yield imap_message_properties_table.fetch_async(transaction,
location_row.message_id, cancellable);
if (!partial_ok && properties == null)
@ -368,8 +373,13 @@ private class Geary.Sqlite.Folder : Object, Geary.ReferenceSemantics {
? message_row.to_email(position, email_id)
: new Geary.Email(position, email_id);
if (properties != null)
email.set_email_properties(properties.get_imap_email_properties());
if (properties != null) {
if (required_fields.require(Geary.Email.Field.PROPERTIES))
email.set_email_properties(properties.get_imap_email_properties());
if (required_fields.require(Geary.Email.Field.FLAGS))
email.set_flags(properties.get_email_flags());
}
emails.add(email);
}
@ -405,9 +415,9 @@ private class Geary.Sqlite.Folder : Object, Geary.ReferenceSemantics {
if (required_fields == Geary.Email.Field.NONE)
return new Geary.Email(position, id);
// Only fetch message row if we have fields other than Properties.
// Only fetch message row if we have fields other than Properties and Flags
MessageRow? message_row = null;
if (required_fields != Geary.Email.Field.PROPERTIES) {
if (required_fields.clear(Geary.Email.Field.PROPERTIES | Geary.Email.Field.FLAGS) != 0) {
message_row = yield message_table.fetch_async(transaction,
location_row.message_id, required_fields, cancellable);
if (message_row == null) {
@ -417,7 +427,8 @@ private class Geary.Sqlite.Folder : Object, Geary.ReferenceSemantics {
// see if the message row fulfills everything but properties, which are held in
// separate table
if (!partial_ok && !message_row.fields.fulfills(required_fields.clear(Geary.Email.Field.PROPERTIES))) {
if (!partial_ok &&
!message_row.fields.fulfills(required_fields.clear(Geary.Email.Field.PROPERTIES | Geary.Email.Field.FLAGS))) {
throw new EngineError.INCOMPLETE_MESSAGE(
"Message %s in folder %s only fulfills %Xh fields (required: %Xh)", id.to_string(),
to_string(), message_row.fields, required_fields);
@ -425,13 +436,13 @@ private class Geary.Sqlite.Folder : Object, Geary.ReferenceSemantics {
}
ImapMessagePropertiesRow? properties = null;
if (required_fields.require(Geary.Email.Field.PROPERTIES)) {
if (required_fields.is_any_set(Geary.Email.Field.PROPERTIES | Geary.Email.Field.FLAGS)) {
properties = yield imap_message_properties_table.fetch_async(transaction,
location_row.message_id, cancellable);
if (!partial_ok && properties == null) {
throw new EngineError.INCOMPLETE_MESSAGE(
"Message %s in folder %s does not have PROPERTIES field", id.to_string(),
to_string());
"Message %s in folder %s does not have PROPERTIES and/or FLAGS fields",
id.to_string(), to_string());
}
}
@ -439,8 +450,13 @@ private class Geary.Sqlite.Folder : Object, Geary.ReferenceSemantics {
email = message_row != null ? message_row.to_email(position, id) : email =
new Geary.Email(position, id);
if (properties != null)
email.set_email_properties(properties.get_imap_email_properties());
if (properties != null) {
if (required_fields.require(Geary.Email.Field.PROPERTIES))
email.set_email_properties(properties.get_imap_email_properties());
if (required_fields.require(Geary.Email.Field.FLAGS))
email.set_flags(properties.get_email_flags());
}
return email;
}
@ -520,7 +536,7 @@ private class Geary.Sqlite.Folder : Object, Geary.ReferenceSemantics {
if (row == null)
continue;
map.set(id, row.get_imap_email_properties().email_flags);
map.set(id, row.get_email_flags());
}
yield transaction.commit_async(cancellable);
@ -580,7 +596,8 @@ private class Geary.Sqlite.Folder : Object, Geary.ReferenceSemantics {
if (email.fields == Geary.Email.Field.NONE)
return;
if (email.fields != Geary.Email.Field.PROPERTIES) {
// Only merge with MessageTable if has fields applicable to it
if (email.fields.clear(Geary.Email.Field.PROPERTIES | Geary.Email.Field.FLAGS) != 0) {
MessageRow? message_row = yield message_table.fetch_async(transaction, message_id, email.fields,
cancellable);
assert(message_row != null);
@ -600,8 +617,16 @@ private class Geary.Sqlite.Folder : Object, Geary.ReferenceSemantics {
long rfc822_size =
(properties.rfc822_size != null) ? properties.rfc822_size.value : -1;
yield imap_message_properties_table.update_async(transaction, message_id,
properties.get_message_flags().serialize(), internaldate, rfc822_size, cancellable);
yield imap_message_properties_table.update_properties_async(transaction, message_id,
internaldate, rfc822_size, cancellable);
}
// update IMAP flags
if (email.fields.fulfills(Geary.Email.Field.FLAGS)) {
string? flags = ((Geary.Imap.EmailFlags) email.email_flags).message_flags.serialize();
yield imap_message_properties_table.update_flags_async(transaction, message_id,
flags, cancellable);
}
}

View file

@ -197,8 +197,8 @@ public class Geary.Sqlite.MessageTable : Geary.Sqlite.Table {
public async MessageRow? fetch_async(Transaction? transaction, int64 id,
Geary.Email.Field requested_fields, Cancellable? cancellable = null) throws Error {
assert(requested_fields != Geary.Email.Field.NONE);
// PROPERTIES are handled by the appropriate PropertiesTable
assert(requested_fields != Geary.Email.Field.PROPERTIES);
// PROPERTIES and FLAGS are handled by the appropriate PropertiesTable
assert(requested_fields.clear(Geary.Email.Field.PROPERTIES | Geary.Email.Field.FLAGS) != 0);
Transaction locked = yield obtain_lock_async(transaction, "MessageTable.fetch_async",
cancellable);

View file

@ -23,14 +23,14 @@ public class Geary.Sqlite.ImapMessagePropertiesRow : Geary.Sqlite.Row {
}
public ImapMessagePropertiesRow.from_imap_properties(ImapMessagePropertiesTable table,
int64 message_id, Geary.Imap.EmailProperties properties) {
int64 message_id, Geary.Imap.EmailProperties? properties, Imap.MessageFlags? message_flags) {
base (table);
id = Row.INVALID_ID;
this.message_id = message_id;
flags = properties.get_message_flags().serialize();
internaldate = properties.internaldate.original;
rfc822_size = properties.rfc822_size.value;
flags = (message_flags != null) ? message_flags.serialize() : "";
internaldate = (properties != null) ? properties.internaldate.original : "";
rfc822_size = (properties != null) ? properties.rfc822_size.value : -1;
}
public Geary.Imap.EmailProperties get_imap_email_properties() {
@ -42,8 +42,11 @@ public class Geary.Sqlite.ImapMessagePropertiesRow : Geary.Sqlite.Row {
err.message);
}
return new Geary.Imap.EmailProperties(Geary.Imap.MessageFlags.deserialize(flags),
constructed, new RFC822.Size(rfc822_size));
return new Geary.Imap.EmailProperties(constructed, new RFC822.Size(rfc822_size));
}
public Geary.EmailFlags get_email_flags() {
return new Geary.Imap.EmailFlags(Geary.Imap.MessageFlags.deserialize(flags));
}
}

View file

@ -59,18 +59,16 @@ public class Geary.Sqlite.ImapMessagePropertiesTable : Geary.Sqlite.Table {
result.fetch_string(1), result.fetch_string(2), (long) result.fetch_int64(3));
}
public async void update_async(Transaction? transaction, int64 message_id, string? flags,
public async void update_properties_async(Transaction? transaction, int64 message_id,
string? internaldate, long rfc822_size, Cancellable? cancellable) throws Error {
Transaction locked = yield obtain_lock_async(transaction, "ImapMessagePropertiesTable.update_async",
cancellable);
SQLHeavy.Query query = locked.prepare(
"UPDATE ImapMessagePropertiesTable SET flags = ?, internaldate = ?, rfc822_size = ? "
+ "WHERE message_id = ?");
query.bind_string(0, flags);
query.bind_string(1, internaldate);
query.bind_int64(2, rfc822_size);
query.bind_int64(3, message_id);
"UPDATE ImapMessagePropertiesTable SET internaldate = ?, rfc822_size = ? WHERE message_id = ?");
query.bind_string(0, internaldate);
query.bind_int64(1, rfc822_size);
query.bind_int64(2, message_id);
yield query.execute_async(cancellable);
locked.set_commit_required();