Monotone-Parent: 0a9a28e3c7ef305257a698ada6ebda67b4cfa9b7

Monotone-Revision: f5575460df29b5335d935f8e6d766b8aa5efda6a

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2011-09-22T15:54:47
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Wolfgang Sourdeau 2011-09-22 15:54:47 +00:00
parent 68bafd5f96
commit 2623aaa726
4 changed files with 151 additions and 98 deletions

View File

@ -6,6 +6,9 @@
Implemented generic version for specialized folders lacking an
implementation and for copying/moving items across folders of
different types.
(-postNotificationsForMoveCopyMessagesWithMIDs:andMessageURLs:andCount:fromFolder:withMIDs:wantCopy:):
new helper method that performs the whole notification magic for
message moves.
* OpenChange/MAPIStoreSOGo.m (sogo_folder_move_copy_messages):
adapted to last backend changes.

View File

@ -155,6 +155,14 @@
- (NSCalendarDate *) lastMessageModificationTime;
/* subclass helpers */
- (void) postNotificationsForMoveCopyMessagesWithMIDs: (uint64_t *) srcMids
andMessageURLs: (NSArray *) oldMessageURLs
andCount: (uint32_t) midCount
fromFolder: (MAPIStoreFolder *) sourceFolder
withMIDs: (uint64_t *) targetMids
wantCopy: (uint8_t) wantCopy;
@end
#endif /* MAPISTOREFOLDER_H */

View File

@ -636,20 +636,148 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
{
int rc = MAPISTORE_SUCCESS;
NSUInteger count;
NSMutableArray *oldMessageURLs;
MAPIStoreMapping *mapping;
if ([sourceFolder isKindOfClass: isa]
|| [self isKindOfClass: [sourceFolder class]])
[self logWithFormat: @"%s: this class could probably implement"
@" a specialized/optimized version", __FUNCTION__];
oldMessageURLs = [NSMutableArray arrayWithCapacity: midCount];
mapping = [[self context] mapping];
for (count = 0; rc == MAPISTORE_SUCCESS && count < midCount; count++)
rc = [self moveCopyMessagesWithMID: srcMids[count]
fromFolder: sourceFolder
withMID: targetMids[count]
wantCopy: wantCopy];
{
[oldMessageURLs addObject: [mapping urlFromID: srcMids[count]]];
rc = [self moveCopyMessagesWithMID: srcMids[count]
fromFolder: sourceFolder
withMID: targetMids[count]
wantCopy: wantCopy];
}
/* Notifications */
if (rc == MAPISTORE_SUCCESS)
{
[self postNotificationsForMoveCopyMessagesWithMIDs: srcMids
andMessageURLs: oldMessageURLs
andCount: midCount
fromFolder: sourceFolder
withMIDs: targetMids
wantCopy: wantCopy];
// We cleanup cache of our source and destination folders
[self cleanupCaches];
[sourceFolder cleanupCaches];
}
return rc;
}
- (void) postNotificationsForMoveCopyMessagesWithMIDs: (uint64_t *) srcMids
andMessageURLs: (NSArray *) oldMessageURLs
andCount: (uint32_t) midCount
fromFolder: (MAPIStoreFolder *) sourceFolder
withMIDs: (uint64_t *) targetMids
wantCopy: (uint8_t) wantCopy
{
NSArray *activeTables;
NSUInteger count, tableCount, max;
MAPIStoreMessage *message;
NSString *messageURL;
MAPIStoreMapping *mapping;
struct mapistore_object_notification_parameters *notif_parameters;
struct mapistore_connection_info *connInfo;
// For the "source folder, we ensure the table caches are loaded so
// that old and new state can be compared
activeTables = [sourceFolder activeMessageTables];
max = [activeTables count];
for (count = 0; count < max; count++)
[[activeTables objectAtIndex: count] restrictedChildKeys];
if (!wantCopy)
{
// We notify the client. We start with the source folder.
notif_parameters = talloc_zero(NULL, struct mapistore_object_notification_parameters);
notif_parameters->object_id = [sourceFolder objectId];
notif_parameters->tag_count = 5;
notif_parameters->tags = talloc_array (notif_parameters, enum MAPITAGS, 5);
notif_parameters->tags[0] = PR_CONTENT_COUNT;
notif_parameters->tags[1] = PR_DELETED_COUNT_TOTAL;
notif_parameters->tags[2] = PR_MESSAGE_SIZE;
notif_parameters->tags[3] = PR_NORMAL_MESSAGE_SIZE;
notif_parameters->tags[4] = PR_RECIPIENT_ON_NORMAL_MSG_COUNT;
notif_parameters->new_message_count = true;
notif_parameters->message_count = [[sourceFolder messageKeys] count] - midCount;
connInfo = [[self context] connectionInfo];
mapistore_push_notification (connInfo->mstore_ctx,
MAPISTORE_FOLDER,
MAPISTORE_OBJECT_MODIFIED,
notif_parameters);
talloc_free(notif_parameters);
}
// move/copy notification of the copied/moved message
for (count = 0; count < midCount; count++)
{
notif_parameters = talloc_zero (NULL, struct mapistore_object_notification_parameters);
notif_parameters->tag_count = 0;
notif_parameters->new_message_count = true;
notif_parameters->message_count = 0;
notif_parameters->object_id = targetMids[count];
notif_parameters->folder_id = [self objectId];
notif_parameters->old_object_id = srcMids[count];
notif_parameters->old_folder_id = [sourceFolder objectId];
mapistore_push_notification (connInfo->mstore_ctx,
MAPISTORE_MESSAGE,
(wantCopy ? MAPISTORE_OBJECT_COPIED : MAPISTORE_OBJECT_MOVED),
notif_parameters);
talloc_free (notif_parameters);
message = [sourceFolder lookupMessageByURL: [oldMessageURLs objectAtIndex: count]];
// table notification
for (tableCount = 0; tableCount < max; tableCount++)
[[activeTables objectAtIndex: tableCount]
notifyChangesForChild: message];
}
// For the "destination folder, we ensure the table caches are loaded so
// that old and new state can be compared
activeTables = [self activeMessageTables];
max = [activeTables count];
for (count = 0; count < max; count++)
[[activeTables objectAtIndex: count] restrictedChildKeys];
notif_parameters = talloc_zero(NULL, struct mapistore_object_notification_parameters);
notif_parameters->object_id = [self objectId];
notif_parameters->tag_count = 5;
notif_parameters->tags = talloc_array (notif_parameters, enum MAPITAGS, 5);
notif_parameters->tags[0] = PR_CONTENT_COUNT;
notif_parameters->tags[1] = PR_DELETED_COUNT_TOTAL;
notif_parameters->tags[2] = PR_MESSAGE_SIZE;
notif_parameters->tags[3] = PR_NORMAL_MESSAGE_SIZE;
notif_parameters->tags[4] = PR_RECIPIENT_ON_NORMAL_MSG_COUNT;
notif_parameters->new_message_count = true;
notif_parameters->message_count = [[self messageKeys] count] + midCount;
connInfo = [[self context] connectionInfo];
mapistore_push_notification (connInfo->mstore_ctx,
MAPISTORE_FOLDER,
MAPISTORE_OBJECT_MODIFIED,
notif_parameters);
talloc_free(notif_parameters);
// table notification
mapping = [[self context] mapping];
for (count = 0; count < midCount; count++)
{
messageURL = [mapping urlFromID: targetMids[count]];
message = [self lookupMessageByURL: messageURL];
for (tableCount = 0; tableCount < max; tableCount++)
[[activeTables objectAtIndex: tableCount]
notifyChangesForChild: message];
}
}
- (int) getDeletedFMIDs: (struct I8Array_r **) fmidsPtr
andCN: (uint64_t *) cnPtr
fromChangeNumber: (uint64_t) changeNum

View File

@ -872,12 +872,8 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
NSArray *destUIDs;
MAPIStoreMapping *mapping;
NSDictionary *result;
NSUInteger count, tableCount, max;
// uint64_t target_mid;
MAPIStoreMessage *message;
NSArray *a, *activeTables;
struct mapistore_object_notification_parameters *notif_parameters;
struct mapistore_connection_info *connInfo;
NSUInteger count;
NSArray *a;
// FIXME
// We only support IMAP-to-IMAP copy operations for now.
@ -956,94 +952,12 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
[mapping registerURL: messageURL withID: targetMids[count]];
}
// For the "source folder, we ensure the table caches are loaded so
// that old and new state can be compared
activeTables = [sourceFolder activeMessageTables];
max = [activeTables count];
for (count = 0; count < max; count++)
[[activeTables objectAtIndex: count] restrictedChildKeys];
if (!wantCopy)
{
// We notify the client. We start with the source folder.
notif_parameters = talloc_zero(NULL, struct mapistore_object_notification_parameters);
notif_parameters->object_id = [sourceFolder objectId];
notif_parameters->tag_count = 5;
notif_parameters->tags = talloc_array (notif_parameters, enum MAPITAGS, 5);
notif_parameters->tags[0] = PR_CONTENT_COUNT;
notif_parameters->tags[1] = PR_DELETED_COUNT_TOTAL;
notif_parameters->tags[2] = PR_MESSAGE_SIZE;
notif_parameters->tags[3] = PR_NORMAL_MESSAGE_SIZE;
notif_parameters->tags[4] = PR_RECIPIENT_ON_NORMAL_MSG_COUNT;
notif_parameters->new_message_count = true;
notif_parameters->message_count = [[sourceFolder messageKeys] count] - midCount;
connInfo = [[self context] connectionInfo];
mapistore_push_notification (connInfo->mstore_ctx,
MAPISTORE_FOLDER,
MAPISTORE_OBJECT_MODIFIED,
notif_parameters);
talloc_free(notif_parameters);
}
// move/copy notification of the copied/moved message
for (count = 0; count < midCount; count++)
{
notif_parameters = talloc_zero (NULL, struct mapistore_object_notification_parameters);
notif_parameters->tag_count = 0;
notif_parameters->new_message_count = true;
notif_parameters->message_count = 0;
notif_parameters->object_id = targetMids[count];
notif_parameters->folder_id = [self objectId];
notif_parameters->old_object_id = srcMids[count];
notif_parameters->old_folder_id = [sourceFolder objectId];
mapistore_push_notification (connInfo->mstore_ctx,
MAPISTORE_MESSAGE,
(wantCopy ? MAPISTORE_OBJECT_COPIED : MAPISTORE_OBJECT_MOVED),
notif_parameters);
talloc_free (notif_parameters);
message = [sourceFolder lookupMessageByURL: [oldMessageURLs objectAtIndex: count]];
// table notification
for (tableCount = 0; tableCount < max; tableCount++)
[[activeTables objectAtIndex: tableCount]
notifyChangesForChild: message];
}
// For the "destination folder, we ensure the table caches are loaded so
// that old and new state can be compared
activeTables = [self activeMessageTables];
max = [activeTables count];
for (count = 0; count < max; count++)
[[activeTables objectAtIndex: count] restrictedChildKeys];
notif_parameters = talloc_zero(NULL, struct mapistore_object_notification_parameters);
notif_parameters->object_id = [self objectId];
notif_parameters->tag_count = 5;
notif_parameters->tags = talloc_array (notif_parameters, enum MAPITAGS, 5);
notif_parameters->tags[0] = PR_CONTENT_COUNT;
notif_parameters->tags[1] = PR_DELETED_COUNT_TOTAL;
notif_parameters->tags[2] = PR_MESSAGE_SIZE;
notif_parameters->tags[3] = PR_NORMAL_MESSAGE_SIZE;
notif_parameters->tags[4] = PR_RECIPIENT_ON_NORMAL_MSG_COUNT;
notif_parameters->new_message_count = true;
notif_parameters->message_count = [[self messageKeys] count] + midCount;
connInfo = [[self context] connectionInfo];
mapistore_push_notification (connInfo->mstore_ctx,
MAPISTORE_FOLDER,
MAPISTORE_OBJECT_MODIFIED,
notif_parameters);
talloc_free(notif_parameters);
// table notification
for (count = 0; count < midCount; count++)
{
messageURL = [mapping urlFromID: targetMids[count]];
message = [self lookupMessageByURL: messageURL];
for (tableCount = 0; tableCount < max; tableCount++)
[[activeTables objectAtIndex: tableCount]
notifyChangesForChild: message];
}
[self postNotificationsForMoveCopyMessagesWithMIDs: srcMids
andMessageURLs: oldMessageURLs
andCount: midCount
fromFolder: sourceFolder
withMIDs: targetMids
wantCopy: wantCopy];
// We cleanup cache of our source and destination folders
[self cleanupCaches];