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
maint-2.0.2
Ludovic Marcotte 2009-10-13 20:17:29 +00:00
parent bf95e10746
commit a285132f8b
8 changed files with 81 additions and 41 deletions

View File

@ -1,3 +1,22 @@
2009-10-13 Ludovic Marcotte <lmarcotte@inverse.ca>
* 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 <flachapelle@inverse.ca>
* UI/WebServerResources/MailerUI.js (-ICalendarButtonCallback):

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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]];

View File

@ -47,9 +47,9 @@
struct
{
int modified: 1;
int isNew: 1;
int ready: 1;
BOOL modified;
BOOL isNew;
BOOL ready;
} defFlags;
}

View File

@ -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

View File

@ -1043,7 +1043,6 @@ static BOOL forwardEnabled = NO;
forKey: @"CalendarCategories"];
[userDefaults setObject: [plist objectAtIndex: 1]
forKey: @"CalendarCategoriesColors"];
NSLog ([plist description]);
}
}