From b67e1deda55ffc702d090629587f8a85b5967d8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20J=2E=20Hern=C3=A1ndez=20Blasco?= Date: Wed, 15 Oct 2014 00:35:17 +0200 Subject: [PATCH] oc-folder: Make deleted items synched when shared By keeping mid on moving messages by soft deleting and only if srcMid is different from targetMid. This makes restore/shared deleted items work. It also requires to do the following to work smoothly: * Do not add soft-deleted messages in ensureIDsForChildKeys * Return soft-deleted messages on getDeletedFMIDs * Do not register a new mid if the URL is matched with soft deleted messages --- OpenChange/MAPIStoreFolder.m | 15 ++++++++++----- OpenChange/MAPIStoreMapping.h | 2 ++ OpenChange/MAPIStoreMapping.m | 30 ++++++++++++++++++++++++------ 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/OpenChange/MAPIStoreFolder.m b/OpenChange/MAPIStoreFolder.m index 472f2b7c7..733ce6114 100644 --- a/OpenChange/MAPIStoreFolder.m +++ b/OpenChange/MAPIStoreFolder.m @@ -679,6 +679,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe //TALLOC_CTX *memCtx; struct SRow aRow; struct SPropValue property; + uint8_t deleteFlags; [self logWithFormat: @"-moveCopyMessageWithMID: 0x%.16llx .. withMID: 0x%.16llx .. wantCopy: %d", srcMid, targetMid, wantCopy]; @@ -709,7 +710,9 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe } [destMsg save: memCtx]; if (!wantCopy) - rc = [sourceFolder deleteMessageWithMID: srcMid andFlags: 0]; + /* We want to keep mid for restoring/shared data to work if mids are different. */ + deleteFlags = (srcMid == targetMid) ? MAPISTORE_PERMANENT_DELETE : MAPISTORE_SOFT_DELETE; + rc = [sourceFolder deleteMessageWithMID: srcMid andFlags: deleteFlags]; end: //talloc_free (memCtx); @@ -949,6 +952,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe NSString *baseURL, *URL, *key; NSArray *newIDs; uint64_t idNbr; + bool softDeleted; baseURL = [self url]; @@ -959,8 +963,8 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe { key = [keys objectAtIndex: count]; URL = [NSString stringWithFormat: @"%@%@", baseURL, key]; - idNbr = [mapping idFromURL: URL]; - if (idNbr == NSNotFound) + idNbr = [mapping idFromURL: URL isSoftDeleted: &softDeleted]; + if (idNbr == NSNotFound && !softDeleted) [missingURLs addObject: URL]; } @@ -1091,6 +1095,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe MAPIStoreMapping *mapping; struct UI8Array_r *fmids; uint64_t fmid; + bool softDeleted; keys = [self getDeletedKeysFromChangeNumber: changeNum andCN: &cnNbr inTableType: tableType]; @@ -1117,10 +1122,10 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe { url = [NSString stringWithFormat: format, baseURL, [keys objectAtIndex: count]]; - fmid = [mapping idFromURL: url]; + fmid = [mapping idFromURL: url isSoftDeleted: &softDeleted]; if (fmid != NSNotFound) /* if no fmid is returned, then the object "never existed" in the OpenChange - databases */ + databases. Soft-deleted messages are returned back */ { fmids->lpui8[fmids->cValues] = fmid; fmids->cValues++; diff --git a/OpenChange/MAPIStoreMapping.h b/OpenChange/MAPIStoreMapping.h index 3210f1eb0..827cddf38 100644 --- a/OpenChange/MAPIStoreMapping.h +++ b/OpenChange/MAPIStoreMapping.h @@ -49,6 +49,8 @@ - (NSString *) urlFromID: (uint64_t) idKey; - (uint64_t) idFromURL: (NSString *) url; +- (uint64_t) idFromURL: (NSString *) url + isSoftDeleted: (bool *) softDeleted; - (BOOL) registerURL: (NSString *) urlString withID: (uint64_t) idNbr; - (void) registerURLs: (NSArray *) urlString diff --git a/OpenChange/MAPIStoreMapping.m b/OpenChange/MAPIStoreMapping.m index 1b2e4a0e7..6a910ea4c 100644 --- a/OpenChange/MAPIStoreMapping.m +++ b/OpenChange/MAPIStoreMapping.m @@ -160,6 +160,21 @@ MAPIStoreMappingKeyFromId (uint64_t idNbr) return NSNotFound; } +- (uint64_t) idFromURL: (NSString *) url + isSoftDeleted: (bool *) softDeleted +{ + enum mapistore_error ret; + uint64_t idNbr; + + ret = indexing->get_fmid(indexing, [username UTF8String], [url UTF8String], + false, &idNbr, softDeleted); + + if (ret != MAPISTORE_SUCCESS) + return NSNotFound; + + return idNbr; +} + - (void) _updateFolderWithURL: (NSString *) oldURL withURL: (NSString *) urlString { @@ -217,7 +232,7 @@ MAPIStoreMappingKeyFromId (uint64_t idNbr) { NSString *oldURL; uint64_t oldIdNbr; - bool rc; + bool rc, softDeleted; oldURL = [self urlFromID: idNbr]; if (oldURL != NULL) @@ -228,13 +243,16 @@ MAPIStoreMappingKeyFromId (uint64_t idNbr) return NO; } - oldIdNbr = [self idFromURL: urlString]; + oldIdNbr = [self idFromURL: urlString isSoftDeleted: &softDeleted]; if (oldIdNbr != NSNotFound) { - [self errorWithFormat: - @"attempt to double register an entry with idNbr ('%@', %lld," - @" 0x%.16"PRIx64", oldid=0x%.16"PRIx64")", - urlString, idNbr, idNbr, oldIdNbr]; + if (softDeleted) + [self logWithFormat: @"Attempt to register a soft-deleted %@", urlString]; + else + [self errorWithFormat: + @"attempt to double register an entry with idNbr ('%@', %lld," + @" 0x%.16"PRIx64", oldid=0x%.16"PRIx64")", + urlString, idNbr, idNbr, oldIdNbr]; return NO; } else