From 5419f411e5bae58cc17ab22b3b95a88efab74252 Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Wed, 25 Jun 2014 15:05:25 -0400 Subject: [PATCH] Fix for bug #2734 --- ActiveSync/SOGoActiveSyncDispatcher+Sync.m | 63 +++++++++++++++++++--- ActiveSync/SOGoActiveSyncDispatcher.m | 40 ++++++++++++++ NEWS | 1 + 3 files changed, 98 insertions(+), 6 deletions(-) diff --git a/ActiveSync/SOGoActiveSyncDispatcher+Sync.m b/ActiveSync/SOGoActiveSyncDispatcher+Sync.m index 8c206baaf..024b2a2a7 100644 --- a/ActiveSync/SOGoActiveSyncDispatcher+Sync.m +++ b/ActiveSync/SOGoActiveSyncDispatcher+Sync.m @@ -126,6 +126,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [[o properties] removeObjectForKey: @"SyncKey"]; [[o properties] removeObjectForKey: @"SyncCache"]; [[o properties] removeObjectForKey: @"DateCache"]; + [[o properties] removeObjectForKey: @"MoreAvailable"]; [[o properties] addEntriesFromDictionary: theFolderMetadata]; [o save]; @@ -477,21 +478,70 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. lastServerKey: (NSString **) theLastServerKey { - NSMutableDictionary *folderMetadata; + NSMutableDictionary *folderMetadata, *dateCache, *syncCache; NSMutableString *s; BOOL more_available; int i, max; + s = [NSMutableString string]; + + more_available = NO; + + if (theFolderType == ActiveSyncMailFolder && !([theSyncKey isEqualToString: @"-1"]) && theFilterType) + { + NSArray *allKeys; + NSString *key; + int softdelete_count; + + softdelete_count = 0; + + folderMetadata = [self _folderMetadataForKey: [theCollection nameInContainer]]; + dateCache = [folderMetadata objectForKey: @"DateCache"]; + syncCache = [folderMetadata objectForKey: @"SyncCache"]; + + allKeys = [dateCache allKeys]; + for (i = 0; i < [allKeys count]; i++) + { + key = [allKeys objectAtIndex: i]; + + if ([[dateCache objectForKey:key] compare: theFilterType] == NSOrderedAscending) + { + [s appendString: @""]; + [s appendFormat: @"%@", key]; + [s appendString: @""]; + + [syncCache removeObjectForKey: key]; + [dateCache removeObjectForKey: key]; + + softdelete_count++; + } + + if (softdelete_count >= theWindowSize) + { + [folderMetadata setObject: [NSNumber numberWithBool: YES] forKey: @"MoreAvailable"]; + [self _setFolderMetadata: folderMetadata forKey: [theCollection nameInContainer]]; + + more_available = YES; + *theLastServerKey = theSyncKey; + + // Since WindowSize is reached don't even try to add more to the response, let's just + // jump to the end and return the response immediately + goto return_response; + } + } + + [folderMetadata removeObjectForKey: @"MoreAvailable"]; + [self _setFolderMetadata: folderMetadata forKey: [theCollection nameInContainer]]; + } + // // No changes in the collection - 2.2.2.19.1.1 Empty Sync Request. // We check this and we don't generate any commands if we don't have to. // - if ([theSyncKey isEqualToString: [theCollection davCollectionTag]]) + if ([theSyncKey isEqualToString: [theCollection davCollectionTag]] && !([s length])) return; - s = [NSMutableString string]; - more_available = NO; switch (theFolderType) @@ -614,7 +664,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. case ActiveSyncMailFolder: default: { - NSMutableDictionary *syncCache, *dateCache; SOGoSyncCacheObject *lastCacheObject, *aCacheObject; NSMutableArray *allCacheObjects, *sortedBySequence; @@ -644,6 +693,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [folderMetadata setObject: [NSMutableDictionary dictionary] forKey: @"SyncCache"]; [folderMetadata setObject: [NSMutableDictionary dictionary] forKey: @"DateCache"]; } + // Check whether GUID in cache is equal to the GUID from imap - this is to avoid cache corruptions if a folder has been renamed and a new folder // with the same name has been created but folderSync has not yet updated the cache if (!([[theCollection nameInContainer] isEqualToString: @@ -805,6 +855,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. break; } // switch (folderType) ... + return_response: + if ([s length]) { [theBuffer appendString: @""]; @@ -1008,7 +1060,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. davCollectionTag = [collection davCollectionTag]; } - // Generate the response buffer [theBuffer appendString: @""]; diff --git a/ActiveSync/SOGoActiveSyncDispatcher.m b/ActiveSync/SOGoActiveSyncDispatcher.m index b98ce3bd2..82c1868fc 100644 --- a/ActiveSync/SOGoActiveSyncDispatcher.m +++ b/ActiveSync/SOGoActiveSyncDispatcher.m @@ -64,6 +64,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #import #import #import +#import #import #import #import @@ -170,6 +171,41 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. return [o properties]; } +- (unsigned int) _softDeleteCountWithFilter: (NSCalendarDate *) theFilter + collectionId: (NSString *) theCollectionId +{ + NSMutableDictionary *dateCache; + NSMutableArray *sdUids; + SOGoCacheGCSObject *o; + NSArray *allKeys; + NSString *key; + + int i; + + sdUids = [NSMutableArray array]; + + if (theFilter) + { + o = [SOGoCacheGCSObject objectWithName: [NSString stringWithFormat: @"%@+folder%@", [context objectForKey: @"DeviceId"], theCollectionId] inContainer: nil]; + [o setObjectType: ActiveSyncGlobalCacheObject]; + [o setTableUrl: [self folderTableURL]]; + [o reloadIfNeeded]; + + dateCache = [[o properties] objectForKey: @"DateCache"]; + allKeys = [dateCache allKeys]; + + for (i = 0; i < [allKeys count]; i++) + { + key = [allKeys objectAtIndex: i]; + + if ([[dateCache objectForKey:key] compare: theFilter ] == NSOrderedAscending) + [sdUids addObject: [dateCache objectForKey:key]]; + } + } + + return [sdUids count]; +} + - (id) globallyUniqueIDToIMAPFolderName: (NSString *) theIdToTranslate type: (SOGoMicrosoftActiveSyncFolderType) theFolderType { @@ -919,6 +955,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. sortOrdering: @"REVERSE ARRIVAL" threaded: NO]; count = [uids count]; + + // Add the number of UIDs expected to "soft delete" + count += [self _softDeleteCountWithFilter: filter collectionId: realCollectionId]; + } else { diff --git a/NEWS b/NEWS index 42cc196d5..46be9433c 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ Enhancements - contacts photos are now synchronized using ActiveSync (#2807) - implemented the GetAttachment ActiveSync command (#2808) - implemented the Ping ActiveSync command + - added "soft deletes" support for ActiveSync (#2734) Bug fixes - better handling of empty "Flag" messages over ActiveSync (#2806)