]> err.no Git - sope/commitdiff
applied patch #1850
authorhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Tue, 17 Apr 2007 21:47:07 +0000 (21:47 +0000)
committerhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Tue, 17 Apr 2007 21:47:07 +0000 (21:47 +0000)
git-svn-id: http://svn.opengroupware.org/SOPE/trunk@1471 e4a50df8-12e2-0310-a44c-efbce7f8a7e3

sope-gdl1/GDLContentStore/ChangeLog
sope-gdl1/GDLContentStore/GCSFolder.h
sope-gdl1/GDLContentStore/GCSFolder.m
sope-gdl1/GDLContentStore/GCSFolderManager.h
sope-gdl1/GDLContentStore/GCSFolderManager.m
sope-gdl1/GDLContentStore/Version

index 269d7350955a6ad6413474b2efa0a4cddf26b7dd..4e01dfc57899a7027605a2b7c59ad71f741d5095 100644 (file)
@@ -1,3 +1,12 @@
+2007-04-17  Helge Hess  <helge.hess@opengroupware.org>
+
+       * fixed a few GNUstep compilation warnings (v4.7.42)
+
+2007-03-21  Wolfgang Sourdeau  <WSourdeau@Inverse.CA>
+
+       * GCSFolder.[hm], GCSFolderManager.[hm]: added ability to create and
+         delete GCS folders programmatically (OGo bug #1850) (v4.7.41)
+
 2007-02-12  Helge Hess  <helge.hess@opengroupware.org>
 
        * GCSFolder.m: fixed a gnustep-base compilation warning (v4.7.40)
index 6abd810de0aeb5af0a76510f95769bf84781deb8..e461666cd50346cf074b202a808fcd2412541af1 100644 (file)
 - (NSException *)writeContent:(NSString *)_content toName:(NSString *)_name;
 - (NSException *)deleteContentWithName:(NSString *)_name;
 
+- (NSException *)deleteFolder;
+
 - (NSDictionary *)fetchContentsOfAllFiles;
 
 - (NSArray *)fetchFields:(NSArray *)_flds 
index cdac1c30abc00e4b01a9bf4b60a5738a00e06543..5033c6db27e9ef897873c21ce5db849bdef2fc85 100644 (file)
@@ -367,7 +367,7 @@ static GCSStringFormatter *stringFormatter = nil;
     _value = [_value stringValue];
     return ([(NSString *)_value hasPrefix:@"Y"] || 
            [(NSString *)_value hasPrefix:@"N"])
-      ? ([_value boolValue] ? @"1" : @"0")
+      ? (id)([_value boolValue] ? @"1" : @"0")
       : _value;
 #endif
     return [_value stringValue];
@@ -637,6 +637,7 @@ static GCSStringFormatter *stringFormatter = nil;
   return error;
 }
 
+
 - (NSException *)writeContent:(NSString *)_content toName:(NSString *)_name {
   /* this method does not check for concurrent writes */
   return [self writeContent:_content toName:_name baseVersion:0];
@@ -706,6 +707,41 @@ static GCSStringFormatter *stringFormatter = nil;
   return error;
 }
 
+- (NSException *)deleteFolder {
+  EOAdaptorChannel *channel;
+  NSString *delsql;
+  NSString *table;
+  
+  /* open channels */
+  
+  if ((channel = [self acquireStoreChannel]) == nil) {
+    [self errorWithFormat:@"could not open channel!"];
+    return nil;
+  }
+  
+  /* delete rows */
+
+  table = [self storeTableName];
+  if ([table length] > 0) {
+    delsql = [@"DROP TABLE " stringByAppendingString: table];
+    [channel evaluateExpressionX:delsql];
+  }
+  table = [self quickTableName];
+  if ([table length] > 0) {
+    delsql = [@"DROP TABLE " stringByAppendingString: table];
+    [channel evaluateExpressionX:delsql];
+  }
+  table = [self aclTableName];
+  if ([table length] > 0) {
+    delsql = [@"DROP TABLE  " stringByAppendingString: table];
+    [channel evaluateExpressionX:delsql];
+  }
+  
+  [self releaseChannel:channel];
+
+  return nil;
+}
+
 - (NSString *)columnNameForFieldName:(NSString *)_fieldName {
   return _fieldName;
 }
index 4610ce7d59edeae723b9ed9c76bab2e657647aa7..eaafae84bd0c636d4118365685b80a8543a4d3d5 100644 (file)
@@ -39,6 +39,7 @@
   GCSChannelManager *channelManager;
   NSDictionary      *nameToType;
   NSURL             *folderInfoLocation;
+  NSString          *folderNamePrefix;
 }
 
 + (id)defaultFolderManager;
@@ -46,6 +47,9 @@
 
 /* accessors */
 
+- (void) setFolderNamePrefix:(NSString *)_folderNamePrefix;
+- (NSString *) folderNamePrefix;
+
 - (NSURL *)folderInfoLocation;
 - (NSString *)folderInfoTableName;
 
@@ -68,6 +72,7 @@
 - (GCSFolder *)folderAtPath:(NSString *)_path;
 
 - (NSException *)createFolderOfType:(NSString *)_type atPath:(NSString *)_path;
+- (NSException *)deleteFolderAtPath:(NSString *)_path;
 
 /* folder types */
 
index 3d1adeff5b798ea27d13719342105496b9d901bc..5de55dd9fe0d2bdccbddb9e8146f8c808ae82bfc 100644 (file)
@@ -57,6 +57,7 @@ static NSString   *GCSTypeRecordName        = @"c_folder_type";
 static NSString   *GCSPathRecordName        = @"c_path";
 static NSString   *GCSGenericFolderTypeName = @"Container";
 static const char *GCSPathColumnPattern     = "c_path%i";
+static NSCharacterSet *asciiAlphaNumericCS    = nil;
 
 + (void)initialize {
   NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
@@ -64,6 +65,15 @@ static const char *GCSPathColumnPattern     = "c_path%i";
   debugOn     = [ud boolForKey:@"GCSFolderManagerDebugEnabled"];
   debugSQLGen = [ud boolForKey:@"GCSFolderManagerSQLDebugEnabled"];
   emptyArray  = [[NSArray alloc] init];
+  if (!asciiAlphaNumericCS)
+    {
+      asciiAlphaNumericCS
+       = [NSCharacterSet characterSetWithCharactersInString:
+                           @"0123456789"
+                         @"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                         @"abcdefghijklmnopqrstuvwxyz"];
+      [asciiAlphaNumericCS retain];
+    }
 }
 
 + (id)defaultFolderManager {
@@ -134,6 +144,7 @@ static const char *GCSPathColumnPattern     = "c_path%i";
   if ((self = [super init])) {
     self->channelManager = [[GCSChannelManager defaultChannelManager] retain];
     self->folderInfoLocation = [_url retain];
+    self->folderNamePrefix = nil;
 
     if ([[self folderInfoTableName] length] == 0) {
       [self logWithFormat:@"ERROR(%s): missing tablename in URL: %@", 
@@ -152,11 +163,22 @@ static const char *GCSPathColumnPattern     = "c_path%i";
   [self->nameToType         release];
   [self->folderInfoLocation release];
   [self->channelManager     release];
+  [self->folderNamePrefix   release];
   [super dealloc];
 }
 
 /* accessors */
 
+- (void) setFolderNamePrefix:(NSString *)_folderNamePrefix
+{
+  ASSIGN(self->folderNamePrefix, _folderNamePrefix);
+}
+
+- (NSString *) folderNamePrefix
+{
+  return self->folderNamePrefix;
+}
+
 - (NSURL *)folderInfoLocation {
   return self->folderInfoLocation;
 }
@@ -605,21 +627,186 @@ static const char *GCSPathColumnPattern     = "c_path%i";
   return [self folderForRecord:record];
 }
 
+- (NSString *)sqlCreateWithTableName: (NSString *)_tabName {
+  return [NSString stringWithFormat: @"CREATE TABLE %@ (\n"
+                   @"  c_name VARCHAR (256) NOT NULL,\n"
+                   @"  c_content VARCHAR (100000) NOT NULL,\n"
+                   @"  c_creationdate INT4 NOT NULL,\n"
+                   @"  c_lastmodified INT4 NOT NULL,\n"
+                   @"  c_version INT4 NOT NULL\n"
+                   @")",
+                   _tabName];
+}
+
+- (NSString *)sqlAclCreateWithTableName: (NSString *)_tabName {
+  return [NSString stringWithFormat: @"CREATE TABLE %@ (\n"
+                   @"  c_uid VARCHAR (256) NOT NULL,\n"
+                   @"  c_object VARCHAR (256) NOT NULL,\n"
+                   @"  c_role VARCHAR (80) NOT NULL\n"
+                   @")",
+                   _tabName];
+}
+
+- (NSString *)baseTableNameForFolderAtPath:(NSString *)_path {
+  NSMutableString *fixedPath;
+  unsigned int count, max;
+  unichar currentChar;
+
+  fixedPath = [NSMutableString new];
+  [fixedPath autorelease];
+
+  if (self->folderNamePrefix != nil)
+    [fixedPath appendString: self->folderNamePrefix];
+
+  max = [_path length];
+  for (count = 0; count < max; count++) {
+    currentChar = [_path characterAtIndex: count];
+    if ([asciiAlphaNumericCS characterIsMember: currentChar])
+      [fixedPath appendFormat: @"%Lc", currentChar];
+    else
+      [fixedPath appendString: @"_"];
+  }
+
+  return (([fixedPath length] < 49)
+         ? (NSString *)fixedPath : [fixedPath substringToIndex: 49]);
+}
+
+- (NSString *)finalizedTableNameForBaseName:(NSString *)_baseName
+                                 atBaseURL:(NSString *)_baseURL
+                               withChannel:(EOAdaptorChannel *)_channel {
+  NSString *potentialName, *sqlTestFormat, *sqlTest;
+  unsigned int count;
+  
+  potentialName = _baseName;
+  sqlTestFormat = [NSString stringWithFormat: @"SELECT * FROM %@"
+                           @" WHERE c_location = '%@/%%@'"
+                           @" OR c_quick_location = '%@/%%@_quick'"
+                           @" OR c_acl_location = '%@/%%@_acl'",
+                           [self folderInfoTableName],
+                           _baseURL, _baseURL, _baseURL];
+
+  sqlTest = [NSString stringWithFormat: sqlTestFormat,
+                     potentialName, potentialName, potentialName];
+  count = 0;
+  while ([[self performSQL: sqlTest] count] > 0) {
+    count++;
+    potentialName = [NSString stringWithFormat: @"%@%d", _baseName, count];
+    sqlTest = [NSString stringWithFormat: sqlTestFormat,
+                       potentialName, potentialName, potentialName];
+  }
+
+  return potentialName;
+}
+
 - (NSException *)createFolderOfType:(NSString *)_type atPath:(NSString *)_path{
-  // TODO: implement folder create
   GCSFolderType *ftype;
-  
+  NSString *tableName, *quickTableName, *aclTableName;
+  NSString *baseURL;
+  EOAdaptorChannel *channel;
+  NSMutableArray *paths;
+
+  if ([[self performSQL: [NSString stringWithFormat: @"SELECT * FROM %@"
+                                 @" WHERE c_path = '%@'",
+                                 [self folderInfoTableName], _path]]
+       count] > 0) {
+    return [NSException exceptionWithName:@"GCSExitingFolder"
+                       reason:@"a folder already exists at that path"
+                       userInfo:nil];
+  }
   if ((ftype = [self folderTypeWithName:_type]) == nil) {
     return [NSException exceptionWithName:@"GCSMissingFolderType"
-                       reason:@"missing folder type"
+                       reason:@"missing folder type"userInfo:nil];
+  }
+  if ((channel = [self acquireOpenChannel]) == nil) {
+    return [NSException exceptionWithName:@"GCSNoChannel"
+                       reason:@"could not open channel"
                        userInfo:nil];
   }
-  
-  [self logWithFormat:@"create folder of type: %@", ftype];
-  
-  return [NSException exceptionWithName:@"NotYetImplemented"
-                     reason:@"no money, no time, ..."
-                     userInfo:nil];
+
+  tableName = [self baseTableNameForFolderAtPath: _path];
+  baseURL
+    = [[folderInfoLocation absoluteString] stringByDeletingLastPathComponent];
+  tableName = [self finalizedTableNameForBaseName: tableName
+                   atBaseURL: baseURL withChannel: channel];
+  quickTableName = [NSString stringWithFormat: @"%@_quick", tableName];
+  aclTableName = [NSString stringWithFormat: @"%@_acl", tableName];
+
+  [channel evaluateExpressionX:
+             [NSString stringWithFormat: @"DROP TABLE %@", tableName]];
+  [channel evaluateExpressionX:
+             [NSString stringWithFormat: @"DROP TABLE %@", quickTableName]];
+  [channel evaluateExpressionX:
+             [NSString stringWithFormat: @"DROP TABLE %@", aclTableName]];
+  [channel evaluateExpressionX:
+            [self sqlCreateWithTableName: tableName]];
+  [channel evaluateExpressionX:
+             [ftype sqlQuickCreateWithTableName: quickTableName]];
+  [channel evaluateExpressionX:
+            [self sqlAclCreateWithTableName: aclTableName]];
+
+  paths = [NSMutableArray
+            arrayWithArray: [_path componentsSeparatedByString: @"/"]];
+  while ([paths count] < 5)
+    [paths addObject: @""];
+
+  [channel evaluateExpressionX:
+             [NSString stringWithFormat: @"INSERT INTO %@"
+                       @"        (c_path, c_path1, c_path2, c_path3, c_path4,"
+                       @"         c_foldername, c_location, c_quick_location,"
+                       @"         c_acl_location, c_folder_type)"
+                       @" VALUES ('%@', '%@', '%@', '%@', '%@', '%@', '%@/%@',"
+                       @"         '%@/%@', '%@/%@', '%@')",
+                       [self folderInfoTableName], _path,
+                       [paths objectAtIndex: 1], [paths objectAtIndex: 2],
+                       [paths objectAtIndex: 3], [paths objectAtIndex: 4],
+                       [_path lastPathComponent],
+                      baseURL, tableName,
+                      baseURL, quickTableName,
+                      baseURL, aclTableName,
+                       _type]];
+
+  [self releaseChannel: channel];
+
+  return nil;
+}
+
+- (NSException *)deleteFolderAtPath:(NSString *)_path {
+  GCSFolder    *folder;
+  NSArray      *fnames;
+  NSString     *sql, *ws;
+  EOAdaptorChannel *channel;
+  NSException *ex;
+
+  if ((folder = [self folderAtPath:_path]) == nil) {
+    return [NSException exceptionWithName:@"GCSMissingFolder"
+                       reason:@"missing folder"
+                       userInfo:nil];
+  }
+
+  if ((fnames = [self internalNamesFromPath:_path]) == nil) {
+    [self debugWithFormat:@"got no internal names for path: '%@'", _path];
+    return nil;
+  }
+
+  ws = [self generateSQLWhereForInternalNames:fnames 
+            exactMatch:YES orDirectSubfolderMatch:NO];
+
+  sql = [NSString stringWithFormat: @"DELETE FROM %@ WHERE %@",
+                 [self folderInfoTableName], ws];
+  if ((channel = [self acquireOpenChannel]) == nil) {
+    return [NSException exceptionWithName:@"GCSNoChannel"
+                       reason:@"could not "
+                       userInfo:nil];
+  }
+
+  if ((ex = [channel evaluateExpressionX:sql]) != nil) {
+    [self releaseChannel:channel];
+    return ex;
+  }
+
+  [self releaseChannel:channel];
+
+  return [folder deleteFolder];
 }
 
 /* folder types */
index 28606453507035720ed92a83c6e07d2d0a826543..945ea188805902838fbed823a0a2df36ad8a5c43 100644 (file)
@@ -2,7 +2,7 @@
 
 MAJOR_VERSION:=4
 MINOR_VERSION:=7
-SUBMINOR_VERSION:=40
+SUBMINOR_VERSION:=42
 
 # v4.5.29 requires libNGExtensions v4.5.161
 # v4.5.26 does not require libNGiCal anymore