Monotone-Parent: 75575dc685de1258c4ba450e53c12e11c7954b71

Monotone-Revision: 28a24e19c42fd0a497caf994e8b2f88fc7432164

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2012-03-12T06:03:56
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Wolfgang Sourdeau
2012-03-12 06:03:56 +00:00
parent e8917905b8
commit 98bf3201e7
6 changed files with 122 additions and 84 deletions

View File

@@ -1,5 +1,25 @@
2012-03-12 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* OpenChange/MAPIStoreGCSFolder.m (-componentQualifier): now
provided by the parent class itself.
(-contentComponentQualifier): new method that returns a qualifier
that translated to "c_content like '%BEGIN:XXX%'". This is a hack
to work-around the fact that calendar folders may content both
vevent and vtodo and that c_component, being part of the quick
table, is no longer available when a record is deleted.
(-synchroniseCache): update version values for deleted records
too, by taking into account the fact that their c_version value
might still be 0. Make use of contentComponentQualifier above.
Remove the modified records from the SOGoGCSFolder cache.
(-getDeletedKeysFromChangeNumber:andCN:inTableType:): wander the
list of deleted records and no longer increase the change number,
as this is now done from "synchroniseCache". Also, handle the case
were deleted records might already have been reported by comparing
their change number to the one provided as parameter. The
resulting change number is now guaranteed to be the highest one.
(-component): new subclassable method that returns a string
matching the folder's handled component.
* OpenChange/MAPIStoreFolder.m
(-getPidTagLocalCommitTimeMax:inMemCtx:): returns
MAPISTORE_ERR_NOT_FOUND if the resulting date is nil.

View File

@@ -49,17 +49,9 @@
return [MAPIStoreCalendarMessageTable tableForContainer: self];
}
- (EOQualifier *) componentQualifier
- (NSString *) component
{
static EOQualifier *componentQualifier = nil;
if (!componentQualifier)
componentQualifier
= [[EOKeyValueQualifier alloc] initWithKey: @"c_component"
operatorSelector: EOQualifierOperatorEqual
value: @"vevent"];
return componentQualifier;
return @"vevent";
}
- (MAPIStoreMessage *) createMessage

View File

@@ -45,18 +45,9 @@
return [MAPIStoreContactsMessageTable tableForContainer: self];
}
- (EOQualifier *) componentQualifier
- (NSString *) component
{
static EOQualifier *componentQualifier = nil;
/* TODO: we need to support vlist as well */
if (!componentQualifier)
componentQualifier
= [[EOKeyValueQualifier alloc] initWithKey: @"c_component"
operatorSelector: EOQualifierOperatorEqual
value: @"vcard"];
return componentQualifier;
return @"vcard";
}
- (MAPIStoreMessage *) createMessage

View File

@@ -36,6 +36,7 @@
{
SOGoMAPIFSMessage *versionsMessage;
NSArray *activeUserRoles;
EOQualifier *componentQualifier;
}
/* synchronisation */
@@ -50,9 +51,12 @@
- (NSArray *) activeUserRoles;
- (EOQualifier *) componentQualifier;
- (EOQualifier *) contentComponentQualifier;
/* subclasses */
- (EOQualifier *) aclQualifier;
- (EOQualifier *) componentQualifier;
- (NSString *) component;
@end

View File

@@ -48,8 +48,15 @@
#include <mapistore/mapistore.h>
#include <mapistore/mapistore_errors.h>
static Class NSNumberK;
@implementation MAPIStoreGCSFolder
+ (void) initialize
{
NSNumberK = [NSNumber class];
}
- (id) initWithSOGoObject: (id) newSOGoObject
inContainer: (MAPIStoreObject *) newContainer
{
@@ -72,6 +79,7 @@
{
[versionsMessage release];
[activeUserRoles release];
[componentQualifier release];
[super dealloc];
}
@@ -207,17 +215,15 @@
- (NSDate *) lastMessageModificationTime
{
NSDate *value;
NSNumber *ti;
NSDate *value = nil;
ti = [[versionsMessage properties]
objectForKey: @"SyncLastSynchronisationDate"];
objectForKey: @"SyncLastModificationDate"];
if (ti)
value = [NSDate dateWithTimeIntervalSince1970: [ti doubleValue]];
else
value = [NSDate date];
[self logWithFormat: @"lastMessageModificationTime: %@", value];
value = nil;
return value;
}
@@ -283,13 +289,41 @@
[changeList setObject: globCnt forKey: guid];
}
- (EOQualifier *) componentQualifier
{
if (!componentQualifier)
componentQualifier
= [[EOKeyValueQualifier alloc] initWithKey: @"c_component"
operatorSelector: EOQualifierOperatorEqual
value: [self component]];
return componentQualifier;
}
- (EOQualifier *) contentComponentQualifier
{
EOQualifier *contentComponentQualifier;
NSString *likeString;
likeString = [NSString stringWithFormat: @"%%BEGIN:%@%%",
[[self component] uppercaseString]];
contentComponentQualifier = [[EOKeyValueQualifier alloc]
initWithKey: @"c_content"
operatorSelector: EOQualifierOperatorLike
value: likeString];
[contentComponentQualifier autorelease];
return contentComponentQualifier;
}
- (BOOL) synchroniseCache
{
BOOL rc = YES, foundChange = NO;
uint64_t newChangeNum;
NSData *changeKey;
NSString *cName;
NSNumber *ti, *changeNumber, *lastModificationDate, *cVersion, *cLastModified;
NSNumber *ti, *changeNumber, *lastModificationDate, *cVersion,
*cLastModified, *cDeleted;
EOFetchSpecification *fs;
EOQualifier *searchQualifier, *fetchQualifier;
NSUInteger count, max;
@@ -304,7 +338,7 @@
if (!fields)
fields = [[NSArray alloc]
initWithObjects: @"c_name", @"c_version", @"c_lastmodified",
nil];
@"c_deleted", nil];
if (!sortOrdering)
{
@@ -313,26 +347,7 @@
[sortOrdering retain];
}
now = [NSCalendarDate date];
currentProperties = [[versionsMessage properties] mutableCopy];
if (!currentProperties)
currentProperties = [NSMutableDictionary new];
[currentProperties autorelease];
messages = [currentProperties objectForKey: @"Messages"];
if (!messages)
{
messages = [NSMutableDictionary new];
[currentProperties setObject: messages forKey: @"Messages"];
[messages release];
}
mapping = [currentProperties objectForKey: @"VersionMapping"];
if (!mapping)
{
mapping = [NSMutableDictionary new];
[currentProperties setObject: mapping forKey: @"VersionMapping"];
[mapping release];
}
currentProperties = [versionsMessage properties];
lastModificationDate = [currentProperties objectForKey: @"SyncLastModificationDate"];
if (lastModificationDate)
@@ -342,8 +357,9 @@
operatorSelector: EOQualifierOperatorGreaterThanOrEqualTo
value: lastModificationDate];
fetchQualifier = [[EOAndQualifier alloc]
initWithQualifiers:
searchQualifier, [self componentQualifier], nil];
initWithQualifiers: searchQualifier,
[self contentComponentQualifier],
nil];
[fetchQualifier autorelease];
[searchQualifier release];
}
@@ -355,21 +371,40 @@
fetchSpecificationWithEntityName: [ocsFolder folderName]
qualifier: fetchQualifier
sortOrderings: [NSArray arrayWithObject: sortOrdering]];
fetchResults = [ocsFolder fetchFields: fields fetchSpecification: fs];
fetchResults = [ocsFolder fetchFields: fields
fetchSpecification: fs
ignoreDeleted: NO];
max = [fetchResults count];
if (max > 0)
{
messages = [currentProperties objectForKey: @"Messages"];
if (!messages)
{
messages = [NSMutableDictionary new];
[currentProperties setObject: messages forKey: @"Messages"];
[messages release];
}
mapping = [currentProperties objectForKey: @"VersionMapping"];
if (!mapping)
{
mapping = [NSMutableDictionary new];
[currentProperties setObject: mapping forKey: @"VersionMapping"];
[mapping release];
}
ldb_transaction_start([[self context] connectionInfo]->oc_ctx);
for (count = 0; count < max; count++)
{
result = [fetchResults objectAtIndex: count];
cName = [result objectForKey: @"c_name"];
cVersion = [result objectForKey: @"c_version"];
cDeleted = [result objectForKey: @"c_deleted"];
if ([cDeleted isKindOfClass: NSNumberK] && [cDeleted intValue])
cVersion = [NSNumber numberWithInt: -1];
else
cVersion = [result objectForKey: @"c_version"];
cLastModified = [result objectForKey: @"c_lastmodified"];
[sogoObject removeChildRecordWithName: cName];
messageEntry = [messages objectForKey: cName];
if (!messageEntry)
{
@@ -377,9 +412,12 @@
[messages setObject: messageEntry forKey: cName];
[messageEntry release];
}
if (![[messageEntry objectForKey: @"c_version"]
isEqual: cVersion])
{
[sogoObject removeChildRecordWithName: cName];
foundChange = YES;
newChangeNum = [[self context] getNewChangeNumber];
@@ -405,6 +443,7 @@
if (foundChange)
{
now = [NSCalendarDate date];
ti = [NSNumber numberWithDouble: [now timeIntervalSince1970]];
[currentProperties setObject: ti
forKey: @"SyncLastSynchronisationDate"];
@@ -529,9 +568,9 @@
NSArray *deletedKeys, *deletedCNames, *records;
NSNumber *changeNumNbr, *lastModified;
NSString *cName;
NSDictionary *versionProperties;
NSMutableDictionary *messages, *mapping;
uint64_t newChangeNum = 0;
NSDictionary *versionProperties, *messageEntry;
NSMutableDictionary *messages;
uint64_t maxChangeNum = changeNum, currentChangeNum;
EOAndQualifier *fetchQualifier;
EOKeyValueQualifier *cDeletedQualifier, *cLastModifiedQualifier;
EOFetchSpecification *fs;
@@ -576,28 +615,28 @@
ignoreDeleted: NO];
deletedCNames = [records objectsForKey: @"c_name" notFoundMarker: nil];
max = [deletedCNames count];
if (max > 0)
for (count = 0; count < max; count++)
{
mapping = [versionProperties objectForKey: @"VersionsMapping"];
for (count = 0; count < max; count++)
cName = [deletedCNames objectAtIndex: count];
[sogoObject removeChildRecordWithName: cName];
messageEntry = [messages objectForKey: cName];
if (messageEntry)
{
cName = [deletedCNames objectAtIndex: count];
if ([messages objectForKey: cName])
currentChangeNum
= [[messageEntry objectForKey: @"version"]
unsignedLongLongValue];
if (MAPICNCompare (changeNum, currentChangeNum)
== NSOrderedAscending)
{
[messages removeObjectForKey: cName];
[(NSMutableArray *) deletedKeys addObject: cName];
newChangeNum = [[self context] getNewChangeNumber];
if (MAPICNCompare (maxChangeNum, currentChangeNum)
== NSOrderedAscending)
maxChangeNum = currentChangeNum;
}
}
if (newChangeNum)
{
changeNumNbr
= [NSNumber numberWithUnsignedLongLong: newChangeNum];
[mapping setObject: lastModified forKey: changeNumNbr];
*cnNbr = changeNumNbr;
[versionsMessage save];
}
}
if (maxChangeNum != changeNum)
*cnNbr = [NSNumber numberWithUnsignedLongLong: maxChangeNum];
}
}
else
@@ -642,7 +681,7 @@
return nil;
}
- (EOQualifier *) componentQualifier
- (NSString *) component
{
[self subclassResponsibility: _cmd];

View File

@@ -48,17 +48,9 @@
return [MAPIStoreTasksMessageTable tableForContainer: self];
}
- (EOQualifier *) componentQualifier
- (NSString *) component
{
static EOQualifier *componentQualifier = nil;
if (!componentQualifier)
componentQualifier
= [[EOKeyValueQualifier alloc] initWithKey: @"c_component"
operatorSelector: EOQualifierOperatorEqual
value: @"vtodo"];
return componentQualifier;
return @"vtodo";
}
- (MAPIStoreMessage *) createMessage