merge of '0bc15679c599b0a07a83838c4039891a9fb7a8bb'

and 'a080c16a5e48751ac225497ff7300f2a67b4721f'

Monotone-Parent: 0bc15679c599b0a07a83838c4039891a9fb7a8bb
Monotone-Parent: a080c16a5e48751ac225497ff7300f2a67b4721f
Monotone-Revision: a32b67b00b6dfccd212526247098ea8c2df940a9

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2012-03-19T16:09:09
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Wolfgang Sourdeau
2012-03-19 16:09:09 +00:00
23 changed files with 259 additions and 85 deletions
+59
View File
@@ -1,3 +1,62 @@
2012-03-16 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* OpenChange/MAPIStoreGCSFolder.m
(-predecessorChangeListForMessageWithKey:): same as below.
(-setChangeKey:forMessageWithKey:): synchronise the version cache
if the message entry is not found.
(-updateVersionsForMessageWithKey:withChangeKey:): new method,
common to all GCS messages, that updates the folder cache and
insert the PidTagChangeKey provided by the client during the save
operations.
* OpenChange/MAPIStoreMailFolder.m
(-predecessorChangeListForMessageWithKey:): the returned list must
be binary ordered by GUID (as specified in the SPEC). We now do so
using the new function below.
(-getPidTagMessageClass:inMemCtx:): removed method, as folders are
not supposed to return a PidTagMessageClass attribute.
* OpenChange/MAPIStoreTypes.m (MAPICNCompare): added as void *
parameter so that the function can be used as a comparator
function in NSArray sort methods.
(MAPIChangeKeyGUIDCompare): new comparator function to compare the
GUID of two change key streams.
* OpenChange/MAPIStoreGCSMessage.m (-updateVersions): new proxy
method for -[MAPIStoreGCSFolder
updateVersionsForMessageWithKey:withChangeKey:].
* OpenChange/MAPIStoreGCSBaseContext.m
(+createRootSecondaryFolderWithFID:andName:forUser:): setup the
userContext in the MAPIApp object.
* OpenChange/MAPIStoreMailContext.m
(+createRootSecondaryFolderWithFID:andName:forUser:): setup the
userContext in the MAPIApp object.
* OpenChange/MAPIStoreContactsFolder.m
(-getPidTagDefaultPostMessageClass:inMemCtx:): new getter.
* OpenChange/MAPIStoreCalendarFolder.m
(-getPidTagDefaultPostMessageClass:inMemCtx:): new getter.
* OpenChange/MAPIStoreTasksFolder.m
(-getPidTagDefaultPostMessageClass:inMemCtx:): new getter.
* OpenChange/MAPIStoreFolder.m
(-getPidTagDefaultPostMessageClass:inMemCtx:): new getter.
* OpenChange/MAPIStoreMessage.m
(-getPidTagMessageStatus:inMemCtx:): removed useless getter.
* OpenChange/MAPIStoreSOGo.m (sogo_backend_init): check for
"SOGoDebugLeaks" in the user defaults and activate GSDebug
allocation utilities.
* OpenChange/NSData+MAPIStore.m (+dataWithChangeKeyGUID:andCnt:):
new method replacing _dataFromChangeKeyGUID:andCnt: from
MAPIStore{GCS,Mail}Folder.
2012-03-16 Jean Raby <jraby@inverse.ca>
* sogo.spec debian/sogo.postint: upon installation, update timestamp
-1
View File
@@ -172,5 +172,4 @@
return MAPISTORE_SUCCESS;
}
@end
+1 -6
View File
@@ -1064,12 +1064,7 @@
if (newParticipationStatus)
[sogoObject changeParticipationStatus: newParticipationStatus
withDelegate: nil];
[(MAPIStoreCalendarFolder *) container synchroniseCache];
value = [properties objectForKey: MAPIPropertyKey (PR_CHANGE_KEY)];
if (value)
[(MAPIStoreCalendarFolder *) container
setChangeKey: value forMessageWithKey: [self nameInContainer]];
[self updateVersions];
}
- (id) lookupAttachment: (NSString *) childKey
+10
View File
@@ -31,11 +31,13 @@
#import "MAPIStoreContactsContext.h"
#import "MAPIStoreContactsMessage.h"
#import "MAPIStoreContactsMessageTable.h"
#import "NSString+MAPIStore.h"
#import "MAPIStoreContactsFolder.h"
#include <util/time.h>
#include <gen_ndr/exchange.h>
#include <mapistore/mapistore_errors.h>
@implementation MAPIStoreContactsFolder
@@ -112,4 +114,12 @@
return [[self activeUserRoles] containsObject: SOGoRole_ObjectViewer];
}
- (int) getPidTagDefaultPostMessageClass: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
*data = [@"IPM.Contact" asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
@end
+2 -5
View File
@@ -1157,11 +1157,8 @@ fromProperties: (NSDictionary *) attachmentProps
// we save the new/modified card
//
[sogoObject saveContentString: [newCard versitString]];
[(MAPIStoreContactsFolder *) container synchroniseCache];
value = [properties objectForKey: MAPIPropertyKey (PR_CHANGE_KEY)];
if (value)
[(MAPIStoreContactsFolder *) container
setChangeKey: value forMessageWithKey: [self nameInContainer]];
[self updateVersions];
}
@end
+8
View File
@@ -1278,6 +1278,14 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
return rc;
}
- (int) getPidTagDefaultPostMessageClass: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
*data = [@"IPM.Note" asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getProperty: (void **) data
withTag: (enum MAPITAGS) propTag
inMemCtx: (TALLOC_CTX *) memCtx
+3
View File
@@ -27,6 +27,7 @@
#import <SOGo/SOGoGCSFolder.h>
#import <SOGo/SOGoParentFolder.h>
#import "MAPIApplication.h"
#import "MAPIStoreUserContext.h"
#import "NSString+MAPIStore.h"
@@ -118,6 +119,7 @@
userContext = [MAPIStoreUserContext userContextWithUsername: userName
andTDBIndexing: NULL];
[MAPIApp setUserContext: userContext];
moduleName = [self MAPIModuleName];
parentFolder = [[userContext rootFolders] objectForKey: moduleName];
if (![parentFolder newFolderWithName: folderName
@@ -126,6 +128,7 @@
userName, moduleName, nameInContainer];
else
mapistoreURI = nil;
[MAPIApp setUserContext: nil];
return mapistoreURI;
}
+2
View File
@@ -41,6 +41,8 @@
/* synchronisation */
- (BOOL) synchroniseCache;
- (void) updateVersionsForMessageWithKey: (NSString *) messageKey
withChangeKey: (NSData *) newChangeKey;
- (NSNumber *) lastModifiedFromMessageChangeNumber: (NSNumber *) changeNum;
- (NSNumber *) changeNumberForMessageWithKey: (NSString *) messageKey;
+35 -26
View File
@@ -252,7 +252,7 @@ static Class NSNumberK;
...
};
VersionMapping = {
Version = MessageKey;
Version = last-modified;
...
}
}
@@ -458,6 +458,15 @@ static Class NSNumberK;
return rc;
}
- (void) updateVersionsForMessageWithKey: (NSString *) messageKey
withChangeKey: (NSData *) newChangeKey
{
[self synchroniseCache];
if (newChangeKey)
[self setChangeKey: newChangeKey forMessageWithKey: messageKey];
}
- (NSNumber *) lastModifiedFromMessageChangeNumber: (NSNumber *) changeNum
{
@@ -491,27 +500,17 @@ static Class NSNumberK;
messages = [[versionsMessage properties] objectForKey: @"Messages"];
messageEntry = [messages objectForKey: messageKey];
if (!messageEntry)
abort ();
{
[self synchroniseCache];
messageEntry = [messages objectForKey: messageKey];
if (!messageEntry)
abort ();
}
[self _setChangeKey: changeKey forMessageEntry: messageEntry];
[versionsMessage save];
}
- (NSData *) _dataFromChangeKeyGUID: (NSString *) guidString
andCnt: (NSData *) globCnt
{
NSMutableData *changeKey;
struct GUID guid;
changeKey = [NSMutableData dataWithCapacity: 16 + [globCnt length]];
[guidString extractGUID: &guid];
[changeKey appendData: [NSData dataWithGUID: &guid]];
[changeKey appendData: globCnt];
return changeKey;
}
- (NSData *) changeKeyForMessageWithKey: (NSString *) messageKey
{
NSDictionary *messages, *changeKeyDict;
@@ -525,7 +524,7 @@ static Class NSNumberK;
{
guid = [changeKeyDict objectForKey: @"GUID"];
globCnt = [changeKeyDict objectForKey: @"LocalId"];
changeKey = [self _dataFromChangeKeyGUID: guid andCnt: globCnt];
changeKey = [NSData dataWithChangeKeyGUID: guid andCnt: globCnt];
}
return changeKey;
@@ -533,9 +532,10 @@ static Class NSNumberK;
- (NSData *) predecessorChangeListForMessageWithKey: (NSString *) messageKey
{
NSMutableData *changeKeys = nil;
NSMutableData *list = nil;
NSDictionary *messages, *changeListDict;
NSArray *keys;
NSMutableArray *changeKeys;
NSUInteger count, max;
NSData *changeKey;
NSString *guid;
@@ -546,21 +546,30 @@ static Class NSNumberK;
objectForKey: @"PredecessorChangeList"];
if (changeListDict)
{
changeKeys = [NSMutableData data];
keys = [changeListDict allKeys];
max = [keys count];
changeKeys = [NSMutableArray arrayWithCapacity: max];
for (count = 0; count < max; count++)
{
guid = [keys objectAtIndex: count];
globCnt = [changeListDict objectForKey: guid];
changeKey = [self _dataFromChangeKeyGUID: guid andCnt: globCnt];
[changeKeys appendUInt8: [changeKey length]];
[changeKeys appendData: changeKey];
changeKey = [NSData dataWithChangeKeyGUID: guid andCnt: globCnt];
[changeKeys addObject: changeKey];
}
[changeKeys sortUsingFunction: MAPIChangeKeyGUIDCompare
context: nil];
list = [NSMutableData data];
for (count = 0; count < max; count++)
{
changeKey = [changeKeys objectAtIndex: count];
[list appendUInt8: [changeKey length]];
[list appendData: changeKey];
}
}
return changeKeys;
return list;
}
- (NSArray *) getDeletedKeysFromChangeNumber: (uint64_t) changeNum
@@ -627,11 +636,11 @@ static Class NSNumberK;
currentChangeNum
= [[messageEntry objectForKey: @"version"]
unsignedLongLongValue];
if (MAPICNCompare (changeNum, currentChangeNum)
if (MAPICNCompare (changeNum, currentChangeNum, NULL)
== NSOrderedAscending)
{
[(NSMutableArray *) deletedKeys addObject: cName];
if (MAPICNCompare (maxChangeNum, currentChangeNum)
if (MAPICNCompare (maxChangeNum, currentChangeNum, NULL)
== NSOrderedAscending)
maxChangeNum = currentChangeNum;
}
+3
View File
@@ -29,6 +29,9 @@
{
}
/* subclass helpers */
- (void) updateVersions;
@end
#endif /* MAPISTOREGCSMESSAGE_H */
+12
View File
@@ -21,6 +21,7 @@
*/
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSValue.h>
#import <NGObjWeb/SoSecurityManager.h>
#import <NGExtensions/NSObject+Logs.h>
@@ -204,4 +205,15 @@
return version;
}
- (void) updateVersions
{
NSData *newChangeKey;
newChangeKey = [properties objectForKey: MAPIPropertyKey (PR_CHANGE_KEY)];
[(MAPIStoreGCSFolder *) container
updateVersionsForMessageWithKey: [self nameInContainer]
withChangeKey: newChangeKey];
}
@end
+3
View File
@@ -32,6 +32,7 @@
#import "NSString+MAPIStore.h"
#import <SOGo/NSString+Utilities.h>
#import "MAPIApplication.h"
#import "MAPIStoreMailContext.h"
#include <dlinklist.h>
@@ -176,6 +177,7 @@ MakeDisplayFolderName (NSString *folderName)
userContext = [MAPIStoreUserContext userContextWithUsername: userName
andTDBIndexing: NULL];
[MAPIApp setUserContext: userContext];
accountFolder = [[userContext rootFolders] objectForKey: @"mail"];
folderName = [NSString stringWithFormat: @"folder%@",
[newFolderName asCSSIdentifier]];
@@ -186,6 +188,7 @@ MakeDisplayFolderName (NSString *folderName)
userName, userName, folderName];
else
mapistoreURI = nil;
[MAPIApp setUserContext: nil];
return mapistoreURI;
}
+18 -31
View File
@@ -218,21 +218,13 @@ static Class SOGoMailFolderK, MAPIStoreOutboxFolderK;
}
- (int) getPidTagContainerClass: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
inMemCtx: (TALLOC_CTX *) memCtx
{
*data = [@"IPF.Note" asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPidTagMessageClass: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
*data = [@"IPM.Note" asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (EOQualifier *) nonDeletedQualifier
{
static EOQualifier *nonDeletedQualifier = nil;
@@ -686,21 +678,6 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
[versionsMessage save];
}
- (NSData *) _dataFromChangeKeyGUID: (NSString *) guidString
andCnt: (NSData *) globCnt
{
NSMutableData *changeKey;
struct GUID guid;
changeKey = [NSMutableData dataWithCapacity: 16 + [globCnt length]];
[guidString extractGUID: &guid];
[changeKey appendData: [NSData dataWithGUID: &guid]];
[changeKey appendData: globCnt];
return changeKey;
}
- (NSData *) changeKeyForMessageWithKey: (NSString *) messageKey
{
NSDictionary *messages, *changeKeyDict;
@@ -716,7 +693,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
{
guid = [changeKeyDict objectForKey: @"GUID"];
globCnt = [changeKeyDict objectForKey: @"LocalId"];
changeKey = [self _dataFromChangeKeyGUID: guid andCnt: globCnt];
changeKey = [NSData dataWithChangeKeyGUID: guid andCnt: globCnt];
}
return changeKey;
@@ -724,9 +701,10 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
- (NSData *) predecessorChangeListForMessageWithKey: (NSString *) messageKey
{
NSMutableData *changeKeys = nil;
NSMutableData *list = nil;
NSDictionary *messages, *changeListDict;
NSArray *keys;
NSMutableArray *changeKeys;
NSUInteger count, max;
NSData *changeKey;
NSString *guid;
@@ -739,21 +717,30 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
objectForKey: @"PredecessorChangeList"];
if (changeListDict)
{
changeKeys = [NSMutableData data];
keys = [changeListDict allKeys];
max = [keys count];
changeKeys = [NSMutableArray arrayWithCapacity: max];
for (count = 0; count < max; count++)
{
guid = [keys objectAtIndex: count];
globCnt = [changeListDict objectForKey: guid];
changeKey = [self _dataFromChangeKeyGUID: guid andCnt: globCnt];
[changeKeys appendUInt8: [changeKey length]];
[changeKeys appendData: changeKey];
changeKey = [NSData dataWithChangeKeyGUID: guid andCnt: globCnt];
[changeKeys addObject: changeKey];
}
[changeKeys sortUsingFunction: MAPIChangeKeyGUIDCompare
context: nil];
list = [NSMutableData data];
for (count = 0; count < max; count++)
{
changeKey = [changeKeys objectAtIndex: count];
[list appendUInt8: [changeKey length]];
[list appendData: changeKey];
}
}
return changeKeys;
return list;
}
- (NSArray *) getDeletedKeysFromChangeNumber: (uint64_t) changeNum
-6
View File
@@ -685,12 +685,6 @@ rtf2html (NSData *compressedRTF)
return MAPISTORE_SUCCESS;
}
- (int) getPidTagMessageStatus: (void **) data // TODO
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getLongZero: data inMemCtx: memCtx];
}
- (int) getPidTagImportance: (void **) data // TODO -> subclass?
inMemCtx: (TALLOC_CTX *) memCtx
{
+11 -1
View File
@@ -21,11 +21,21 @@
*/
#import "MAPIStoreNotesFolder.h"
#import "MAPIStoreNotesMessage.h"
#import "NSString+MAPIStore.h"
#include <mapistore/mapistore_errors.h>
#import "MAPIStoreNotesFolder.h"
@implementation MAPIStoreNotesFolder
- (int) getPidTagDefaultPostMessageClass: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
*data = [@"IPM.StickyNote" asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
@end
+20
View File
@@ -23,6 +23,7 @@
/* OpenChange SOGo storage backend */
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSDebug.h>
#import <Foundation/NSFileHandle.h>
#import <Foundation/NSProcessInfo.h>
#import <Foundation/NSUserDefaults.h>
@@ -48,6 +49,7 @@
#include <mapistore/mapistore_errors.h>
static Class MAPIStoreContextK = Nil;
static BOOL leakDebugging = NO;
static enum mapistore_error
sogo_backend_unexpected_error()
@@ -57,6 +59,16 @@ sogo_backend_unexpected_error()
return MAPISTORE_SUCCESS;
}
static void
sogo_backend_atexit (void)
{
NSAutoreleasePool *pool;
pool = [NSAutoreleasePool new];
NSLog (@"allocated classes:\n%s", GSDebugAllocationList (YES));
[pool release];
}
/**
\details Initialize sogo mapistore backend
@@ -89,6 +101,14 @@ sogo_backend_init (void)
ud = [NSUserDefaults standardUserDefaults];
[ud registerDefaults: [ud persistentDomainForName: @"sogod"]];
if (!leakDebugging && [ud boolForKey: @"SOGoDebugLeaks"])
{
NSLog (@" leak debugging on");
GSDebugAllocationActive (YES);
atexit (sogo_backend_atexit);
leakDebugging = YES;
}
registry = [SoProductRegistry sharedProductRegistry];
[registry scanForProductsInDirectory: SOGO_BUNDLES_DIR];
+10
View File
@@ -34,11 +34,13 @@
#import "MAPIStoreTasksContext.h"
#import "MAPIStoreTasksMessage.h"
#import "MAPIStoreTasksMessageTable.h"
#import "NSString+MAPIStore.h"
#import "MAPIStoreTasksFolder.h"
#include <util/time.h>
#include <gen_ndr/exchange.h>
#include <mapistore/mapistore_errors.h>
@implementation MAPIStoreTasksFolder
@@ -124,4 +126,12 @@
[(SOGoAppointmentFolder *) sogoObject aclSQLListingFilter]];
}
- (int) getPidTagDefaultPostMessageClass: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
*data = [@"IPM.Task" asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
@end
+3 -6
View File
@@ -450,7 +450,7 @@
// percent complete
// NOTE: this does not seem to work on Outlook 2003. PidLidPercentComplete's value
// is always set to 0, no matter what value is set in Outlook
value = [properties objectForKey: MAPIPropertyKey(PidLidPercentComplete)];
value = [properties objectForKey: MAPIPropertyKey (PidLidPercentComplete)];
if (value)
[vToDo setPercentComplete: [value stringValue]];
@@ -462,11 +462,8 @@
[vToDo setTimeStampAsDate: now];
[sogoObject saveContentString: [vCalendar versitString]];
[(MAPIStoreTasksFolder *) container synchroniseCache];
value = [properties objectForKey: MAPIPropertyKey (PR_CHANGE_KEY)];
if (value)
[(MAPIStoreTasksFolder *) container
setChangeKey: value forMessageWithKey: [self nameInContainer]];
[self updateVersions];
}
@end
+2 -1
View File
@@ -42,7 +42,8 @@ id NSObjectFromSPropValue (const struct SPropValue *);
id NSObjectFromMAPISPropValue (const struct mapi_SPropValue *);
id NSObjectFromValuePointer (enum MAPITAGS, const void *);
NSComparisonResult MAPICNCompare (uint64_t cn1, uint64_t cn2);
NSComparisonResult MAPICNCompare (uint64_t cn1, uint64_t cn2, void *);
NSComparisonResult MAPIChangeKeyGUIDCompare (NSData *ck1, NSData *ck2, void *);
static inline NSNumber *
MAPIPropertyKey (enum MAPITAGS propTag)
+36 -1
View File
@@ -284,7 +284,7 @@ _reverseCN (uint64_t cn)
}
NSComparisonResult
MAPICNCompare (uint64_t cn1, uint64_t cn2)
MAPICNCompare (uint64_t cn1, uint64_t cn2, void *unused)
{
NSComparisonResult result;
@@ -298,6 +298,41 @@ MAPICNCompare (uint64_t cn1, uint64_t cn2)
return result;
}
NSComparisonResult MAPIChangeKeyGUIDCompare (NSData *ck1, NSData *ck2, void *unused)
{
NSUInteger count;
const unsigned char *ptr1, *ptr2;
NSComparisonResult result = NSOrderedSame;
if ([ck1 length] < 16)
{
NSLog (@"ck1 has a length < 16");
abort ();
}
if ([ck2 length] < 16)
{
NSLog (@"ck2 has a length < 16");
abort ();
}
ptr1 = [ck1 bytes];
ptr2 = [ck2 bytes];
for (count = 0; result == NSOrderedSame && count < 16; count++)
{
if (*ptr1 < *ptr2)
result = NSOrderedAscending;
else if (*ptr1 > *ptr2)
result = NSOrderedDescending;
else
{
ptr1++;
ptr2++;
}
}
return result;
}
void
MAPIStoreDumpMessageProperties (NSDictionary *properties)
{
+3
View File
@@ -42,6 +42,9 @@
+ (id) dataWithXID: (const struct XID *) xid;
- (struct XID *) asXIDInMemCtx: (void *) memCtx;
+ (id) dataWithChangeKeyGUID: (NSString *) guidString
andCnt: (NSData *) globCnt;
@end
@interface NSMutableData (MAPIStoreDataTypes)
+17
View File
@@ -20,6 +20,8 @@
* Boston, MA 02111-1307, USA.
*/
#import "NSString+MAPIStore.h"
#import "NSData+MAPIStore.h"
#undef DEBUG
@@ -168,6 +170,21 @@ static void _fillFlatUIDWithGUID (struct FlatUID_r *flatUID, const struct GUID *
return xid;
}
+ (id) dataWithChangeKeyGUID: (NSString *) guidString
andCnt: (NSData *) globCnt;
{
NSMutableData *changeKey;
struct GUID guid;
changeKey = [NSMutableData dataWithCapacity: 16 + [globCnt length]];
[guidString extractGUID: &guid];
[changeKey appendData: [NSData dataWithGUID: &guid]];
[changeKey appendData: globCnt];
return changeKey;
}
@end
@implementation NSMutableData (MAPIStoreDataTypes)
+1 -1
View File
@@ -54,7 +54,7 @@ class WebdavSyncTest(unittest.TestCase):
self.assertTrue(token > 0)
query1EndTime = int(math.ceil(query1.start + query1.duration))
self.assertTrue(token <= query1EndTime,
"token = %d > query1EndTime = %d" % (token, query1EndTime))
"token = %d > query1EndTime = %d" % (token, query1EndTime))
# we make sure that any token is accepted when the collection is
# empty, but that the returned token differs