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 @interface MAPIStoreMailFolder : MAPIStoreFolder
{ {
SOGoMAPIDBMessage *versionsMessage; SOGoMAPIDBMessage *versionsMessage;
NSMutableDictionary *bodyData;
} }
- (BOOL) ensureFolderExists; - (BOOL) ensureFolderExists;

View File

@ -25,6 +25,7 @@
#import <Foundation/NSArray.h> #import <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h> #import <Foundation/NSCalendarDate.h>
#import <Foundation/NSDictionary.h> #import <Foundation/NSDictionary.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h> #import <Foundation/NSString.h>
#import <Foundation/NSURL.h> #import <Foundation/NSURL.h>
#import <NGObjWeb/WOContext+SoObjects.h> #import <NGObjWeb/WOContext+SoObjects.h>
@ -50,6 +51,7 @@
#import "MAPIStoreContext.h" #import "MAPIStoreContext.h"
#import "MAPIStoreFAIMessage.h" #import "MAPIStoreFAIMessage.h"
#import "MAPIStoreMailContext.h" #import "MAPIStoreMailContext.h"
#import "MAPIStoreMailMessage.h"
#import "MAPIStoreMailMessageTable.h" #import "MAPIStoreMailMessageTable.h"
#import "MAPIStoreMapping.h" #import "MAPIStoreMapping.h"
#import "MAPIStoreTypes.h" #import "MAPIStoreTypes.h"
@ -86,6 +88,7 @@ static Class SOGoMailFolderK, MAPIStoreMailFolderK, MAPIStoreOutboxFolderK;
if ((self = [super init])) if ((self = [super init]))
{ {
versionsMessage = nil; versionsMessage = nil;
bodyData = [NSMutableDictionary new];
} }
return self; return self;
@ -94,6 +97,7 @@ static Class SOGoMailFolderK, MAPIStoreMailFolderK, MAPIStoreOutboxFolderK;
- (void) dealloc - (void) dealloc
{ {
[versionsMessage release]; [versionsMessage release];
[bodyData release];
[super dealloc]; [super dealloc];
} }
@ -1161,6 +1165,24 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
inContainer: self]; 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 - (NSArray *) rolesForExchangeRights: (uint32_t) rights
{ {
NSMutableArray *roles; NSMutableArray *roles;
@ -1219,6 +1241,70 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
return rights; 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 @end
@implementation MAPIStoreOutboxFolder @implementation MAPIStoreOutboxFolder

View File

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

View File

@ -240,7 +240,7 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
if (!headerSetup) if (!headerSetup)
[self _fetchHeaderData]; [self _fetchHeaderData];
if (mimeKey) if (!bodyContent && mimeKey)
{ {
result = [sogoObject fetchParts: [NSArray arrayWithObject: mimeKey]]; result = [sogoObject fetchParts: [NSArray arrayWithObject: mimeKey]];
result = [[result valueForKey: @"RawResponse"] objectForKey: @"fetch"]; result = [[result valueForKey: @"RawResponse"] objectForKey: @"fetch"];
@ -1550,6 +1550,31 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
return MAPISTORE_SUCCESS; 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 - (void) save
{ {
NSNumber *value; NSNumber *value;