]> err.no Git - scalable-opengroupware.org/commitdiff
implemented profile saving
authorhelge <helge@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Tue, 12 Jul 2005 15:00:36 +0000 (15:00 +0000)
committerhelge <helge@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Tue, 12 Jul 2005 15:00:36 +0000 (15:00 +0000)
git-svn-id: http://svn.opengroupware.org/SOGo/trunk@727 d1b88da0-ebda-0310-925b-ed51d893ca5b

SOGo/SoObjects/SOGo/AgenorUserDefaults.h
SOGo/SoObjects/SOGo/AgenorUserDefaults.m
SOGo/SoObjects/SOGo/ChangeLog
SOGo/SoObjects/SOGo/Version

index 667bdc8a8e5a55df277d65cc04cebc8c3d41ba56..d27513899d36a358f1b16af10e1900dc1647bba6 100644 (file)
@@ -41,6 +41,7 @@
   NSString *uid;
   
   NSArray             *fieldNames;
+  NSDictionary        *attributes;
   NSMutableDictionary *values;
   NSCalendarDate      *lastFetch;
 
index 5941b493f9adc32f926ecc098911f3188dd9efb5..dcab5b00003d6b938e78801838cb2e7c395cbc44 100644 (file)
@@ -23,6 +23,8 @@
 #include <GDLContentStore/GCSChannelManager.h>
 #include <GDLContentStore/NSURL+GCS.h>
 #include <GDLAccess/EOAdaptorChannel.h>
+#include <GDLAccess/EOAdaptorContext.h>
+#include <GDLAccess/EOAttribute.h>
 #include "common.h"
 
 @implementation AgenorUserDefaults
@@ -48,10 +50,11 @@ static NSString *uidColumnName = @"uid";
 }
 
 - (void)dealloc {
-  [self->lastFetch release];
-  [self->parent    release];
-  [self->url       release];
-  [self->uid       release];
+  [self->attributes release];
+  [self->lastFetch  release];
+  [self->parent     release];
+  [self->url        release];
+  [self->uid        release];
   [super dealloc];
 }
 
@@ -70,6 +73,31 @@ static NSString *uidColumnName = @"uid";
 
 /* operation */
 
+- (void)_loadAttributes:(NSArray *)_attrs {
+  NSMutableArray      *fields;
+  NSMutableDictionary *attrmap;
+  unsigned i, count;
+  
+  fields  = [[NSMutableArray      alloc] initWithCapacity:16];
+  attrmap = [[NSMutableDictionary alloc] initWithCapacity:16];
+  for (i = 0, count = [_attrs count]; i < count; i++) {
+    EOAttribute *attr;
+    NSString    *name;
+    
+    attr = [_attrs objectAtIndex:i];
+    name = [attr valueForKey:@"name"];
+    [attrmap setObject:attr forKey:name];
+    
+    if (![name isEqual:uidColumnName]) 
+      [fields  addObject:name];
+  }
+  
+  ASSIGNCOPY(self->fieldNames, fields);
+  ASSIGNCOPY(self->attributes, attrmap);
+  [attrmap release];
+  [fields  release];
+}
+
 - (BOOL)primaryFetchProfile {
   GCSChannelManager *cm;
   EOAdaptorChannel  *channel;
@@ -77,7 +105,6 @@ static NSString *uidColumnName = @"uid";
   NSException       *ex;
   NSString          *sql;
   NSArray           *attrs;
-  NSMutableArray    *fields;
   
   cm = [GCSChannelManager defaultChannelManager];
   if ((channel = [cm acquireOpenChannelForURL:[self tableURL]]) == nil) {
@@ -104,17 +131,13 @@ static NSString *uidColumnName = @"uid";
   /* fetch schema */
   
   attrs = [channel describeResults:NO /* don't beautify */];
-  
-  fields = [[attrs valueForKey:@"name"] mutableCopy];
-  [fields removeObject:uidColumnName];
-  ASSIGNCOPY(self->fieldNames, fields);
-  [fields release]; fields =nil;
+  [self _loadAttributes:attrs];
   
   /* fetch values */
   
   row = [channel fetchAttributes:attrs withZone:NULL];
   [channel cancelFetch];
-
+  
   /* remember values */
   
   [self->values release]; self->values = nil;
@@ -131,6 +154,97 @@ static NSString *uidColumnName = @"uid";
   return YES;
 }
 
+- (NSString *)generateSQLForUpdate {
+  NSMutableString *sql;
+  unsigned i, count;
+  
+  if ([self->values count] == 0)
+    return nil;
+  
+  sql = [NSMutableString stringWithCapacity:2048];
+  
+  [sql appendString:@"UPDATE "];
+  [sql appendString:[[self tableURL] gcsTableName]];
+  [sql appendString:@" SET "];
+  
+  for (i = 0, count = [self->fieldNames count]; i < count; i++) {
+    EOAttribute *attr;
+    NSString    *name;
+    id value;
+    
+    name  = [self->fieldNames objectAtIndex:i];
+    value = [self->values objectForKey:name];
+    attr  = [self->attributes objectForKey:name];
+    
+    if (i != 0) [sql appendString:@", "];
+    [sql appendString:[attr columnName]];
+    
+    if ([value isNotNull]) {
+      /* a rather limited set of supported value types */
+      
+      if ([[attr externalType] hasPrefix:@"int"])
+       [sql appendFormat:@" = %i", [value intValue]];
+      else {
+       // TODO: any other escaping?! move to adaptor?
+       value = [value stringValue];
+       value = [value stringByReplacingString:@"'" withString:@"''"];
+       [sql appendString:@" = '"];
+       [sql appendString:value];
+       [sql appendString:@"'"];
+      }
+    }
+    else
+      [sql appendString:@" = NULL"];
+  }
+  
+  [sql appendString:@" WHERE "];
+  [sql appendString:uidColumnName];
+  [sql appendString:@" = '"];
+  [sql appendString:[self uid]];
+  [sql appendString:@"'"];
+  return sql;
+}
+
+- (BOOL)primaryStoreProfile {
+  GCSChannelManager *cm;
+  EOAdaptorChannel  *channel;
+  NSException       *ex;
+  NSString          *sql;
+  
+  cm = [GCSChannelManager defaultChannelManager];
+  if ((channel = [cm acquireOpenChannelForURL:[self tableURL]]) == nil) {
+    [self errorWithFormat:@"failed to acquire channel for URL: %@", 
+         [self tableURL]];
+    return NO;
+  }
+  
+  /* run SQL */
+  
+  sql = [self generateSQLForUpdate];
+  if ((ex = [channel evaluateExpressionX:sql]) != nil) {
+    [self errorWithFormat:@"could not run SQL '%@': %@", sql, ex];
+    [cm releaseChannel:channel];
+    return NO;
+  }
+  
+  /* commit */
+  
+  ex = nil;
+  if ([[channel adaptorContext] hasOpenTransaction])
+    ex = [channel evaluateExpressionX:@"COMMIT TRANSACTION"];
+  
+  [cm releaseChannel:channel];
+  
+  if (ex != nil) {
+    [self errorWithFormat:@"could not commit transaction for update: %@", ex];
+    return NO;
+  }
+  
+  self->defFlags.modified = 0;
+  return YES;
+}
+
+
 - (BOOL)fetchProfile {
   if (self->values != nil)
     return YES;
@@ -200,9 +314,27 @@ static NSString *uidColumnName = @"uid";
 - (BOOL)synchronize {
   if (!self->defFlags.modified) /* was not modified */
     return YES;
+  
+  /* ensure fetched data (more or less guaranteed by modified!=0) */
+  if (![self fetchProfile])
+    return NO;
+  
+  /* store */
+  if (![self primaryStoreProfile]) {
+    [self primaryFetchProfile];
+    return NO;
+  }
+  
+  /* refetch */
+  return [self primaryFetchProfile];
+}
 
-  [self logWithFormat:@"TODO: sync!"];
-  return NO;
+- (void)flush {
+  [self->values     release]; self->values     = nil;
+  [self->fieldNames release]; self->fieldNames = nil;
+  [self->attributes release]; self->attributes = nil;
+  [self->lastFetch  release]; self->lastFetch  = nil;
+  self->defFlags.modified = 0;
 }
 
 /* typed accessors */
index 453d72d31e8a1d3d154399febba91a06260a9bb3..2b5c2d6e99f5a4acb9a1d107ba051d875798761d 100644 (file)
@@ -1,3 +1,8 @@
+2005-07-12  Helge Hess  <helge.hess@opengroupware.org>
+
+       * AgenorUserDefaults.m: implemented saving of changed profiles
+         (v0.9.47)
+
 2005-07-12  Marcus Mueller  <znek@mulle-kybernetik.com>
 
        * AgenorUserManager.[hm]: new API for extracting UIDs from iCalPersons
index 09850cc9a414c04a980fd224d306960965fec306..cd83313cc633a0d5af6636eb5ca4a0dc2751a66c 100644 (file)
@@ -1,6 +1,6 @@
 # version file
 
-SUBMINOR_VERSION:=46
+SUBMINOR_VERSION:=47
 
 # v0.9.34 requires libGDLContentStore v4.5.26
 # v0.9.26 requires libOGoContentStore v0.9.13