From 06476abdf7018337116b1608ffe2016196f3924c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20J=2E=20Hern=C3=A1ndez=20Blasco?= Date: Thu, 26 Mar 2015 22:05:43 +0100 Subject: [PATCH 1/2] oc-mail: return soft-deleted mails while syncing As well as hard deleted As explained in [MS-OXCFXICS] Section 2.2.1.3.1, the property MetaTagIdsetDeleted must include both types of messages and this idset is filled with the return value of this message. --- OpenChange/MAPIStoreMailFolder.m | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/OpenChange/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m index e8f25e183..11e1154be 100644 --- a/OpenChange/MAPIStoreMailFolder.m +++ b/OpenChange/MAPIStoreMailFolder.m @@ -1009,6 +1009,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) NSString *changeNumber; uint64_t modseq; NSDictionary *versionProperties; + EOQualifier *deletedQualifier, *kvQualifier, *searchQualifier; if (tableType == MAPISTORE_MESSAGE_TABLE) { @@ -1017,8 +1018,33 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) unsignedLongLongValue]; if (modseq > 0) { + /* Hard deleted items */ deletedUIDs = [(SOGoMailFolder *) sogoObject fetchUIDsOfVanishedItems: modseq]; + + /* Soft deleted items */ + kvQualifier = [[EOKeyValueQualifier alloc] + initWithKey: @"modseq" + operatorSelector: EOQualifierOperatorGreaterThanOrEqualTo + value: [NSNumber numberWithUnsignedLongLong: modseq]]; + deletedQualifier + = [[EOKeyValueQualifier alloc] + initWithKey: @"FLAGS" + operatorSelector: EOQualifierOperatorContains + value: [NSArray arrayWithObject: @"Deleted"]]; + + searchQualifier = [[EOAndQualifier alloc] + initWithQualifiers: + kvQualifier, deletedQualifier, nil]; + + deletedUIDs = [deletedUIDs arrayByAddingObjectsFromArray: + [sogoObject fetchUIDsMatchingQualifier: searchQualifier + sortOrdering: nil]]; + + [deletedQualifier release]; + [kvQualifier release]; + [searchQualifier release]; + deletedKeys = [deletedUIDs stringsWithFormat: @"%@.eml"]; if ([deletedUIDs count] > 0) { From dfde498b7c170cd0c92bf75e74dd8c47d8764fa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20J=2E=20Hern=C3=A1ndez=20Blasco?= Date: Thu, 26 Mar 2015 22:45:13 +0100 Subject: [PATCH 2/2] oc-mail: Include Deleted flagged messages on syncing cache This gives an accurate value for SyncLastDeletedMessage --- OpenChange/MAPIStoreMailFolder.m | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/OpenChange/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m index 11e1154be..07d1debe2 100644 --- a/OpenChange/MAPIStoreMailFolder.m +++ b/OpenChange/MAPIStoreMailFolder.m @@ -519,7 +519,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) *nextModseq; NSString *changeNumber, *uid, *messageKey; uint64_t lastModseqNbr; - EOQualifier *kvQualifier, *searchQualifier; + EOQualifier *searchQualifier; NSArray *uids, *changeNumbers; NSUInteger count, max; NSArray *fetchResults; @@ -560,14 +560,11 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) { lastModseqNbr = [lastModseq unsignedLongLongValue]; nextModseq = [NSNumber numberWithUnsignedLongLong: lastModseqNbr + 1]; - kvQualifier = [[EOKeyValueQualifier alloc] + searchQualifier = [[EOKeyValueQualifier alloc] initWithKey: @"modseq" operatorSelector: EOQualifierOperatorGreaterThanOrEqualTo value: nextModseq]; - searchQualifier = [[EOAndQualifier alloc] - initWithQualifiers: - kvQualifier, [self nonDeletedQualifier], nil]; - [kvQualifier release]; + [searchQualifier autorelease]; } else @@ -595,7 +592,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) fetchResults = [(NSDictionary *) [sogoObject fetchUIDs: uids - parts: [NSArray arrayWithObject: @"modseq"]] + parts: [NSArray arrayWithObjects: @"modseq", @"flags", nil]] objectForKey: @"fetch"]; /* NOTE: we sort items manually because Cyrus does not properly sort @@ -631,17 +628,22 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) if (!lastModseq || ([lastModseq compare: modseq] == NSOrderedAscending)) lastModseq = modseq; + + if ([[result objectForKey: @"flags"] containsObject: @"deleted"]) + [currentProperties setObject: changeNumber + forKey: @"SyncLastDeleteChangeNumber"]; } [currentProperties setObject: lastModseq forKey: @"SyncLastModseq"]; foundChange = YES; } - /* 2. we synchronise deleted UIDs */ + /* 2. we synchronise expunged UIDs */ if (initialLastModseq) { fetchResults = [(SOGoMailFolder *) sogoObject fetchUIDsOfVanishedItems: lastModseqNbr]; + max = [fetchResults count]; changeNumber = nil; @@ -769,7 +771,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) if (!messageEntry) { fetchResults = [(NSDictionary *) [sogoObject fetchUIDs: [NSArray arrayWithObject: messageUID] - parts: [NSArray arrayWithObject: @"modseq"]] + parts: [NSArray arrayWithObjects: @"modseq", @"flags", nil]] objectForKey: @"fetch"]; if ([fetchResults count] == 1) { @@ -795,6 +797,11 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) mapping = [currentProperties objectForKey: @"VersionMapping"]; [mapping setObject: modseq forKey: changeNumberStr]; + /* Store the last deleted change number if it is soft-deleted */ + if ([[result objectForKey: @"flags"] containsObject: @"deleted"]) + [currentProperties setObject: changeNumberStr + forKey: @"SyncLastDeleteChangeNumber"]; + /* Save the message */ [versionsMessage save]; return YES;