+2004-08-14 Helge Hess <helge.hess@skyrix.com>
+
+ * v0.9.1
+
+ * OCSiCalFieldExtractor.m: extract new quick fields: location,
+ partmails, sequence (does not yet handle allday and cycle due to
+ NGiCal restrictions)
+
+ * appointment.ocs, sql/foldertablecreate-helge-privcal.psql,
+ sql/testapt-agenor-helge-privcal.psql, sql/appointment-create.psql:
+ added quick fields: isallday, iscycle, location, partmails, sequence
+
+ * started ocs_recreatequick tool intended for recreating a quick table
+ based on the content table of a folder
+
2004-07-20 Helge Hess <helge.hess@opengroupware.org>
* OCSChannelManager.m: fixed a bug in the channel GC which resulted
include ./Version
LIBRARY_NAME = libOGoContentStore
-TOOL_NAME = ocs_ls ocs_mkdir ocs_cat
+TOOL_NAME = ocs_ls ocs_mkdir ocs_cat ocs_recreatequick
libOGoContentStore_HEADER_FILES_DIR = .
libOGoContentStore_HEADER_FILES_INSTALL_DIR = /OGoContentStore
ocs_ls_OBJC_FILES += ocs_ls.m
ocs_mkdir_OBJC_FILES += ocs_mkdir.m
ocs_cat_OBJC_FILES += ocs_cat.m
+ocs_recreatequick_OBJC_FILES += ocs_recreatequick.m
-include GNUmakefile.preamble
include $(GNUSTEP_MAKEFILES)/library.make
-lNGExtensions -lEOControl \
-lDOM -lSaxObjC
-ocs_ls_TOOL_LIBS += $(OCS_TOOL_LIBS)
-ocs_mkdir_TOOL_LIBS += $(OCS_TOOL_LIBS)
-ocs_cat_TOOL_LIBS += $(OCS_TOOL_LIBS)
+ocs_ls_TOOL_LIBS += $(OCS_TOOL_LIBS)
+ocs_mkdir_TOOL_LIBS += $(OCS_TOOL_LIBS)
+ocs_cat_TOOL_LIBS += $(OCS_TOOL_LIBS)
+ocs_recreatequick_TOOL_LIBS += $(OCS_TOOL_LIBS)
ADDITIONAL_INCLUDE_DIRS += -I. -I..
- (NSMutableDictionary *)extractQuickFieldsFromEvent:(iCalEvent *)_event {
NSMutableDictionary *row;
NSCalendarDate *startDate, *endDate;
- NSString *uid;
- NSString *title;
- id participants;
+ NSString *uid, *title, *location, *sequence;
+ id participants, partmails;
if (_event == nil)
return nil;
endDate = [_event endDate];
uid = [_event uid];
title = [_event summary];
+ location = [_event location];
+ sequence = [_event sequence];
- participants = [[_event attendees] valueForKey:@"cn"];
+ participants = [_event attendees];
+ partmails = [participants valueForKey:@"email"];
+ partmails = [partmails componentsJoinedByString:@", "];
+ participants = [participants valueForKey:@"cn"];
participants = [participants componentsJoinedByString:@", "];
+ // TODO: cyclic/allday (not supported by NGiCal)
+
/* build row */
row = [NSMutableDictionary dictionaryWithCapacity:8];
-
- if ([title isNotNull]) [row setObject:title forKey:@"title"];
- if ([uid isNotNull]) [row setObject:uid forKey:@"uid"];
+
+ if ([uid isNotNull])
+ [row setObject:uid forKey:@"uid"];
+ else
+ [self logWithFormat:@"WARNING: could not extract a uid from event!"];
+
+ if ([title isNotNull]) [row setObject:title forKey:@"title"];
+ if ([location isNotNull]) [row setObject:location forKey:@"location"];
+ if ([sequence isNotNull]) [row setObject:sequence forKey:@"sequence"];
if ([startDate isNotNull])
[row setObject:[self numberForDate:startDate] forKey:@"startdate"];
if ([endDate isNotNull])
[row setObject:[self numberForDate:endDate] forKey:@"enddate"];
-
+
if ([participants length] > 0)
[row setObject:participants forKey:@"participants"];
+ if ([partmails length] > 0)
+ [row setObject:partmails forKey:@"partmails"];
return row;
}
- we need to parse the BLOB for different clients anyway (iCal != iCal ...)
- XML: we could use some XML query extension to PG in the future?
+Update: we now have OCSiCalFieldExtractor
+ - it parses the BLOB as an iCalendar file and extracts a set of fixed
+ keys:
+ - title - plain copy of "summary"
+ - uid - plain copy
+ - startdate - date as utime
+ - enddate - date as utime
+ - participants - CNs of attendees separated by comma ", "
+ - location
+ - partmails
+ - sequence
+ - TBD: iscyclic
+ - TBD: isallday
+ - TBD: cycles - I guess the client should fetch the BLOB to resolve
+ - the field extractor is accessed by OCSFolder using the folderinfo:
+ extractor = [self->folderInfo quickExtractor];
+ quickRow = [extractor extractQuickFieldsFromContent:_content];
+
+- vCard
+ - we don't have a vCard parser yet
+ - except the one by Max, we could use it
+
Support Tools
=============
MAJOR_VERSION=0
MINOR_VERSION=9
-SUBMINOR_VERSION:=0
+SUBMINOR_VERSION:=1
sqlType = "VARCHAR(1000000)";
allowsNull = NO;
},
+ {
+ columnName = isallday;
+ sqlType = "INT";
+ allowsNull = YES;
+ },
+ {
+ columnName = iscycle;
+ sqlType = "INT";
+ allowsNull = YES;
+ },
+ {
+ columnName = location;
+ sqlType = "VARCHAR(256)";
+ allowsNull = YES;
+ },
+ {
+ columnName = partmails;
+ sqlType = "VARCHAR(100000)";
+ allowsNull = NO;
+ },
+ {
+ columnName = sequence;
+ sqlType = "INT";
+ allowsNull = YES;
+ },
);
}
--- /dev/null
+// $Id: ocs_mkdir.m 113 2004-06-30 11:26:54Z znek $
+
+#import <Foundation/NSObject.h>
+
+@class NSUserDefaults;
+@class OCSFolderManager;
+
+@interface Tool : NSObject
+{
+ NSUserDefaults *ud;
+ OCSFolderManager *folderManager;
+}
+
++ (int)run;
+- (int)run;
+
+@end
+
+#include <OGoContentStore/OCSFolder.h>
+#include <OGoContentStore/OCSFolderManager.h>
+#include "common.h"
+
+@implementation Tool
+
+- (id)init {
+ if ((self = [super init])) {
+ self->ud = [[NSUserDefaults standardUserDefaults] retain];
+ self->folderManager = [[OCSFolderManager defaultFolderManager] retain];
+ }
+ return self;
+}
+- (void)dealloc {
+ [self->ud release];
+ [self->folderManager release];
+ [super dealloc];
+}
+
+/* operation */
+
+- (int)runOnPath:(NSString *)_path {
+ NSException *error;
+ OCSFolder *folder;
+
+ [self logWithFormat:@"update quick from store at path: '%@'", _path];
+
+ if (![self->folderManager folderExistsAtPath:_path]) {
+ [self logWithFormat:@"no folder exist at path: '%@'", _path];
+ return 1;
+ }
+
+ if ((folder = [self->folderManager folderAtPath:_path]) == nil) {
+ [self logWithFormat:@"got no folder object for path: '%@'", _path];
+ return 2;
+ }
+ [self logWithFormat:@" folder: %@", folder];
+
+ // TODO:
+ [self logWithFormat:@" should recreate folder .."];
+
+ return 0;
+}
+
+- (int)run {
+ NSEnumerator *e;
+ NSString *type;
+ NSString *path;
+
+ [self logWithFormat:@"manager: %@", self->folderManager];
+
+ if (![self->folderManager canConnect]) {
+ [self logWithFormat:@"cannot connect folder-info database!"];
+ return 1;
+ }
+
+ e = [[[NSProcessInfo processInfo] argumentsWithoutDefaults]
+ objectEnumerator];
+ [e nextObject]; // skip tool name
+
+ while ((path = [e nextObject]))
+ [self runOnPath:path];
+
+ return 0;
+}
++ (int)run {
+ return [(Tool *)[[[self alloc] init] autorelease] run];
+}
+
+@end /* Tool */
+
+int main(int argc, char **argv, char **env) {
+ NSAutoreleasePool *pool;
+ int rc;
+
+ pool = [[NSAutoreleasePool alloc] init];
+#if LIB_FOUNDATION_LIBRARY
+ [NSProcessInfo initializeWithArguments:argv count:argc environment:env];
+#endif
+
+ rc = [Tool run];
+
+ [pool release];
+ return rc;
+}
--- /dev/null
+# $Id$
+
+Files
+=====
+
+appointment-create.psql
+- this is a template for creating appointment quick/blob tables
+- not used by code atm
+
+folderinfo-create.psql
+- create folder info table (folder registry table)
+- insert some folders per default:
+ - /Users
+ - /Users/helge
+ - /Users/helge/Calendar
+
+foldertablecreate-root.psql
+- insert "/" and "/Users" parent folders (without storage, quick and type)
+
+foldertablecreate-helge-privcal.psql
+- create a quick and content table for 'helge/Calendar' folder
+
+register-agenor-helge-privcal.psql
+- register folder "/Users/helge/Calendar" folder in the registry table with
+ a link to the proper quick and content tables
+
+testapt-agenor-helge-privcal.psql
+- insert a raw iCalendar test appointment in the /Users/helge/Calendar
+ folder quick and content tables
startdate INT NOT NULL,
enddate INT NOT NULL,
title VARCHAR(1000) NOT NULL,
- participants VARCHAR(100000) NOT NULL
+ participants VARCHAR(100000) NOT NULL, -- the CNs of the participants
+ isallday INT NULL,
+ iscycle INT NULL, -- client needs to fetch to resolve
+ location VARCHAR(256) NULL,
+ partmails VARCHAR(100000) NOT NULL, -- the emails of the participants
+ sequence INT NULL -- the iCal sequence
);
CREATE TABLE %s_blob (
startdate INT NOT NULL,
enddate INT NOT NULL,
title VARCHAR(1000) NOT NULL,
- participants VARCHAR(100000) NOT NULL
+ participants VARCHAR(100000) NOT NULL, -- the CNs of the participants
+ isallday INT NULL,
+ iscycle INT NULL, -- client needs to fetch to resolve
+ location VARCHAR(256) NULL,
+ partmails VARCHAR(100000) NOT NULL, -- the emails of the participants
+ sequence INT NULL -- the iCal sequence
);
CREATE TABLE SOGo_helge_privcal (
);
INSERT INTO SOGo_helge_privcal_quick
- ( c_name, uid, startdate, enddate, title, participants )
+ ( c_name, uid, startdate, enddate, title, participants, isallday, iscycle,
+ location, partmails, sequence )
VALUES (
'BD91C454-AA65-11D8-84CA-000D93C1A604',
'BD91C454-AA65-11D8-84CA-000D93C1A604',
1092146400,
1092150000,
'SIZE EVENT',
- 'Elke Bethke, Erik Doernenburg, Christian Schnelle, Chris Herrenberger, Horst Parplies, Imdat Solak, Jens Enders, Jens Muenster, Laurent Pierre, Marcel Weiher'
+ 'Elke Bethke, Erik Doernenburg, Christian Schnelle, Chris Herrenberger, Horst Parplies, Imdat Solak, Jens Enders, Jens Muenster, Laurent Pierre, Marcel Weiher',
+ 0,
+ 0,
+ NULL,
+ 'E.Bethke@Sachsen-Anhalt-Lotto.de, erik@x101.net, cs@enervation.de, nomail, horst.parplies@freenet.de, imdat@solak.de, jens.enders@skyrix.com, jens.muenster@skyrix.com, laurent.pierre@linagora.com, marcel@metaobject.com',
+ 1
);