Fix for bug #1442.

See ChangeLog.

Monotone-Parent: d7092dc459f63233bb9e0a7aadc3380b2682ed2a
Monotone-Revision: f6c6bfab15922450127ccb9597bbc97468d695c0

Monotone-Author: flachapelle@inverse.ca
Monotone-Date: 2011-10-21T14:57:57
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Francis Lachapelle 2011-10-21 14:57:57 +00:00
parent f2aaeaec2a
commit 19169e821d
9 changed files with 256 additions and 34 deletions

View File

@ -4,6 +4,45 @@
extractorClassName = "OCSiCalFieldExtractor"; extractorClassName = "OCSiCalFieldExtractor";
fields = ( fields = (
{
columnName = c_name;
sqlType = "VARCHAR2(255)";
allowsNull = NO;
isPrimaryKey = YES;
},
{
columnName = c_content;
sqlType = "CLOB";
allowsNull = NO;
isPrimaryKey = NO;
},
{
columnName = c_creationdate;
sqlType = "INTEGER";
allowsNull = NO;
isPrimaryKey = NO;
},
{
columnName = c_lastmodified;
sqlType = "INTEGER";
allowsNull = NO;
isPrimaryKey = NO;
},
{
columnName = c_version;
sqlType = "INTEGER";
allowsNull = NO;
isPrimaryKey = NO;
},
{
columnName = c_deleted;
sqlType = "INTEGER";
allowsNull = YES;
isPrimaryKey = NO;
}
);
quickFields = (
{ {
columnName = c_name; columnName = c_name;
sqlType = "VARCHAR2(255)"; sqlType = "VARCHAR2(255)";

View File

@ -4,6 +4,45 @@
extractorClassName = "OCSiCalFieldExtractor"; extractorClassName = "OCSiCalFieldExtractor";
fields = ( fields = (
{
columnName = c_name;
sqlType = "VARCHAR(255)";
allowsNull = NO;
isPrimaryKey = YES;
},
{
columnName = c_content;
sqlType = "VARCHAR(100000)";
allowsNull = NO;
isPrimaryKey = NO;
},
{
columnName = c_creationdate;
sqlType = "INT4";
allowsNull = NO;
isPrimaryKey = NO;
},
{
columnName = c_lastmodified;
sqlType = "INT4";
allowsNull = NO;
isPrimaryKey = NO;
},
{
columnName = c_version;
sqlType = "INT4";
allowsNull = NO;
isPrimaryKey = NO;
},
{
columnName = c_deleted;
sqlType = "INT4";
allowsNull = YES;
isPrimaryKey = NO;
}
);
quickFields = (
{ {
columnName = c_name; columnName = c_name;
sqlType = "VARCHAR(255)"; sqlType = "VARCHAR(255)";
@ -114,6 +153,6 @@
columnName = c_nextalarm; columnName = c_nextalarm;
sqlType = "INT"; sqlType = "INT";
allowsNull = YES; allowsNull = YES;
}, }
); );
} }

View File

@ -4,6 +4,45 @@
extractorClassName= "OCSContactFieldExtractor"; extractorClassName= "OCSContactFieldExtractor";
fields = ( fields = (
{
columnName = c_name;
sqlType = "VARCHAR2(255)";
allowsNull = NO;
isPrimaryKey = YES;
},
{
columnName = c_content;
sqlType = "CLOB";
allowsNull = NO;
isPrimaryKey = NO;
},
{
columnName = c_creationdate;
sqlType = "INTEGER";
allowsNull = NO;
isPrimaryKey = NO;
},
{
columnName = c_lastmodified;
sqlType = "INTEGER";
allowsNull = NO;
isPrimaryKey = NO;
},
{
columnName = c_version;
sqlType = "INTEGER";
allowsNull = NO;
isPrimaryKey = NO;
},
{
columnName = c_deleted;
sqlType = "INTEGER";
allowsNull = YES;
isPrimaryKey = NO;
}
);
quickFields = (
{ {
columnName = c_name; columnName = c_name;
sqlType = "VARCHAR2(255)"; sqlType = "VARCHAR2(255)";

View File

@ -4,6 +4,45 @@
extractorClassName= "OCSContactFieldExtractor"; extractorClassName= "OCSContactFieldExtractor";
fields = ( fields = (
{
columnName = c_name;
sqlType = "VARCHAR(255)";
allowsNull = NO;
isPrimaryKey = YES;
},
{
columnName = c_content;
sqlType = "VARCHAR(100000)";
allowsNull = NO;
isPrimaryKey = NO;
},
{
columnName = c_creationdate;
sqlType = "INT4";
allowsNull = NO;
isPrimaryKey = NO;
},
{
columnName = c_lastmodified;
sqlType = "INT4";
allowsNull = NO;
isPrimaryKey = NO;
},
{
columnName = c_version;
sqlType = "INT4";
allowsNull = NO;
isPrimaryKey = NO;
},
{
columnName = c_deleted;
sqlType = "INT4";
allowsNull = YES;
isPrimaryKey = NO;
}
);
quickFields = (
{ {
columnName = c_name; columnName = c_name;
sqlType = "VARCHAR(255)"; sqlType = "VARCHAR(255)";
@ -51,7 +90,7 @@
allowsNull = YES; allowsNull = YES;
}, },
{ {
columnName = c_telephoneNumber; columnName = c_telephonenumber;
sqlType = "VARCHAR(255)"; sqlType = "VARCHAR(255)";
allowsNull = YES; allowsNull = YES;
}, },

View File

@ -1,3 +1,16 @@
2011-10-21 Francis Lachapelle <flachapelle@inverse.ca>
* GCSFolder.m
(_generateUpdateStatementForRow:adaptor:fields:tableName:whereColumn:isEqualTo:andColumn:isEqualTo:):
this method now uses the formatValue:forAttribute: method from the
database adaptor to benefit from the proper formatting depending
on the column type.
(-initWithPath:primaryKey:folderTypeName:folderType:location:quickLocation:aclLocation:folderManager:):
load the content field names from the GCSFolderType object.
* GCSFolderType.m (-initWithPropertyList:): the content table
structure is now part of the plist (.ocs) file.
2011-10-03 Francis Lachapelle <flachapelle@inverse.ca> 2011-10-03 Francis Lachapelle <flachapelle@inverse.ca>
* GCSFolder.m (-updateQuickFields:whereColumn:isEqualTo:): new * GCSFolder.m (-updateQuickFields:whereColumn:isEqualTo:): new

View File

@ -66,7 +66,7 @@
NSURL *quickLocation; NSURL *quickLocation;
NSURL *aclLocation; NSURL *aclLocation;
NSString *folderTypeName; NSString *folderTypeName;
NSMutableArray *quickFieldNames; NSMutableArray *quickFieldNames, *contentFieldNames;
struct { struct {
int requiresFolderSelect:1; int requiresFolderSelect:1;

View File

@ -1,7 +1,7 @@
/* /*
Copyright (C) 2004-2007 SKYRIX Software AG Copyright (C) 2004-2007 SKYRIX Software AG
Copyright (C) 2007 Helge Hess Copyright (C) 2007 Helge Hess
Copyright (c) 2008-2009 Inverse inc. Copyright (c) 2008-2011 Inverse inc.
This file is part of OpenGroupware.org. This file is part of OpenGroupware.org.
@ -30,6 +30,7 @@
#import <GDLAccess/EOEntity.h> #import <GDLAccess/EOEntity.h>
#import <GDLAccess/EOAttribute.h> #import <GDLAccess/EOAttribute.h>
#import <GDLAccess/EOSQLQualifier.h> #import <GDLAccess/EOSQLQualifier.h>
#import <GDLAccess/EOAdaptor.h>
#import <GDLAccess/EOAdaptorContext.h> #import <GDLAccess/EOAdaptorContext.h>
#import "GCSFieldInfo.h" #import "GCSFieldInfo.h"
@ -60,7 +61,6 @@ static Class NSNumberClass = Nil;
static Class NSCalendarDateClass = Nil; static Class NSCalendarDateClass = Nil;
static GCSStringFormatter *stringFormatter = nil; static GCSStringFormatter *stringFormatter = nil;
static NSArray *contentFieldNames = nil;
+ (void) initialize + (void) initialize
{ {
@ -72,13 +72,6 @@ static NSArray *contentFieldNames = nil;
NSStringClass = [NSString class]; NSStringClass = [NSString class];
NSNumberClass = [NSNumber class]; NSNumberClass = [NSNumber class];
NSCalendarDateClass = [NSCalendarDate class]; NSCalendarDateClass = [NSCalendarDate class];
if (!contentFieldNames)
{
contentFieldNames = [NSArray arrayWithObjects: @"c_content",
@"c_creationdate", @"c_lastmodified",
@"c_version", @"c_deleted", nil];
[contentFieldNames retain];
}
stringFormatter = [GCSStringFormatter sharedFormatter]; stringFormatter = [GCSStringFormatter sharedFormatter];
} }
@ -106,7 +99,7 @@ static NSArray *contentFieldNames = nil;
if ((self = [super init])) { if ((self = [super init])) {
folderManager = [_fm retain]; folderManager = [_fm retain];
folderInfo = [_ftype retain]; folderInfo = [_ftype retain];
fields = [[_ftype fields] objectEnumerator]; fields = [[_ftype quickFields] objectEnumerator];
quickFieldNames = [NSMutableArray new]; quickFieldNames = [NSMutableArray new];
while ((field = [fields nextObject])) while ((field = [fields nextObject]))
{ {
@ -114,6 +107,14 @@ static NSArray *contentFieldNames = nil;
if (![fieldName isEqualToString: @"c_name"]) if (![fieldName isEqualToString: @"c_name"])
[quickFieldNames addObject: fieldName]; [quickFieldNames addObject: fieldName];
} }
fields = [[_ftype fields] objectEnumerator];
contentFieldNames = [NSMutableArray new];
while ((field = [fields nextObject]))
{
fieldName = [field columnName];
[contentFieldNames addObject: fieldName];
}
folderId = [_folderId copy]; folderId = [_folderId copy];
folderName = [[_path lastPathComponent] copy]; folderName = [[_path lastPathComponent] copy];
@ -163,6 +164,7 @@ static NSArray *contentFieldNames = nil;
[location release]; [location release];
[quickLocation release]; [quickLocation release];
[quickFieldNames release]; [quickFieldNames release];
[contentFieldNames release];
[aclLocation release]; [aclLocation release];
[folderTypeName release]; [folderTypeName release];
[super dealloc]; [super dealloc];
@ -667,15 +669,20 @@ static NSArray *contentFieldNames = nil;
} }
- (NSString *)_generateUpdateStatementForRow:(NSDictionary *)_row - (NSString *)_generateUpdateStatementForRow:(NSDictionary *)_row
tableName:(NSString *)_table adaptor:(EOAdaptor *)_adaptor
whereColumn:(NSString *)_colname isEqualTo:(id)_value fields:(NSArray *)_fields
andColumn:(NSString *)_colname2 isEqualTo:(id)_value2 tableName:(NSString *)_table
whereColumn:(NSString *)_colname isEqualTo:(id)_value
andColumn:(NSString *)_colname2 isEqualTo:(id)_value2
{ {
// TODO: move to NSDictionary category? // TODO: move to NSDictionary category?
NSMutableString *sql; NSMutableString *sql;
NSArray *keys; NSArray *keys;
NSString *fieldName, *sqlType;
EOAttribute *attribute;
id value;
unsigned i, count; unsigned i, count;
if (_row == nil || _table == nil) if (_row == nil || _table == nil)
return nil; return nil;
@ -684,18 +691,30 @@ static NSArray *contentFieldNames = nil;
sql = [NSMutableString stringWithCapacity:512]; sql = [NSMutableString stringWithCapacity:512];
[sql appendString:@"UPDATE "]; [sql appendString:@"UPDATE "];
[sql appendString:_table]; [sql appendString:_table];
[sql appendString:@" SET "]; [sql appendString:@" SET "];
for (i = 0, count = [keys count]; i < count; i++) { for (i = 0, count = [keys count]; i < count; i++) {
id value; fieldName = [keys objectAtIndex:i];
sqlType = [self _sqlTypeForColumn: fieldName withFieldInfos: _fields];
value = [_row objectForKey:[keys objectAtIndex:i]]; if (sqlType)
value = [self _formatRowValue:value]; {
value = [_row objectForKey: fieldName];
if (i != 0) [sql appendString:@", "]; attribute = AUTORELEASE([[EOAttribute alloc] init]);
[sql appendString:[keys objectAtIndex:i]]; [attribute setName: fieldName];
[sql appendString:@" = "]; [attribute setColumnName: fieldName];
[sql appendString:value]; [attribute setExternalType: sqlType];
if (i != 0) [sql appendString:@", "];
[sql appendString:fieldName];
[sql appendString:@" = "];
[sql appendString:[_adaptor formatValue: value forAttribute: attribute]];
}
else
{
[self errorWithFormat:@"%s: no type found for column name %@",
__PRETTY_FUNCTION__, fieldName];
}
} }
[sql appendString:@" WHERE "]; [sql appendString:@" WHERE "];
@ -713,6 +732,26 @@ static NSArray *contentFieldNames = nil;
return sql; return sql;
} }
- (NSString *) _sqlTypeForColumn: (NSString *) _field withFieldInfos: (NSArray *) _fields
{
NSString *sqlType;
NSEnumerator *fields;
GCSFieldInfo *fieldInfo;
sqlType = nil;
fields = [_fields objectEnumerator];
while ((fieldInfo = [fields nextObject]))
{
if ([[fieldInfo columnName] caseInsensitiveCompare: _field] == NSOrderedSame)
{
sqlType = [fieldInfo sqlType];
break;
}
}
return sqlType;
}
- (EOEntity *) _entityWithName: (NSString *) _name - (EOEntity *) _entityWithName: (NSString *) _name
{ {
EOAttribute *attribute; EOAttribute *attribute;
@ -749,7 +788,6 @@ static NSArray *contentFieldNames = nil;
{ {
EOEntity *entity; EOEntity *entity;
EOAttribute *attribute; EOAttribute *attribute;
GCSFieldInfo *field;
NSEnumerator *fields; NSEnumerator *fields;
NSString *fieldName; NSString *fieldName;
@ -956,6 +994,8 @@ static NSArray *contentFieldNames = nil;
isEqualTo: _name andColumn: nil isEqualTo: nil isEqualTo: _name andColumn: nil isEqualTo: nil
entity: quickTableEntity]] entity: quickTableEntity]]
: [quickChannel evaluateExpressionX: [self _generateUpdateStatementForRow: quickRow : [quickChannel evaluateExpressionX: [self _generateUpdateStatementForRow: quickRow
adaptor: [[quickChannel adaptorContext] adaptor]
fields: [folderInfo quickFields]
tableName: [self quickTableName] tableName: [self quickTableName]
whereColumn: @"c_name" isEqualTo: _name whereColumn: @"c_name" isEqualTo: _name
andColumn: nil isEqualTo: nil]]); andColumn: nil isEqualTo: nil]]);
@ -966,7 +1006,10 @@ static NSArray *contentFieldNames = nil;
andColumn: (_baseVersion != 0 ? (id)@"c_version" : (id)nil) andColumn: (_baseVersion != 0 ? (id)@"c_version" : (id)nil)
isEqualTo: (_baseVersion != 0 ? [NSNumber numberWithUnsignedInt:_baseVersion] : (NSNumber *)nil) isEqualTo: (_baseVersion != 0 ? [NSNumber numberWithUnsignedInt:_baseVersion] : (NSNumber *)nil)
entity: storeTableEntity]] entity: storeTableEntity]]
: [storeChannel evaluateExpressionX: [self _generateUpdateStatementForRow: contentRow tableName:[self storeTableName] : [storeChannel evaluateExpressionX: [self _generateUpdateStatementForRow: contentRow
adaptor: [[storeChannel adaptorContext] adaptor]
fields: [folderInfo fields]
tableName:[self storeTableName]
whereColumn: @"c_name" isEqualTo: _name whereColumn: @"c_name" isEqualTo: _name
andColumn: (_baseVersion != 0 ? (id)@"c_version" : (id)nil) andColumn: (_baseVersion != 0 ? (id)@"c_version" : (id)nil)
isEqualTo: (_baseVersion != 0 ? [NSNumber numberWithUnsignedInt: _baseVersion] : (NSNumber *)nil)]]); isEqualTo: (_baseVersion != 0 ? [NSNumber numberWithUnsignedInt: _baseVersion] : (NSNumber *)nil)]]);

View File

@ -45,10 +45,10 @@
@interface GCSFolderType : NSObject @interface GCSFolderType : NSObject
{ {
NSString *blobTablePattern; // eg 'SOGo_$folderId$_blob NSString *blobTablePattern; // eg 'SOGo_$folderId$_blob
NSString *quickTablePattern; // eg 'SOGo_$folderId$_quick NSString *quickTablePattern; // eg 'SOGo_$folderId$_quick
NSArray *fields; // GCSFieldInfo objects NSArray *fields, *quickFields; // GCSFieldInfo objects
EOQualifier *folderQualifier; // to further limit the table set EOQualifier *folderQualifier; // to further limit the table set
NSString *extractorClassName; NSString *extractorClassName;
GCSFieldExtractor *extractor; GCSFieldExtractor *extractor;
} }
@ -76,6 +76,7 @@
+ (NGResourceLocator *)resourceLocator; + (NGResourceLocator *)resourceLocator;
- (NSArray *) fields; - (NSArray *) fields;
- (NSArray *) quickFields;
@end @end
#endif /* __GDLContentStore_GCSFolderType_H__ */ #endif /* __GDLContentStore_GCSFolderType_H__ */

View File

@ -78,6 +78,8 @@
fields = [[GCSFieldInfo fieldsForPropertyList: fields = [[GCSFieldInfo fieldsForPropertyList:
[plist objectForKey:@"fields"]] retain]; [plist objectForKey:@"fields"]] retain];
quickFields = [[GCSFieldInfo fieldsForPropertyList:
[plist objectForKey:@"quickFields"]] retain];
} }
return self; return self;
@ -119,6 +121,7 @@
[blobTablePattern release]; [blobTablePattern release];
[quickTablePattern release]; [quickTablePattern release];
[fields release]; [fields release];
[quickFields release];
[folderQualifier release]; [folderQualifier release];
[super dealloc]; [super dealloc];
} }
@ -159,11 +162,11 @@
unsigned i, count; unsigned i, count;
sql = [NSMutableString stringWithFormat: @"CREATE TABLE %@ (", _tabName]; sql = [NSMutableString stringWithFormat: @"CREATE TABLE %@ (", _tabName];
count = [fields count]; count = [quickFields count];
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
if (i > 0) [sql appendString:@", "]; if (i > 0) [sql appendString:@", "];
[sql appendFormat: @" %@", [[fields objectAtIndex:i] sqlCreateSection]]; [sql appendFormat: @" %@", [[quickFields objectAtIndex:i] sqlCreateSection]];
} }
[sql appendString:@"\n)"]; [sql appendString:@"\n)"];
@ -200,6 +203,11 @@
return quickExtractor; return quickExtractor;
} }
- (NSArray *) quickFields
{
return quickFields;
}
- (NSArray *) fields - (NSArray *) fields
{ {
return fields; return fields;
@ -217,6 +225,7 @@
[ms appendFormat:@" blobtable='%@'", blobTablePattern]; [ms appendFormat:@" blobtable='%@'", blobTablePattern];
[ms appendFormat:@" quicktable='%@'", quickTablePattern]; [ms appendFormat:@" quicktable='%@'", quickTablePattern];
[ms appendFormat:@" fields=%@", fields]; [ms appendFormat:@" fields=%@", fields];
[ms appendFormat:@" quickFields=%@", fields];
[ms appendFormat:@" extractor=%@", extractorClassName]; [ms appendFormat:@" extractor=%@", extractorClassName];
if (folderQualifier) if (folderQualifier)