diff --git a/ChangeLog b/ChangeLog index 045b8c0..ba9e06c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,53 @@ +2003-03-21 Manuel Guesdon + * EOAccess/EODatabaseContext.m: + o added assert in _primaryKeyForObject: + o in -recordChangesInEditingContext test + nil/eonull on relationshipCommitedSnapshotValue and + relationshipSnapshotValue instead of only nil testing + o in -recordChangesInEditingContext fix for value changing + testing when commitedSnapshotValue is nil/EONull + + * EOAccess/EOEntity.m: + o logs + o fix in inverseRelationshipClassPropertyNames to test on + destination entity property names + * EOControl/EOClassDescription.m: + o logs + * EOControl/GNUmakefile: + o added EONSAddOns.h + * EOCOntrol/EOKeyValueCoding.m: + o fixes in NSArray -computeXXForKey: + * EOAccess/EOSQLExpression.m: + o assert in -sqlStringForKeyValueQualifier: + o -sqlStringForArrayOfQualifiers:operation: + hanlde different qualifier cases using isKindOfClass: + may probably be improved + o logs + * EOControl/EOEditingContext.m: + o fix in unprocessedInfo (invert/change swap). + * EOControl/EOQualifier.m + o -qualifierWithQualifierFormat:varargList: + raise exception if operator is unknwon + * EOControl/EOMutableKnownKeyDictionary.m: + o add precision in exception message + * EOAccess/EORelationship.m: + o more info in some logs + o fix in -_sourceRowToForeignKeyMapping for foreign keys + which are not in primaryKey. + * EOControl/EODatabaseOperation.m: + o in -setDatabaseOperator: Don't Delete a not inserted object + * EOControl/EOAccessFault.m: + o logs + o EOAccessFaultHandler: -dealloc fix: call super dealloc + o implement faultWillFire: This fix a hard memory problem + * EOControl/EOFault.m: + o -dealloc: fix possible infinite loop + o logs + * EOCheapCopyArray.m: + o ucomment retain/release/... + o fix shallowCopy for memory management. + This was causing hard memory trouble + 2003-03-12 Mirko Viviani * EOControl/EOClassDescription.m ([EOClassDescription +initialize]): diff --git a/EOAccess/EOAccessFault.m b/EOAccess/EOAccessFault.m index ad3f39d..6050264 100644 --- a/EOAccess/EOAccessFault.m +++ b/EOAccess/EOAccessFault.m @@ -51,17 +51,23 @@ RCS_ID("$Id$") #import #import - NSString *EOAccessFaultObjectNotAvailableException = @"EOAccessFaultObjectNotAvailableException"; @implementation EOAccessGenericFaultHandler +- (id)init +{ + if ((self = [super init])) + { + } + + return self; +} - (void)linkAfter: (EOAccessGenericFaultHandler *)faultHandler usingGeneration: (unsigned int)gen { _generation = gen; - _prev = faultHandler; _next = faultHandler->_next; @@ -110,7 +116,14 @@ NSString *EOAccessFaultObjectNotAvailableException = @"EOAccessFaultObjectNotAva - (void)faultWillFire: (id)object { -//TODO change le prev, met à 0 + //We will be deallocated so link previous and next together... + if (_next) + _next->_prev=_prev; + if (_prev) + _prev->_next=_next; + + _prev=nil; + _next=nil; } @end @@ -132,9 +145,10 @@ NSString *EOAccessFaultObjectNotAvailableException = @"EOAccessFaultObjectNotAva databaseContext: (EODatabaseContext *)dbcontext editingContext: (EOEditingContext *)ec { - return [[[self alloc] initWithGlobalID: globalID + EOAccessFaultHandler* handler= [[[self alloc] initWithGlobalID: globalID databaseContext: dbcontext editingContext: ec] autorelease]; + return handler; } - (id) initWithGlobalID: (EOKeyGlobalID *)globalID @@ -157,11 +171,21 @@ NSString *EOAccessFaultObjectNotAvailableException = @"EOAccessFaultObjectNotAva - (void)dealloc { - EOFLOGObjectFnStopOrCond(@"EOAccesFaultHandler"); +#ifdef DEBUG + NSDebugFLog(@"Dealloc EOAccessFaultHandler %p. ThreadID=%p", + (void*)self,(void*)objc_thread_id()); +#endif DESTROY(gid); DESTROY(databaseContext); DESTROY(editingContext); + + [super dealloc]; + +#ifdef DEBUG + NSDebugFLog(@"Dealloc EOAccessFaultHandler %p. ThreadID=%p", + (void*)self,(void*)objc_thread_id()); +#endif } - (EOKeyGlobalID *)globalID @@ -257,6 +281,15 @@ NSString *EOAccessFaultObjectNotAvailableException = @"EOAccessFaultObjectNotAva editingContext: ec] autorelease]; } +- (id)init +{ + if ((self = [super init])) + { + } + + return self; +} + - initWithSourceGlobalID: (EOKeyGlobalID *)sourceGID relationshipName: (NSString *)relName databaseContext: (EODatabaseContext *)dbcontext @@ -275,12 +308,21 @@ NSString *EOAccessFaultObjectNotAvailableException = @"EOAccessFaultObjectNotAva - (void)dealloc { +#ifdef DEBUG + NSDebugFLog(@"Dealloc EOAccessArrayFaultHandler %p. ThreadID=%p", + (void*)self,(void*)objc_thread_id()); +#endif + DESTROY(sgid); DESTROY(relationshipName); DESTROY(databaseContext); DESTROY(editingContext); [super dealloc]; +#ifdef DEBUG + NSDebugFLog(@"Stop Dealloc EOAccessArrayFaultHandler %p. ThreadID=%p", + (void*)self,(void*)objc_thread_id()); +#endif } - (EOKeyGlobalID *)sourceGlobalID diff --git a/EOAccess/EODatabaseContext.m b/EOAccess/EODatabaseContext.m index f5b449f..f6b5dca 100644 --- a/EOAccess/EODatabaseContext.m +++ b/EOAccess/EODatabaseContext.m @@ -2549,17 +2549,21 @@ nullifyAttributesInRelationship:rel sourceObject:object destinationObject:nil (s EOFLOGObjectLevelArgs(@"EODatabaseContext", @"relationshipCommitedSnapshotValue %p=%@", relationshipCommitedSnapshotValue, - relationshipCommitedSnapshotValue); + ([EOFault isFault:relationshipCommitedSnapshotValue] ? + (NSString*)@"[Fault]" + : (NSString*)relationshipCommitedSnapshotValue)); if (relationshipSnapshotValue == relationshipCommitedSnapshotValue) valuesAreEqual = YES; else if (isNilOrEONull(relationshipSnapshotValue)) valuesAreEqual = isNilOrEONull(relationshipCommitedSnapshotValue); + else if (isNilOrEONull(relationshipCommitedSnapshotValue)) + valuesAreEqual = isNilOrEONull(relationshipSnapshotValue); else if (isToMany) valuesAreEqual = [relationshipSnapshotValue - containsIdenticalObjectsWithArray: - relationshipCommitedSnapshotValue]; + containsIdenticalObjectsWithArray: + relationshipCommitedSnapshotValue]; else // ToOne bu not same object valuesAreEqual = NO; @@ -2666,7 +2670,7 @@ nullifyAttributesInRelationship:rel sourceObject:object destinationObject:nil (s { //id destinationObject=[object storedValueForKey:relationshipName]; - if (relationshipCommitedSnapshotValue) // a value was removed + if (!isNilOrEONull(relationshipCommitedSnapshotValue)) // a value was removed { EOFLOGObjectLevelArgs(@"EODatabaseContext", @"will call nullifyAttributes from source %p (class %@)", @@ -2691,7 +2695,7 @@ nullifyAttributesInRelationship:rel sourceObject:object destinationObject:nil (s relationshipCommitedSnapshotValue]; } - if (relationshipSnapshotValue) // a value was added + if (!isNilOrEONull(relationshipSnapshotValue)) // a value was added { EOFLOGObjectLevelArgs(@"EODatabaseContext", @"will call relay from source %p relname=%@", @@ -6267,13 +6271,18 @@ Raises an exception is the adaptor is unable to perform the operations. } else { - EOMutableKnownKeyDictionary *foreignKeyForSourceRow = - [relationship _foreignKeyForSourceRow: row];//{code = 1; } + EOMutableKnownKeyDictionary *foreignKeyForSourceRow = nil; EOFLOGObjectLevelArgs(@"EODatabaseContext", - @"foreignKeyForSourceRow:%@\n=%@", - foreignKeyForSourceRow, row); + @"relationship=%@ foreignKeyInDestination:%d", + [relationship name],[relationship foreignKeyInDestination]); + foreignKeyForSourceRow = [relationship _foreignKeyForSourceRow: row]; + + EOFLOGObjectLevelArgs(@"EODatabaseContext", + @"foreignKeyForSourceRow:%@\n=%@", + foreignKeyForSourceRow, row); + if (![foreignKeyForSourceRow containsObjectsNotIdenticalTo: [EONull null]]) { @@ -6576,6 +6585,7 @@ _numLocked = 0; EOFLOGObjectFnStart(); EOFLOGObjectLevelArgs(@"EODatabaseContext", @"object=%@", object); + NSAssert(!isNilOrEONull(object), @"No object"); entity = [_database entityForObject: object]; shouldGeneratePrimaryKey = [self _shouldGeneratePrimaryKeyForEntityName: @@ -6763,10 +6773,15 @@ _numLocked = 0; // get object value for the relationship id relationshipValue=[objectSnapshot valueForKey:relationshipName]; - EOFLOGObjectLevelArgs(@"EODatabaseContext", @"relationshipValue=%@", - relationshipValue); + EOFLOGObjectLevelArgs(@"EODatabaseContext", @"entity name=%@ relationship name=%@ Value=%@", + [entity name],relationshipName,relationshipValue); // get relationshipValue pk + NSAssert2(!isNilOrEONull(relationshipValue), + @"No relationshipValue for relationship %@ in objectSnapshot %@ ", + relationshipName, + objectSnapshot); + relationshipValuePK = [self _primaryKeyForObject:relationshipValue]; EOFLOGObjectLevelArgs(@"EODatabaseContext", @"relationshipValuePK=%@", relationshipValuePK); diff --git a/EOAccess/EODatabaseOperation.m b/EOAccess/EODatabaseOperation.m index cc9de6b..14baea6 100644 --- a/EOAccess/EODatabaseOperation.m +++ b/EOAccess/EODatabaseOperation.m @@ -157,6 +157,16 @@ RCS_ID("$Id$") || _databaseOperator==EODatabaseDeleteOperator) setOpe=NO; } + else if (dbOpe == EODatabaseDeleteOperator) + { + // Don't Delete a not inserted object + if (_databaseOperator==EODatabaseInsertOperator) + { + NSDebugMLog(@"Don't Delete a not inserted object: %p %@", + _object,_object); + dbOpe=EODatabaseNothingOperator; + }; + } if (setOpe) _databaseOperator = dbOpe; diff --git a/EOAccess/EOEntity.m b/EOAccess/EOEntity.m index a5ae0e0..2d9ec3c 100644 --- a/EOAccess/EOEntity.m +++ b/EOAccess/EOEntity.m @@ -101,9 +101,7 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat _flags.updating = YES; ASSIGN(_name, [propertyList objectForKey: @"name"]); -// ASSIGN(_externalName,[propertyList objectForKey: @"externalName"]); [self setExternalName: [propertyList objectForKey: @"externalName"]]; -// ASSIGN(_externalQuery, [propertyList objectForKey: @"externalQuery"]); [self setExternalQuery: [propertyList objectForKey: @"externalQuery"]]; @@ -152,8 +150,6 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat @"tmpString is not a NSString but a %@ tmpString:\n%@", [tmpString class], tmpString);*/ - //[self setUserInfo:[tmpString propertyList]]; -// ASSIGN(_userInfo, tmpObject); [self setUserInfo: tmpObject]; } @@ -162,11 +158,8 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat EOFLOGObjectLevelArgs(@"EOEntity", @"tmpObject=%@ [%@]", tmpObject, [tmpObject class]); -// ASSIGN(_internalInfo, tmpObject); [self _setInternalInfo: tmpObject]; -// ASSIGN(_docComment, [propertyList objectForKey:@"docComment"]); [self setDocComment:[propertyList objectForKey:@"docComment"]]; -// [self _setClassName:[propertyList objectForKey: @"className"]]; [self setClassName: [propertyList objectForKey: @"className"]]; [self setIsAbstractEntity: [[propertyList objectForKey: @"isAbstractEntity"] boolValue]]; @@ -1733,7 +1726,7 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat NS_DURING { value = [object valueForKey: key]; - if (value == nil || value == [EONull null]) + if (value == nil || value == [EONull null] || value == [NSNull null]) isValid = NO; } NS_HANDLER @@ -4370,17 +4363,14 @@ fromInsertionInEditingContext: (EOEditingContext *)anEditingContext //Near OK NSString *inverseName = nil; EORelationship *relationship = [_entity relationshipNamed: relationshipKey]; - NSArray *classPropertieNames = [_entity classPropertyNames]; EOEntity *parentEntity = [_entity parentEntity]; //TODO what if parentEntity EORelationship *inverseRelationship = [relationship inverseRelationship]; if (inverseRelationship) { - /* EOEntity *inverseRelationshipEntity = - [inverseRelationship entity]; - NSArray *inverseRelationshipClassProperties = - [inverseRelationshipEntity classProperties];*/ + EOEntity *inverseEntity = [inverseRelationship entity]; + NSArray *classPropertieNames = [inverseEntity classPropertyNames]; inverseName = [inverseRelationship name]; diff --git a/EOAccess/EORelationship.m b/EOAccess/EORelationship.m index 7acf6fb..2dc2005 100644 --- a/EOAccess/EORelationship.m +++ b/EOAccess/EORelationship.m @@ -246,7 +246,7 @@ RCS_ID("$Id$") { EOFLOGObjectLevelArgs(@"EORelationship", @"Unknown joinSemanticString=%@. entityName=%@ relationshipName=%@", joinSemanticString, - [owner name], + [(EOEntity*)owner name], relationshipName); NSEmitTODO(); //TODO [self notImplemented: _cmd]; //TODO @@ -257,7 +257,7 @@ RCS_ID("$Id$") if (destinationEntityName) { EOFLOGObjectLevelArgs(@"EORelationship", @"!joinSemanticString but destinationEntityName. entityName=%@ relationshipName=%@", - [owner name], + [(EOEntity*)owner name], relationshipName); NSEmitTODO(); //TODO [self notImplemented: _cmd]; //TODO @@ -266,7 +266,7 @@ RCS_ID("$Id$") deleteRuleString = [propertyList objectForKey: @"deleteRule"]; EOFLOGObjectLevelArgs(@"EORelationship", @"entityName=%@ relationshipName=%@ deleteRuleString=%@", - [owner name], + [(EOEntity*)owner name], relationshipName, deleteRuleString); @@ -276,7 +276,7 @@ RCS_ID("$Id$") deleteRuleString]; EOFLOGObjectLevelArgs(@"EORelationship", @"entityName=%@ relationshipName=%@ deleteRule=%d", - [owner name], + [(EOEntity*)owner name], relationshipName, (int)deleteRule); NSAssert2(deleteRule >= 0 && deleteRule < 4, @@ -428,68 +428,96 @@ RCS_ID("$Id$") - (void)encodeIntoPropertyList: (NSMutableDictionary *)propertyList { - //VERIFY - [propertyList setObject: [self name] - forKey: @"name"]; - - if ([self isFlattened]) + NS_DURING //Just for debugging { - NSString *definition = [self definition]; - - [propertyList setObject: definition - forKey: @"definition"]; - } - else - { - [propertyList setObject: ([self isToMany] ? @"Y" : @"N") - forKey: @"isToMany"]; - [propertyList setObject: [self destinationEntity] - forKey: @"destination"]; - } - - if ([self isMandatory]) - [propertyList setObject: @"Y" - forKey: @"isMandatory"]; - - if ([self ownsDestination]) - { - NSEmitTODO(); //TODO - [self notImplemented: _cmd]; //TODO - } - - if ([self propagatesPrimaryKey]) - { - NSEmitTODO(); //TODO - [self notImplemented: _cmd]; //TODO - } - - { - int joinsCount = [_joins count]; - - if (joinsCount > 0) + //VERIFY + [propertyList setObject: [self name] + forKey: @"name"]; + + if ([self isFlattened]) + { + NSString *definition = [self definition]; + NSAssert(definition,@"No definition"); + [propertyList setObject: definition + forKey: @"definition"]; + } + else + { + [propertyList setObject: ([self isToMany] ? @"Y" : @"N") + forKey: @"isToMany"]; + if ([self destinationEntity]) + { + NSAssert2([[self destinationEntity] name], + @"No entity name in relationship named %@ entity named %@", + [self name], + [[self entity]name]); + [propertyList setObject: [[self destinationEntity] name] // if we put entity, it loops !! + forKey: @"destination"]; + }; + } + + if ([self isMandatory]) + [propertyList setObject: @"Y" + forKey: @"isMandatory"]; + + if ([self ownsDestination]) + { + NSEmitTODO(); //TODO + } + + if ([self propagatesPrimaryKey]) + { + NSEmitTODO(); //TODO + } + { - NSMutableArray *joinsArray = [NSMutableArray array]; - int i; - - for(i = 0; i < joinsCount; i++) + int joinsCount = [_joins count]; + + if (joinsCount > 0) { - NSMutableDictionary *joinDict = [NSMutableDictionary dictionary]; - EOJoin *join = [_joins objectAtIndex: i]; + NSMutableArray *joinsArray = [NSMutableArray array]; + int i = 0; + + for(i = 0; i < joinsCount; i++) + { + NSMutableDictionary *joinDict = [NSMutableDictionary dictionary]; + EOJoin *join = [_joins objectAtIndex: i]; + + NSAssert([[join sourceAttribute] name], + @"No source attribute name"); - [joinDict setObject: [[join sourceAttribute] name] - forKey: @"sourceAttribute"]; - [joinDict setObject: [[join destinationAttribute] name] - forKey: @"destinationAttribute"]; - [joinsArray addObject: joinDict]; + [joinDict setObject: [[join sourceAttribute] name] + forKey: @"sourceAttribute"]; + + NSAssert([[join destinationAttribute] name], + @"No destination attribute name"); + [joinDict setObject: [[join destinationAttribute] name] + forKey: @"destinationAttribute"]; + + [joinsArray addObject: joinDict]; + } + + [propertyList setObject: joinsArray + forKey: @"joins"]; } - - [propertyList setObject: joinsArray - forKey: @"joins"]; + + NSAssert([self joinSemanticString], + @"No joinSemanticString"); + [propertyList setObject: [self joinSemanticString] + forKey: @"joinSemantic"]; } - - [propertyList setObject: [self joinSemanticString] - forKey: @"joinSemantic"]; - } + } + NS_HANDLER + { + NSLog(@"exception in EORelationship encodeIntoPropertyList: self=%p class=%@", + self, [self class]); + NSDebugMLog(@"exception in EORelationship encodeIntoPropertyList: self=%p class=%@", + self, [self class]); + NSLog(@"exception=%@", localException); + NSDebugMLog(@"exception=%@", localException); + [localException raise]; + } + NS_ENDHANDLER; } - (NSString *)description @@ -528,9 +556,10 @@ RCS_ID("$Id$") { NSLog(@"exception in EORelationship description: self=%p class=%@", self, [self class]); - NSLog(@"exception in EORelationship definition: self name=%@ _definitionArray=%@", - [self name], _definitionArray); + NSDebugMLog(@"exception in EORelationship description: self=%p class=%@", + self, [self class]); NSLog(@"exception=%@", localException); + NSDebugMLog(@"exception=%@", localException); [localException raise]; } @@ -2076,10 +2105,11 @@ dst entity primaryKeyAttributeNames [self notImplemented:_cmd]; // TODO } +/** Return dictionary of key/value for destination object of source row/object **/ - (NSDictionary*) _foreignKeyForSourceRow: (NSDictionary*)row { NSDictionary *foreignKey = nil; - EOMKKDSubsetMapping *sourceRowToForeignKeyMapping; + EOMKKDSubsetMapping *sourceRowToForeignKeyMapping = nil; EOFLOGObjectFnStart(); @@ -2110,30 +2140,31 @@ dst entity primaryKeyAttributeNames NSArray *sourceKeys; NSArray *destinationKeys; EOEntity *destinationEntity; - EOMKKDInitializer *primaryKeyDictionaryInitializer; + EOMKKDInitializer *destinationDictionaryInitializer = nil; EOMKKDInitializer *adaptorDictionaryInitializer; EOMKKDSubsetMapping *sourceRowToForeignKeyMapping; sourceToDestinationKeyMap = [self _sourceToDestinationKeyMap]; - EOFLOGObjectLevelArgs(@"EORelationship", @"sourceToDestinationKeyMap=%@", - sourceToDestinationKeyMap); + EOFLOGObjectLevelArgs(@"EORelationship", @"rel=%@ sourceToDestinationKeyMap=%@", + [self name], sourceToDestinationKeyMap); sourceKeys = [sourceToDestinationKeyMap objectForKey: @"sourceKeys"]; - EOFLOGObjectLevelArgs(@"EORelationship", @"sourceKeys=%@", sourceKeys); + EOFLOGObjectLevelArgs(@"EORelationship", @"rel=%@ sourceKeys=%@", + [self name], sourceKeys); destinationKeys = [sourceToDestinationKeyMap objectForKey: @"destinationKeys"]; - EOFLOGObjectLevelArgs(@"EORelationship", @"destinationKeys=%@", destinationKeys); - + EOFLOGObjectLevelArgs(@"EORelationship", @"rel=%@ destinationKeys=%@", + [self name], destinationKeys); destinationEntity = [self destinationEntity]; - primaryKeyDictionaryInitializer = [destinationEntity - _primaryKeyDictionaryInitializer]; + + destinationDictionaryInitializer = [destinationEntity _adaptorDictionaryInitializer]; EOFLOGObjectLevelArgs(@"EORelationship", @"destinationEntity named %@ primaryKeyDictionaryInitializer=%@", [destinationEntity name], - primaryKeyDictionaryInitializer); + destinationDictionaryInitializer); adaptorDictionaryInitializer = [_entity _adaptorDictionaryInitializer]; EOFLOGObjectLevelArgs(@"EORelationship",@"entity named %@ adaptorDictionaryInitializer=%@", @@ -2141,7 +2172,7 @@ dst entity primaryKeyAttributeNames adaptorDictionaryInitializer); sourceRowToForeignKeyMapping = - [primaryKeyDictionaryInitializer + [destinationDictionaryInitializer subsetMappingForSourceDictionaryInitializer: adaptorDictionaryInitializer sourceKeys: sourceKeys diff --git a/EOAccess/EOSQLExpression.m b/EOAccess/EOSQLExpression.m index eaf7a7a..e497710 100644 --- a/EOAccess/EOSQLExpression.m +++ b/EOAccess/EOSQLExpression.m @@ -1284,9 +1284,33 @@ NSString *EOBindVariableColumnKey = @"EOBindVariableColumnKey"; for (i = 0; i < count; i++) { - EOKeyValueQualifier *kvQualifier = [qualifiers objectAtIndex: i]; - NSString *tmpSqlString = [self sqlStringForKeyValueQualifier: - kvQualifier]; + NSString *tmpSqlString=nil; + + EOQualifier *qualifier = [qualifiers objectAtIndex: i]; + + // use of isKindOfClass is not very good. Improve it ? + if ([qualifier isKindOfClass:[EOKeyValueQualifier class]]) + tmpSqlString = [self sqlStringForKeyValueQualifier: + (EOKeyValueQualifier*)qualifier]; + + else if ([qualifier isKindOfClass:[EOAndQualifier class]]) + tmpSqlString=[self sqlStringForConjoinedQualifiers: + [(EOAndQualifier*)qualifier qualifiers]]; + + else if ([qualifier isKindOfClass:[EOOrQualifier class]]) + tmpSqlString=[self sqlStringForDisjoinedQualifiers: + [(EOOrQualifier*)qualifier qualifiers]]; + + else if ([qualifier isKindOfClass:[EONotQualifier class]]) + tmpSqlString=[self sqlStringForNegatedQualifier:qualifier]; + + else if ([qualifier isKindOfClass:[EOKeyComparisonQualifier class]]) + tmpSqlString=[self sqlStringForKeyComparisonQualifier:qualifier]; + + else + [NSException raise: NSInternalInconsistencyException + format: @"EOSQLExpression: Unknown qualifier class %@", + [qualifier class]]; if (tmpSqlString) { @@ -1373,6 +1397,11 @@ NSString *EOBindVariableColumnKey = @"EOBindVariableColumnKey"; EOFLOGObjectFnStart(); + NSAssert2([qualifier isKindOfClass:[EOKeyValueQualifier class]], + @"qualifier is not a EOKeyValueQualifier but a %@: %@", + [qualifier class], + qualifier); + key = [qualifier key];//OK EOFLOGObjectLevelArgs(@"EOSQLExpression", @"key=%@", key); @@ -1397,8 +1426,13 @@ NSString *EOBindVariableColumnKey = @"EOBindVariableColumnKey"; valueSQLString = [self sqlStringForValue: value attributeNamed: key];//OK - EOFLOGObjectLevelArgs(@"EOSQLExpression", @"valueSQLString=%@", - valueSQLString); + + EOFLOGObjectLevelArgs(@"EOSQLExpression", @"valueSQLString=%@ qualifier=%@ [qualifier selector]=%p %@", + valueSQLString, + qualifier, + [qualifier selector], + NSStringFromSelector([qualifier selector])); + selectorSQLString = [self sqlStringForSelector: [qualifier selector] value: value];//OK //value ?? @@ -1928,6 +1962,9 @@ else if([anAttribute isDerived] == YES) } } + EOFLOGObjectLevelArgs(@"EOSQLExpression", @"path=%@ sqlString=%@", + path, sqlString); + return sqlString; } diff --git a/EOControl/EOCheapArray.m b/EOControl/EOCheapArray.m index 678e088..9d3bd37 100644 --- a/EOControl/EOCheapArray.m +++ b/EOControl/EOCheapArray.m @@ -43,8 +43,22 @@ RCS_ID("$Id$") @implementation EOCheapCopyArray : NSArray +- (id) init +{ +#ifdef DEBUG + NSDebugFLog(@"Init EOCheapCopyArray %p", + self); +#endif + + return [super init]; +}; - (id) initWithArray: (id)array { +#ifdef DEBUG + NSDebugFLog(@"initWithArray EOCheapCopyArray %p", + self); +#endif + if ((self = [super initWithArray: array])) { } @@ -55,6 +69,11 @@ RCS_ID("$Id$") - (id) initWithObjects: (id*)objects count: (unsigned int)count { +#ifdef DEBUG + NSDebugFLog(@"initWithObjects EOCheapCopyArray %p", + self); +#endif + if (count > 0) { unsigned i; @@ -86,7 +105,10 @@ RCS_ID("$Id$") - (void) dealloc { - NSDebugMLLog(@"gsdb", @"Deallocate EOCheapCopyArray %p", self); +#ifdef DEBUG + NSDebugFLog(@"Deallocate EOCheapCopyArray %p zone=%p _contents_array=%p _count=%d _refcount=%d", + self, [self zone], _contents_array, _count, _refcount); +#endif if (_contents_array) { @@ -102,26 +124,48 @@ RCS_ID("$Id$") } NSDeallocateObject(self); + +#ifdef DEBUG + NSDebugFLog(@"Stop Dealloc EOCheapCopyArray %p. ThreadID=%p", + (void*)self,(void*)objc_thread_id()); +#endif +} + +- (id) autorelease +{ +#ifdef DEBUG + NSDebugFLog(@"autorelease EOCheapCopyArray %p. ThreadID=%p [super retainCount]=%d", + (void*)self,(void*)objc_thread_id(),[super retainCount]); +#endif + return [super autorelease]; } - (void) release { - NSDebugMLLog(@"gsdb", @"Release EOCheapCopyArray %p", self); - //TODO-NOW +#ifdef DEBUG + NSDebugFLog(@"Release EOCheapCopyArray %p. ThreadID=%p [super retainCount]=%d", + (void*)self,(void*)objc_thread_id(),[super retainCount]); +#endif + [super release]; } - (unsigned int) retainCount { - NSDebugMLLog(@"gsdb", @"retainCount EOCheapCopyArray %p", self); - //TODO-NOW - return 1; +#ifdef DEBUG + NSDebugFLog(@"retainCount EOCheapCopyArray %p. ThreadID=%p", + (void*)self,(void*)objc_thread_id()); +#endif + return [super retainCount]; + } - (id) retain { - //TODO-NOW - NSDebugMLLog(@"gsdb", @"retain EOCheapCopyArray %p", self); - return self; +#ifdef DEBUG + NSDebugFLog(@"retain EOCheapCopyArray %p. ThreadID=%p, [super retainCount]=%d", + (void*)self,(void*)objc_thread_id(),[super retainCount]); +#endif + return [super retain]; } - (id) objectAtIndex: (unsigned int)index @@ -198,8 +242,10 @@ RCS_ID("$Id$") - (void) dealloc { - NSDebugMLLog(@"gsdb", @"Deallocate EOCheapCopyArray %p", self); - +#ifdef DEBUG + NSDebugFLog(@"Deallocate EOCheapCopyMutableArray %p zone=%p _contents_array=%p _count=%d _capacity=%d", + self, [self zone], _contents_array, _count, _capacity); +#endif if (_contents_array) { #if !GS_WITH_GC @@ -214,18 +260,34 @@ RCS_ID("$Id$") DESTROY(_immutableCopy); NSDeallocateObject(self); + +#ifdef DEBUG + NSDebugFLog(@"Stop Dealloc EOCheapCopyMutableArray %p. ThreadID=%p", + (void*)self,(void*)objc_thread_id()); +#endif } - (id) shallowCopy { +#ifdef DEBUG + NSDebugFLog(@"Start shallowCopy EOCheapCopyMutableArray %p. ThreadID=%p immutableCopy=%p", + (void*)self,(void*)objc_thread_id(),_immutableCopy); +#endif //OK if (!_immutableCopy) { + // OK. It's retained for us. _immutableCopy= [[EOCheapCopyArray alloc] initWithObjects: _contents_array count: _count]; + //Next will retain for caller } + RETAIN(_immutableCopy); // Because copy return a not autoreleased object. Retain for request caller +#ifdef DEBUG + NSDebugFLog(@"Stop shallowCopy EOCheapCopyMutableArray %p. ThreadID=%p immutableCopy=%p", + (void*)self,(void*)objc_thread_id(),_immutableCopy); +#endif return _immutableCopy; } diff --git a/EOControl/EOEditingContext.m b/EOControl/EOEditingContext.m index f2d77b8..f95a20f 100644 --- a/EOControl/EOEditingContext.m +++ b/EOControl/EOEditingContext.m @@ -3052,9 +3052,9 @@ shouldContinueFetchingWithCurrentObjectCount: (unsigned)count } infoDict = [NSDictionary dictionaryWithObjectsAndKeys: - objectsForInfo[0], @"insert", + objectsForInfo[0], @"update", objectsForInfo[1], @"delete", - objectsForInfo[2], @"update", + objectsForInfo[2], @"insert", nil, nil]; NSDebugMLog(@"infoDict=%@", infoDict); diff --git a/EOControl/EOFault.m b/EOControl/EOFault.m index 65107cd..ba153c6 100644 --- a/EOControl/EOFault.m +++ b/EOControl/EOFault.m @@ -424,8 +424,18 @@ typedef struct { - (void)dealloc { +#ifdef DEBUG + NSDebugFLog(@"Dealloc EOFault %p. ThreadID=%p", + (void*)self,(void*)objc_thread_id()); +#endif [EOFault clearFault: self]; - [self dealloc]; + NSDebugMLog(@"EOFault dealloc self=%p",self); + if (![EOFault isFault:self]) // otherwise, this loop. + [self dealloc]; +#ifdef DEBUG + NSDebugFLog(@"Stop Dealloc EOFault %p. ThreadID=%p", + (void*)self,(void*)objc_thread_id()); +#endif } - (NSZone *)zone @@ -461,8 +471,6 @@ typedef struct { retval_t ret; NSInvocation *inv; - EOFLOGObjectLevelArgs(@"gsdb", @"START self=%p", self); - inv = [[[NSInvocation alloc] initWithArgframe: args selector: sel] autorelease]; @@ -470,21 +478,15 @@ typedef struct { ret = [inv returnFrame: args]; - EOFLOGObjectLevelArgs(@"gsdb", @"STOP self=%p", self); - return ret; } - (void)forwardInvocation: (NSInvocation *)invocation { - EOFLOGObjectLevelArgs(@"gsdb", @"START self=%p", self); - if ([_handler shouldPerformInvocation: invocation]) [_handler completeInitializationOfObject: self]; [invocation invoke]; - - EOFLOGObjectLevelArgs(@"gsdb", @"STOP self=%p", self); } - (unsigned int)hash diff --git a/EOControl/EOFetchSpecification.m b/EOControl/EOFetchSpecification.m index 610e7c3..6343535 100644 --- a/EOControl/EOFetchSpecification.m +++ b/EOControl/EOFetchSpecification.m @@ -77,12 +77,11 @@ RCS_ID("$Id$") return self; } -// Turbocat - (void)dealloc { #ifdef DEBUG - NSString *fmt = GSDebugMethodMsg(self, _cmd, __FILE__, __LINE__, @"FNSTOP"); - EOFLOGObjectFnStartOrCond(@"EOFetchSpecification"); + NSDebugFLog(@"Dealloc EOFetchSpecification %p. ThreadID=%p", + (void*)self,(void*)objc_thread_id()); #endif DESTROY(_qualifier); @@ -95,7 +94,8 @@ RCS_ID("$Id$") [super dealloc]; #ifdef DEBUG - EOFLOGObjectFnStopOrCondPlain(@"EOFetchSpecification", fmt); + NSDebugFLog(@"Stop Dealloc EOFetchSpecification %p. ThreadID=%p", + (void*)self,(void*)objc_thread_id()); #endif } diff --git a/EOControl/EOGenericRecord.m b/EOControl/EOGenericRecord.m index d8f4b8c..287b0de 100644 --- a/EOControl/EOGenericRecord.m +++ b/EOControl/EOGenericRecord.m @@ -199,7 +199,7 @@ static NSRecursiveLock *allGenericRecordsLock = nil; return classDescription; } -#if !FOUNDATION_HAS_KVC +//MG #if !FOUNDATION_HAS_KVC static const char _c_id[2] = { _C_ID, NULL }; @@ -619,7 +619,7 @@ static const char _c_id[2] = { _C_ID, NULL }; EOFLOGObjectFnStopCond(@"EOGenericRecordKVC"); } -#endif /* !FOUNDATION_HAS_KVC */ +//#endif /* !FOUNDATION_HAS_KVC */ /** if key is a bidirectional rel, use addObject:toBothSidesOfRelationship otherwise call takeValue:forKey: **/ - (void)smartTakeValue: (id)anObject @@ -658,7 +658,7 @@ static const char _c_id[2] = { _C_ID, NULL }; forKey: aKey]; } -#if !FOUNDATION_HAS_KVC +//MG#if !FOUNDATION_HAS_KVC - (void) takeValue: (id)anObject forKey: (NSString*)aKey { SEL sel; @@ -811,8 +811,8 @@ static const char _c_id[2] = { _C_ID, NULL }; return value; } -#else /* FOUNDATION_HAS_KVC */ - +//MG#else /* FOUNDATION_HAS_KVC */ +/* - (id) handleQueryWithUnboundKey: (NSString *)key { id value; @@ -856,8 +856,8 @@ static const char _c_id[2] = { _C_ID, NULL }; EOFLOGObjectFnStopCond(@"EOGenericRecordKVC"); } - -#endif /* FOUNDATION_HAS_KVC */ +*/ +//MG#endif /* FOUNDATION_HAS_KVC */ /** used in -decription for self toOne or toMany objects to avoid diff --git a/EOControl/EOKeyValueCoding.m b/EOControl/EOKeyValueCoding.m index 49e7914..fbce296 100644 --- a/EOControl/EOKeyValueCoding.m +++ b/EOControl/EOKeyValueCoding.m @@ -424,7 +424,7 @@ RCS_ID("$Id$") ret = [NSDecimalNumber zero]; while ((item = [arrayEnum nextObject])) - [ret decimalNumberByAdding: item]; + [ret decimalNumberByAdding: [item valueForKey:key]]; EOFLOGObjectFnStopCond(@"EOKVC"); @@ -442,7 +442,7 @@ RCS_ID("$Id$") ret = [NSDecimalNumber zero]; while ((item = [arrayEnum nextObject])) - [ret decimalNumberByAdding: item]; + [ret decimalNumberByAdding: [item valueForKey:key]]; ret = [ret decimalNumberByDividingBy: [NSDecimalNumber decimalNumberWithMantissa: [self count] @@ -471,19 +471,23 @@ RCS_ID("$Id$") { NSEnumerator *arrayEnum; NSDecimalNumber *item, *max; + id value = nil; EOFLOGObjectFnStartCond(@"EOKVC"); arrayEnum = [self objectEnumerator]; - max = item = [arrayEnum nextObject]; + item = [arrayEnum nextObject]; + value = [item valueForKey:key]; + max = value; - if (max != nil) + if (item != nil) { while ((item = [arrayEnum nextObject])) { - if ([max compare: item] == NSOrderedAscending) - max = item; + value = [item valueForKey:key]; + if ([max compare: value] == NSOrderedAscending) + max = value; } } @@ -496,18 +500,22 @@ RCS_ID("$Id$") { NSEnumerator *arrayEnum; NSDecimalNumber *item, *min; + id value = nil; EOFLOGObjectFnStartCond(@"EOKVC"); arrayEnum = [self objectEnumerator]; - min = item = [arrayEnum nextObject]; + item = [arrayEnum nextObject]; + value = [item valueForKey:key]; + min = value; - if (min != nil) + if (item != nil) { while ((item = [arrayEnum nextObject])) { - if ([min compare: item] == NSOrderedDescending) - min = item; + value = [item valueForKey:key]; + if ([min compare: value] == NSOrderedDescending) + min = value; } } @@ -602,6 +610,7 @@ RCS_ID("$Id$") return value; } +#endif /* !FOUNDATION_HAS_KVC */ //MG - (id)valueForKeyPath: (NSString*)keyPath { @@ -685,7 +694,7 @@ RCS_ID("$Id$") return value; } -#endif /* !FOUNDATION_HAS_KVC */ +//MG #endif /* !FOUNDATION_HAS_KVC */ - (id)storedValueForKeyPath: (NSString*)keyPath { diff --git a/EOControl/EOMutableKnownKeyDictionary.m b/EOControl/EOMutableKnownKeyDictionary.m index ad660e1..d48b8da 100644 --- a/EOControl/EOMutableKnownKeyDictionary.m +++ b/EOControl/EOMutableKnownKeyDictionary.m @@ -290,11 +290,11 @@ RCS_ID("$Id$") EOFLOGObjectLevelArgs(@"EOMKKD", @"sourceIndex=%d", sourceIndex); NSAssert2(destinationIndex != NSNotFound, - @"Key %@ not found in %@", + @"Destination Key %@ not found in %@", destinationKey, self); NSAssert2(sourceIndex != NSNotFound, - @"Key %@ not found in %@", + @"Source Key %@ not found in %@", sourceKey, sourceInitializer); @@ -519,6 +519,14 @@ RCS_ID("$Id$") @implementation EOMutableKnownKeyDictionary ++ (id)dictionaryFromDictionary: (NSDictionary *)dict + subsetMapping: (EOMKKDSubsetMapping *)subsetMapping +{ + return [[self newDictionaryFromDictionary: dict + subsetMapping: subsetMapping + zone: NULL] autorelease]; +} + + (id)newDictionaryFromDictionary: (NSDictionary*)dict subsetMapping: (EOMKKDSubsetMapping*)subsetMapping zone: (NSZone*)zone @@ -577,14 +585,6 @@ RCS_ID("$Id$") return newDict; } -+ (id)dictionaryFromDictionary: (NSDictionary *)dict - subsetMapping: (EOMKKDSubsetMapping *)subsetMapping -{ - return [[self newDictionaryFromDictionary: dict - subsetMapping: subsetMapping - zone: NULL] autorelease]; -} - + (id)newDictionaryWithObjects: (id*)objects arrayMapping: (id)mapping zone: (NSZone*)zone diff --git a/EOControl/EOQualifier.m b/EOControl/EOQualifier.m index a73ab37..6b22c7b 100644 --- a/EOControl/EOQualifier.m +++ b/EOControl/EOQualifier.m @@ -111,6 +111,21 @@ RCS_ID("$Id$") return nil; } +- (void)dealloc +{ +#ifdef DEBUG + NSDebugFLog(@"Dealloc EOQualifier %p. ThreadID=%p", + (void*)self,(void*)objc_thread_id()); +#endif + + [super dealloc]; + +#ifdef DEBUG + NSDebugFLog(@"Stop Dealloc EOQualifier %p. ThreadID=%p", + (void*)self,(void*)objc_thread_id()); +#endif +} + static NSString *getOperator(const char **cFormat, const char **s) { NSString *operator; @@ -468,6 +483,12 @@ static Class whichQualifier(const char **cFormat, const char **s) rightKey = getKey(&cFormat, &s, &isKeyValue, &args); operatorSelector = [EOQualifier operatorSelectorForString: operator]; + if (!operatorSelector) + [NSException raise: NSInvalidArgumentException + format: @"%@ -- %@ 0x%x: no operator or unknown operator: '%@'", + NSStringFromSelector(_cmd), + NSStringFromClass([self class]), self, + operator]; EOFLOGObjectLevelArgs(@"EOQualifier", @"leftKey=%@ operatorSelector=%s rightKey=%@ class=%@", diff --git a/EOControl/GNUmakefile b/EOControl/GNUmakefile index 945607e..2c02208 100644 --- a/EOControl/GNUmakefile +++ b/EOControl/GNUmakefile @@ -95,7 +95,8 @@ EODataSource.h \ EODetailDataSource.h \ EOUndoManager.h \ EODebug.h \ -EOControl.h +EOControl.h \ +EONSAddOns.h \ gdl2control_AUTOGSDOC_HEADERS = $(libgnustep-db2control_HEADER_FILES) diff --git a/TODO b/TODO index c6fed81..6c4e574 100644 --- a/TODO +++ b/TODO @@ -1,20 +1,5 @@ -DB Contextex -initializeObject:(id)object//<%EOGenericRecord[Payment](0x2f4f940)> - row:(NSDictionary*)row//0x2f3dae0 - entity:(EOEntity*)entity - editingContext:(EOEditingContext*)context +o Implement databaseFailedToFetchObject mechanism. + Cf Developper's guide p 121 +o Implement to-one PK to Foreign Key support + Not implemented by WO but it's really cool. -New class ? -EOAccessDeferredFaultHandler -EOSQLQualifier - -Class _EODotPathString -_string=NSString * object:0x4adb74 Description:testIt.count -_prefix=NSString * object:0x19ea920 Description:testIt -_suffix=NSString * object:0x19e1a48 Description:count - - - -http://developer.apple.com/techpubs/macosx/Cocoa/Reference/Foundation/Java/Classes/NSKeyValue.html - -http://developer.apple.com/techpubs/macosx/Cocoa/TasksAndConcepts/ProgrammingTopics/KeyValueCoding/Concepts/basicprinciples.html