]> err.no Git - scalable-opengroupware.org/commitdiff
more work on defaults
authorhelge <helge@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Tue, 12 Jul 2005 12:59:52 +0000 (12:59 +0000)
committerhelge <helge@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Tue, 12 Jul 2005 12:59:52 +0000 (12:59 +0000)
git-svn-id: http://svn.opengroupware.org/SOGo/trunk@718 d1b88da0-ebda-0310-925b-ed51d893ca5b

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

index 19c0fd66d65bfb1c9f82c57df192f314b24bc937..667bdc8a8e5a55df277d65cc04cebc8c3d41ba56 100644 (file)
 */
 
 @class NSString, NSURL, NSUserDefaults, NSArray, NSDictionary, NSData;
+@class NSCalendarDate, NSMutableDictionary;
 
 @interface AgenorUserDefaults : NSObject
 {
   NSUserDefaults *parent;
   NSURL    *url;
   NSString *uid;
+  
+  NSArray             *fieldNames;
+  NSMutableDictionary *values;
+  NSCalendarDate      *lastFetch;
+
+  struct {
+    int modified:1;
+    int reserved:31;
+  } defFlags;
 }
 
 - (id)initWithTableURL:(NSURL *)_url uid:(NSString *)_uid;
 - (void)setFloat:(float)value forKey:(NSString *)_key;
 - (void)setInteger:(int)value forKey:(NSString *)_key;
 
+/* saving changes */
+
+- (BOOL)synchronize;
+
 @end
 
 #endif /* __AgenorUserDefaults_H_ */
index 989918864c1ef8a418dad174c97526d6436bdea7..5941b493f9adc32f926ecc098911f3188dd9efb5 100644 (file)
 
 #include "AgenorUserDefaults.h"
 #include <GDLContentStore/GCSChannelManager.h>
+#include <GDLContentStore/NSURL+GCS.h>
+#include <GDLAccess/EOAdaptorChannel.h>
 #include "common.h"
 
 @implementation AgenorUserDefaults
 
+static NSString *uidColumnName = @"uid";
+
 - (id)initWithTableURL:(NSURL *)_url uid:(NSString *)_uid {
   if ((self = [super init])) {
     if (_url == nil || [_uid length] < 1) {
 }
 
 - (void)dealloc {
-  [self->parent release];
-  [self->url release];
-  [self->uid release];
+  [self->lastFetch release];
+  [self->parent    release];
+  [self->url       release];
+  [self->uid       release];
   [super dealloc];
 }
 
 
 /* operation */
 
-- (BOOL)fill {
+- (BOOL)primaryFetchProfile {
   GCSChannelManager *cm;
   EOAdaptorChannel  *channel;
+  NSDictionary      *row;
+  NSException       *ex;
+  NSString          *sql;
+  NSArray           *attrs;
+  NSMutableArray    *fields;
   
   cm = [GCSChannelManager defaultChannelManager];
   if ((channel = [cm acquireOpenChannelForURL:[self tableURL]]) == nil) {
          [self tableURL]];
     return NO;
   }
+  
+  /* generate SQL */
+  
+  sql = [[self tableURL] gcsTableName];
+  sql = [@"SELECT * FROM " stringByAppendingString:sql];
+  sql = [sql stringByAppendingFormat:@" WHERE %@ = '%@'", 
+            uidColumnName, [self uid]];
+  
+  /* run SQL */
+  
+  if ((ex = [channel evaluateExpressionX:sql]) != nil) {
+    [self errorWithFormat:@"could not run SQL '%@': %@", sql, ex];
+    [cm releaseChannel:channel];
+    return NO;
+  }
+
+  /* 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;
+  
+  /* fetch values */
+  
+  row = [channel fetchAttributes:attrs withZone:NULL];
+  [channel cancelFetch];
 
-  [self logWithFormat:@"do work on: %@", channel];
+  /* remember values */
+  
+  [self->values release]; self->values = nil;
+  if (row != nil)
+    self->values = [row mutableCopy];
+  else
+    self->values = [[NSMutableDictionary alloc] initWithCapacity:8];
+  [self->values removeObjectForKey:uidColumnName];
+  
+  ASSIGN(self->lastFetch, [NSCalendarDate date]);
+  self->defFlags.modified = 0;
   
   [cm releaseChannel:channel];
   return YES;
 }
 
+- (BOOL)fetchProfile {
+  if (self->values != nil)
+    return YES;
+  
+  return [self primaryFetchProfile];
+}
+
+- (NSArray *)primaryDefaultNames {
+  if (![self fetchProfile])
+    return nil;
+  
+  return self->fieldNames;
+}
+
 /* value access */
 
 - (void)setObject:(id)_value forKey:(NSString *)_key {
-  [self logWithFormat:@"TODO(%s): %@", __PRETTY_FUNCTION__, _key];
+  if (![self fetchProfile])
+    return;
+  
+  if (![self->fieldNames containsObject:_key]) {
+    [self errorWithFormat:@"tried to write key: '%@'", _key];
+    return;
+  }
+  
+  /* check whether the value is actually modified */
+  if (!self->defFlags.modified) {
+    id old;
+
+    old = [self->values objectForKey:_key];
+    if (old == _value || [old isEqual:_value]) /* value didn't change */
+      return;
+  
+    /* we need to this because our typed accessors convert to strings */
+    // TODO: especially problematic with bools
+    if ([_value isKindOfClass:[NSString class]]) {
+      if (![old isKindOfClass:[NSString class]])
+        if ([[old description] isEqualToString:_value])
+       return;
+    }
+  }
+  
+  /* set in hash and mark as modified */
+  [self->values setObject:(_value ? _value : [NSNull null])  forKey:_key];
+  self->defFlags.modified = 1;
 }
+
 - (id)objectForKey:(NSString *)_key {
-  [self logWithFormat:@"TODO(%s): %@", __PRETTY_FUNCTION__, _key];
-  [self fill];
-  return nil;
+  id value;
+  
+  if (![self fetchProfile])
+    return nil;
+  
+  if (![self->fieldNames containsObject:_key])
+    return [self->parent objectForKey:_key];
+  
+  value = [self->values objectForKey:_key];
+  return [value isNotNull] ? value : nil;
 }
 
 - (void)removeObjectForKey:(NSString *)_key {
   [self setObject:nil forKey:_key];
 }
 
+/* saving changes */
+
+- (BOOL)synchronize {
+  if (!self->defFlags.modified) /* was not modified */
+    return YES;
+
+  [self logWithFormat:@"TODO: sync!"];
+  return NO;
+}
+
 /* typed accessors */
 
 - (NSArray *)arrayForKey:(NSString *)_key {
 }
 
 - (BOOL)boolForKey:(NSString *)_key {
+  // TODO: need special support here for int-DB fields
   id obj;
   
   if ((obj = [self objectForKey:_key]) == nil)
 }
 
 - (void)setBool:(BOOL)value forKey:(NSString *)_key {
+  // TODO: need special support here for int-DB fields
   [self setObject:(value ? @"YES" : @"NO") forKey:_key];
 }
 - (void)setFloat:(float)value forKey:(NSString *)_key {
index c676c8cb64d2e0f4d8a9cfbc78bf198fb495c54b..89ee183e2942bc0a91683e87257e11843a4c483a 100644 (file)
@@ -1,5 +1,11 @@
 2005-07-12  Helge Hess  <helge.hess@opengroupware.org>
 
+       * v0.9.45
+       
+       * AgenorUserDefaults.m: properly fetch profile contents
+       
+       * agenor_defaults.m: read operation can now return all defined keys
+       
        * v0.9.44
 
        * AgenorUserDefaults.m: added typed value accessors and proper
index 7fdb0b30e6bd19c047c0373f7d12ab4d47006b13..2bea963b3a27ed0872886202ac4b82d99eee9df5 100644 (file)
@@ -1,6 +1,6 @@
 # version file
 
-SUBMINOR_VERSION:=44
+SUBMINOR_VERSION:=45
 
 # v0.9.34 requires libGDLContentStore v4.5.26
 # v0.9.26 requires libOGoContentStore v0.9.13
index e7a18bc46b1b5f9034c19b69ade6ec05499b93f6..89837ce4ffc63fe6d392c015c7c57d5ccc793ef2 100644 (file)
@@ -23,7 +23,7 @@
 #include "common.h"
 
 static void usage(NSArray *args) {
-  fprintf(stderr, "usage: %s <uid> read|write <key> [<value>]\n",
+  fprintf(stderr, "usage: %s <uid> read|write|info [<key>] [<value>]\n",
          [[args objectAtIndex:0] cString]);
 }
 
@@ -35,14 +35,30 @@ static void doInfo(NSUserDefaults *defaults) {
 
 static void doRead(NSUserDefaults *defaults, NSString *key) {
   id value;
-  
-  if ((value = [defaults objectForKey:key]) == nil) {
+
+  if (key == nil) {
+    NSArray  *defNames;
+    unsigned i, count;
+    
+    defNames = [defaults valueForKey:@"primaryDefaultNames"];
+    if ((count = [defNames count]) == 0) {
+      fprintf(stderr, "There are no keys in the Agenor profile!\n");
+      return;
+    }
+    
+    for (i = 0; i < count; i++) {
+      printf("%s: %s\n",
+            [[defNames objectAtIndex:i] cString],
+            [[[defaults objectForKey:[defNames objectAtIndex:i]]
+               description] cString]);
+    }
+  }
+  else if ((value = [defaults objectForKey:key]) == nil) {
     fprintf(stderr, "There is no key '%s' in the Agenor profile!\n", 
            [key cString]);
-    return;
   }
-  
-  printf("%s\n", [[value description] cString]);
+  else
+    printf("%s\n", [[value description] cString]);
 }
 
 static void doWrite(NSUserDefaults *defaults, NSString *key, NSString *value) {
@@ -71,13 +87,8 @@ static void doIt(NSArray *args) {
   key   = nil;
   value = nil;
   
-  if ([op isEqualToString:@"write"] || [op isEqualToString:@"read"]) {
-    if ([args count] < 4) {
-      usage(args);
-      return;
-    }
+  if ([args count] > 3)
     key = [args objectAtIndex:3];
-  }
   
   if ([op isEqualToString:@"write"]) {
     if ([args count] < 5) {