Fix for bug #2734
parent
22f5ed62fe
commit
5419f411e5
|
@ -126,6 +126,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
[[o properties] removeObjectForKey: @"SyncKey"];
|
[[o properties] removeObjectForKey: @"SyncKey"];
|
||||||
[[o properties] removeObjectForKey: @"SyncCache"];
|
[[o properties] removeObjectForKey: @"SyncCache"];
|
||||||
[[o properties] removeObjectForKey: @"DateCache"];
|
[[o properties] removeObjectForKey: @"DateCache"];
|
||||||
|
[[o properties] removeObjectForKey: @"MoreAvailable"];
|
||||||
|
|
||||||
[[o properties] addEntriesFromDictionary: theFolderMetadata];
|
[[o properties] addEntriesFromDictionary: theFolderMetadata];
|
||||||
[o save];
|
[o save];
|
||||||
|
@ -477,21 +478,70 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
lastServerKey: (NSString **) theLastServerKey
|
lastServerKey: (NSString **) theLastServerKey
|
||||||
|
|
||||||
{
|
{
|
||||||
NSMutableDictionary *folderMetadata;
|
NSMutableDictionary *folderMetadata, *dateCache, *syncCache;
|
||||||
NSMutableString *s;
|
NSMutableString *s;
|
||||||
|
|
||||||
BOOL more_available;
|
BOOL more_available;
|
||||||
int i, max;
|
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: @"<SoftDelete xmlns=\"AirSync:\">"];
|
||||||
|
[s appendFormat: @"<ServerId xmlns=\"AirSync:\">%@</ServerId>", key];
|
||||||
|
[s appendString: @"</SoftDelete>"];
|
||||||
|
|
||||||
|
[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.
|
// 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.
|
// 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;
|
return;
|
||||||
|
|
||||||
s = [NSMutableString string];
|
|
||||||
|
|
||||||
more_available = NO;
|
more_available = NO;
|
||||||
|
|
||||||
switch (theFolderType)
|
switch (theFolderType)
|
||||||
|
@ -614,7 +664,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
case ActiveSyncMailFolder:
|
case ActiveSyncMailFolder:
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
NSMutableDictionary *syncCache, *dateCache;
|
|
||||||
SOGoSyncCacheObject *lastCacheObject, *aCacheObject;
|
SOGoSyncCacheObject *lastCacheObject, *aCacheObject;
|
||||||
NSMutableArray *allCacheObjects, *sortedBySequence;
|
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: @"SyncCache"];
|
||||||
[folderMetadata setObject: [NSMutableDictionary dictionary] forKey: @"DateCache"];
|
[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
|
// 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
|
// with the same name has been created but folderSync has not yet updated the cache
|
||||||
if (!([[theCollection nameInContainer] isEqualToString:
|
if (!([[theCollection nameInContainer] isEqualToString:
|
||||||
|
@ -805,6 +855,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
break;
|
break;
|
||||||
} // switch (folderType) ...
|
} // switch (folderType) ...
|
||||||
|
|
||||||
|
return_response:
|
||||||
|
|
||||||
if ([s length])
|
if ([s length])
|
||||||
{
|
{
|
||||||
[theBuffer appendString: @"<Commands>"];
|
[theBuffer appendString: @"<Commands>"];
|
||||||
|
@ -1008,7 +1060,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
davCollectionTag = [collection davCollectionTag];
|
davCollectionTag = [collection davCollectionTag];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Generate the response buffer
|
// Generate the response buffer
|
||||||
[theBuffer appendString: @"<Collection>"];
|
[theBuffer appendString: @"<Collection>"];
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#import <NGMime/NGMimeBodyPart.h>
|
#import <NGMime/NGMimeBodyPart.h>
|
||||||
#import <NGMime/NGMimeFileData.h>
|
#import <NGMime/NGMimeFileData.h>
|
||||||
#import <NGMime/NGMimeMultipartBody.h>
|
#import <NGMime/NGMimeMultipartBody.h>
|
||||||
|
#import <NGMime/NGMimeType.h>
|
||||||
#import <NGMail/NGMimeMessageParser.h>
|
#import <NGMail/NGMimeMessageParser.h>
|
||||||
#import <NGMail/NGMimeMessage.h>
|
#import <NGMail/NGMimeMessage.h>
|
||||||
#import <NGMail/NGMimeMessageGenerator.h>
|
#import <NGMail/NGMimeMessageGenerator.h>
|
||||||
|
@ -170,6 +171,41 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
return [o properties];
|
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
|
- (id) globallyUniqueIDToIMAPFolderName: (NSString *) theIdToTranslate
|
||||||
type: (SOGoMicrosoftActiveSyncFolderType) theFolderType
|
type: (SOGoMicrosoftActiveSyncFolderType) theFolderType
|
||||||
{
|
{
|
||||||
|
@ -919,6 +955,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
sortOrdering: @"REVERSE ARRIVAL"
|
sortOrdering: @"REVERSE ARRIVAL"
|
||||||
threaded: NO];
|
threaded: NO];
|
||||||
count = [uids count];
|
count = [uids count];
|
||||||
|
|
||||||
|
// Add the number of UIDs expected to "soft delete"
|
||||||
|
count += [self _softDeleteCountWithFilter: filter collectionId: realCollectionId];
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
1
NEWS
1
NEWS
|
@ -5,6 +5,7 @@ Enhancements
|
||||||
- contacts photos are now synchronized using ActiveSync (#2807)
|
- contacts photos are now synchronized using ActiveSync (#2807)
|
||||||
- implemented the GetAttachment ActiveSync command (#2808)
|
- implemented the GetAttachment ActiveSync command (#2808)
|
||||||
- implemented the Ping ActiveSync command
|
- implemented the Ping ActiveSync command
|
||||||
|
- added "soft deletes" support for ActiveSync (#2734)
|
||||||
|
|
||||||
Bug fixes
|
Bug fixes
|
||||||
- better handling of empty "Flag" messages over ActiveSync (#2806)
|
- better handling of empty "Flag" messages over ActiveSync (#2806)
|
||||||
|
|
Loading…
Reference in New Issue