propagate from branch 'ca.inverse.sogo.1_3_17' (head e853157abbabf35bc95273da8bc10b2d3b142627)

to branch 'ca.inverse.sogo' (head f4b12b256d58270841b46929996b4bdf21924369)

Monotone-Parent: e853157abbabf35bc95273da8bc10b2d3b142627
Monotone-Parent: f4b12b256d58270841b46929996b4bdf21924369
Monotone-Revision: 1c4b0de1b13fe836e324570323e90b9d779a8fa5

Monotone-Author: jraby@inverse.ca
Monotone-Date: 2012-07-05T21:16:08
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Jean Raby 2012-07-05 21:16:08 +00:00
commit 3520a8c847
85 changed files with 3011 additions and 1971 deletions

View file

@ -24,6 +24,25 @@
This still need some css tweaks. This still need some css tweaks.
2012-07-01 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* OpenChange/MAPIStoreRecurrenceUtils.m
(-setupRecurrenceWithMasterEntity:fromRecurrencePattern:): add
exception dates to master entity based on the
"DeletedInstanceDates" member of the struct.
(-fillRecurrencePattern:withEvent:inTimeZone:inMemCtx:): new name
for fillRecurrencePattern:withStartDate:andEndDate:, add exception
dates to struct.
* OpenChange/NSDate+MAPIStore.m (NSDateCompare): new comparison
function for sorting array of NSDate instances.
2012-06-30 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* OpenChange/NSObject+MAPIStore.h: renamed
MAPIStoreTallocWrapper.MAPIStoreSOGoObject to .instance, to avoid
confusion in certain versions of GCC with our new class type.
2012-06-29 Jean Raby <jraby@inverse.ca> 2012-06-29 Jean Raby <jraby@inverse.ca>
* SoObjects/SOGo/WORequest+SOGo.[mh] * SoObjects/SOGo/WORequest+SOGo.[mh]
@ -34,6 +53,23 @@
Let sogo append system sources if the request comes from an android Let sogo append system sources if the request comes from an android
client even if its user agent matches the IPhoneAddressBook client even if its user agent matches the IPhoneAddressBook
2012-06-29 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* OpenChange/MAPIStoreSOGo.m
(sogo_message_attachment_open_embedded_message): added the "mode"
parameter.
* OpenChange/SOGoMAPIDBObject.m: new class module that replaced
SOGoMAPIFSMessage.
* OpenChange/SOGoMAPIDBFolder.m: new class module that replaced
SOGoMAPIFSFolder.
2012-06-28 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* SoObjects/SOGo/SOGoObject.m (-initWithName:inContainer:): make
sure that "_name" is neither nil nor empty.
2012-06-27 Jean Raby <jraby@inverse.ca> 2012-06-27 Jean Raby <jraby@inverse.ca>
* SoObjects/Appointments/SOGoAppointmentObject.m * SoObjects/Appointments/SOGoAppointmentObject.m

View file

@ -201,6 +201,7 @@ static BOOL debugLeaks;
fileSuffix = [channelURL scheme]; fileSuffix = [channelURL scheme];
tc = [cm acquireOpenChannelForURL: channelURL]; tc = [cm acquireOpenChannelForURL: channelURL];
/* FIXME: make use of [EOChannelAdaptor describeTableNames] instead */
tableName = [url lastPathComponent]; tableName = [url lastPathComponent];
if ([tc evaluateExpressionX: if ([tc evaluateExpressionX:
[NSString stringWithFormat: @"SELECT count(*) FROM %@", [NSString stringWithFormat: @"SELECT count(*) FROM %@",

View file

@ -25,11 +25,11 @@
#import <EOControl/EOQualifier.h> #import <EOControl/EOQualifier.h>
@class SOGoMAPIVolatileMessage; @class SOGoMAPIDBObject;
@interface EOQualifier (MAPIStoreRestrictions) @interface EOQualifier (MAPIStoreRestrictions)
- (BOOL) evaluateMAPIVolatileMessage: (SOGoMAPIVolatileMessage *) message; - (BOOL) evaluateSOGoMAPIDBObject: (SOGoMAPIDBObject *) object;
@end @end

View file

@ -28,28 +28,28 @@
#import <NGExtensions/NSObject+Logs.h> #import <NGExtensions/NSObject+Logs.h>
#import "SOGoMAPIVolatileMessage.h" #import "EOBitmaskQualifier.h"
#import "SOGoMAPIDBObject.h"
#import "EOQualifier+MAPI.h" #import "EOQualifier+MAPI.h"
#import "EOBitmaskQualifier.h"
@implementation EOQualifier (MAPIStoreRestrictions) @implementation EOQualifier (MAPIStoreRestrictions)
- (BOOL) _evaluateMAPIVolatileMessageProperties: (NSDictionary *) properties - (BOOL) _evaluateSOGoMAPIDBObject: (NSDictionary *) properties
{ {
[self subclassResponsibility: _cmd]; [self subclassResponsibility: _cmd];
return NO; return NO;
} }
- (BOOL) evaluateMAPIVolatileMessage: (SOGoMAPIVolatileMessage *) message - (BOOL) evaluateSOGoMAPIDBObject: (SOGoMAPIDBObject *) object
{ {
NSDictionary *properties; NSDictionary *properties;
BOOL rc; BOOL rc;
[self logWithFormat: @"evaluating message '%@'", message]; [self logWithFormat: @"evaluating object '%@'", object];
properties = [message properties]; properties = [object properties];
rc = [self _evaluateMAPIVolatileMessageProperties: properties]; rc = [self _evaluateSOGoMAPIDBObject: properties];
[self logWithFormat: @" evaluation result: %d", rc]; [self logWithFormat: @" evaluation result: %d", rc];
@ -60,7 +60,7 @@
@implementation EOAndQualifier (MAPIStoreRestrictionsPrivate) @implementation EOAndQualifier (MAPIStoreRestrictionsPrivate)
- (BOOL) _evaluateMAPIVolatileMessageProperties: (NSDictionary *) properties - (BOOL) _evaluateSOGoMAPIDBObject: (NSDictionary *) properties
{ {
NSUInteger i; NSUInteger i;
BOOL rc; BOOL rc;
@ -69,7 +69,7 @@
for (i = 0; rc && i < count; i++) for (i = 0; rc && i < count; i++)
rc = [[qualifiers objectAtIndex: i] rc = [[qualifiers objectAtIndex: i]
_evaluateMAPIVolatileMessageProperties: properties]; _evaluateSOGoMAPIDBObject: properties];
return rc; return rc;
} }
@ -78,7 +78,7 @@
@implementation EOOrQualifier (MAPIStoreRestrictionsPrivate) @implementation EOOrQualifier (MAPIStoreRestrictionsPrivate)
- (BOOL) _evaluateMAPIVolatileMessageProperties: (NSDictionary *) properties - (BOOL) _evaluateSOGoMAPIDBObject: (NSDictionary *) properties
{ {
NSUInteger i; NSUInteger i;
BOOL rc; BOOL rc;
@ -87,7 +87,7 @@
for (i = 0; !rc && i < count; i++) for (i = 0; !rc && i < count; i++)
rc = [[qualifiers objectAtIndex: i] rc = [[qualifiers objectAtIndex: i]
_evaluateMAPIVolatileMessageProperties: properties]; _evaluateSOGoMAPIDBObject: properties];
return rc; return rc;
} }
@ -96,9 +96,9 @@
@implementation EONotQualifier (MAPIStoreRestrictionsPrivate) @implementation EONotQualifier (MAPIStoreRestrictionsPrivate)
- (BOOL) _evaluateMAPIVolatileMessageProperties: (NSDictionary *) properties - (BOOL) _evaluateSOGoMAPIDBObject: (NSDictionary *) properties
{ {
return ![qualifier _evaluateMAPIVolatileMessageProperties: properties]; return ![qualifier _evaluateSOGoMAPIDBObject: properties];
} }
@end @end
@ -107,7 +107,7 @@
typedef BOOL (*EOComparator) (id, SEL, id); typedef BOOL (*EOComparator) (id, SEL, id);
- (BOOL) _evaluateMAPIVolatileMessageProperties: (NSDictionary *) properties - (BOOL) _evaluateSOGoMAPIDBObject: (NSDictionary *) properties
{ {
id finalKey; id finalKey;
id propValue; id propValue;
@ -136,7 +136,7 @@ typedef BOOL (*EOComparator) (id, SEL, id);
@implementation EOBitmaskQualifier (MAPIStoreRestrictionsPrivate) @implementation EOBitmaskQualifier (MAPIStoreRestrictionsPrivate)
- (BOOL) _evaluateMAPIVolatileMessageProperties: (NSDictionary *) properties - (BOOL) _evaluateSOGoMAPIDBObject: (NSDictionary *) properties
{ {
NSNumber *propTag; NSNumber *propTag;
id propValue; id propValue;

View file

@ -0,0 +1,34 @@
/* GCSSpecialQueries+OpenChange.h - this file is part of SOGo
*
* Copyright (C) 2012 Inverse inc
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef GCSSPECIALQUERIES_OPENCHANGE_H
#define GCSSPECIALQUERIES_OPENCHANGE_H
#import <GDLContentStore/GCSSpecialQueries.h>
@interface GCSSpecialQueries (OpenChangeHelpers)
- (NSString *) createOpenChangeFSTableWithName: (NSString *) tableName;
@end
#endif /* GCSSPECIALQUERIES_OPENCHANGE_H */

View file

@ -0,0 +1,102 @@
/* GCSSpecialQueries+OpenChange.m - this file is part of SOGo
*
* Copyright (C) 2012 Inverse inc
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSString.h>
#import "GCSSpecialQueries+OpenChange.h"
@interface GCSPostgreSQLSpecialQueries (OpenChangeHelpers)
@end
@interface GCSMySQLSpecialQueries (OpenChangeHelpers)
@end
@interface GCSOracleSpecialQueries (OpenChangeHelpers)
@end
@implementation GCSSpecialQueries (OpenChangeHelpers)
- (NSString *) createOpenChangeFSTableWithName: (NSString *) tableName
{
[self subclassResponsibility: _cmd];
return nil;
}
@end
@implementation GCSPostgreSQLSpecialQueries (OpenChangeHelpers)
- (NSString *) createOpenChangeFSTableWithName: (NSString *) tableName
{
static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ ("
@" c_path VARCHAR(255) PRIMARY KEY,"
@" c_type SMALLINT NOT NULL,"
@" c_creationdate INT4 NOT NULL,"
@" c_lastmodified INT4 NOT NULL,"
@" c_version INT4 NOT NULL DEFAULT 0,"
@" c_deleted SMALLINT NOT NULL DEFAULT 0,"
@" c_content TEXT)");
return [NSString stringWithFormat: sqlFolderFormat, tableName];
}
@end
@implementation GCSMySQLSpecialQueries (OpenChangeHelpers)
- (NSString *) createOpenChangeFSTableWithName: (NSString *) tableName
{
static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ ("
@" c_path VARCHAR(255) PRIMARY KEY,"
@" c_type TINYINT NOT NULL,"
@" c_creationdate INT NOT NULL,"
@" c_lastmodified INT NOT NULL,"
@" c_version INT NOT NULL DEFAULT 0,"
@" c_deleted TINYINT NOT NULL DEFAULT 0,"
@" c_content TEXT)");
return [NSString stringWithFormat: sqlFolderFormat, tableName];
}
@end
@implementation GCSOracleSpecialQueries (OpenChangeHelpers)
- (NSString *) createOpenChangeFSTableWithName: (NSString *) tableName
{
static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ ("
@" c_path VARCHAR2(255) PRIMARY KEY,"
@" c_type SMALLINT NOT NULL,"
@" c_creationdate INT4 NOT NULL,"
@" c_lastmodified INT4 NOT NULL,"
@" c_version INT4 NOT NULL DEFAULT 0,"
@" c_deleted SMALLINT NOT NULL DEFAULT 0,"
@" c_content CLOB)");
return [NSString stringWithFormat: sqlFolderFormat, tableName];
}
@end

View file

@ -41,9 +41,11 @@ $(SOGOBACKEND)_OBJC_FILES += \
MAPIStoreSamDBUtils.m \ MAPIStoreSamDBUtils.m \
MAPIStoreUserContext.m \ MAPIStoreUserContext.m \
\ \
SOGoMAPIVolatileMessage.m \ SOGoMAPIObject.m \
SOGoMAPIFSFolder.m \ \
SOGoMAPIFSMessage.m \ SOGoMAPIDBObject.m \
SOGoMAPIDBMessage.m \
SOGoMAPIDBFolder.m \
\ \
MAPIStoreAppointmentWrapper.m \ MAPIStoreAppointmentWrapper.m \
MAPIStoreAttachment.m \ MAPIStoreAttachment.m \
@ -53,18 +55,17 @@ $(SOGOBACKEND)_OBJC_FILES += \
MAPIStoreFolder.m \ MAPIStoreFolder.m \
MAPIStoreMessage.m \ MAPIStoreMessage.m \
MAPIStoreObject.m \ MAPIStoreObject.m \
MAPIStoreSOGoObject.m \
MAPIStoreTable.m \ MAPIStoreTable.m \
MAPIStoreMessageTable.m \ MAPIStoreMessageTable.m \
MAPIStoreFolderTable.m \ MAPIStoreFolderTable.m \
MAPIStorePermissionsTable.m \ MAPIStorePermissionsTable.m \
\ \
MAPIStoreVolatileMessage.m \ MAPIStoreDBBaseContext.m \
\ MAPIStoreDBFolder.m \
MAPIStoreFSBaseContext.m \ MAPIStoreDBFolderTable.m \
MAPIStoreFSFolder.m \ MAPIStoreDBMessage.m \
MAPIStoreFSFolderTable.m \ MAPIStoreDBMessageTable.m \
MAPIStoreFSMessage.m \
MAPIStoreFSMessageTable.m \
\ \
MAPIStoreFAIMessage.m \ MAPIStoreFAIMessage.m \
MAPIStoreFAIMessageTable.m \ MAPIStoreFAIMessageTable.m \
@ -113,7 +114,10 @@ $(SOGOBACKEND)_OBJC_FILES += \
NSValue+MAPIStore.m \ NSValue+MAPIStore.m \
\ \
EOBitmaskQualifier.m \ EOBitmaskQualifier.m \
EOQualifier+MAPI.m \ \
GCSSpecialQueries+OpenChange.m\
\
EOQualifier+MAPI.m
$(SOGOBACKEND)_RESOURCE_FILES += \ $(SOGOBACKEND)_RESOURCE_FILES += \
@ -145,7 +149,13 @@ PLREADER_TOOL = plreader
$(PLREADER_TOOL)_OBJC_FILES += \ $(PLREADER_TOOL)_OBJC_FILES += \
plreader.m \ plreader.m \
TEST_TOOL_NAME += $(PLREADER_TOOL) DBMSGREADER_TOOL = dbmsgreader
$(DBMSGREADER_TOOL)_OBJC_FILES += \
dbmsgreader.m
$(DBMSGREADER_TOOL)_LIB_DIRS += -L../SoObjects/SOGo/ -lSOGo -lNGObjWeb
TEST_TOOL_NAME += $(PLREADER_TOOL) $(DBMSGREADER_TOOL)
### cflags and libs ### cflags and libs
LIBMAPI_CFLAGS = $(shell pkg-config libmapi --cflags) LIBMAPI_CFLAGS = $(shell pkg-config libmapi --cflags)

View file

@ -28,11 +28,8 @@
#import <Foundation/NSTimeZone.h> #import <Foundation/NSTimeZone.h>
#import <NGExtensions/NSObject+Logs.h> #import <NGExtensions/NSObject+Logs.h>
#import <NGCards/iCalAlarm.h> #import <NGCards/iCalAlarm.h>
#import <NGCards/iCalDateTime.h>
#import <NGCards/iCalEvent.h> #import <NGCards/iCalEvent.h>
#import <NGCards/iCalPerson.h> #import <NGCards/iCalPerson.h>
#import <NGCards/iCalRecurrenceRule.h>
#import <NGCards/iCalTimeZone.h>
#import <NGCards/iCalTrigger.h> #import <NGCards/iCalTrigger.h>
#import <NGCards/NSString+NGCards.h> #import <NGCards/NSString+NGCards.h>
#import <SOGo/SOGoUser.h> #import <SOGo/SOGoUser.h>
@ -580,7 +577,7 @@ static NSCharacterSet *hexCharacterSet = nil;
} }
- (int) getPidTagMessageClass: (void **) data - (int) getPidTagMessageClass: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
const char *className; const char *className;
@ -633,7 +630,7 @@ static NSCharacterSet *hexCharacterSet = nil;
} }
- (int) getPidTagStartDate: (void **) data - (int) getPidTagStartDate: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
NSCalendarDate *dateValue; NSCalendarDate *dateValue;
NSInteger offset; NSInteger offset;
@ -827,7 +824,7 @@ static NSCharacterSet *hexCharacterSet = nil;
/* sender (organizer) */ /* sender (organizer) */
- (int) getPidTagSenderEmailAddress: (void **) data - (int) getPidTagSenderEmailAddress: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
return [self _getEmailAddress: data return [self _getEmailAddress: data
forICalPerson: [event organizer] forICalPerson: [event organizer]
@ -835,7 +832,7 @@ static NSCharacterSet *hexCharacterSet = nil;
} }
- (int) getPidTagSenderAddressType: (void **) data - (int) getPidTagSenderAddressType: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
return [self _getAddrType: data return [self _getAddrType: data
forICalPerson: [event organizer] forICalPerson: [event organizer]
@ -843,7 +840,7 @@ static NSCharacterSet *hexCharacterSet = nil;
} }
- (int) getPidTagSenderName: (void **) data - (int) getPidTagSenderName: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
return [self _getName: data return [self _getName: data
forICalPerson: [event organizer] forICalPerson: [event organizer]
@ -851,7 +848,7 @@ static NSCharacterSet *hexCharacterSet = nil;
} }
- (int) getPidTagSenderEntryId: (void **) data - (int) getPidTagSenderEntryId: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
return [self _getEntryId: data return [self _getEntryId: data
forICalPerson: [event organizer] forICalPerson: [event organizer]
@ -860,7 +857,7 @@ static NSCharacterSet *hexCharacterSet = nil;
/* attendee */ /* attendee */
- (int) getPidTagReceivedByEmailAddress: (void **) data - (int) getPidTagReceivedByEmailAddress: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
return [self _getEmailAddress: data return [self _getEmailAddress: data
forICalPerson: [event userAsAttendee: user] forICalPerson: [event userAsAttendee: user]
@ -868,7 +865,7 @@ static NSCharacterSet *hexCharacterSet = nil;
} }
- (int) getPidTagReceivedByAddressType: (void **) data - (int) getPidTagReceivedByAddressType: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
return [self _getAddrType: data return [self _getAddrType: data
forICalPerson: [event userAsAttendee: user] forICalPerson: [event userAsAttendee: user]
@ -876,7 +873,7 @@ static NSCharacterSet *hexCharacterSet = nil;
} }
- (int) getPidTagReceivedByName: (void **) data - (int) getPidTagReceivedByName: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
return [self _getName: data return [self _getName: data
forICalPerson: [event userAsAttendee: user] forICalPerson: [event userAsAttendee: user]
@ -884,7 +881,7 @@ static NSCharacterSet *hexCharacterSet = nil;
} }
- (int) getPidTagReceivedByEntryId: (void **) data - (int) getPidTagReceivedByEntryId: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
return [self _getEntryId: data return [self _getEntryId: data
forICalPerson: [event userAsAttendee: user] forICalPerson: [event userAsAttendee: user]
@ -893,7 +890,7 @@ static NSCharacterSet *hexCharacterSet = nil;
/* /attendee */ /* /attendee */
- (int) getPidTagEndDate: (void **) data - (int) getPidTagEndDate: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
NSCalendarDate *dateValue; NSCalendarDate *dateValue;
NSInteger offset; NSInteger offset;
@ -995,7 +992,8 @@ static NSCharacterSet *hexCharacterSet = nil;
return [self getPidLidLocation: data inMemCtx: memCtx]; return [self getPidLidLocation: data inMemCtx: memCtx];
} }
- (int) getPidLidServerProcessed: (void **) data inMemCtx: (TALLOC_CTX *) memCtx - (int) getPidLidServerProcessed: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{ {
/* TODO: we need to check whether the event has been processed internally by /* TODO: we need to check whether the event has been processed internally by
SOGo or if it was received only by mail. We only assume the SOGo case SOGo or if it was received only by mail. We only assume the SOGo case
@ -1003,7 +1001,8 @@ static NSCharacterSet *hexCharacterSet = nil;
return [self getYes: data inMemCtx: memCtx]; return [self getYes: data inMemCtx: memCtx];
} }
- (int) getPidLidServerProcessingActions: (void **) data inMemCtx: (TALLOC_CTX *) memCtx - (int) getPidLidServerProcessingActions: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{ {
*data = MAPILongValue (memCtx, *data = MAPILongValue (memCtx,
0x00000010 /* cpsCreatedOnPrincipal */ 0x00000010 /* cpsCreatedOnPrincipal */
@ -1020,14 +1019,14 @@ static NSCharacterSet *hexCharacterSet = nil;
} }
- (int) getPidTagSensitivity: (void **) data // not implemented, depends on CLASS - (int) getPidTagSensitivity: (void **) data // not implemented, depends on CLASS
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
// normal = 0, personal?? = 1, private = 2, confidential = 3 // normal = 0, personal?? = 1, private = 2, confidential = 3
return [self getLongZero: data inMemCtx: memCtx]; return [self getLongZero: data inMemCtx: memCtx];
} }
- (int) getPidTagImportance: (void **) data - (int) getPidTagImportance: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
uint32_t v; uint32_t v;
if ([[event priority] isEqualToString: @"9"]) if ([[event priority] isEqualToString: @"9"])
@ -1043,7 +1042,7 @@ static NSCharacterSet *hexCharacterSet = nil;
} }
- (int) getPidTagBody: (void **) data - (int) getPidTagBody: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
int rc = MAPISTORE_SUCCESS; int rc = MAPISTORE_SUCCESS;
NSString *stringValue; NSString *stringValue;
@ -1074,29 +1073,6 @@ static NSCharacterSet *hexCharacterSet = nil;
return MAPISTORE_SUCCESS; return MAPISTORE_SUCCESS;
} }
static void
_fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
NSCalendarDate *startDate, NSTimeInterval duration,
NSCalendarDate * endDate, iCalRecurrenceRule *rule)
{
uint32_t startMinutes;
[rule fillRecurrencePattern: &arp->RecurrencePattern
withStartDate: startDate andEndDate: endDate];
arp->ReaderVersion2 = 0x00003006;
arp->WriterVersion2 = 0x00003009;
startMinutes = ([startDate hourOfDay] * 60 + [startDate minuteOfHour]);
arp->StartTimeOffset = startMinutes;
arp->EndTimeOffset = startMinutes + (uint32_t) (duration / 60);
arp->ExceptionCount = 0;
arp->ReservedBlock1Size = 0;
/* Currently ignored in property.idl:
arp->ReservedBlock2Size = 0; */
}
- (struct SBinary_short *) _computeAppointmentRecurInMemCtx: (TALLOC_CTX *) memCtx - (struct SBinary_short *) _computeAppointmentRecurInMemCtx: (TALLOC_CTX *) memCtx
{ {
@ -1105,6 +1081,7 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
struct SBinary_short *sBin; struct SBinary_short *sBin;
NSCalendarDate *firstStartDate; NSCalendarDate *firstStartDate;
iCalRecurrenceRule *rule; iCalRecurrenceRule *rule;
NSUInteger startMinutes;
rule = [[event recurrenceRules] objectAtIndex: 0]; rule = [[event recurrenceRules] objectAtIndex: 0];
@ -1114,10 +1091,27 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
[firstStartDate setTimeZone: timeZone]; [firstStartDate setTimeZone: timeZone];
arp = talloc_zero (memCtx, struct AppointmentRecurrencePattern); arp = talloc_zero (memCtx, struct AppointmentRecurrencePattern);
_fillAppointmentRecurrencePattern (arp, firstStartDate, [rule fillRecurrencePattern: &arp->RecurrencePattern
[event durationAsTimeInterval], withEvent: event
[event lastPossibleRecurrenceStartDate], inTimeZone: timeZone
rule); inMemCtx: arp];
arp->ReaderVersion2 = 0x00003006;
arp->WriterVersion2 = 0x00003009;
startMinutes = ([firstStartDate hourOfDay] * 60
+ [firstStartDate minuteOfHour]);
arp->StartTimeOffset = startMinutes;
arp->EndTimeOffset = (startMinutes
+ (NSUInteger) ([event durationAsTimeInterval]
/ 60));
arp->ExceptionCount = 0;
arp->ReservedBlock1Size = 0;
/* Currently ignored in property.idl: arp->ReservedBlock2Size = 0; */
/* convert struct to blob */
sBin = talloc_zero (memCtx, struct SBinary_short); sBin = talloc_zero (memCtx, struct SBinary_short);
bin = set_AppointmentRecurrencePattern (sBin, arp); bin = set_AppointmentRecurrencePattern (sBin, arp);
sBin->cb = bin->cb; sBin->cb = bin->cb;

View file

@ -37,6 +37,7 @@
- (uint32_t) AID; - (uint32_t) AID;
- (int) openEmbeddedMessage: (MAPIStoreEmbeddedMessage **) messagePtr - (int) openEmbeddedMessage: (MAPIStoreEmbeddedMessage **) messagePtr
inMode: (enum OpenEmbeddedMessage_OpenModeFlags) mode
withMID: (uint64_t *) mid withMID: (uint64_t *) mid
withMAPIStoreMsg: (struct mapistore_message **) mapistoreMsgPtr withMAPIStoreMsg: (struct mapistore_message **) mapistoreMsgPtr
inMemCtx: (TALLOC_CTX *) memCtx; inMemCtx: (TALLOC_CTX *) memCtx;

View file

@ -91,6 +91,7 @@
} }
- (int) openEmbeddedMessage: (MAPIStoreEmbeddedMessage **) messagePtr - (int) openEmbeddedMessage: (MAPIStoreEmbeddedMessage **) messagePtr
inMode: (enum OpenEmbeddedMessage_OpenModeFlags) mode
withMID: (uint64_t *) mid withMID: (uint64_t *) mid
withMAPIStoreMsg: (struct mapistore_message **) mapistoreMsgPtr withMAPIStoreMsg: (struct mapistore_message **) mapistoreMsgPtr
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
@ -103,19 +104,23 @@
mapping = [self mapping]; mapping = [self mapping];
attMessage = [self openEmbeddedMessage]; if (mode == MAPI_CREATE)
if (attMessage) attMessage = [self createEmbeddedMessage];
else
{ {
*mid = [mapping idFromURL: [attMessage url]]; // if (attMessage)
*messagePtr = attMessage; // [mapping registerURL: [attMessage url]
*mapistoreMsgPtr = mapistoreMsg; // withID: *mid];
attMessage = [self openEmbeddedMessage];
if (attMessage)
{
*mid = [mapping idFromURL: [attMessage url]];
*messagePtr = attMessage;
*mapistoreMsgPtr = mapistoreMsg;
}
} }
// else if (flags == MAPI_CREATE) // else if (flags == MAPI_CREATE)
// { // {
// attMessage = [self createEmbeddedMessage];
// if (attMessage)
// [mapping registerURL: [attMessage url]
// withID: *mid];
// } // }
return (attMessage ? MAPISTORE_SUCCESS : MAPISTORE_ERROR); return (attMessage ? MAPISTORE_SUCCESS : MAPISTORE_ERROR);

View file

@ -67,10 +67,10 @@
{ {
MAPIStoreEmbeddedMessage *msg; MAPIStoreEmbeddedMessage *msg;
if (isNew) // if (isNew)
msg = nil;
else
msg = nil; msg = nil;
// else
// msg = nil;
return msg; return msg;
} }

View file

@ -1111,9 +1111,7 @@
newAid = [[self attachmentKeys] count]; newAid = [[self attachmentKeys] count];
newAttachment = [MAPIStoreCalendarAttachment newAttachment = [MAPIStoreCalendarAttachment
mapiStoreObjectWithSOGoObject: nil mapiStoreObjectInContainer: self];
inContainer: self];
[newAttachment setIsNew: YES];
[newAttachment setAID: newAid]; [newAttachment setAID: newAid];
newKey = [NSString stringWithFormat: @"%ul", newAid]; newKey = [NSString stringWithFormat: @"%ul", newAid];
[attachmentParts setObject: newAttachment [attachmentParts setObject: newAttachment

View file

@ -35,6 +35,7 @@
#import <Mailer/NSString+Mail.h> #import <Mailer/NSString+Mail.h>
#import <SOGo/SOGoPermissions.h> #import <SOGo/SOGoPermissions.h>
#import "MAPIStoreAttachment.h"
#import "MAPIStoreContactsAttachment.h" #import "MAPIStoreContactsAttachment.h"
#import "MAPIStoreContactsFolder.h" #import "MAPIStoreContactsFolder.h"
#import "MAPIStorePropertySelectors.h" #import "MAPIStorePropertySelectors.h"
@ -767,8 +768,7 @@
|| [encoding isEqualToString: @"BASE64"]) || [encoding isEqualToString: @"BASE64"])
{ {
attachment = [MAPIStoreContactsAttachment attachment = [MAPIStoreContactsAttachment
mapiStoreObjectWithSOGoObject: nil mapiStoreObjectInContainer: self];
inContainer: self];
[attachment setAID: 0]; [attachment setAID: 0];
[attachment setPhoto: photo]; [attachment setPhoto: photo];
[attachmentParts setObject: attachment forKey: @"photo"]; [attachmentParts setObject: attachment forKey: @"photo"];

View file

@ -28,11 +28,9 @@
#import <NGObjWeb/WOContext+SoObjects.h> #import <NGObjWeb/WOContext+SoObjects.h>
#import <NGExtensions/NSObject+Logs.h> #import <NGExtensions/NSObject+Logs.h>
#import <SOGo/SOGoFolder.h>
#import <SOGo/SOGoUser.h> #import <SOGo/SOGoUser.h>
#import "SOGoMAPIFSFolder.h"
#import "SOGoMAPIFSMessage.h"
#import "MAPIStoreAttachment.h" #import "MAPIStoreAttachment.h"
// #import "MAPIStoreAttachmentTable.h" // #import "MAPIStoreAttachmentTable.h"
#import "MAPIStoreFallbackContext.h" #import "MAPIStoreFallbackContext.h"
@ -294,9 +292,11 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri)
[MAPIStoreUserContext userContextWithUsername: username [MAPIStoreUserContext userContextWithUsername: username
andTDBIndexing: indexingTdb]); andTDBIndexing: indexingTdb]);
#if 0
mapistore_mgmt_backend_register_user (newConnInfo, mapistore_mgmt_backend_register_user (newConnInfo,
"SOGo", "SOGo",
[username UTF8String]); [username UTF8String]);
#endif
connInfo = newConnInfo; connInfo = newConnInfo;
username = [NSString stringWithUTF8String: newConnInfo->username]; username = [NSString stringWithUTF8String: newConnInfo->username];
@ -315,9 +315,12 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri)
- (void) dealloc - (void) dealloc
{ {
#if 0
mapistore_mgmt_backend_unregister_user ([self connectionInfo], "SOGo", mapistore_mgmt_backend_unregister_user ([self connectionInfo], "SOGo",
[[userContext username] [[userContext username]
UTF8String]); UTF8String]);
#endif
[contextUrl release]; [contextUrl release];
[userContext release]; [userContext release];
[containersBag release]; [containersBag release];
@ -428,25 +431,29 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri)
[self ensureContextFolder]; [self ensureContextFolder];
currentFolder = [self rootSOGoFolder]; currentFolder = [self rootSOGoFolder];
[containersBag addObject: currentFolder];
path = [contextUrl path]; path = [contextUrl path];
if ([path hasPrefix: @"/"]) if ([path hasPrefix: @"/"])
path = [path substringFromIndex: 1]; path = [path substringFromIndex: 1];
if ([path hasSuffix: @"/"]) if ([path hasSuffix: @"/"])
path = [path substringToIndex: [path length] - 1]; path = [path substringToIndex: [path length] - 1];
pathComponents = [path componentsSeparatedByString: @"/"]; if ([path length] > 0)
max = [pathComponents count];
for (count = 0; currentFolder && count < max; count++)
{ {
[woContext setClientObject: currentFolder]; pathComponents = [path componentsSeparatedByString: @"/"];
currentFolder max = [pathComponents count];
= [currentFolder lookupName: [pathComponents objectAtIndex: count] for (count = 0; currentFolder && count < max; count++)
inContext: woContext {
[woContext setClientObject: currentFolder];
currentFolder = [currentFolder
lookupName: [pathComponents objectAtIndex: count]
inContext: woContext
acquire: NO]; acquire: NO];
if ([currentFolder isKindOfClass: SOGoObjectK]) /* class common to all if ([currentFolder isKindOfClass: SOGoObjectK]) /* class common to all
SOGo folder types */ SOGo folder types */
[containersBag addObject: currentFolder]; [containersBag addObject: currentFolder];
else else
currentFolder = nil; currentFolder = nil;
}
} }
if (currentFolder) if (currentFolder)
@ -455,7 +462,6 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri)
mapiStoreObjectWithSOGoObject: currentFolder mapiStoreObjectWithSOGoObject: currentFolder
inContainer: nil]; inContainer: nil];
[baseFolder setContext: self]; [baseFolder setContext: self];
*folderPtr = baseFolder; *folderPtr = baseFolder;
rc = MAPISTORE_SUCCESS; rc = MAPISTORE_SUCCESS;
} }

View file

@ -1,6 +1,6 @@
/* MAPIStoreFSBaseContext.h - this file is part of SOGo /* MAPIStoreDBBaseContext.h - this file is part of SOGo
* *
* Copyright (C) 2010 Inverse inc. * Copyright (C) 2012 Inverse inc.
* *
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca> * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
@ -20,13 +20,13 @@
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*/ */
#ifndef MAPISTOREFSBASECONTEXT_H #ifndef MAPISTOREDBBASECONTEXT_H
#define MAPISTOREFSBASECONTEXT_H #define MAPISTOREDBBASECONTEXT_H
#import "MAPIStoreContext.h" #import "MAPIStoreContext.h"
@interface MAPIStoreFSBaseContext : MAPIStoreContext @interface MAPIStoreDBBaseContext : MAPIStoreContext
@end @end
#endif /* MAPISTOREFSBASECONTEXT_H */ #endif /* MAPISTOREDBBASECONTEXT_H */

View file

@ -0,0 +1,116 @@
/* MAPIStoreDBBaseContext.m - this file is part of SOGo
*
* Copyright (C) 2012 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/* A generic parent class for all context that will store their data on the
disk in the form of a plist. */
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
#import <Foundation/NSURL.h>
#import <NGExtensions/NSObject+Logs.h>
#import "MAPIStoreDBFolder.h"
#import "MAPIStoreMapping.h"
#import "MAPIStoreUserContext.h"
#import "SOGoMAPIDBFolder.h"
#import "MAPIStoreDBBaseContext.h"
#undef DEBUG
#include <mapistore/mapistore.h>
static Class MAPIStoreDBFolderK;
@implementation MAPIStoreDBBaseContext
+ (void) initialize
{
MAPIStoreDBFolderK = [MAPIStoreDBFolder class];
}
+ (NSString *) MAPIModuleName
{
return nil;
}
- (Class) MAPIStoreFolderClass
{
return MAPIStoreDBFolderK;
}
- (void) ensureContextFolder
{
SOGoMAPIDBFolder *currentFolder;
NSArray *parts;
NSMutableArray *folders;
NSString *folderName;
NSUInteger count, max;
parts = [[contextUrl path] componentsSeparatedByString: @"/"];
max = [parts count];
folders = [NSMutableArray arrayWithCapacity: max];
/* build the folder chain */
currentFolder = [self rootSOGoFolder];
[folders addObject: currentFolder];
for (count = 1; count < max; count++)
{
folderName = [parts objectAtIndex: count];
if ([folderName length] > 0)
{
currentFolder = [SOGoMAPIDBFolder objectWithName: folderName
inContainer: currentFolder];
[folders addObject: currentFolder];
}
}
/* ensure each folder in the chain actually exists, so that it becomes
"listable" in further operations */
max = [folders count];
for (count = 0; count < max; count++)
{
currentFolder = [folders objectAtIndex: count];
[currentFolder reloadIfNeeded];
if ([currentFolder isNew])
[currentFolder save];
}
}
- (id) rootSOGoFolder
{
SOGoMAPIDBFolder *folder;
[userContext ensureFolderTableExists];
folder = [SOGoMAPIDBFolder objectWithName: [isa MAPIModuleName]
inContainer: nil];
[folder setTableUrl: [userContext folderTableURL]];
// [folder reloadIfNeeded];
/* we don't need to set the "path prefix" of the folder since the module
name is used as the label for the top folder */
return folder;
}
@end

View file

@ -1,6 +1,6 @@
/* MAPIStoreFSFolder.h - this file is part of SOGo /* MAPIStoreDBFolder.h - this file is part of SOGo
* *
* Copyright (C) 2011 Inverse inc * Copyright (C) 2012 Inverse inc
* *
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca> * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
@ -20,14 +20,14 @@
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*/ */
#ifndef MAPISTOREFSFOLDER_H #ifndef MAPISTOREDBFOLDER_H
#define MAPISTOREFSFOLDER_H #define MAPISTOREDBFOLDER_H
#import "MAPIStoreFolder.h" #import "MAPIStoreFolder.h"
@interface MAPIStoreFSFolder : MAPIStoreFolder @interface MAPIStoreDBFolder : MAPIStoreFolder
@end @end
#endif /* MAPISTOREFSFOLDER_H */ #endif /* MAPISTOREDBFOLDER_H */

View file

@ -1,4 +1,4 @@
/* MAPIStoreFSFolder.m - this file is part of SOGo /* MAPIStoreDBFolder.m - this file is part of SOGo
* *
* Copyright (C) 2011 Inverse inc * Copyright (C) 2011 Inverse inc
* *
@ -31,15 +31,15 @@
#import <SOGo/SOGoUser.h> #import <SOGo/SOGoUser.h>
#import "EOQualifier+MAPI.h" #import "EOQualifier+MAPI.h"
#import "MAPIStoreContext.h" #import "MAPIStoreContext.h"
#import "MAPIStoreFSFolderTable.h" #import "MAPIStoreDBFolderTable.h"
#import "MAPIStoreFSMessage.h" #import "MAPIStoreDBMessage.h"
#import "MAPIStoreFSMessageTable.h" #import "MAPIStoreDBMessageTable.h"
#import "MAPIStoreTypes.h" #import "MAPIStoreTypes.h"
#import "MAPIStoreUserContext.h" #import "MAPIStoreUserContext.h"
#import "SOGoMAPIFSFolder.h" #import "SOGoMAPIDBFolder.h"
#import "SOGoMAPIFSMessage.h" #import "SOGoMAPIDBMessage.h"
#import "MAPIStoreFSFolder.h" #import "MAPIStoreDBFolder.h"
#undef DEBUG #undef DEBUG
#include <mapistore/mapistore.h> #include <mapistore/mapistore.h>
@ -57,39 +57,34 @@ static NSString *MAPIStoreRightCreateSubfolders = @"RightsCreateSubfolders";
static NSString *MAPIStoreRightFolderOwner = @"RightsFolderOwner"; static NSString *MAPIStoreRightFolderOwner = @"RightsFolderOwner";
static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact"; static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact";
@implementation MAPIStoreFSFolder @implementation MAPIStoreDBFolder
+ (void) initialize + (void) initialize
{ {
EOKeyValueQualifierK = [EOKeyValueQualifier class]; EOKeyValueQualifierK = [EOKeyValueQualifier class];
} }
- (void) setupAuxiliaryObjects
{
[super setupAuxiliaryObjects];
ASSIGN (sogoObject, dbFolder);
}
- (MAPIStoreMessageTable *) messageTable - (MAPIStoreMessageTable *) messageTable
{ {
return [MAPIStoreFSMessageTable tableForContainer: self]; return [MAPIStoreDBMessageTable tableForContainer: self];
} }
- (MAPIStoreFolderTable *) folderTable - (MAPIStoreFolderTable *) folderTable
{ {
return [MAPIStoreFSFolderTable tableForContainer: self]; return [MAPIStoreDBFolderTable tableForContainer: self];
} }
- (enum mapistore_error) createFolder: (struct SRow *) aRow - (enum mapistore_error) createFolder: (struct SRow *) aRow
withFID: (uint64_t) newFID withFID: (uint64_t) newFID
andKey: (NSString **) newKeyP andKey: (NSString **) newKeyP
{ {
NSString *newKey, *urlString; *newKeyP = [NSString stringWithFormat: @"0x%.16"PRIx64, (unsigned long long) newFID];
NSURL *childURL;
SOGoMAPIFSFolder *childFolder;
newKey = [NSString stringWithFormat: @"0x%.16"PRIx64, (unsigned long long) newFID];
urlString = [NSString stringWithFormat: @"%@/%@", [self url], newKey];
childURL = [NSURL URLWithString: [urlString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
childFolder = [SOGoMAPIFSFolder folderWithURL: childURL
andTableType: MAPISTORE_MESSAGE_TABLE];
[childFolder ensureDirectory];
*newKeyP = newKey;
return MAPISTORE_SUCCESS; return MAPISTORE_SUCCESS;
} }
@ -97,14 +92,15 @@ static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact";
- (MAPIStoreMessage *) createMessage - (MAPIStoreMessage *) createMessage
{ {
MAPIStoreMessage *newMessage; MAPIStoreMessage *newMessage;
SOGoMAPIFSMessage *fsObject; SOGoMAPIDBMessage *fsObject;
NSString *newKey; NSString *newKey;
newKey = [NSString stringWithFormat: @"%@.plist", newKey = [NSString stringWithFormat: @"%@.plist",
[SOGoObject globallyUniqueObjectId]]; [SOGoObject globallyUniqueObjectId]];
fsObject = [SOGoMAPIFSMessage objectWithName: newKey fsObject = [SOGoMAPIDBMessage objectWithName: newKey
inContainer: sogoObject]; inContainer: sogoObject];
newMessage = [MAPIStoreFSMessage mapiStoreObjectWithSOGoObject: fsObject [fsObject setObjectType: MAPIDBObjectTypeMessage];
newMessage = [MAPIStoreDBMessage mapiStoreObjectWithSOGoObject: fsObject
inContainer: self]; inContainer: self];
return newMessage; return newMessage;
@ -119,9 +115,10 @@ static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact";
ownerUser = [[self userContext] sogoUser]; ownerUser = [[self userContext] sogoUser];
if ([[context activeUser] isEqual: ownerUser] if ([[context activeUser] isEqual: ownerUser]
|| [self subscriberCanReadMessages]) || [self subscriberCanReadMessages])
keys = [(SOGoMAPIFSFolder *) sogoObject keys = [(SOGoMAPIDBFolder *) sogoObject childKeysOfType: MAPIDBObjectTypeMessage
toOneRelationshipKeysMatchingQualifier: qualifier includeDeleted: NO
andSortOrderings: sortOrderings]; matchingQualifier: qualifier
andSortOrderings: sortOrderings];
else else
keys = [NSArray array]; keys = [NSArray array];
@ -131,39 +128,17 @@ static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact";
- (NSArray *) folderKeysMatchingQualifier: (EOQualifier *) qualifier - (NSArray *) folderKeysMatchingQualifier: (EOQualifier *) qualifier
andSortOrderings: (NSArray *) sortOrderings andSortOrderings: (NSArray *) sortOrderings
{ {
NSArray *entries; return [dbFolder childKeysOfType: MAPIDBObjectTypeFolder
NSMutableArray *filteredEntries; includeDeleted: NO
NSUInteger count, max; matchingQualifier: qualifier
MAPIStoreFSFolder *subfolder; andSortOrderings: sortOrderings];
SOGoMAPIFSMessage *propertiesMessage;
NSString *subfolderKey;
entries = [(SOGoMAPIFSFolder *) sogoObject toManyRelationshipKeys];
if (qualifier)
{
max = [entries count];
filteredEntries = [NSMutableArray arrayWithCapacity: max];
for (count = 0; count < max; count++)
{
subfolderKey = [entries objectAtIndex: count];
subfolder = [self lookupFolder: subfolderKey];
propertiesMessage = [subfolder propertiesMessage];
if ([qualifier evaluateMAPIVolatileMessage: propertiesMessage])
[filteredEntries addObject: subfolderKey];
}
entries = filteredEntries;
}
if (sortOrderings)
[self errorWithFormat: @"sort orderings are not used for folders"];
return entries;
} }
- (NSDate *) lastMessageModificationTime - (NSDate *) lastMessageModificationTime
{ {
NSUInteger count, max; NSUInteger count, max;
NSDate *date, *fileDate; NSDate *date, *fileDate;
MAPIStoreFSMessage *msg; MAPIStoreDBMessage *msg;
NSArray *messageKeys; NSArray *messageKeys;
messageKeys = [self messageKeys]; messageKeys = [self messageKeys];
@ -189,7 +164,7 @@ static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact";
- (SOGoFolder *) aclFolder - (SOGoFolder *) aclFolder
{ {
return propsFolder; return sogoObject;
} }
- (NSArray *) rolesForExchangeRights: (uint32_t) rights - (NSArray *) rolesForExchangeRights: (uint32_t) rights

View file

@ -1,6 +1,6 @@
/* MAPIStoreFSFolderTable.h - this file is part of SOGo /* MAPIStoreDBFolderTable.h - this file is part of SOGo
* *
* Copyright (C) 2011 Inverse inc * Copyright (C) 2012 Inverse inc
* *
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca> * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
@ -20,12 +20,12 @@
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*/ */
#ifndef MAPISTOREFSFOLDERTABLE_H #ifndef MAPISTOREDBFOLDERTABLE_H
#define MAPISTOREFSFOLDERTABLE_H #define MAPISTOREDBFOLDERTABLE_H
#import "MAPIStoreFolderTable.h" #import "MAPIStoreFolderTable.h"
@interface MAPIStoreFSFolderTable : MAPIStoreFolderTable @interface MAPIStoreDBFolderTable : MAPIStoreFolderTable
@end @end
#endif /* MAPISTOREFSFOLDERTABLE_H */ #endif /* MAPISTOREDBFOLDERTABLE_H */

View file

@ -1,6 +1,6 @@
/* MAPIStoreFSFolderTable.m - this file is part of SOGo /* MAPIStoreDBFolderTable.m - this file is part of SOGo
* *
* Copyright (C) 2011 Inverse inc * Copyright (C) 2012 Inverse inc
* *
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca> * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
@ -24,9 +24,9 @@
#import "MAPIStoreTypes.h" #import "MAPIStoreTypes.h"
#import "MAPIStoreFSFolderTable.h" #import "MAPIStoreDBFolderTable.h"
@implementation MAPIStoreFSFolderTable @implementation MAPIStoreDBFolderTable
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property - (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property
{ {

View file

@ -1,6 +1,6 @@
/* MAPIStoreFSMessage.h - this file is part of SOGo /* MAPIStoreDBMessage.h - this file is part of SOGo
* *
* Copyright (C) 2011 Inverse inc * Copyright (C) 2012 Inverse inc
* *
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca> * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
@ -20,12 +20,12 @@
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*/ */
#ifndef MAPISTOREFSMESSAGE_H #ifndef MAPISTOREDBMESSAGE_H
#define MAPISTOREFSMESSAGE_H #define MAPISTOREDBMESSAGE_H
#import "MAPIStoreVolatileMessage.h" #import "MAPIStoreMessage.h"
@interface MAPIStoreFSMessage : MAPIStoreVolatileMessage @interface MAPIStoreDBMessage : MAPIStoreMessage
@end @end
#endif /* MAPISTOREFSMESSAGE_H */ #endif /* MAPISTOREDBMESSAGE_H */

View file

@ -1,4 +1,4 @@
/* MAPIStoreFSMessage.m - this file is part of SOGo /* MAPIStoreDBMessage.m - this file is part of SOGo
* *
* Copyright (C) 2011 Inverse inc * Copyright (C) 2011 Inverse inc
* *
@ -21,24 +21,25 @@
*/ */
#import <Foundation/NSArray.h> #import <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSDictionary.h> #import <Foundation/NSDictionary.h>
#import <Foundation/NSValue.h> #import <Foundation/NSValue.h>
#import <NGExtensions/NSObject+Logs.h> #import <NGExtensions/NSObject+Logs.h>
#import "MAPIStoreContext.h" #import "MAPIStoreContext.h"
#import "MAPIStorePropertySelectors.h" #import "MAPIStorePropertySelectors.h"
#import "SOGoMAPIFSMessage.h" #import "SOGoMAPIDBMessage.h"
#import "MAPIStoreFSFolder.h" #import "MAPIStoreDBFolder.h"
#import "MAPIStoreFSMessage.h" #import "MAPIStoreDBMessage.h"
#import "MAPIStoreTypes.h" #import "MAPIStoreTypes.h"
#import "NSData+MAPIStore.h" #import "NSObject+MAPIStore.h"
#undef DEBUG #undef DEBUG
#include <mapistore/mapistore.h> #include <mapistore/mapistore.h>
#include <mapistore/mapistore_errors.h> #include <mapistore/mapistore_errors.h>
@implementation MAPIStoreFSMessage @implementation MAPIStoreDBMessage
+ (int) getAvailableProperties: (struct SPropTagArray **) propertiesP + (int) getAvailableProperties: (struct SPropTagArray **) propertiesP
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
@ -60,13 +61,96 @@
/* FIXME (hack): append a few undocumented properties that can be added to /* FIXME (hack): append a few undocumented properties that can be added to
FAI messages */ FAI messages */
for (count = 0; count < 8; count++) for (count = 0; count < 8; count++)
properties->aulPropTag[MAPIStoreSupportedPropertiesCount+count] = faiProperties[count]; properties->aulPropTag[MAPIStoreSupportedPropertiesCount+count]
= faiProperties[count];
*propertiesP = properties; *propertiesP = properties;
return MAPISTORE_SUCCESS; return MAPISTORE_SUCCESS;
} }
- (id) initWithSOGoObject: (id) newSOGoObject
inContainer: (MAPIStoreObject *) newContainer
{
if ((self = [super initWithSOGoObject: newSOGoObject
inContainer: newContainer]))
{
[properties release];
properties = [newSOGoObject properties];
[properties retain];
}
return self;
}
- (uint64_t) objectVersion
{
NSNumber *versionNbr;
uint64_t objectVersion;
[(SOGoMAPIDBMessage *) sogoObject reloadIfNeeded];
versionNbr = [properties objectForKey: @"version"];
if (versionNbr)
objectVersion = [versionNbr unsignedLongLongValue];
else
objectVersion = ULLONG_MAX;
return objectVersion;
}
- (int) getProperties: (struct mapistore_property_data *) data
withTags: (enum MAPITAGS *) tags
andCount: (uint16_t) columnCount
inMemCtx: (TALLOC_CTX *) memCtx
{
[sogoObject reloadIfNeeded];
return [super getProperties: data
withTags: tags
andCount: columnCount
inMemCtx: memCtx];
}
- (int) getProperty: (void **) data
withTag: (enum MAPITAGS) propTag
inMemCtx: (TALLOC_CTX *) memCtx
{
id value;
int rc;
value = [properties objectForKey: MAPIPropertyKey (propTag)];
if (value)
rc = [value getValue: data forTag: propTag inMemCtx: memCtx];
else
rc = [super getProperty: data withTag: propTag inMemCtx: memCtx];
return rc;
}
- (int) getPidTagSubject: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
id value;
int rc;
value = [properties
objectForKey: MAPIPropertyKey (PidTagNormalizedSubject)];
if (value)
rc = [value getValue: data forTag: PidTagNormalizedSubject
inMemCtx: memCtx];
else
rc = MAPISTORE_ERR_NOT_FOUND;
return rc;
}
- (void) addProperties: (NSDictionary *) newNewProperties
{
[sogoObject reloadIfNeeded];
[super addProperties: newNewProperties];
}
- (void) save - (void) save
{ {
uint64_t newVersion; uint64_t newVersion;
@ -76,13 +160,11 @@
newVersion = exchange_globcnt ([[self context] getNewChangeNumber] >> 16); newVersion = exchange_globcnt ([[self context] getNewChangeNumber] >> 16);
[properties setObject: [NSNumber numberWithUnsignedLongLong: newVersion] [properties setObject: [NSNumber numberWithUnsignedLongLong: newVersion]
forKey: @"version"]; forKey: @"version"];
[self logWithFormat: @"%d props in dict", [properties count]]; [self logWithFormat: @"%d props in dict", [properties count]];
[sogoObject appendProperties: properties];
[sogoObject save]; [sogoObject save];
[properties removeAllObjects];
} }
- (BOOL) _messageIsFreeBusy - (BOOL) _messageIsFreeBusy
@ -91,7 +173,7 @@
/* This is a HACK until we figure out how to determine a message position in /* This is a HACK until we figure out how to determine a message position in
the mailbox hierarchy.... (missing: folderid and role) */ the mailbox hierarchy.... (missing: folderid and role) */
msgClass = [[sogoObject properties] msgClass = [properties
objectForKey: MAPIPropertyKey (PR_MESSAGE_CLASS_UNICODE)]; objectForKey: MAPIPropertyKey (PR_MESSAGE_CLASS_UNICODE)];
return [msgClass isEqualToString: @"IPM.Microsoft.ScheduleData.FreeBusy"]; return [msgClass isEqualToString: @"IPM.Microsoft.ScheduleData.FreeBusy"];
@ -115,12 +197,12 @@
- (NSDate *) creationTime - (NSDate *) creationTime
{ {
return [sogoObject creationTime]; return [sogoObject creationDate];
} }
- (NSDate *) lastModificationTime - (NSDate *) lastModificationTime
{ {
return [sogoObject lastModificationTime]; return [sogoObject lastModified];
} }
@end @end

View file

@ -1,6 +1,6 @@
/* MAPIStoreFSMessageTable.h - this file is part of SOGo /* MAPIStoreDBMessageTable.h - this file is part of SOGo
* *
* Copyright (C) 2010 Inverse inc * Copyright (C) 2012 Inverse inc
* *
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca> * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
@ -20,12 +20,12 @@
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*/ */
#ifndef MAPISTOREFSMESSAGETABLE_H #ifndef MAPISTOREDBMESSAGETABLE_H
#define MAPISTOREFSMESSAGETABLE_H #define MAPISTOREDBMESSAGETABLE_H
#import "MAPIStoreMessageTable.h" #import "MAPIStoreMessageTable.h"
@interface MAPIStoreFSMessageTable : MAPIStoreMessageTable @interface MAPIStoreDBMessageTable : MAPIStoreMessageTable
@end @end
#endif /* MAPISTOREFSMESSAGETABLE_H */ #endif /* MAPISTOREDBMESSAGETABLE_H */

View file

@ -1,6 +1,6 @@
/* MAPIStoreFSMessageTable.m - this file is part of SOGo /* MAPIStoreDBMessageTable.m - this file is part of SOGo
* *
* Copyright (C) 2010 Inverse inc * Copyright (C) 2012 Inverse inc
* *
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca> * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
@ -25,25 +25,25 @@
#import <EOControl/EOQualifier.h> #import <EOControl/EOQualifier.h>
#import "MAPIStoreTypes.h" #import "MAPIStoreTypes.h"
#import "MAPIStoreFSMessage.h" #import "MAPIStoreDBMessage.h"
#import "MAPIStoreFSMessageTable.h" #import "MAPIStoreDBMessageTable.h"
#undef DEBUG #undef DEBUG
#include <mapistore/mapistore.h> #include <mapistore/mapistore.h>
static Class MAPIStoreFSMessageK = Nil; static Class MAPIStoreDBMessageK = Nil;
@implementation MAPIStoreFSMessageTable @implementation MAPIStoreDBMessageTable
+ (void) initialize + (void) initialize
{ {
MAPIStoreFSMessageK = [MAPIStoreFSMessage class]; MAPIStoreDBMessageK = [MAPIStoreDBMessage class];
} }
+ (Class) childObjectClass + (Class) childObjectClass
{ {
return MAPIStoreFSMessageK; return MAPIStoreDBMessageK;
} }
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property - (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property

View file

@ -23,9 +23,9 @@
#ifndef MAPISTOREFAIMESSAGE_H #ifndef MAPISTOREFAIMESSAGE_H
#define MAPISTOREFAIMESSAGE_H #define MAPISTOREFAIMESSAGE_H
#import "MAPIStoreFSMessage.h" #import "MAPIStoreDBMessage.h"
@interface MAPIStoreFAIMessage : MAPIStoreFSMessage @interface MAPIStoreFAIMessage : MAPIStoreDBMessage
@end @end
#endif /* MAPISTOREFAIMESSAGE_H */ #endif /* MAPISTOREFAIMESSAGE_H */

View file

@ -23,9 +23,9 @@
#ifndef MAPISTOREFAIMESSAGETABLE_H #ifndef MAPISTOREFAIMESSAGETABLE_H
#define MAPISTOREFAIMESSAGETABLE_H #define MAPISTOREFAIMESSAGETABLE_H
#import "MAPIStoreFSMessageTable.h" #import "MAPIStoreDBMessageTable.h"
@interface MAPIStoreFAIMessageTable : MAPIStoreFSMessageTable @interface MAPIStoreFAIMessageTable : MAPIStoreDBMessageTable
@end @end
#endif /* MAPISTOREFAIMESSAGETABLE_H */ #endif /* MAPISTOREFAIMESSAGETABLE_H */

View file

@ -1,79 +0,0 @@
/* MAPIStoreFSBaseContext.m - this file is part of SOGo
*
* Copyright (C) 2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/* A generic parent class for all context that will store their data on the
disk in the form of a plist. */
#import <Foundation/NSString.h>
#import <Foundation/NSURL.h>
#import <NGExtensions/NSObject+Logs.h>
#import "MAPIStoreFSFolder.h"
#import "MAPIStoreMapping.h"
#import "MAPIStoreUserContext.h"
#import "SOGoMAPIFSFolder.h"
#import "MAPIStoreFSBaseContext.h"
#undef DEBUG
#include <mapistore/mapistore.h>
static Class MAPIStoreFSFolderK;
@implementation MAPIStoreFSBaseContext
+ (void) initialize
{
MAPIStoreFSFolderK = [MAPIStoreFSFolder class];
}
+ (NSString *) MAPIModuleName
{
return nil;
}
- (Class) MAPIStoreFolderClass
{
return MAPIStoreFSFolderK;
}
- (void) ensureContextFolder
{
SOGoMAPIFSFolder *contextFolder;
contextFolder = [SOGoMAPIFSFolder folderWithURL: contextUrl
andTableType: MAPISTORE_MESSAGE_TABLE];
[contextFolder ensureDirectory];
}
- (id) rootSOGoFolder
{
NSString *urlString;
urlString = [NSString stringWithFormat: @"sogo://%@@%@/",
[userContext username], [isa MAPIModuleName]];
return [SOGoMAPIFSFolder folderWithURL: [NSURL URLWithString: urlString]
andTableType: MAPISTORE_MESSAGE_TABLE];
}
@end

View file

@ -23,9 +23,9 @@
#ifndef MAPISTOREFALLBACKCONTEXT_H #ifndef MAPISTOREFALLBACKCONTEXT_H
#define MAPISTOREFALLBACKCONTEXT_H #define MAPISTOREFALLBACKCONTEXT_H
#import "MAPIStoreFSBaseContext.h" #import "MAPIStoreDBBaseContext.h"
@interface MAPIStoreFallbackContext : MAPIStoreFSBaseContext @interface MAPIStoreFallbackContext : MAPIStoreDBBaseContext
@end @end

View file

@ -26,7 +26,7 @@
#import "MAPIStoreUserContext.h" #import "MAPIStoreUserContext.h"
#import "NSString+MAPIStore.h" #import "NSString+MAPIStore.h"
#import "SOGoMAPIFSFolder.h" #import "SOGoMAPIDBFolder.h"
#import "MAPIStoreFallbackContext.h" #import "MAPIStoreFallbackContext.h"
@ -51,10 +51,11 @@
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
struct mapistore_contexts_list *firstContext = NULL, *context; struct mapistore_contexts_list *firstContext = NULL, *context;
SOGoMAPIFSFolder *root; SOGoMAPIDBFolder *root;
NSArray *names; NSArray *names;
NSUInteger count, max; NSUInteger count, max;
NSString *baseURL, *url, *name; NSString *baseURL, *url, *name;
MAPIStoreUserContext *userContext;
baseURL = [NSString stringWithFormat: @"sogo://%@@fallback/", userName]; baseURL = [NSString stringWithFormat: @"sogo://%@@fallback/", userName];
@ -67,11 +68,15 @@
DLIST_ADD_END (firstContext, context, void); DLIST_ADD_END (firstContext, context, void);
/* Maybe emsmdbp_provisioning should be fixed in order to only take the uri /* Maybe emsmdbp_provisioning should be fixed in order to only take the uri
returned above to avoid deleting its entries... */ returned above to avoid deleting its entries... */
root = [SOGoMAPIFSFolder folderWithURL: [NSURL URLWithString: baseURL] root = [SOGoMAPIDBFolder objectWithName: [self MAPIModuleName]
andTableType: MAPISTORE_MESSAGE_TABLE]; inContainer: nil];
[root setOwner: userName];
userContext = [MAPIStoreUserContext userContextWithUsername: userName
andTDBIndexing: indexingTdb];
[userContext ensureFolderTableExists];
[root setTableUrl: [userContext folderTableURL]];
names = [root toManyRelationshipKeys]; names = [root toManyRelationshipKeys];
max = [names count]; max = [names count];
for (count = 0; count < max; count++) for (count = 0; count < max; count++)

View file

@ -38,29 +38,34 @@
@class MAPIStoreMessageTable; @class MAPIStoreMessageTable;
@class MAPIStorePermissionsTable; @class MAPIStorePermissionsTable;
@class SOGoFolder; @class SOGoFolder;
@class SOGoMAPIFSFolder; @class SOGoMAPIDBFolder;
@class SOGoMAPIFSMessage; @class SOGoMAPIDBMessage;
#import "MAPIStoreObject.h" #import "MAPIStoreSOGoObject.h"
@interface MAPIStoreFolder : MAPIStoreObject @interface MAPIStoreFolder : MAPIStoreSOGoObject
{ {
MAPIStoreContext *context; MAPIStoreContext *context;
// NSArray *messageKeys; // NSArray *messageKeys;
// NSArray *faiMessageKeys; // NSArray *faiMessageKeys;
// NSArray *folderKeys; // NSArray *folderKeys;
SOGoMAPIFSFolder *faiFolder; SOGoMAPIDBFolder *dbFolder;
SOGoMAPIFSFolder *propsFolder; // SOGoMAPIDBFolder *faiFolder;
SOGoMAPIFSMessage *propsMessage; // SOGoMAPIDBFolder *propsFolder;
// SOGoMAPIDBMessage *propsMessage;
} }
- (void) setContext: (MAPIStoreContext *) newContext; - (void) setContext: (MAPIStoreContext *) newContext;
- (void) setupAuxiliaryObjects;
- (SOGoMAPIDBFolder *) dbFolder;
- (NSArray *) activeMessageTables; - (NSArray *) activeMessageTables;
- (NSArray *) activeFAIMessageTables; - (NSArray *) activeFAIMessageTables;
- (SOGoMAPIFSMessage *) propertiesMessage; // - (SOGoMAPIDBMessage *) propertiesMessage;
- (id) lookupMessageByURL: (NSString *) messageURL; - (id) lookupMessageByURL: (NSString *) messageURL;
- (id) lookupFolderByURL: (NSString *) folderURL; - (id) lookupFolderByURL: (NSString *) folderURL;

View file

@ -48,8 +48,8 @@
#import "NSDate+MAPIStore.h" #import "NSDate+MAPIStore.h"
#import "NSString+MAPIStore.h" #import "NSString+MAPIStore.h"
#import "NSObject+MAPIStore.h" #import "NSObject+MAPIStore.h"
#import "SOGoMAPIFSFolder.h" #import "SOGoMAPIDBFolder.h"
#import "SOGoMAPIFSMessage.h" #import "SOGoMAPIDBMessage.h"
#include <gen_ndr/exchange.h> #include <gen_ndr/exchange.h>
@ -79,33 +79,67 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
// messageKeys = nil; // messageKeys = nil;
// faiMessageKeys = nil; // faiMessageKeys = nil;
// folderKeys = nil; // folderKeys = nil;
faiFolder = nil; dbFolder = nil;
context = nil; context = nil;
propsFolder = nil; // propsFolder = nil;
propsMessage = nil; // propsMessage = nil;
} }
return self; return self;
} }
- (void) _setupAuxiliaryObjects - (void) setupAuxiliaryObjects
{ {
NSURL *propsURL; NSURL *folderURL;
NSString *urlString; NSMutableString *pathPrefix;
NSString *path, *folderName;
NSArray *parts;
NSUInteger lastPartIdx;
MAPIStoreUserContext *userContext;
folderURL = [NSURL URLWithString: [self url]];
path = [folderURL path];
path = [path substringFromIndex: 1];
if ([path length] > 0)
{
parts = [path componentsSeparatedByString: @"/"];
lastPartIdx = [parts count] - 1;
if ([path hasSuffix: @"/"])
lastPartIdx--;
folderName = [parts objectAtIndex: lastPartIdx];
}
else
folderName = [folderURL host];
userContext = [self userContext];
[userContext ensureFolderTableExists];
ASSIGN (dbFolder,
[SOGoMAPIDBFolder objectWithName: folderName
inContainer: [container dbFolder]]);
[dbFolder setTableUrl: [userContext folderTableURL]];
if (!container && [path length] > 0)
{
pathPrefix = [NSMutableString stringWithCapacity: 64];
[pathPrefix appendFormat: @"/%@", [folderURL host]];
parts = [parts subarrayWithRange: NSMakeRange (0, lastPartIdx)];
if ([parts count] > 0)
[pathPrefix appendFormat: @"/%@", [parts componentsJoinedByString: @"/"]];
[dbFolder setPathPrefix: pathPrefix];
}
[dbFolder reloadIfNeeded];
/* propsMessage and self share the same properties dictionary */
// ASSIGN (propsMessage,
// [SOGoMAPIDBMessage objectWithName: @"properties.plist"
// inContainer: dbFolder]);
// [propsMessage setObjectType: MAPIDBObjectTypeInternal];
// [propsMessage reloadIfNeeded];
[properties release];
properties = [dbFolder properties];
[properties retain];
urlString = [[self url] stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
propsURL = [NSURL URLWithString: urlString];
[self logWithFormat: @"_setupAuxiliaryObjects: %@", propsURL];
ASSIGN (faiFolder,
[SOGoMAPIFSFolder folderWithURL: propsURL
andTableType: MAPISTORE_FAI_TABLE]);
ASSIGN (propsFolder,
[SOGoMAPIFSFolder folderWithURL: propsURL
andTableType: MAPISTORE_FOLDER_TABLE]);
ASSIGN (propsMessage,
[SOGoMAPIFSMessage objectWithName: @"properties.plist"
inContainer: propsFolder]);
[self setupVersionsMessage]; [self setupVersionsMessage];
} }
@ -119,7 +153,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
inContainer: newContainer]) inContainer: newContainer])
&& newContainer) && newContainer)
{ {
[self _setupAuxiliaryObjects]; [self setupAuxiliaryObjects];
} }
return self; return self;
@ -129,13 +163,13 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
{ {
ASSIGN (context, newContext); ASSIGN (context, newContext);
if (newContext) if (newContext)
[self _setupAuxiliaryObjects]; [self setupAuxiliaryObjects];
} }
- (MAPIStoreContext *) context - (MAPIStoreContext *) context
{ {
if (!context) if (!context)
[self setContext: [container context]]; [self setContext: (MAPIStoreContext *) [container context]];
return context; return context;
} }
@ -145,29 +179,31 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
// [messageKeys release]; // [messageKeys release];
// [faiMessageKeys release]; // [faiMessageKeys release];
// [folderKeys release]; // [folderKeys release];
[propsMessage release]; // [propsMessage release];
[propsFolder release]; [dbFolder release];
[faiFolder release];
[context release]; [context release];
[super dealloc]; [super dealloc];
} }
- (SOGoMAPIDBFolder *) dbFolder
{
return dbFolder;
}
/* backend interface */ /* backend interface */
- (SOGoMAPIFSMessage *) propertiesMessage // - (SOGoMAPIDBMessage *) propertiesMessage
{ // {
return propsMessage; // return propsMessage;
} // }
- (uint64_t) objectVersion - (uint64_t) objectVersion
{ {
NSNumber *value; NSNumber *value;
NSDictionary *props;
uint64_t cn; uint64_t cn;
props = [propsMessage properties]; value = [properties objectForKey: MAPIPropertyKey (PidTagChangeNumber)];
value = [props objectForKey: MAPIPropertyKey (PidTagChangeNumber)];
if (value) if (value)
cn = [value unsignedLongLongValue]; cn = [value unsignedLongLongValue];
else else
@ -175,10 +211,10 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
[self logWithFormat: @"no value for PidTagChangeNumber, adding one now"]; [self logWithFormat: @"no value for PidTagChangeNumber, adding one now"];
cn = [[self context] getNewChangeNumber]; cn = [[self context] getNewChangeNumber];
value = [NSNumber numberWithUnsignedLongLong: cn]; value = [NSNumber numberWithUnsignedLongLong: cn];
props = [NSDictionary dictionaryWithObject: value
forKey: MAPIPropertyKey (PidTagChangeNumber)]; [properties setObject: value
[propsMessage appendProperties: props]; forKey: MAPIPropertyKey (PidTagChangeNumber)];
[propsMessage save]; [dbFolder save];
} }
return cn >> 16; return cn >> 16;
@ -186,21 +222,24 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
- (id) lookupFolder: (NSString *) folderKey - (id) lookupFolder: (NSString *) folderKey
{ {
MAPIStoreFolder *childFolder = nil; MAPIStoreFolder *childFolder;
SOGoFolder *sogoFolder; SOGoFolder *sogoFolder;
WOContext *woContext; WOContext *woContext;
if ([[self folderKeys] containsObject: folderKey]) if ([[self folderKeys] containsObject: folderKey])
{ {
woContext = [[self userContext] woContext]; woContext = [[self userContext] woContext];
sogoFolder = [sogoObject lookupName: folderKey sogoFolder = [sogoObject lookupName: folderKey inContext: woContext
inContext: woContext
acquire: NO]; acquire: NO];
[sogoFolder setContext: woContext];
if (sogoFolder && ![sogoFolder isKindOfClass: NSExceptionK]) if (sogoFolder && ![sogoFolder isKindOfClass: NSExceptionK])
childFolder = [isa mapiStoreObjectWithSOGoObject: sogoFolder {
inContainer: self]; [sogoFolder setContext: woContext];
childFolder = [isa mapiStoreObjectWithSOGoObject: sogoFolder
inContainer: self];
}
} }
else
childFolder = nil;
return childFolder; return childFolder;
} }
@ -264,9 +303,9 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
{ {
if ([[self faiMessageKeys] containsObject: messageKey]) if ([[self faiMessageKeys] containsObject: messageKey])
{ {
msgObject = [faiFolder lookupName: messageKey msgObject = [dbFolder lookupName: messageKey
inContext: nil inContext: nil
acquire: NO]; acquire: NO];
childMessage childMessage
= [MAPIStoreFAIMessageK mapiStoreObjectWithSOGoObject: msgObject = [MAPIStoreFAIMessageK mapiStoreObjectWithSOGoObject: msgObject
inContainer: self]; inContainer: self];
@ -383,9 +422,8 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
- (int) deleteFolder - (int) deleteFolder
{ {
[propsMessage delete]; // [propsMessage delete];
[propsFolder delete]; [dbFolder delete];
[faiFolder delete];
[self cleanupCaches]; [self cleanupCaches];
@ -1004,7 +1042,11 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
/* TODO: this should no longer be required once mapistore v2 API is in /* TODO: this should no longer be required once mapistore v2 API is in
place, when we can then do this from -dealloc below */ place, when we can then do this from -dealloc below */
[dbFolder reloadIfNeeded];
propsCopy = [newProperties mutableCopy]; propsCopy = [newProperties mutableCopy];
[propsCopy autorelease];
currentProp = bannedProps; currentProp = bannedProps;
while (*currentProp) while (*currentProp)
{ {
@ -1012,9 +1054,8 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
currentProp++; currentProp++;
} }
[propsMessage appendProperties: propsCopy]; [properties addEntriesFromDictionary: propsCopy];
[propsMessage save]; [dbFolder save];
[propsCopy release];
} }
- (NSArray *) messageKeys - (NSArray *) messageKeys
@ -1039,9 +1080,10 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
- (NSArray *) faiMessageKeysMatchingQualifier: (EOQualifier *) qualifier - (NSArray *) faiMessageKeysMatchingQualifier: (EOQualifier *) qualifier
andSortOrderings: (NSArray *) sortOrderings andSortOrderings: (NSArray *) sortOrderings
{ {
return [faiFolder return [dbFolder childKeysOfType: MAPIDBObjectTypeFAI
toOneRelationshipKeysMatchingQualifier: qualifier includeDeleted: NO
andSortOrderings: sortOrderings]; matchingQualifier: qualifier
andSortOrderings: sortOrderings];
} }
- (NSArray *) faiMessageKeys - (NSArray *) faiMessageKeys
@ -1287,6 +1329,19 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
return MAPISTORE_SUCCESS; return MAPISTORE_SUCCESS;
} }
- (int) getProperties: (struct mapistore_property_data *) data
withTags: (enum MAPITAGS *) tags
andCount: (uint16_t) columnCount
inMemCtx: (TALLOC_CTX *) memCtx
{
[dbFolder reloadIfNeeded];
return [super getProperties: data
withTags: tags
andCount: columnCount
inMemCtx: memCtx];
}
- (int) getProperty: (void **) data - (int) getProperty: (void **) data
withTag: (enum MAPITAGS) propTag withTag: (enum MAPITAGS) propTag
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
@ -1294,8 +1349,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
int rc; int rc;
id value; id value;
value = [[propsMessage properties] value = [properties objectForKey: MAPIPropertyKey (propTag)];
objectForKey: MAPIPropertyKey (propTag)];
if (value) if (value)
rc = [value getValue: data forTag: propTag inMemCtx: memCtx]; rc = [value getValue: data forTag: propTag inMemCtx: memCtx];
else else
@ -1307,13 +1361,15 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
- (MAPIStoreMessage *) _createAssociatedMessage - (MAPIStoreMessage *) _createAssociatedMessage
{ {
MAPIStoreMessage *newMessage; MAPIStoreMessage *newMessage;
SOGoMAPIFSMessage *fsObject; SOGoMAPIDBMessage *dbObject;
NSString *newKey; NSString *newKey;
newKey = [NSString stringWithFormat: @"%@.plist", newKey = [NSString stringWithFormat: @"%@.plist",
[SOGoObject globallyUniqueObjectId]]; [SOGoObject globallyUniqueObjectId]];
fsObject = [SOGoMAPIFSMessage objectWithName: newKey inContainer: faiFolder]; dbObject = [SOGoMAPIDBMessage objectWithName: newKey inContainer: dbFolder];
newMessage = [MAPIStoreFAIMessageK mapiStoreObjectWithSOGoObject: fsObject [dbObject setObjectType: MAPIDBObjectTypeFAI];
[dbObject setIsNew: YES];
newMessage = [MAPIStoreFAIMessageK mapiStoreObjectWithSOGoObject: dbObject
inContainer: self]; inContainer: self];
return newMessage; return newMessage;
@ -1328,9 +1384,15 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
newMessage = [self _createAssociatedMessage]; newMessage = [self _createAssociatedMessage];
else else
newMessage = [self createMessage]; newMessage = [self createMessage];
[newMessage setIsNew: YES]; /* FIXME: this is ugly as the specifics of message creation should all be
delegated to subclasses */
if ([newMessage respondsToSelector: @selector (setIsNew:)])
[newMessage setIsNew: YES];
woContext = [[self userContext] woContext]; woContext = [[self userContext] woContext];
[[newMessage sogoObject] setContext: woContext]; /* FIXME: this is ugly too as the specifics of message creation should all
be delegated to subclasses */
if ([newMessage respondsToSelector: @selector (sogoObject:)])
[[newMessage sogoObject] setContext: woContext];
return newMessage; return newMessage;
} }
@ -1598,12 +1660,12 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
- (NSDate *) creationTime - (NSDate *) creationTime
{ {
return [propsMessage creationTime]; return [dbFolder creationDate];
} }
- (NSDate *) lastModificationTime - (NSDate *) lastModificationTime
{ {
return [propsMessage lastModificationTime]; return [dbFolder lastModified];
} }
/* subclasses */ /* subclasses */

View file

@ -34,7 +34,7 @@
@interface MAPIStoreGCSFolder : MAPIStoreFolder @interface MAPIStoreGCSFolder : MAPIStoreFolder
{ {
SOGoMAPIFSMessage *versionsMessage; SOGoMAPIDBMessage *versionsMessage;
NSArray *activeUserRoles; NSArray *activeUserRoles;
EOQualifier *componentQualifier; EOQualifier *componentQualifier;
} }

View file

@ -40,7 +40,7 @@
#import "NSData+MAPIStore.h" #import "NSData+MAPIStore.h"
#import "NSDate+MAPIStore.h" #import "NSDate+MAPIStore.h"
#import "NSString+MAPIStore.h" #import "NSString+MAPIStore.h"
#import "SOGoMAPIFSMessage.h" #import "SOGoMAPIDBMessage.h"
#import "MAPIStoreGCSFolder.h" #import "MAPIStoreGCSFolder.h"
@ -71,8 +71,9 @@ static Class NSNumberK;
- (void) setupVersionsMessage - (void) setupVersionsMessage
{ {
ASSIGN (versionsMessage, ASSIGN (versionsMessage,
[SOGoMAPIFSMessage objectWithName: @"versions.plist" [SOGoMAPIDBMessage objectWithName: @"versions.plist"
inContainer: propsFolder]); inContainer: dbFolder]);
[versionsMessage setObjectType: MAPIDBObjectTypeInternal];
} }
- (void) dealloc - (void) dealloc
@ -288,7 +289,8 @@ static Class NSNumberK;
forKey: @"PredecessorChangeList"]; forKey: @"PredecessorChangeList"];
[changeList release]; [changeList release];
} }
[changeList setObject: globCnt forKey: guid]; [changeList setObject: globCnt
forKey: guid];
} }
- (EOQualifier *) componentQualifier - (EOQualifier *) componentQualifier
@ -349,6 +351,7 @@ static Class NSNumberK;
[sortOrdering retain]; [sortOrdering retain];
} }
[versionsMessage reloadIfNeeded];
currentProperties = [versionsMessage properties]; currentProperties = [versionsMessage properties];
lastModificationDate = [currentProperties objectForKey: @"SyncLastModificationDate"]; lastModificationDate = [currentProperties objectForKey: @"SyncLastModificationDate"];
@ -451,7 +454,6 @@ static Class NSNumberK;
forKey: @"SyncLastSynchronisationDate"]; forKey: @"SyncLastSynchronisationDate"];
[currentProperties setObject: lastModificationDate [currentProperties setObject: lastModificationDate
forKey: @"SyncLastModificationDate"]; forKey: @"SyncLastModificationDate"];
[versionsMessage appendProperties: currentProperties];
[versionsMessage save]; [versionsMessage save];
} }
} }

View file

@ -30,9 +30,11 @@
@interface MAPIStoreMailAttachment : MAPIStoreAttachment @interface MAPIStoreMailAttachment : MAPIStoreAttachment
{ {
NSDictionary *bodyInfo; NSDictionary *bodyInfo;
SOGoMailBodyPart *bodyPart;
} }
- (void) setBodyInfo: (NSDictionary *) newBodyInfo; - (void) setBodyInfo: (NSDictionary *) newBodyInfo;
- (void) setBodyPart: (SOGoMailBodyPart *) newBodyPart;
@end @end

View file

@ -52,6 +52,7 @@
if ((self = [super init])) if ((self = [super init]))
{ {
bodyInfo = nil; bodyInfo = nil;
bodyPart = nil;
} }
return self; return self;
@ -60,6 +61,7 @@
- (void) dealloc - (void) dealloc
{ {
[bodyInfo release]; [bodyInfo release];
[bodyPart release];
[super dealloc]; [super dealloc];
} }
@ -68,6 +70,11 @@
ASSIGN (bodyInfo, newBodyInfo); ASSIGN (bodyInfo, newBodyInfo);
} }
- (void) setBodyPart: (SOGoMailBodyPart *) newBodyPart
{
ASSIGN (bodyPart, newBodyPart);
}
- (int) getPidTagAttachMethod: (void **) data - (int) getPidTagAttachMethod: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
@ -187,7 +194,7 @@
- (int) getPidTagAttachDataBinary: (void **) data - (int) getPidTagAttachDataBinary: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
*data = [[sogoObject fetchBLOBWithPeek: YES] asBinaryInMemCtx: memCtx]; *data = [[bodyPart fetchBLOBWithPeek: YES] asBinaryInMemCtx: memCtx];
return MAPISTORE_SUCCESS; return MAPISTORE_SUCCESS;
} }

View file

@ -36,7 +36,7 @@
@interface MAPIStoreMailFolder : MAPIStoreFolder @interface MAPIStoreMailFolder : MAPIStoreFolder
{ {
SOGoMAPIFSMessage *versionsMessage; SOGoMAPIDBMessage *versionsMessage;
} }
- (BOOL) ensureFolderExists; - (BOOL) ensureFolderExists;

View file

@ -54,9 +54,8 @@
#import "MAPIStoreTypes.h" #import "MAPIStoreTypes.h"
#import "NSData+MAPIStore.h" #import "NSData+MAPIStore.h"
#import "NSString+MAPIStore.h" #import "NSString+MAPIStore.h"
#import "SOGoMAPIFSMessage.h" #import "SOGoMAPIDBMessage.h"
#import "SOGoMAPIVolatileMessage.h"
#import "MAPIStoreMailVolatileMessage.h" #import "MAPIStoreMailVolatileMessage.h"
#import "MAPIStoreMailFolder.h" #import "MAPIStoreMailFolder.h"
@ -97,8 +96,9 @@ static Class SOGoMailFolderK, MAPIStoreOutboxFolderK;
- (void) setupVersionsMessage - (void) setupVersionsMessage
{ {
ASSIGN (versionsMessage, ASSIGN (versionsMessage,
[SOGoMAPIFSMessage objectWithName: @"versions.plist" [SOGoMAPIDBMessage objectWithName: @"versions.plist"
inContainer: propsFolder]); inContainer: dbFolder]);
[versionsMessage setObjectType: MAPIDBObjectTypeInternal];
} }
- (BOOL) ensureFolderExists - (BOOL) ensureFolderExists
@ -119,6 +119,9 @@ static Class SOGoMailFolderK, MAPIStoreOutboxFolderK;
&& ![[(SOGoMailFolder *) sogoObject displayName] && ![[(SOGoMailFolder *) sogoObject displayName]
isEqualToString: newDisplayName]) isEqualToString: newDisplayName])
{ {
[NSException raise: @"MAPIStoreIOException"
format: @"renaming a mail folder via OpenChange is"
@" currently a bad idea"];
[(SOGoMailFolder *) sogoObject renameTo: newDisplayName]; [(SOGoMailFolder *) sogoObject renameTo: newDisplayName];
propsCopy = [newProperties mutableCopy]; propsCopy = [newProperties mutableCopy];
[propsCopy removeObjectForKey: key]; [propsCopy removeObjectForKey: key];
@ -489,10 +492,8 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
now = [NSCalendarDate date]; now = [NSCalendarDate date];
[now setTimeZone: utcTZ]; [now setTimeZone: utcTZ];
currentProperties = [[versionsMessage properties] mutableCopy]; [versionsMessage reloadIfNeeded];
if (!currentProperties) currentProperties = [versionsMessage properties];
currentProperties = [NSMutableDictionary new];
[currentProperties autorelease];
messages = [currentProperties objectForKey: @"Messages"]; messages = [currentProperties objectForKey: @"Messages"];
if (!messages) if (!messages)
{ {
@ -613,7 +614,6 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
ti = [NSNumber numberWithDouble: [now timeIntervalSince1970]]; ti = [NSNumber numberWithDouble: [now timeIntervalSince1970]];
[currentProperties setObject: ti [currentProperties setObject: ti
forKey: @"SyncLastSynchronisationDate"]; forKey: @"SyncLastSynchronisationDate"];
[versionsMessage appendProperties: currentProperties];
[versionsMessage save]; [versionsMessage save];
} }
@ -1004,20 +1004,16 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
- (MAPIStoreMessage *) createMessage - (MAPIStoreMessage *) createMessage
{ {
MAPIStoreMailVolatileMessage *newMessage; SOGoMAPIObject *childObject;
SOGoMAPIVolatileMessage *newObject;
newObject = [SOGoMAPIVolatileMessage childObject = [SOGoMAPIObject objectWithName: [SOGoMAPIObject
objectWithName: [SOGoObject globallyUniqueObjectId] globallyUniqueObjectId]
inContainer: sogoObject]; inContainer: sogoObject];
newMessage return [MAPIStoreMailVolatileMessage
= [MAPIStoreMailVolatileMessage mapiStoreObjectWithSOGoObject: newObject mapiStoreObjectWithSOGoObject: childObject
inContainer: self]; inContainer: self];
return newMessage;
} }
- (NSArray *) rolesForExchangeRights: (uint32_t) rights - (NSArray *) rolesForExchangeRights: (uint32_t) rights
{ {
NSMutableArray *roles; NSMutableArray *roles;

View file

@ -373,7 +373,7 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
if (uid) if (uid)
{ {
changeNumber = [(MAPIStoreMailFolder *) container changeNumber = [(MAPIStoreMailFolder *) container
changeNumberForMessageUID: uid]; changeNumberForMessageUID: uid];
if (!changeNumber) if (!changeNumber)
{ {
[self warnWithFormat: @"attempting to get change number" [self warnWithFormat: @"attempting to get change number"
@ -1529,8 +1529,8 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
if (currentPart) if (currentPart)
{ {
attachment = [MAPIStoreMailAttachment attachment = [MAPIStoreMailAttachment
mapiStoreObjectWithSOGoObject: currentPart mapiStoreObjectInContainer: self];
inContainer: self]; [attachment setBodyPart: currentPart];
[attachment setBodyInfo: [attachmentParts objectForKey: childKey]]; [attachment setBodyInfo: [attachmentParts objectForKey: childKey]];
[attachment setAID: [[self attachmentKeys] indexOfObject: childKey]]; [attachment setAID: [[self attachmentKeys] indexOfObject: childKey]];
} }

View file

@ -332,7 +332,7 @@ static Class MAPIStoreMailMessageK, NSDataK, NSStringK;
if (!fetchedCoreInfos) if (!fetchedCoreInfos)
{ {
fetchedCoreInfos = YES; fetchedCoreInfos = YES;
[(SOGoMailFolder *) [container sogoObject] [(SOGoMailFolder *) [(MAPIStoreMailFolder *) container sogoObject]
prefetchCoreInfosForMessageKeys: [self restrictedChildKeys]]; prefetchCoreInfosForMessageKeys: [self restrictedChildKeys]];
} }

View file

@ -23,9 +23,9 @@
#ifndef MAPISTOREMAILVOLATILEMESSAGE_H #ifndef MAPISTOREMAILVOLATILEMESSAGE_H
#define MAPISTOREMAILVOLATILEMESSAGE_H #define MAPISTOREMAILVOLATILEMESSAGE_H
#import "MAPIStoreVolatileMessage.h" #import "MAPIStoreMessage.h"
@interface MAPIStoreMailVolatileMessage : MAPIStoreVolatileMessage @interface MAPIStoreMailVolatileMessage : MAPIStoreMessage
- (int) submitWithFlags: (enum SubmitFlags) flags; - (int) submitWithFlags: (enum SubmitFlags) flags;

View file

@ -51,6 +51,7 @@
#import <Mailer/NSString+Mail.h> #import <Mailer/NSString+Mail.h>
#import "MAPIStoreAttachment.h" #import "MAPIStoreAttachment.h"
#import "MAPIStoreAttachmentTable.h"
#import "MAPIStoreContext.h" #import "MAPIStoreContext.h"
#import "MAPIStoreMailFolder.h" #import "MAPIStoreMailFolder.h"
#import "MAPIStoreMIME.h" #import "MAPIStoreMIME.h"
@ -60,7 +61,7 @@
#import "NSData+MAPIStore.h" #import "NSData+MAPIStore.h"
#import "NSObject+MAPIStore.h" #import "NSObject+MAPIStore.h"
#import "NSString+MAPIStore.h" #import "NSString+MAPIStore.h"
#import "SOGoMAPIVolatileMessage.h" #import "SOGoMAPIObject.h"
#import "MAPIStoreMailVolatileMessage.h" #import "MAPIStoreMailVolatileMessage.h"
@ -68,6 +69,8 @@
#include <mapistore/mapistore.h> #include <mapistore/mapistore.h>
#include <mapistore/mapistore_errors.h> #include <mapistore/mapistore_errors.h>
static Class NSNumberK = Nil;
static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" }; static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" };
// //
@ -242,6 +245,106 @@ static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" };
@implementation MAPIStoreMailVolatileMessage @implementation MAPIStoreMailVolatileMessage
+ (void) initialize
{
NSNumberK = [NSNumber class];
}
- (id) initWithSOGoObject: (id) newSOGoObject
inContainer: (MAPIStoreObject *) newContainer
{
if ((self = [super initWithSOGoObject: newSOGoObject
inContainer: newContainer]))
{
ASSIGN (properties, [sogoObject properties]);
}
return self;
}
- (void) addProperties: (NSDictionary *) newProperties
{
[super addProperties: newProperties];
[sogoObject adjustLastModified];
}
- (BOOL) canGetProperty: (enum MAPITAGS) propTag
{
return ([super canGetProperty: propTag]
|| [properties objectForKey: MAPIPropertyKey (propTag)] != nil);
}
- (uint64_t) objectVersion
{
NSNumber *version;
version = [properties objectForKey: @"version"];
return (version
? exchange_globcnt ([version unsignedLongLongValue])
: ULLONG_MAX);
}
- (int) getPidTagSubject: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
{
/* if we get here, it means that the properties file didn't contain a
relevant value */
return [self getEmptyString: data inMemCtx: memCtx];
}
- (int) getPidTagMessageClass: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
{
*data = [@"IPM.Note" asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPidTagChangeKey: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
{
NSData *changeKey;
int rc;
changeKey = [properties objectForKey: MAPIPropertyKey (PR_CHANGE_KEY)];
if (changeKey)
{
*data = [changeKey asBinaryInMemCtx: memCtx];
rc = MAPISTORE_SUCCESS;
}
else
rc = [super getPidTagChangeKey: data inMemCtx: memCtx];
return rc;
}
- (NSArray *) attachmentsKeysMatchingQualifier: (EOQualifier *) qualifier
andSortOrderings: (NSArray *) sortOrderings
{
NSDictionary *attachments;
attachments = [properties objectForKey: @"attachments"];
return [attachments allKeys];
}
- (NSDate *) creationTime
{
return [sogoObject creationDate];
}
- (NSDate *) lastModificationTime
{
return [sogoObject lastModified];
}
- (id) lookupAttachment: (NSString *) childKey
{
NSDictionary *attachments;
attachments = [properties objectForKey: @"attachments"];
return [attachments objectForKey: childKey];
}
- (void) getMessageData: (struct mapistore_message **) dataPtr - (void) getMessageData: (struct mapistore_message **) dataPtr
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
@ -258,9 +361,11 @@ static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" };
samCtx = [[self context] connectionInfo]->sam_ctx; samCtx = [[self context] connectionInfo]->sam_ctx;
[super getMessageData: &msgData inMemCtx: memCtx]; // [super getMessageData: &msgData inMemCtx: memCtx];
allRecipients = [[sogoObject properties] objectForKey: @"recipients"]; msgData = talloc_zero (memCtx, struct mapistore_message);
allRecipients = [properties objectForKey: @"recipients"];
msgData->columns = set_SPropTagArray (msgData, 9, msgData->columns = set_SPropTagArray (msgData, 9,
PR_OBJECT_TYPE, PR_OBJECT_TYPE,
PR_DISPLAY_TYPE, PR_DISPLAY_TYPE,
@ -660,10 +765,13 @@ MakeTextPartBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
return textBody; return textBody;
} }
// static id
// MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
// NSString **contentType)
static id static id
MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts, MakeMessageBody (NSDictionary *mailProperties, NSString **contentType)
NSString **contentType)
{ {
NSDictionary *attachmentParts;
id messageBody, textBody; id messageBody, textBody;
NSString *textContentType; NSString *textContentType;
NSArray *parts; NSArray *parts;
@ -671,6 +779,7 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
NGMutableHashMap *headers; NGMutableHashMap *headers;
NSUInteger count, max; NSUInteger count, max;
attachmentParts = [mailProperties objectForKey: @"attachments"];
textBody = MakeTextPartBody (mailProperties, attachmentParts, textBody = MakeTextPartBody (mailProperties, attachmentParts,
&textContentType); &textContentType);
@ -707,22 +816,20 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
- (NGMimeMessage *) _generateMessage - (NGMimeMessage *) _generateMessage
{ {
NSDictionary *mailProperties;
NSString *contentType; NSString *contentType;
NGMimeMessage *message; NGMimeMessage *message;
NGMutableHashMap *headers; NGMutableHashMap *headers;
id messageBody; id messageBody;
mailProperties = [sogoObject properties];
headers = [[NGMutableHashMap alloc] initWithCapacity: 16]; headers = [[NGMutableHashMap alloc] initWithCapacity: 16];
FillMessageHeadersFromProperties (headers, mailProperties, FillMessageHeadersFromProperties (headers, properties,
[[self context] connectionInfo]); [[self context] connectionInfo]);
message = [[NGMimeMessage alloc] initWithHeader: headers]; message = [[NGMimeMessage alloc] initWithHeader: headers];
[message autorelease]; [message autorelease];
[headers release]; [headers release];
messageBody = MakeMessageBody (mailProperties, attachmentParts, &contentType); messageBody = MakeMessageBody (properties, &contentType);
// messageBody = MakeMessageBody (mailProperties, attachmentParts, &contentType);
if (messageBody) if (messageBody)
{ {
[headers setObject: contentType forKey: @"content-type"]; [headers setObject: contentType forKey: @"content-type"];
@ -775,7 +882,7 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
- (int) submitWithFlags: (enum SubmitFlags) flags - (int) submitWithFlags: (enum SubmitFlags) flags
{ {
NSDictionary *mailProperties, *recipients; NSDictionary *recipients;
NSData *messageData; NSData *messageData;
NSMutableArray *recipientEmails; NSMutableArray *recipientEmails;
NSArray *list; NSArray *list;
@ -785,19 +892,17 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
// SOGoMailFolder *sentFolder; // SOGoMailFolder *sentFolder;
SOGoDomainDefaults *dd; SOGoDomainDefaults *dd;
NSException *error; NSException *error;
MAPIStoreMapping *mapping; // MAPIStoreMapping *mapping;
mailProperties = [sogoObject properties]; msgClass = [properties objectForKey: MAPIPropertyKey (PidTagMessageClass)];
msgClass = [mailProperties objectForKey: MAPIPropertyKey (PidTagMessageClass)];
if ([msgClass isEqualToString: @"IPM.Note"]) /* we skip invitation replies */ if ([msgClass isEqualToString: @"IPM.Note"]) /* we skip invitation replies */
{ {
/* send mail */ /* send mail */
messageData = [self _generateMailDataWithBcc: NO]; messageData = [self _generateMailDataWithBcc: NO];
mailProperties = [sogoObject properties];
recipientEmails = [NSMutableArray arrayWithCapacity: 32]; recipientEmails = [NSMutableArray arrayWithCapacity: 32];
recipients = [mailProperties objectForKey: @"recipients"]; recipients = [properties objectForKey: @"recipients"];
for (count = 0; count < 3; count++) for (count = 0; count < 3; count++)
{ {
recId = recTypes[count]; recId = recTypes[count];
@ -819,11 +924,11 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
if (error) if (error)
[self logWithFormat: @"an error occurred: '%@'", error]; [self logWithFormat: @"an error occurred: '%@'", error];
mapping = [self mapping]; // mapping = [self mapping];
[mapping unregisterURLWithID: [self objectId]]; // [mapping unregisterURLWithID: [self objectId]];
[self setIsNew: NO]; // [self setIsNew: NO];
[properties removeAllObjects]; // [properties removeAllObjects];
[[self container] cleanupCaches]; [(MAPIStoreMailFolder *) [self container] cleanupCaches];
} }
else else
[self logWithFormat: @"skipping submit of message with class '%@'", [self logWithFormat: @"skipping submit of message with class '%@'",
@ -834,14 +939,14 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
- (void) save - (void) save
{ {
NSString *folderName, *flag, *newIdString; NSString *folderName, *flag, *newIdString, *messageKey;
NSData *changeKey, *messageData; NSData *changeKey, *messageData;
NGImap4Connection *connection; NGImap4Connection *connection;
NGImap4Client *client; NGImap4Client *client;
SOGoMailFolder *containerFolder; SOGoMailFolder *containerFolder;
NSDictionary *result, *responseResult; NSDictionary *result, *responseResult;
MAPIStoreMapping *mapping; // MAPIStoreMapping *mapping;
uint64_t mid; // uint64_t mid;
messageData = [self _generateMailDataWithBcc: YES]; messageData = [self _generateMailDataWithBcc: YES];
@ -860,21 +965,24 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
flag = [responseResult objectForKey: @"flag"]; flag = [responseResult objectForKey: @"flag"];
newIdString = [[flag componentsSeparatedByString: @" "] newIdString = [[flag componentsSeparatedByString: @" "]
objectAtIndex: 2]; objectAtIndex: 2];
mid = [self objectId]; // mid = [self objectId];
mapping = [self mapping]; // mapping = [self mapping];
[mapping unregisterURLWithID: mid]; // [mapping unregisterURLWithID: mid];
[sogoObject setNameInContainer: [NSString stringWithFormat: @"%@.eml", newIdString]]; // [sogoObject setNameInContainer: ];
[mapping registerURL: [self url] withID: mid]; messageKey = [NSString stringWithFormat: @"%@.eml", newIdString];
} // [mapping registerURL: [NSString stringWithFormat: @"%@%@",
// [(MAPIStoreMailFolder *) container url], messageKey]
// withID: mid];
/* synchronise the cache and update the change key with the one provided by /* synchronise the cache and update the change key with the one provided
the client */ by the client */
[(MAPIStoreMailFolder *) container synchroniseCache]; [(MAPIStoreMailFolder *) container synchroniseCache];
changeKey = [[sogoObject properties] changeKey = [properties objectForKey: MAPIPropertyKey (PR_CHANGE_KEY)];
objectForKey: MAPIPropertyKey (PR_CHANGE_KEY)]; if (changeKey)
if (changeKey) [(MAPIStoreMailFolder *) container
[(MAPIStoreMailFolder *) container setChangeKey: changeKey
setChangeKey: changeKey forMessageWithKey: [self nameInContainer]]; forMessageWithKey: messageKey];
}
} }
@end @end

View file

@ -35,9 +35,9 @@
@class MAPIStoreAttachmentTable; @class MAPIStoreAttachmentTable;
@class MAPIStoreFolder; @class MAPIStoreFolder;
#import "MAPIStoreObject.h" #import "MAPIStoreSOGoObject.h"
@interface MAPIStoreMessage : MAPIStoreObject @interface MAPIStoreMessage : MAPIStoreSOGoObject
{ {
NSArray *attachmentKeys; NSArray *attachmentKeys;
NSMutableDictionary *attachmentParts; NSMutableDictionary *attachmentParts;

View file

@ -36,6 +36,7 @@
#import "MAPIStoreAttachmentTable.h" #import "MAPIStoreAttachmentTable.h"
#import "MAPIStoreContext.h" #import "MAPIStoreContext.h"
#import "MAPIStoreFolder.h" #import "MAPIStoreFolder.h"
#import "MAPIStoreMessageTable.h"
#import "MAPIStorePropertySelectors.h" #import "MAPIStorePropertySelectors.h"
#import "MAPIStoreSamDBUtils.h" #import "MAPIStoreSamDBUtils.h"
#import "MAPIStoreTypes.h" #import "MAPIStoreTypes.h"
@ -116,7 +117,6 @@ rtf2html (NSData *compressedRTF)
@interface SOGoObject (MAPIStoreProtocol) @interface SOGoObject (MAPIStoreProtocol)
- (NSString *) davEntityTag;
- (NSString *) davContentLength; - (NSString *) davContentLength;
@end @end
@ -304,6 +304,7 @@ rtf2html (NSData *compressedRTF)
NSData *htmlData, *rtfData; NSData *htmlData, *rtfData;
static NSNumber *htmlKey = nil, *rtfKey = nil; static NSNumber *htmlKey = nil, *rtfKey = nil;
/* we intercept any RTF content and convert it to HTML */
[super addProperties: newNewProperties]; [super addProperties: newNewProperties];
if (!htmlKey) if (!htmlKey)
@ -339,10 +340,8 @@ rtf2html (NSData *compressedRTF)
newAid = [[self attachmentKeys] count]; newAid = [[self attachmentKeys] count];
newAttachment = [MAPIStoreAttachment newAttachment = [MAPIStoreAttachment mapiStoreObjectInContainer: self];
mapiStoreObjectWithSOGoObject: nil // [newAttachment setIsNew: YES];
inContainer: self];
[newAttachment setIsNew: YES];
[newAttachment setAID: newAid]; [newAttachment setAID: newAid];
newKey = [NSString stringWithFormat: @"%ul", newAid]; newKey = [NSString stringWithFormat: @"%ul", newAid];
[attachmentParts setObject: newAttachment [attachmentParts setObject: newAttachment
@ -497,7 +496,6 @@ rtf2html (NSData *compressedRTF)
[[containerTables objectAtIndex: count] [[containerTables objectAtIndex: count]
notifyChangesForChild: self]; notifyChangesForChild: self];
[self setIsNew: NO]; [self setIsNew: NO];
[properties removeAllObjects];
[container cleanupCaches]; [container cleanupCaches];
rc = MAPISTORE_SUCCESS; rc = MAPISTORE_SUCCESS;
} }
@ -792,7 +790,7 @@ rtf2html (NSData *compressedRTF)
- (int) getPidTagOriginalMessageClass: (void **) data - (int) getPidTagOriginalMessageClass: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
return [self getPidTagMessageClass: data inMemCtx: memCtx]; return [self getProperty: data withTag: PidTagMessageClass inMemCtx: memCtx];
} }
- (int) getPidTagHasAttachments: (void **) data - (int) getPidTagHasAttachments: (void **) data

View file

@ -28,6 +28,7 @@
@interface MAPIStoreMessageTable : MAPIStoreTable @interface MAPIStoreMessageTable : MAPIStoreTable
- (void) setSortOrder: (const struct SSortOrderSet *) set; - (void) setSortOrder: (const struct SSortOrderSet *) set;
- (void) notifyChangesForChild: (MAPIStoreMessage *) child;
@end @end

View file

@ -27,6 +27,7 @@
#import <SOGo/SOGoFolder.h> #import <SOGo/SOGoFolder.h>
#import <SOGo/SOGoObject.h> #import <SOGo/SOGoObject.h>
#import "MAPIStoreContext.h"
#import "MAPIStoreFolder.h" #import "MAPIStoreFolder.h"
#import "MAPIStoreTypes.h" #import "MAPIStoreTypes.h"
#import "NSData+MAPIStore.h" #import "NSData+MAPIStore.h"
@ -83,4 +84,60 @@
return [(MAPIStoreFolder *) container lookupMessage: childKey]; return [(MAPIStoreFolder *) container lookupMessage: childKey];
} }
- (void) notifyChangesForChild: (MAPIStoreMessage *) child
{
NSUInteger currentChildRow, newChildRow;
NSArray *list;
NSString *childName;
struct mapistore_table_notification_parameters notif_parameters;
struct mapistore_context *mstoreCtx;
mstoreCtx = [[(MAPIStoreFolder *) container context]
connectionInfo]->mstore_ctx;
notif_parameters.table_type = tableType;
notif_parameters.handle = handleId;
notif_parameters.folder_id = [(MAPIStoreFolder *) container objectId];
notif_parameters.object_id = [child objectId];
notif_parameters.instance_id = 0; /* TODO: always 0 ? */
childName = [child nameInContainer];
list = [self restrictedChildKeys];
currentChildRow = [list indexOfObject: childName];
notif_parameters.row_id = currentChildRow;
[self cleanupCaches];
list = [self restrictedChildKeys];
newChildRow = [list indexOfObject: childName];
if (currentChildRow == NSNotFound)
{
if (newChildRow != NSNotFound)
{
notif_parameters.row_id = newChildRow;
mapistore_push_notification (mstoreCtx,
MAPISTORE_TABLE,
MAPISTORE_OBJECT_CREATED,
&notif_parameters);
}
}
else
{
if (newChildRow == NSNotFound)
mapistore_push_notification (mstoreCtx,
MAPISTORE_TABLE,
MAPISTORE_OBJECT_DELETED,
&notif_parameters);
else
{
/* the fact that the row order has changed has no impact here */
notif_parameters.row_id = newChildRow;
mapistore_push_notification (mstoreCtx,
MAPISTORE_TABLE,
MAPISTORE_OBJECT_MODIFIED,
&notif_parameters);
}
}
}
@end @end

View file

@ -23,9 +23,9 @@
#ifndef MAPISTORENOTESCONTEXT_H #ifndef MAPISTORENOTESCONTEXT_H
#define MAPISTORENOTESCONTEXT_H #define MAPISTORENOTESCONTEXT_H
#import "MAPIStoreFSBaseContext.h" #import "MAPIStoreDBBaseContext.h"
@interface MAPIStoreNotesContext : MAPIStoreFSBaseContext @interface MAPIStoreNotesContext : MAPIStoreDBBaseContext
@end @end

View file

@ -23,9 +23,9 @@
#ifndef MAPISTORENOTESFOLDER_H #ifndef MAPISTORENOTESFOLDER_H
#define MAPISTORENOTESFOLDER_H #define MAPISTORENOTESFOLDER_H
#import "MAPIStoreFSFolder.h" #import "MAPIStoreDBFolder.h"
@interface MAPIStoreNotesFolder : MAPIStoreFSFolder @interface MAPIStoreNotesFolder : MAPIStoreDBFolder
@end @end
#endif /* MAPISTORENOTESFOLDER_H */ #endif /* MAPISTORENOTESFOLDER_H */

View file

@ -23,9 +23,9 @@
#ifndef MAPISTORENOTESMESSAGE_H #ifndef MAPISTORENOTESMESSAGE_H
#define MAPISTORENOTESMESSAGE_H #define MAPISTORENOTESMESSAGE_H
#import "MAPIStoreFSMessage.h" #import "MAPIStoreDBMessage.h"
@interface MAPIStoreNotesMessage : MAPIStoreFSMessage @interface MAPIStoreNotesMessage : MAPIStoreDBMessage
@end @end
#endif /* MAPISTORENOTESMESSAGE_H */ #endif /* MAPISTORENOTESMESSAGE_H */

View file

@ -53,21 +53,4 @@
return MAPISTORE_SUCCESS; return MAPISTORE_SUCCESS;
} }
- (int) getPidTagSubject: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
id value;
int rc;
value = [[sogoObject properties]
objectForKey: MAPIPropertyKey (PidTagNormalizedSubject)];
if (value)
rc = [value getValue: data forTag: PidTagNormalizedSubject
inMemCtx: memCtx];
else
rc = MAPISTORE_ERR_NOT_FOUND;
return rc;
}
@end @end

View file

@ -33,56 +33,38 @@
@class NSMutableArray; @class NSMutableArray;
@class NSMutableDictionary; @class NSMutableDictionary;
@class EOQualifier;
@class MAPIStoreContext; @class MAPIStoreContext;
@class MAPIStoreFolder;
@class MAPIStoreMapping; @class MAPIStoreMapping;
@class MAPIStoreTable;
@class MAPIStoreUserContext; @class MAPIStoreUserContext;
@class MAPIStoreSOGoObject;
@interface MAPIStoreObject : NSObject @interface MAPIStoreObject : NSObject
{ {
const IMP *classGetters; const IMP *classGetters;
NSMutableArray *parentContainersBag; NSMutableArray *parentContainersBag;
MAPIStoreObject *container; id container;
id sogoObject;
NSMutableDictionary *properties; NSMutableDictionary *properties;
BOOL isNew;
} }
+ (id) mapiStoreObjectWithSOGoObject: (id) newSOGoObject + (id) mapiStoreObjectInContainer: (MAPIStoreObject *) newContainer;
inContainer: (MAPIStoreObject *) newContainer; - (id) initInContainer: (MAPIStoreObject *) newContainer;
+ (int) getAvailableProperties: (struct SPropTagArray **) propertiesP + (int) getAvailableProperties: (struct SPropTagArray **) propertiesP
inMemCtx: (TALLOC_CTX *) memCtx; inMemCtx: (TALLOC_CTX *) memCtx;
- (id) initWithSOGoObject: (id) newSOGoObject
inContainer: (MAPIStoreObject *) newFolder;
- (void) setIsNew: (BOOL) newIsNew;
- (BOOL) isNew;
- (NSString *) nameInContainer;
- (id) sogoObject;
- (MAPIStoreObject *) container; - (MAPIStoreObject *) container;
- (MAPIStoreContext *) context; - (MAPIStoreContext *) context;
- (MAPIStoreUserContext *) userContext; - (MAPIStoreUserContext *) userContext;
- (MAPIStoreMapping *) mapping; - (MAPIStoreMapping *) mapping;
- (void) cleanupCaches;
- (uint64_t) objectId;
- (NSString *) url;
/* properties */ /* properties */
- (BOOL) canGetProperty: (enum MAPITAGS) propTag; - (BOOL) canGetProperty: (enum MAPITAGS) propTag;
- (void) addProperties: (NSDictionary *) newProperties; - (void) addProperties: (NSDictionary *) newProperties;
- (NSDictionary *) properties; - (NSMutableDictionary *) properties;
/* ops */ /* ops */
- (int) getAvailableProperties: (struct SPropTagArray **) propertiesP - (int) getAvailableProperties: (struct SPropTagArray **) propertiesP
@ -104,26 +86,12 @@
fromGlobCnt: (uint64_t) objectCnt fromGlobCnt: (uint64_t) objectCnt
inMemCtx: (TALLOC_CTX *) memCtx; inMemCtx: (TALLOC_CTX *) memCtx;
/* implemented getters */
- (int) getPidTagDisplayName: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidTagSearchKey: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidTagGenerateExchangeViews: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidTagParentSourceKey: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidTagSourceKey: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidTagChangeKey: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidTagCreationTime: (void **) data - (int) getPidTagCreationTime: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx; inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidTagLastModificationTime: (void **) data - (int) getPidTagLastModificationTime: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx; inMemCtx: (TALLOC_CTX *) memCtx;
/* subclasses */ /* subclasses */
- (uint64_t) objectVersion;
- (NSDate *) creationTime; - (NSDate *) creationTime;
- (NSDate *) lastModificationTime; - (NSDate *) lastModificationTime;

View file

@ -58,13 +58,11 @@ static Class NSExceptionK, MAPIStoreFolderK;
MAPIStoreFolderK = [MAPIStoreFolder class]; MAPIStoreFolderK = [MAPIStoreFolder class];
} }
+ (id) mapiStoreObjectWithSOGoObject: (id) newSOGoObject + (id) mapiStoreObjectInContainer: (MAPIStoreObject *) newContainer
inContainer: (MAPIStoreObject *) newContainer
{ {
id newObject; id newObject;
newObject = [[self alloc] initWithSOGoObject: newSOGoObject newObject = [[self alloc] initInContainer: newContainer];
inContainer: newContainer];
[newObject autorelease]; [newObject autorelease];
return newObject; return newObject;
@ -106,22 +104,18 @@ static Class NSExceptionK, MAPIStoreFolderK;
classGetters = (IMP *) MAPIStorePropertyGettersForClass (isa); classGetters = (IMP *) MAPIStorePropertyGettersForClass (isa);
parentContainersBag = [NSMutableArray new]; parentContainersBag = [NSMutableArray new];
container = nil; container = nil;
sogoObject = nil;
properties = [NSMutableDictionary new]; properties = [NSMutableDictionary new];
isNew = NO;
} }
[self logWithFormat: @"-init"]; // [self logWithFormat: @"-init"];
return self; return self;
} }
- (id) initWithSOGoObject: (id) newSOGoObject - (id) initInContainer: (MAPIStoreObject *) newContainer
inContainer: (MAPIStoreObject *) newContainer
{ {
if ((self = [self init])) if ((self = [self init]))
{ {
ASSIGN (sogoObject, newSOGoObject);
ASSIGN (container, newContainer); ASSIGN (container, newContainer);
} }
@ -130,42 +124,21 @@ static Class NSExceptionK, MAPIStoreFolderK;
- (void) dealloc - (void) dealloc
{ {
[self logWithFormat: @"-dealloc"]; // [self logWithFormat: @"-dealloc"];
[sogoObject release];
[properties release]; [properties release];
[parentContainersBag release]; [parentContainersBag release];
[container release]; [container release];
[super dealloc]; [super dealloc];
} }
- (void) setIsNew: (BOOL) newIsNew
{
isNew = newIsNew;
}
- (BOOL) isNew
{
return isNew;
}
- (id) sogoObject
{
return sogoObject;
}
- (MAPIStoreObject *) container - (MAPIStoreObject *) container
{ {
return container; return container;
} }
- (NSString *) nameInContainer
{
return [sogoObject nameInContainer];
}
- (MAPIStoreContext *) context - (MAPIStoreContext *) context
{ {
return [container context]; return (MAPIStoreContext *) [container context];
} }
- (MAPIStoreUserContext *) userContext - (MAPIStoreUserContext *) userContext
@ -178,47 +151,14 @@ static Class NSExceptionK, MAPIStoreFolderK;
return [[self userContext] mapping]; return [[self userContext] mapping];
} }
- (void) cleanupCaches
{
}
/* helpers */ /* helpers */
- (uint64_t) objectId
{
uint64_t objectId;
if ([container isKindOfClass: MAPIStoreFolderK])
objectId = [(MAPIStoreFolder *) container
idForObjectWithKey: [sogoObject nameInContainer]];
else
{
[self errorWithFormat: @"%s: container is not a folder", __PRETTY_FUNCTION__];
objectId = (uint64_t) -1;
}
return objectId;
}
- (NSString *) url
{
NSString *containerURL, *format;
containerURL = [container url];
if ([containerURL hasSuffix: @"/"])
format = @"%@%@";
else
format = @"%@/%@";
return [NSString stringWithFormat: format,
containerURL, [self nameInContainer]];
}
- (void) addProperties: (NSDictionary *) newNewProperties - (void) addProperties: (NSDictionary *) newNewProperties
{ {
[properties addEntriesFromDictionary: newNewProperties]; [properties addEntriesFromDictionary: newNewProperties];
} }
- (NSDictionary *) properties - (NSMutableDictionary *) properties
{ {
return properties; return properties;
} }
@ -248,124 +188,8 @@ static Class NSExceptionK, MAPIStoreFolderK;
return rc; return rc;
} }
/* helper getters */
- (NSData *) getReplicaKeyFromGlobCnt: (uint64_t) objectCnt
{
struct mapistore_connection_info *connInfo;
NSMutableData *replicaKey;
char buffer[6];
NSUInteger count;
connInfo = [[self context] connectionInfo];
for (count = 0; count < 6; count++)
{
buffer[count] = objectCnt & 0xff;
objectCnt >>= 8;
}
replicaKey = [NSMutableData dataWithCapacity: 22];
[replicaKey appendBytes: &connInfo->replica_guid
length: sizeof (struct GUID)];
[replicaKey appendBytes: buffer length: 6];
return replicaKey;
}
- (int) getReplicaKey: (void **) data
fromGlobCnt: (uint64_t) objectCnt
inMemCtx: (TALLOC_CTX *) memCtx
{
*data = [[self getReplicaKeyFromGlobCnt: objectCnt] asBinaryInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
/* getters */
- (int) getPidTagDisplayName: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
*data = [[sogoObject displayName] asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPidTagSearchKey: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
NSString *stringValue;
stringValue = [sogoObject nameInContainer];
*data = [[stringValue dataUsingEncoding: NSASCIIStringEncoding]
asBinaryInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPidTagGenerateExchangeViews: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getNo: data inMemCtx: memCtx];
}
- (int) getPidTagParentSourceKey: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getReplicaKey: data fromGlobCnt: [container objectId] >> 16
inMemCtx: memCtx];
}
- (int) getPidTagSourceKey: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getReplicaKey: data fromGlobCnt: [self objectId] >> 16
inMemCtx: memCtx];
}
- (uint64_t) objectVersion
{
[self subclassResponsibility: _cmd];
return ULLONG_MAX;
}
- (int) getPidTagChangeKey: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
int rc;
uint64_t obVersion;
obVersion = [self objectVersion];
if (obVersion == ULLONG_MAX)
rc = MAPISTORE_ERR_NOT_FOUND;
else
rc = [self getReplicaKey: data fromGlobCnt: obVersion
inMemCtx: memCtx];
return rc;
}
- (int) getPidTagChangeNumber: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
int rc;
uint64_t obVersion;
obVersion = [self objectVersion];
if (obVersion == ULLONG_MAX)
rc = MAPISTORE_ERR_NOT_FOUND;
else
{
*data = MAPILongLongValue (memCtx, ((obVersion << 16)
| 0x0001));
rc = MAPISTORE_SUCCESS;
}
return rc;
}
- (int) getPidTagCreationTime: (void **) data - (int) getPidTagCreationTime: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx inMemCtx: (TALLOC_CTX *) memCtx
{ {
*data = [[self creationTime] asFileTimeInMemCtx: memCtx]; *data = [[self creationTime] asFileTimeInMemCtx: memCtx];
@ -474,6 +298,38 @@ static Class NSExceptionK, MAPIStoreFolderK;
return MAPISTORE_SUCCESS; return MAPISTORE_SUCCESS;
} }
- (NSData *) getReplicaKeyFromGlobCnt: (uint64_t) objectCnt
{
struct mapistore_connection_info *connInfo;
NSMutableData *replicaKey;
char buffer[6];
NSUInteger count;
connInfo = [[self context] connectionInfo];
for (count = 0; count < 6; count++)
{
buffer[count] = objectCnt & 0xff;
objectCnt >>= 8;
}
replicaKey = [NSMutableData dataWithCapacity: 22];
[replicaKey appendBytes: &connInfo->replica_guid
length: sizeof (struct GUID)];
[replicaKey appendBytes: buffer length: 6];
return replicaKey;
}
- (int) getReplicaKey: (void **) data
fromGlobCnt: (uint64_t) objectCnt
inMemCtx: (TALLOC_CTX *) memCtx
{
*data = [[self getReplicaKeyFromGlobCnt: objectCnt] asBinaryInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
/* subclasses */ /* subclasses */
- (NSDate *) creationTime - (NSDate *) creationTime
{ {

View file

@ -50,7 +50,7 @@
MAPIStorePermissionEntry *newEntry; MAPIStorePermissionEntry *newEntry;
newEntry = [[self alloc] initWithUserId: newUserId andMemberId: newMemberId newEntry = [[self alloc] initWithUserId: newUserId andMemberId: newMemberId
forFolder: newFolder]; forFolder: newFolder];
[newEntry autorelease]; [newEntry autorelease];
return newEntry; return newEntry;
@ -60,7 +60,7 @@
andMemberId: (uint64_t) newMemberId andMemberId: (uint64_t) newMemberId
forFolder: (MAPIStoreFolder *) newFolder forFolder: (MAPIStoreFolder *) newFolder
{ {
if ((self = [self initWithSOGoObject: nil inContainer: newFolder])) if ((self = [self initInContainer: newFolder]))
{ {
ASSIGN (userId, newUserId); ASSIGN (userId, newUserId);
memberId = newMemberId; memberId = newMemberId;

View file

@ -23,10 +23,14 @@
#ifndef MAPISTORERECURRENCEUTILS_H #ifndef MAPISTORERECURRENCEUTILS_H
#define MAPISTORERECURRENCEUTILS_H #define MAPISTORERECURRENCEUTILS_H
#include <talloc.h>
#import <NGCards/iCalCalendar.h> #import <NGCards/iCalCalendar.h>
#import <NGCards/iCalRecurrenceRule.h> #import <NGCards/iCalRecurrenceRule.h>
@class NSCalendarDate; @class NSTimeZone;
@class iCalEvent;
@class iCalRepeatableEntityObject; @class iCalRepeatableEntityObject;
@class iCalRecurrenceRule; @class iCalRecurrenceRule;
@ -44,8 +48,9 @@
@interface iCalRecurrenceRule (MAPIStoreRecurrence) @interface iCalRecurrenceRule (MAPIStoreRecurrence)
- (void) fillRecurrencePattern: (struct RecurrencePattern *) rp - (void) fillRecurrencePattern: (struct RecurrencePattern *) rp
withStartDate: (NSCalendarDate *) startDate withEvent: (iCalEvent *) event
andEndDate: (NSCalendarDate *) endDate; inTimeZone: (NSTimeZone *) timeZone
inMemCtx: (TALLOC_CTX *) memCtx;
@end @end

View file

@ -21,17 +21,22 @@
*/ */
#import <Foundation/NSArray.h> #import <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSString.h> #import <Foundation/NSString.h>
#import <NGExtensions/NSCalendarDate+misc.h> #import <NGExtensions/NSCalendarDate+misc.h>
#import <NGExtensions/NSObject+Logs.h> #import <NGExtensions/NSObject+Logs.h>
#import <NGCards/iCalByDayMask.h>
#import <NGCards/iCalDateTime.h>
#import <NGCards/iCalEvent.h>
#import <NGCards/iCalRepeatableEntityObject.h> #import <NGCards/iCalRepeatableEntityObject.h>
#import <NGCards/iCalRecurrenceRule.h> #import <NGCards/iCalRecurrenceRule.h>
#import <NGCards/iCalByDayMask.h> #import <NGCards/iCalTimeZone.h>
#import "NSDate+MAPIStore.h" #import "NSDate+MAPIStore.h"
#import "MAPIStoreRecurrenceUtils.h" #import "MAPIStoreRecurrenceUtils.h"
#import "MAPIStoreTypes.h"
#include <stdbool.h> #include <stdbool.h>
#include <talloc.h> #include <talloc.h>
@ -43,7 +48,7 @@
- (void) setupRecurrenceWithMasterEntity: (iCalRepeatableEntityObject *) entity - (void) setupRecurrenceWithMasterEntity: (iCalRepeatableEntityObject *) entity
fromRecurrencePattern: (struct RecurrencePattern *) rp fromRecurrencePattern: (struct RecurrencePattern *) rp
{ {
NSCalendarDate *startDate, *olEndDate, *untilDate; NSCalendarDate *startDate, *olEndDate, *untilDate, *exDate;
NSString *monthDay, *month; NSString *monthDay, *month;
iCalRecurrenceRule *rule; iCalRecurrenceRule *rule;
iCalByDayMask *byDayMask; iCalByDayMask *byDayMask;
@ -203,6 +208,17 @@
[self errorWithFormat: @"invalid value for EndType: %.4x", [self errorWithFormat: @"invalid value for EndType: %.4x",
rp->EndType]; rp->EndType];
} }
/* exception dates */
for (count = 0; count < rp->DeletedInstanceCount; count++)
{
exDate
= [NSDate dateFromMinutesSince1601: rp->DeletedInstanceDates[count]];
exDate = [exDate hour: [startDate hourOfDay]
minute: [startDate minuteOfHour]
second: [startDate secondOfMinute]];
[entity addToExceptionDates: exDate];
}
} }
@end @end
@ -210,17 +226,24 @@
@implementation iCalRecurrenceRule (MAPIStoreRecurrence) @implementation iCalRecurrenceRule (MAPIStoreRecurrence)
- (void) fillRecurrencePattern: (struct RecurrencePattern *) rp - (void) fillRecurrencePattern: (struct RecurrencePattern *) rp
withStartDate: (NSCalendarDate *) startDate withEvent: (iCalEvent *) event
andEndDate: (NSCalendarDate *) endDate inTimeZone: (NSTimeZone *) timeZone
inMemCtx: (TALLOC_CTX *) memCtx
{ {
iCalRecurrenceFrequency freq; iCalRecurrenceFrequency freq;
iCalByDayMask *byDayMask; iCalByDayMask *byDayMask;
NSString *byMonthDay, *bySetPos; NSString *byMonthDay, *bySetPos;
NSCalendarDate *untilDate, *beginOfWeek, *minimumDate, *moduloDate, *midnight; NSCalendarDate *startDate, *endDate, *untilDate, *beginOfWeek, *minimumDate, *moduloDate, *midnight;
iCalWeekOccurrences *days; iCalWeekOccurrences *days;
NSInteger dayOfWeek, repeatInterval, repeatCount, count, firstOccurrence; NSInteger dayOfWeek, repeatInterval, repeatCount, count, firstOccurrence, max;
uint32_t nbrMonths, mask; uint32_t nbrMonths, mask;
NSArray *exDates;
startDate = [event firstRecurrenceStartDate];
[startDate setTimeZone: timeZone];
endDate = [event lastPossibleRecurrenceStartDate];
[endDate setTimeZone: timeZone];
rp->ReaderVersion = 0x3004; rp->ReaderVersion = 0x3004;
rp->WriterVersion = 0x3004; rp->WriterVersion = 0x3004;
@ -370,6 +393,19 @@
[self errorWithFormat: @"rule for an event that never occurs"]; [self errorWithFormat: @"rule for an event that never occurs"];
} }
} }
exDates = [[event exceptionDatesWithTimeZone: utcTZ]
sortedArrayUsingFunction: NSDateCompare
context: NULL];
max = [exDates count];
rp->DeletedInstanceCount = max;
rp->DeletedInstanceDates = talloc_array (memCtx, uint32_t, max);
for (count = 0; count < max; count++)
{
startDate = [[exDates objectAtIndex: count] hour: 0 minute: 0 second: 0];
*(rp->DeletedInstanceDates + count) = [startDate asMinutesSince1601];
}
} }
@end @end

View file

@ -273,7 +273,7 @@ sogo_context_get_path(void *backend_object, TALLOC_CTX *mem_ctx,
if (backend_object) if (backend_object)
{ {
wrapper = backend_object; wrapper = backend_object;
context = wrapper->MAPIStoreSOGoObject; context = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [context getPath: path ofFMID: fmid inMemCtx: mem_ctx]; rc = [context getPath: path ofFMID: fmid inMemCtx: mem_ctx];
@ -303,7 +303,7 @@ sogo_context_get_root_folder(void *backend_object, TALLOC_CTX *mem_ctx,
if (backend_object) if (backend_object)
{ {
wrapper = backend_object; wrapper = backend_object;
context = wrapper->MAPIStoreSOGoObject; context = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [context getRootFolder: &folder withFID: fid]; rc = [context getRootFolder: &folder withFID: fid];
@ -342,7 +342,7 @@ sogo_folder_open_folder(void *folder_object, TALLOC_CTX *mem_ctx, uint64_t fid,
if (folder_object) if (folder_object)
{ {
wrapper = folder_object; wrapper = folder_object;
folder = wrapper->MAPIStoreSOGoObject; folder = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [folder openFolder: &childFolder withFID: fid]; rc = [folder openFolder: &childFolder withFID: fid];
@ -382,7 +382,7 @@ sogo_folder_create_folder(void *folder_object, TALLOC_CTX *mem_ctx,
if (folder_object) if (folder_object)
{ {
wrapper = folder_object; wrapper = folder_object;
folder = wrapper->MAPIStoreSOGoObject; folder = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [folder createFolder: &childFolder withRow: aRow andFID: fid]; rc = [folder createFolder: &childFolder withRow: aRow andFID: fid];
@ -421,7 +421,7 @@ sogo_folder_delete(void *folder_object)
if (folder_object) if (folder_object)
{ {
wrapper = folder_object; wrapper = folder_object;
folder = wrapper->MAPIStoreSOGoObject; folder = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [folder deleteFolder]; rc = [folder deleteFolder];
@ -449,7 +449,7 @@ sogo_folder_get_child_count(void *folder_object, enum mapistore_table_type table
if (folder_object) if (folder_object)
{ {
wrapper = folder_object; wrapper = folder_object;
folder = wrapper->MAPIStoreSOGoObject; folder = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [folder getChildCount: child_count ofTableType: table_type]; rc = [folder getChildCount: child_count ofTableType: table_type];
@ -481,7 +481,7 @@ sogo_folder_open_message(void *folder_object,
if (folder_object) if (folder_object)
{ {
wrapper = folder_object; wrapper = folder_object;
folder = wrapper->MAPIStoreSOGoObject; folder = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [folder openMessage: &message rc = [folder openMessage: &message
@ -519,7 +519,7 @@ sogo_folder_create_message(void *folder_object,
if (folder_object) if (folder_object)
{ {
wrapper = folder_object; wrapper = folder_object;
folder = wrapper->MAPIStoreSOGoObject; folder = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [folder createMessage: &message rc = [folder createMessage: &message
@ -551,7 +551,7 @@ sogo_folder_delete_message(void *folder_object, uint64_t mid, uint8_t flags)
if (folder_object) if (folder_object)
{ {
wrapper = folder_object; wrapper = folder_object;
folder = wrapper->MAPIStoreSOGoObject; folder = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [folder deleteMessageWithMID: mid andFlags: flags]; rc = [folder deleteMessageWithMID: mid andFlags: flags];
@ -584,10 +584,10 @@ sogo_folder_move_copy_messages(void *folder_object,
if (folder_object) if (folder_object)
{ {
wrapper = folder_object; wrapper = folder_object;
targetFolder = wrapper->MAPIStoreSOGoObject; targetFolder = wrapper->instance;
wrapper = source_folder_object; wrapper = source_folder_object;
sourceFolder = wrapper->MAPIStoreSOGoObject; sourceFolder = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
@ -623,7 +623,7 @@ sogo_folder_get_deleted_fmids(void *folder_object, TALLOC_CTX *mem_ctx,
if (folder_object) if (folder_object)
{ {
wrapper = folder_object; wrapper = folder_object;
folder = wrapper->MAPIStoreSOGoObject; folder = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [folder getDeletedFMIDs: fmidsp rc = [folder getDeletedFMIDs: fmidsp
@ -658,7 +658,7 @@ sogo_folder_open_table(void *folder_object, TALLOC_CTX *mem_ctx,
if (folder_object) if (folder_object)
{ {
wrapper = folder_object; wrapper = folder_object;
folder = wrapper->MAPIStoreSOGoObject; folder = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [folder getTable: &table rc = [folder getTable: &table
@ -693,7 +693,7 @@ sogo_folder_modify_permissions(void *folder_object, uint8_t flags,
if (folder_object) if (folder_object)
{ {
wrapper = folder_object; wrapper = folder_object;
folder = wrapper->MAPIStoreSOGoObject; folder = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [folder modifyPermissions: permissions rc = [folder modifyPermissions: permissions
@ -725,7 +725,7 @@ sogo_message_get_message_data(void *message_object,
if (message_object) if (message_object)
{ {
wrapper = message_object; wrapper = message_object;
message = wrapper->MAPIStoreSOGoObject; message = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
[message getMessageData: msg_dataP [message getMessageData: msg_dataP
@ -756,7 +756,7 @@ sogo_message_create_attachment (void *message_object, TALLOC_CTX *mem_ctx, void
if (message_object) if (message_object)
{ {
wrapper = message_object; wrapper = message_object;
message = wrapper->MAPIStoreSOGoObject; message = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [message createAttachment: &attachment inAID: aidp]; rc = [message createAttachment: &attachment inAID: aidp];
@ -789,7 +789,7 @@ sogo_message_open_attachment (void *message_object, TALLOC_CTX *mem_ctx,
if (message_object) if (message_object)
{ {
wrapper = message_object; wrapper = message_object;
message = wrapper->MAPIStoreSOGoObject; message = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [message getAttachment: &attachment withAID: aid]; rc = [message getAttachment: &attachment withAID: aid];
@ -821,7 +821,7 @@ sogo_message_get_attachment_table (void *message_object, TALLOC_CTX *mem_ctx, vo
if (message_object) if (message_object)
{ {
wrapper = message_object; wrapper = message_object;
message = wrapper->MAPIStoreSOGoObject; message = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [message getAttachmentTable: &table rc = [message getAttachmentTable: &table
@ -856,7 +856,7 @@ sogo_message_modify_recipients (void *message_object,
if (message_object) if (message_object)
{ {
wrapper = message_object; wrapper = message_object;
message = wrapper->MAPIStoreSOGoObject; message = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [message modifyRecipientsWithRecipients: recipients rc = [message modifyRecipientsWithRecipients: recipients
@ -887,7 +887,7 @@ sogo_message_set_read_flag (void *message_object, uint8_t flag)
if (message_object) if (message_object)
{ {
wrapper = message_object; wrapper = message_object;
message = wrapper->MAPIStoreSOGoObject; message = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [message setReadFlag: flag]; rc = [message setReadFlag: flag];
@ -916,7 +916,7 @@ sogo_message_save (void *message_object)
if (message_object) if (message_object)
{ {
wrapper = message_object; wrapper = message_object;
message = wrapper->MAPIStoreSOGoObject; message = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [message saveMessage]; rc = [message saveMessage];
@ -945,7 +945,7 @@ sogo_message_submit (void *message_object, enum SubmitFlags flags)
if (message_object) if (message_object)
{ {
wrapper = message_object; wrapper = message_object;
message = wrapper->MAPIStoreSOGoObject; message = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [message submitWithFlags: flags]; rc = [message submitWithFlags: flags];
@ -963,9 +963,8 @@ sogo_message_submit (void *message_object, enum SubmitFlags flags)
static enum mapistore_error static enum mapistore_error
sogo_message_attachment_open_embedded_message sogo_message_attachment_open_embedded_message
(void *attachment_object, (void *attachment_object, enum OpenEmbeddedMessage_OpenModeFlags mode,
TALLOC_CTX *mem_ctx, void **message_object, TALLOC_CTX *mem_ctx, void **message_object, uint64_t *midP,
uint64_t *midP,
struct mapistore_message **msg) struct mapistore_message **msg)
{ {
struct MAPIStoreTallocWrapper *wrapper; struct MAPIStoreTallocWrapper *wrapper;
@ -979,10 +978,11 @@ sogo_message_attachment_open_embedded_message
if (attachment_object) if (attachment_object)
{ {
wrapper = attachment_object; wrapper = attachment_object;
attachment = wrapper->MAPIStoreSOGoObject; attachment = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [attachment openEmbeddedMessage: &message rc = [attachment openEmbeddedMessage: &message
inMode: mode
withMID: midP withMID: midP
withMAPIStoreMsg: msg withMAPIStoreMsg: msg
inMemCtx: mem_ctx]; inMemCtx: mem_ctx];
@ -1012,7 +1012,7 @@ static enum mapistore_error sogo_table_get_available_properties(void *table_obje
if (table_object) if (table_object)
{ {
wrapper = table_object; wrapper = table_object;
table = wrapper->MAPIStoreSOGoObject; table = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [table getAvailableProperties: propertiesP inMemCtx: mem_ctx]; rc = [table getAvailableProperties: propertiesP inMemCtx: mem_ctx];
@ -1040,7 +1040,7 @@ sogo_table_set_columns (void *table_object, uint16_t count, enum MAPITAGS *prope
if (table_object) if (table_object)
{ {
wrapper = table_object; wrapper = table_object;
table = wrapper->MAPIStoreSOGoObject; table = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [table setColumns: properties rc = [table setColumns: properties
@ -1069,7 +1069,7 @@ sogo_table_set_restrictions (void *table_object, struct mapi_SRestriction *restr
if (table_object) if (table_object)
{ {
wrapper = table_object; wrapper = table_object;
table = wrapper->MAPIStoreSOGoObject; table = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
[table setRestrictions: restrictions]; [table setRestrictions: restrictions];
@ -1100,7 +1100,7 @@ sogo_table_set_sort_order (void *table_object, struct SSortOrderSet *sort_order,
if (table_object) if (table_object)
{ {
wrapper = table_object; wrapper = table_object;
table = wrapper->MAPIStoreSOGoObject; table = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
[table setSortOrder: sort_order]; [table setSortOrder: sort_order];
@ -1133,7 +1133,7 @@ sogo_table_get_row (void *table_object, TALLOC_CTX *mem_ctx,
if (table_object) if (table_object)
{ {
wrapper = table_object; wrapper = table_object;
table = wrapper->MAPIStoreSOGoObject; table = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [table getRow: data withRowID: row_id andQueryType: query_type rc = [table getRow: data withRowID: row_id andQueryType: query_type
@ -1164,7 +1164,7 @@ sogo_table_get_row_count (void *table_object,
if (table_object) if (table_object)
{ {
wrapper = table_object; wrapper = table_object;
table = wrapper->MAPIStoreSOGoObject; table = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [table getRowCount: row_countp rc = [table getRowCount: row_countp
@ -1193,7 +1193,7 @@ sogo_table_handle_destructor (void *table_object, uint32_t handle_id)
if (table_object) if (table_object)
{ {
wrapper = table_object; wrapper = table_object;
table = wrapper->MAPIStoreSOGoObject; table = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
[table destroyHandle: handle_id]; [table destroyHandle: handle_id];
@ -1223,7 +1223,7 @@ static enum mapistore_error sogo_properties_get_available_properties(void *objec
if (object) if (object)
{ {
wrapper = object; wrapper = object;
propObject = wrapper->MAPIStoreSOGoObject; propObject = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [propObject getAvailableProperties: propertiesP inMemCtx: mem_ctx]; rc = [propObject getAvailableProperties: propertiesP inMemCtx: mem_ctx];
@ -1254,7 +1254,7 @@ sogo_properties_get_properties (void *object,
if (object) if (object)
{ {
wrapper = object; wrapper = object;
propObject = wrapper->MAPIStoreSOGoObject; propObject = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [propObject getProperties: data withTags: properties rc = [propObject getProperties: data withTags: properties
@ -1284,7 +1284,7 @@ sogo_properties_set_properties (void *object, struct SRow *aRow)
if (object) if (object)
{ {
wrapper = object; wrapper = object;
propObject = wrapper->MAPIStoreSOGoObject; propObject = wrapper->instance;
GSRegisterCurrentThread (); GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
rc = [propObject addPropertiesFromRow: aRow]; rc = [propObject addPropertiesFromRow: aRow];

View file

@ -0,0 +1,89 @@
/* MAPIStoreObject.h - this file is part of SOGo
*
* Copyright (C) 2011 Inverse inc
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef MAPISTORESOGOOBJECT_H
#define MAPISTORESOGOOBJECT_H
#include <talloc.h>
#import "MAPIStoreObject.h"
@class NSDate;
@class NSData;
@class NSString;
@class NSMutableArray;
@class NSMutableDictionary;
@class EOQualifier;
@class MAPIStoreContext;
@class MAPIStoreFolder;
@class MAPIStoreMapping;
@class MAPIStoreTable;
@class MAPIStoreUserContext;
@interface MAPIStoreSOGoObject : MAPIStoreObject
{
id sogoObject;
BOOL isNew;
}
+ (id) mapiStoreObjectWithSOGoObject: (id) newSOGoObject
inContainer: (MAPIStoreObject *) newContainer;
- (id) initWithSOGoObject: (id) newSOGoObject
inContainer: (MAPIStoreObject *) newFolder;
- (void) setIsNew: (BOOL) newIsNew;
- (BOOL) isNew;
- (id) sogoObject;
- (NSString *) nameInContainer;
- (MAPIStoreObject *) container;
- (void) cleanupCaches;
- (uint64_t) objectId;
- (NSString *) url;
/* implemented getters */
- (int) getPidTagDisplayName: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidTagSearchKey: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidTagGenerateExchangeViews: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidTagParentSourceKey: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidTagSourceKey: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidTagChangeKey: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
/* subclasses */
- (uint64_t) objectVersion;
@end
#endif /* MAPISTORESOGOOBJECT_H */

View file

@ -0,0 +1,255 @@
/* MAPIStoreObject.m - this file is part of SOGo
*
* Copyright (C) 2011 Inverse inc
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSTimeZone.h>
#import <NGExtensions/NSObject+Logs.h>
#import <SOGo/SOGoObject.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import "MAPIStoreContext.h"
#import "MAPIStoreFolder.h"
#import "MAPIStorePropertySelectors.h"
#import "MAPIStoreTypes.h"
#import "MAPIStoreUserContext.h"
#import "NSDate+MAPIStore.h"
#import "NSData+MAPIStore.h"
#import "NSObject+MAPIStore.h"
#import "NSString+MAPIStore.h"
#import "MAPIStoreSOGoObject.h"
#undef DEBUG
#include <stdbool.h>
#include <talloc.h>
#include <gen_ndr/exchange.h>
#include <mapistore/mapistore.h>
#include <mapistore/mapistore_errors.h>
@implementation MAPIStoreSOGoObject
static Class MAPIStoreFolderK;
+ (void) initialize
{
MAPIStoreFolderK = [MAPIStoreFolder class];
}
+ (id) mapiStoreObjectWithSOGoObject: (id) newSOGoObject
inContainer: (MAPIStoreObject *) newContainer
{
id newObject;
newObject = [[self alloc] initWithSOGoObject: newSOGoObject
inContainer: newContainer];
[newObject autorelease];
return newObject;
}
- (id) init
{
if ((self = [super init]))
{
sogoObject = nil;
isNew = NO;
}
[self logWithFormat: @"-init"];
return self;
}
- (id) initWithSOGoObject: (id) newSOGoObject
inContainer: (MAPIStoreObject *) newContainer
{
if ((self = [self initInContainer: newContainer]))
{
ASSIGN (sogoObject, newSOGoObject);
}
return self;
}
- (void) dealloc
{
// [self logWithFormat: @"-dealloc"];
[sogoObject release];
[super dealloc];
}
- (void) setIsNew: (BOOL) newIsNew
{
isNew = newIsNew;
}
- (BOOL) isNew
{
return isNew;
}
- (id) sogoObject
{
return sogoObject;
}
- (MAPIStoreObject *) container
{
return container;
}
- (NSString *) nameInContainer
{
return [sogoObject nameInContainer];
}
- (void) cleanupCaches
{
}
/* helpers */
- (uint64_t) objectId
{
uint64_t objectId;
if ([container isKindOfClass: MAPIStoreFolderK])
objectId = [(MAPIStoreFolder *) container
idForObjectWithKey: [sogoObject nameInContainer]];
else
{
[self errorWithFormat: @"%s: container is not a folder", __PRETTY_FUNCTION__];
objectId = (uint64_t) -1;
}
return objectId;
}
- (NSString *) url
{
NSString *containerURL, *format;
containerURL = (NSString *) [container url];
if ([containerURL hasSuffix: @"/"])
format = @"%@%@";
else
format = @"%@/%@";
return [NSString stringWithFormat: format,
containerURL, [self nameInContainer]];
}
/* getters */
- (int) getPidTagDisplayName: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
*data = [[sogoObject displayName] asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPidTagSearchKey: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
NSString *stringValue;
stringValue = [sogoObject nameInContainer];
*data = [[stringValue dataUsingEncoding: NSASCIIStringEncoding]
asBinaryInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPidTagGenerateExchangeViews: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getNo: data inMemCtx: memCtx];
}
- (int) getPidTagParentSourceKey: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getReplicaKey: data fromGlobCnt: [container objectId] >> 16
inMemCtx: memCtx];
}
- (int) getPidTagSourceKey: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getReplicaKey: data fromGlobCnt: [self objectId] >> 16
inMemCtx: memCtx];
}
/* helper getters */
- (int) getPidTagChangeKey: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
int rc;
uint64_t obVersion;
obVersion = [self objectVersion];
if (obVersion == ULLONG_MAX)
rc = MAPISTORE_ERR_NOT_FOUND;
else
rc = [self getReplicaKey: data fromGlobCnt: obVersion
inMemCtx: memCtx];
return rc;
}
- (int) getPidTagChangeNumber: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
int rc;
uint64_t obVersion;
obVersion = [self objectVersion];
if (obVersion == ULLONG_MAX)
rc = MAPISTORE_ERR_NOT_FOUND;
else
{
*data = MAPILongLongValue (memCtx, ((obVersion << 16)
| 0x0001));
rc = MAPISTORE_SUCCESS;
}
return rc;
}
/* subclasses */
- (uint64_t) objectVersion
{
[self subclassResponsibility: _cmd];
return ULLONG_MAX;
}
/* logging */
- (NSString *) loggingPrefix
{
return [NSString stringWithFormat:@"<%@:%p:%@>",
NSStringFromClass (isa), self, [self nameInContainer]];
}
@end

View file

@ -100,8 +100,6 @@ typedef enum {
- (int) getRowCount: (uint32_t *) countP - (int) getRowCount: (uint32_t *) countP
withQueryType: (enum mapistore_query_type) queryType; withQueryType: (enum mapistore_query_type) queryType;
- (void) notifyChangesForChild: (MAPIStoreObject *) child;
/* helpers */ /* helpers */
- (SEL) operatorFromRestrictionOperator: (uint32_t) resOp; - (SEL) operatorFromRestrictionOperator: (uint32_t) resOp;

View file

@ -874,61 +874,6 @@ static Class NSDataK, NSStringK;
return MAPISTORE_SUCCESS; return MAPISTORE_SUCCESS;
} }
- (void) notifyChangesForChild: (MAPIStoreObject *) child
{
NSUInteger currentChildRow, newChildRow;
NSArray *list;
NSString *childName;
struct mapistore_table_notification_parameters notif_parameters;
struct mapistore_context *mstoreCtx;
mstoreCtx = [[container context] connectionInfo]->mstore_ctx;
notif_parameters.table_type = tableType;
notif_parameters.handle = handleId;
notif_parameters.folder_id = [container objectId];
notif_parameters.object_id = [child objectId];
notif_parameters.instance_id = 0; /* TODO: always 0 ? */
childName = [child nameInContainer];
list = [self restrictedChildKeys];
currentChildRow = [list indexOfObject: childName];
notif_parameters.row_id = currentChildRow;
[self cleanupCaches];
list = [self restrictedChildKeys];
newChildRow = [list indexOfObject: childName];
if (currentChildRow == NSNotFound)
{
if (newChildRow != NSNotFound)
{
notif_parameters.row_id = newChildRow;
mapistore_push_notification (mstoreCtx,
MAPISTORE_TABLE,
MAPISTORE_OBJECT_CREATED,
&notif_parameters);
}
}
else
{
if (newChildRow == NSNotFound)
mapistore_push_notification (mstoreCtx,
MAPISTORE_TABLE,
MAPISTORE_OBJECT_DELETED,
&notif_parameters);
else
{
/* the fact that the row order has changed has no impact here */
notif_parameters.row_id = newChildRow;
mapistore_push_notification (mstoreCtx,
MAPISTORE_TABLE,
MAPISTORE_OBJECT_MODIFIED,
&notif_parameters);
}
}
}
/* subclasses */ /* subclasses */
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property - (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property
{ {

View file

@ -28,6 +28,7 @@
@class NSMutableDictionary; @class NSMutableDictionary;
@class NSString; @class NSString;
@class NSTimeZone; @class NSTimeZone;
@class NSURL;
@class WOContext; @class WOContext;
@ -52,6 +53,9 @@
MAPIStoreMapping *mapping; MAPIStoreMapping *mapping;
BOOL userDbTableExists;
NSURL *folderTableURL;
WOContext *woContext; WOContext *woContext;
MAPIStoreAuthenticator *authenticator; MAPIStoreAuthenticator *authenticator;
} }
@ -71,8 +75,11 @@
- (NSDictionary *) rootFolders; - (NSDictionary *) rootFolders;
- (NSURL *) folderTableURL;
- (MAPIStoreMapping *) mapping; - (MAPIStoreMapping *) mapping;
- (void) ensureFolderTableExists;
/* SOGo hacky magic */ /* SOGo hacky magic */
- (void) activateWithUser: (SOGoUser *) activeUser; - (void) activateWithUser: (SOGoUser *) activeUser;
- (MAPIStoreAuthenticator *) authenticator; - (MAPIStoreAuthenticator *) authenticator;

View file

@ -6,7 +6,7 @@
* *
* This file is free software; you can redistribute it and/or modify * This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 3, or (at your option)
* any later version. * any later version.
* *
* This file is distributed in the hope that it will be useful, * This file is distributed in the hope that it will be useful,
@ -23,17 +23,21 @@
#import <Foundation/NSDictionary.h> #import <Foundation/NSDictionary.h>
#import <Foundation/NSMapTable.h> #import <Foundation/NSMapTable.h>
#import <Foundation/NSThread.h> #import <Foundation/NSThread.h>
#import <Foundation/NSURL.h>
#import <NGObjWeb/WOContext.h> #import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WOContext+SoObjects.h> #import <NGObjWeb/WOContext+SoObjects.h>
#import <NGImap4/NGImap4Connection.h> #import <NGImap4/NGImap4Connection.h>
#import <GDLContentStore/GCSChannelManager.h>
#import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoUser.h> #import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserFolder.h> #import <SOGo/SOGoUserFolder.h>
#import <Mailer/SOGoMailAccount.h> #import <Mailer/SOGoMailAccount.h>
#import <Mailer/SOGoMailAccounts.h> #import <Mailer/SOGoMailAccounts.h>
#import "GCSSpecialQueries+OpenChange.h"
#import "MAPIApplication.h" #import "MAPIApplication.h"
#import "MAPIStoreAuthenticator.h" #import "MAPIStoreAuthenticator.h"
#import "MAPIStoreMapping.h" #import "MAPIStoreMapping.h"
@ -80,6 +84,9 @@ static NSMapTable *contextsTable = nil;
mapping = nil; mapping = nil;
userDbTableExists = NO;
folderTableURL = nil;
authenticator = nil; authenticator = nil;
woContext = [WOContext contextWithRequest: nil]; woContext = [WOContext contextWithRequest: nil];
[woContext retain]; [woContext retain];
@ -117,6 +124,8 @@ static NSMapTable *contextsTable = nil;
[authenticator release]; [authenticator release];
[mapping release]; [mapping release];
[folderTableURL release];
[sogoUser release]; [sogoUser release];
[contextsTable removeObjectForKey: username]; [contextsTable removeObjectForKey: username];
@ -213,6 +222,72 @@ static NSMapTable *contextsTable = nil;
return mapping; return mapping;
} }
/* OpenChange db table */
- (NSURL *) folderTableURL
{
NSString *urlString, *ocFSTableName;
NSMutableArray *parts;
SOGoUser *user;
if (!folderTableURL)
{
user = [self sogoUser];
urlString = [[user domainDefaults] folderInfoURL];
parts = [[urlString componentsSeparatedByString: @"/"]
mutableCopy];
[parts autorelease];
if ([parts count] == 5)
{
/* If "OCSFolderInfoURL" is properly configured, we must have 5
parts in this url. */
ocFSTableName = [NSString stringWithFormat: @"socfs_%@", username];
[parts replaceObjectAtIndex: 4 withObject: ocFSTableName];
folderTableURL
= [NSURL URLWithString: [parts componentsJoinedByString: @"/"]];
[folderTableURL retain];
}
else
[NSException raise: @"MAPIStoreIOException"
format: @"'OCSFolderInfoURL' is not set"];
}
return folderTableURL;
}
- (void) ensureFolderTableExists
{
GCSChannelManager *cm;
EOAdaptorChannel *channel;
NSString *tableName, *query;
GCSSpecialQueries *queries;
[self folderTableURL];
cm = [GCSChannelManager defaultChannelManager];
channel = [cm acquireOpenChannelForURL: folderTableURL];
/* FIXME: make use of [EOChannelAdaptor describeTableNames] instead */
tableName = [[folderTableURL path] lastPathComponent];
if ([channel evaluateExpressionX:
[NSString stringWithFormat: @"SELECT count(*) FROM %@",
tableName]])
{
queries = [channel specialQueries];
query = [queries createOpenChangeFSTableWithName: tableName];
if ([channel evaluateExpressionX: query])
[NSException raise: @"MAPIStoreIOException"
format: @"could not create special table '%@'", tableName];
}
else
[channel cancelFetch];
[cm releaseChannel: channel];
}
/* SOGo context objects */
- (WOContext *) woContext - (WOContext *) woContext
{ {
return woContext; return woContext;

View file

@ -1,208 +0,0 @@
/* MAPIStoreVolatileMessage.m - this file is part of SOGo
*
* Copyright (C) 2011 Inverse inc
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
#import <NGExtensions/NGHashMap.h>
#import <NGExtensions/NSObject+Logs.h>
#import <NGExtensions/NSString+Encoding.h>
#import <NGMail/NGMimeMessage.h>
#import <NGMail/NGMimeMessageGenerator.h>
#import <NGImap4/NGImap4Client.h>
#import <NGImap4/NGImap4Connection.h>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSCalendarDate+SOGo.h>
#import <SOGo/NSString+Utilities.h>
#import <Mailer/SOGoMailFolder.h>
#import <Mailer/NSString+Mail.h>
#import "MAPIStoreContext.h"
#import "MAPIStoreMailFolder.h"
#import "MAPIStoreMapping.h"
#import "MAPIStoreTypes.h"
#import "NSData+MAPIStore.h"
#import "NSObject+MAPIStore.h"
#import "NSString+MAPIStore.h"
#import "SOGoMAPIVolatileMessage.h"
#import "MAPIStoreVolatileMessage.h"
#undef DEBUG
#include <mapistore/mapistore.h>
#include <mapistore/mapistore_errors.h>
Class NSNumberK;
@implementation MAPIStoreVolatileMessage
+ (void) initialize
{
NSNumberK = [NSNumber class];
}
- (id) init
{
if ((self = [super init]))
{
fetchedAttachments = NO;
ASSIGN (creationTime, [NSDate date]);
lastModificationTime = [creationTime copy];
}
return self;
}
- (void) dealloc
{
[creationTime release];
[lastModificationTime release];
[super dealloc];
}
- (void) addProperties: (NSDictionary *) newProperties
{
[super addProperties: newProperties];
[sogoObject appendProperties: properties];
[properties removeAllObjects];
ASSIGN (lastModificationTime, [NSDate date]);
}
- (BOOL) canGetProperty: (enum MAPITAGS) propTag
{
return ([super canGetProperty: propTag]
|| [[sogoObject properties] objectForKey: MAPIPropertyKey (propTag)]);
}
- (uint64_t) objectVersion
{
NSNumber *version;
version = [[sogoObject properties] objectForKey: @"version"];
return (version
? exchange_globcnt ([version unsignedLongLongValue])
: ULLONG_MAX);
}
- (int) getProperty: (void **) data
withTag: (enum MAPITAGS) propTag
inMemCtx: (TALLOC_CTX *) memCtx
{
id value;
int rc;
value = [[sogoObject properties] objectForKey: MAPIPropertyKey (propTag)];
if (value)
rc = [value getValue: data forTag: propTag inMemCtx: memCtx];
else
rc = [super getProperty: data withTag: propTag inMemCtx: memCtx];
return rc;
}
- (int) getPidTagSubject: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
{
/* if we get here, it means that the properties file didn't contain a
relevant value */
return [self getEmptyString: data inMemCtx: memCtx];
}
- (int) getPidTagMessageClass: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
{
*data = [@"IPM.Note" asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPidTagChangeKey: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
{
NSData *changeKey;
int rc;
changeKey = [[sogoObject properties]
objectForKey: MAPIPropertyKey (PR_CHANGE_KEY)];
if (changeKey)
{
*data = [changeKey asBinaryInMemCtx: memCtx];
rc = MAPISTORE_SUCCESS;
}
else
rc = [super getPidTagChangeKey: data inMemCtx: memCtx];
return rc;
}
- (NSArray *) attachmentsKeysMatchingQualifier: (EOQualifier *) qualifier
andSortOrderings: (NSArray *) sortOrderings
{
NSDictionary *attachments;
NSArray *keys;
NSString *key, *newKey;
NSUInteger count, max, aid;
MAPIStoreAttachment *attachment;
if (!fetchedAttachments)
{
attachments = [[sogoObject properties] objectForKey: @"attachments"];
keys = [attachments allKeys];
max = [keys count];
if (max > 0)
{
aid = [keys count];
for (count = 0; count < max; count++)
{
key = [keys objectAtIndex: count];
attachment = [attachments objectForKey: key];
newKey = [NSString stringWithFormat: @"%ul", (aid + count)];
[attachmentParts setObject: attachment forKey: newKey];
}
}
fetchedAttachments = YES;
}
return [super attachmentKeysMatchingQualifier: qualifier
andSortOrderings: sortOrderings];
}
- (NSDate *) creationTime
{
return creationTime;
}
- (NSDate *) lastModificationTime
{
return lastModificationTime;
}
- (id) lookupAttachment: (NSString *) childKey
{
return [attachmentParts objectForKey: childKey];
}
- (void) save
{
[self subclassResponsibility: _cmd];
}
@end

View file

@ -25,9 +25,11 @@
#import <Foundation/NSDate.h> #import <Foundation/NSDate.h>
@class NSCalendarDate;
@interface NSDate (MAPIStoreDataTypes) @interface NSDate (MAPIStoreDataTypes)
+ (id) dateFromMinutesSince1601: (uint32_t) minutes; + (NSCalendarDate *) dateFromMinutesSince1601: (uint32_t) minutes;
- (uint32_t) asMinutesSince1601; - (uint32_t) asMinutesSince1601;
+ (id) dateFromFileTime: (const struct FILETIME *) timeValue; + (id) dateFromFileTime: (const struct FILETIME *) timeValue;
@ -37,4 +39,6 @@
@end @end
NSComparisonResult NSDateCompare (id date1, id date2, void *);
#endif /* NSCALENDARDATE+MAPISTORE_H */ #endif /* NSCALENDARDATE+MAPISTORE_H */

View file

@ -51,7 +51,7 @@ _setupRefDate ()
timeZone: [NSTimeZone timeZoneWithName: @"UTC"]]; timeZone: [NSTimeZone timeZoneWithName: @"UTC"]];
} }
+ (id) dateFromMinutesSince1601: (uint32_t) minutes + (NSCalendarDate *) dateFromMinutesSince1601: (uint32_t) minutes
{ {
NSCalendarDate *result; NSCalendarDate *result;
@ -129,3 +129,22 @@ _setupRefDate ()
} }
@end @end
NSComparisonResult
NSDateCompare (id date1, id date2, void *ctx)
{
NSTimeInterval secs1, secs2;
NSComparisonResult result;
secs1 = [date1 timeIntervalSince1970];
secs2 = [date2 timeIntervalSince1970];
if (secs1 == secs2)
result = NSOrderedSame;
else if (secs1 < secs2)
result = NSOrderedAscending;
else
result = NSOrderedDescending;
return result;
}

View file

@ -29,7 +29,7 @@
struct MAPIStoreTallocWrapper struct MAPIStoreTallocWrapper
{ {
id MAPIStoreSOGoObject; id instance;
}; };
@interface NSObject (MAPIStoreTallocHelpers) @interface NSObject (MAPIStoreTallocHelpers)

View file

@ -50,7 +50,7 @@ MAPIStoreTallocWrapperDestroy (void *data)
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
wrapper = data; wrapper = data;
// NSLog (@"destroying wrapped object (wrapper: %p; object: %p)...\n", wrapper, wrapper->MAPIStoreSOGoObject); // NSLog (@"destroying wrapped object (wrapper: %p; object: %p)...\n", wrapper, wrapper->MAPIStoreSOGoObject);
[wrapper->MAPIStoreSOGoObject release]; [wrapper->instance release];
[pool release]; [pool release];
GSUnregisterCurrentThread (); GSUnregisterCurrentThread ();
@ -63,7 +63,7 @@ MAPIStoreTallocWrapperDestroy (void *data)
wrapper = talloc_zero (tallocCtx, struct MAPIStoreTallocWrapper); wrapper = talloc_zero (tallocCtx, struct MAPIStoreTallocWrapper);
talloc_set_destructor ((void *) wrapper, MAPIStoreTallocWrapperDestroy); talloc_set_destructor ((void *) wrapper, MAPIStoreTallocWrapperDestroy);
wrapper->MAPIStoreSOGoObject = self; wrapper->instance = self;
[self retain]; [self retain];
// NSLog (@"returning wrapper: %p; object: %p", wrapper, self); // NSLog (@"returning wrapper: %p; object: %p", wrapper, self);

View file

@ -0,0 +1,182 @@
/* dbmsgdump.m - this file is part of SOGo
*
* Copyright (C) 2011 Inverse inc
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/* A format-agnostic property list dumper.
Usage: dbmsgdump [filename] */
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSData.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSProcessInfo.h>
#import <Foundation/NSPropertyList.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
#import <NGExtensions/NSNull+misc.h>
const char *indentationStep = " ";
@interface NSObject (plext)
- (void) displayWithIndentation: (NSInteger) anInt;
@end
@implementation NSObject (plext)
- (void) _outputIndentation: (NSInteger) anInt
{
NSInteger i;
for (i = 0; i < anInt; i++)
printf ("%s", indentationStep);
}
- (void) displayWithIndentation: (NSInteger) anInt
{
printf ("(%s) %s",
[NSStringFromClass (isa) UTF8String],
[[self description] UTF8String]);
}
@end
@implementation NSDictionary (plext)
- (void) displayKey: (NSString *) key
withIndentation: (NSInteger) anInt
{
[self _outputIndentation: anInt];
printf ("%s ", [[key description] UTF8String]);
if ([key isKindOfClass: [NSValue class]])
printf ("(%s: 0x%.8x) ", [(NSValue *) key objCType], [key intValue]);
printf ("= ");
}
- (void) displayWithIndentation: (NSInteger) anInt
{
NSUInteger i, max;
NSArray *keys;
NSInteger subIndent;
NSString *key;
keys = [self allKeys];
max = [keys count];
printf ("{ (%ld) items\n", (long) max);
subIndent = anInt + 1;
for (i = 0; i < max; i++)
{
key = [keys objectAtIndex: i];
[self displayKey: key withIndentation: subIndent];
[[self objectForKey: key] displayWithIndentation: subIndent];
if (i < (max - 1))
printf (",");
printf ("\n");
}
[self _outputIndentation: anInt];
printf ("}");
}
@end
@implementation NSArray (plext)
- (void) displayCount: (NSUInteger) count
withIndentation: (NSInteger) anInt
{
[self _outputIndentation: anInt];
printf ("%lu = ", (unsigned long) count);
}
- (void) displayWithIndentation: (NSInteger) anInt
{
NSUInteger i, max;
NSInteger subIndent;
max = [self count];
printf ("[ (%ld) items\n", (long) max);
subIndent = anInt + 1;
for (i = 0; i < max; i++)
{
[self displayCount: i withIndentation: subIndent];
[[self objectAtIndex: i] displayWithIndentation: subIndent];
if (i < (max - 1))
printf (",");
printf ("\n");
}
[self _outputIndentation: anInt];
printf ("]");
}
@end
static void
OCDumpPListData (NSData *content)
{
NSDictionary *d;
NSPropertyListFormat format;
NSString *error = nil;
const char *formatName;
d = [NSPropertyListSerialization propertyListFromData: content
mutabilityOption: NSPropertyListImmutable
format: &format
errorDescription: &error];
if (d)
{
switch (format)
{
case NSPropertyListOpenStepFormat:
formatName = "OpenStep";
break;
case NSPropertyListXMLFormat_v1_0:
formatName = "XML";
break;
case NSPropertyListBinaryFormat_v1_0:
formatName = "Binary";
break;
case NSPropertyListGNUstepFormat:
formatName = "GNUstep";
break;
case NSPropertyListGNUstepBinaryFormat:
formatName = "GNUstep binary";
break;
default: formatName = "unknown";
}
printf ("File format is: %s\n", formatName);
[d displayWithIndentation: 0];
printf ("\n");
}
else
printf ("an error occurred: %s\n", [error UTF8String]);
}

View file

@ -1,6 +1,6 @@
/* SOGoMAPIFSFolder.h - this file is part of SOGo /* SOGoMAPIDBFolder.h - this file is part of SOGo
* *
* Copyright (C) 2010 Inverse inc. * Copyright (C) 2012 Inverse inc.
* *
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca> * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
@ -20,41 +20,38 @@
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*/ */
#ifndef SOGOMAPIFSFOLDER_H #ifndef SOGOMAPIDBFOLDER_H
#define SOGOMAPIFSFOLDER_H #define SOGOMAPIDBFOLDER_H
#import <SOGo/SOGoFolder.h> #import "SOGoMAPIDBObject.h"
@class NSArray; @class NSArray;
@class NSMutableString;
@class NSString; @class NSString;
@class NSURL; @class NSURL;
@class EOQualifier; @class EOQualifier;
@class SOGoMAPIFSMessage; @class SOGoMAPIDBMessage;
@interface SOGoMAPIFSFolder : SOGoFolder @interface SOGoMAPIDBFolder : SOGoMAPIDBObject
{ {
NSString *directory; NSString *pathPrefix; /* for root folders */
BOOL directoryIsSane; SOGoMAPIDBObject *aclMessage;
} }
+ (id) folderWithURL: (NSURL *) url - (void) setPathPrefix: (NSString *) newPathPrefix;
andTableType: (uint8_t) tableType;
- (id) initWithURL: (NSURL *) url
andTableType: (uint8_t) tableType;
- (NSString *) directory; - (NSMutableString *) pathForChild: (NSString *) childName;
- (SOGoMAPIFSMessage *) newMessage; - (NSArray *) toOneRelationshipKeys;
- (void) ensureDirectory; - (NSArray *) toManyRelationshipKeys;
- (NSCalendarDate *) creationTime; - (NSArray *) childKeysOfType: (MAPIDBObjectType) type
- (NSCalendarDate *) lastModificationTime; includeDeleted: (BOOL) includeDeleted
matchingQualifier: (EOQualifier *) qualifier
- (NSArray *) toOneRelationshipKeysMatchingQualifier: (EOQualifier *) qualifier andSortOrderings: (NSArray *) sortOrderings;
andSortOrderings: (NSArray *) sortOrderings;
@end @end
#endif /* SOGOMAPIFSFOLDER_H */ #endif /* SOGOMAPIDBFOLDER_H */

View file

@ -0,0 +1,402 @@
/* SOGoMAPIDBFolder.m - this file is part of SOGo
*
* Copyright (C) 2012 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSData.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSException.h>
#import <Foundation/NSPropertyList.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
#import <Foundation/NSURL.h>
#import <NGExtensions/NSObject+Logs.h>
#import <GDLAccess/EOAdaptorChannel.h>
#import <GDLContentStore/GCSChannelManager.h>
// #import <GDLContentStore/EOQualifier+GCS.m>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoUser.h>
#import "EOQualifier+MAPI.h"
#import "GCSSpecialQueries+OpenChange.h"
#import "SOGoMAPIDBMessage.h"
#import "SOGoMAPIDBFolder.h"
#undef DEBUG
#include <stdbool.h>
#include <talloc.h>
#include <util/time.h>
#include <mapistore/mapistore.h>
#include <mapistore/mapistore_errors.h>
#include <libmapiproxy.h>
#include <param.h>
Class SOGoMAPIDBObjectK = Nil;
@implementation SOGoMAPIDBFolder
+ (void) initialize
{
SOGoMAPIDBObjectK = [SOGoMAPIDBObject class];
}
- (id) init
{
if ((self = [super init]))
{
pathPrefix = nil;
}
return self;
}
- (id) initWithName: (NSString *) name inContainer: (id) newContainer
{
if ((self = [super initWithName: name inContainer: newContainer]))
{
objectType = MAPIDBObjectTypeFolder;
aclMessage = [SOGoMAPIDBObject objectWithName: @"permissions"
inContainer: self];
[aclMessage setObjectType: MAPIDBObjectTypeInternal];
[aclMessage retain];
}
return self;
}
- (void) dealloc
{
[aclMessage release];
[pathPrefix release];
[super dealloc];
}
- (BOOL) isFolderish
{
return YES;
}
- (void) setPathPrefix: (NSString *) newPathPrefix
{
ASSIGN (pathPrefix, newPathPrefix);
}
- (NSMutableString *) pathForChild: (NSString *) childName
{
NSMutableString *path;
path = [self path];
[path appendFormat: @"/%@", childName];
return path;
}
- (NSMutableString *) path
{
NSMutableString *path;
path = [super path];
if (pathPrefix)
[path insertString: pathPrefix atIndex: 0];
return path;
}
// - (SOGoMAPIDBMessage *) newMessage
// {
// NSString *newFilename;
// newFilename = [NSString stringWithFormat: @"%@.plist",
// [SOGoObject globallyUniqueObjectId]];
// return [SOGoMAPIDBMessage objectWithName: filename inContainer: self];
// }
- (NSArray *) childKeysOfType: (MAPIDBObjectType) type
includeDeleted: (BOOL) includeDeleted
matchingQualifier: (EOQualifier *) qualifier
andSortOrderings: (NSArray *) sortOrderings
{
NSMutableArray *childKeys;
NSMutableString *sql// , *qualifierClause
;
NSString *childPathPrefix, *childPath, *childKey;
NSMutableArray *whereClause;
NSArray *records;
NSDictionary *record;
NSUInteger childPathPrefixLen, count, max;
SOGoMAPIDBObject *currentChild;
/* query construction */
sql = [NSMutableString stringWithCapacity: 256];
[sql appendFormat: @"SELECT * FROM %@", [self tableName]];
whereClause = [NSMutableArray arrayWithCapacity: 2];
childPathPrefix = [NSString stringWithFormat: @"%@/", [self path]];
[whereClause addObject: [NSString stringWithFormat: @"c_path LIKE '%@%%'",
childPathPrefix]];
[whereClause addObject: [NSString stringWithFormat: @"c_type = %d", type]];
if (!includeDeleted)
[whereClause addObject: @"c_deleted = 0"];
[sql appendFormat: @" WHERE %@",
[whereClause componentsJoinedByString: @" AND "]];
/* results */
records = [self performSQLQuery: sql];
if (records)
{
max = [records count];
childKeys = [NSMutableArray arrayWithCapacity: max];
childPathPrefixLen = [childPathPrefix length];
for (count = 0; count < max; count++)
{
record = [records objectAtIndex: count];
childPath = [record objectForKey: @"c_path"];
childKey = [childPath substringFromIndex: childPathPrefixLen];
if ([childKey rangeOfString: @"/"].location == NSNotFound)
{
if (qualifier)
{
currentChild = [SOGoMAPIDBObject objectWithName: childKey
inContainer: self];
[currentChild setupFromRecord: record];
if ([qualifier evaluateSOGoMAPIDBObject: currentChild])
[childKeys addObject: childKey];
}
else
[childKeys addObject: childKey];
}
}
}
else
childKeys = nil;
return childKeys;
}
- (NSArray *) toManyRelationshipKeys
{
return [self childKeysOfType: MAPIDBObjectTypeFolder
includeDeleted: NO
matchingQualifier: nil
andSortOrderings: nil];
}
- (NSArray *) toOneRelationshipKeys
{
return [self childKeysOfType: MAPIDBObjectTypeMessage
includeDeleted: NO
matchingQualifier: nil
andSortOrderings: nil];
}
// - (NSArray *) toOneRelationshipKeysMatchingQualifier: (EOQualifier *) qualifier
// andSortOrderings: (NSArray *) sortOrderings
// {
// NSArray *allKeys;
// NSMutableArray *keys;
// NSUInteger count, max;
// NSString *messageKey;
// SOGoMAPIDBMessage *message;
// if (sortOrderings)
// [self warnWithFormat: @"sorting is not handled yet"];
// allKeys = [self toOneRelationshipKeys];
// if (qualifier)
// {
// [self logWithFormat: @"%s: getting restricted FAI keys", __PRETTY_FUNCTION__];
// max = [allKeys count];
// keys = [NSMutableArray arrayWithCapacity: max];
// for (count = 0; count < max; count++)
// {
// messageKey = [allKeys objectAtIndex: count];
// message = [self lookupName: messageKey
// inContext: nil
// acquire: NO];
// if ([qualifier evaluateMAPIVolatileMessage: message])
// [keys addObject: messageKey];
// }
// }
// else
// keys = (NSMutableArray *) allKeys;
// return keys;
// }
- (id) lookupName: (NSString *) childName
inContext: (WOContext *) woContext
acquire: (BOOL) acquire
{
id object;
Class objectClass;
NSString *childPath;
NSDictionary *record;
childPath = [self pathForChild: childName];
record = [self lookupRecord: childPath newerThanVersion: -1];
if (record)
{
if ([[record objectForKey: @"c_type"] intValue] == MAPIDBObjectTypeFolder)
objectClass = isa;
else
objectClass = SOGoMAPIDBObjectK;
object = [objectClass objectWithName: childName
inContainer: self];
[object setupFromRecord: record];
}
else
object = nil;
return object;
}
- (id) lookupFolder: (NSString *) folderName
inContext: (WOContext *) woContext
{
id object;
object = [SOGoMAPIDBFolder objectWithName: folderName
inContainer: self];
[object reloadIfNeeded];
return object;
}
// - (id) _fileAttributeForKey: (NSString *) key
// {
// NSDictionary *attributes;
// attributes = [[NSFileManager defaultManager]
// fileAttributesAtPath: directory
// traverseLink: NO];
// return [attributes objectForKey: key];
// }
// - (NSCalendarDate *) creationTime
// {
// return [self _fileAttributeForKey: NSFileCreationDate];
// }
// - (NSCalendarDate *) lastModificationTime
// {
// return [self _fileAttributeForKey: NSFileModificationDate];
// }
- (NSException *) delete
{
[self notImplemented: _cmd];
// NSFileManager *fm;
// NSException *error;
// fm = [NSFileManager defaultManager];
// if (![fm removeFileAtPath: directory handler: NULL])
// error = [NSException exceptionWithName: @"MAPIStoreIOException"
// reason: @"could not delete folder"
// userInfo: nil];
// else
// error = nil;
// return error;
return nil;
}
/* acl */
- (NSString *) defaultUserID
{
return @"default";
}
- (NSMutableDictionary *) _aclEntries
{
NSMutableDictionary *aclEntries;
[aclMessage reloadIfNeeded];
aclEntries = [aclMessage properties];
if (![aclEntries objectForKey: @"users"])
[aclEntries setObject: [NSMutableArray array] forKey: @"users"];
if (![aclEntries objectForKey: @"entries"])
[aclEntries setObject: [NSMutableDictionary dictionary]
forKey: @"entries"];
return aclEntries;
}
- (void) addUserInAcls: (NSString *) user
{
NSMutableDictionary *acl;
NSMutableArray *users;
acl = [self _aclEntries];
users = [acl objectForKey: @"users"];
[users addObjectUniquely: user];
[aclMessage save];
}
- (void) removeAclsForUsers: (NSArray *) oldUsers
{
NSDictionary *acl;
NSMutableDictionary *entries;
NSMutableArray *users;
acl = [self _aclEntries];
entries = [acl objectForKey: @"entries"];
[entries removeObjectsForKeys: oldUsers];
users = [acl objectForKey: @"users"];
[users removeObjectsInArray: oldUsers];
[aclMessage save];
}
- (NSArray *) aclUsers
{
return [[self _aclEntries] objectForKey: @"users"];
}
- (NSArray *) aclsForUser: (NSString *) uid
{
NSDictionary *entries;
entries = [[self _aclEntries] objectForKey: @"entries"];
return [entries objectForKey: uid];
}
- (void) setRoles: (NSArray *) roles
forUser: (NSString *) uid
{
NSMutableDictionary *acl;
NSMutableDictionary *entries;
acl = [self _aclEntries];
entries = [acl objectForKey: @"entries"];
[entries setObject: roles forKey: uid];
[aclMessage save];
}
@end

View file

@ -1,6 +1,6 @@
/* MAPIStoreVolatileMessage.h - this file is part of SOGo /* SOGoMAPIDBMessage.h - this file is part of SOGo
* *
* Copyright (C) 2011 Inverse inc * Copyright (C) 2012 Inverse inc.
* *
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca> * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
@ -20,18 +20,15 @@
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*/ */
#ifndef MAPISTOREVOLATILEMESSAGE_H #ifndef SOGOMAPIDBMESSAGE_H
#define MAPISTOREVOLATILEMESSAGE_H #define SOGOMAPIDBMESSAGE_H
#import "MAPIStoreMessage.h" #import "SOGoMAPIDBObject.h"
@interface MAPIStoreVolatileMessage : MAPIStoreMessage @class NSDate;
{ @class NSString;
BOOL fetchedAttachments;
NSDate *creationTime;
NSDate *lastModificationTime;
}
@interface SOGoMAPIDBMessage : SOGoMAPIDBObject
@end @end
#endif /* MAPISTOREVOLATILEMESSAGE_H */ #endif /* SOGOMAPIDBMESSAGE_H */

View file

@ -0,0 +1,61 @@
/* SOGoMAPIDBMessage.m - this file is part of SOGo
*
* Copyright (C) 2012 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSData.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSException.h>
#import <Foundation/NSPropertyList.h>
#import <Foundation/NSString.h>
#import <NGExtensions/NSObject+Logs.h>
#import "SOGoMAPIDBFolder.h"
#import "SOGoMAPIDBMessage.h"
@implementation SOGoMAPIDBMessage
- (Class) mapistoreMessageClass
{
// NSArray *dirMembers;
NSString *className;
[NSException raise: @"whereisthisusedexception"
format: @"this exception should be triggered only for tracing"];
// /* FIXME: this method is a bit dirty */
// dirMembers = [[container directory] componentsSeparatedByString: @"/"];
// if ([dirMembers containsObject: @"fai"]) /* should not occur as FAI message
// are instantiated directly in
// MAPIStoreFolder */
// className = @"MAPIStoreFAIMessage";
// else if ([dirMembers containsObject: @"notes"])
// className = @"MAPIStoreNotesMessage";
// else
// className = @"MAPIStoreDBMessage";
className = @"nimportequoi";
return NSClassFromString (className);
}
@end

View file

@ -0,0 +1,83 @@
/* SOGoMAPIDBObject.h - this file is part of SOGo
*
* Copyright (C) 2012 Inverse inc
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef SOGOMAPIDBOBJECT_H
#define SOGOMAPIDBOBJECT_H
#import "SOGoMAPIObject.h"
@class NSArray;
@class NSMutableDictionary;
@class NSMutableString;
@class NSString;
@class NSURL;
@class EOAdaptor;
typedef enum {
MAPIDBObjectTypeFolder = 1,
MAPIDBObjectTypeMessage = 2,
MAPIDBObjectTypeFAI = 3,
MAPIDBObjectTypeInternal = 99 /* object = property list */
} MAPIDBObjectType;
@interface SOGoMAPIDBObject : SOGoMAPIObject
{
NSURL *tableUrl;
BOOL initialized; /* safe guard */
MAPIDBObjectType objectType;
NSInteger version;
BOOL deleted;
}
/* actions */
- (void) setupFromRecord: (NSDictionary *) record;
- (void) reloadIfNeeded;
- (void) save;
/* accessors */
- (NSMutableString *) path; /* full filename */
- (void) setTableUrl: (NSURL *) newTableUrl;
- (NSURL *) tableUrl;
- (NSString *) tableName;
- (NSArray *) performSQLQuery: (NSString *) sql;
- (NSDictionary *) lookupRecord: (NSString *) path
newerThanVersion: (NSInteger) startVersion;
- (void) setObjectType: (MAPIDBObjectType) newObjectType;
- (MAPIDBObjectType) objectType; /* message, fai, folder */
/* automatically set from actions */
- (BOOL) deleted;
/* db helpers */
- (EOAdaptor *) tableChannelAdaptor;
- (NSArray *) performSQLQuery: (NSString *) sql;
@end
#endif /* SOGOMAPIDBOBJECT_H */

View file

@ -0,0 +1,483 @@
/* SOGoMAPIDBObject.m - this file is part of SOGo
*
* Copyright (C) 2012 Inverse inc
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSException.h>
#import <Foundation/NSNull.h>
#import <Foundation/NSPropertyList.h>
#import <Foundation/NSString.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSValue.h>
#import <GDLAccess/EOAdaptor.h>
#import <GDLAccess/EOAdaptorChannel.h>
#import <GDLAccess/EOAdaptorContext.h>
#import <GDLAccess/EOAttribute.h>
#import <GDLContentStore/GCSChannelManager.h>
#import <NGExtensions/NGBase64Coding.h>
#import <NGExtensions/NSNull+misc.h>
#import <NGExtensions/NSObject+Logs.h>
#import <SOGo/NSObject+Utilities.h>
#import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoUser.h>
#import "GCSSpecialQueries+OpenChange.h"
#import "MAPIStoreTypes.h"
#import "SOGoMAPIDBFolder.h"
#import "SOGoMAPIDBObject.h"
static EOAttribute *textColumn = nil;
@implementation SOGoMAPIDBObject
+ (void) initialize
{
NSDictionary *description;
if (!textColumn)
{
/* TODO: this is a hack for providing an EOAttribute definition that is
compatible with all the backends that we support. We should make use
of EOModel instead. */
description = [NSDictionary dictionaryWithObjectsAndKeys:
@"c_textfield", @"columnName",
@"VARCHAR", @"externalType",
nil];
textColumn = [EOAttribute attributeFromPropertyList: description];
[textColumn retain];
}
}
/*
= (@"CREATE TABLE %@ ("
@" c_path VARCHAR(255) PRIMARY KEY,"
@" c_type VARCHAR(20) NOT NULL,"
@" c_creationdate INT4 NOT NULL,"
@" c_lastmodified INT4 NOT NULL,"
@" c_version INT4 NOT NULL DEFAULT 0,"
@" c_deleted SMALLINT NOT NULL DEFAULT 0,"
*/
/* indexes:
c_path (primary key)
c_counter
c_path, c_type
c_path, c_creationdate */
- (id) init
{
if ((self = [super init]))
{
tableUrl = nil;
initialized = NO;
objectType = -1;
deleted = NO;
version = 0;
}
return self;
}
- (void) dealloc
{
[tableUrl release];
[super dealloc];
}
- (void) setTableUrl: (NSURL *) newTableUrl
{
ASSIGN (tableUrl, newTableUrl);
}
- (NSURL *) tableUrl
{
if (!tableUrl)
{
tableUrl = [container tableUrl];
[tableUrl retain];
if (!tableUrl)
[NSException raise: @"MAPIStoreIOException"
format: @"table url is not set for object '%@'", self];
}
return tableUrl;
}
- (NSString *) tableName
{
NSArray *parts;
[self tableUrl];
parts = [[tableUrl path] componentsSeparatedByString: @"/"];
return [parts lastObject];
}
- (void) setupFromRecord: (NSDictionary *) record
{
NSInteger intValue;
NSString *propsValue, *error;
NSDictionary *newValues;
NSPropertyListFormat format;
objectType = [[record objectForKey: @"c_type"] intValue];
intValue = [[record objectForKey: @"c_creationdate"] intValue];
ASSIGN (creationDate,
[NSCalendarDate
dateWithTimeIntervalSince1970: (NSTimeInterval) intValue]);
intValue = [[record objectForKey: @"c_lastmodified"] intValue];
ASSIGN (lastModified,
[NSCalendarDate
dateWithTimeIntervalSince1970: (NSTimeInterval) intValue]);
deleted = ([[record objectForKey: @"c_deleted"] intValue] > 0);
version = [[record objectForKey: @"c_version"] intValue];
propsValue = [record objectForKey: @"c_content"];
if ([propsValue isNotNull])
{
newValues = [NSPropertyListSerialization propertyListFromData: [propsValue dataByDecodingBase64]
mutabilityOption: NSPropertyListMutableContainers
format: &format
errorDescription: &error];
[properties addEntriesFromDictionary: newValues];
// [properties addEntriesFromDictionary: [propsValue
// objectFromJSONString]];
}
else
[properties removeAllObjects];
initialized = YES;
}
/* accessors */
- (NSMutableString *) path
{
NSMutableString *path;
if (container)
path = [container pathForChild: nameInContainer];
else
path = [NSMutableString stringWithFormat: @"/%@", nameInContainer];
if ([path rangeOfString: @"//"].location != NSNotFound)
[NSException raise: @"MAPIStoreIOException"
format: @"object path has not been properly set for"
" folder '%@' (%@)",
self, path];
return path;
}
- (void) setObjectType: (MAPIDBObjectType) newObjectType
{
objectType = newObjectType;
}
- (MAPIDBObjectType) objectType /* message, fai, folder */
{
return objectType;
}
- (NSCalendarDate *) creationDate
{
if (!initialized)
[NSException raise: @"MAPIStoreIOException"
format: @"record has not been initialized: %@", self];
return creationDate;
}
- (NSCalendarDate *) lastModified
{
if (!initialized)
[NSException raise: @"MAPIStoreIOException"
format: @"record has not been initialized: %@", self];
return lastModified;
}
- (BOOL) deleted
{
return deleted;
}
- (Class) mapistoreMessageClass
{
NSString *className, *mapiMsgClass;
switch (objectType)
{
case MAPIDBObjectTypeMessage:
mapiMsgClass = [properties
objectForKey: MAPIPropertyKey (PidTagMessageClass)];
if (mapiMsgClass)
{
if ([mapiMsgClass isEqualToString: @"IPM.StickyNote"])
className = @"MAPIStoreNotesMessage";
else
className = @"MAPIStoreDBMessage";
[self logWithFormat: @"PidTagMessageClass = '%@', returning '%@'",
mapiMsgClass, className];
}
else
{
[self warnWithFormat: @"PidTagMessageClass is not set, falling back"
@" to 'MAPIStoreDBMessage'"];
className = @"MAPIStoreDBMessage";
}
break;
case MAPIDBObjectTypeFAI:
className = @"MAPIStoreFAIMessage";
break;
default:
[NSException raise: @"MAPIStoreIOException"
format: @"message class should not be queried for objects"
@" of type '%d'", objectType];
}
return NSClassFromString (className);
}
/* actions */
- (EOAdaptor *) tableChannelAdaptor
{
GCSChannelManager *cm;
EOAdaptor *adaptor;
EOAdaptorChannel *channel;
cm = [GCSChannelManager defaultChannelManager];
channel = [cm acquireOpenChannelForURL: [self tableUrl]];
adaptor = [[channel adaptorContext] adaptor];
[cm releaseChannel: channel];
return adaptor;
}
- (NSArray *) performSQLQuery: (NSString *) sql
{
NSMutableArray *records;
GCSChannelManager *cm;
EOAdaptorChannel *channel;
NSException *error;
NSArray *attrs;
NSDictionary *record;
cm = [GCSChannelManager defaultChannelManager];
channel = [cm acquireOpenChannelForURL: [self tableUrl]];
error = [channel evaluateExpressionX: sql];
if (error)
{
records = nil;
[self logWithFormat:
@"an exception occurred when executing query '%@'",
sql];
[self logWithFormat: @"exception is '%@'", error];
}
else
{
records = [NSMutableArray arrayWithCapacity: 256];
attrs = [channel describeResults: NO];
while ((record = [channel fetchAttributes: attrs withZone: NULL]))
[records addObject: record];
}
[cm releaseChannel: channel];
return records;
}
- (NSDictionary *) lookupRecord: (NSString *) path
newerThanVersion: (NSInteger) startVersion
{
NSDictionary *record;
NSArray *records;
NSString *tableName, *pathValue;
NSMutableString *sql;
EOAdaptor *adaptor;
if ([path hasSuffix: @"/"])
[NSException raise: @"MAPIStoreIOException"
format: @"path ends with a slash: %@", path];
tableName = [self tableName];
adaptor = [self tableChannelAdaptor];
pathValue = [adaptor formatValue: path
forAttribute: textColumn];
/* query */
sql = [NSMutableString stringWithFormat:
@"SELECT * FROM %@ WHERE c_path = %@",
tableName, pathValue];
if (startVersion > -1)
[sql appendFormat: @" AND c_version > %d", startVersion];
/* execution */
records = [self performSQLQuery: sql];
if ([records count] > 0)
record = [records objectAtIndex: 0];
else
record = nil;
return record;
}
- (void) reloadIfNeeded
{
/* if object is uninitialized: reload without condition, otherwise, load if
c_version > :version */
NSDictionary *record;
if (initialized)
{
if (!isNew)
{
record = [self lookupRecord: [self path]
newerThanVersion: version];
if (record)
[self setupFromRecord: record];
}
}
else
{
record = [self lookupRecord: [self path]
newerThanVersion: -1];
if (record)
{
[self setupFromRecord: record];
isNew = NO;
}
else
isNew = YES;
initialized = YES;
}
}
- (NSException *) delete
{
deleted = YES;
[properties removeAllObjects];
[self save];
return nil;
}
- (void) save
{
NSString *sql;
NSData *content;
NSCalendarDate *now;
GCSChannelManager *cm;
EOAdaptor *adaptor;
EOAdaptorChannel *channel;
NSInteger creationDateValue, lastModifiedValue, deletedValue;
NSString *tableName, *pathValue, *propsValue;
NSException *result;
if (!initialized)
[NSException raise: @"MAPIStoreIOException"
format: @"record has not been initialized: %@", self];
cm = [GCSChannelManager defaultChannelManager];
channel = [cm acquireOpenChannelForURL: [self tableUrl]];
tableName = [self tableName];
now = [NSCalendarDate date];
ASSIGN (lastModified, now);
/*
- (NSException *)insertRowX:(NSDictionary *)_row forEntity:(EOEntity *)_entity;
- (NSException *)updateRowX:(NSDictionary*)aRow
describedByQualifier:(EOSQLQualifier*)aQualifier;
*/
adaptor = [[channel adaptorContext] adaptor];
pathValue = [adaptor formatValue: [self path]
forAttribute: textColumn];
lastModifiedValue = (NSInteger) [lastModified timeIntervalSince1970];
if (objectType == -1)
[NSException raise: @"MAPIStoreIOException"
format: @"object type has not been set for object '%@'",
self];
if ([properties count] > 0)
{
content = [NSPropertyListSerialization
dataFromPropertyList: properties
format: NSPropertyListBinaryFormat_v1_0
errorDescription: NULL];
propsValue = [adaptor formatValue: [content stringByEncodingBase64]
forAttribute: textColumn];
}
else
propsValue = @"NULL";
if (isNew)
{
ASSIGN (creationDate, now);
creationDateValue = (NSInteger) [creationDate timeIntervalSince1970];
sql = [NSString stringWithFormat:
(@"INSERT INTO %@"
@" (c_path, c_type, c_creationdate, c_lastmodified,"
@" c_deleted, c_version, c_content)"
@" VALUES (%@, %d, %d, %d, 0, 0, %@"
@")"),
tableName,
pathValue, objectType,
creationDateValue, lastModifiedValue,
propsValue];
isNew = NO;
}
else
{
version++;
deletedValue = (deleted ? 1 : 0);
sql = [NSString stringWithFormat:
(@"UPDATE %@"
@" SET c_lastmodified = %d, c_deleted = %d,"
@" c_version = %d, c_content = %@"
@" WHERE c_path = %@"),
tableName,
lastModifiedValue, deletedValue, version, propsValue,
pathValue];
}
result = [channel evaluateExpressionX: sql];
if (result)
[self errorWithFormat: @"could not insert/update record for record %@"
@" in %@: %@", pathValue, tableName, result];
// @" c_path VARCHAR(255) PRIMARY KEY,"
// @" c_type SMALLINT NOT NULL,"
// @" c_creationdate INT4 NOT NULL,"
// @" c_lastmodified INT4 NOT NULL,"
// @" c_deleted SMALLINT NOT NULL DEFAULT 0,"
// @" c_content BLOB");
[cm releaseChannel: channel];
}
@end

View file

@ -1,439 +0,0 @@
/* SOGoMAPIFSFolder.m - this file is part of SOGo
*
* Copyright (C) 2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSData.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSException.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSPropertyList.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
#import <Foundation/NSURL.h>
#import <NGExtensions/NSObject+Logs.h>
#import <SOGo/NSArray+Utilities.h>
#import "EOQualifier+MAPI.h"
#import "SOGoMAPIFSMessage.h"
#import "SOGoMAPIFSFolder.h"
#undef DEBUG
#include <stdbool.h>
#include <talloc.h>
#include <util/time.h>
#include <mapistore/mapistore.h>
#include <mapistore/mapistore_errors.h>
#include <libmapiproxy.h>
#include <param.h>
static NSString *privateDir = nil;
@implementation SOGoMAPIFSFolder
+ (void) initialize
{
struct loadparm_context *lpCtx;
const char *cPrivateDir;
if (!privateDir)
{
lpCtx = loadparm_init_global (true);
cPrivateDir = lpcfg_private_dir (lpCtx);
privateDir = [NSString stringWithUTF8String: cPrivateDir];
[privateDir retain];
}
}
+ (id) folderWithURL: (NSURL *) url
andTableType: (uint8_t) tableType
{
SOGoMAPIFSFolder *newFolder;
newFolder = [[self alloc] initWithURL: url
andTableType: tableType];
[newFolder autorelease];
return newFolder;
}
- (id) init
{
if ((self = [super init]))
{
directory = nil;
directoryIsSane = NO;
}
return self;
}
- (void) dealloc
{
[directory release];
[super dealloc];
}
- (id) initWithURL: (NSURL *) url
andTableType: (uint8_t) tableType
{
NSString *path, *username, *tableParticle;
if ((self = [self init]))
{
if (tableType == MAPISTORE_MESSAGE_TABLE)
tableParticle = @"message";
else if (tableType == MAPISTORE_FAI_TABLE)
tableParticle = @"fai";
else if (tableType == MAPISTORE_FOLDER_TABLE)
tableParticle = @"folder";
else
{
[NSException raise: @"MAPIStoreIOException"
format: @"unsupported table type: %d", tableType];
tableParticle = nil;
}
path = [url path];
if (![path hasSuffix: @"/"])
path = [NSString stringWithFormat: @"%@/", path];
username = [url user];
directory = [NSString stringWithFormat: @"%@/mapistore/SOGo/%@/%@/%@%@",
privateDir, username, tableParticle,
[url host], path];
[self setOwner: username];
[self logWithFormat: @"directory: %@", directory];
[directory retain];
ASSIGN (nameInContainer, [path stringByDeletingLastPathComponent]);
}
return self;
}
- (id) initWithName: (NSString *) newName
inContainer: (id) newContainer
{
if ((self = [super initWithName: newName inContainer: newContainer]))
{
directory = [[newContainer directory]
stringByAppendingPathComponent: newName];
[directory retain];
}
return self;
}
- (NSString *) directory
{
return directory;
}
- (SOGoMAPIFSMessage *) newMessage
{
NSString *filename;
filename = [NSString stringWithFormat: @"%@.plist",
[SOGoObject globallyUniqueObjectId]];
return [SOGoMAPIFSMessage objectWithName: filename inContainer: self];
}
- (void) ensureDirectory
{
NSFileManager *fm;
NSDictionary *attributes;
BOOL isDir;
if (!directory)
[NSException raise: @"MAPIStoreIOException"
format: @"directory is nil"];
fm = [NSFileManager defaultManager];
if ([fm fileExistsAtPath: directory isDirectory: &isDir])
{
if (!isDir)
[NSException raise: @"MAPIStoreIOException"
format: @"object at path '%@' is not a directory",
directory];
}
else
{
attributes
= [NSDictionary dictionaryWithObject: [NSNumber numberWithInt: 0700]
forKey: NSFilePosixPermissions];
[fm createDirectoryAtPath: directory
attributes: attributes];
}
directoryIsSane = YES;
}
- (NSArray *) _objectsInDirectory: (BOOL) dirs
{
NSFileManager *fm;
NSArray *contents;
NSMutableArray *files;
NSUInteger count, max;
NSString *file, *fullName;
BOOL isDir;
if (!directoryIsSane)
[self ensureDirectory];
fm = [NSFileManager defaultManager];
contents = [fm directoryContentsAtPath: directory];
max = [contents count];
files = [NSMutableArray arrayWithCapacity: max];
for (count = 0; count < max; count++)
{
file = [contents objectAtIndex: count];
if (![file isEqualToString: @"permissions.plist"])
{
fullName = [directory stringByAppendingPathComponent: file];
if ([fm fileExistsAtPath: fullName
isDirectory: &isDir]
&& dirs == isDir)
[files addObject: file];
}
}
return files;
}
- (NSArray *) toManyRelationshipKeys
{
return [self _objectsInDirectory: YES];
}
- (NSArray *) toOneRelationshipKeys
{
return [self _objectsInDirectory: NO];
}
- (NSArray *) toOneRelationshipKeysMatchingQualifier: (EOQualifier *) qualifier
andSortOrderings: (NSArray *) sortOrderings
{
NSArray *allKeys;
NSMutableArray *keys;
NSUInteger count, max;
NSString *messageKey;
SOGoMAPIFSMessage *message;
if (sortOrderings)
[self warnWithFormat: @"sorting is not handled yet"];
allKeys = [self toOneRelationshipKeys];
if (qualifier)
{
[self logWithFormat: @"%s: getting restricted FAI keys", __PRETTY_FUNCTION__];
max = [allKeys count];
keys = [NSMutableArray arrayWithCapacity: max];
for (count = 0; count < max; count++)
{
messageKey = [allKeys objectAtIndex: count];
message = [self lookupName: messageKey
inContext: nil
acquire: NO];
if ([qualifier evaluateMAPIVolatileMessage: message])
[keys addObject: messageKey];
}
}
else
keys = (NSMutableArray *) allKeys;
return keys;
}
- (id) lookupName: (NSString *) fileName
inContext: (WOContext *) woContext
acquire: (BOOL) acquire
{
NSFileManager *fm;
NSString *fullName;
id object;
BOOL isDir;
if (!directoryIsSane)
[self ensureDirectory];
fm = [NSFileManager defaultManager];
fullName = [directory stringByAppendingPathComponent: fileName];
if ([fm fileExistsAtPath: fullName
isDirectory: &isDir])
{
if (isDir)
object = [isa objectWithName: fileName
inContainer: self];
else
object = [SOGoMAPIFSMessage objectWithName: fileName
inContainer: self];
}
else
object = nil;
return object;
}
- (id) _fileAttributeForKey: (NSString *) key
{
NSDictionary *attributes;
attributes = [[NSFileManager defaultManager]
fileAttributesAtPath: directory
traverseLink: NO];
return [attributes objectForKey: key];
}
- (NSCalendarDate *) creationTime
{
return [self _fileAttributeForKey: NSFileCreationDate];
}
- (NSCalendarDate *) lastModificationTime
{
return [self _fileAttributeForKey: NSFileModificationDate];
}
- (NSException *) delete
{
NSFileManager *fm;
NSException *error;
fm = [NSFileManager defaultManager];
if (![fm removeFileAtPath: directory handler: NULL])
error = [NSException exceptionWithName: @"MAPIStoreIOException"
reason: @"could not delete folder"
userInfo: nil];
else
error = nil;
return error;
}
/* acl */
- (NSString *) defaultUserID
{
return @"default";
}
- (NSMutableDictionary *) _aclEntries
{
NSMutableDictionary *aclEntries;
NSData *content;
NSString *error, *filename;
NSPropertyListFormat format;
filename = [directory stringByAppendingPathComponent: @"permissions.plist"];
content = [NSData dataWithContentsOfFile: filename];
if (content)
aclEntries = [NSPropertyListSerialization propertyListFromData: content
mutabilityOption: NSPropertyListMutableContainers
format: &format
errorDescription: &error];
else
aclEntries = nil;
if (!aclEntries)
{
aclEntries = [NSMutableDictionary dictionary];
[aclEntries setObject: [NSMutableArray array] forKey: @"users"];
[aclEntries setObject: [NSMutableDictionary dictionary]
forKey: @"entries"];
}
return aclEntries;
}
- (void) _saveAcl: (NSDictionary *) acl
{
NSString *filename;
NSData *content;
filename = [directory stringByAppendingPathComponent: @"permissions.plist"];
[self ensureDirectory];
if (acl)
content = [NSPropertyListSerialization
dataFromPropertyList: acl
format: NSPropertyListBinaryFormat_v1_0
errorDescription: NULL];
else
content = [NSData data];
if (![content writeToFile: filename atomically: NO])
[NSException raise: @"MAPIStoreIOException"
format: @"could not save acl"];
}
- (void) addUserInAcls: (NSString *) user
{
NSMutableDictionary *acl;
NSMutableArray *users;
acl = [self _aclEntries];
users = [acl objectForKey: @"users"];
[users addObjectUniquely: user];
[self _saveAcl: acl];
}
- (void) removeAclsForUsers: (NSArray *) oldUsers
{
NSDictionary *acl;
NSMutableDictionary *entries;
NSMutableArray *users;
acl = [self _aclEntries];
entries = [acl objectForKey: @"entries"];
[entries removeObjectsForKeys: oldUsers];
users = [acl objectForKey: @"users"];
[users removeObjectsInArray: oldUsers];
[self _saveAcl: acl];
}
- (NSArray *) aclUsers
{
return [[self _aclEntries] objectForKey: @"users"];
}
- (NSArray *) aclsForUser: (NSString *) uid
{
NSDictionary *entries;
entries = [[self _aclEntries] objectForKey: @"entries"];
return [entries objectForKey: uid];
}
- (void) setRoles: (NSArray *) roles
forUser: (NSString *) uid
{
NSMutableDictionary *acl;
NSMutableDictionary *entries;
acl = [self _aclEntries];
entries = [acl objectForKey: @"entries"];
[entries setObject: roles forKey: uid];
[self _saveAcl: acl];
}
@end

View file

@ -1,47 +0,0 @@
/* SOGoMAPIFSMessage.h - this file is part of SOGo
*
* Copyright (C) 2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef SOGOMAPIFSMESSAGE_H
#define SOGOMAPIFSMESSAGE_H
#import "SOGoMAPIVolatileMessage.h"
@class NSDate;
@class NSString;
@interface SOGoMAPIFSMessage : SOGoMAPIVolatileMessage
{
NSString *completeFilename;
NSUInteger inode;
NSData *lastModificationTime;
}
- (void) save;
- (NSString *) completeFilename;
- (NSDate *) creationTime;
- (NSDate *) lastModificationTime;
@end
#endif /* SOGOMAPIFSMESSAGE_H */

View file

@ -1,238 +0,0 @@
/* SOGoMAPIFSMessage.m - this file is part of SOGo
*
* Copyright (C) 2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSData.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSException.h>
#import <Foundation/NSPropertyList.h>
#import <Foundation/NSString.h>
#import <NGExtensions/NSObject+Logs.h>
#import "SOGoMAPIFSFolder.h"
#import "SOGoMAPIFSMessage.h"
@implementation SOGoMAPIFSMessage
- (id) init
{
if ((self = [super init]))
{
completeFilename = nil;
inode = 0;
lastModificationTime = nil;
}
return self;
}
- (void) dealloc
{
[completeFilename release];
[super dealloc];
}
- (Class) mapistoreMessageClass
{
NSArray *dirMembers;
NSString *className;
/* FIXME: this method is a bit dirty */
dirMembers = [[container directory] componentsSeparatedByString: @"/"];
if ([dirMembers containsObject: @"fai"]) /* should not occur as FAI message
are instantiated directly in
MAPIStoreFolder */
className = @"MAPIStoreFAIMessage";
else if ([dirMembers containsObject: @"notes"])
className = @"MAPIStoreNotesMessage";
else
className = @"MAPIStoreFSMessage";
return NSClassFromString (className);
}
- (NSString *) completeFilename
{
if (!completeFilename)
{
completeFilename = [[container directory]
stringByAppendingPathComponent: nameInContainer];
[completeFilename retain];
}
return completeFilename;
}
- (BOOL) _readFileChangesDataWithDate: (NSDate **) newLMTime
andInode: (NSUInteger *) newInode
{
BOOL rc;
NSDictionary *attributes;
attributes = [[NSFileManager defaultManager]
fileAttributesAtPath: [self completeFilename]
traverseLink: NO];
if (attributes)
{
*newLMTime = [attributes fileModificationDate];
*newInode = [attributes fileSystemFileNumber];
rc = YES;
}
else
rc = NO;
return rc;
}
- (BOOL) _checkFileChangesDataWithDate: (NSDate **) newLMTime
andInode: (NSUInteger *) newInode
{
BOOL hasChanged = NO;
NSDate *lastLMTime;
NSUInteger lastInode;
if ([self _readFileChangesDataWithDate: &lastLMTime
andInode: &lastInode])
{
if (inode != lastInode
|| ![lastModificationTime isEqual: lastLMTime])
{
if (lastLMTime)
*newLMTime = lastLMTime;
if (newInode)
*newInode = lastInode;
hasChanged = YES;
}
}
return hasChanged;
}
- (NSMutableDictionary *) properties
{
NSData *content;
NSString *error;
NSPropertyListFormat format;
NSDate *lastLMTime;
NSUInteger lastInode;
if ([self _checkFileChangesDataWithDate: &lastLMTime
andInode: &lastInode])
{
[self logWithFormat: @"file '%@' new or modified: rereading properties",
[self completeFilename]];
[properties release];
properties = nil;
content = [NSData dataWithContentsOfFile: [self completeFilename]];
if (content)
{
properties = [NSPropertyListSerialization propertyListFromData: content
mutabilityOption: NSPropertyListMutableContainers
format: &format
errorDescription: &error];
[properties retain];
if (!properties)
[self logWithFormat: @"an error occurred during deserialization"
@" of message: '%@'", error];
}
ASSIGN (lastModificationTime, lastLMTime);
inode = lastInode;
}
return [super properties];
}
- (void) save
{
NSData *content;
NSDate *lastLMTime;
NSUInteger lastInode;
[container ensureDirectory];
// [self logWithFormat: @"%d props in whole dict", [properties count]];
content = [NSPropertyListSerialization
dataFromPropertyList: [self properties]
format: NSPropertyListBinaryFormat_v1_0
errorDescription: NULL];
if (![content writeToFile: [self completeFilename] atomically: YES])
[NSException raise: @"MAPIStoreIOException"
format: @"could not save message"];
[self _readFileChangesDataWithDate: &lastLMTime andInode: &lastInode];
ASSIGN (lastModificationTime, lastLMTime);
inode = lastInode;
// [self logWithFormat: @"fs message written to '%@'", [self completeFilename]];
}
- (NSString *) davEntityTag
{
NSDate *lm;
lm = [self lastModificationTime];
return [NSString stringWithFormat: @"%d", (int) [lm timeIntervalSince1970]];
}
- (NSException *) delete
{
NSFileManager *fm;
NSException *error;
fm = [NSFileManager defaultManager];
if (![fm removeFileAtPath: [self completeFilename] handler: NULL])
error = [NSException exceptionWithName: @"MAPIStoreIOException"
reason: @"could not delete message"
userInfo: nil];
else
error = nil;
return error;
}
- (id) _fileAttributeForKey: (NSString *) key
{
NSDictionary *attributes;
attributes = [[NSFileManager defaultManager]
fileAttributesAtPath: [self completeFilename]
traverseLink: NO];
return [attributes objectForKey: key];
}
- (NSDate *) creationTime
{
return [self _fileAttributeForKey: NSFileCreationDate];
}
- (NSDate *) lastModificationTime
{
return [self _fileAttributeForKey: NSFileModificationDate];
}
@end

View file

@ -1,12 +1,12 @@
/* SOGoMAPIVolatileMessage.h - this file is part of SOGo /* SOGoMAPIObject.h - this file is part of SOGo
* *
* Copyright (C) 2011 Inverse inc * Copyright (C) 2012 Inverse inc
* *
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca> * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
* This file is free software; you can redistribute it and/or modify * This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* This file is distributed in the hope that it will be useful, * This file is distributed in the hope that it will be useful,
@ -20,22 +20,30 @@
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*/ */
#ifndef SOGOMAPIVOLATILEMESSAGE_H #ifndef SOGOMAPIOBJECT_H
#define SOGOMAPIVOLATILEMESSAGE_H #define SOGOMAPIOBJECT_H
#import <SOGo/SOGoObject.h> #import <SOGo/SOGoObject.h>
@class NSDictionary;
@class NSMutableDictionary; @class NSMutableDictionary;
@interface SOGoMAPIVolatileMessage : SOGoObject @interface SOGoMAPIObject : SOGoObject
{ {
BOOL isNew;
NSMutableDictionary *properties; NSMutableDictionary *properties;
NSCalendarDate *creationDate;
NSCalendarDate *lastModified;
} }
- (void) setIsNew: (BOOL) newIsNew;
- (BOOL) isNew;
- (void) adjustLastModified;
- (NSMutableDictionary *) properties; - (NSMutableDictionary *) properties;
- (void) appendProperties: (NSDictionary *) newProperties; - (NSCalendarDate *) creationDate;
- (NSCalendarDate *) lastModified;
@end @end
#endif /* SOGOMAPIVOLATILEMESSAGE_H */ #endif /* SOGOMAPIOBJECT_H */

View file

@ -1,6 +1,6 @@
/* SOGoMAPIVolatileMessage.m - this file is part of SOGo /* SOGoMAPIObject.m - this file is part of SOGo
* *
* Copyright (C) 2011 Inverse inc * Copyright (C) 2012 Inverse inc
* *
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca> * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
@ -20,17 +20,19 @@
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*/ */
#import <Foundation/NSDictionary.h> #import "SOGoMAPIObject.h"
#import "SOGoMAPIVolatileMessage.h" @implementation SOGoMAPIObject
@implementation SOGoMAPIVolatileMessage
- (id) init - (id) init
{ {
if ((self = [super init])) if ((self = [super init]))
{ {
properties = nil; isNew = NO;
creationDate = [NSCalendarDate date];
[creationDate retain];
lastModified = [creationDate copy];
properties = [NSMutableDictionary new];
} }
return self; return self;
@ -38,21 +40,45 @@
- (void) dealloc - (void) dealloc
{ {
[creationDate release];
[lastModified release];
[properties release]; [properties release];
[super dealloc]; [super dealloc];
} }
- (void) setIsNew: (BOOL) newIsNew
{
isNew = newIsNew;
}
- (BOOL) isNew
{
return isNew;
}
- (void) adjustLastModified
{
ASSIGN (lastModified, [NSCalendarDate date]);
}
- (BOOL) isFolderish
{
return NO;
}
- (NSMutableDictionary *) properties - (NSMutableDictionary *) properties
{ {
if (!properties)
properties = [NSMutableDictionary new];
return properties; return properties;
} }
- (void) appendProperties: (NSDictionary *) newProperties - (NSCalendarDate *) creationDate
{ {
[[self properties] addEntriesFromDictionary: newProperties]; return creationDate;
}
- (NSCalendarDate *) lastModified
{
return lastModified;
} }
@end @end

109
OpenChange/dbmsgreader.m Normal file
View file

@ -0,0 +1,109 @@
/* dbmsgreader.m - this file is part of SOGo
*
* Copyright (C) 2011 Inverse inc
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/* A format-agnostic property list readerer.
Usage: dbmsgreader [username] [filename] */
#import <Foundation/NSArray.h>
#import <Foundation/NSBundle.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSProcessInfo.h>
#import <Foundation/NSUserDefaults.h>
#import <NGExtensions/NGBase64Coding.h>
#import <NGObjWeb/SoProductRegistry.h>
#import <SOGo/SOGoProductLoader.h>
#import <SOGo/SOGoSystemDefaults.h>
#import "MAPIStoreUserContext.h"
#import "SOGoMAPIDBObject.h"
#import "NSObject+PropertyList.m"
Class MAPIStoreUserContextK, SOGoMAPIDBObjectK;
static void
DbDumpObject (NSString *username, NSString *path)
{
id ctx;
NSData *content;
id dbobject;
NSDictionary *record;
ctx = [MAPIStoreUserContextK userContextWithUsername: username
andTDBIndexing: NULL];
dbobject = [SOGoMAPIDBObjectK new];
[dbobject setTableUrl: [ctx folderTableURL]];
record = [dbobject lookupRecord: path newerThanVersion: -1];
if (record)
{
content = [[record objectForKey: @"c_content"] dataByDecodingBase64];
OCDumpPListData (content);
}
else
NSLog (@"record not found");
[dbobject release];
}
int main (int argc, char *argv[], char *envp[])
{
NSAutoreleasePool *pool;
SOGoProductLoader *loader;
NSUserDefaults *ud;
SoProductRegistry *registry;
NSArray *arguments;
/* Here we work around a bug in GNUstep which decodes XML user
defaults using the system encoding rather than honouring
the encoding specified in the file. */
putenv ("GNUSTEP_STRING_ENCODING=NSUTF8StringEncoding");
pool = [NSAutoreleasePool new];
[SOGoSystemDefaults sharedSystemDefaults];
/* We force the plugin to base its configuration on the SOGo tree. */
ud = [NSUserDefaults standardUserDefaults];
[ud registerDefaults: [ud persistentDomainForName: @"sogod"]];
[NSProcessInfo initializeWithArguments: argv
count: argc
environment: envp];
registry = [SoProductRegistry sharedProductRegistry];
[registry scanForProductsInDirectory: SOGO_BUNDLES_DIR];
loader = [SOGoProductLoader productLoader];
[loader loadProducts: [NSArray arrayWithObject: BACKEND_BUNDLE_NAME]];
MAPIStoreUserContextK = NSClassFromString (@"MAPIStoreUserContext");
SOGoMAPIDBObjectK = NSClassFromString (@"SOGoMAPIDBObject");
arguments = [[NSProcessInfo processInfo] arguments];
if ([arguments count] > 2)
DbDumpObject ([arguments objectAtIndex: 1],
[arguments objectAtIndex: 2]);
[pool release];
return 0;
}

View file

@ -23,164 +23,19 @@
/* A format-agnostic property list dumper. /* A format-agnostic property list dumper.
Usage: plreader [filename] */ Usage: plreader [filename] */
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSArray.h> #import <Foundation/NSArray.h>
#import <Foundation/NSData.h> #import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSProcessInfo.h> #import <Foundation/NSProcessInfo.h>
#import <Foundation/NSPropertyList.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
#import <NGExtensions/NSNull+misc.h>
const char *indentationStep = " "; #import "NSObject+PropertyList.m"
@interface NSObject (plext)
- (void) displayWithIndentation: (NSInteger) anInt;
@end
@implementation NSObject (plext)
- (void) _outputIndentation: (NSInteger) anInt
{
NSInteger i;
for (i = 0; i < anInt; i++)
printf ("%s", indentationStep);
}
- (void) displayWithIndentation: (NSInteger) anInt
{
printf ("(%s) %s",
[NSStringFromClass (isa) UTF8String],
[[self description] UTF8String]);
}
@end
@implementation NSDictionary (plext)
- (void) displayKey: (NSString *) key
withIndentation: (NSInteger) anInt
{
[self _outputIndentation: anInt];
printf ("%s ", [[key description] UTF8String]);
if ([key isKindOfClass: [NSValue class]])
printf ("(%s: 0x%.8x) ", [(NSValue *) key objCType], [key intValue]);
printf ("= ");
}
- (void) displayWithIndentation: (NSInteger) anInt
{
NSUInteger i, max;
NSArray *keys;
NSInteger subIndent;
NSString *key;
keys = [self allKeys];
max = [keys count];
printf ("{ (%ld) items\n", (long) max);
subIndent = anInt + 1;
for (i = 0; i < max; i++)
{
key = [keys objectAtIndex: i];
[self displayKey: key withIndentation: subIndent];
[[self objectForKey: key] displayWithIndentation: subIndent];
if (i < (max - 1))
printf (",");
printf ("\n");
}
[self _outputIndentation: anInt];
printf ("}");
}
@end
@implementation NSArray (plext)
- (void) displayCount: (NSUInteger) count
withIndentation: (NSInteger) anInt
{
[self _outputIndentation: anInt];
printf ("%lu = ", (unsigned long) count);
}
- (void) displayWithIndentation: (NSInteger) anInt
{
NSUInteger i, max;
NSInteger subIndent;
max = [self count];
printf ("[ (%ld) items\n", (long) max);
subIndent = anInt + 1;
for (i = 0; i < max; i++)
{
[self displayCount: i withIndentation: subIndent];
[[self objectAtIndex: i] displayWithIndentation: subIndent];
if (i < (max - 1))
printf (",");
printf ("\n");
}
[self _outputIndentation: anInt];
printf ("]");
}
@end
static void static void
PLReaderDumpPListFile (NSString *filename) PLReaderDumpPListFile (NSString *filename)
{ {
NSData *content; NSData *content;
NSDictionary *d;
NSPropertyListFormat format;
NSString *error = nil;
const char *formatName;
content = [NSData dataWithContentsOfFile: filename]; content = [NSData dataWithContentsOfFile: filename];
d = [NSPropertyListSerialization propertyListFromData: content OCDumpPListData (content);
mutabilityOption: NSPropertyListImmutable
format: &format
errorDescription: &error];
if (d)
{
switch (format)
{
case NSPropertyListOpenStepFormat:
formatName = "OpenStep";
break;
case NSPropertyListXMLFormat_v1_0:
formatName = "XML";
break;
case NSPropertyListBinaryFormat_v1_0:
formatName = "Binary";
break;
case NSPropertyListGNUstepFormat:
formatName = "GNUstep";
break;
case NSPropertyListGNUstepBinaryFormat:
formatName = "GNUstep binary";
break;
default: formatName = "unknown";
}
printf ("File format is: %s\n", formatName);
[d displayWithIndentation: 0];
printf ("\n");
}
else
printf ("an error occurred: %s\n", [error UTF8String]);
} }
int main() int main()

View file

@ -48,4 +48,15 @@
@end @end
/* interfaces exposed so that categories can be created from them */
@interface GCSPostgreSQLSpecialQueries : GCSSpecialQueries
@end
@interface GCSMySQLSpecialQueries : GCSSpecialQueries
@end
@interface GCSOracleSpecialQueries : GCSSpecialQueries
@end
#endif /* GCSSPECIALQUERIES_H */ #endif /* GCSSPECIALQUERIES_H */

View file

@ -27,15 +27,6 @@
#import "GCSSpecialQueries.h" #import "GCSSpecialQueries.h"
@interface GCSPostgreSQLSpecialQueries : GCSSpecialQueries
@end
@interface GCSMySQLSpecialQueries : GCSSpecialQueries
@end
@interface GCSOracleSpecialQueries : GCSSpecialQueries
@end
@implementation EOAdaptorChannel (GCSSpecialQueries) @implementation EOAdaptorChannel (GCSSpecialQueries)
- (GCSSpecialQueries *) specialQueries - (GCSSpecialQueries *) specialQueries
@ -163,7 +154,7 @@
{ {
static NSString *sqlFolderFormat static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ (\n" = (@"CREATE TABLE %@ (\n"
@" c_name VARCHAR (255) NOT NULL PRIMARY KEY,\n" @" c_name VARCHAR (255) PRIMARY KEY,\n"
@" c_content TEXT NOT NULL,\n" @" c_content TEXT NOT NULL,\n"
@" c_creationdate INT4 NOT NULL,\n" @" c_creationdate INT4 NOT NULL,\n"
@" c_lastmodified INT4 NOT NULL,\n" @" c_lastmodified INT4 NOT NULL,\n"
@ -190,7 +181,7 @@
{ {
static NSString *sqlFolderFormat static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ (" = (@"CREATE TABLE %@ ("
@" c_id VARCHAR(255) NOT NULL PRIMARY KEY," @" c_id VARCHAR(255) PRIMARY KEY,"
@" c_value VARCHAR(255) NOT NULL," @" c_value VARCHAR(255) NOT NULL,"
@" c_creationdate INT4 NOT NULL," @" c_creationdate INT4 NOT NULL,"
@" c_lastseen INT4 NOT NULL)"); @" c_lastseen INT4 NOT NULL)");
@ -257,7 +248,7 @@
{ {
static NSString *sqlFolderFormat static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ (\n" = (@"CREATE TABLE %@ (\n"
@" c_name VARCHAR (255) NOT NULL PRIMARY KEY,\n" @" c_name VARCHAR (255) PRIMARY KEY,\n"
@" c_content MEDIUMTEXT NOT NULL,\n" @" c_content MEDIUMTEXT NOT NULL,\n"
@" c_creationdate INT NOT NULL,\n" @" c_creationdate INT NOT NULL,\n"
@" c_lastmodified INT NOT NULL,\n" @" c_lastmodified INT NOT NULL,\n"
@ -284,7 +275,7 @@
{ {
static NSString *sqlFolderFormat static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ (" = (@"CREATE TABLE %@ ("
@" c_id VARCHAR(255) NOT NULL PRIMARY KEY," @" c_id VARCHAR(255) PRIMARY KEY,"
@" c_value VARCHAR(255) NOT NULL," @" c_value VARCHAR(255) NOT NULL,"
@" c_creationdate INT NOT NULL," @" c_creationdate INT NOT NULL,"
@" c_lastseen INT NOT NULL)"); @" c_lastseen INT NOT NULL)");
@ -351,7 +342,7 @@
{ {
static NSString *sqlFolderFormat static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ (\n" = (@"CREATE TABLE %@ (\n"
@" c_name VARCHAR2 (255) NOT NULL PRIMARY KEY,\n" @" c_name VARCHAR2 (255) PRIMARY KEY,\n"
@" c_content CLOB NOT NULL,\n" @" c_content CLOB NOT NULL,\n"
@" c_creationdate INTEGER NOT NULL,\n" @" c_creationdate INTEGER NOT NULL,\n"
@" c_lastmodified INTEGER NOT NULL,\n" @" c_lastmodified INTEGER NOT NULL,\n"
@ -377,7 +368,7 @@
{ {
static NSString *sqlFolderFormat static NSString *sqlFolderFormat
= (@"CREATE TABLE %@ (" = (@"CREATE TABLE %@ ("
@" c_id VARCHAR2(255) NOT NULL PRIMARY KEY," @" c_id VARCHAR2(255) PRIMARY KEY,"
@" c_value VARCHAR2(255) NOT NULL," @" c_value VARCHAR2(255) NOT NULL,"
@" c_creationdate INTEGER NOT NULL," @" c_creationdate INTEGER NOT NULL,"
@" c_lastseen INTEGER NOT NULL)"); @" c_lastseen INTEGER NOT NULL)");

View file

@ -177,6 +177,9 @@
{ {
if ((self = [self init])) if ((self = [self init]))
{ {
if ([_name length] == 0)
[NSException raise: NSInvalidArgumentException
format: @"'_name' must not be an empty string"];
context = [[WOApplication application] context]; context = [[WOApplication application] context];
nameInContainer = [_name copy]; nameInContainer = [_name copy];
container = _container; container = _container;

View file

@ -2,6 +2,6 @@
# This file is included by library makefiles to set the version information # This file is included by library makefiles to set the version information
# of the executable. # of the executable.
MAJOR_VERSION=1 MAJOR_VERSION=2
MINOR_VERSION=3 MINOR_VERSION=0
SUBMINOR_VERSION=17 SUBMINOR_VERSION=0