#import <Foundation/NSObject.h>
+@class NSString, NSArray;
+
@interface OCSFieldInfo : NSObject
{
+ NSString *columnName;
+ NSString *sqlType;
+ BOOL allowsNull;
+ BOOL isPrimaryKey;
}
++ (NSArray *)fieldsForPropertyList:(NSArray *)_plist;
+- (id)initWithPropertyList:(id)_plist;
+
+/* accessors */
+
+- (NSString *)columnName;
+- (NSString *)sqlType;
+- (BOOL)doesAllowNull;
+- (BOOL)isPrimaryKey;
+
+/* generating SQL */
+
+- (NSString *)sqlCreateSection;
+
@end
#endif /* __OGoContentStore_OCSFieldInfo_H__ */
@implementation OCSFieldInfo
++ (NSArray *)fieldsForPropertyList:(NSArray *)_plist {
+ NSMutableArray *fields;
+ unsigned i, count;
+
+ if (_plist == nil)
+ return nil;
+
+ count = [_plist count];
+ fields = [NSMutableArray arrayWithCapacity:count];
+ for (i = 0; i < count; i++) {
+ OCSFieldInfo *field;
+
+ field = [[OCSFieldInfo alloc] initWithPropertyList:
+ [_plist objectAtIndex:i]];
+ if (field) [fields addObject:field];
+ [field release];
+ }
+ return fields;
+}
+
+- (id)initWithPropertyList:(id)_plist {
+ if ((self = [super init])) {
+ }
+ return self;
+}
+
- (void)dealloc {
+ [self->columnName release];
+ [self->sqlType release];
[super dealloc];
}
+/* accessors */
+
+- (NSString *)columnName {
+ return self->columnName;
+}
+- (NSString *)sqlType {
+ return self->sqlType;
+}
+
+- (BOOL)doesAllowNull {
+ return self->allowsNull;
+}
+- (BOOL)isPrimaryKey {
+ return self->isPrimaryKey;
+}
+
+/* generating SQL */
+
+- (NSString *)sqlCreateSection {
+ NSMutableString *ms;
+
+ ms = [NSMutableString stringWithCapacity:32];
+ [ms appendString:[self columnName]];
+ [ms appendString:@" "];
+ [ms appendString:[self sqlType]];
+
+ [ms appendString:@" "];
+ if (![self doesAllowNull]) [ms appendString:@"NOT "];
+ [ms appendString:@"NULL"];
+
+ if ([self isPrimaryKey]) [ms appendString:@" PRIMARY KEY"];
+ return ms;
+}
+
+/* description */
+
+- (NSString *)description {
+ NSMutableString *ms;
+ id tmp;
+
+ ms = [NSMutableString stringWithCapacity:256];
+ [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])];
+
+ if ((tmp = [self columnName])) [ms appendFormat:@" column=%@", tmp];
+ if ((tmp = [self sqlType])) [ms appendFormat:@" sql=%@", tmp];
+ if ([self doesAllowNull]) [ms appendString:@" allows-null"];
+ if ([self isPrimaryKey]) [ms appendString:@" pkey"];
+
+ [ms appendString:@">"];
+ return ms;
+}
+
@end /* OCSFieldInfo */
return nil;
}
if ((self = [super init])) {
+ OCSFolderType *cal;
+
self->channelManager = [[OCSChannelManager defaultChannelManager] retain];
self->folderInfoLocation = [_url retain];
+ cal = [[OCSFolderType alloc] initWithFolderTypeName:@"appointment"];
self->nameToType =
- [[NSDictionary alloc] initWithObjectsAndKeys:
- [OCSFolderType defaultCalendarFolderType],
- @"appointment", nil];
+ [[NSDictionary alloc] initWithObjectsAndKeys:cal, @"appointment", nil];
+ [cal release]; cal = nil;
}
return self;
}
- (NSException *)createFolderOfType:(NSString *)_type atPath:(NSString *)_path{
// TODO: implement folder create
+ OCSFolderType *ftype;
+
+ if ((ftype = [self folderTypeWithName:_type]) == nil) {
+ return [NSException exceptionWithName:@"OCSMissingFolderType"
+ reason:@"missing folder type"
+ userInfo:nil];
+ }
+
+ [self logWithFormat:@"create folder of type: %@", _type];
+
return [NSException exceptionWithName:@"NotYetImplemented"
reason:@"no money, no time, ..."
userInfo:nil];
#import <Foundation/NSObject.h>
-@class NSString, NSDictionary;
+@class NSString, NSArray, NSDictionary;
@class EOQualifier;
@class OCSFolder;
{
NSString *blobTablePattern; // eg 'SOGo_$folderId$_blob
NSString *quickTablePattern; // eg 'SOGo_$folderId$_quick
- NSDictionary *fields; // maps a name to OCSFieldInfo
+ NSArray *fields; // OCSFieldInfo objects
+ NSDictionary *fieldDict; // maps a name to OCSFieldInfo
EOQualifier *folderQualifier; // to further limit the table set
}
-+ (id)defaultCalendarFolderType;
+- (id)initWithPropertyList:(id)_plist;
+- (id)initWithContentsOfFile:(NSString *)_path;
+- (id)initWithFolderTypeName:(NSString *)_typeName;
/* operations */
- (NSString *)blobTableNameForFolder:(OCSFolder *)_folder;
- (NSString *)quickTableNameForFolder:(OCSFolder *)_folder;
+/* generating SQL */
+
+- (NSString *)sqlQuickCreateWithTableName:(NSString *)_tabName;
+
@end
#endif /* __OGoContentStore_OCSFolderType_H__ */
#include "OCSFolderType.h"
#include "OCSFolder.h"
+#include "OCSFieldInfo.h"
#include "common.h"
#include <EOControl/EOKeyValueCoding.h>
@implementation OCSFolderType
-static OCSFolderType *calendarType = nil;
-
-- (id)initAsCalendarFolderType {
- // TODO: should be moved to a plist file
+- (id)initWithPropertyList:(id)_plist {
if ((self = [super init])) {
- self->blobTablePattern = @"SOGo_$folderId$_blob";
- self->quickTablePattern = @"SOGo_$folderId$_quick";
- self->folderQualifier = nil; // a table per folder
+ self->blobTablePattern = [[_plist objectForKey:@"blobTablePattern"] copy];
+ self->quickTablePattern = [[_plist objectForKey:@"quickTablePattern"]copy];
+ // TODO: qualifier;
- // TODO: which fields?
+ self->fields = [[OCSFieldInfo fieldsForPropertyList:
+ [_plist objectForKey:@"fields"]] retain];
}
return self;
}
-+ (id)defaultCalendarFolderType {
- if (calendarType == nil)
- calendarType = [[self alloc] init];
- return calendarType;
+- (id)initWithContentsOfFile:(NSString *)_path {
+ NSDictionary *plist;
+
+ plist = [NSDictionary dictionaryWithContentsOfFile:_path];
+ if (plist == nil) {
+ NSLog(@"ERROR(%s): could not read dictionary at path %@",
+ __PRETTY_FUNCTION__, _path);
+ [self release];
+ return nil;
+ }
+ return [self initWithPropertyList:plist];
+}
+
+- (id)initWithFolderTypeName:(NSString *)_typeName {
+ // TODO: use GNUSTEP_PATHPREFIX_LIST
+ NSDictionary *env;
+ NSFileManager *fm;
+ NSString *filename, *path;
+
+ env = [[NSProcessInfo processInfo] environment];
+ fm = [NSFileManager defaultManager];
+ filename = [_typeName stringByAppendingPathExtension:@"ocs"];
+
+ path = [env objectForKey:@"GNUSTEP_USER_ROOT"];
+ path = [path stringByAppendingPathComponent:@"Library"];
+ path = [path stringByAppendingPathComponent:@"OCSTypeModels"];
+ path = [path stringByAppendingPathComponent:filename];
+ if ([fm fileExistsAtPath:path])
+ return [self initWithContentsOfFile:path];
+
+ NSLog(@"ERROR(%s): did not find model for type: '%@'",
+ __PRETTY_FUNCTION__, _typeName);
+ [self release];
+ return nil;
}
- (void)dealloc {
[self->blobTablePattern release];
[self->quickTablePattern release];
[self->fields release];
+ [self->fieldDict release];
[self->folderQualifier release];
[super dealloc];
}
requiresAllVariables:NO];
}
+/* generating SQL */
+
+- (NSString *)sqlQuickCreateWithTableName:(NSString *)_tabName {
+ NSMutableString *sql;
+ unsigned i, count;
+
+ sql = [NSMutableString stringWithCapacity:512];
+ [sql appendString:@"CREATE TABLE "];
+ [sql appendString:_tabName];
+ [sql appendString:@" ( "];
+
+ count = [self->fields count];
+ for (i = 0; i < count; i++) {
+ if (i > 0) [sql appendString:@", "];
+
+ [sql appendString:[[self->fields objectAtIndex:i] sqlCreateSection]];
+ }
+
+ [sql appendString:@")"];
+
+ return sql;
+}
+
/* description */
- (NSString *)description {
--- /dev/null
+{
+ blobTablePattern = "SOGo_$folderId$_blob";
+ quickTablePattern = "SOGo_$folderId$_quick";
+
+ fields = (
+ {
+ columnName = pkey;
+ sqlType = "INTEGER";
+ allowsNull = NO;
+ isPrimaryKey = YES;
+ },
+ {
+ columnName = startdate;
+ sqlType = "INT";
+ allowsNull = NO;
+ },
+ {
+ columnName = enddate;
+ sqlType = "INT";
+ allowsNull = NO;
+ },
+ {
+ columnName = title;
+ sqlType = "VARCHAR(1000)";
+ allowsNull = NO;
+ },
+ {
+ columnName = participants;
+ sqlType = "VARCHAR(1000000)";
+ allowsNull = NO;
+ },
+ );
+}
--- /dev/null
+CREATE TABLE %s (
+ pkey INTEGER
+ NOT NULL
+ PRIMARY KEY,
+ startdate INT NOT NULL,
+ enddate INT NOT NULL,
+ title VARCHAR(1000) NOT NULL,
+ participants VARCHAR(100000) NOT NULL
+);