Implemented a mechanism to preload body parts for email messages

maint-2.0.2
Wolfgang Sourdeau 2012-10-06 13:02:39 -04:00
parent a7691c552b
commit a549773554
4 changed files with 117 additions and 1 deletions

View File

@ -37,6 +37,7 @@
@interface MAPIStoreMailFolder : MAPIStoreFolder
{
SOGoMAPIDBMessage *versionsMessage;
NSMutableDictionary *bodyData;
}
- (BOOL) ensureFolderExists;

View File

@ -25,6 +25,7 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
#import <Foundation/NSURL.h>
#import <NGObjWeb/WOContext+SoObjects.h>
@ -50,6 +51,7 @@
#import "MAPIStoreContext.h"
#import "MAPIStoreFAIMessage.h"
#import "MAPIStoreMailContext.h"
#import "MAPIStoreMailMessage.h"
#import "MAPIStoreMailMessageTable.h"
#import "MAPIStoreMapping.h"
#import "MAPIStoreTypes.h"
@ -86,6 +88,7 @@ static Class SOGoMailFolderK, MAPIStoreMailFolderK, MAPIStoreOutboxFolderK;
if ((self = [super init]))
{
versionsMessage = nil;
bodyData = [NSMutableDictionary new];
}
return self;
@ -94,6 +97,7 @@ static Class SOGoMailFolderK, MAPIStoreMailFolderK, MAPIStoreOutboxFolderK;
- (void) dealloc
{
[versionsMessage release];
[bodyData release];
[super dealloc];
}
@ -1161,6 +1165,24 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
inContainer: self];
}
- (id) lookupMessage: (NSString *) messageKey
{
MAPIStoreMailMessage *message;
NSData *rawBodyData;
NSNumber *messageUID;
message = [super lookupMessage: messageKey];
if (message)
{
messageUID = [self messageUIDFromMessageKey: messageKey];
rawBodyData = [bodyData objectForKey: messageUID];
if (rawBodyData)
[message setBodyContentFromRawData: rawBodyData];
}
return message;
}
- (NSArray *) rolesForExchangeRights: (uint32_t) rights
{
NSMutableArray *roles;
@ -1219,6 +1241,70 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
return rights;
}
- (enum mapistore_error) preloadMessageBodiesWithKeys: (NSArray *) keys
{
MAPIStoreMailMessage *message;
NSMutableSet *bodyPartKeys;
NSMutableDictionary *keyAssoc;
NSDictionary *response;
NSUInteger count, max;
NSString *messageKey, *bodyPartKey;
NSNumber *messageUID;
NGImap4Client *client;
NSArray *fetch;
NSData *bodyContent;
[bodyData removeAllObjects];
max = [keys count];
if (max > 0)
{
bodyPartKeys = [NSMutableSet setWithCapacity: max];
keyAssoc = [NSMutableDictionary dictionaryWithCapacity: max];
for (count = 0; count < max; count++)
{
messageKey = [keys objectAtIndex: count];
messageUID = [self messageUIDFromMessageKey: messageKey];
if (messageUID)
{
message = [self lookupMessage: messageKey];
if (message)
{
bodyPartKey = [message bodyContentPartKey];
[bodyPartKeys addObject: bodyPartKey];
[keyAssoc setObject: bodyPartKey forKey: messageUID];
}
}
}
client = [[(SOGoMailFolder *) sogoObject imap4Connection] client];
[client select: [sogoObject absoluteImap4Name]];
response = [client fetchUids: [keyAssoc allKeys]
parts: [bodyPartKeys allObjects]];
fetch = [response objectForKey: @"fetch"];
max = [fetch count];
for (count = 0; count < max; count++)
{
response = [fetch objectAtIndex: count];
messageUID = [response objectForKey: @"uid"];
if (messageUID)
{
bodyPartKey = [keyAssoc objectForKey: messageUID];
if (bodyPartKey)
{
bodyContent = [[response objectForKey: bodyPartKey]
objectForKey: @"data"];
if (bodyContent)
[bodyData setObject: bodyContent forKey: messageUID];
}
}
}
}
return MAPISTORE_SUCCESS;
}
@end
@implementation MAPIStoreOutboxFolder

View File

@ -70,6 +70,10 @@
- (int) getPidTagDisplayBcc: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
/* batch-mode helpers */
- (NSString *) bodyContentPartKey;
- (void) setBodyContentFromRawData: (NSData *) rawContent;
@end
#endif /* MAPISTOREMAILMESSAGE_H */

View File

@ -240,7 +240,7 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
if (!headerSetup)
[self _fetchHeaderData];
if (mimeKey)
if (!bodyContent && mimeKey)
{
result = [sogoObject fetchParts: [NSArray arrayWithObject: mimeKey]];
result = [[result valueForKey: @"RawResponse"] objectForKey: @"fetch"];
@ -1550,6 +1550,31 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
return MAPISTORE_SUCCESS;
}
- (NSString *) bodyContentPartKey
{
NSString *bodyPartKey;
if (!headerSetup)
[self _fetchHeaderData];
if ([mimeKey hasPrefix: @"body.peek"])
bodyPartKey = [NSString stringWithFormat: @"body[%@]",
[mimeKey _strippedBodyKey]];
else
bodyPartKey = mimeKey;
return bodyPartKey;
}
- (void) setBodyContentFromRawData: (NSData *) rawContent
{
if (!headerSetup)
[self _fetchHeaderData];
ASSIGN (bodyContent, [rawContent bodyDataFromEncoding: headerEncoding]);
bodySetup = YES;
}
- (void) save
{
NSNumber *value;