Implemented a mechanism to preload body parts for email messages
parent
a7691c552b
commit
a549773554
|
@ -37,6 +37,7 @@
|
||||||
@interface MAPIStoreMailFolder : MAPIStoreFolder
|
@interface MAPIStoreMailFolder : MAPIStoreFolder
|
||||||
{
|
{
|
||||||
SOGoMAPIDBMessage *versionsMessage;
|
SOGoMAPIDBMessage *versionsMessage;
|
||||||
|
NSMutableDictionary *bodyData;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) ensureFolderExists;
|
- (BOOL) ensureFolderExists;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue