Monotone-Parent: dac752317ac0c81975ef28320e87acabbe394823

Monotone-Revision: 56f352efadfe2c0d5853cf5995e81a1cca3e4f21

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2011-11-14T17:31:29
maint-2.0.2
Wolfgang Sourdeau 2011-11-14 17:31:29 +00:00
parent be0053879e
commit f975ef9ce8
2 changed files with 98 additions and 64 deletions

View File

@ -3,6 +3,10 @@
* GCSFolder.m * GCSFolder.m
(_generateUpdateStatementForRow:adaptor:fields:tableName:whereColumn:isEqualTo:andColumn:isEqualTo:): (_generateUpdateStatementForRow:adaptor:fields:tableName:whereColumn:isEqualTo:andColumn:isEqualTo:):
same as below. same as below.
(_attributeForColumn:): new helper method that automatically
constructs an EOAttribute for a colum name passed as parameter.
(_formatRowValue:withAdaptor:andAttribute:): now invokes
-[EOAdaptor formatValue:forAttribute:] to avoid a call from the caller.
2011-10-21 Francis Lachapelle <flachapelle@inverse.ca> 2011-10-21 Francis Lachapelle <flachapelle@inverse.ca>

View File

@ -600,17 +600,15 @@ static GCSStringFormatter *stringFormatter = nil;
/* writing content */ /* writing content */
- (NSString *)_formatRowValue:(id)_value { - (NSString *)_formatRowValue:(id)_value
withAdaptor: (EOAdaptor *)_adaptor
andAttribute: (EOAttribute *)_attribute
{
if ([_value isKindOfClass:NSCalendarDateClass]) { if ([_value isKindOfClass:NSCalendarDateClass]) {
/* be smart ... convert to timestamp. Note: we loose precision. */ _value = [NSString stringWithFormat: @"%d", (int)[_value timeIntervalSince1970]];
char buf[256];
snprintf(buf, sizeof(buf), "%i", (int)[_value timeIntervalSince1970]);
return [NSString stringWithCString:buf];
}
else {
return _value;
} }
return [_adaptor formatValue: _value forAttribute: _attribute];
} }
- (NSString *) _sqlTypeForColumn: (NSString *) _field withFieldInfos: (NSArray *) _fields - (NSString *) _sqlTypeForColumn: (NSString *) _field withFieldInfos: (NSArray *) _fields
@ -633,14 +631,36 @@ static GCSStringFormatter *stringFormatter = nil;
return sqlType; return sqlType;
} }
- (EOAttribute *) _attributeForColumn: (NSString *) _field
{
NSString *sqlType;
EOAttribute *attribute;
sqlType = [self _sqlTypeForColumn: _field
withFieldInfos: [folderInfo quickFields]];
if (!sqlType)
sqlType = [self _sqlTypeForColumn: _field
withFieldInfos: [folderInfo fields]];
if (sqlType)
{
attribute = AUTORELEASE([[EOAttribute alloc] init]);
[attribute setName: _field];
[attribute setColumnName: _field];
[attribute setExternalType: sqlType];
}
else
attribute = nil;
return attribute;
}
- (NSString *) _generateInsertStatementForRow:(NSDictionary *)_row - (NSString *) _generateInsertStatementForRow:(NSDictionary *)_row
adaptor:(EOAdaptor *)_adaptor adaptor:(EOAdaptor *)_adaptor
fields:(NSArray *)_fields
tableName:(NSString *)_table tableName:(NSString *)_table
{ {
// TODO: move to NSDictionary category? // TODO: move to NSDictionary category?
NSMutableString *sql; NSMutableString *sql;
NSString *fieldName, *sqlType; NSString *fieldName;
NSArray *keys; NSArray *keys;
EOAttribute *attribute; EOAttribute *attribute;
id value; id value;
@ -665,18 +685,13 @@ static GCSStringFormatter *stringFormatter = nil;
for (i = 0, count = [keys count]; i < count; i++) { for (i = 0, count = [keys count]; i < count; i++) {
fieldName = [keys objectAtIndex:i]; fieldName = [keys objectAtIndex:i];
sqlType = [self _sqlTypeForColumn: fieldName withFieldInfos: _fields]; attribute = [self _attributeForColumn: fieldName];
if (attribute)
if (sqlType)
{ {
value = [self _formatRowValue: [_row objectForKey: fieldName]];
attribute = AUTORELEASE([[EOAttribute alloc] init]);
[attribute setName: fieldName];
[attribute setColumnName: fieldName];
[attribute setExternalType: sqlType];
if (i != 0) [sql appendString:@", "]; if (i != 0) [sql appendString:@", "];
[sql appendString:[_adaptor formatValue: value forAttribute: attribute]]; value = [self _formatRowValue: [_row objectForKey: fieldName]
withAdaptor: _adaptor andAttribute: attribute];
[sql appendString: value];
} }
else else
{ {
@ -691,7 +706,6 @@ static GCSStringFormatter *stringFormatter = nil;
- (NSString *)_generateUpdateStatementForRow:(NSDictionary *)_row - (NSString *)_generateUpdateStatementForRow:(NSDictionary *)_row
adaptor:(EOAdaptor *)_adaptor adaptor:(EOAdaptor *)_adaptor
fields:(NSArray *)_fields
tableName:(NSString *)_table tableName:(NSString *)_table
whereColumn:(NSString *)_colname isEqualTo:(id)_value whereColumn:(NSString *)_colname isEqualTo:(id)_value
andColumn:(NSString *)_colname2 isEqualTo:(id)_value2 andColumn:(NSString *)_colname2 isEqualTo:(id)_value2
@ -699,7 +713,7 @@ static GCSStringFormatter *stringFormatter = nil;
// TODO: move to NSDictionary category? // TODO: move to NSDictionary category?
NSMutableString *sql; NSMutableString *sql;
NSArray *keys; NSArray *keys;
NSString *fieldName, *sqlType; NSString *fieldName;
EOAttribute *attribute; EOAttribute *attribute;
id value; id value;
unsigned i, count; unsigned i, count;
@ -716,20 +730,16 @@ static GCSStringFormatter *stringFormatter = nil;
for (i = 0, count = [keys count]; i < count; i++) { for (i = 0, count = [keys count]; i < count; i++) {
fieldName = [keys objectAtIndex:i]; fieldName = [keys objectAtIndex:i];
sqlType = [self _sqlTypeForColumn: fieldName withFieldInfos: _fields];
if (sqlType) attribute = [self _attributeForColumn: fieldName];
if (attribute)
{ {
value = [self _formatRowValue: [_row objectForKey: fieldName]];
attribute = AUTORELEASE([[EOAttribute alloc] init]);
[attribute setName: fieldName];
[attribute setColumnName: fieldName];
[attribute setExternalType: sqlType];
if (i != 0) [sql appendString:@", "]; if (i != 0) [sql appendString:@", "];
[sql appendString:fieldName]; [sql appendString:fieldName];
[sql appendString:@" = "]; [sql appendString:@" = "];
[sql appendString:[_adaptor formatValue: value forAttribute: attribute]]; value = [self _formatRowValue: [_row objectForKey: fieldName]
withAdaptor: _adaptor andAttribute: attribute];
[sql appendString: value];
} }
else else
{ {
@ -738,27 +748,23 @@ static GCSStringFormatter *stringFormatter = nil;
} }
} }
sqlType = [self _sqlTypeForColumn: _colname withFieldInfos: _fields];
attribute = AUTORELEASE([[EOAttribute alloc] init]);
[attribute setName: _colname];
[attribute setColumnName: _colname];
[attribute setExternalType: sqlType];
[sql appendString:@" WHERE "]; [sql appendString:@" WHERE "];
[sql appendString:_colname]; [sql appendString:_colname];
[sql appendString:@" = "]; [sql appendString:@" = "];
[sql appendString:[_adaptor formatValue: [self _formatRowValue:_value] forAttribute: attribute]]; attribute = [self _attributeForColumn: _colname];
value = [self _formatRowValue: _value
withAdaptor: _adaptor andAttribute: attribute];
[sql appendString: value];
if (_colname2 != nil) { if (_colname2 != nil) {
[sql appendString:@" AND "]; [sql appendString:@" AND "];
sqlType = [self _sqlTypeForColumn: _colname2 withFieldInfos: _fields];
attribute = AUTORELEASE([[EOAttribute alloc] init]);
[attribute setName: _colname2];
[attribute setColumnName: _colname2];
[attribute setExternalType: sqlType];
[sql appendString:_colname2]; [sql appendString:_colname2];
[sql appendString:@" = "]; [sql appendString:@" = "];
[sql appendString:[_adaptor formatValue: [self _formatRowValue:_value2] forAttribute: attribute]]; attribute = [self _attributeForColumn: _colname2];
value = [self _formatRowValue: _value2
withAdaptor: _adaptor andAttribute: attribute];
[sql appendString: value];
} }
return sql; return sql;
@ -821,19 +827,30 @@ static GCSStringFormatter *stringFormatter = nil;
andColumn:(NSString *)_colname2 andColumn:(NSString *)_colname2
isEqualTo:(id)_value2 isEqualTo:(id)_value2
entity: (EOEntity *)_entity entity: (EOEntity *)_entity
withAdaptor: (EOAdaptor *)_adaptor
{ {
EOSQLQualifier *qualifier; EOSQLQualifier *qualifier;
EOAttribute *attribute1, *attribute2;
attribute1 = [_entity attributeNamed: _colname];
if (_colname2 == nil) if (_colname2 == nil)
{ {
qualifier = [[EOSQLQualifier alloc] initWithEntity: _entity qualifier = [[EOSQLQualifier alloc] initWithEntity: _entity
qualifierFormat: @"%A = %@", _colname, [self _formatRowValue:_value]]; qualifierFormat: @"%A = %@", _colname,
[self _formatRowValue:_value
withAdaptor: _adaptor andAttribute: attribute1]];
} }
else else
{ {
attribute2 = [_entity attributeNamed: _colname2];
qualifier = [[EOSQLQualifier alloc] initWithEntity: _entity qualifier = [[EOSQLQualifier alloc] initWithEntity: _entity
qualifierFormat: @"%A = %@ AND %A = %@", _colname, [self _formatRowValue:_value], qualifierFormat: @"%A = %@ AND %A = %@",
_colname2, [self _formatRowValue:_value2]]; _colname,
[self _formatRowValue:_value
withAdaptor: _adaptor andAttribute: attribute1],
_colname2,
[self _formatRowValue:_value2
withAdaptor: _adaptor andAttribute: attribute2]];
} }
return AUTORELEASE(qualifier); return AUTORELEASE(qualifier);
@ -842,15 +859,21 @@ static GCSStringFormatter *stringFormatter = nil;
- (void) _purgeRecordWithName: (NSString *) recordName - (void) _purgeRecordWithName: (NSString *) recordName
{ {
NSString *delSql, *table; NSString *delSql, *table;
EOAdaptorContext *adaptorCtx;
EOAdaptorChannel *channel; EOAdaptorChannel *channel;
EOAttribute *attribute;
channel = [self acquireStoreChannel]; channel = [self acquireStoreChannel];
[[channel adaptorContext] beginTransaction]; adaptorCtx = [channel adaptorContext];
[adaptorCtx beginTransaction];
table = [self storeTableName]; table = [self storeTableName];
attribute = [self _attributeForColumn: @"c_name"];
delSql = [NSString stringWithFormat: @"DELETE FROM %@" delSql = [NSString stringWithFormat: @"DELETE FROM %@"
@" WHERE c_name = %@", table, @" WHERE c_name = %@", table,
[self _formatRowValue: recordName]]; [self _formatRowValue: recordName
withAdaptor: [adaptorCtx adaptor]
andAttribute: attribute]];
[channel evaluateExpressionX: delSql]; [channel evaluateExpressionX: delSql];
[[channel adaptorContext] commitTransaction]; [[channel adaptorContext] commitTransaction];
@ -989,7 +1012,6 @@ static GCSStringFormatter *stringFormatter = nil;
: [quickChannel : [quickChannel
evaluateExpressionX: [self _generateInsertStatementForRow: quickRow evaluateExpressionX: [self _generateInsertStatementForRow: quickRow
adaptor: [[quickChannel adaptorContext] adaptor] adaptor: [[quickChannel adaptorContext] adaptor]
fields: [folderInfo quickFields]
tableName: [self quickTableName]]]); tableName: [self quickTableName]]]);
if (!error) if (!error)
@ -998,7 +1020,6 @@ static GCSStringFormatter *stringFormatter = nil;
: [storeChannel : [storeChannel
evaluateExpressionX: [self _generateInsertStatementForRow: contentRow evaluateExpressionX: [self _generateInsertStatementForRow: contentRow
adaptor: [[storeChannel adaptorContext] adaptor] adaptor: [[storeChannel adaptorContext] adaptor]
fields: [folderInfo fields]
tableName: [self storeTableName]]]); tableName: [self storeTableName]]]);
} }
else else
@ -1008,10 +1029,10 @@ static GCSStringFormatter *stringFormatter = nil;
? [quickChannel updateRowX: quickRow ? [quickChannel updateRowX: quickRow
describedByQualifier: [self _qualifierUsingWhereColumn: @"c_name" describedByQualifier: [self _qualifierUsingWhereColumn: @"c_name"
isEqualTo: _name andColumn: nil isEqualTo: nil isEqualTo: _name andColumn: nil isEqualTo: nil
entity: quickTableEntity]] entity: quickTableEntity
withAdaptor: [[storeChannel adaptorContext] adaptor]]]
: [quickChannel evaluateExpressionX: [self _generateUpdateStatementForRow: quickRow : [quickChannel evaluateExpressionX: [self _generateUpdateStatementForRow: quickRow
adaptor: [[quickChannel adaptorContext] adaptor] 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]]);
@ -1021,10 +1042,10 @@ static GCSStringFormatter *stringFormatter = nil;
describedByQualifier: [self _qualifierUsingWhereColumn: @"c_name" isEqualTo: _name describedByQualifier: [self _qualifierUsingWhereColumn: @"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)
entity: storeTableEntity]] entity: storeTableEntity
withAdaptor: [[storeChannel adaptorContext] adaptor]]]
: [storeChannel evaluateExpressionX: [self _generateUpdateStatementForRow: contentRow : [storeChannel evaluateExpressionX: [self _generateUpdateStatementForRow: contentRow
adaptor: [[storeChannel adaptorContext] adaptor] adaptor: [[storeChannel adaptorContext] adaptor]
fields: [folderInfo fields]
tableName:[self storeTableName] 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)
@ -1084,6 +1105,7 @@ static GCSStringFormatter *stringFormatter = nil;
- (NSException *)deleteContentWithName:(NSString *)_name { - (NSException *)deleteContentWithName:(NSString *)_name {
EOAdaptorChannel *storeChannel, *quickChannel; EOAdaptorChannel *storeChannel, *quickChannel;
EOAdaptorContext *adaptorCtx;
NSException *error; NSException *error;
NSString *delsql; NSString *delsql;
NSCalendarDate *nowDate; NSCalendarDate *nowDate;
@ -1119,7 +1141,8 @@ static GCSStringFormatter *stringFormatter = nil;
} }
if (!ofFlags.sameTableForQuick) [[quickChannel adaptorContext] beginTransaction]; if (!ofFlags.sameTableForQuick) [[quickChannel adaptorContext] beginTransaction];
[[storeChannel adaptorContext] beginTransaction]; adaptorCtx = [storeChannel adaptorContext];
[adaptorCtx beginTransaction];
/* delete rows */ /* delete rows */
nowDate = [NSCalendarDate calendarDate]; nowDate = [NSCalendarDate calendarDate];
@ -1129,7 +1152,9 @@ static GCSStringFormatter *stringFormatter = nil;
delsql = [delsql stringByAppendingFormat:@", c_lastmodified = %u", delsql = [delsql stringByAppendingFormat:@", c_lastmodified = %u",
(unsigned int) [nowDate timeIntervalSince1970]]; (unsigned int) [nowDate timeIntervalSince1970]];
delsql = [delsql stringByAppendingString:@" WHERE c_name="]; delsql = [delsql stringByAppendingString:@" WHERE c_name="];
delsql = [delsql stringByAppendingString:[self _formatRowValue:_name]]; delsql = [delsql stringByAppendingString: [self _formatRowValue:_name
withAdaptor: [adaptorCtx adaptor]
andAttribute: [self _attributeForColumn: @"c_name"]]];
if ((error = [storeChannel evaluateExpressionX:delsql]) != nil) { if ((error = [storeChannel evaluateExpressionX:delsql]) != nil) {
[self errorWithFormat: [self errorWithFormat:
@"%s: cannot delete content '%@': %@", @"%s: cannot delete content '%@': %@",
@ -1139,7 +1164,9 @@ static GCSStringFormatter *stringFormatter = nil;
/* content row deleted, now delete the quick row */ /* content row deleted, now delete the quick row */
delsql = [@"DELETE FROM " stringByAppendingString:[self quickTableName]]; delsql = [@"DELETE FROM " stringByAppendingString:[self quickTableName]];
delsql = [delsql stringByAppendingString:@" WHERE c_name="]; delsql = [delsql stringByAppendingString:@" WHERE c_name="];
delsql = [delsql stringByAppendingString:[self _formatRowValue:_name]]; delsql = [delsql stringByAppendingString: [self _formatRowValue:_name
withAdaptor: [adaptorCtx adaptor]
andAttribute: [self _attributeForColumn: @"c_name"]]];
if ((error = [quickChannel evaluateExpressionX:delsql]) != nil) { if ((error = [quickChannel evaluateExpressionX:delsql]) != nil) {
[self errorWithFormat: [self errorWithFormat:
@"%s: cannot delete quick row '%@': %@", @"%s: cannot delete quick row '%@': %@",
@ -1152,7 +1179,7 @@ static GCSStringFormatter *stringFormatter = nil;
} }
/* release channels and return */ /* release channels and return */
[[storeChannel adaptorContext] commitTransaction]; [adaptorCtx commitTransaction];
[self releaseChannel:storeChannel]; [self releaseChannel:storeChannel];
if (!ofFlags.sameTableForQuick) { if (!ofFlags.sameTableForQuick) {
@ -1254,24 +1281,27 @@ static GCSStringFormatter *stringFormatter = nil;
isEqualTo: (id) _value isEqualTo: (id) _value
{ {
EOAdaptorChannel *quickChannel; EOAdaptorChannel *quickChannel;
EOAdaptorContext *adaptorCtx;
NSException *error; NSException *error;
quickChannel = [self acquireQuickChannel]; quickChannel = [self acquireQuickChannel];
[[quickChannel adaptorContext] beginTransaction]; adaptorCtx = [quickChannel adaptorContext];
[adaptorCtx beginTransaction];
error = [quickChannel updateRowX: _fields error = [quickChannel updateRowX: _fields
describedByQualifier: [self _qualifierUsingWhereColumn: _colname describedByQualifier: [self _qualifierUsingWhereColumn: _colname
isEqualTo: _value andColumn: nil isEqualTo: nil isEqualTo: _value andColumn: nil isEqualTo: nil
entity: [self _quickTableEntity]]]; entity: [self _quickTableEntity]
withAdaptor: [adaptorCtx adaptor]]];
if (error) if (error)
{ {
[[quickChannel adaptorContext] rollbackTransaction]; [adaptorCtx rollbackTransaction];
[self logWithFormat: [self logWithFormat:
@"ERROR(%s): cannot update content : %@", __PRETTY_FUNCTION__, error]; @"ERROR(%s): cannot update content : %@", __PRETTY_FUNCTION__, error];
} }
else else
{ {
[[quickChannel adaptorContext] commitTransaction]; [adaptorCtx commitTransaction];
} }
[self releaseChannel: quickChannel]; [self releaseChannel: quickChannel];