From a285132f8bc7585192de3900201b8db23e773274 Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Tue, 13 Oct 2009 20:17:29 +0000 Subject: [PATCH] See ChangeLog Monotone-Parent: 4437a82e041d016710ea3a45d8b7cf5b6341afff Monotone-Revision: 0746b51101ad96419ffd4e8f557f967f13b70a60 Monotone-Author: ludovic@Sophos.ca Monotone-Date: 2009-10-13T20:17:29 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 19 +++++++ SoObjects/SOGo/NSDictionary+BSJSONAdditions.m | 5 +- SoObjects/SOGo/SOGoCache.h | 2 - SoObjects/SOGo/SOGoCache.m | 50 +++++++++++++------ SoObjects/SOGo/SOGoUser.m | 27 ++++++---- SoObjects/SOGo/SOGoUserDefaults.h | 6 +-- SoObjects/SOGo/SOGoUserDefaults.m | 12 ++--- UI/PreferencesUI/UIxPreferences.m | 1 - 8 files changed, 81 insertions(+), 41 deletions(-) diff --git a/ChangeLog b/ChangeLog index 279d56768..391361d33 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2009-10-13 Ludovic Marcotte + + * SoObjects/SOGo/NSDictionary+BSJSONAdditions.m + Fixed the objCType comparison on GNUstep for boolean + values - we must consider 'c' and 'C' + * SoObjects/SOGo/SOGoCache.m + Introduce a localCache static variable to avoid going + to memcached all the time. We'll cache values during + the request and flush them after. + * SoObjects/SOGo/SOGoUser.m + Modified -userDefaults to set the timezone when prefs + have first been set. + * SoObjects/SOGo/SOGoUserDefaults.m + Reworked the logic in order to use the correct UPDATE/INSERT + statement when prefs exist or not. Also cleaned up the + types definition. + * UI/PreferencesUI/UIxPreferences.m + Removed worthless NSLog() call. + 2009-10-13 Francis Lachapelle * UI/WebServerResources/MailerUI.js (-ICalendarButtonCallback): diff --git a/SoObjects/SOGo/NSDictionary+BSJSONAdditions.m b/SoObjects/SOGo/NSDictionary+BSJSONAdditions.m index 1bc0e7530..0569376bb 100644 --- a/SoObjects/SOGo/NSDictionary+BSJSONAdditions.m +++ b/SoObjects/SOGo/NSDictionary+BSJSONAdditions.m @@ -97,9 +97,10 @@ const int jsonDoNotIndent = -1; jsonString = jsonNullString; else if ([value respondsToSelector:@selector(objCType)]) { // NSNumber - representing true, false, and any form of numeric NSNumber *number = (NSNumber *)value; - if (((*[number objCType]) == 'c') && ([number boolValue] == YES)) // true + const char *t = [number objCType]; + if (((*t == 'c') || *t == 'C') && ([number boolValue] == YES)) // true jsonString = jsonTrueString; - else if (((*[number objCType]) == 'c') && ([number boolValue] == NO)) // false + else if (((*t == 'c') || *t == 'C') && ([number boolValue] == NO)) // false jsonString = jsonFalseString; else // attempt to handle as a decimal number - int, fractional, exponential // TODO: values converted from exponential json to dict and back to json do not format as exponential again diff --git a/SoObjects/SOGo/SOGoCache.h b/SoObjects/SOGo/SOGoCache.h index 820b22b37..8b26b2a15 100644 --- a/SoObjects/SOGo/SOGoCache.h +++ b/SoObjects/SOGo/SOGoCache.h @@ -30,7 +30,6 @@ @class NSMutableDictionary; @class NSString; -@class NSTimer; @class NSUserDefaults; @class SOGoObject; @@ -40,7 +39,6 @@ @interface SOGoCache : NSObject { @private - NSTimer *_cleanupTimer; memcached_server_st *servers; memcached_st *handle; } diff --git a/SoObjects/SOGo/SOGoCache.m b/SoObjects/SOGo/SOGoCache.m index e5db1cbc4..c07d70758 100644 --- a/SoObjects/SOGo/SOGoCache.m +++ b/SoObjects/SOGo/SOGoCache.m @@ -57,6 +57,13 @@ static NSTimeInterval cleanupInterval = 300; static NSMutableDictionary *cache = nil; static NSMutableDictionary *users = nil; +// localCache is used to avoid going all the time to the memcached server during +// each request. We'll cache the value we got from memcached for the duration +// of the current request - which is good enough for pretty much all caces. We +// surely don't want to get new defaults/settings during the _same_ requests, it +// could produce relatively strange behaviors +static NSMutableDictionary *localCache = nil; + static NSString *memcachedServerName = @"localhost"; static SOGoCache *sharedCache = nil; @@ -103,6 +110,7 @@ static NSLock *lock; // This is essential for refetching the cached values in case something has changed // accross various sogod processes [users removeAllObjects]; + [localCache removeAllObjects]; #if defined(THREADSAFE) [lock unlock]; #endif @@ -117,6 +125,7 @@ static NSLock *lock; cache = [[NSMutableDictionary alloc] init]; users = [[NSMutableDictionary alloc] init]; + localCache = [[NSMutableDictionary alloc] init]; // We fire our timer that will cleanup cache entries cleanupSetting = [[NSUserDefaults standardUserDefaults] @@ -146,6 +155,7 @@ static NSLock *lock; memcached_free(handle); [cache release]; [users release]; + [localCache release]; [super dealloc]; } @@ -265,30 +275,42 @@ static NSLock *lock; forLogin: (NSString *) theLogin { NSDictionary *d; - memcached_return rc; + NSString *k; + const char *key; - char *s; - unsigned int len, flags; - size_t vlen; + unsigned int len; if (!handle) return nil; - key = [[NSString stringWithFormat: @"%@+%@", theLogin, theType] UTF8String]; + k = [NSString stringWithFormat: @"%@+%@", theLogin, theType]; + key = [k UTF8String]; len = strlen(key); - d = nil; - s = memcached_get(handle, key, len, &vlen, &flags, &rc); + d = [localCache objectForKey: k]; - if (rc == MEMCACHED_SUCCESS && s) + if (!d) { - NSString *v; + memcached_return rc; + unsigned int flags; + size_t vlen; + char *s; - v = [NSString stringWithUTF8String: s]; - d = [NSDictionary dictionaryWithJSONString: v]; - //[self logWithFormat: @"read values (%@) for subtype %@ for user %@", [d description], theType, theLogin]; - - free(s); + s = memcached_get(handle, key, len, &vlen, &flags, &rc); + + if (rc == MEMCACHED_SUCCESS && s) + { + NSString *v; + + v = [NSString stringWithUTF8String: s]; + d = [NSDictionary dictionaryWithJSONString: v]; + //[self logWithFormat: @"read values (%@) for subtype %@ for user %@", [d description], theType, theLogin]; + + // Cache the value in our localCache + [localCache setObject: d forKey: k]; + + free(s); + } } return d; diff --git a/SoObjects/SOGo/SOGoUser.m b/SoObjects/SOGo/SOGoUser.m index fad71c6e5..ffa8a1285 100644 --- a/SoObjects/SOGo/SOGoUser.m +++ b/SoObjects/SOGo/SOGoUser.m @@ -507,16 +507,23 @@ _timeValue (NSString *key) if (values) { - // Required parameters for the Web interface. This will trigger the - // preferences to load so it's important to leave those calls here. - if (![[_defaults stringForKey: @"ReplyPlacement"] length]) - [_defaults setObject: defaultReplyPlacement forKey: @"ReplyPlacement"]; - if (![[_defaults stringForKey: @"SignaturePlacement"] length]) - [_defaults setObject: defaultSignaturePlacement forKey: @"SignaturePlacement"]; - if (![[_defaults stringForKey: @"MessageForwarding"] length]) - [_defaults setObject: defaultMessageForwarding forKey: @"MessageForwarding"]; + BOOL b; + + b = NO; + if (![[_defaults stringForKey: @"MessageCheck"] length]) - [_defaults setObject: defaultMessageCheck forKey: @"MessageCheck"]; + { + [_defaults setObject: defaultMessageCheck forKey: @"MessageCheck"]; + b = YES; + } + if (![[_defaults stringForKey: @"TimeZone"] length]) + { + [_defaults setObject: [serverTimeZone name] forKey: @"TimeZone"]; + b = YES; + } + + if (b) + [_defaults synchronize]; [[SOGoCache sharedCache] cacheValues: [_defaults values] ofType: @"defaults" forLogin: login]; } @@ -1047,7 +1054,7 @@ _timeValue (NSString *key) /* module access */ - (BOOL) canAccessModule: (NSString *) module { - NSString *accessValue; + id accessValue; accessValue = [self _fetchFieldForUser: [NSString stringWithFormat: @"%@Access", module]]; diff --git a/SoObjects/SOGo/SOGoUserDefaults.h b/SoObjects/SOGo/SOGoUserDefaults.h index 2641a71be..99285c078 100644 --- a/SoObjects/SOGo/SOGoUserDefaults.h +++ b/SoObjects/SOGo/SOGoUserDefaults.h @@ -47,9 +47,9 @@ struct { - int modified: 1; - int isNew: 1; - int ready: 1; + BOOL modified; + BOOL isNew; + BOOL ready; } defFlags; } diff --git a/SoObjects/SOGo/SOGoUserDefaults.m b/SoObjects/SOGo/SOGoUserDefaults.m index adf651d48..a5b3b9ad4 100644 --- a/SoObjects/SOGo/SOGoUserDefaults.m +++ b/SoObjects/SOGo/SOGoUserDefaults.m @@ -56,6 +56,7 @@ static NSString *uidColumnName = @"c_uid"; url = [theURL copy]; uid = [theUID copy]; defFlags.ready = YES; + defFlags.isNew = YES; } else { @@ -134,7 +135,7 @@ static NSString *uidColumnName = @"c_uid"; /* fetch values */ row = [channel fetchAttributes: attrs withZone: NULL]; - defFlags.isNew = (row == nil); + defFlags.isNew = !row; [channel cancelFetch]; /* remember values */ @@ -307,7 +308,7 @@ static NSString *uidColumnName = @"c_uid"; [self fetchProfile]; if (values) - jsonRep = [values jsonRepresentation]; + jsonRep = [values jsonStringValue]; else jsonRep = @"{}"; @@ -402,13 +403,6 @@ static NSString *uidColumnName = @"c_uid"; return [self primaryFetchProfile]; } -- (void) flush -{ - [values removeAllObjects]; - defFlags.modified = NO; - defFlags.isNew = NO; -} - /* typed accessors */ - (NSArray *) arrayForKey: (NSString *) key diff --git a/UI/PreferencesUI/UIxPreferences.m b/UI/PreferencesUI/UIxPreferences.m index a492bc168..ff7623125 100644 --- a/UI/PreferencesUI/UIxPreferences.m +++ b/UI/PreferencesUI/UIxPreferences.m @@ -1043,7 +1043,6 @@ static BOOL forwardEnabled = NO; forKey: @"CalendarCategories"]; [userDefaults setObject: [plist objectAtIndex: 1] forKey: @"CalendarCategoriesColors"]; - NSLog ([plist description]); } }