Monotone-Parent: 48c9c37f78835c3255c4103136b86bdfcaaca051

Monotone-Revision: d9c62c6e142174bc3d2adb12ee04492347c95ede

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2011-07-29T02:13:39
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Wolfgang Sourdeau 2011-07-29 02:13:39 +00:00
parent aaa7559ff0
commit 7a5f67babe
7 changed files with 259 additions and 0 deletions

View File

@ -1,5 +1,8 @@
2011-07-28 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* OpenChange/MAPIStoreSOGo.m (sogo_folder_get_deleted_fmids):
implemented new backend method.
* OpenChange/MAPIStoreTable.m (-loggingPrefix): removed method as
it was causing crashes when the parent object was deallocated.

View File

@ -29,6 +29,7 @@
@class NSArray;
@class NSMutableArray;
@class NSNumber;
@class NSURL;
@class EOQualifier;
@ -109,6 +110,11 @@
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) deleteMessageWithMID: (uint64_t) mid
andFlags: (uint8_t) flags;
- (int) getDeletedFMIDs: (struct I8Array_r **) fmidsPtr
andCN: (uint64_t *) cnPtr
fromChangeNumber: (uint64_t) changeNum
inTableType: (uint8_t) tableType
inMemCtx: (TALLOC_CTX *) mem_ctx;
- (int) getTable: (MAPIStoreTable **) tablePtr
andRowCount: (uint32_t *) count
@ -124,6 +130,9 @@
- (MAPIStoreMessageTable *) messageTable;
- (NSArray *) messageKeysMatchingQualifier: (EOQualifier *) qualifier
andSortOrderings: (NSArray *) sortOrderings;
- (NSArray *) getDeletedKeysFromChangeNumber: (uint64_t) changeNum
andCN: (NSNumber **) cnNbr
inTableType: (uint8_t) tableType;
- (NSString *) createFolder: (struct SRow *) aRow
withFID: (uint64_t) newFID;

View File

@ -519,6 +519,64 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
return rc;
}
- (int) getDeletedFMIDs: (struct I8Array_r **) fmidsPtr
andCN: (uint64_t *) cnPtr
fromChangeNumber: (uint64_t) changeNum
inTableType: (uint8_t) tableType
inMemCtx: (TALLOC_CTX *) memCtx
{
int rc;
NSString *baseURL, *format, *url;
NSArray *keys;
NSNumber *cnNbr;
NSUInteger count, max;
MAPIStoreMapping *mapping;
struct I8Array_r *fmids;
uint64_t fmid;
keys = [self getDeletedKeysFromChangeNumber: changeNum andCN: &cnNbr
inTableType: tableType];
if (keys)
{
mapping = [[self context] mapping];
max = [keys count];
fmids = talloc_zero (memCtx, struct I8Array_r);
fmids->cValues = 0;
fmids->lpi8 = talloc_array (fmids, int64_t, max);
*fmidsPtr = fmids;
if (max > 0)
*cnPtr = [cnNbr unsignedLongLongValue];
baseURL = [self url];
if ([baseURL hasSuffix: @"/"])
format = @"%@%@";
else
format = @"%@/%@";
for (count = 0; count < max; count++)
{
url = [NSString stringWithFormat: format,
baseURL, [keys objectAtIndex: count]];
fmid = [mapping idFromURL: url];
if (fmid != NSNotFound) /* if no fmid is returned, then the object
"never existed" in the OpenChange
databases */
{
fmids->lpi8[fmids->cValues] = fmid;
fmids->cValues++;
}
}
rc = MAPISTORE_SUCCESS;
}
else
rc = MAPISTORE_ERR_NOT_FOUND;
return rc;
}
- (int) getTable: (MAPIStoreTable **) tablePtr
andRowCount: (uint32_t *) countPtr
tableType: (uint8_t) tableType
@ -928,6 +986,13 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
return nil;
}
- (NSArray *) getDeletedKeysFromChangeNumber: (uint64_t) changeNum
andCN: (NSNumber **) cnNbrs
inTableType: (uint8_t) tableType
{
return nil;
}
- (Class) messageClass
{
[self subclassResponsibility: _cmd];

View File

@ -299,6 +299,92 @@
return changeNumber;
}
- (NSArray *) getDeletedKeysFromChangeNumber: (uint64_t) changeNum
andCN: (NSNumber **) cnNbr
inTableType: (uint8_t) tableType
{
NSArray *deletedKeys, *deletedCNames, *records;
NSNumber *changeNumNbr, *lastModified;
NSString *cName;
NSDictionary *versionProperties;
NSMutableDictionary *messages, *mapping;
uint64_t newChangeNum = 0;
EOAndQualifier *fetchQualifier;
EOKeyValueQualifier *cDeletedQualifier, *cLastModifiedQualifier;
EOFetchSpecification *fs;
GCSFolder *ocsFolder;
NSUInteger count, max;
if (tableType == MAPISTORE_MESSAGE_TABLE)
{
deletedKeys = [NSMutableArray array];
changeNumNbr = [NSNumber numberWithUnsignedLongLong: changeNum];
lastModified = [self lastModifiedFromMessageChangeNumber: changeNumNbr];
if (lastModified)
{
versionProperties = [versionsMessage properties];
messages = [versionProperties objectForKey: @"Messages"];
ocsFolder = [sogoObject ocsFolder];
cLastModifiedQualifier = [[EOKeyValueQualifier alloc]
initWithKey: @"c_lastmodified"
operatorSelector: EOQualifierOperatorGreaterThanOrEqualTo
value: lastModified];
cDeletedQualifier = [[EOKeyValueQualifier alloc]
initWithKey: @"c_deleted"
operatorSelector: EOQualifierOperatorEqual
value: [NSNumber numberWithInt: 1]];
fetchQualifier = [[EOAndQualifier alloc] initWithQualifiers:
cLastModifiedQualifier,
cDeletedQualifier,
nil];
[fetchQualifier autorelease];
[cLastModifiedQualifier release];
[cDeletedQualifier release];
fs = [EOFetchSpecification
fetchSpecificationWithEntityName: [ocsFolder folderName]
qualifier: fetchQualifier
sortOrderings: nil];
records = [ocsFolder
fetchFields: [NSArray arrayWithObject: @"c_name"]
fetchSpecification: fs
ignoreDeleted: NO];
deletedCNames = [records objectsForKey: @"c_name" notFoundMarker: nil];
max = [deletedCNames count];
if (max > 0)
{
mapping = [versionProperties objectForKey: @"VersionsMapping"];
for (count = 0; count < max; count++)
{
cName = [deletedCNames objectAtIndex: count];
if ([messages objectForKey: cName])
{
[messages removeObjectForKey: cName];
[(NSMutableArray *) deletedKeys addObject: cName];
newChangeNum = [[self context] getNewChangeNumber];
}
}
if (newChangeNum)
{
changeNumNbr
= [NSNumber numberWithUnsignedLongLong: newChangeNum];
[mapping setObject: lastModified forKey: changeNumNbr];
*cnNbr = changeNumNbr;
[versionsMessage save];
}
}
}
}
else
deletedKeys = [super getDeletedKeysFromChangeNumber: changeNum
andCN: cnNbr
inTableType: tableType];
return deletedKeys;
}
/* subclasses */
- (EOQualifier *) componentQualifier

View File

@ -32,6 +32,7 @@
#import <EOControl/EOSortOrdering.h>
#import <NGExtensions/NSObject+Logs.h>
#import <NGExtensions/NSString+misc.h>
#import <NGImap4/NGImap4Connection.h>
#import <Mailer/SOGoDraftsFolder.h>
#import <Mailer/SOGoMailAccount.h>
#import <Mailer/SOGoMailAccounts.h>
@ -97,6 +98,9 @@ static Class SOGoMailFolderK;
accountFolder = [accountsFolder lookupName: @"0"
inContext: woContext
acquire: NO];
[[accountFolder imap4Connection]
enableExtension: @"QRESYNC"];
[parentContainersBag addObject: accountFolder];
[woContext setClientObject: accountFolder];
@ -501,6 +505,61 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
return changeNumber;
}
- (NSArray *) getDeletedKeysFromChangeNumber: (uint64_t) changeNum
andCN: (NSNumber **) cnNbr
inTableType: (uint8_t) tableType
{
NSArray *deletedKeys, *deletedUIDs;
NSNumber *changeNumNbr;
uint64_t modseq;
NSDictionary *versionProperties, *status;
NSMutableDictionary *messages, *mapping;
NSNumber *newChangeNumNbr, *highestModseq;
uint64_t newChangeNum;
NSUInteger count, max;
if (tableType == MAPISTORE_MESSAGE_TABLE)
{
changeNumNbr = [NSNumber numberWithUnsignedLongLong: changeNum];
modseq = [[self modseqFromMessageChangeNumber: changeNumNbr]
unsignedLongLongValue];
if (modseq > 0)
{
status
= [sogoObject
statusForFlags: [NSArray arrayWithObject: @"HIGHESTMODSEQ"]];
highestModseq = [status objectForKey: @"highestmodseq"];
versionProperties = [versionsMessage properties];
messages = [versionProperties objectForKey: @"Messages"];
deletedUIDs = [(SOGoMailFolder *) sogoObject
fetchUIDsOfVanishedItems: modseq];
deletedKeys = [deletedUIDs stringsWithFormat: @"%@.eml"];
max = [deletedUIDs count];
if (max > 0)
{
[messages removeObjectsForKeys: deletedUIDs];
mapping = [versionProperties objectForKey: @"VersionsMapping"];
for (count = 0; count < max; count++)
newChangeNum = [[self context] getNewChangeNumber];
newChangeNumNbr = [NSNumber numberWithUnsignedLongLong: newChangeNum];
*cnNbr = newChangeNumNbr;
[mapping setObject: newChangeNumNbr forKey: @"SyncLastModseq"];
[versionsMessage save];
}
}
else
deletedKeys = [NSArray array];
}
else
deletedKeys = [super getDeletedKeysFromChangeNumber: changeNum
andCN: cnNbr
inTableType: tableType];
return deletedKeys;
}
@end
@implementation MAPIStoreInboxFolder : MAPIStoreMailFolder

View File

@ -62,6 +62,8 @@ MAPIStoreMappingTDBTraverse (TDB_CONTEXT *ctx, TDB_DATA data1, TDB_DATA data2,
mapping = data;
[mapping setObject: uri forKey: idNbr];
NSLog (@"preregistered url '%@' for id '%@'", uri, idNbr);
return 0;
}
@ -104,6 +106,7 @@ MAPIStoreMappingTDBTraverse (TDB_CONTEXT *ctx, TDB_DATA data1, TDB_DATA data2,
{
idNbr = [keys objectAtIndex: count];
uri = [mapping objectForKey: idNbr];
[self logWithFormat: @"preregistered id '%@' for url '%@'", idNbr, uri];
[reverseMapping setObject: idNbr forKey: uri];
}
}

View File

@ -441,6 +441,39 @@ sogo_folder_delete_message(void *folder_object, uint64_t mid, uint8_t flags)
return rc;
}
static int
sogo_folder_get_deleted_fmids(void *folder_object, TALLOC_CTX *mem_ctx,
uint8_t table_type, uint64_t change_num,
struct I8Array_r **fmidsp, uint64_t *cnp)
{
struct MAPIStoreTallocWrapper *wrapper;
NSAutoreleasePool *pool;
MAPIStoreFolder *folder;
int rc;
DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__));
if (folder_object)
{
wrapper = folder_object;
folder = wrapper->MAPIStoreSOGoObject;
pool = [NSAutoreleasePool new];
rc = [folder getDeletedFMIDs: fmidsp
andCN: cnp
fromChangeNumber: change_num
inTableType: table_type
inMemCtx: mem_ctx];
[pool release];
}
else
{
NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO OBJECT");
rc = MAPISTORE_SUCCESS;
}
return rc;
}
static int
sogo_folder_open_table(void *folder_object, TALLOC_CTX *mem_ctx,
uint8_t table_type, uint32_t handle_id,
@ -989,6 +1022,7 @@ int mapistore_init_backend(void)
backend.folder.open_message = sogo_folder_open_message;
backend.folder.create_message = sogo_folder_create_message;
backend.folder.delete_message = sogo_folder_delete_message;
backend.folder.get_deleted_fmids = sogo_folder_get_deleted_fmids;
backend.folder.get_child_count = sogo_folder_get_child_count;
backend.folder.open_table = sogo_folder_open_table;
backend.message.create_attachment = sogo_message_create_attachment;