From 409de8d58939dabd457c435a1ce032112f1a3fc3 Mon Sep 17 00:00:00 2001 From: Manuel Guesdon Date: Fri, 11 Feb 2005 17:31:29 +0000 Subject: [PATCH] * EOAccess/EOAdaptor.m: o optimization in 'for' loops * EOAccess/EODatabase.m: o include o replaced isNilOrEONull() by _isNilOrEONull() * EOAccess/EODatabaseContext.h: o added _snapshotForGlobalIDIMP * EOAccess/EODatabaseContext.m: o commented NSEmitTODO in -objectsForSourceGlobalID:relationshipName:editingContext: o added beter exception format in qualifierForLockingAttributes:primaryKeyAttributes:entity:snapshot: o fix compiler warning in -relayPrimaryKey:object:entity: o logs o optimizations in -objectsWithFetchSpecification:editingContext: o replaced isNilOrEONull() by _isNilOrEONull() o replace [EOFault isFault:] by _isFault() o use _snapshotForGlobalIDIMP o IMP usage optimization * EOAccess/EOAttribute.[hm]: o added EOAdaptorUnknownType o added _adaptorValueType and avoid recomputing it each time o added _valueTypeChar to avoid string comparaisons o use EOPriv classes declarations o Temporary reverted David changes in -adaptorValueByConvertingAttributeValue * EOAccess/EOAttributePriv.h: o added _valueTypeChar to avoid string comparaisons * EOAccess/EOEntityPriv.h: o moved -attributeForPath: and -relationshipForPath: to EOEntityGDL2Additions category * EOAccess/EOEntity.h: o moved private -attributeForPath: and -relationshipForPath: to EOEntityGDL2Additions category * EOAccess/EOEntity.m: o better exception in classProperties o fix compiler warning in -setClassProperties:, -setPrimaryKeyAttributes:, -setAttributesUsedForLocking: o moved -attributeForPath: and -relationshipForPath: to EOEntityGDL2Additions category o include o replaced [EONull null] by GDL2EONull * EOAccess/EOSQLExpression.m: o optimization in -tableListWithRootEntity: o optimization in -formatSQLString:format: o optimization in +sqlPatternFromShellPattern: o optimization in +sqlPatternFromShellPattern:withEscapeCharacter: o fix in -sqlStringForKeyValueQualifier: o added log in -sqlStringForKeyValueQualifier: for not handled readFormat o added log -addInsertListAttribute:value: for not handled writeFormat o added log -addUpdateListAttribute:value: for not handled writeFormat o changed EOFLOGObjectFnStart to EOFLOGObjectFnStartCond o changed EOFLOGObjectFnStop to EOFLOGObjectFnStopCond o include o replaced [EONull null] by GDL2EONull * EOAccess/EOSQLQualifier.m: o implemented EOKeyComparisonQualifier -schemaBasedQualifierWithRootEntity * EOAccess/EOUtilities.m: o include o replaced [EONull null] by GDL2EONull * EOControl/EOPriv.[hm]: o added. Contains various classes/selectors/IMPs * EOControl/EOClassDescription.m: o handle EONull case in -propagateDeleteForObject:editingContext:, -addObject:toPropertyWithKey:, -snapshot, -removeObject:fromPropertyWithKey:, _setObject:forBothSidesOfRelationshipWithKey:, addObject:toBothSidesOfRelationshipWithKey:, -removeObject:fromBothSidesOfRelationshipWithKey: o fix compiler warning in -dictionaryForInstanceProperties, -shallowCopy, -updateFromSnapshot:, -snapshot o include o replaced [EONull null] by GDL2EONull o replaced isNilOrEONull() by _isNilOrEONull() o fix in -validateForSave o rewritten -validateValue:forKey: selector build * EOControl/EOEditingContext.h: o added -hasUnprocessedChanges * EOControl/EOEditingContext.m: o added -hasUnprocessedChanges o added NS_DURING,... to catch exceptions o replace [EOFault isFault:] by _isFault() o IMP usage optimization * EOControl/EOKeyGlobalID.m: o replaced isNilOrEONull() by _isNilOrEONull() o include * EOControl/EOGenericRecord.m: o partially rewritten -description o include o replaced isNilOrEONull() by _isNilOrEONull() o replace [EOFault isFault:] by _isFault() o changed variable name type of _infoForInstanceVariableNamed:retType:retSize:retOffset: o rewritten valueForKey:,... to use cString NSKeyValueCoding * EOControl/EOKeyValueCoding.m: o changed NSAssert in NSArray -valueForKey: o optimization in NSDictionary -takeValue:forKeyPath:isSmart: o optimization in NSDictionary -takeStoredValue:forKeyPath: o include o replaced [EONull null] by GDL2EONull o include * EOControl/EOKeyValueQualifier.m: o fixes for EONull/nil in -evaluateWithObject: o replaced [EONull null] by GDL2EONull o include * EOControl/EOSortOrdering.m: o include o replaced [EONull null] by GDL2EONull * EOAdaptors/Postgres95SQLExpression.m: o float formatting in +formatValue:forAttribute: o added -externalNameQuoteCharacter o added +sqlPatternFromShellPattern: o added +sqlPatternFromShellPattern:withEscapeCharacter: o replaced isNilOrEONull() by _isNilOrEONull() * EOAdaptors/Postgres95Channel.m: o logs * EOAdaptors/Postgres95Values.m: o logs o fix in +setPostgres95Format: o fix calendard format to handle timezone (%z) o optimizations * EOControl/EOMutableKnownKeyDictionary.m o removed EOMKKDArrayMapping +dictionaryFromDictionary:subsetMapping: o include o replaced isNilOrEONull() by _isNilOrEONull() * EOControl/EONSAddOns.[hm]: o added NSString(ShellPattern) git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@20687 72102866-910b-0410-8b05-ffd578937521 --- EOControl/EOClassDescription.m | 1009 +++++++++++++---------- EOControl/EOEditingContext.h | 8 + EOControl/EOEditingContext.m | 970 ++++++++++++++-------- EOControl/EOFault.h | 1 + EOControl/EOFault.m | 5 + EOControl/EOFaultHandler.m | 4 + EOControl/EOGenericRecord.m | 729 +++++++++------- EOControl/EOKeyGlobalID.m | 12 +- EOControl/EOKeyValueCoding.m | 125 +-- EOControl/EOKeyValueQualifier.m | 85 +- EOControl/EOMutableKnownKeyDictionary.h | 9 + EOControl/EOMutableKnownKeyDictionary.m | 321 +++++-- EOControl/EONSAddOns.h | 8 +- EOControl/EONSAddOns.m | 13 +- EOControl/EONull.h | 1 + EOControl/EOPriv.h | 164 ++++ EOControl/EOPriv.m | 202 +++++ EOControl/EOSortOrdering.m | 26 +- EOControl/GNUmakefile | 5 +- 19 files changed, 2472 insertions(+), 1225 deletions(-) create mode 100644 EOControl/EOPriv.h create mode 100644 EOControl/EOPriv.m diff --git a/EOControl/EOClassDescription.m b/EOControl/EOClassDescription.m index 1a23099..854825c 100644 --- a/EOControl/EOClassDescription.m +++ b/EOControl/EOClassDescription.m @@ -68,6 +68,7 @@ RCS_ID("$Id$") #include #include #include +#include #include // NOTE: (stephane@sente.ch) Should we subclass NSClassDescription? @@ -108,11 +109,19 @@ static NSMapTable *classDescriptionForClass = NULL; static id classDelegate = nil; static NSRecursiveLock *local_lock = nil; -+ (void)initialize ++ (void) initialize { - if (self == [EOClassDescription class]) + static BOOL initialized=NO; + if (!initialized) { - Class cls = NSClassFromString(@"EOModelGroup"); + Class cls = Nil; + + initialized=YES; + + GDL2PrivInit(); + + cls = NSClassFromString(@"EOModelGroup"); + local_lock = [GSLazyRecursiveLock new]; classDescriptionForClass = NSCreateMapTable(NSObjectMapKeyCallBacks, @@ -274,7 +283,7 @@ static NSRecursiveLock *local_lock = nil; EOFLOGObjectFnStart(); // Get class properties (attributes + relationships) - classPropertyNames = [[NSMutableArray alloc] + classPropertyNames = [((NSMutableArray*)[NSMutableArray alloc]) initWithArray: [self attributeKeys]]; [classPropertyNames addObjectsFromArray: [self toOneRelationshipKeys]]; @@ -435,179 +444,186 @@ fromInsertionInEditingContext: (EOEditingContext *)anEditingContext NSDebugMLLog(@"gsdb",@"object %p=%@", object, object); - classDelegate = [[self class] classDelegate]; - - NSDebugMLLog(@"gsdb", @"classDelegate%p=%@", - classDelegate, - classDelegate); - - toRelArray = [object toOneRelationshipKeys]; - toRelEnum = [toRelArray objectEnumerator]; - - while ((key = [toRelEnum nextObject])) + if (object==GDL2EONull) { - BOOL shouldPropagate = YES; + NSWarnMLog(@"Warning: object is an EONull"); + } + else + { + classDelegate = [[self class] classDelegate]; - NSDebugMLLog(@"gsdb", @"ToOne key=%@", key); + NSDebugMLLog(@"gsdb", @"classDelegate%p=%@", + classDelegate, + classDelegate); + + toRelArray = [object toOneRelationshipKeys]; + toRelEnum = [toRelArray objectEnumerator]; + + while ((key = [toRelEnum nextObject])) + { + BOOL shouldPropagate = YES; + + NSDebugMLLog(@"gsdb", @"ToOne key=%@", key); + + if (classDelegate) + shouldPropagate = [classDelegate shouldPropagateDeleteForObject: object + inEditingContext: context + forRelationshipKey: key]; + + NSDebugMLLog(@"gsdb", @"ToOne key=%@ shouldPropagate=%s", key, + (shouldPropagate ? "YES" : "NO")); + + if (shouldPropagate) + { + destination = [object storedValueForKey: key]; + NSDebugMLLog(@"gsdb", @"destination %p=%@", + destination, destination); + + if (!_isNilOrEONull(destination)) + { + EODeleteRule deleteRule = [object deleteRuleForRelationshipKey: + key]; - if (classDelegate) - shouldPropagate = [classDelegate shouldPropagateDeleteForObject: object - inEditingContext: context - forRelationshipKey: key]; + NSDebugMLLog(@"gsdb", @"deleteRule=%d", (int)deleteRule); - NSDebugMLLog(@"gsdb", @"ToOne key=%@ shouldPropagate=%s", key, - (shouldPropagate ? "YES" : "NO")); + switch (deleteRule) + { + case EODeleteRuleNullify: + EOFLOGObjectLevel(@"gsdb", @"EODeleteRuleNullify"); + + [object removeObject: destination + fromBothSidesOfRelationshipWithKey: key]; + /* + [object takeValue:nil + forKey:key]; + inverseKey = [object inverseForRelationshipKey:key]; + NSDebugMLLog(@"gsdb",@"inverseKey=%@",inverseKey); + + if (inverseKey) + // p.ex. : the statement [employee inverseForRelationshipKey:@"department"] --> returns "employees" + [destination removeObject:object + fromPropertyWithKey:inverseKey]; + */ + break; + + case EODeleteRuleCascade: + //OK + EOFLOGObjectLevel(@"gsdb", @"EODeleteRuleCascade"); + [object removeObject: destination + fromBothSidesOfRelationshipWithKey: key]; + [context deleteObject: destination]; + [destination propagateDeleteWithEditingContext: context]; + break; + + case EODeleteRuleDeny: + EOFLOGObjectLevel(@"gsdb", @"EODeleteRuleDeny"); + // TODO don't know how to do yet, if raise an exception + // or something else. + NSEmitTODO(); + [self notImplemented: _cmd]; + break; + + case EODeleteRuleNoAction: + EOFLOGObjectLevel(@"gsdb", @"EODeleteRuleNoAction"); + break; + } + } + } + } + + toRelArray = [self toManyRelationshipKeys]; + toRelEnum = [toRelArray objectEnumerator]; - if (shouldPropagate) - { - destination = [object storedValueForKey: key]; - NSDebugMLLog(@"gsdb", @"destination %p=%@", - destination, destination); + while ((key = [toRelEnum nextObject])) + { + BOOL shouldPropagate = YES; - if (destination) - { - EODeleteRule deleteRule = [object deleteRuleForRelationshipKey: - key]; + NSDebugMLLog(@"gsdb", @"ToMany key=%@", key); + if (classDelegate) + shouldPropagate = [classDelegate shouldPropagateDeleteForObject: object + inEditingContext: context + forRelationshipKey: key]; + NSDebugMLLog(@"gsdb", @"ToMany key=%@ shouldPropagate=%s", key, + (shouldPropagate ? "YES" : "NO")); + + if (shouldPropagate) + { + NSArray *toManyArray; + EODeleteRule deleteRule; + + toManyArray = [object valueForKey: key]; + NSDebugMLLog(@"gsdb", @"toManyArray %p=%@", toManyArray, toManyArray); + + deleteRule = [object deleteRuleForRelationshipKey: key]; NSDebugMLLog(@"gsdb", @"deleteRule=%d", (int)deleteRule); - switch (deleteRule) - { - case EODeleteRuleNullify: + switch (deleteRule) + { + case EODeleteRuleNullify: EOFLOGObjectLevel(@"gsdb", @"EODeleteRuleNullify"); + NSDebugMLLog(@"gsdb", @"toManyArray %p=%@", toManyArray, + toManyArray); - [object removeObject: destination - fromBothSidesOfRelationshipWithKey: key]; - /* - [object takeValue:nil - forKey:key]; - inverseKey = [object inverseForRelationshipKey:key]; - NSDebugMLLog(@"gsdb",@"inverseKey=%@",inverseKey); + while ((destination = [toManyArray lastObject])) + { + NSDebugMLLog(@"gsdb", @"destination %p=%@", destination, + destination); - if (inverseKey) - // p.ex. : the statement [employee inverseForRelationshipKey:@"department"] --> returns "employees" - [destination removeObject:object - fromPropertyWithKey:inverseKey]; - */ - break; + [object removeObject: destination + fromBothSidesOfRelationshipWithKey: key]; + /* + inverseKey = [self inverseForRelationshipKey:key]; + NSDebugMLLog(@"gsdb",@"inverseKey=%@",inverseKey); - case EODeleteRuleCascade: + if (inverseKey) + [destination removeObject:object + fromPropertyWithKey:inverseKey]; + */ + } + NSDebugMLLog(@"gsdb", @"toManyArray %p=%@", + toManyArray, toManyArray); + break; + + case EODeleteRuleCascade: //OK EOFLOGObjectLevel(@"gsdb", @"EODeleteRuleCascade"); - [object removeObject: destination - fromBothSidesOfRelationshipWithKey: key]; - [context deleteObject: destination]; - [destination propagateDeleteWithEditingContext: context]; - break; + NSDebugMLLog(@"gsdb", @"toManyArray %p=%@", + toManyArray, toManyArray); - case EODeleteRuleDeny: + while ((destination = [toManyArray lastObject])) + { + NSDebugMLLog(@"gsdb", @"destination %p=%@", + destination, destination); + + [object removeObject: destination + fromBothSidesOfRelationshipWithKey: key]; + [context deleteObject: destination]; + [destination propagateDeleteWithEditingContext: context]; + } + NSDebugMLLog(@"gsdb", @"toManyArray %p=%@", + toManyArray, toManyArray); + break; + + case EODeleteRuleDeny: EOFLOGObjectLevel(@"gsdb", @"EODeleteRuleDeny"); - // TODO don't know how to do yet, if raise an exception - // or something else. - NSEmitTODO(); - [self notImplemented: _cmd]; - break; + NSDebugMLLog(@"gsdb", @"toManyArray %p=%@", + toManyArray, toManyArray); + if ([toManyArray count] > 0) + { + // TODO don't know how to do yet, if raise an exception + // or something else. + NSEmitTODO(); + [self notImplemented: _cmd]; + } + break; - case EODeleteRuleNoAction: + case EODeleteRuleNoAction: EOFLOGObjectLevel(@"gsdb", @"EODeleteRuleNoAction"); - break; - } - } - } - } - - toRelArray = [self toManyRelationshipKeys]; - toRelEnum = [toRelArray objectEnumerator]; - - while ((key = [toRelEnum nextObject])) - { - BOOL shouldPropagate = YES; - - NSDebugMLLog(@"gsdb", @"ToMany key=%@", key); - - if (classDelegate) - shouldPropagate = [classDelegate shouldPropagateDeleteForObject: object - inEditingContext: context - forRelationshipKey: key]; - NSDebugMLLog(@"gsdb", @"ToMany key=%@ shouldPropagate=%s", key, - (shouldPropagate ? "YES" : "NO")); - - if (shouldPropagate) - { - NSArray *toManyArray; - EODeleteRule deleteRule; - - toManyArray = [object valueForKey: key]; - NSDebugMLLog(@"gsdb", @"toManyArray %p=%@", toManyArray, toManyArray); - - deleteRule = [object deleteRuleForRelationshipKey: key]; - NSDebugMLLog(@"gsdb", @"deleteRule=%d", (int)deleteRule); - - switch (deleteRule) - { - case EODeleteRuleNullify: - EOFLOGObjectLevel(@"gsdb", @"EODeleteRuleNullify"); - NSDebugMLLog(@"gsdb", @"toManyArray %p=%@", toManyArray, - toManyArray); - - while ((destination = [toManyArray lastObject])) - { - NSDebugMLLog(@"gsdb", @"destination %p=%@", destination, - destination); - - [object removeObject: destination - fromBothSidesOfRelationshipWithKey: key]; - /* - inverseKey = [self inverseForRelationshipKey:key]; - NSDebugMLLog(@"gsdb",@"inverseKey=%@",inverseKey); - - if (inverseKey) - [destination removeObject:object - fromPropertyWithKey:inverseKey]; - */ - } - NSDebugMLLog(@"gsdb", @"toManyArray %p=%@", - toManyArray, toManyArray); - break; - - case EODeleteRuleCascade: - //OK - EOFLOGObjectLevel(@"gsdb", @"EODeleteRuleCascade"); - NSDebugMLLog(@"gsdb", @"toManyArray %p=%@", - toManyArray, toManyArray); - - while ((destination = [toManyArray lastObject])) - { - NSDebugMLLog(@"gsdb", @"destination %p=%@", - destination, destination); - - [object removeObject: destination - fromBothSidesOfRelationshipWithKey: key]; - [context deleteObject: destination]; - [destination propagateDeleteWithEditingContext: context]; - } - NSDebugMLLog(@"gsdb", @"toManyArray %p=%@", - toManyArray, toManyArray); - break; - - case EODeleteRuleDeny: - EOFLOGObjectLevel(@"gsdb", @"EODeleteRuleDeny"); - NSDebugMLLog(@"gsdb", @"toManyArray %p=%@", - toManyArray, toManyArray); - if ([toManyArray count] > 0) - { - // TODO don't know how to do yet, if raise an exception - // or something else. - NSEmitTODO(); - [self notImplemented: _cmd]; - } - break; - - case EODeleteRuleNoAction: - EOFLOGObjectLevel(@"gsdb", @"EODeleteRuleNoAction"); - break; - } - } + break; + } + } + } } EOFLOGObjectFnStop(); @@ -914,27 +930,29 @@ fromInsertionInEditingContext: (EOEditingContext *)anEditingContext if (exception == nil) { - NSMutableString *selString = [NSMutableString stringWithCapacity: 32]; - SEL validateSelector; - const char *str; - char l; + int size = [key length]; - str = [key cString]; - l = str[0]; + if (size < 1) + { + [NSException raise: NSInvalidArgumentException + format: @"storedValueForKey: ... empty key"]; + } + else + { + SEL validateSelector=NULL; + char buf[size+8]; // 8 characters for validate + strcpy(buf, "validate"); + [key getCString: &buf[8]]; + if (islower(buf[8])) + buf[8]=toupper(buf[8]); - if (islower(l)) - l = toupper(l); + validateSelector = sel_get_any_uid(buf); - [selString appendString: @"validate"]; - [selString appendString: [NSString stringWithCString: &l length: 1]]; - [selString appendString: [NSString stringWithCString: &str[1]]]; - [selString appendString: @":"]; - - validateSelector = NSSelectorFromString(selString); - if (validateSelector && [self respondsToSelector: validateSelector]) - exception = [self performSelector: validateSelector - withObject: *valueP]; + if (validateSelector && [self respondsToSelector: validateSelector]) + exception = [self performSelector: validateSelector + withObject: *valueP]; + }; } EOFLOGObjectFnStop(); @@ -980,6 +998,7 @@ fromInsertionInEditingContext: (EOEditingContext *)anEditingContext NSString *key = [keys objectAtIndex: i]; id value = [self valueForKey: key]; id newValue = value; + BOOL isEqual=NO; exception = [self validateValue: &newValue forKey: key]; @@ -988,11 +1007,21 @@ fromInsertionInEditingContext: (EOEditingContext *)anEditingContext if (!expArray) expArray = [NSMutableArray array]; [expArray addObject: exception]; - } + } + if (newValue==value) + isEqual = YES; + else if (_isNilOrEONull(newValue)) + isEqual = _isNilOrEONull(value); + else + isEqual = [newValue isEqual: value]; - if ([newValue isEqual: value] == NO) - [self takeValue: newValue - forKey: key]; + if (isEqual == NO) + { + NSDebugMLLog(@"gsdb", @"key=%@ newValue='%@' (class=%@) value='%@' (class=%@)", + key,newValue,[newValue class],value,[value class]); + [self takeValue: newValue + forKey: key]; + }; } } } @@ -1042,7 +1071,7 @@ fromInsertionInEditingContext: (EOEditingContext *)anEditingContext - (NSArray *)shallowCopy { - return [[NSArray alloc] initWithArray: self]; + return [((NSMutableArray*)[NSArray alloc]) initWithArray: self]; } @end @@ -1061,86 +1090,93 @@ fromInsertionInEditingContext: (EOEditingContext *)anEditingContext int attributeKeyCount; int toOneRelationshipKeyCount; int toManyRelationshipKeyCount; - EONull *null = (EONull *)[EONull null]; int i; EOFLOGObjectFnStart(); + NSDebugMLLog(@"gsdb", @"self=%@", self); - attributeKeys = [self attributeKeys]; - NSDebugMLLog(@"gsdb", @"attributeKeys=%@", attributeKeys); - - toOneRelationshipKeys = [self toOneRelationshipKeys]; - toManyRelationshipKeys = [self toManyRelationshipKeys]; - - attributeKeyCount = [attributeKeys count]; - toOneRelationshipKeyCount = [toOneRelationshipKeys count]; - toManyRelationshipKeyCount = [toManyRelationshipKeys count]; - - NSDebugMLLog(@"gsdb", @"attributeKeyCount=%d toOneRelationshipKeyCount=%d " - @"toManyRelationshipKeyCount=%d", - attributeKeyCount, toOneRelationshipKeyCount, - toManyRelationshipKeyCount); - - snapshot = [NSMutableDictionary dictionaryWithCapacity: attributeKeyCount - + toOneRelationshipKeyCount - + toManyRelationshipKeyCount]; - NSDebugMLLog(@"gsdb", @"attributeKeys=%@", attributeKeys); - - for (i = 0; i < attributeKeyCount; i++) + if (self==GDL2EONull) { - id key = [attributeKeys objectAtIndex: i]; - id value = [self storedValueForKey: key]; - - if (!value) - value = null; - - NSDebugMLLog(@"gsdb", @"snap=%p key=%@ ==> value %p=%@", - snapshot, key, value, value); - [snapshot setObject: value - forKey: key]; + NSWarnMLog(@"Warning: self is an EONull"); } - - NSDebugMLLog(@"gsdb", @"toOneRelationshipKeys=%@", toOneRelationshipKeys); - - for (i = 0; i < toOneRelationshipKeyCount; i++) + else { - id key = [toOneRelationshipKeys objectAtIndex: i]; - id value = [self storedValueForKey: key]; + attributeKeys = [self attributeKeys]; + NSDebugMLLog(@"gsdb", @"attributeKeys=%@", attributeKeys); - if (!value) - value = null; + toOneRelationshipKeys = [self toOneRelationshipKeys]; + toManyRelationshipKeys = [self toManyRelationshipKeys]; - NSDebugMLLog(@"gsdb", @"TOONE snap=%p key=%@ ==> value %p=%@", - snapshot, key, value, value); + attributeKeyCount = [attributeKeys count]; + toOneRelationshipKeyCount = [toOneRelationshipKeys count]; + toManyRelationshipKeyCount = [toManyRelationshipKeys count]; - [snapshot setObject: value - forKey: key]; - } + NSDebugMLLog(@"gsdb", @"attributeKeyCount=%d toOneRelationshipKeyCount=%d " + @"toManyRelationshipKeyCount=%d", + attributeKeyCount, toOneRelationshipKeyCount, + toManyRelationshipKeyCount); - NSDebugMLLog(@"gsdb", @"toManyRelationshipKeys=%@", toManyRelationshipKeys); + snapshot = [NSMutableDictionary dictionaryWithCapacity: attributeKeyCount + + toOneRelationshipKeyCount + + toManyRelationshipKeyCount]; + NSDebugMLLog(@"gsdb", @"attributeKeys=%@", attributeKeys); - for (i = 0; i < toManyRelationshipKeyCount; i++) - { - id key = [toManyRelationshipKeys objectAtIndex: i]; - id value = [self storedValueForKey: key]; - - if (value) + for (i = 0; i < attributeKeyCount; i++) { - NSDebugMLLog(@"gsdb", @"TOMANY snap=%p key=%@ ==> value %p=%@", - snapshot, key, value, value); + id key = [attributeKeys objectAtIndex: i]; + id value = [self storedValueForKey: key]; - value = AUTORELEASE([value shallowCopy]); - NSDebugMLLog(@"gsdb", @"TOMANY snap=%p key=%@ ==> value %p=%@", - snapshot, key, value, value); + if (!value) + value = GDL2EONull; + + NSDebugMLLog(@"gsdb", @"snap=%p key=%@ ==> value %p=%@", + snapshot, key, value, value); + [snapshot setObject: value + forKey: key]; + } + + NSDebugMLLog(@"gsdb", @"toOneRelationshipKeys=%@", toOneRelationshipKeys); + + for (i = 0; i < toOneRelationshipKeyCount; i++) + { + id key = [toOneRelationshipKeys objectAtIndex: i]; + id value = [self storedValueForKey: key]; + + if (!value) + value = GDL2EONull; + + NSDebugMLLog(@"gsdb", @"TOONE snap=%p key=%@ ==> value %p=%@", + snapshot, key, value, value); [snapshot setObject: value forKey: key]; } - /* //TODO-VERIFY or set it to eonull ? - else - value=null; - */ + + NSDebugMLLog(@"gsdb", @"toManyRelationshipKeys=%@", toManyRelationshipKeys); + + for (i = 0; i < toManyRelationshipKeyCount; i++) + { + id key = [toManyRelationshipKeys objectAtIndex: i]; + id value = [self storedValueForKey: key]; + + if (value) + { + NSDebugMLLog(@"gsdb", @"TOMANY snap=%p key=%@ ==> value %p=%@", + snapshot, key, value, value); + + value = AUTORELEASE([((NSArray*)value) shallowCopy]); + NSDebugMLLog(@"gsdb", @"TOMANY snap=%p key=%@ ==> value %p=%@", + snapshot, key, value, value); + + [snapshot setObject: value + forKey: key]; + } + /* //TODO-VERIFY or set it to eonull ? + else + value=GDL2EONull; + */ + } } NSDebugMLLog(@"gsdb", @"self=%p snapshot=%p", self, snapshot); @@ -1159,18 +1195,17 @@ fromInsertionInEditingContext: (EOEditingContext *)anEditingContext { NSEnumerator *snapshotEnum = [snapshot keyEnumerator]; NSString *key; - EONull *null = (EONull *)[EONull null]; id val; while ((key = [snapshotEnum nextObject])) { val = [snapshot objectForKey: key]; - if ([val isEqual: null]) + if (val==GDL2EONull) val = nil; if ([val isKindOfClass: [NSArray class]]) - val = AUTORELEASE([AUTORELEASE([val shallowCopy]) mutableCopy]); + val = AUTORELEASE([AUTORELEASE([((NSArray*)val) shallowCopy]) mutableCopy]); [self takeStoredValue: val forKey: key]; } @@ -1312,86 +1347,93 @@ toPropertyWithKey: (NSString *)key NSDebugMLLog(@"gsdb", @"object=%@", object); NSDebugMLLog(@"gsdb", @"key=%@", key); - str = [key cString]; - - NSDebugMLLog(@"gsdb", @"*+* ciao3 %@", key); - NSDebugMLLog(@"gsdb", @"*+* ciao3 %@", object); - - if ([key length]) + if (self==GDL2EONull) { - NSMutableString *selString = [NSMutableString stringWithCapacity: 25]; - SEL addToSelector; - char l = str[0]; + NSWarnMLog(@"Warning: self is an EONull. key=%@ object=%@",key,object); + } + else + { + str = [key cString]; - if (islower(l)) - l = toupper(l); + NSDebugMLLog(@"gsdb", @"*+* ciao3 %@", key); + NSDebugMLLog(@"gsdb", @"*+* ciao3 %@", object); - [selString appendString: @"addTo"]; - [selString appendString: [NSString stringWithCString: &l length: 1]]; - [selString appendString: [NSString stringWithCString: &str[1]]]; - [selString appendString: @":"]; - - addToSelector = NSSelectorFromString(selString); - - if (addToSelector && [self respondsToSelector: addToSelector] == YES) - { - NSDebugMLLog(@"gsdb", @"selector=%@", selString); - - [self performSelector: addToSelector - withObject: object]; - } - else + if ([key length]) { - id val = nil; + NSMutableString *selString = [NSMutableString stringWithCapacity: 25]; + SEL addToSelector; + char l = str[0]; - if ([self isToManyKey: key] == YES) - { - EOFLOGObjectLevel(@"gsdb", @"to many"); + if (islower(l)) + l = toupper(l); - val = [self valueForKey: key]; //should use storedValueForKey: ? + [selString appendString: @"addTo"]; + [selString appendString: [NSString stringWithCString: &l length: 1]]; + [selString appendString: [NSString stringWithCString: &str[1]]]; + [selString appendString: @":"]; - NSDebugMLLog(@"gsdb", @"to many val=%@ (%@)", val, [val class]); + addToSelector = NSSelectorFromString(selString); - if ([val containsObject: object]) + if (addToSelector && [self respondsToSelector: addToSelector] == YES) + { + NSDebugMLLog(@"gsdb", @"selector=%@", selString); + + [self performSelector: addToSelector + withObject: object]; + } + else + { + id val = nil; + + if ([self isToManyKey: key] == YES) { - NSDebugMLog(@"Object %p already in too many val=%@ (%@)", - object, val, [val class]); - } - else - { - if ([val isKindOfClass: [NSMutableArray class]]) + EOFLOGObjectLevel(@"gsdb", @"to many"); + + val = [self valueForKey: key]; //should use storedValueForKey: ? + + NSDebugMLLog(@"gsdb", @"to many val=%@ (%@)", val, [val class]); + + if ([val containsObject: object]) { - EOFLOGObjectLevel(@"gsdb", @"to many2"); - [self willChange]; - [val addObject: object]; + NSDebugMLog(@"Object %p already in too many val=%@ (%@)", + object, val, [val class]); } else { - NSMutableArray *relArray; - - if (val) - relArray = AUTORELEASE([val mutableCopy]); + if ([val isKindOfClass: [NSMutableArray class]]) + { + EOFLOGObjectLevel(@"gsdb", @"to many2"); + [self willChange]; + [val addObject: object]; + } else - relArray = [NSMutableArray arrayWithCapacity: 10]; + { + NSMutableArray *relArray; - NSDebugMLLog(@"gsdb", @"relArray=%@ (%@)", - relArray, [relArray class]); + if (val) + relArray = AUTORELEASE([val mutableCopy]); + else + relArray = [NSMutableArray arrayWithCapacity: 10]; - [relArray addObject: object]; - NSDebugMLLog(@"gsdb", @"relArray=%@ (%@)", - relArray, [relArray class]); + NSDebugMLLog(@"gsdb", @"relArray=%@ (%@)", + relArray, [relArray class]); - [self takeValue: relArray - forKey: key]; + [relArray addObject: object]; + NSDebugMLLog(@"gsdb", @"relArray=%@ (%@)", + relArray, [relArray class]); + + [self takeValue: relArray + forKey: key]; + } } } - } - else - { - EOFLOGObjectLevel(@"gsdb", @"key is not to many"); + else + { + EOFLOGObjectLevel(@"gsdb", @"key is not to many"); - [self takeValue: object - forKey: key]; + [self takeValue: object + forKey: key]; + } } } } @@ -1413,75 +1455,82 @@ toPropertyWithKey: (NSString *)key NSDebugMLLog(@"gsdb", @"object=%@", object); NSDebugMLLog(@"gsdb", @"key=%@ class=%@", key, [key class]); - str = [key cString]; - - if ([key length]) + if (self==GDL2EONull) { - NSMutableString *selString = [NSMutableString stringWithCapacity: 25]; - SEL removeFromSelector; - char l = str[0]; + NSWarnMLog(@"Warning: self is an EONull. key=%@ object=%@",key,object); + } + else + { + str = [key cString]; - if (islower(l)) - l = toupper(l); + if ([key length]) + { + NSMutableString *selString = [NSMutableString stringWithCapacity: 25]; + SEL removeFromSelector; + char l = str[0]; + + if (islower(l)) + l = toupper(l); - [selString appendString: @"removeFrom"]; - NSDebugMLLog(@"gsdb", @"selString=%@", selString); - [selString appendString: [NSString stringWithCString: &l - length: 1]]; - NSDebugMLLog(@"gsdb", @"selString=%@", selString); - [selString appendString: [NSString stringWithCString: &str[1]]]; - NSDebugMLLog(@"gsdb", @"selString=%@", selString); - [selString appendString: @":"]; - NSDebugMLLog(@"gsdb", @"selString=%@", selString); + [selString appendString: @"removeFrom"]; + NSDebugMLLog(@"gsdb", @"selString=%@", selString); + [selString appendString: [NSString stringWithCString: &l + length: 1]]; + NSDebugMLLog(@"gsdb", @"selString=%@", selString); + [selString appendString: [NSString stringWithCString: &str[1]]]; + NSDebugMLLog(@"gsdb", @"selString=%@", selString); + [selString appendString: @":"]; + NSDebugMLLog(@"gsdb", @"selString=%@", selString); - removeFromSelector = NSSelectorFromString(selString); + removeFromSelector = NSSelectorFromString(selString); - NSDebugMLLog(@"gsdb", @"selString=%@ removeFromSelector=%p", selString, - (void*)removeFromSelector); + NSDebugMLLog(@"gsdb", @"selString=%@ removeFromSelector=%p", selString, + (void*)removeFromSelector); - if (removeFromSelector && [self respondsToSelector: removeFromSelector]) - { - EOFLOGObjectLevel(@"gsdb", @"responds=YES"); - [self performSelector: removeFromSelector - withObject: object]; - } - else - { - id val = nil; - - EOFLOGObjectLevel(@"gsdb", @"responds=NO"); - - if ([self isToManyKey:key] == YES) - { - EOFLOGObjectLevel(@"gsdb", @"key is to many"); - - val = [self valueForKey: key]; - NSDebugMLLog(@"gsdb", @"val=%@", val); - - if ([val isKindOfClass: [NSMutableArray class]]) - { - [self willChange]; - [val removeObject: object]; - } - else - { - NSMutableArray *relArray = nil; - - if (val) - { - relArray = AUTORELEASE([val mutableCopy]); - - [relArray removeObject: object]; - [self takeValue: relArray - forKey: key]; - } - } - } - else + if (removeFromSelector && [self respondsToSelector: removeFromSelector]) { - EOFLOGObjectLevel(@"gsdb", @"key is not to many"); - [self takeValue: nil - forKey: key]; + EOFLOGObjectLevel(@"gsdb", @"responds=YES"); + [self performSelector: removeFromSelector + withObject: object]; + } + else + { + id val = nil; + + EOFLOGObjectLevel(@"gsdb", @"responds=NO"); + + if ([self isToManyKey:key] == YES) + { + EOFLOGObjectLevel(@"gsdb", @"key is to many"); + + val = [self valueForKey: key]; + NSDebugMLLog(@"gsdb", @"val=%@", val); + + if ([val isKindOfClass: [NSMutableArray class]]) + { + [self willChange]; + [val removeObject: object]; + } + else + { + NSMutableArray *relArray = nil; + + if (val) + { + relArray = AUTORELEASE([val mutableCopy]); + + [relArray removeObject: object]; + [self takeValue: relArray + forKey: key]; + } + } + } + else + { + EOFLOGObjectLevel(@"gsdb", @"key is not to many"); + [self takeValue: nil + forKey: key]; + } } } } @@ -1504,44 +1553,58 @@ forBothSidesOfRelationshipWithKey: (NSString*)key NSDebugMLLog(@"gsdb", @"object=%@", object); NSDebugMLLog(@"gsdb", @"key=%@", key); - inverseKey = [self inverseForRelationshipKey:key]; - NSDebugMLLog(@"gsdb", @"inverseKey=%@", inverseKey); - - oldObject = [self valueForKey: key]; - NSDebugMLLog(@"gsdb", @"oldObject=%@", oldObject); - - if (inverseKey) + if (self==GDL2EONull) { - [oldObject removeObject: self - fromPropertyWithKey: inverseKey]; - [object addObject: self - toPropertyWithKey: inverseKey]; -/* if ([object isToManyKey:inverseKey]) - { - //?? - EOFLOGObjectLevel(@"gsdb",@"Inverse is to many"); - [oldObject removeObject:self - fromPropertyWithKey:inverseKey]; - [object addObject:self - toPropertyWithKey:inverseKey]; - } - else - { - EOFLOGObjectLevel(@"gsdb",@"Inverse is not to many"); - //OK - //MIRKO if ((inverseKey = [oldObject inverseForRelationshipKey:key])) - //MIRKO [oldObject removeObject:self - // fromPropertyWithKey:inverseKey]; - [oldObject takeValue:nil - forKey:inverseKey]; - [object takeValue:self - forKey:inverseKey]; - }; -*/ + NSWarnMLog(@"Warning: self is an EONull. key=%@ object=%@",key,object); } + else + { + inverseKey = [self inverseForRelationshipKey:key]; + NSDebugMLLog(@"gsdb", @"inverseKey=%@", inverseKey); - [self takeValue: object - forKey: key]; + oldObject = [self valueForKey: key]; + NSDebugMLLog(@"gsdb", @"oldObject=%@", oldObject); + + if (inverseKey) + { + if (oldObject==GDL2EONull) + { + NSWarnMLog(@"Warning: oldObject is an EONull. self=%@ key=%@ object=%@",self,key,object); + } + else + { + [oldObject removeObject: self + fromPropertyWithKey: inverseKey]; + [object addObject: self + toPropertyWithKey: inverseKey]; + /* if ([object isToManyKey:inverseKey]) + { + //?? + EOFLOGObjectLevel(@"gsdb",@"Inverse is to many"); + [oldObject removeObject:self + fromPropertyWithKey:inverseKey]; + [object addObject:self + toPropertyWithKey:inverseKey]; + } + else + { + EOFLOGObjectLevel(@"gsdb",@"Inverse is not to many"); + //OK + //MIRKO if ((inverseKey = [oldObject inverseForRelationshipKey:key])) + //MIRKO [oldObject removeObject:self + // fromPropertyWithKey:inverseKey]; + [oldObject takeValue:nil + forKey:inverseKey]; + [object takeValue:self + forKey:inverseKey]; + }; + */ + } + } + + [self takeValue: object + forKey: key]; + } NSDebugMLLog(@"gsdb", @"self=%@", self); NSDebugMLLog(@"gsdb", @"object=%@", object); @@ -1558,57 +1621,71 @@ toBothSidesOfRelationshipWithKey: (NSString *)key NSDebugMLLog(@"gsdb", @"object=%@", object); NSDebugMLLog(@"gsdb", @"key=%@", key); - // 2 differents cases: to-one and to-many relation - if ([self isToManyKey:key]) // to-many + if (self==GDL2EONull) { - //See if there's an inverse relationship - NSString *inverseKey = [self inverseForRelationshipKey: key]; - - NSDebugMLLog(@"gsdb", @"self %p=%@,object %p=%@ key=%@ inverseKey=%@", - self, - self, - object, - object, - key, - inverseKey); - - // First add object to self relation array - [self addObject: object - toPropertyWithKey: key]; - - if (inverseKey) //if no inverse relation do nothing - { - // See if inverse relationship is to-many or to-one - if ([object isToManyKey: inverseKey]) - { - //TODO VERIFY - [object addObject:self - toPropertyWithKey:inverseKey]; - } - else - { - // Previous value, if any - id oldObject = [object valueForKey: inverseKey]; - - NSDebugMLLog(@"gsdb", @"oldObject=%@", oldObject); - - if (oldObject) - { - //TODO VERIFY - [object removeObject:oldObject - fromPropertyWithKey:inverseKey]; - } - - // Just set self into object relationship property - [object takeValue: self - forKey: inverseKey]; - } - } + NSWarnMLog(@"Warning: self is an EONull. key=%@ object=%@",key,object); } else { - [self _setObject: object - forBothSidesOfRelationshipWithKey: key]; + // 2 differents cases: to-one and to-many relation + if ([self isToManyKey:key]) // to-many + { + //See if there's an inverse relationship + NSString *inverseKey = [self inverseForRelationshipKey: key]; + + NSDebugMLLog(@"gsdb", @"self %p=%@,object %p=%@ key=%@ inverseKey=%@", + self, + self, + object, + object, + key, + inverseKey); + + // First add object to self relation array + [self addObject: object + toPropertyWithKey: key]; + + if (inverseKey) //if no inverse relation do nothing + { + if (object==GDL2EONull) + { + NSWarnMLog(@"Warning: object is an EONull. self=%@ key=%@ object=%@",self,key,object); + } + else + { + // See if inverse relationship is to-many or to-one + if ([object isToManyKey: inverseKey]) + { + //TODO VERIFY + [object addObject:self + toPropertyWithKey:inverseKey]; + } + else + { + // Previous value, if any + id oldObject = [object valueForKey: inverseKey]; + + NSDebugMLLog(@"gsdb", @"oldObject=%@", oldObject); + + if (oldObject) + { + //TODO VERIFY + [object removeObject:oldObject + fromPropertyWithKey:inverseKey]; + } + + // Just set self into object relationship property + [object takeValue: self + forKey: inverseKey]; + } + } + } + } + else + { + [self _setObject: object + forBothSidesOfRelationshipWithKey: key]; + } } NSDebugMLLog(@"gsdb", @"self=%@", self); @@ -1620,14 +1697,34 @@ toBothSidesOfRelationshipWithKey: (NSString *)key - (void)removeObject: (id)object fromBothSidesOfRelationshipWithKey: (NSString *)key { - NSString *inverseKey; + EOFLOGObjectFnStart(); - [self removeObject: object - fromPropertyWithKey: key]; + if (self==GDL2EONull) + { + NSWarnMLog(@"Warning: self is an EONull. key=%@ object=%@",key,object); + } + else + { + NSString *inverseKey=nil; - if ((inverseKey = [self inverseForRelationshipKey: key])) - [object removeObject: self - fromPropertyWithKey: inverseKey]; + [self removeObject: object + fromPropertyWithKey: key]; + + if ((inverseKey = [self inverseForRelationshipKey: key])) + { + if (object==GDL2EONull) + { + NSWarnMLog(@"Warning: object is an EONull. self=%@ key=%@",self,key); + } + else + { + [object removeObject: self + fromPropertyWithKey: inverseKey]; + } + }; + } + + EOFLOGObjectFnStop(); } @end @@ -1780,10 +1877,10 @@ fromBothSidesOfRelationshipWithKey: (NSString *)key val = [self storedValueForKey: key]; oldVal = [snapshot objectForKey: key]; - if ((id)val == [EONull null]) + if ((id)val == GDL2EONull) val = nil; - if ((id)oldVal == [EONull null]) + if ((id)oldVal == GDL2EONull) oldVal = nil; if (!val && !oldVal) diff --git a/EOControl/EOEditingContext.h b/EOControl/EOEditingContext.h index 5f8006c..f676c79 100644 --- a/EOControl/EOEditingContext.h +++ b/EOControl/EOEditingContext.h @@ -370,9 +370,17 @@ shouldContinueFetchingWithCurrentObjectCount: (unsigned)count */ @interface EOEditingContext (EOEditingContextInfo) +- (NSDictionary*)unprocessedObjects; - (NSDictionary *)unprocessedInfo; - (NSDictionary *)pendingInfo; +/** Returns YES if there unprocessed changes or deletes or inserts **/ +- (BOOL)hasUnprocessedChanges; + @end +// Private +GDL2CONTROL_EXPORT id EOEditingContext_objectForGlobalIDWithImpPtr(EOEditingContext* edContext,IMP* impPtr,EOGlobalID* gid); +EOGlobalID* EOEditingContext_globalIDForObjectWithImpPtr(EOEditingContext* edContext,IMP* impPtr,id object); +GDL2CONTROL_EXPORT id EOEditingContext_recordObjectGlobalIDWithImpPtr(EOEditingContext* edContext,IMP* impPtr,id object,EOGlobalID* gid); #endif diff --git a/EOControl/EOEditingContext.m b/EOControl/EOEditingContext.m index 7f47825..2f0afdd 100644 --- a/EOControl/EOEditingContext.m +++ b/EOControl/EOEditingContext.m @@ -54,6 +54,7 @@ RCS_ID("$Id$") #include #include #include +#include @class EOEntityClassDescription; @@ -157,8 +158,6 @@ RCS_ID("$Id$") @implementation EOEditingContext -static EONull *null = nil; -static Class EOEditingContextClass = nil; static Class EOAssociationClass = nil; static EOObjectStore *defaultParentStore = nil; @@ -205,33 +204,50 @@ _mergeValueForKey(id obj, id value, || (value != nil && add == nil && del == nil)), @"Illegal usage of function."); - for (i = 0, n = [del count]; i < n; i++) + n = [del count]; + if (n>0) { - relObj = [del objectAtIndex: i]; - [obj removeObject: relObj fromPropertyWithKey: key]; - } - for (i = 0, n = [add count]; i < n; i++) + IMP oaiIMP=[del methodForSelector: GDL2_objectAtIndexSEL]; + + for (i = 0; i < n; i++) + { + relObj = GDL2ObjectAtIndexWithImp(del,oaiIMP,i); + + [obj removeObject: relObj + fromPropertyWithKey: key]; + } + }; + + n = [add count]; + if (n>0) { - relObj = [add objectAtIndex: i]; - [obj addObject: relObj toPropertyWithKey: key]; - } + IMP oaiIMP=[add methodForSelector: GDL2_objectAtIndexSEL]; + + for (i = 0; i < n; i++) + { + relObj = GDL2ObjectAtIndexWithImp(add,oaiIMP,i); + + [obj addObject: relObj + toPropertyWithKey: key]; + } + }; if (add == nil && del == nil) { - value = (value == null) ? nil : value; + value = (value == GDL2EONull) ? nil : value; [obj takeStoredValue: value forKey: key]; } } + (void)initialize { - if (self == [EOEditingContext class] && defaultParentStore == nil) + static BOOL initialized=NO; + if (!initialized) { - BOOL gswapp; + BOOL gswapp = NO; + initialized=YES; defaultParentStore = [EOObjectStoreCoordinator defaultCoordinator]; - null = [EONull null]; - EOEditingContextClass = self; EOAssociationClass = NSClassFromString(@"EOAssociation"); gswapp = (NSClassFromString(@"GSWApplication") != nil || NSClassFromString(@"WOApplication") != nil); @@ -392,19 +408,25 @@ _mergeValueForKey(id obj, id value, NSDictionary *change; id val; - for(i = 0, n = [changes count]; i < n; i++) + n = [changes count]; + if (n>0) { - change = [changes objectAtIndex: i]; - key = [change objectForKey: EOConstKey]; - val = [change objectForKey: EOConstValue]; - if (val == nil) - { - add = [change objectForKey: EOConstAdd]; - del = [change objectForKey: EOConstDel]; - NSAssert(add!=nil && del!=nil,@"Invalid changes dictionary."); - } - _mergeValueForKey(obj, val, add, del, key); - } + IMP oaiIMP=[del methodForSelector: GDL2_objectAtIndexSEL]; + + for(i = 0; i < n; i++) + { + change = GDL2ObjectAtIndexWithImp(changes,oaiIMP,i); + key = [change objectForKey: EOConstKey]; + val = [change objectForKey: EOConstValue]; + if (val == nil) + { + add = [change objectForKey: EOConstAdd]; + del = [change objectForKey: EOConstDel]; + NSAssert(add!=nil && del!=nil,@"Invalid changes dictionary."); + } + _mergeValueForKey(obj, val, add, del, key); + } + }; } /* @@ -412,7 +434,7 @@ _mergeValueForKey(id obj, id value, * change action, based on a similar dictionary with globalIDs. * For each key of EODeletedKey, EOInsertedKey, EOInvalidatedKey * and EOUpdatedKey an array of corresponding GIDs from the - * CHANGES array will be mapped to the cooresponding objects + * CHANGES array will be mapped to the corresponding objects * managed by the receiver for ther returned dictionary. */ - (NSDictionary *)_objectBasedChangeInfoForGIDInfo: (NSDictionary *)changes @@ -422,8 +444,9 @@ _mergeValueForKey(id obj, id value, EOInvalidatedKey, EOUpdatedKey }; NSArray *valueArray[4]; - NSDictionary *dict; + NSDictionary *dict = nil; int i; + IMP objectForGlobalIDIMP = NULL; EOFLOGObjectFnStart(); @@ -439,13 +462,19 @@ _mergeValueForKey(id obj, id value, valuesPStart = valuesP = (cnt > GS_MAX_OBJECTS_FROM_STACK ? GSAutoreleasedBuffer(sizeof(id) * cnt) : values); - for (j=0; j0) { - EOGlobalID *gid = [gids objectAtIndex: j]; - id obj = [self objectForGlobalID: gid]; - NSAssert1(obj, @"called with GID %@ not managed by reciever.", gid); - *valuesP++ = obj; - } + IMP oaiIMP=[gids methodForSelector: GDL2_objectAtIndexSEL]; + + for (j=0; j0) { - id obj = [deletedGIDs objectAtIndex: i]; - [self _forgetObjectWithGlobalID: obj]; - } + IMP oaiIMP=[deletedGIDs methodForSelector: GDL2_objectAtIndexSEL]; + for (i = 0; i < n; i++) + { + id obj = GDL2ObjectAtIndexWithImp(deletedGIDs,oaiIMP,i); + [self _forgetObjectWithGlobalID: obj]; + } + }; invalidatedGIDs = [changes objectForKey: EOInvalidatedKey]; EOFLOGObjectLevelArgs(@"EOEditingContext", @"invalidatedGIDs=%@", @@ -548,14 +582,19 @@ _mergeValueForKey(id obj, id value, [_undoManager removeAllActionsWithTarget: self]; n = [updatedChanges count]; - for (i = 0; i < n; i++) + if (n>0) { - changeSet = [updatedChanges objectAtIndex: i]; - obj = [changeSet objectForKey: EOConstObject]; - chgs = [changeSet objectForKey: EOConstChanges]; + IMP oaiIMP=[deletedGIDs methodForSelector: GDL2_objectAtIndexSEL]; - [self _mergeObject: obj withChanges: chgs]; - } + for (i = 0; i < n; i++) + { + changeSet = GDL2ObjectAtIndexWithImp(updatedChanges,oaiIMP,i); + obj = [changeSet objectForKey: EOConstObject]; + chgs = [changeSet objectForKey: EOConstChanges]; + + [self _mergeObject: obj withChanges: chgs]; + } + }; } if ([updatedChanges count] @@ -589,14 +628,15 @@ _mergeValueForKey(id obj, id value, if ((n = [globalIDs count])) { + IMP oaiIMP=[globalIDs methodForSelector: GDL2_objectAtIndexSEL]; SEL sel = @selector(editingContext:shouldMergeChangesForObject:); BOOL send; send = [_delegate respondsToSelector: sel]; chgs = [NSMutableArray arrayWithCapacity: n]; - + for (i = 0; i < n; i++) { - EOGlobalID *globalID = [globalIDs objectAtIndex: i]; + EOGlobalID *globalID = GDL2ObjectAtIndexWithImp(globalIDs, oaiIMP, i); id obj = NSMapGet(_objectsByGID, globalID); if (obj != nil && [EOFault isFault: obj] == NO) @@ -652,72 +692,92 @@ _mergeValueForKey(id obj, id value, NSDictionary *change; id objVal, ssVal; unsigned i,n; + IMP chgsAddObjectIMP=[chgs methodForSelector: GDL2_addObjectSEL]; - for(i = 0, n = [attribKeys count]; i < n; i++) + n = [attribKeys count]; + if (n>0) { - key = [attribKeys objectAtIndex: i]; - objVal = [obj storedValueForKey: key]; - ssVal = [snapshot objectForKey: key]; + IMP oaiIMP=[attribKeys methodForSelector: GDL2_objectAtIndexSEL]; - objVal = (objVal == nil) ? null : objVal; - - if ([objVal isEqual: ssVal] == NO) + for(i = 0; i < n; i++) { - change = [NSDictionary dictionaryWithObjectsAndKeys: - key, EOConstKey, - objVal, EOConstValue, nil]; - [chgs addObject: change]; - } - } - - for(i = 0, n = [toOneKeys count]; i < n; i++) - { - key = [toOneKeys objectAtIndex: i]; - objVal = [obj storedValueForKey: key]; - ssVal = [snapshot objectForKey: key]; - if (objVal != nil) - { - EOGlobalID *gid = [self globalIDForObject: objVal]; - objVal = (gid == nil) ? null : objVal; - if (objVal != ssVal) + key = GDL2ObjectAtIndexWithImp(attribKeys,oaiIMP, i); + objVal = [obj storedValueForKey: key]; + ssVal = [snapshot objectForKey: key]; + + objVal = (objVal == nil) ? GDL2EONull : objVal; + + if ([objVal isEqual: ssVal] == NO) { - change = [NSDictionary dictionaryWithObjectsAndKeys: - key, EOConstKey, - objVal, EOConstValue, nil]; - [chgs addObject: change]; + change = [NSDictionary dictionaryWithObjectsAndKeys: + key, EOConstKey, + objVal, EOConstValue, nil]; + GDL2AddObjectWithImp(chgs, chgsAddObjectIMP, change); } } - } + }; - for(i = 0, n = [toManyKeys count]; i < n; i++) + n = [toOneKeys count]; + if (n>0) { - key = [toOneKeys objectAtIndex: i]; - objVal = [obj storedValueForKey: key]; - ssVal = [snapshot objectForKey: key]; - if ([EOFault isFault: objVal] == NO - && [EOFault isFault: ssVal] == NO) + IMP oaiIMP = [toOneKeys methodForSelector: GDL2_objectAtIndexSEL]; + IMP globalIDForObjectIMP = NULL; + + for(i = 0; i < n; i++) { - NSMutableSet *objSet = [self _mutableSetFromToManyArray: objVal]; - NSMutableSet *ssSet = [self _mutableSetFromToManyArray: ssVal]; - NSSet *_ssSet = [NSSet setWithSet: ssSet]; - - [ssSet minusSet: objSet]; /* now contains deleted objects */ - [objSet minusSet: _ssSet]; /* now contains added objects */ - - if ([objSet count] != 0 || [ssSet count] != 0) + key = GDL2ObjectAtIndexWithImp(toOneKeys, oaiIMP, i); + objVal = [obj storedValueForKey: key]; + ssVal = [snapshot objectForKey: key]; + if (objVal != nil) { - NSArray *addArr = [objSet allObjects]; - NSArray *delArr = [ssSet allObjects]; - - change = [NSDictionary dictionaryWithObjectsAndKeys: - key, EOConstKey, - addArr, EOConstAdd, - delArr, EOConstDel, - nil]; - [chgs addObject: change]; + EOGlobalID *gid = EOEditingContext_globalIDForObjectWithImpPtr(self, &globalIDForObjectIMP, objVal); + objVal = (gid == nil) ? GDL2EONull : objVal; + if (objVal != ssVal) + { + change = [NSDictionary dictionaryWithObjectsAndKeys: + key, EOConstKey, + objVal, EOConstValue, nil]; + GDL2AddObjectWithImp(chgs, chgsAddObjectIMP, change); + } } } - } + }; + + n = [toManyKeys count]; + if (n>0) + { + IMP oaiIMP=[toManyKeys methodForSelector: GDL2_objectAtIndexSEL]; + + for(i = 0; i < n; i++) + { + key = GDL2ObjectAtIndexWithImp(toManyKeys, oaiIMP, i); + objVal = [obj storedValueForKey: key]; + ssVal = [snapshot objectForKey: key]; + if ([EOFault isFault: objVal] == NO + && [EOFault isFault: ssVal] == NO) + { + NSMutableSet *objSet = [self _mutableSetFromToManyArray: objVal]; + NSMutableSet *ssSet = [self _mutableSetFromToManyArray: ssVal]; + NSSet *_ssSet = [NSSet setWithSet: ssSet]; + + [ssSet minusSet: objSet]; /* now contains deleted objects */ + [objSet minusSet: _ssSet]; /* now contains added objects */ + + if ([objSet count] != 0 || [ssSet count] != 0) + { + NSArray *addArr = [objSet allObjects]; + NSArray *delArr = [ssSet allObjects]; + + change = [NSDictionary dictionaryWithObjectsAndKeys: + key, EOConstKey, + addArr, EOConstAdd, + delArr, EOConstDel, + nil]; + GDL2AddObjectWithImp(chgs, chgsAddObjectIMP, change); + } + } + } + }; return ([chgs count] == 0) ? nil : chgs; } @@ -732,12 +792,19 @@ _mergeValueForKey(id obj, id value, set = [NSMutableSet setWithCapacity: n]; NSAssert(_objectsByGID, @"_objectsByGID does not exist!"); - for (i=0; i0) { - gid = [array objectAtIndex: i]; - obj = NSMapGet(_objectsByGID, gid); - [set addObject: obj]; - } + IMP oaiIMP=[array methodForSelector: GDL2_objectAtIndexSEL]; + IMP aoIMP=[set methodForSelector: GDL2_addObjectSEL]; + + for (i=0; itmpGID mapping. */ NSMapInsert(_globalIDsByObject, object, gid); + EOFLOGObjectLevelArgs(@"EOEditingContext", + @"objectsByGID: Remove Object tempGID=%@", + tempGID); NSMapRemove(_objectsByGID, tempGID); + + EOFLOGObjectLevelArgs(@"EOEditingContext", + @"objectsByGID: Insert Object gid=%@", + gid); NSMapInsert(_objectsByGID, gid, object); } else @@ -951,7 +1025,14 @@ _mergeValueForKey(id obj, id value, - (void) _forgetObjectWithGlobalID:(EOGlobalID*)gid { - id object = [self objectForGlobalID: gid]; + id object = nil; + + EOFLOGObjectFnStart(); + + NSDebugMLLog(@"EOEditingContext", @"forgetObjectWithGlobalID: %@", + gid); + + object = EOEditingContext_objectForGlobalIDWithImpPtr(self,NULL,gid); if (object != nil) { [self forgetObject: object]; @@ -964,6 +1045,8 @@ _mergeValueForKey(id obj, id value, [object clearProperties]; } } + + EOFLOGObjectFnStop(); } - (void) _invalidateObject: (id)object @@ -971,6 +1054,12 @@ _mergeValueForKey(id obj, id value, { SEL sel = @selector(editingContext:shouldInvalidateObject:globalID:); BOOL invalidate = YES; + + EOFLOGObjectFnStart(); + + NSDebugMLLog(@"EOEditingContext", @"invalidateObject:withGlobalID: %@", + gid); + if ([_delegate respondsToSelector: sel]) { invalidate = [_delegate editingContext: self @@ -983,32 +1072,49 @@ _mergeValueForKey(id obj, id value, withGlobalID: gid editingContext: self]; } + + EOFLOGObjectFnStop(); } - (void) _invalidateObjectWithGlobalID: (EOGlobalID*)gid { - id object = [self objectForGlobalID: gid]; + id object = nil; + + EOFLOGObjectFnStart(); + + NSDebugMLLog(@"EOEditingContext", @"invalidateObjectWithGlobalID: %@", + gid); + + object = EOEditingContext_objectForGlobalIDWithImpPtr(self,NULL,gid); if ((object != nil ) && ([EOFault isFault: object] == NO)) { [self _invalidateObject: object withGlobalID: gid]; } + + EOFLOGObjectFnStop(); } - (void) _invalidateObjectsWithGlobalIDs: (NSArray*)gids { - unsigned i, count; - SEL oaiSEL = @selector(objectAtIndex:); - SEL iowgidSEL = @selector(_invalidateObjectWithGlobalID:); - IMP oaiIMP = [gids methodForSelector: oaiSEL]; - IMP iowgidIMP = [self methodForSelector: iowgidSEL]; - + unsigned count = 0; + EOFLOGObjectFnStart(); - for (i=0, count=[gids count]; i0) { - EOGlobalID *gid = (*oaiIMP)(gids, oaiSEL, i); - (*iowgidIMP)(self, iowgidSEL, gid); - } + unsigned i = 0; + SEL iowgidSEL = @selector(_invalidateObjectWithGlobalID:);//TODO optimz + IMP oaiIMP = [gids methodForSelector: GDL2_objectAtIndexSEL]; + IMP iowgidIMP = [self methodForSelector: iowgidSEL]; + + for (i=0; i0) { - EOGlobalID *gid = [gids objectAtIndex: i]; - id obj = [self objectForGlobalID: gid]; + IMP oaiIMP = [gids methodForSelector: GDL2_objectAtIndexSEL]; + IMP insertedAddObjectIMP = NULL; + IMP deletedAddObjectIMP = NULL; + IMP objectForGlobalIDIMP=NULL; - if (obj != nil) + for (i=0; i 0) { - NSString *relKey = [toOneRelationshipKeys objectAtIndex: i]; - BOOL ownsDestinationObjects - = [object ownsDestinationObjectsForRelationshipKey:relKey]; - - EOFLOGObjectLevelArgs(@"EOEditingContext", @"relKey:%@", relKey); - EOFLOGObjectLevelArgs(@"EOEditingContext", - @"ownsDestinationObjects: %s", - (ownsDestinationObjects ? "YES" : "NO")); - - if (ownsDestinationObjects) + IMP oaiIMP=[toOneRelationshipKeys methodForSelector: GDL2_objectAtIndexSEL]; + + for (i = 0; i < count; i++) { - id existingObject = nil; - id value = nil; - - if (!objectSnapshot) - objectSnapshot = [self currentEventSnapshotForObject: object]; - - EOFLOGObjectLevelArgs(@"EOEditingContext", @"objectSnapshot:%@", - objectSnapshot); - - existingObject = [objectSnapshot objectForKey: relKey]; - EOFLOGObjectLevelArgs(@"EOEditingContext", @"existingObject:%@", - existingObject); - - value = [object storedValueForKey: relKey]; - EOFLOGObjectLevelArgs(@"EOEditingContext", @"value:%@", value); - - if (value != existingObject) + NSString *relKey = GDL2ObjectAtIndexWithImp(toOneRelationshipKeys, oaiIMP, i); + BOOL ownsDestinationObjects + = [object ownsDestinationObjectsForRelationshipKey:relKey]; + + EOFLOGObjectLevelArgs(@"EOEditingContext", @"relKey:%@", relKey); + EOFLOGObjectLevelArgs(@"EOEditingContext", + @"ownsDestinationObjects: %s", + (ownsDestinationObjects ? "YES" : "NO")); + + if (ownsDestinationObjects) { - if (isNilOrEONull(value)) + id existingObject = nil; + id value = nil; + + if (!objectSnapshot) + objectSnapshot = [self currentEventSnapshotForObject: object]; + + EOFLOGObjectLevelArgs(@"EOEditingContext", @"objectSnapshot:%@", + objectSnapshot); + + existingObject = [objectSnapshot objectForKey: relKey]; + EOFLOGObjectLevelArgs(@"EOEditingContext", @"existingObject:%@", + existingObject); + + value = [object storedValueForKey: relKey]; + EOFLOGObjectLevelArgs(@"EOEditingContext", @"value:%@", value); + + if (value != existingObject) { - if (!isNilOrEONull(existingObject))//value is new - { - //existing object is removed - //TODO ?? ad it in delete table ?? - NSEmitTODO(); - [self notImplemented:_cmd]; //TODO - } - } - else - { - if (!isNilOrEONull(existingObject))//value is new - { - //existing object is removed - //TODO ?? ad it in delete table ?? - NSEmitTODO(); - [self notImplemented:_cmd]; //TODO - } - if (!NSHashGet(changeTable,value))//id not already in change table + if (_isNilOrEONull(value)) { - //We will insert it - NSHashInsertIfAbsent(objectsToInsert,value); - EOFLOGObjectLevelArgs(@"EOEditingContext",@"Will insert %@",value); + if (!_isNilOrEONull(existingObject))//value is new + { + //existing object is removed + //TODO ?? ad it in delete table ?? + NSEmitTODO(); + NSLog(@"object=%@",object); + NSLog(@"objectSnapshot=%@",objectSnapshot); + NSLog(@"relKey=%@",relKey); + NSLog(@"value=%@",value); + NSLog(@"existingObject=%@",existingObject); + [self notImplemented:_cmd]; //TODO + } + } + else + { + if (!_isNilOrEONull(existingObject))//value is new + { + //existing object is removed + //TODO ?? ad it in delete table ?? + NSEmitTODO(); + NSLog(@"object=%@",object); + NSLog(@"objectSnapshot=%@",objectSnapshot); + NSLog(@"relKey=%@",relKey); + NSLog(@"value=%@",value); + NSLog(@"existingObject=%@",existingObject); + [self notImplemented:_cmd]; //TODO + } + if (!NSHashGet(changeTable,value))//id not already in change table + { + //We will insert it + NSHashInsertIfAbsent(objectsToInsert,value); + EOFLOGObjectLevelArgs(@"EOEditingContext",@"Will insert %@",value); + } } } } } - } + }; toManyRelationshipKeys = [object toManyRelationshipKeys]; @@ -2011,18 +2162,20 @@ _mergeValueForKey(id obj, id value, toManyRelationshipKeys); count = [toManyRelationshipKeys count]; - + + IMP oaiIMP=[toManyRelationshipKeys methodForSelector: GDL2_objectAtIndexSEL]; + for (i = 0; i < count; i++) { - NSString *relKey = [toManyRelationshipKeys objectAtIndex: i]; //1-1 payments + NSString *relKey = GDL2ObjectAtIndexWithImp(toManyRelationshipKeys, oaiIMP, i); BOOL ownsDestinationObjects - = [object ownsDestinationObjectsForRelationshipKey: relKey]; - + = [object ownsDestinationObjectsForRelationshipKey: relKey]; + EOFLOGObjectLevelArgs(@"EOEditingContext", @"relKey: %@", relKey); EOFLOGObjectLevelArgs(@"EOEditingContext", - @"ownsDestinationObjects: %s", - (ownsDestinationObjects ? "YES" : "NO")); - + @"ownsDestinationObjects: %s", + (ownsDestinationObjects ? "YES" : "NO")); + if (ownsDestinationObjects) //1-1 YES { NSArray *existingObjects = nil; @@ -2030,52 +2183,52 @@ _mergeValueForKey(id obj, id value, NSArray *newObjects = nil; int newObjectsCount = 0; int iNewObject = 0; - + if (!objectSnapshot) objectSnapshot = [self currentEventSnapshotForObject: object]; - + EOFLOGObjectLevelArgs(@"EOEditingContext", - @"objectSnapshot:%p: %@", - objectSnapshot, objectSnapshot); - + @"objectSnapshot:%p: %@", + objectSnapshot, objectSnapshot); + existingObjects = [objectSnapshot objectForKey: relKey]; EOFLOGObjectLevelArgs(@"EOEditingContext", - @"key %@ existingObjects: %@", - relKey, existingObjects); - + @"key %@ existingObjects: %@", + relKey, existingObjects); + currentObjects = [object storedValueForKey: relKey]; EOFLOGObjectLevelArgs(@"EOEditingContext", - @"key %@ currentObjects: %@", - relKey, currentObjects); -//TODO YY=[currentObjects shallowCopy]; - + @"key %@ currentObjects: %@", + relKey, currentObjects); + //TODO YY=[currentObjects shallowCopy]; + newObjects = [currentObjects arrayExcludingObjectsInArray: - existingObjects]; + existingObjects]; EOFLOGObjectLevelArgs(@"EOEditingContext", @"newObjects: %@", - newObjects); - + newObjects); + newObjectsCount = [newObjects count]; - + for (iNewObject = 0; iNewObject < newObjectsCount; iNewObject++) { id newObject = [newObjects objectAtIndex: iNewObject]; - + EOFLOGObjectLevelArgs(@"EOEditingContext", @"newObject: %@", - newObject); - + newObject); + if (!NSHashGet(changeTable, newObject)) //id not already in change table (or in insertTable ?) { //We will insert it NSHashInsertIfAbsent(objectsToInsert, newObject); EOFLOGObjectLevelArgs(@"EOEditingContext", - @"Will insert %@", newObject); + @"Will insert %@", newObject); } } - -//TODO XX=[existingObjects arrayExcludingObjectsInArray:(newObjects or currentObjects)];//nil -//=========> - NSEmitTODO(); -//TODO [self notImplemented:_cmd]; //TODO + + //TODO XX=[existingObjects arrayExcludingObjectsInArray:(newObjects or currentObjects)];//nil + //=========> + NSEmitTODO(); + //TODO [self notImplemented:_cmd]; //TODO } } } @@ -2106,7 +2259,7 @@ _mergeValueForKey(id obj, id value, EOFLOGObjectLevelArgs(@"EOEditingContext", @"object=%@", object); - gid = [self globalIDForObject: object]; + gid = EOEditingContext_globalIDForObjectWithImpPtr(self,NULL,object); EOFLOGObjectLevelArgs(@"EOEditingContext", @"gid=%@", gid); snapshot = [self currentEventSnapshotForObject: object]; @@ -2194,7 +2347,6 @@ _mergeValueForKey(id obj, id value, EOFLOGObjectFnStop(); } - - (void)deleteObject: (id)object { EOFLOGObjectFnStart(); @@ -2249,7 +2401,7 @@ _mergeValueForKey(id obj, id value, - (void)lockObject: (id)object { - EOGlobalID *gid = [self globalIDForObject: object]; + EOGlobalID *gid = EOEditingContext_globalIDForObjectWithImpPtr(self,NULL,object); if (gid == nil) [NSException raise: NSInvalidArgumentException @@ -2323,13 +2475,19 @@ _mergeValueForKey(id obj, id value, [self incrementUndoTransactionID]; //OK for update { - EOGlobalID *gid; + EOGlobalID *gid=nil; + IMP objectForGlobalIDIMP=NULL; enumerator = [[_snapshotsByGID allKeys] objectEnumerator]; while ((gid = [enumerator nextObject])) { - [_snapshotsByGID setObject: [[self objectForGlobalID:gid] snapshot] + id ofgid=EOEditingContext_objectForGlobalIDWithImpPtr(self,&objectForGlobalIDIMP,gid); + id snapshot=[ofgid snapshot]; + EOFLOGObjectLevelArgs(@"EOEditingContext", + @"gid=%@ snapshot=%@", + gid,snapshot); + [_snapshotsByGID setObject: snapshot forKey: gid]; } } @@ -2448,13 +2606,14 @@ _mergeValueForKey(id obj, id value, - (void)revert { NSEnumerator *enumerator; - EOGlobalID *gid; + EOGlobalID *gid=nil; + IMP objectForGlobalIDIMP=NULL; enumerator = [_eventSnapshotsByGID keyEnumerator]; while ((gid = [enumerator nextObject])) { - [[self objectForGlobalID: gid] - updateFromSnapshot: [_eventSnapshotsByGID objectForKey: gid]]; + id ofgid=EOEditingContext_objectForGlobalIDWithImpPtr(self,&objectForGlobalIDIMP,gid); + [ofgid updateFromSnapshot: [_eventSnapshotsByGID objectForKey: gid]]; } [_undoManager removeAllActions]; @@ -2476,7 +2635,7 @@ _mergeValueForKey(id obj, id value, EOFLOGObjectFnStart(); - gid = [self globalIDForObject: object]; + gid = EOEditingContext_globalIDForObjectWithImpPtr(self,NULL,object); if (gid) { @@ -2488,16 +2647,19 @@ _mergeValueForKey(id obj, id value, - (id)objectForGlobalID:(EOGlobalID *)globalID { - id object; + id object = nil; EOFLOGObjectFnStart(); - EOFLOGObjectLevelArgs(@"EOEditingContext", @"gid=%@", globalID); -// NSDebugMLLog(@"XXX",@"_objectsByGID=%@",NSAllMapTableKeys(_objectsByGID)); + EOFLOGObjectLevelArgs(@"EOEditingContext", + @"EditingContext: %p gid=%@", + self, globalID); object = NSMapGet(_objectsByGID, globalID); - EOFLOGObjectLevelArgs(@"EOEditingContext", @"object=%p", object); + EOFLOGObjectLevelArgs(@"EOEditingContext", + @"EditingContext: %p gid=%@ object=%p", + self, globalID, object); EOFLOGObjectFnStop(); @@ -2507,7 +2669,7 @@ _mergeValueForKey(id obj, id value, - (EOGlobalID *)globalIDForObject: (id)object { //Consider OK - EOGlobalID *gid; + EOGlobalID *gid = nil; /* [self recordForObject:object] @@ -2519,7 +2681,6 @@ _mergeValueForKey(id obj, id value, EOFLOGObjectLevelArgs(@"EOEditingContext", @"ed context=%p _globalIDsByObject=%p object=%p", self, _globalIDsByObject, object); -// EOFLOGObjectLevelArgs(@"EOEditingContext",@"_globalIDsByObject Values=%@",NSAllMapTableValues(_globalIDsByObject)); gid = NSMapGet(_globalIDsByObject, object); @@ -2621,8 +2782,8 @@ _mergeValueForKey(id obj, id value, { NSDictionary *snapshot; - EOFLOGObjectLevelArgs(@"EOEditingContext", @"*** object change %p %@", - object, [object class]); + EOFLOGObjectLevelArgs(@"EOEditingContext", @"*** editingContext=%p object change %p %@", + self,object, [object class]); //recordForObject: snapshot = [object snapshot]; // OK @@ -2638,9 +2799,13 @@ _mergeValueForKey(id obj, id value, if (NSHashInsertIfAbsent(_unprocessedChanges, object)) //The object is already here { + EOFLOGObjectLevelArgs(@"EOEditingContext", @"*** editingContext=%p object change %p %@. Snapshot Already Inserted: %p", + self,object, [object class], + [_snapshotsByGID objectForKey:EOEditingContext_globalIDForObjectWithImpPtr(self,NULL,object)]); EOFLOGObjectLevel(@"EOEditingContext", @"_enqueueEndOfEventNotification"); [self _enqueueEndOfEventNotification]; + if(_undoManager) [_undoManager registerUndoWithTarget: self selector:@selector(_revertChange:) @@ -2652,15 +2817,24 @@ _mergeValueForKey(id obj, id value, else { //??????????? - EOGlobalID *gid = [self globalIDForObject: object]; + NSDictionary *snapshot = nil; + EOGlobalID *gid = nil; - EOFLOGObjectLevel(@"EOEditingContext", - @"insert into xxsnapshotsByGID"); + EOFLOGObjectLevelArgs(@"EOEditingContext", @"*** editingContext=%p object change %p %@. Snapshot Not Already Inserted: %p", + self,object, [object class], + [_snapshotsByGID objectForKey:EOEditingContext_globalIDForObjectWithImpPtr(self,NULL,object)]); - [_eventSnapshotsByGID setObject: [object snapshot] + snapshot = [object snapshot]; // OK + gid = EOEditingContext_globalIDForObjectWithImpPtr(self,NULL,object); + + EOFLOGObjectLevelArgs(@"EOEditingContext", + @"insert into snapshotsByGID: gid=%@ snapshot %p=%@", + gid,snapshot,snapshot); + + [_eventSnapshotsByGID setObject: snapshot forKey: gid]; - [_snapshotsByGID setObject: [object snapshot] + [_snapshotsByGID setObject: snapshot forKey: gid]; if (_flags.autoLocking == YES) @@ -2697,20 +2871,22 @@ _mergeValueForKey(id obj, id value, EOFLOGObjectLevel(@"EOEditingContext", @"insertInto _globalIDsByObject"); NSMapInsert(_globalIDsByObject, object, globalID); - //TODO: delete + //TODO: Remove this test code { - id aGID2; + id aGID2 = nil; id aGID = NSMapGet(_globalIDsByObject, object); NSAssert1(aGID, @"Object %p recorded but can't retrieve it directly !", object); - aGID2 = [self globalIDForObject: object]; + aGID2 = EOEditingContext_globalIDForObjectWithImpPtr(self,NULL,object); NSAssert1(aGID2, @"Object %p recorded but can't retrieve it with globalIDForObject: !", object); } - EOFLOGObjectLevel(@"EOEditingContext", @"insertInto _objectsByGID"); + EOFLOGObjectLevelArgs(@"EOEditingContext", + @"EditingContext: %p objectsByGID: Insert Object gid=%@", + self, globalID); NSMapInsert(_objectsByGID, globalID, object); @@ -2726,15 +2902,24 @@ _mergeValueForKey(id obj, id value, { EOGlobalID *gid; + EOFLOGObjectFnStart(); + /* Global hash table for faster dealloc. */ NSHashRemove(ecDeallocHT, object); - gid = [self globalIDForObject: object]; + gid = EOEditingContext_globalIDForObjectWithImpPtr(self,NULL,object); + + EOFLOGObjectLevelArgs(@"EOEditingContext", + @"forgetObject gid: %@", + gid); + NSMapRemove(_globalIDsByObject, object); NSMapRemove(_objectsByGID, gid); [EOObserverCenter removeObserver: self forObject: object]; + + EOFLOGObjectFnStop(); } - (NSArray *)registeredObjects @@ -2849,8 +3034,21 @@ It is updated after commiting new values. - (NSDictionary *)committedSnapshotForObject: (id)object { - //OK - return [_snapshotsByGID objectForKey: [self globalIDForObject: object]]; + EOGlobalID* gid=nil; + NSDictionary* snapshot=nil; + + EOFLOGObjectFnStart(); + + gid=EOEditingContext_globalIDForObjectWithImpPtr(self,NULL,object); + snapshot=[_snapshotsByGID objectForKey: gid]; + + EOFLOGObjectLevelArgs(@"EOEditingContext", + @"object=%p snapshot %p=%@", + object,snapshot,snapshot); + + EOFLOGObjectFnStop(); + + return snapshot; } /** Returns a dictionary containing a snapshot of object with @@ -2861,7 +3059,8 @@ modified state of the object.**/ - (NSDictionary *)currentEventSnapshotForObject: (id)object { //OK - return [_eventSnapshotsByGID objectForKey: [self globalIDForObject: object]]; + EOGlobalID* gid=EOEditingContext_globalIDForObjectWithImpPtr(self,NULL,object); + return [_eventSnapshotsByGID objectForKey: gid]; } - (NSDictionary *)uncommittedChangesForObject: (id)object @@ -2874,7 +3073,8 @@ modified state of the object.**/ { NSMutableArray *objs = [[NSMutableArray new] autorelease]; NSEnumerator *objsEnum; - id obj; + id obj = nil; + IMP globalIDForObjectIMP=NULL; [self processRecentChanges]; @@ -2887,9 +3087,12 @@ modified state of the object.**/ objsEnum = [objs objectEnumerator]; while ((obj = [objsEnum nextObject])) - [self refaultObject: obj - withGlobalID: [self globalIDForObject: obj] - editingContext: self]; + { + EOGlobalID* gid=EOEditingContext_globalIDForObjectWithImpPtr(self,&globalIDForObjectIMP,obj); + [self refaultObject: obj + withGlobalID: gid + editingContext: self]; + }; } // Refaults all objects that haven't been modified, inserted or deleted. @@ -2933,7 +3136,7 @@ modified state of the object.**/ editingContext: (EOEditingContext *)context { //OK - id object = [self objectForGlobalID: globalID]; + id object = EOEditingContext_objectForGlobalIDWithImpPtr(self,NULL,globalID); if (!object) { @@ -2967,7 +3170,7 @@ modified state of the object.**/ entityName]; #warning (stephane@sente.ch) ERROR: trying to use EOEntity/EOEntityDescription which are defined in EOAccess globalID = [[classDesc entity] globalIDForRow: row]; - object = [self objectForGlobalID: globalID]; + object = EOEditingContext_objectForGlobalIDWithImpPtr(self,NULL,globalID); if (object) { @@ -2981,8 +3184,7 @@ modified state of the object.**/ NSAssert1(objectCopy, @"No Object. classDesc=%@", classDesc); [objectCopy updateFromSnapshot: [object snapshot]]; - [context recordObject: objectCopy - globalID: globalID]; + EOEditingContext_recordObjectGlobalIDWithImpPtr(context,NULL,objectCopy,globalID); return objectCopy; } @@ -3013,9 +3215,9 @@ modified state of the object.**/ relationshipName: (NSString *)name editingContext: (EOEditingContext *)context { - NSArray *fault; - id object = [self objectForGlobalID: globalID]; - id objectCopy; + NSArray *fault = nil; + id object = EOEditingContext_objectForGlobalIDWithImpPtr(self,NULL,globalID); + id objectCopy = nil; if (object) { @@ -3036,8 +3238,7 @@ modified state of the object.**/ NSAssert1(objectCopy, @"No Object. globalID=%@", globalID); [objectCopy updateFromSnapshot: [object snapshot]]; - [context recordObject: objectCopy - globalID: globalID]; + EOEditingContext_recordObjectGlobalIDWithImpPtr(context,NULL,objectCopy,globalID); return [objectCopy valueForKey: name]; } @@ -3091,8 +3292,12 @@ modified state of the object.**/ } NS_HANDLER { - NSLog(@"%@ (%@)", localException, [localException reason]); - NSDebugMLog(@"%@ (%@)", localException, [localException reason]); + NSLog(@"%@ (%@). globalID=%@ relationshipName=%@", + localException, [localException reason], + globalID, name); + NSDebugMLog(@"%@ (%@). globalID=%@ relationshipName=%@", + localException, [localException reason], + globalID, name); [self unlock]; [localException raise]; } @@ -3139,53 +3344,69 @@ modified state of the object.**/ { if (context != self) { - NSArray *objects; - NSEnumerator *objsEnum; - EOGlobalID *gid; - id object, localObject; + NS_DURING // Debugging Purpose + { + NSArray *objects; + NSEnumerator *objsEnum; + EOGlobalID *gid; + id object, localObject; + IMP objectForGlobalIDIMP=NULL; + IMP globalIDForObjectIMP=NULL; - objects = [context insertedObjects]; - - objsEnum = [objects objectEnumerator]; - while ((object = [objsEnum nextObject])) - { - gid = [context globalIDForObject: object]; - - localObject = [[EOClassDescription classDescriptionForEntityName: - [gid entityName]] - createInstanceWithEditingContext: context - globalID: gid - zone: NULL]; - - NSAssert1(localObject, @"No Object. gid=%@", gid); - - [localObject updateFromSnapshot: [object snapshot]]; - - [self recordObject: localObject - globalID: gid]; + objects = [context insertedObjects]; + + objsEnum = [objects objectEnumerator]; + while ((object = [objsEnum nextObject])) + { + gid=EOEditingContext_globalIDForObjectWithImpPtr(context,&globalIDForObjectIMP,object); + + localObject = [[EOClassDescription classDescriptionForEntityName: + [gid entityName]] + createInstanceWithEditingContext: context + globalID: gid + zone: NULL]; + + NSAssert1(localObject, @"No Object. gid=%@", gid); + + [localObject updateFromSnapshot: [object snapshot]]; + + EOEditingContext_recordObjectGlobalIDWithImpPtr(self,NULL,localObject,gid); + } + + objects = [context updatedObjects]; + + objsEnum = [objects objectEnumerator]; + while ((object = [objsEnum nextObject])) + { + gid=EOEditingContext_globalIDForObjectWithImpPtr(context,&globalIDForObjectIMP,object); + localObject = EOEditingContext_objectForGlobalIDWithImpPtr(self,&objectForGlobalIDIMP,gid); + + [localObject updateFromSnapshot:[object snapshot]]; + } + + objects = [context deletedObjects]; + + objsEnum = [objects objectEnumerator]; + while ((object = [objsEnum nextObject])) + { + gid=EOEditingContext_globalIDForObjectWithImpPtr(context,&globalIDForObjectIMP,object); + localObject = EOEditingContext_objectForGlobalIDWithImpPtr(self,&objectForGlobalIDIMP,gid); + + [self deleteObject: localObject]; + } } - - objects = [context updatedObjects]; - - objsEnum = [objects objectEnumerator]; - while ((object = [objsEnum nextObject])) + NS_HANDLER { - gid = [context globalIDForObject: object]; - localObject = [self objectForGlobalID: gid]; - - [localObject updateFromSnapshot:[object snapshot]]; - } - - objects = [context deletedObjects]; - - objsEnum = [objects objectEnumerator]; - while ((object = [objsEnum nextObject])) - { - gid = [context globalIDForObject: object]; - localObject = [self objectForGlobalID: gid]; - - [self deleteObject: localObject]; + NSLog(@"Exception in %@ -%@ %@ (%@)", + NSStringFromClass([self class]), NSStringFromSelector(_cmd), + localException, [localException reason]); + NSDebugMLog(@"Exception in %@ -%@ %@ (%@)", + NSStringFromClass([self class]),NSStringFromSelector(_cmd), + localException, [localException reason]); + + [localException raise]; } + NS_ENDHANDLER; } } @@ -3501,6 +3722,23 @@ static BOOL usesContextRelativeEncoding = NO; // Informations @implementation EOEditingContext(EOEditingContextInfo) +- (NSDictionary*)unprocessedObjects +{ + NSDictionary *infoDict = nil; + + EOFLOGObjectFnStart(); + + infoDict = [NSDictionary dictionaryWithObjectsAndKeys: + NSAllHashTableObjects(_unprocessedChanges), @"update", + NSAllHashTableObjects(_unprocessedDeletes), @"delete", + NSAllHashTableObjects(_unprocessedInserts), @"insert", + nil, nil]; + + EOFLOGObjectFnStop(); + + return infoDict; +} + - (NSDictionary*)unprocessedInfo { NSDictionary *infoDict = nil; @@ -3581,6 +3819,17 @@ static BOOL usesContextRelativeEncoding = NO; return infoDict; } +/** Returns YES if there unprocessed changes or deletes or inserts **/ +- (BOOL)hasUnprocessedChanges +{ + if(NSCountHashTable(_unprocessedChanges) + || NSCountHashTable(_unprocessedDeletes) + || NSCountHashTable(_unprocessedInserts)) + return YES; + + return NO; +} + @end @implementation NSObject (DeallocHack) @@ -3597,7 +3846,7 @@ static BOOL usesContextRelativeEncoding = NO; { if (ecDeallocHT && NSHashGet(ecDeallocHT, self)) { - [EOEditingContextClass objectDeallocated: self]; + [GDL2EOEditingContextClass objectDeallocated: self]; } if (assocDeallocHT && NSHashGet(assocDeallocHT, self)) { @@ -3607,3 +3856,72 @@ static BOOL usesContextRelativeEncoding = NO; NSDeallocateObject (self); } @end + +id EOEditingContext_objectForGlobalIDWithImpPtr(EOEditingContext* edContext,IMP* impPtr,EOGlobalID* gid) +{ + if (edContext) + { + IMP imp=NULL; + if (impPtr) + imp=*impPtr; + if (!imp) + { + if (GSObjCClass(edContext)==GDL2EOEditingContextClass + && GDL2EOEditingContext_objectForGlobalIDIMP) + imp=GDL2EOEditingContext_objectForGlobalIDIMP; + else + imp=[edContext methodForSelector:GDL2_objectForGlobalIDSEL]; + if (impPtr) + *impPtr=imp; + } + return (*imp)(edContext,GDL2_objectForGlobalIDSEL,gid); + } + else + return nil; +}; + +EOGlobalID* EOEditingContext_globalIDForObjectWithImpPtr(EOEditingContext* edContext,IMP* impPtr,id object) +{ + if (edContext) + { + IMP imp=NULL; + if (impPtr) + imp=*impPtr; + if (!imp) + { + if (GSObjCClass(edContext)==GDL2EOEditingContextClass + && GDL2EOEditingContext_globalIDForObjectIMP) + imp=GDL2EOEditingContext_globalIDForObjectIMP; + else + imp=[edContext methodForSelector:GDL2_globalIDForObjectSEL]; + if (impPtr) + *impPtr=imp; + } + return (*imp)(edContext,GDL2_globalIDForObjectSEL,object); + } + else + return nil; +}; + +id EOEditingContext_recordObjectGlobalIDWithImpPtr(EOEditingContext* edContext,IMP* impPtr,id object,EOGlobalID* gid) +{ + if (edContext) + { + IMP imp=NULL; + if (impPtr) + imp=*impPtr; + if (!imp) + { + if (GSObjCClass(edContext)==GDL2EOEditingContextClass + && GDL2EOEditingContext_recordObjectGlobalIDIMP) + imp=GDL2EOEditingContext_recordObjectGlobalIDIMP; + else + imp=[edContext methodForSelector:GDL2_recordObjectGlobalIDSEL]; + if (impPtr) + *impPtr=imp; + } + return (*imp)(edContext,GDL2_recordObjectGlobalIDSEL,object,gid); + } + else + return nil; +}; diff --git a/EOControl/EOFault.h b/EOControl/EOFault.h index 925d28a..5620137 100644 --- a/EOControl/EOFault.h +++ b/EOControl/EOFault.h @@ -54,6 +54,7 @@ @interface EOFault { +@public Class isa; EOFaultHandler *_handler; } diff --git a/EOControl/EOFault.m b/EOControl/EOFault.m index 10f83f1..12e44de 100644 --- a/EOControl/EOFault.m +++ b/EOControl/EOFault.m @@ -172,6 +172,7 @@ static Class EOFaultClass = NULL; + (BOOL)isFault: (id)object { + //See also EOControl/EOPriv.h // NSDebugFLLog(@"gsdb",@"object=%p",object); if (object == nil) @@ -491,6 +492,10 @@ static Class EOFaultClass = NULL; - (void)forwardInvocation: (NSInvocation *)invocation { + NSDebugFLLog(@"gsdb",@"invocation selector=%@ target: %p", + NSStringFromSelector([invocation selector]), + [invocation target]); + if ([_handler shouldPerformInvocation: invocation]) [_handler completeInitializationOfObject: self]; diff --git a/EOControl/EOFaultHandler.m b/EOControl/EOFaultHandler.m index bd8113b..800b7a7 100644 --- a/EOControl/EOFaultHandler.m +++ b/EOControl/EOFaultHandler.m @@ -44,6 +44,7 @@ RCS_ID("$Id$") #include #include #include +#include #else #include #endif @@ -234,6 +235,9 @@ BOOL __isGCEnabled(Class class_) - (BOOL)shouldPerformInvocation: (NSInvocation *)invocation { + NSDebugFLLog(@"gsdb",@"invocation selector=%@ target: %p", + NSStringFromSelector([invocation selector]), + [invocation target]); return YES; } diff --git a/EOControl/EOGenericRecord.m b/EOControl/EOGenericRecord.m index ef7af42..6c5fbeb 100644 --- a/EOControl/EOGenericRecord.m +++ b/EOControl/EOGenericRecord.m @@ -63,6 +63,7 @@ RCS_ID("$Id$") #include #include #include +#include #include #include #include @@ -109,8 +110,13 @@ static NSRecursiveLock *allGenericRecordsLock = nil; + (void) initialize { - if (self == [EOGenericRecord class] && !allGenericRecords) + static BOOL initialized=NO; + if (!initialized) { + initialized=YES; + + GDL2PrivInit(); + allGenericRecords = NSCreateHashTable(NSNonOwnedPointerHashCallBacks, 1000); allGenericRecordsLock = [GSLazyRecursiveLock new]; @@ -201,7 +207,8 @@ static NSRecursiveLock *allGenericRecordsLock = nil; static const char _c_id[2] = { _C_ID, 0 }; //used to allow derived object implementation -- (BOOL)_infoForInstanceVariableNamed: (NSString*)name +- (BOOL)_infoForInstanceVariableNamed: (const char*)cStringName + stringName: (NSString*)stringName retType: (const char**)type retSize: (unsigned int*)size retOffset: (int*)offset @@ -214,22 +221,24 @@ static const char _c_id[2] = { _C_ID, 0 }; retSize:size retOffset:offset]; */ - ok = GSObjCFindVariable(self, [name cString], type, size, offset); + ok = GSObjCFindVariable(self, cStringName, type, size, offset); EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", - @"Super InstanceVar named %@:%s", - name, (ok ? "YES" : "NO")); + @"Super InstanceVar named %s:%s", + cStringName, (ok ? "YES" : "NO")); if (!ok) { + NSString* name=(stringName ? stringName : GDL2StringWithCString(cStringName)); + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"dictionary: %p eoMKKDInitializer: %p", dictionary, [dictionary eoMKKDInitializer]); EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"dictionary allkeys= %@", [dictionary allKeys]); - - if ([dictionary hasKey: name]) + + if (EOMKKD_hasKeyWithImpPtr(dictionary,NULL,name)) { if (type) *type = _c_id; @@ -262,24 +271,18 @@ static const char _c_id[2] = { _C_ID, 0 }; EOFLOGObjectFnStartCond(@"EOGenericRecordKVC"); EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", - @"Super InstanceVar named %@: offset=%u", - aKey, offset); + @"Super InstanceVar named %@: sel=%@ type=%s size=%u offset=%u", + aKey,NSStringFromSelector(sel),type,size,offset); if (offset == UINT_MAX) { - value = [dictionary objectForKey: aKey]; + value = EOMKKD_objectForKeyWithImpPtr(dictionary,NULL,aKey); EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"value %p (class=%@)", value, [value class]); } else { - /* value=[super _getValueForKey:aKey - selector:sel - type:type - size:size - offset:offset];*/ - value = GSObjCGetValue(self, aKey, sel, type, size, offset); EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"value %p (class=%@)", value, [value class]); @@ -308,19 +311,11 @@ static const char _c_id[2] = { _C_ID, 0 }; if (offset == UINT_MAX) { if (anObject) - [dictionary setObject: anObject - forKey: aKey]; + EOMKKD_setObjectForKeyWithImpPtr(dictionary,NULL,anObject,aKey); else - [dictionary removeObjectForKey: aKey]; + EOMKKD_removeObjectForKeyWithImpPtr(dictionary,NULL,aKey); } else -/* [super _setValueForKey:aKey - object:anObject - selector:sel - type:type - size:size - offset:offset]; -*/ GSObjCSetValue(self, aKey, anObject, sel, type, size, offset); EOFLOGObjectFnStopCond(@"EOGenericRecordKVC"); @@ -360,7 +355,7 @@ static const char _c_id[2] = { _C_ID, 0 }; forKey: key]; EOFLOGObjectFnStopOrCond(@"EOGenericRecord"); // -// if(value == nil || value == [EONull null]) +// if(value == nil || value == GDL2EONull) // [dictionary removeObjectForKey:key]; // else // { @@ -419,20 +414,30 @@ static const char _c_id[2] = { _C_ID, 0 }; } */ +inline BOOL infoForInstanceVariableWithImpPtr(id object,GDL2IMP_BOOL* impPtr, + const char* cStringName,NSString* stringName, + const char** type,unsigned int* size, + int* offset) +{ + SEL sel=@selector(_infoForInstanceVariableNamed:stringName:retType:retSize:retOffset:); + if (!*impPtr) + *impPtr=(GDL2IMP_BOOL)[object methodForSelector:sel]; + return (**impPtr)(object,sel,cStringName,stringName,type,size,offset); +}; + - (id) storedValueForKey: (NSString*)aKey { SEL sel = 0; const char *type = NULL; unsigned size = 0; unsigned off = 0; - NSString *name = nil; - NSString *cap = nil; id value = nil; + Class selfClass=[self class]; EOFLOGObjectFnStartCond(@"EOGenericRecordKVC"); EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"aKey=%@", aKey); - if ([[self class] useStoredAccessor] == NO) + if ([selfClass useStoredAccessor] == NO) { value = [self valueForKey: aKey]; } @@ -445,70 +450,116 @@ static const char _c_id[2] = { _C_ID, 0 }; [NSException raise: NSInvalidArgumentException format: @"storedValueForKey: ... empty key"]; } - - cap = [[aKey substringToIndex: 1] uppercaseString]; - if (size > 1) + else { - cap = [cap stringByAppendingString: [aKey substringFromIndex: 1]]; - } + char buf[size+5]; + char lo; + char hi; + GDL2IMP_BOOL rtsIMP=NULL; + GDL2IMP_BOOL infoVarIMP=NULL; + + strcpy(buf, "_get"); + [aKey getCString: &buf[4]]; + lo = buf[4]; + hi = islower(lo) ? toupper(lo) : lo; + buf[4] = hi; - name = [NSString stringWithFormat: @"_get%@", cap]; - sel = NSSelectorFromString(name); + // test _getKey + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"A aKey=%@ Method [_getKey] name=%s", + aKey, buf); + sel = sel_get_any_uid(buf); - if (sel == 0 || [self respondsToSelector: sel] == NO) - { - name = [NSString stringWithFormat: @"_%@", aKey]; - sel = NSSelectorFromString(name); - - if (sel == 0 || [self respondsToSelector: sel] == NO) + if (sel == 0 || GDL2RespondsToSelectorWithImpPtr(self,&rtsIMP,sel) == NO) { - sel = 0; - } - } + // test _key + buf[3]='_'; + buf[4]=lo; - if (sel == 0) - { - if ([[self class] accessInstanceVariablesDirectly] == YES) - { - name = [NSString stringWithFormat: @"_%@", aKey]; - - if ([self _infoForInstanceVariableNamed:name - retType: &type - retSize: &size - retOffset: &off]==NO) + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"B aKey=%@ Method [_key] name=%s", + aKey, &buf[3]); + sel = sel_get_any_uid(&buf[3]); + + if (sel == 0 || GDL2RespondsToSelectorWithImpPtr(self,&rtsIMP,sel) == NO) { - name = aKey; - [self _infoForInstanceVariableNamed:name - retType: &type - retSize: &size - retOffset: &off]; + sel = 0; } } - - if (type == NULL) + + if (sel == 0) { - name = [NSString stringWithFormat: @"get%@", cap]; - sel = NSSelectorFromString(name); - - if (sel == 0 || [self respondsToSelector: sel] == NO) + if ([selfClass accessInstanceVariablesDirectly] == YES) { - name = aKey; - sel = NSSelectorFromString(name); + // test _key + buf[3]='_'; + buf[4]=lo; - if (sel == 0 || [self respondsToSelector: sel] == NO) + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"C aKey=%@ Instance [_key] name=%s", + aKey, &buf[3]); + /*if ([self _infoForInstanceVariableNamed:&buf[3] + stringName: nil + retType: &type + retSize: &size + retOffset: &off]==NO)*/ + if (infoForInstanceVariableWithImpPtr(self,&infoVarIMP, + &buf[3], // name + nil, // stringName + &type, // retType + &size, // retSize + &off)==NO) // retOffset { - sel = 0; + // key + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"C aKey=%@ Instance [key] name=%s", + aKey, &buf[4]); + /*[self _infoForInstanceVariableNamed:&buf[4] + stringName: aKey + retType: &type + retSize: &size + retOffset: &off];*/ + infoForInstanceVariableWithImpPtr(self,&infoVarIMP, + &buf[4], // name + aKey, // stringName + &type, // retType + &size, // retSize + &off); // retOffset + } + } + + if (type == NULL) + { + //test getKey + buf[3]='t'; + buf[4]=hi; + + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"E aKey=%@ Method [getKey] name=%s", + aKey, &buf[1]); + sel = sel_get_any_uid(&buf[1]); + if (sel == 0 || GDL2RespondsToSelectorWithImpPtr(self,&rtsIMP,sel) == NO) + { + // test key + buf[4]=lo; + + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"F aKey=%@ Method [key] name=%s", + aKey, &buf[4]); + sel = sel_get_any_uid(&buf[4]); + + if (sel == 0 || GDL2RespondsToSelectorWithImpPtr(self,&rtsIMP,sel) == NO) + { + sel = 0; + } } } } - } - value = [self _getValueForKey: aKey - selector: sel - type: type - size: size - offset: off]; + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", + @"class=%@ aKey=%@ sel=%@ offset=%u", + selfClass, aKey, NSStringFromSelector(sel), off); + value = [self _getValueForKey: aKey + selector: sel + type: type + size: size + offset: off]; + }; } EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"value=%@", value); @@ -524,14 +575,13 @@ static const char _c_id[2] = { _C_ID, 0 }; const char *type = NULL; unsigned size = 0; unsigned off = 0; - NSString *cap = nil; - NSString *name = nil; + Class selfClass=[self class]; EOFLOGObjectFnStartCond(@"EOGenericRecordKVC"); EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"anObject=%@", anObject); EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"aKey=%@", aKey); - if ([[self class] useStoredAccessor] == NO) + if ([selfClass useStoredAccessor] == NO) { EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"aKey=%@", aKey); @@ -547,72 +597,106 @@ static const char _c_id[2] = { _C_ID, 0 }; [NSException raise: NSInvalidArgumentException format: @"takeStoredValue:forKey: ... empty key"]; } - - cap = [[aKey substringToIndex: 1] uppercaseString]; - if (size > 1) + else { - cap = [cap stringByAppendingString: [aKey substringFromIndex: 1]]; - } - - name = [NSString stringWithFormat: @"_set%@:", cap]; - type = NULL; - sel = NSSelectorFromString(name); + char buf[size+6]; + char lo; + char hi; + GDL2IMP_BOOL rtsIMP=NULL; + GDL2IMP_BOOL infoVarIMP=NULL; - if (sel == 0 || [self respondsToSelector: sel] == NO) - { - sel = 0; + strcpy(buf, "_set"); + [aKey getCString: &buf[4]]; + lo = buf[4]; + hi = islower(lo) ? toupper(lo) : lo; + buf[4] = hi; + buf[size+4] = ':'; + buf[size+5] = '\0'; - if ([[self class] accessInstanceVariablesDirectly] == YES) + // test _setKey: + type = NULL; + + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"A aKey=%@ Method [_setKey] name=%s", + aKey, buf); + + sel = sel_get_any_uid(buf); + + if (sel == 0 || GDL2RespondsToSelectorWithImpPtr(self,&rtsIMP,sel) == NO) { - name = [NSString stringWithFormat: @"_%@", aKey]; - - EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"aKey=%@ name=%@", - aKey, name); - - if ([self _infoForInstanceVariableNamed: name - retType: &type - retSize: &size - retOffset: &off]==NO) + sel = 0; + + if ([selfClass accessInstanceVariablesDirectly] == YES) { - name = aKey; + // test _key + buf[3] = '_'; + buf[4] = lo; + buf[size+4] = '\0'; - EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", - @"aKey=%@ name=%@", aKey, name); + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"B aKey=%@ Instance [_key] name=%s", + aKey, &buf[3]); + + /*if ([self _infoForInstanceVariableNamed:&buf[3] + stringName: nil + retType: &type + retSize: &size + retOffset: &off]==NO) + */ + if (infoForInstanceVariableWithImpPtr(self,&infoVarIMP, + &buf[3], // name + nil, // stringName + &type, // retType + &size, // retSize + &off)==NO) // retOffset + { + // Test key + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", + @"C aKey=%@ Instance [_key] name=%s", aKey, &buf[4]); + + /*[self _infoForInstanceVariableNamed: &buf[4] + stringName: aKey + retType: &type + retSize: &size + retOffset: &off];*/ + infoForInstanceVariableWithImpPtr(self,&infoVarIMP, + &buf[4], // name + aKey, // stringName + &type, // retType + &size, // retSize + &off); // retOffset + } + } + + if (type == NULL) + { + // Test setKey: + buf[3] = 't'; + buf[4] = hi; + buf[size+4] = ':'; - [self _infoForInstanceVariableNamed: name - retType: &type - retSize: &size - retOffset: &off]; - } - } - - if (type == NULL) - { - name = [NSString stringWithFormat: @"set%@:", cap]; - - EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"aKey=%@ name=%@", - aKey, name); - - sel = NSSelectorFromString(name); - - if (sel == 0 || [self respondsToSelector: sel] == NO) - { - sel = 0; + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"D aKey=%@ Method [setKey:] name=%s", + aKey, &buf[1]); + + sel = sel_get_any_uid(&buf[1]); + + if (sel == 0 || GDL2RespondsToSelectorWithImpPtr(self,&rtsIMP,sel) == NO) + { + sel = 0; + } } } + + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", + @"class=%@ aKey=%@ sel=%@ offset=%u", + selfClass, aKey, NSStringFromSelector(sel), off); + + [self _setValueForKey: aKey + object: anObject + selector: sel + type: type + size: size + offset: off]; } - - EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", - @"class=%@ aKey=%@ sel=%p offset=%u", - [self class], aKey, sel, off); - - [self _setValueForKey: aKey - object: anObject - selector: sel - type: type - size: size - offset: off]; - } + }; EOFLOGObjectFnStopCond(@"EOGenericRecordKVC"); } @@ -632,11 +716,11 @@ static const char _c_id[2] = { _C_ID, 0 }; || [[classDescription toOneRelationshipKeys] containsObject: aKey]) && [classDescription inverseForRelationshipKey: aKey] != nil) { - if (isNilOrEONull(anObject)) + if (_isNilOrEONull(anObject)) { id oldObj = [self valueForKey: aKey]; - if (isNilOrEONull(oldObj)) + if (_isNilOrEONull(oldObj)) { if (!isToMany) [self takeValue: anObject @@ -662,8 +746,6 @@ static const char _c_id[2] = { _C_ID, 0 }; const char *type; unsigned size; unsigned off=0; - NSString *cap; - NSString *name; EOFLOGObjectFnStartCond(@"EOGenericRecordKVC"); EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"anObject=%@", anObject); @@ -675,52 +757,91 @@ static const char _c_id[2] = { _C_ID, 0 }; [NSException raise: NSInvalidArgumentException format: @"takeValue:forKey: ... empty key"]; } - - cap = [[aKey substringToIndex: 1] uppercaseString]; - if (size > 1) + else { - cap = [cap stringByAppendingString: [aKey substringFromIndex: 1]]; - } + char buf[size+6]; + char lo; + char hi; + GDL2IMP_BOOL rtsIMP=NULL; + GDL2IMP_BOOL infoVarIMP=NULL; - name = [NSString stringWithFormat: @"set%@:", cap]; - type = NULL; - sel = NSSelectorFromString(name); + strcpy(buf, "_set"); + [aKey getCString: &buf[4]]; + lo = buf[4]; + hi = islower(lo) ? toupper(lo) : lo; + buf[4] = hi; + buf[size+4] = ':'; + buf[size+5] = '\0'; - if (sel == 0 || [self respondsToSelector: sel] == NO) - { - name = [NSString stringWithFormat: @"_set%@:", cap]; - sel = NSSelectorFromString(name); + type = NULL; - if (sel == 0 || [self respondsToSelector: sel] == NO) - { - sel = 0; + //Try setKey: + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"A aKey=%@ Method [setKey:] name=%s", + aKey, &buf[1]); + sel = sel_get_any_uid(&buf[1]); - if ([[self class] accessInstanceVariablesDirectly] == YES) - { - name = [NSString stringWithFormat: @"_%@", aKey]; + if (sel == 0 || GDL2RespondsToSelectorWithImpPtr(self,&rtsIMP,sel) == NO) + { + // Try _setKey: + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"B aKey=%@ Method [_setKey:] name=%s", + aKey, buf); + sel = sel_get_any_uid(buf); - if ([self _infoForInstanceVariableNamed: name - retType: &type - retSize: &size - retOffset: &off]==NO) - { - name = aKey; + if (sel == 0 || GDL2RespondsToSelectorWithImpPtr(self,&rtsIMP,sel) == NO) + { + sel = 0; - [self _infoForInstanceVariableNamed: name - retType: &type - retSize: &size - retOffset: &off]; - } - } - } - } + if ([[self class] accessInstanceVariablesDirectly] == YES) + { + // test _key + buf[size+4] = '\0'; + buf[3] = '_'; + buf[4] = lo; + + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"C aKey=%@ Instance [_key] name=%s", + aKey, &buf[3]); + /*if ([self _infoForInstanceVariableNamed: &buf[3] + stringName: nil + retType: &type + retSize: &size + retOffset: &off]==NO)*/ + if (infoForInstanceVariableWithImpPtr(self,&infoVarIMP, + &buf[3], // name + nil, // stringName + &type, // retType + &size, // retSize + &off)==NO) // retOffset + { + // Test key + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"D aKey=%@ Instance [key] name=%s", + aKey, &buf[4]); + /*[self _infoForInstanceVariableNamed: &buf[4] + stringName: aKey + retType: &type + retSize: &size + retOffset: &off];*/ + infoForInstanceVariableWithImpPtr(self,&infoVarIMP, + &buf[4], // name + aKey, // stringName + &type, // retType + &size, // retSize + &off); // retOffset + } + } + } + } + + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", + @"aKey=%@ sel=%@ offset=%u", + aKey, NSStringFromSelector(sel), off); - [self _setValueForKey: aKey - object: anObject - selector: sel - type: type - size: size - offset: off]; + [self _setValueForKey: aKey + object: anObject + selector: sel + type: type + size: size + offset: off]; + }; EOFLOGObjectFnStopCond(@"EOGenericRecordKVC"); } @@ -728,8 +849,6 @@ static const char _c_id[2] = { _C_ID, 0 }; - (id) valueForKey: (NSString*)aKey { SEL sel = 0; - NSString *cap; - NSString *name = nil; const char *type = NULL; unsigned size; unsigned off = 0; @@ -744,63 +863,109 @@ static const char _c_id[2] = { _C_ID, 0 }; [NSException raise: NSInvalidArgumentException format: @"valueForKey: ... empty key"]; } - - cap = [[aKey substringToIndex: 1] uppercaseString]; - if (size > 1) + else { - cap = [cap stringByAppendingString: [aKey substringFromIndex: 1]]; - } + char buf[size+5]; + char lo; + char hi; + GDL2IMP_BOOL rtsIMP=NULL; + GDL2IMP_BOOL infoVarIMP=NULL; - name = [@"get" stringByAppendingString: cap]; - sel = NSSelectorFromString(name); + strcpy(buf, "_get"); + [aKey getCString: &buf[4]]; + lo = buf[4]; + hi = islower(lo) ? toupper(lo) : lo; + buf[4] = hi; - if (sel == 0 || [self respondsToSelector: sel] == NO) - { - name = aKey; - sel = NSSelectorFromString(name); + // Test getKey + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"A aKey=%@ Method [getKey] name=%s", + aKey, &buf[1]); + sel = sel_get_any_uid(&buf[1]); - if (sel == 0 || [self respondsToSelector: sel] == NO) - { - name = [@"_get" stringByAppendingString: cap]; - sel = NSSelectorFromString(name); - - if (sel == 0 || [self respondsToSelector: sel] == NO) - { - name = [NSString stringWithFormat: @"_%@", aKey]; - sel = NSSelectorFromString(name); - - if (sel == 0 || [self respondsToSelector: sel] == NO) - { - sel = 0; - } - } - } - } - - if (sel == 0 && [[self class] accessInstanceVariablesDirectly] == YES) - { - name = [NSString stringWithFormat: @"_%@", aKey]; - - if ([self _infoForInstanceVariableNamed: name - retType: &type - retSize: &size - retOffset: &off]==NO) + if (sel == 0 || GDL2RespondsToSelectorWithImpPtr(self,&rtsIMP,sel) == NO) { - name = aKey; + //Test key + buf[4] = lo; - [self _infoForInstanceVariableNamed: name - retType: &type - retSize: &size - retOffset: &off]; + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"B aKey=%@ Method [key] name=%s", + aKey, &buf[4]); + sel = sel_get_any_uid(&buf[4]); + + if (sel == 0 || GDL2RespondsToSelectorWithImpPtr(self,&rtsIMP,sel) == NO) + { + //Test _getKey + buf[4] = hi; + + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"C aKey=%@ Method [_getKey] name=%s", + aKey, buf); + sel = sel_get_any_uid(buf); + + if (sel == 0 || GDL2RespondsToSelectorWithImpPtr(self,&rtsIMP,sel) == NO) + { + // Test _key + buf[3] = '_'; + buf[4] = lo; + + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"C aKey=%@ Method [_key] name=%s", + aKey, &buf[3]); + sel = sel_get_any_uid(&buf[3]); + + if (sel == 0 || GDL2RespondsToSelectorWithImpPtr(self,&rtsIMP,sel) == NO) + { + sel = 0; + } + } + } } - } - - value = [self _getValueForKey: aKey - selector: sel - type: type - size: size - offset: off]; + if (sel == 0 && [[self class] accessInstanceVariablesDirectly] == YES) + { + // Test _key + buf[3] = '_'; + buf[4] = lo; + + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"D aKey=%@ Instance [_key] name=%s", + aKey, &buf[3]); + /*if ([self _infoForInstanceVariableNamed: &buf[3] + stringName: nil + retType: &type + retSize: &size + retOffset: &off]==NO)*/ + if (infoForInstanceVariableWithImpPtr(self,&infoVarIMP, + &buf[3], // name + nil, // stringName + &type, // retType + &size, // retSize + &off)==NO) // retOffset + { + // Test key + + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"E aKey=%@ Instance [key] name=%s", + aKey, &buf[4]); + /*[self _infoForInstanceVariableNamed: &buf[4] + stringName: aKey + retType: &type + retSize: &size + retOffset: &off];*/ + infoForInstanceVariableWithImpPtr(self,&infoVarIMP, + &buf[4], // name + aKey, // stringName + &type, // retType + &size, // retSize + &off); // retOffset + } + } + + EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", + @"aKey=%@ sel=%@ offset=%u", + aKey, NSStringFromSelector(sel), off); + + value = [self _getValueForKey: aKey + selector: sel + type: type + size: size + offset: off]; + }; EOFLOGObjectLevelArgs(@"EOGenericRecordKVC", @"value: %p (class=%@)", value, [value class]); EOFLOGObjectFnStopCond(@"EOGenericRecordKVC"); @@ -847,7 +1012,7 @@ static const char _c_id[2] = { _C_ID, 0 }; [dictionary setObject: value forKey: key]; else -// [dictionary setObject: [EONull null] +// [dictionary setObject: GDL2EONull // forKey: key]; [dictionary removeObjectForKey: key]; @@ -867,6 +1032,7 @@ infinite loop in description **/ NSMutableDictionary *dict; NSString *key = nil; id obj = nil; + IMP ofkIMP=NULL; toManyKeys = [classDescription toManyRelationshipKeys]; toOneKeys = [classDescription toOneRelationshipKeys]; @@ -874,8 +1040,7 @@ infinite loop in description **/ while ((key = [enumerator nextObject])) { - obj = [dictionary objectForKey: key]; - + obj = EOMKKD_objectForKeyWithImpPtr(dictionary,&ofkIMP,key); if (!obj) [dict setObject: @"(null)" forKey: key]; @@ -906,6 +1071,7 @@ infinite loop in description **/ NSMutableDictionary *dict; NSString *key = nil; id obj = nil; + IMP ofkIMP=NULL; toManyKeys = [classDescription toManyRelationshipKeys]; toOneKeys = [classDescription toOneRelationshipKeys]; @@ -914,64 +1080,63 @@ infinite loop in description **/ while ((key = [enumerator nextObject])) { - obj = [dictionary objectForKey: key]; + obj = EOMKKD_objectForKeyWithImpPtr(dictionary,&ofkIMP,key); if (!obj) [dict setObject: @"(null)" forKey: key]; + else if (_isFault(obj) == YES) + { + [dict setObject: [obj description] + forKey: key]; + } + else if (obj==GDL2EONull) + [dict setObject: @"(null)" + forKey: key]; else { - if ([toManyKeys containsObject: key] == NO - && [toOneKeys containsObject: key] == NO) + if ([toManyKeys containsObject: key] != NO) { - [dict setObject: obj + NSEnumerator *toManyEnum; + NSMutableArray *array; + id rel; + + array = [NSMutableArray arrayWithCapacity: 8]; + toManyEnum = [obj objectEnumerator]; + + while ((rel = [toManyEnum nextObject])) + { + NSString* relDescr=nil; + // Avoid infinit loop + if ([rel respondsToSelector: @selector(_shortDescription)]) + relDescr=[rel _shortDescription]; + else + relDescr=[rel description]; + + [array addObject: + [NSString + stringWithFormat: @"<%@ %p>", + relDescr, NSStringFromClass([rel class])]]; + } + + [dict setObject: [NSString stringWithFormat: + @"<%p %@ : %@>", + obj, [obj class], array] + forKey: key]; + } + else if ([toOneKeys containsObject: key] != NO) + { + [dict setObject: [NSString + stringWithFormat: @"<%p %@: classDescription=%@>", + obj, + NSStringFromClass([obj class]), + [(EOGenericRecord *)obj classDescription]] forKey: key]; } else { - if ([EOFault isFault: obj] == YES) - { - [dict setObject: [obj description] - forKey: key]; - } - else if ([toManyKeys containsObject: key] == YES) - { - NSEnumerator *toManyEnum; - NSMutableArray *array; - id rel; - - array = [NSMutableArray arrayWithCapacity: 8]; - toManyEnum = [obj objectEnumerator]; - - while ((rel = [toManyEnum nextObject])) - { - NSString* relDescr; - // Avoid infinit loop - if ([rel respondsToSelector: @selector(_shortDescription)]) - relDescr=[rel _shortDescription]; - else - relDescr=[rel description]; - - [array addObject: - [NSString - stringWithFormat: @"<%@ %p>", - relDescr, NSStringFromClass([rel class])]]; - } - - [dict setObject: [NSString stringWithFormat: - @"<%p %@ : %@>", - obj, [obj class], array] - forKey: key]; - } - else - { - [dict setObject: [NSString - stringWithFormat: @"<%p %@: classDescription=%@>", - obj, - NSStringFromClass([obj class]), - [(EOGenericRecord *)obj classDescription]] - forKey: key]; - } + [dict setObject: obj + forKey: key]; } } } @@ -1026,7 +1191,7 @@ You can override this to exclude properties manually handled by derived object * while ((record = (EOGenericRecord*)NSNextHashEnumeratorItem(&hashEnum))) { - if ([EOFault isFault:record]) + if (_isFault(record)) [EOFault eoCalculateSizeWith: dict forFault: record]; else @@ -1114,12 +1279,12 @@ You can override this to exclude properties manually handled by derived object * id value = [self valueForKey: propKey]; //NSDebugMLog(@"propKey=%@", propKey); - //NSDebugMLog(@"value isFault=%s", ([EOFault isFault:value] ? "YES" : "NO")); + //NSDebugMLog(@"value isFault=%s", (_isFault(value) ? "YES" : "NO")); //NSDebugMLog(@"value=%p class=%@", value, [value class]); if (value) { - if ([EOFault isFault:value]) + if (_isFault(value)) size += [EOFault eoCalculateSizeWith: dict forFault: value]; else if ([value respondsToSelector: @selector(eoCalculateSizeWith:)]) diff --git a/EOControl/EOKeyGlobalID.m b/EOControl/EOKeyGlobalID.m index 5b6b0a1..22e2ec6 100644 --- a/EOControl/EOKeyGlobalID.m +++ b/EOControl/EOKeyGlobalID.m @@ -53,10 +53,20 @@ RCS_ID("$Id$") #include #include #include +#include @implementation EOKeyGlobalID ++ (void) initialize +{ + static BOOL initialized=NO; + if (!initialized) + { + GDL2PrivInit(); + }; +}; + + (id)globalIDWithEntityName: (NSString *)entityName keys: (id *)keys keyCount: (unsigned)count @@ -229,7 +239,7 @@ RCS_ID("$Id$") BOOL areNulls = YES; for (i = 0; areNulls && i < _keyCount; i++) - areNulls = isNilOrEONull(_keyValues[i]); + areNulls = _isNilOrEONull(_keyValues[i]); return areNulls; } diff --git a/EOControl/EOKeyValueCoding.m b/EOControl/EOKeyValueCoding.m index ec7fd58..6e3cf6a 100644 --- a/EOControl/EOKeyValueCoding.m +++ b/EOControl/EOKeyValueCoding.m @@ -68,27 +68,27 @@ RCS_ID("$Id$") #include #include #include +#include #include -static EONull *null = nil; -static SEL oaiSel; static BOOL strictWO; +static BOOL initialized=NO; static inline void initialize(void) { - if (null == nil) + if (!initialized) { - oaiSel = @selector(objectAtIndex:); + initialized=YES; strictWO = GSUseStrictWO451Compatibility(nil); - null = [EONull null]; + GDL2PrivInit(); } } /* This macro is only used locally in defined places so for the sake of efficiency, we don't use the do {} while (0) pattern. */ -#define INITIALIZE if (null == nil) initialize(); +#define INITIALIZE if (!initialized) initialize(); @implementation NSObject (_EOKeyValueCodingCompatibility) @@ -217,7 +217,9 @@ initialize(void) selStr = [NSString stringWithFormat: @"compute%@ForKey:", [[key substringWithRange: r] initialCapitalizedString]]; sel = NSSelectorFromString(selStr); - NSAssert1(sel!=NULL, @"Invalid computational key %@", selStr); + NSAssert2(sel!=NULL,@"Invalid computational key: '%@' Selector: '%@'", + key, + selStr); result = [self performSelector: sel withObject: attrStr]; @@ -226,7 +228,7 @@ initialize(void) { result = [self resultsOfPerformingSelector: @selector(valueForKey:) withObject: key - defaultResult: null]; + defaultResult: GDL2EONull]; } EOFLOGObjectFnStopCond(@"EOKVC"); @@ -302,26 +304,30 @@ initialize(void) */ - (id)computeSumForKey: (NSString *)key { - NSDecimalNumber *ret; + NSDecimalNumber *ret=nil; NSDecimal result, left, right; NSRoundingMode mode; - unsigned int i, count; - IMP oai; + unsigned int count; INITIALIZE; EOFLOGObjectFnStartCond(@"EOKVC"); + mode = [[NSDecimalNumber defaultBehavior] roundingMode]; - oai = [self methodForSelector: oaiSel]; count = [self count]; NSDecimalFromComponents(&result, 0, 0, NO); - for (i=0; i0) { - left = result; - right = [[(*oai)(self, oaiSel, i) valueForKey: key] decimalValue]; - NSDecimalAdd(&result, &left, &right, mode); - } + unsigned int i=0; + IMP oaiIMP = [self methodForSelector: GDL2_objectAtIndexSEL]; + for (i=0; i0) { - left = result; - right = [[(*oai)(self, oaiSel, i) valueForKey: key] decimalValue]; - NSDecimalAdd(&result, &left, &right, mode); - } + unsigned int i=0; + IMP oaiIMP = [self methodForSelector: GDL2_objectAtIndexSEL]; + + for (i=0; i 0) { - id current,currentVal; - IMP oai; + unsigned int i=0; + id current = nil; + id currentVal = nil; + IMP oaiIMP = [self methodForSelector: GDL2_objectAtIndexSEL]; - oai = [self methodForSelector: oaiSel]; - for(i=0; i 0) { - id current, currentVal; - IMP oai; + id current=nil; + id currentVal=nil; + unsigned int i = 0; + IMP oaiIMP = [self methodForSelector: GDL2_objectAtIndexSEL]; - oai = [self methodForSelector: oaiSel]; - for(i=0; i 0) + while (keyPathArrayCount > 0) { id tmpKey; @@ -851,6 +864,7 @@ initialize(void) //EOFLOGObjectLevelArgs(@"EOKVC", @"tmpKey=%@", tmpKey); [keyPathArray removeObjectAtIndex: 0]; + keyPathArrayCount--; if ([key length] > 0) [key appendString: @"."]; @@ -872,7 +886,7 @@ initialize(void) //EOFLOGObjectLevelArgs(@"EOKVC",@"left keyPathArray=\"%@\"", // keyPathArray); - if ([keyPathArray count] > 0) + if (keyPathArrayCount > 0) { id obj = [self objectForKey: key]; @@ -937,9 +951,11 @@ initialize(void) mutableCopy] autorelease]; NSMutableString *key = [NSMutableString string]; + int keyPathArrayCount=[keyPathArray count]; + //EOFLOGObjectLevelArgs(@"EOKVC", @"keyPathArray=%@", keyPathArray); - while ([keyPathArray count] > 0) + while (keyPathArrayCount > 0) { id tmpKey; @@ -949,6 +965,7 @@ initialize(void) //EOFLOGObjectLevelArgs(@"EOKVC", @"tmpKey=%@", tmpKey); [keyPathArray removeObjectAtIndex: 0]; + keyPathArrayCount--; if ([key length] > 0) [key appendString: @"."]; @@ -969,7 +986,7 @@ initialize(void) //EOFLOGObjectLevelArgs(@"EOKVC",@"left keyPathArray=\"%@\"", // keyPathArray); - if ([keyPathArray count] > 0) + if (keyPathArrayCount > 0) { id obj = [self objectForKey: key]; @@ -1055,7 +1072,7 @@ initialize(void) if (val == nil) { - val = null; + val = GDL2EONull; } [newKeyPaths addObject: keyPath]; @@ -1173,7 +1190,7 @@ initialize(void) NS_ENDHANDLER; if (val == nil) - val = null; + val = GDL2EONull; [newKeyPaths addObject: keyPath]; [newVals addObject: val]; diff --git a/EOControl/EOKeyValueQualifier.m b/EOControl/EOKeyValueQualifier.m index 64e1893..dbe5841 100644 --- a/EOControl/EOKeyValueQualifier.m +++ b/EOControl/EOKeyValueQualifier.m @@ -61,6 +61,7 @@ RCS_ID("$Id$") #include #include #include +#include /* This declaration is needed by the compiler to state that @@ -81,10 +82,16 @@ RCS_ID("$Id$") @end @implementation EOKeyValueQualifier -static EONull *null = nil; + + (void)initialize { - null = [EONull null]; + static BOOL initialized=NO; + if (!initialized) + { + initialized=YES; + + GDL2PrivInit(); + }; } /** @@ -121,7 +128,7 @@ static EONull *null = nil; ASSIGNCOPY(_key, key); if (value == nil) { - value = null; + value = GDL2EONull; } ASSIGN(_value, value); } @@ -200,59 +207,99 @@ static EONull *null = nil; */ - (BOOL) evaluateWithObject: (id)object { - NSObject *val; + NSObject *objectValue; + NSObject *selfValue=_value; BOOL (*imp)(id, SEL, id); - val = [object valueForKey: _key]; + objectValue = [object valueForKey: _key]; - if (val == nil) + if (objectValue == nil) { - val = null; + objectValue = GDL2EONull; + } + if (selfValue == nil) + { + selfValue = GDL2EONull; } - imp = (BOOL (*)(id, SEL, id))[val methodForSelector: _selector]; + imp = (BOOL (*)(id, SEL, id))[objectValue methodForSelector: _selector]; if (imp != NULL) { - return (*imp) (val, _selector, _value); + return (*imp) (objectValue, _selector, selfValue); } if (sel_eq(_selector, EOQualifierOperatorEqual) == YES) { - return [val isEqual: _value]; + return [objectValue isEqual: selfValue]; } else if (sel_eq(_selector, EOQualifierOperatorNotEqual) == YES) { - return ([val isEqual: _value]?NO:YES); + return ([objectValue isEqual: selfValue]?NO:YES); } else if (sel_eq(_selector, EOQualifierOperatorLessThan) == YES) { - return [val compare: _value] == NSOrderedAscending; + if (objectValue==GDL2EONull) + return ((selfValue==GDL2EONull) ? NO : YES); + else if (selfValue==GDL2EONull) + return NO; + else + return [objectValue compare: selfValue] == NSOrderedAscending; } else if (sel_eq(_selector, EOQualifierOperatorGreaterThan) == YES) { - return [val compare: _value] == NSOrderedDescending; + if (objectValue==GDL2EONull) + return NO; + else if (selfValue==GDL2EONull) + return YES; + else + return [objectValue compare: selfValue] == NSOrderedDescending; } else if (sel_eq(_selector, EOQualifierOperatorLessThanOrEqualTo) == YES) { - return [val compare: _value] != NSOrderedDescending; + if (objectValue==GDL2EONull) + return YES; + else if (selfValue==GDL2EONull) + return NO; + else + return [objectValue compare: selfValue] != NSOrderedDescending; } else if (sel_eq(_selector, EOQualifierOperatorGreaterThanOrEqualTo) == YES) { - return [val compare: _value] != NSOrderedAscending; + if (objectValue==GDL2EONull) + return ((selfValue==GDL2EONull) ? YES : NO); + else if (selfValue==GDL2EONull) + return YES; + else + return [objectValue compare: selfValue] != NSOrderedAscending; } else if (sel_eq(_selector, EOQualifierOperatorContains) == YES) { - return [(id)val rangeOfString: _value].location != NSNotFound; + //Philosophical question: does nil contains nil ?? + + if (objectValue==GDL2EONull) // Let's say nil does contain nothing (even not nil) + return NO; + else if (selfValue==GDL2EONull) // Let's say nil is contained by nothing + return NO; + else + return [(NSString*)objectValue rangeOfString: + (NSString*)selfValue].location != NSNotFound; } else if (sel_eq(_selector, EOQualifierOperatorLike) == YES) { NSEmitTODO(); //TODO - return [val isEqual: _value] == NSOrderedSame; + //How to handle nil like ? + return [objectValue isEqual: selfValue]; } else if (sel_eq(_selector, EOQualifierOperatorCaseInsensitiveLike) == YES) { NSEmitTODO(); //TODO - return [[(id)val uppercaseString] isEqual: [_value uppercaseString]] - == NSOrderedSame; + //How to handle nil like ? + if (objectValue==GDL2EONull) + return ((selfValue==GDL2EONull) ? YES : NO); + else if (selfValue==GDL2EONull) + return NO; + else + return [(id)objectValue caseInsensitiveCompare: + (NSString*)selfValue] == NSOrderedSame; } /*Ayers (09-02-2002): Maybe we should raise instead of returning NO.*/ return NO; diff --git a/EOControl/EOMutableKnownKeyDictionary.h b/EOControl/EOMutableKnownKeyDictionary.h index d56baa8..7af4b55 100644 --- a/EOControl/EOMutableKnownKeyDictionary.h +++ b/EOControl/EOMutableKnownKeyDictionary.h @@ -171,4 +171,13 @@ @end +/** mkkkd can be a NSMutableKnownKey or another kind of dictionary **/ +GDL2CONTROL_EXPORT id EOMKKD_objectForKeyWithImpPtr(NSDictionary* mkkd,IMP* impPtr,NSString* key); +GDL2CONTROL_EXPORT void EOMKKD_setObjectForKeyWithImpPtr(NSDictionary* mkkd,IMP* impPtr,id anObject,NSString* key); +GDL2CONTROL_EXPORT void EOMKKD_removeObjectForKeyWithImpPtr(NSDictionary* mkkd,IMP* impPtr,NSString* key); +GDL2CONTROL_EXPORT BOOL EOMKKD_hasKeyWithImpPtr(NSDictionary* mkkd,GDL2IMP_BOOL* impPtr,NSString* key); + +GDL2CONTROL_EXPORT unsigned int EOMKKD_indexForKeyWithImpPtr(EOMutableKnownKeyDictionary* mkkd,GDL2IMP_UINT* impPtr,NSString* key); +GDL2CONTROL_EXPORT unsigned int EOMKKDInitializer_indexForKeyWithImpPtr(EOMKKDInitializer* mkkdInit,GDL2IMP_UINT* impPtr,NSString* key); + #endif diff --git a/EOControl/EOMutableKnownKeyDictionary.m b/EOControl/EOMutableKnownKeyDictionary.m index 5bf497e..0ad5d17 100644 --- a/EOControl/EOMutableKnownKeyDictionary.m +++ b/EOControl/EOMutableKnownKeyDictionary.m @@ -53,6 +53,7 @@ RCS_ID("$Id$") #include #endif +#include #include #include #include @@ -60,6 +61,16 @@ RCS_ID("$Id$") @implementation EOMKKDInitializer ++ (void)initialize +{ + static BOOL initialized=NO; + if (!initialized) + { + initialized=YES; + GDL2PrivInit(); + } +} + + (EOMKKDInitializer*)initializerFromKeyArray: (NSArray*)keys { EOMKKDInitializer *initializer = [[self newWithKeyArray: keys] autorelease]; @@ -236,15 +247,14 @@ RCS_ID("$Id$") - (BOOL)hasKey: (id)key { - return ([self indexForKey: key] != NSNotFound); + return (EOMKKDInitializer_indexForKeyWithImpPtr(self,NULL,key) != NSNotFound); } - (EOMKKDArrayMapping*) arrayMappingForKeys: (NSArray*)keys { int selfKeyCount = [keys count]; int keyCount = [keys count]; - EOMKKDArrayMapping *arrayMapping; - int i; + EOMKKDArrayMapping *arrayMapping = nil; NSAssert(keyCount <= selfKeyCount, @"key count greater than our key count"); @@ -252,13 +262,21 @@ RCS_ID("$Id$") destinationDescription: self zone: [self zone]] autorelease]; - for (i = 0; i < keyCount; i++) + if (keyCount>0) { - NSString *key = [keys objectAtIndex: i]; - int destinationIndex = [self indexForKey:key]; + int i=0; + GDL2IMP_UINT indexForKeyIMP=NULL; + IMP objectAtIndexIMP=[keys methodForSelector:GDL2_objectAtIndexSEL]; - arrayMapping->_destinationOffsetForArrayIndex[i] = destinationIndex + 1; - } + for (i = 0; i < keyCount; i++) + { + NSString *key = GDL2AddObjectWithImp(keys,objectAtIndexIMP,i); + int destinationIndex = EOMKKDInitializer_indexForKeyWithImpPtr(self,&indexForKeyIMP,key); + + + arrayMapping->_destinationOffsetForArrayIndex[i] = destinationIndex + 1; + } + }; return arrayMapping; } @@ -269,8 +287,7 @@ RCS_ID("$Id$") { unsigned int selfKeyCount = [self count]; unsigned int keyCount = [destinationKeys count]; - EOMKKDSubsetMapping *subsetMapping; - int i; + EOMKKDSubsetMapping *subsetMapping = nil; NSAssert([sourceKeys count] == keyCount, @"Source and destination keys count are different"); NSAssert(keyCount <= selfKeyCount, @"key count greater than our key count"); @@ -285,38 +302,55 @@ RCS_ID("$Id$") EOFLOGObjectLevelArgs(@"EOMKKD", @"sourceKeys=%@", sourceKeys); EOFLOGObjectLevelArgs(@"EOMKKD", @"destinationKeys=%@", destinationKeys); - for (i = 0; i < keyCount; i++) - { - NSString *sourceKey; - NSString *destinationKey; - int destinationIndex; - int sourceIndex; + if (keyCount>0) + { + int i; + GDL2IMP_UINT selfIndexForKeyIMP=NULL; + GDL2IMP_UINT sourceInitializerIndexForKeyIMP=NULL; + IMP sourceObjectAtIndexIMP=[sourceKeys methodForSelector:GDL2_objectAtIndexSEL]; + IMP destinationObjectAtIndexIMP=[destinationKeys methodForSelector:GDL2_objectAtIndexSEL]; - sourceKey = [sourceKeys objectAtIndex: i]; - EOFLOGObjectLevelArgs(@"EOMKKD", @"sourceKey=%@", sourceKey); - - destinationKey = [destinationKeys objectAtIndex: i]; - EOFLOGObjectLevelArgs(@"EOMKKD", @"destinationKey=%@", destinationKey); - - destinationIndex = [self indexForKey: destinationKey]; - EOFLOGObjectLevelArgs(@"EOMKKD", @"destinationIndex=%d", - destinationIndex); - - sourceIndex = [sourceInitializer indexForKey: sourceKey]; - EOFLOGObjectLevelArgs(@"EOMKKD", @"sourceIndex=%d", sourceIndex); - - NSAssert2(destinationIndex != NSNotFound, - @"Destination Key %@ not found in %@", - destinationKey, - self); - NSAssert2(sourceIndex != NSNotFound, - @"Source Key %@ not found in %@", - sourceKey, - sourceInitializer); - - subsetMapping->_sourceOffsetForDestinationOffset[destinationIndex] - = sourceIndex + 1; - } + for (i = 0; i < keyCount; i++) + { + NSString *sourceKey = nil; + NSString *destinationKey = nil; + int destinationIndex = 0; + int sourceIndex = 0; + + sourceKey = + GDL2AddObjectWithImp(sourceKeys,sourceObjectAtIndexIMP,i); + EOFLOGObjectLevelArgs(@"EOMKKD", @"sourceKey=%@", sourceKey); + + destinationKey = + GDL2AddObjectWithImp(destinationKeys,destinationObjectAtIndexIMP,i); + EOFLOGObjectLevelArgs(@"EOMKKD", @"destinationKey=%@", destinationKey); + + destinationIndex = + EOMKKDInitializer_indexForKeyWithImpPtr(self, + &selfIndexForKeyIMP, + destinationKey); + EOFLOGObjectLevelArgs(@"EOMKKD", @"destinationIndex=%d", + destinationIndex); + + sourceIndex = + EOMKKDInitializer_indexForKeyWithImpPtr(sourceInitializer, + &sourceInitializerIndexForKeyIMP, + sourceKey); + EOFLOGObjectLevelArgs(@"EOMKKD", @"sourceIndex=%d", sourceIndex); + + NSAssert2(destinationIndex != NSNotFound, + @"Destination Key %@ not found in %@", + destinationKey, + self); + NSAssert2(sourceIndex != NSNotFound, + @"Source Key %@ not found in %@", + sourceKey, + sourceInitializer); + + subsetMapping->_sourceOffsetForDestinationOffset[destinationIndex] + = sourceIndex + 1; + } + }; return subsetMapping; } @@ -329,22 +363,28 @@ RCS_ID("$Id$") sourceDescription: sourceInitializer destinationDescription: self zone: [self zone]] autorelease]; - int i; - for (i = 0; i < keyCount; i++) + if (keyCount>0) { - NSString *key; - int index; - - key = _keys[i]; - EOFLOGObjectLevelArgs(@"EOMKKD", @"key=%@", key); - - index = [sourceInitializer indexForKey: key]; - EOFLOGObjectLevelArgs(@"EOMKKD", @"index=%d", index); - - subsetMapping->_sourceOffsetForDestinationOffset[i] - = (index == NSNotFound ? 0 : index + 1); - } + int i=0; + GDL2IMP_UINT indexForKeyIMP=NULL; + + for (i = 0; i < keyCount; i++) + { + NSString *key; + int index; + + key = _keys[i]; + EOFLOGObjectLevelArgs(@"EOMKKD", @"key=%@", key); + + index = EOMKKDInitializer_indexForKeyWithImpPtr(sourceInitializer, + &indexForKeyIMP,key); + EOFLOGObjectLevelArgs(@"EOMKKD", @"index=%d", index); + + subsetMapping->_sourceOffsetForDestinationOffset[i] + = (index == NSNotFound ? 0 : index + 1); + } + }; return subsetMapping; } @@ -485,16 +525,6 @@ RCS_ID("$Id$") @implementation EOMKKDArrayMapping -+ (id)dictionaryFromDictionary: (NSDictionary *)dict - subsetMapping: (EOMKKDSubsetMapping *)subsetMapping -{ -#warning (stephane@sente.ch) Method is really not implemented! -#warning (Ayers 28-03-2003) Either remove this method from array or use EOMutableKnownKeyDictionary instead of self - return [[self newDictionaryFromDictionary: dict - subsetMapping: subsetMapping - zone: NULL] autorelease]; -} - + (id)newInstanceWithKeyCount: (unsigned int)keyCount destinationDescription: (EOMKKDInitializer*)destination zone: (NSZone*)zone @@ -536,6 +566,16 @@ RCS_ID("$Id$") @implementation EOMutableKnownKeyDictionary ++ (void)initialize +{ + static BOOL initialized=NO; + if (!initialized) + { + initialized=YES; + GDL2PrivInit(); + } +} + + (id)dictionaryFromDictionary: (NSDictionary *)dict subsetMapping: (EOMKKDSubsetMapping *)subsetMapping { @@ -803,7 +843,7 @@ RCS_ID("$Id$") // EOFLOGObjectFnStart(); NSAssert(_MKKDInitializer, @"No _MKKDInitializer"); - index = [_MKKDInitializer indexForKey: key]; + index = EOMKKDInitializer_indexForKeyWithImpPtr(_MKKDInitializer,NULL,key); // EOFLOGObjectLevelArgs(@"EOMKKD", @"index=%d", index); @@ -832,7 +872,7 @@ RCS_ID("$Id$") NSAssert(_MKKDInitializer, @"No _MKKDInitializer"); - index = [_MKKDInitializer indexForKey: key]; + index = EOMKKDInitializer_indexForKeyWithImpPtr(_MKKDInitializer,NULL,key); if (index == NSNotFound) { @@ -857,7 +897,7 @@ RCS_ID("$Id$") NSAssert(_MKKDInitializer, @"No _MKKDInitializer"); - index = [_MKKDInitializer indexForKey: key]; + index = EOMKKDInitializer_indexForKeyWithImpPtr(_MKKDInitializer,NULL,key); if (index == NSNotFound) { @@ -883,9 +923,9 @@ RCS_ID("$Id$") { if (_values[i] != object) { - if (isNilOrEONull(_values[i])) - result =! isNilOrEONull(object); - else if (isNilOrEONull(object)) + if (_isNilOrEONull(_values[i])) + result =! _isNilOrEONull(object); + else if (_isNilOrEONull(object)) result = YES; else result = ![_values[i] isEqual: object]; @@ -900,11 +940,12 @@ RCS_ID("$Id$") - (void)addEntriesFromDictionary: (NSDictionary*)dictionary { NSEnumerator *e = [dictionary keyEnumerator]; - id key; + id key=nil; + IMP indexForKeyIMP=NULL; while ((key = [e nextObject])) { - if (![self objectForKey: key]) //Don't overwrite already present values ? + if (!EOMKKD_objectForKeyWithImpPtr(self,&indexForKeyIMP,key)) //Don't overwrite already present values ? { [self setObject: [dictionary objectForKey: key] forKey: key]; @@ -965,3 +1006,137 @@ RCS_ID("$Id$") } @end + +id EOMKKD_objectForKeyWithImpPtr(NSDictionary* mkkd,IMP* impPtr,NSString* key) +{ + if (mkkd) + { + IMP imp=NULL; + if (impPtr) + imp=*impPtr; + if (!imp) + { + if (GSObjCClass(mkkd)==GDL2MKKDClass + && GDL2MKKD_objectForKeyIMP) + imp=GDL2MKKD_objectForKeyIMP; + else + imp=[mkkd methodForSelector:GDL2_objectForKeySEL]; + if (impPtr) + *impPtr=imp; + } + return (*imp)(mkkd,GDL2_objectForKeySEL,key); + } + else + return nil; +}; + +void EOMKKD_setObjectForKeyWithImpPtr(NSDictionary* mkkd,IMP* impPtr,id anObject,NSString* key) +{ + if (mkkd) + { + IMP imp=NULL; + if (impPtr) + imp=*impPtr; + if (!imp) + { + if (GSObjCClass(mkkd)==GDL2MKKDClass + && GDL2MKKD_setObjectForKeyIMP) + imp=GDL2MKKD_setObjectForKeyIMP; + else + imp=[mkkd methodForSelector:GDL2_setObjectForKeySEL]; + if (impPtr) + *impPtr=imp; + } + (*imp)(mkkd,GDL2_setObjectForKeySEL,anObject,key); + }; +}; + +void EOMKKD_removeObjectForKeyWithImpPtr(NSDictionary* mkkd,IMP* impPtr,NSString* key) +{ + if (mkkd) + { + IMP imp=NULL; + if (impPtr) + imp=*impPtr; + if (!imp) + { + if (GSObjCClass(mkkd)==GDL2MKKDClass + && GDL2MKKD_removeObjectForKeyIMP) + imp=GDL2MKKD_removeObjectForKeyIMP; + else + imp=[mkkd methodForSelector:GDL2_removeObjectForKeySEL]; + if (impPtr) + *impPtr=imp; + } + (*imp)(mkkd,GDL2_removeObjectForKeySEL,key); + }; +}; + +BOOL EOMKKD_hasKeyWithImpPtr(NSDictionary* mkkd,GDL2IMP_BOOL* impPtr,NSString* key) +{ + if (mkkd) + { + GDL2IMP_BOOL imp=NULL; + if (impPtr) + imp=*impPtr; + if (!imp) + { + if (GSObjCClass(mkkd)==GDL2MKKDClass + && GDL2MKKD_hasKeyIMP) + imp=GDL2MKKD_hasKeyIMP; + else + imp=(GDL2IMP_BOOL)[mkkd methodForSelector:GDL2_hasKeySEL]; + if (impPtr) + *impPtr=imp; + } + return (*imp)(mkkd,GDL2_hasKeySEL,key); + } + else + return NO; +}; + +unsigned int EOMKKD_indexForKeyWithImpPtr(EOMutableKnownKeyDictionary* mkkd,GDL2IMP_UINT* impPtr,NSString* key) +{ + if (mkkd) + { + GDL2IMP_UINT imp=NULL; + if (impPtr) + imp=*impPtr; + if (!imp) + { + if (GSObjCClass(mkkd)==GDL2MKKDClass + && GDL2MKKD_indexForKeyIMP) + imp=GDL2MKKD_indexForKeyIMP; + else + imp=(GDL2IMP_UINT)[mkkd methodForSelector:GDL2_indexForKeySEL]; + if (impPtr) + *impPtr=imp; + } + return (*imp)(mkkd,GDL2_indexForKeySEL,key); + } + else + return 0; +}; + +unsigned int EOMKKDInitializer_indexForKeyWithImpPtr(EOMKKDInitializer* mkkdInit,GDL2IMP_UINT* impPtr,NSString* key) +{ + if (mkkdInit) + { + GDL2IMP_UINT imp=NULL; + if (impPtr) + imp=*impPtr; + if (!imp) + { + if (GSObjCClass(mkkdInit)==GDL2EOMKKDInitializerClass + && GDL2EOMKKDInitializer_indexForKeyIMP) + imp=GDL2EOMKKDInitializer_indexForKeyIMP; + else + imp=(GDL2IMP_UINT)[mkkdInit methodForSelector:GDL2_indexForKeySEL]; + if (impPtr) + *impPtr=imp; + } + return (*imp)(mkkdInit,GDL2_indexForKeySEL,key); + } + else + return 0; +}; diff --git a/EOControl/EONSAddOns.h b/EOControl/EONSAddOns.h index f5fbc89..eaa46b3 100644 --- a/EOControl/EONSAddOns.h +++ b/EOControl/EONSAddOns.h @@ -1,7 +1,7 @@ /* -*-objc-*- EONSAddOns.h - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000-2005 Free Software Foundation, Inc. Author: Manuel Guesdon Date: October 2000 @@ -118,6 +118,12 @@ GDL2_ActivateAllGDL2Categories(void); -(unsigned long long)unsignedLongLongValue; @end +@interface NSString (ShellPattern) +/** returns YES is string contain shell pattern characters, +NO otherwise **/ +- (BOOL)hasShellPatternCharacter; +@end + @interface NSObject (PerformSelect3) /** * Causes the receiver to execute the method implementation corresponding diff --git a/EOControl/EONSAddOns.m b/EOControl/EONSAddOns.m index f7137e0..6a87b2a 100644 --- a/EOControl/EONSAddOns.m +++ b/EOControl/EONSAddOns.m @@ -59,6 +59,7 @@ RCS_ID("$Id$") #include #include +#include #include @@ -147,6 +148,16 @@ GDL2_ActivateAllGDL2Categories(void) } +@implementation NSString (ShellPattern) +/** returns YES is string contain shell pattern characters, +NO otherwise **/ +- (BOOL)hasShellPatternCharacter +{ + NSRange r=[self rangeOfCharacterFromSet:GDL2_shellPatternCharacterSet]; + return (r.length>0 ? YES : NO); +}; + +@end @implementation NSObject (NSObjectPerformingSelector) @@ -190,7 +201,7 @@ GDL2_ActivateAllGDL2Categories(void) object, sel_get_name(sel)); - [results addObject: result]; + [results addObject: result]; //TODO What to do if nil ?? } } NS_HANDLER diff --git a/EOControl/EONull.h b/EOControl/EONull.h index 8e522b8..b622919 100644 --- a/EOControl/EONull.h +++ b/EOControl/EONull.h @@ -50,5 +50,6 @@ GDL2CONTROL_EXPORT BOOL isNilOrEONull(id v); + #endif /* __EONull_h__ */ diff --git a/EOControl/EOPriv.h b/EOControl/EOPriv.h new file mode 100644 index 0000000..50e10ad --- /dev/null +++ b/EOControl/EOPriv.h @@ -0,0 +1,164 @@ +/* -*-objc-*- + EOPriv.h + + Copyright (C) 2005 Free Software Foundation, Inc. + + Author: Manuel Guesdon + Date: Jan 2005 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EOPriv_h__ +#define __EOPriv_h__ + +#include + +@class NSNumber; +@class EONull; + +typedef unsigned int (*GDL2IMP_UINT)(id, SEL, ...); +typedef BOOL (*GDL2IMP_BOOL)(id, SEL, ...); + +GDL2CONTROL_EXPORT Class GDL2NSStringClass; +GDL2CONTROL_EXPORT Class GDL2NSNumberClass; +GDL2CONTROL_EXPORT Class GDL2NSDecimalNumberClass; +GDL2CONTROL_EXPORT Class GDL2NSCalendarDateClass; +GDL2CONTROL_EXPORT Class GDL2NSDateClass; +GDL2CONTROL_EXPORT Class GDL2NSAutoreleasePoolClass; +GDL2CONTROL_EXPORT Class GDL2NSDataClass; +GDL2CONTROL_EXPORT Class GDL2EOFaultClass; +GDL2CONTROL_EXPORT Class GDL2MKKDClass; +GDL2CONTROL_EXPORT Class GDL2EOMKKDInitializerClass; +GDL2CONTROL_EXPORT Class GDL2EODatabaseContextClass; +GDL2CONTROL_EXPORT Class GDL2EOEditingContextClass; +GDL2CONTROL_EXPORT Class GDL2EOAttributeClass; + +GDL2CONTROL_EXPORT SEL GDL2_newSEL; +GDL2CONTROL_EXPORT SEL GDL2_allocWithZoneSEL; +GDL2CONTROL_EXPORT SEL GDL2_isEqualToStringSEL; +GDL2CONTROL_EXPORT SEL GDL2_appendStringSEL; +GDL2CONTROL_EXPORT SEL GDL2_stringWithCString_lengthSEL; +GDL2CONTROL_EXPORT SEL GDL2_stringWithCStringSEL; +GDL2CONTROL_EXPORT SEL GDL2_addObjectSEL; +GDL2CONTROL_EXPORT SEL GDL2_objectAtIndexSEL; +GDL2CONTROL_EXPORT SEL GDL2_indexOfObjectIdenticalToSEL; +GDL2CONTROL_EXPORT SEL GDL2_nextObjectSEL; +GDL2CONTROL_EXPORT SEL GDL2_takeStoredValueForKeySEL; +GDL2CONTROL_EXPORT SEL GDL2_snapshotForGlobalIDSEL; +GDL2CONTROL_EXPORT SEL GDL2_objectForKeySEL; +GDL2CONTROL_EXPORT SEL GDL2_setObjectForKeySEL; +GDL2CONTROL_EXPORT SEL GDL2_removeObjectForKeySEL; +GDL2CONTROL_EXPORT SEL GDL2_respondsToSelectorSEL; +GDL2CONTROL_EXPORT SEL GDL2_hasKeySEL; +GDL2CONTROL_EXPORT SEL GDL2_indexForKeySEL; +GDL2CONTROL_EXPORT SEL GDL2_snapshotForGlobalIDSEL; +GDL2CONTROL_EXPORT SEL GDL2_recordObjectGlobalIDSEL; +GDL2CONTROL_EXPORT SEL GDL2_objectForGlobalIDSEL; +GDL2CONTROL_EXPORT SEL GDL2_globalIDForObjectSEL; + +GDL2CONTROL_EXPORT IMP GDL2NSAutoreleasePool_newIMP; +GDL2CONTROL_EXPORT IMP GDL2NSNumber_allocWithZoneIMP; +GDL2CONTROL_EXPORT IMP GDL2NSDecimalNumber_allocWithZoneIMP; +GDL2CONTROL_EXPORT IMP GDL2NSString_allocWithZoneIMP; +GDL2CONTROL_EXPORT IMP GDL2NSCalendarDate_allocWithZoneIMP; +GDL2CONTROL_EXPORT IMP GDL2NSData_allocWithZoneIMP; + +GDL2CONTROL_EXPORT IMP GDL2NSString_stringWithCString_lengthIMP; +GDL2CONTROL_EXPORT IMP GDL2NSString_stringWithCStringIMP; + +GDL2CONTROL_EXPORT IMP GDL2MKKD_objectForKeyIMP; +GDL2CONTROL_EXPORT IMP GDL2MKKD_setObjectForKeyIMP; +GDL2CONTROL_EXPORT IMP GDL2MKKD_removeObjectForKeyIMP; +GDL2CONTROL_EXPORT GDL2IMP_BOOL GDL2MKKD_hasKeyIMP; +GDL2CONTROL_EXPORT GDL2IMP_UINT GDL2MKKD_indexForKeyIMP; +GDL2CONTROL_EXPORT GDL2IMP_UINT GDL2EOMKKDInitializer_indexForKeyIMP; + +GDL2CONTROL_EXPORT IMP GDL2EODatabaseContext_snapshotForGlobalIDIMP; + +GDL2CONTROL_EXPORT IMP GDL2EOEditingContext_recordObjectGlobalIDIMP; +GDL2CONTROL_EXPORT IMP GDL2EOEditingContext_objectForGlobalIDIMP; +GDL2CONTROL_EXPORT IMP GDL2EOEditingContext_globalIDForObjectIMP; + +GDL2CONTROL_EXPORT NSNumber* GDL2NSNumberBool_Yes; +GDL2CONTROL_EXPORT NSNumber* GDL2NSNumberBool_No; +GDL2CONTROL_EXPORT EONull* GDL2EONull; +GDL2CONTROL_EXPORT NSCharacterSet* GDL2_shellPatternCharacterSet; + +GDL2CONTROL_EXPORT void GDL2PrivInit(); + +#define _isNilOrEONull(v) \ + (isNilOrEONull(v)) + +// (((v)==nil || (v)==GDL2EONull) ? YES : NO) + +//See also EOControl/EOFault.m +#define _isFault(v) \ + (((v)==nil) ? NO : ((((EOFault*)(v))->isa == GDL2EOFaultClass) ? YES : NO)) + +#define GDL2AppendStringWithImp(string,methodIMP,aString) \ + (*(methodIMP))((string),GDL2_appendStringSEL,(aString)) + +#define GDL2AddObjectWithImp(array,methodIMP,anObject) \ + (*(methodIMP))((array),GDL2_addObjectSEL,(anObject)) + +#define GDL2ObjectAtIndexWithImp(array,methodIMP,index) \ + (*(methodIMP))((array),GDL2_objectAtIndexSEL,(index)) + +#define GDL2IndexOfObjectIdenticalToWithImp(array,methodIMP,anObject) \ + (*(methodIMP))((array),GDL2_indexOfObjectIdenticalToSEL,(anObject)) + +#define GDL2NextObjectWithImp(enumerator,methodIMP) \ + (*(methodIMP))((array),GDL2_nextObjectSEL) + +#define GDL2TakeStoredValueForKeyWithImp(object,methodIMP,value,key) \ + (*methodIMP)((object),GDL2_takeStoredValueForKeySEL,value,key) + +#define GDL2StringWithCStringAndLength(cString,length) \ + (*GDL2NSString_stringWithCString_lengthIMP)(GDL2NSStringClass,GDL2_stringWithCString_lengthSEL,(const char*)(cString),(int)(length)) + +#define GDL2StringWithCString(cString) \ + (*GDL2NSString_stringWithCStringIMP)(GDL2NSStringClass,GDL2_stringWithCStringSEL,(const char*)(cString)) + +#define GDL2NSAutoreleasePool_new() \ + (*GDL2NSAutoreleasePool_newIMP)(GDL2NSAutoreleasePoolClass,GDL2_newSEL) + +#define GDL2NSString_alloc() \ + (*GDL2NSString_allocWithZoneIMP)(GDL2NSStringClass,GDL2_allocWithZoneSEL,NULL) + +#define GDL2NSDecimalNumber_alloc() \ + (*GDL2NSDecimalNumber_allocWithZoneIMP)(GDL2NSDecimalNumberClass,GDL2_allocWithZoneSEL,NULL) + +#define GDL2NSNumber_alloc() \ + (*GDL2NSNumber_allocWithZoneIMP)(GDL2NSNumberClass,GDL2_allocWithZoneSEL,NULL) + +#define GDL2NSCalendarDate_alloc() \ + (*GDL2NSCalendarDate_allocWithZoneIMP)(GDL2NSCalendarDateClass,GDL2_allocWithZoneSEL,NULL) + +#define GDL2NSData_alloc() \ + (*GDL2NSData_allocWithZoneIMP)(GDL2NSDataClass,GDL2_allocWithZoneSEL,NULL) + +static inline BOOL GDL2RespondsToSelectorWithImpPtr(id object,GDL2IMP_BOOL* impPtr,SEL sel) +{ + if (!*impPtr) + *impPtr=(GDL2IMP_BOOL)[object methodForSelector:GDL2_respondsToSelectorSEL]; + return (**impPtr)(object,GDL2_respondsToSelectorSEL,sel); +}; + +#endif /* __EOPriv_h__ */ + diff --git a/EOControl/EOPriv.m b/EOControl/EOPriv.m new file mode 100644 index 0000000..8adb630 --- /dev/null +++ b/EOControl/EOPriv.m @@ -0,0 +1,202 @@ +/** + EOPriv.m EOPriv: various definitions + + Copyright (C) 2005 Free Software Foundation, Inc. + + Date: Jan 2005 + + $Revision$ + $Date$ + + + + This file is part of the GNUstep Database Library. + + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +**/ + +#include "config.h" + +RCS_ID("$Id$") + +#include + +#ifndef GNUSTEP +#include +#include +#endif + +#include +#include +#include +#include + +Class GDL2NSStringClass=Nil; +Class GDL2NSNumberClass=Nil; +Class GDL2NSDecimalNumberClass=Nil; +Class GDL2NSCalendarDateClass=Nil; +Class GDL2NSDateClass=Nil; +Class GDL2NSAutoreleasePoolClass=Nil; +Class GDL2NSDataClass=Nil; +Class GDL2EOFaultClass=Nil; +Class GDL2MKKDClass=Nil; +Class GDL2EOMKKDInitializerClass=Nil; +Class GDL2EODatabaseContextClass=Nil; +Class GDL2EOEditingContextClass=Nil; +Class GDL2EOAttributeClass=Nil; + +SEL GDL2_newSEL=NULL; +SEL GDL2_allocWithZoneSEL=NULL; +SEL GDL2_isEqualToStringSEL=NULL; +SEL GDL2_appendStringSEL=NULL; +SEL GDL2_stringWithCString_lengthSEL=NULL; +SEL GDL2_stringWithCStringSEL=NULL; +SEL GDL2_addObjectSEL=NULL; +SEL GDL2_objectAtIndexSEL=NULL; +SEL GDL2_indexOfObjectIdenticalToSEL=NULL; +SEL GDL2_nextObjectSEL=NULL; +SEL GDL2_takeStoredValueForKeySEL=NULL; +SEL GDL2_snapshotForGlobalIDSEL=NULL; +SEL GDL2_objectForKeySEL=NULL; +SEL GDL2_respondsToSelectorSEL=NULL; +SEL GDL2_setObjectForKeySEL=NULL; +SEL GDL2_removeObjectForKeySEL=NULL; +SEL GDL2_hasKeySEL=NULL; +SEL GDL2_indexForKeySEL=NULL; + +SEL GDL2_recordObjectGlobalIDSEL=NULL; +SEL GDL2_objectForGlobalIDSEL=NULL; +SEL GDL2_globalIDForObjectSEL=NULL; + +IMP GDL2NSAutoreleasePool_newIMP=NULL; +IMP GDL2NSNumber_allocWithZoneIMP=NULL; +IMP GDL2NSDecimalNumber_allocWithZoneIMP=NULL; +IMP GDL2NSString_allocWithZoneIMP=NULL; +IMP GDL2NSCalendarDate_allocWithZoneIMP=NULL; +IMP GDL2NSData_allocWithZoneIMP=NULL; + +IMP GDL2NSString_stringWithCString_lengthIMP=NULL; +IMP GDL2NSString_stringWithCStringIMP=NULL; + +IMP GDL2MKKD_objectForKeyIMP=NULL; +IMP GDL2MKKD_setObjectForKeyIMP=NULL; +IMP GDL2MKKD_removeObjectForKeyIMP=NULL; +GDL2IMP_BOOL GDL2MKKD_hasKeyIMP=NULL; +GDL2IMP_UINT GDL2MKKD_indexForKeyIMP=NULL; +GDL2IMP_UINT GDL2EOMKKDInitializer_indexForKeyIMP=NULL; + +IMP GDL2EODatabaseContext_snapshotForGlobalIDIMP=NULL; +IMP GDL2EOEditingContext_recordObjectGlobalIDIMP=NULL; +IMP GDL2EOEditingContext_objectForGlobalIDIMP=NULL; +IMP GDL2EOEditingContext_globalIDForObjectIMP=NULL; + +NSNumber* GDL2NSNumberBool_Yes=nil; +NSNumber* GDL2NSNumberBool_No=nil; + +EONull* GDL2EONull=nil; + +NSCharacterSet* GDL2_shellPatternCharacterSet=nil; + + +void GDL2PrivInit() +{ + static BOOL initialized=NO; + if (!initialized) + { + GDL2NSStringClass=[NSString class]; + GDL2NSNumberClass=[NSNumber class]; + GDL2NSDecimalNumberClass=[NSDecimalNumber class]; + GDL2NSCalendarDateClass=[NSCalendarDate class]; + GDL2NSDateClass = [NSDate class]; + GDL2NSAutoreleasePoolClass = [NSAutoreleasePool class]; + GDL2NSDataClass = [NSData class]; + GDL2EOFaultClass = [EOFault class]; + GDL2MKKDClass = [EOMutableKnownKeyDictionary class]; + GDL2EOMKKDInitializerClass = [EOMKKDInitializer class]; + GDL2EODatabaseContextClass = [EODatabaseContext class]; + GDL2EOEditingContextClass = [EOEditingContext class]; + GDL2EOAttributeClass = [EOAttribute class]; + + GDL2_newSEL=@selector(new); + GDL2_allocWithZoneSEL=@selector(alloc); + GDL2_isEqualToStringSEL=@selector(isEqualToString:); + GDL2_appendStringSEL=@selector(appendString:); + GDL2_stringWithCString_lengthSEL=@selector(stringWithCString:length:); + GDL2_stringWithCStringSEL=@selector(stringWithCString:); + GDL2_addObjectSEL=@selector(addObject:); + GDL2_objectAtIndexSEL=@selector(objectAtIndex:); + GDL2_indexOfObjectIdenticalToSEL=@selector(indexOfObjectIdenticalTo:); + GDL2_nextObjectSEL=@selector(nextObject); + GDL2_takeStoredValueForKeySEL=@selector(takeStoredValue:forKey:); + GDL2_snapshotForGlobalIDSEL=@selector(snapshotForGlobalID:); + GDL2_objectForKeySEL=@selector(objectForKey:); + GDL2_setObjectForKeySEL=@selector(setObject:forKey:); + GDL2_removeObjectForKeySEL=@selector(removeObjectForKey:); + GDL2_respondsToSelectorSEL=@selector(respondsToSelector:); + GDL2_hasKeySEL=@selector(hasKey:); + GDL2_indexForKeySEL=@selector(indexForKey:); + GDL2_snapshotForGlobalIDSEL=@selector(snapshotForGlobalID:); + GDL2_recordObjectGlobalIDSEL=@selector(recordObject:globalID:); + GDL2_objectForGlobalIDSEL=@selector(objectForGlobalID:); + GDL2_globalIDForObjectSEL=@selector(globalIDForObject:); + + GDL2NSAutoreleasePool_newIMP=[GDL2NSAutoreleasePoolClass + methodForSelector:GDL2_newSEL]; + + GDL2NSNumber_allocWithZoneIMP=[GDL2NSNumberClass + methodForSelector:GDL2_allocWithZoneSEL]; + + GDL2NSDecimalNumber_allocWithZoneIMP=[GDL2NSDecimalNumberClass + methodForSelector:GDL2_allocWithZoneSEL]; + + GDL2NSString_allocWithZoneIMP=[GDL2NSStringClass + methodForSelector:GDL2_allocWithZoneSEL]; + + GDL2NSCalendarDate_allocWithZoneIMP=[GDL2NSCalendarDateClass + methodForSelector:GDL2_allocWithZoneSEL]; + + GDL2NSData_allocWithZoneIMP=[GDL2NSDataClass + methodForSelector:GDL2_allocWithZoneSEL]; + + GDL2NSString_stringWithCString_lengthIMP= + [GDL2NSStringClass methodForSelector:GDL2_stringWithCString_lengthSEL]; + + GDL2NSString_stringWithCStringIMP= + [GDL2NSStringClass methodForSelector:GDL2_stringWithCStringSEL]; + + GDL2MKKD_objectForKeyIMP=[GDL2MKKDClass instanceMethodForSelector:GDL2_objectForKeySEL]; + GDL2MKKD_setObjectForKeyIMP=[GDL2MKKDClass instanceMethodForSelector:GDL2_setObjectForKeySEL]; + GDL2MKKD_removeObjectForKeyIMP=[GDL2MKKDClass instanceMethodForSelector:GDL2_removeObjectForKeySEL]; + GDL2MKKD_hasKeyIMP=(GDL2IMP_BOOL)[GDL2MKKDClass instanceMethodForSelector:GDL2_hasKeySEL]; + GDL2MKKD_indexForKeyIMP=(GDL2IMP_UINT)[GDL2MKKDClass instanceMethodForSelector:GDL2_indexForKeySEL]; + GDL2EOMKKDInitializer_indexForKeyIMP=(GDL2IMP_UINT)[GDL2EOMKKDInitializerClass instanceMethodForSelector:GDL2_indexForKeySEL]; + + GDL2EODatabaseContext_snapshotForGlobalIDIMP=[GDL2EODatabaseContextClass instanceMethodForSelector:GDL2_snapshotForGlobalIDSEL]; + + GDL2EOEditingContext_recordObjectGlobalIDIMP==[GDL2EOEditingContextClass instanceMethodForSelector:GDL2_recordObjectGlobalIDSEL]; + GDL2EOEditingContext_objectForGlobalIDIMP=[GDL2EOEditingContextClass instanceMethodForSelector:GDL2_objectForGlobalIDSEL]; + GDL2EOEditingContext_globalIDForObjectIMP=[GDL2EOEditingContextClass instanceMethodForSelector:GDL2_globalIDForObjectSEL]; + + ASSIGN(GDL2NSNumberBool_Yes,[GDL2NSNumberClass numberWithBool:YES]); + ASSIGN(GDL2NSNumberBool_No,[GDL2NSNumberClass numberWithBool:NO]); + + ASSIGN(GDL2EONull,[EONull null]); + + ASSIGN(GDL2_shellPatternCharacterSet,([NSCharacterSet characterSetWithCharactersInString:@"*?%_"])); + }; +} diff --git a/EOControl/EOSortOrdering.m b/EOControl/EOSortOrdering.m index 4703d9e..513d798 100644 --- a/EOControl/EOSortOrdering.m +++ b/EOControl/EOSortOrdering.m @@ -52,9 +52,21 @@ RCS_ID("$Id$") #include #include #include +#include @implementation EOSortOrdering ++ (void)initialize +{ + static BOOL initialized=NO; + if (!initialized) + { + initialized=YES; + + GDL2PrivInit(); + }; +}; + /** * Returns an autoreleased EOSortOrdering initilaized with key and selector. * The selector should take an id as an argument and return an @@ -176,17 +188,11 @@ compareUsingSortOrderings(id left, id right, void* vpSortOrders) { - static EONull *null = nil; NSArray *sortOrders = (NSArray *)vpSortOrders; NSComparisonResult r = NSOrderedSame; unsigned int i; unsigned int sortOrdCnt = [sortOrders count]; - if (null == nil) - { - null = [EONull null]; - } - /* Loop over all sort orderings until we have an ordering difference. */ for (i=0; (r == NSOrderedSame) && (i < sortOrdCnt); i++) { @@ -199,15 +205,15 @@ compareUsingSortOrderings(id left, NSComparisonResult (*imp)(id, SEL, id); /* Use EONull instead of nil. */ - leftVal = (leftVal != nil)?(leftVal) :(null); - rightVal = (rightVal != nil)?(rightVal):(null); + leftVal = (leftVal != nil)?(leftVal) :(GDL2EONull); + rightVal = (rightVal != nil)?(rightVal):(GDL2EONull); /* Insure that EONull is not the parameter for comparisons with other classes. */ - if (rightVal == null) + if (rightVal == GDL2EONull) { rightVal = leftVal; - leftVal = null; + leftVal = GDL2EONull; inverted = YES; } diff --git a/EOControl/GNUmakefile b/EOControl/GNUmakefile index 77f9305..5fb1856 100644 --- a/EOControl/GNUmakefile +++ b/EOControl/GNUmakefile @@ -65,7 +65,8 @@ EOMutableKnownKeyDictionary.m \ EONSAddOns.m \ EOCheapArray.m \ EOArrayDataSource.m \ -EODebug.m +EODebug.m \ +EOPriv.m libgnustep-db2control_HEADER_FILES_DIR = . libgnustep-db2control_HEADER_FILES_INSTALL_DIR = /EOControl @@ -94,7 +95,7 @@ EONSAddOns.h \ EODefines.h \ EODeprecated.h \ EOControl.h \ - +EOPriv.h DOCUMENT_NAME = EOControl EOControl_AUTOGSDOC_HEADERS = $(libgnustep-db2control_HEADER_FILES)