diff --git a/ChangeLog b/ChangeLog index ecc5c241f..76f19bebf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-03-27 Ludovic Marcotte + + * Added the SOGoLocalStorageURL preference that allows + one to set a different database where resource tables will + be created. If not set, it'll default to the database + specified in OCSFolderInfoURL. This is particularly useful + for multi-sites deployments where the sogo_folder_info and + sogo_user_profile are shared across sites but resources + tables are located at each sites, to minimize bandwitdh + requirements. + 2011-03-24 Wolfgang Sourdeau * UI/Contacts/UIxContactsListView.m (-currentContactClasses): new diff --git a/NEWS b/NEWS index 456898b20..1b0890072 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ Enhancements - updated Spanish translation - "check while typing" is no longer enabled by default in HTML editor - updated CKEditor to version 3.5.2 +- now possible to set a per-instance database storage using the SOGoLocalStorageURL preference Bug Fixes - restored the automatic expunge of IMAP folders - sogo-tool now works in multi-domain environments diff --git a/SOPE/GDLContentStore/GCSFolderManager.h b/SOPE/GDLContentStore/GCSFolderManager.h index 3f4ca95c3..0302895cf 100644 --- a/SOPE/GDLContentStore/GCSFolderManager.h +++ b/SOPE/GDLContentStore/GCSFolderManager.h @@ -67,7 +67,7 @@ - (GCSFolder *)folderAtPath:(NSString *)_path; -- (NSException *)createFolderOfType:(NSString *)_type withName:(NSString *)_name atPath:(NSString *)_path; +- (NSException *)createFolderOfType:(NSString *)_type withName:(NSString *)_name atPath:(NSString *)_path andURL:(NSURL *) _url; - (NSException *)deleteFolderAtPath:(NSString *)_path; /* alarms */ diff --git a/SOPE/GDLContentStore/GCSFolderManager.m b/SOPE/GDLContentStore/GCSFolderManager.m index 6b998734d..c4e0bbcee 100644 --- a/SOPE/GDLContentStore/GCSFolderManager.m +++ b/SOPE/GDLContentStore/GCSFolderManager.m @@ -725,32 +725,46 @@ static NSCharacterSet *asciiAlphaNumericCS = nil; - (NSException *) _reallyCreateFolderWithName: (NSString *) folderName andFolderType: (NSString *) folderType andType: (GCSFolderType *) ftype - andChannel: (EOAdaptorChannel *) channel + andFolderChannel: (EOAdaptorChannel *) folderChannel + andFolderInfoChannel: (EOAdaptorChannel *) folderInfoChannel atPath: (NSString *) path + andURL: (NSURL *) url { - NSException *error; - NSString *baseURL, *tableName, *quickTableName, *aclTableName, *createQuery, - *sql; - EOAdaptorContext *aContext; - NSMutableArray *paths; + NSString *baseURL, *tableName, *quickTableName, *aclTableName, *createQuery, *sql; + EOAdaptorContext *folderChannelContext, *folderInfoChannelContext; GCSSpecialQueries *specialQuery; + NSMutableArray *paths; + NSException *error; + BOOL b; paths = [NSMutableArray arrayWithArray: [path componentsSeparatedByString: @"/"]]; while ([paths count] < 5) [paths addObject: @"NULL"]; - aContext = [channel adaptorContext]; - [aContext beginTransaction]; + // start a transaction to modify sogo_folder_info + folderInfoChannelContext = [folderInfoChannel adaptorContext]; + [folderInfoChannelContext beginTransaction]; + + // if we use a different database for resource tables, we also start a transaction + if (folderChannel != folderInfoChannel) + { + folderChannelContext = [folderChannel adaptorContext]; + [folderChannelContext beginTransaction]; + b = YES; + } tableName = [self baseTableNameWithUID: [paths objectAtIndex: 2]]; quickTableName = [tableName stringByAppendingString: @"_quick"]; aclTableName = [tableName stringByAppendingString: @"_acl"]; - // TBD: fix SQL injection issues - baseURL - = [[folderInfoLocation absoluteString] stringByDeletingLastPathComponent]; - + // holds the path to the database + baseURL = [url absoluteString]; + + if (!url) + baseURL = [[folderInfoLocation absoluteString] stringByDeletingLastPathComponent]; + + // TBD: fix SQL injection issues sql = [NSString stringWithFormat: @"INSERT INTO %@" @" (c_path, c_path1, c_path2, c_path3, c_path4," @" c_foldername, c_location, c_quick_location," @@ -765,29 +779,36 @@ static NSCharacterSet *asciiAlphaNumericCS = nil; baseURL, quickTableName, baseURL, aclTableName, folderType]; - error = [channel evaluateExpressionX: sql]; + error = [folderInfoChannel evaluateExpressionX: sql]; if (!error) { - specialQuery = [channel specialQueries]; + specialQuery = [folderChannel specialQueries]; createQuery = [specialQuery createFolderTableWithName: tableName]; - error = [channel evaluateExpressionX: createQuery]; + error = [folderChannel evaluateExpressionX: createQuery]; if (!error) { sql = [ftype sqlQuickCreateWithTableName: quickTableName]; - error = [channel evaluateExpressionX: sql]; + error = [folderChannel evaluateExpressionX: sql]; if (!error) { - createQuery = [specialQuery - createFolderACLTableWithName: aclTableName]; - error = [channel evaluateExpressionX: createQuery]; + createQuery = [specialQuery createFolderACLTableWithName: aclTableName]; + error = [folderChannel evaluateExpressionX: createQuery]; } } } if (error) - [aContext rollbackTransaction]; + { + [folderInfoChannelContext rollbackTransaction]; + if (b) + [folderChannelContext rollbackTransaction]; + } else - [aContext commitTransaction]; + { + [folderInfoChannelContext commitTransaction]; + if (b) + [folderChannelContext commitTransaction]; + } return error; } @@ -795,11 +816,12 @@ static NSCharacterSet *asciiAlphaNumericCS = nil; - (NSException *) createFolderOfType: (NSString *) _type withName: (NSString*) _name atPath: (NSString *) _path + andURL: (NSURL *) _url { // TBD: would be best to perform all operations as a single SQL statement. - GCSFolderType *ftype; - EOAdaptorChannel *channel; - NSException *error; + EOAdaptorChannel *folderChannel, *folderInfoChannel; + GCSFolderType *ftype; + NSException *error; // TBD: fix SQL injection issue! if ([self folderExistsAtPath: _path]) @@ -811,17 +833,34 @@ static NSCharacterSet *asciiAlphaNumericCS = nil; ftype = [self folderTypeWithName:_type]; if (ftype) { - channel = [self acquireOpenChannel]; - if (channel) + folderInfoChannel = [self acquireOpenChannel]; + folderChannel = nil; + + // We use the provided alternate database, if any. The content, + // quick and acl tables will be created in there. + if (_url) + folderChannel = [[self channelManager] acquireOpenChannelForURL: _url]; + + // Otherwise we use the same database used by sogo_folder_info + if (!folderChannel) + folderChannel = folderInfoChannel; + + if (folderChannel) { error = [self _reallyCreateFolderWithName: _name andFolderType: _type - andType: ftype andChannel: channel - atPath: _path]; + andType: ftype + andFolderChannel: folderChannel + andFolderInfoChannel: folderInfoChannel + atPath: _path + andURL: _url]; if (error && [self folderExistsAtPath: _path]) error = nil; - [self releaseChannel: channel]; + if (folderChannel != folderInfoChannel) + [self releaseChannel: folderChannel]; + + [self releaseChannel: folderInfoChannel]; } else error = [NSException exceptionWithName: @"GCSNoChannel" diff --git a/SoObjects/SOGo/SOGoFolder.m b/SoObjects/SOGo/SOGoFolder.m index ea89273ae..9079816b8 100644 --- a/SoObjects/SOGo/SOGoFolder.m +++ b/SoObjects/SOGo/SOGoFolder.m @@ -1,6 +1,6 @@ /* SOGoFolder.m - this file is part of SOGo * - * Copyright (C) 2007-2009 Inverse inc. + * Copyright (C) 2007-2011 Inverse inc. * * Author: Wolfgang Sourdeau * diff --git a/SoObjects/SOGo/SOGoGCSFolder.h b/SoObjects/SOGo/SOGoGCSFolder.h index 8a85ee59f..7b8a4c1d6 100644 --- a/SoObjects/SOGo/SOGoGCSFolder.h +++ b/SoObjects/SOGo/SOGoGCSFolder.h @@ -1,6 +1,6 @@ /* Copyright (C) 2004-2005 SKYRIX Software AG - Copyright (C) 2006-2010 Inverse inc. + Copyright (C) 2006-2011 Inverse inc. This file is part of SOGo. diff --git a/SoObjects/SOGo/SOGoGCSFolder.m b/SoObjects/SOGo/SOGoGCSFolder.m index 81e696237..0ac2e0872 100644 --- a/SoObjects/SOGo/SOGoGCSFolder.m +++ b/SoObjects/SOGo/SOGoGCSFolder.m @@ -1,7 +1,7 @@ /* SOGoGCSFolder.m - this file is part of SOGo * * Copyright (C) 2004-2005 SKYRIX Software AG - * Copyright (C) 2006-2010 Inverse inc. + * Copyright (C) 2006-2011 Inverse inc. * * Author: Wolfgang Sourdeau * @@ -70,6 +70,7 @@ #import "SOGoParentFolder.h" #import "SOGoPermissions.h" #import "SOGoUser.h" +#import "SOGoSystemDefaults.h" #import "SOGoUserDefaults.h" #import "SOGoUserSettings.h" #import "SOGoUserManager.h" @@ -525,12 +526,34 @@ static NSArray *childRecordFields = nil; } } +// +// This method honors the SOGoLocalStorageURL preference in order +// to create the database tables at the preferred location instead of +// creating them in the same database as the one specified in the +// OCSFolderInfoURL preference. This is particularly useful for +// multi-sites deployments. +// - (BOOL) create { + GCSFolderManager *folderManager; + EOAdaptorChannel *channel; NSException *result; - result = [[self folderManager] createFolderOfType: [self folderType] - withName: displayName - atPath: ocsPath]; + NSString *s; + NSURL *url; + + folderManager = [self folderManager]; + channel = nil; + + s = [[SOGoSystemDefaults sharedSystemDefaults] stringForKey: @"SOGoLocalStorageURL"]; + url = nil; + + if (s) + url = [NSURL URLWithString: s]; + + result = [folderManager createFolderOfType: [self folderType] + withName: displayName + atPath: ocsPath + andURL: url]; if (!result && [[context request] handledByDefaultHandler])