+2004-10-19 Helge Hess <helge.hess@opengroupware.org>
+
+ * OCSFolder.m: added new method -fetchContentsOfAllFiles method which
+ fetches the contents of all files stored in the folder (required for
+ iCal generation, such bulk fetches should be avoided if possible!)
+ (v0.9.13)
+
2004-10-15 Marcus Mueller <znek@mulle-kybernetik.com>
* OCSStringFormatter.[hm]: minor cleanup (v0.9.12)
#import <Foundation/NSObject.h>
@class NSString, NSURL, NSNumber, NSArray, NSException, NSMutableString;
+@class NSDictionary;
@class EOQualifier, EOFetchSpecification;
@class EOAdaptorChannel;
@class OCSFolderManager, OCSFolderType, OCSChannelManager;
- (NSException *)writeContent:(NSString *)_content toName:(NSString *)_name;
- (NSException *)deleteContentWithName:(NSString *)_name;
+- (NSDictionary *)fetchContentsOfAllFiles;
+
- (NSArray *)fetchFields:(NSArray *)_flds
fetchSpecification:(EOFetchSpecification *)_fs;
- (NSArray *)fetchFields:(NSArray *)_flds matchingQualifier:(EOQualifier *)_q;
inContentWithName:_name];
}
+- (NSDictionary *)fetchContentsOfAllFiles {
+ /*
+ Note: try to avoid the use of this method! The key of the dictionary
+ will be filename, the value the content.
+ */
+ NSMutableDictionary *result;
+ EOAdaptorChannel *channel;
+ NSException *error;
+ NSDictionary *row;
+ NSArray *attrs;
+ NSString *sql;
+
+ if ((channel = [self acquireStoreChannel]) == nil) {
+ [self logWithFormat:@"ERROR(%s): could not open storage channel!",
+ __PRETTY_FUNCTION__];
+ return nil;
+ }
+
+ /* generate SQL */
+
+ sql = @"SELECT \"c_name\", \"c_content\" FROM ";
+ sql = [sql stringByAppendingString:[self storeTableName]];
+
+ /* run SQL */
+
+ if ((error = [channel evaluateExpressionX:sql]) != nil) {
+ [self logWithFormat:@"ERROR(%s): cannot execute SQL '%@': %@",
+ __PRETTY_FUNCTION__, sql, error];
+ [self releaseChannel:channel];
+ return nil;
+ }
+
+ /* fetch results */
+
+ result = [NSMutableDictionary dictionaryWithCapacity:128];
+ attrs = [channel describeResults];
+ while ((row = [channel fetchAttributes:attrs withZone:NULL]) != nil) {
+ NSString *cName, *cContent;
+
+ cName = [row objectForKey:@"cName"];
+ cContent = [row objectForKey:@"cContent"];
+
+ if (![cName isNotNull]) {
+ [self logWithFormat:@"ERROR: missing cName in row: %@", row];
+ continue;
+ }
+ if (![cContent isNotNull]) {
+ [self logWithFormat:@"ERROR: missing cContent in row: %@", row];
+ continue;
+ }
+
+ [result setObject:cContent forKey:cName];
+ }
+
+ /* release and return result */
+
+ [self releaseChannel:channel];
+ return result;
+}
+
/* writing content */
- (NSString *)_formatRowValue:(id)_value {
MAJOR_VERSION=0
MINOR_VERSION=9
-SUBMINOR_VERSION:=12
+SUBMINOR_VERSION:=13
# v0.9.11 requires libFoundation v1.0.63
# v0.9.11 requires libNGExtensions v4.3.125
2004-10-19 Helge Hess <helge.hess@opengroupware.org>
+ * moved fetch method to a direct action SoMethod (v0.9.3)
+
* SOGoICalHTTPHandler.m: some work on assembly support (v0.9.2)
2004-10-08 Helge Hess <helge.hess@opengroupware.org>
* created ChangeLog
-
iCalHTTP_OBJC_FILES = \
iCalHTTPProduct.m \
SOGoICalHTTPHandler.m \
+ SOGoICalFileFetch.m \
iCalHTTP_RESOURCE_FILES += \
Version \
--- /dev/null
+/*
+ Copyright (C) 2004 SKYRIX Software AG
+
+ This file is part of OpenGroupware.org.
+
+ OGo is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ OGo 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with OGo; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.
+*/
+
+#include <NGObjWeb/WODirectAction.h>
+
+@interface SOGoICalFileFetch : WODirectAction
+{
+}
+
+@end
+
+#include "SOGoICalHTTPHandler.h"
+#include <SOGo/SoObjects/Appointments/SOGoAppointmentFolder.h>
+#include <SOGoLogic/SOGoAppointment.h>
+#include "common.h"
+
+@implementation SOGoICalFileFetch
+
+- (id)clientObject {
+ return [[super clientObject] aptFolderInContext:[self context]];
+}
+
+- (id)defaultAction {
+ NSArray *events;
+
+ [self logWithFormat:@"assemble iCal events ..."];
+ events = [[self clientObject] fetchAllSOGoAppointments];
+ [self logWithFormat:@" events: %@", events];
+
+ return nil;
+}
+
+@end /* SOGoICalFileFetch */
Object to represent a SOGoAppointmentFolder as a single iCalendar file.
*/
+@class SOGoAppointmentFolder;
+
@interface SOGoICalHTTPHandler : NSObject
{
// TODO: remember for ivars: there is _one_ handler per class! Not per ctx!
}
+- (SOGoAppointmentFolder *)aptFolderInContext:(id)_ctx;
+
@end
#endif /* __iCalHTTP_SOGoICalHTTPHandler_H__ */
*/
#include "SOGoICalHTTPHandler.h"
+#include <SOGo/SoObjects/Appointments/SOGoAppointmentFolder.h>
#include "common.h"
#include <NGObjWeb/WOContext+SoObjects.h>
/* clientObject */
-- (id)clientObjectInContext:(id)_ctx {
+- (SOGoAppointmentFolder *)aptFolderInContext:(id)_ctx {
/*
The handler object is _not_ a method, its just a regular object
itself! (because methods are defined on it).
*/
+ SOGoAppointmentFolder *folder;
NSArray *stack;
stack = [_ctx objectTraversalStack];
return nil;
}
- if ([stack lastObject] != self) // TODO: hm, hm, not really OK
- return [stack lastObject];
-
- return [stack objectAtIndex:[stack count] - 2];
-}
-
-/* fetching */
-
-- (NSArray *)storedNamesInContext:(id)_ctx {
- /* the client object will cache the names */
- return [[self clientObjectInContext:_ctx] toOneRelationshipKeys];
+ folder = ([stack lastObject] != self) // TODO: hm, hm, not really OK
+ ? [stack lastObject]
+ : [stack objectAtIndex:[stack count] - 2];
+ if (![folder isKindOfClass:NSClassFromString(@"SOGoAppointmentFolder")]) {
+ [self logWithFormat:@"ERROR: unexpected object in stack: %@", folder];
+ return nil;
+ }
+ return folder;
}
/* actions */
-- (id)assembleEventsInContext:(id)_ctx {
- [self logWithFormat:@"assemble iCal events ..."];
- [self logWithFormat:@" names: %@", [self storedNamesInContext:_ctx]];
- return self;
-}
-
- (id)updateEventsInContext:(id)_ctx {
[self logWithFormat:@"updates iCal events from a full collection ..."];
return [NSException exceptionWithHTTPStatus:501 /* Not Implemented */
# $Id: Version 368 2004-10-06 19:28:12Z znek $
-SUBMINOR_VERSION:=2
+SUBMINOR_VERSION:=3
methods = {
GET = {
protectedBy = "View";
- selector = {
- name = "assembleEventsInContext:";
- addContextParameter = YES;
- };
+ actionClass = "SOGoICalFileFetch";
};
PUT = {
protectedBy = "View";
+2004-10-19 Helge Hess <helge.hess@opengroupware.org>
+
+ * SOGoAppointmentFolder.h: added -fetchAllSOGoAppointments method
+ which performs a bulk fetch on all files contained in the folder
+ and parses all contents into an array of SOGoAppointment objects
+ (used in the iCal file support, try to avoid this method, expensive!)
+ (v0.9.13)
+
2004-09-25 Helge Hess <helge.hess@opengroupware.org>
* fixed compilation on MacOSX (v0.9.12)
- (id)lookupGroupFolderForUIDs:(NSArray *)_uids inContext:(id)_ctx;
- (id)lookupGroupCalendarFolderForUIDs:(NSArray *)_uids inContext:(id)_ctx;
+/* bulk fetches */
+
+- (NSArray *)fetchAllSOGoAppointments;
+
@end
#endif /* __Appointments_SOGoAppointmentFolder_H__ */
return folder;
}
+/* bulk fetches */
+
+- (NSArray *)fetchAllSOGoAppointments {
+ /*
+ Note: very expensive method, do not use unless absolutely required.
+ returns an array of SOGoAppointment objects.
+
+ Note that we can leave out the filenames, supposed to be stored
+ in the 'uid' field of the iCalendar object!
+ */
+ NSMutableArray *events;
+ NSDictionary *files;
+ NSEnumerator *contents;
+ NSString *content;
+
+ /* fetch all raw contents */
+
+ files = [self fetchContentStringsAndNamesOfAllObjects];
+ if (![files isNotNull]) return nil;
+ if ([files isKindOfClass:[NSException class]]) return (id)files;
+
+ /* transform to SOGo appointments */
+
+ events = [NSMutableArray arrayWithCapacity:[files count]];
+ contents = [files objectEnumerator];
+ while ((content = [contents nextObject]) != nil) {
+ SOGoAppointment *event;
+
+ event = [[SOGoAppointment alloc] initWithICalString:content];
+ if (![event isNotNull]) {
+ [self logWithFormat:@"ERROR(%s): could not parse an iCal file!",
+ __PRETTY_FUNCTION__];
+ continue;
+ }
+
+ [events addObject:event];
+ [event release];
+ }
+
+ return events;
+}
+
/* GET */
- (id)GETAction:(WOContext *)_ctx {
# $Id: Version,v 1.9 2004/05/19 14:30:45 helge Exp $
-SUBMINOR_VERSION:=12
+SUBMINOR_VERSION:=13
+
+# v0.9.13 requires libSOGo v0.9.26
+2004-10-19 Helge Hess <helge.hess@opengroupware.org>
+
+ * SOGoFolder: added method -fetchContentStringsAndNamesOfAllObjects
+ which fetches the contents of all folders objects (avoid to use this
+ high overhead method!). Required for iCalendar file generation.
+ (v0.9.26)
+
2004-10-08 Helge Hess <helge.hess@opengroupware.org>
* SOGoUserFolder.m: enhanced object lookup so that when a Calendar
#include <SOGo/SOGoObject.h>
+@class NSString, NSArray, NSDictionary;
@class OCSFolder;
+/*
+ SOGoFolder
+
+ A common superclass for folders stored in OCS. Already deals with all OCS
+ folder specific things.
+*/
+
@interface SOGoFolder : SOGoObject
{
NSString *ocsPath;
- (OCSFolder *)ocsFolderForPath:(NSString *)_path;
- (OCSFolder *)ocsFolder;
+/* lower level fetches */
+
+- (NSArray *)fetchContentObjectNames;
+- (NSDictionary *)fetchContentStringsAndNamesOfAllObjects;
+
@end
#endif /* __SOGo_SOGoFolder_H__ */
}
- (NSArray *)fetchContentObjectNames {
- NSArray *fields, *records;
+ NSArray *fields, *records;
fields = [NSArray arrayWithObject:@"c_name"];
records = [[self ocsFolder] fetchFields:fields matchingQualifier:nil];
return records;
return [records valueForKey:@"cName"];
}
+- (NSDictionary *)fetchContentStringsAndNamesOfAllObjects {
+ NSDictionary *files;
+
+ files = [[self ocsFolder] fetchContentsOfAllFiles];
+ if (![files isNotNull]) {
+ [self logWithFormat:@"ERROR(%s): fetch failed!", __PRETTY_FUNCTION__];
+ return nil;
+ }
+ if ([files isKindOfClass:[NSException class]])
+ return files;
+ return files;
+}
/* reflection */
# $Id: Version 170 2004-08-11 10:45:40Z helge $
-SUBMINOR_VERSION:=25
+SUBMINOR_VERSION:=26
+
+# v0.9.26 requires libOGoContentStore v0.9.13
+2004-10-19 Helge Hess <helge.hess@opengroupware.org>
+
+ * SOGoAppointment.m: added a -description (v0.9.20)
+
2004-10-17 Marcus Mueller <znek@mulle-kybernetik.com>
* SOGoAppointmentICalRenderer.m: it's never wrong to escape '\', thus
@interface SOGoAppointment : NSObject
{
- id calendar;
+ id calendar;
iCalEvent *event;
- id participants;
+ id participants;
}
- (id)initWithICalString:(NSString *)_iCal;
return filtered;
}
+/* description */
+
+- (void)appendAttributesToDescription:(NSMutableString *)_ms {
+ [_ms appendFormat:@" uid=%@", [self uid]];
+ [_ms appendFormat:@" date=%@", [self startDate]];
+}
+
+- (NSString *)description {
+ NSMutableString *ms;
+
+ ms = [NSMutableString stringWithCapacity:64];
+ [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])];
+ [self appendAttributesToDescription:ms];
+ [ms appendString:@">"];
+ return ms;
+}
+
@end /* SOGoAppointment */
# $Id$
-SUBMINOR_VERSION:=19
+SUBMINOR_VERSION:=20
# v0.9.18 requires NGExtensions v4.3.123
# v0.9.13 requires libFoundation v1.0.62