diff --git a/ChangeLog b/ChangeLog index 136085c..a58e21e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,89 @@ +2003-02-03 Stephane Corthesy + + * Postgres95Adaptor.m: made some changes to externalTypeNames (needs + to be reviewed completely!); avoided needless autoreleased object + * Postgres95Channel.m: avoided needless autoreleased object ; added + arg to NSDebugMLLog (should be replaced by other log macro); use + macros RETAIN, AUTORELASE; when invoking PQexec, added ending ";" to + statement (necessary for inserts, at least) + * Postgres95SQLExpression.m: replaced #import by + smaller #imports; commented out use of external type 'datetime' + (obsolete?); corrected bug in +formatValue:forAttribute: (error when + escaping special characters); overloaded + +dropTableStatementsForEntityGroup: to append CASCADE (maybe this + should be done in EOSQLExpression class?), else it is not possible to + drop tables which contain foreign key constraints; overloaded + +prepareConstraintStatementForRelationship:sourceColumns: + destinationColumns: to append DEFERRABLE INITIALLY DEFERRED (maybe this + should be done in EOSQLExpression class?) + * Postgres95Values.h: made Postgres95Values inherit from NSObject, else + ObjC runtime doesn't like it and crashes! + + * EOAdaptor.m: added #import ; corrected bug when + instantiating adaptor: class name needs to be taken exclusively from + infoDictionary, because a framework's principalClass is indeterminate + (is it?); corrected var type; added empty implementation of + EOLoginPanel class (is the method named + "administraticeConnectionDictionaryForAdaptor:" correct? Shouldn't it + be "administrativeConnectionDictionaryForAdaptor:" ??) + * EOAttribute.m: added #include ; use -[NSTimeZone name] + instead of -[NSTimeZone timeZoneName] (also on GNUstep?) + * EODatabaseChannel.m: corrected bug with macro NSDebugMLog (which + should be replaced by other macro...); in -fetchObject, added support + for raw rows (works for me, but I'm not sure whether it is totally + correct: _fetchSpecifications ivar is used nowhere!); avoided use of + autoreleased objects; in + -_selectWithFetchSpecification:editingContext:, uncommented last part + to allow support for raw rows. + * EODatabaseContext.h: added #import + * EODatabaseContext.m: #import only + when FOUNDATION_HAS_KVC? ; added declaration of -entityForGlobalID:; + replaced some retain by RETAIN; in + objectsWithFetchSpecification:editingContext:, added support for raw + rows (adapted code of non raw rows => needs refactoring); added missing + cast; corrected bug with macro NSDebugMLog (which should be replaced by + other macro...) + * EODatabaseDatasource.m: added #import ; + added declaration of + -_partialInitWithEditingContext:entityName:fetchSpecificationName: + * EOEntity.m: corrected bugs with lazy loading of ivars by using + _flags.updating, in -initWithPropertyList:owner:, and by using methods + instead of direct access to ivars; in -classProperties, corrected + problem with vars containing sometimes strings, sometimes + EOAttribute/EORelationship! (very weird way of lazy initialization... + Should be reviewed); added use of _flags.updating in -relationships and + -attributes; in -isPrimaryKeyValidInObject:, no longer tests against + [NSNull null], because [EONull null] == [NSNull null]; replaced some + retain by RETAIN; in -addAttribute:, -removeAttribute:, + -addRelationship: and -removeRelationship:, corrected nasty bug due to + mutableCopy: now we are independant of mutableCopy implementation (deep + or shallow copy), as implementation changed these last days and might + change again. Added -_setClassName: to allow modification without + calling willChange, when necessary (init); modified _setIsEdited to + test _flags.updating; in -awakeObject:fromInsertionInEditingContext:, + corrected conditions to create relationship (propagatesPrimaryKey has + nothing to do with it, whereas isMandatory is important) + * EOModel.m: added #include and #import + ; changed search strategy for models by + using NSSearchPathForDirectoriesInDomains(); replaced some retain by + RETAIN; avoided use of mutableCopy and copy + * EORelationship.m: replaced some retain by RETAIN; avoided use of + mutableCopy and copy + * EOSQLExpression.m: added declaration of +sqlExpressionWithEntity:; + added +foreignKeyConstraintStatementsForEntityGroup: and + +foreignKeyConstraintStatementsForEntityGroups:; in + +createTableStatementsForEntityGroup:, corrected call to listString; in + +schemaCreationStatementsForEntities:options:, reordered defaults[] to + allow correct SQL generation (you drop first, then create) and + corrected method to invoke for EOForeignKeyConstraintsKey; corrected + -columnTypeStringForAttribute: and -addCreateClauseForAttribute: + * EOSchemaGeneration.h: corrected documentation + * EOStoredProcedure.m: added #import + * EOUtilities.h: removed duplicate delcaration of -objectsOfClass: + * EOUtilities.m: added #import ; corrected + bug with macro NSDebugMLog (which should be replaced by other + macro...); corrected type casting; added type casting. + 2003-02-02 Mirko Viviani * EOControl/EOGenericRecord.m ([EOGenericRecord +initialize]): import diff --git a/EOAccess/EOAdaptor.m b/EOAccess/EOAdaptor.m index e935008..304d6d4 100644 --- a/EOAccess/EOAdaptor.m +++ b/EOAccess/EOAdaptor.m @@ -56,6 +56,7 @@ RCS_ID("$Id$") #import #import #import +#import #import #import @@ -224,15 +225,14 @@ NSString *EOGeneralAdaptorException = @"EOGeneralAdaptorException"; property list containing one entry whose key is adaptorClassName. It identifies the actual adaptor class from the bundle. */ - adaptorClass = [bundle principalClass]; //NSString* adaptorClassName=[infoDictionary objectForKey:@"EOAdaptorClassName"]; ?? + if(![bundle isLoaded]) + NSLog(@"Loaded %@? %@", bundle, ([bundle load]? @"YES":@"NO")); - if (adaptorClass == Nil) { - adaptorClassName = [[bundle infoDictionary] objectForKey: @"EOAdaptorClassName"]; + adaptorClassName = [[bundle infoDictionary] objectForKey: @"EOAdaptorClassName"]; - NSLog(@"adaptorClassName is %@", adaptorClassName); + NSLog(@"adaptorClassName is %@", adaptorClassName); - adaptorClass = NSClassFromString(adaptorClassName); - } + adaptorClass = NSClassFromString(adaptorClassName); if(!adaptorClass) [NSException raise: NSInvalidArgumentException @@ -438,7 +438,7 @@ NSString *EOGeneralAdaptorException = @"EOGeneralAdaptorException"; { NSString *encodingString=nil; NSDictionary *encodingsDict = [self connectionDictionary]; - NSStringEncoding *availableEncodingsArray; + const NSStringEncoding *availableEncodingsArray; int count = 0; NSStringEncoding availableEncodingValue; NSString *availableEncodingString; @@ -726,3 +726,19 @@ NSString *EOGeneralAdaptorException = @"EOGeneralAdaptorException"; } @end + +@implementation EOLoginPanel + +- (NSDictionary *) runPanelForAdaptor: (EOAdaptor *)adaptor validate: (BOOL)yn +{ + [self subclassResponsibility: _cmd]; + return nil; +} + +- (NSDictionary *) administraticeConnectionDictionaryForAdaptor: (EOAdaptor *)adaptor +{ + [self subclassResponsibility: _cmd]; + return nil; +} + +@end diff --git a/EOAccess/EOAttribute.m b/EOAccess/EOAttribute.m index fcc89b2..6ab826f 100644 --- a/EOAccess/EOAttribute.m +++ b/EOAccess/EOAttribute.m @@ -39,6 +39,7 @@ RCS_ID("$Id$") #include +#include #import #import @@ -251,7 +252,7 @@ static NSString *defaultCalendarFormat = @"%b %d %Y %H:%M"; if (_name) [propertyList setObject: _name forKey: @"name"]; if (_serverTimeZone) - [propertyList setObject: [_serverTimeZone timeZoneName] + [propertyList setObject: [_serverTimeZone name] forKey: @"serverTimeZone"]; if (_columnName) [propertyList setObject: _columnName forKey: @"columnName"]; diff --git a/EOAccess/EODatabaseChannel.m b/EOAccess/EODatabaseChannel.m index 8af64bf..3b9f988 100644 --- a/EOAccess/EODatabaseChannel.m +++ b/EOAccess/EODatabaseChannel.m @@ -277,7 +277,7 @@ RCS_ID("$Id$") if (![self isFetchInProgress]) { NSLog(@"No Fetch in progress"); - NSDebugMLog(@"No Fetch in progress"); + NSDebugMLog(@"No Fetch in progress", ""); [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: no fetch in progress", @@ -312,6 +312,10 @@ RCS_ID("$Id$") adaptorContext transactionDidCommit */ } + else if([[_fetchSpecifications lastObject] fetchesRawRows]) // Testing against only one should be enough + { + object = [NSDictionary dictionaryWithDictionary:row]; + } else { BOOL isObjectNew = YES; //TODO used to avoid double fetch. We should see how to do when isRefreshingObjects == YES @@ -680,12 +684,13 @@ RCS_ID("$Id$") { EOFetchSpecification *fetchSubEntity; - fetchSubEntity = [[fetch copy] autorelease]; + fetchSubEntity = [fetch copy]; [fetchSubEntity setEntityName: [entity name]]; [array addObjectsFromArray: [context objectsWithFetchSpecification: fetchSubEntity]]; + [fetchSubEntity release]; } } } @@ -747,7 +752,7 @@ RCS_ID("$Id$") ([self isFetchInProgress] ? "YES" : "NO")); //TODO: verify -/* +// (stephane@sente.ch) Uncommented end to allow rawRow fetches if([_databaseContext updateStrategy] == EOUpdateWithPessimisticLocking && ![[_databaseContext adaptorContext] transactionNestingLevel]) [NSException raise:NSInvalidArgumentException @@ -770,9 +775,9 @@ RCS_ID("$Id$") [_fetchSpecifications addObject:fetch]; - [self setCurrentEntity:[[_databaseContext database] - entityNamed:[fetch entityName]]];//done - [self setCurrentEditingContext:context];//done +// [self setCurrentEntity:[[_databaseContext database] +// entityNamed:[fetch entityName]]];//done +// [self setCurrentEditingContext:context];//done [self setIsLocking:([_databaseContext updateStrategy] == EOUpdateWithPessimisticLocking ? @@ -780,21 +785,21 @@ RCS_ID("$Id$") [fetch locksObjects])]; [self setIsRefreshingObjects:[fetch refreshesRefetchedObjects]]; - attributesToFetch = [_currentEntity attributesToFetch];//done +// attributesToFetch = [_currentEntity attributesToFetch];//done - EOFLOGObjectLevelArgs(@"gsdb",@"[_adaptorChannel class]: %@",[_adaptorChannel class]); - [_adaptorChannel selectAttributes:attributesToFetch - fetchSpecification:fetch - lock:_isLocking - entity:_currentEntity];//done +// EOFLOGObjectLevelArgs(@"gsdb",@"[_adaptorChannel class]: %@",[_adaptorChannel class]); +// [_adaptorChannel selectAttributes:attributesToFetch +// fetchSpecification:fetch +// lock:_isLocking +// entity:_currentEntity];//done - [_fetchProperties addObjectsFromArray:attributesToFetch]; + [_fetchProperties addObjectsFromArray:[self _propertiesToFetch]]; if(_delegateRespondsTo.didSelectObjects) [_delegate databaseContext:_databaseContext didSelectObjectsWithFetchSpecification:fetch databaseChannel:self]; -*/ + EOFLOGObjectFnStop(); } diff --git a/EOAccess/EODatabaseContext.h b/EOAccess/EODatabaseContext.h index 71cb24e..4bacba3 100644 --- a/EOAccess/EODatabaseContext.h +++ b/EOAccess/EODatabaseContext.h @@ -32,6 +32,7 @@ #import #import #import +#import #import diff --git a/EOAccess/EODatabaseContext.m b/EOAccess/EODatabaseContext.m index 4f55815..2045545 100644 --- a/EOAccess/EODatabaseContext.m +++ b/EOAccess/EODatabaseContext.m @@ -49,6 +49,11 @@ RCS_ID("$Id$") #import #import #import +#if FOUNDATION_HAS_KVC +#import +#endif + +#include #import #import @@ -98,6 +103,10 @@ NSString *EODatabaseOperationsKey = @"EODatabaseOperationsKey"; NSString *EOFailedDatabaseOperationKey = @"EOFailedDatabaseOperationKey"; +@interface EODatabaseContext(EOObjectStoreSupportPrivate) +- (id) entityForGlobalID: (EOGlobalID *)globalID; +@end + @implementation EODatabaseContext // Initializing instances @@ -186,7 +195,7 @@ static Class _contextClass = Nil; if ((self = [super init])) { - _adaptorContext = [[[database adaptor] createAdaptorContext] retain]; + _adaptorContext = RETAIN([[database adaptor] createAdaptorContext]); if (_adaptorContext == nil) { @@ -195,7 +204,7 @@ static Class _contextClass = Nil; return nil; } - _database = [database retain]; + _database = RETAIN(database); // Register this object into database [_database registerContext: self]; @@ -608,7 +617,7 @@ May raise an exception if transaction has began or if you want pessimistic lock DESTROY(_registeredChannels); - _adaptorContext = [[[[self database] adaptor] createAdaptorContext] retain]; + _adaptorContext = RETAIN([[[self database] adaptor] createAdaptorContext]); _registeredChannels = [NSMutableArray new]; EOFLOGObjectFnStopOrCond2(@"DatabaseLevel", @"EODatabaseContext"); @@ -1339,12 +1348,196 @@ userInfo = { */ rawRowKeyPaths = [fetch rawRowKeyPaths];//OK if (rawRowKeyPaths) +#if 0 { NSEmitTODO(); [self notImplemented: _cmd]; //TODO } +#else + // (stephane@sente.ch) Adapted implementation of non raw rows + { + //cachesObject + //fetchspe isDeep ret 1 + channel = [self _obtainOpenChannel]; - if ([entity cachesObjects] == YES)//OK + if (!channel) + { + NSEmitTODO(); + [self notImplemented: _cmd];//TODO + } + else + { + EOFLOGObjectLevelArgs(@"EODatabaseContext", @"channel class %@ [channel isFetchInProgress]=%s", + [channel class], + ([channel isFetchInProgress] ? "YES" : "NO")); + + NSLog(@"%@ -- %@ 0x%x: channel isFetchInProgress=%s", + NSStringFromSelector(_cmd), + NSStringFromClass([self class]), + self, + ([channel isFetchInProgress] ? "YES" : "NO")); + + //mirko: +#if 0 + if (_flags.beganTransaction == NO + && _updateStrategy == EOUpdateWithPessimisticLocking) + { + [_adaptorContext beginTransaction]; + + EOFLOGObjectLevel(@"EODatabaseContext", + @"BEGAN TRANSACTION FLAG==>YES"); + _flags.beganTransaction = YES; + } +#endif + + if ([entity isAbstractEntity] == NO) //Mirko ??? + // (stephane@sente) Should we test deepInheritanceFetch? + { + int autoreleaseSteps = 20; + int autoreleaseStep = autoreleaseSteps; + BOOL promptsAfterFetchLimit = NO; + NSAutoreleasePool *arp = nil;//To avoid too much memory use when fetching a lot of objects + int limit = 0; + + [channel selectObjectsWithFetchSpecification: fetch + editingContext: context];//OK + + EOFLOGObjectLevelArgs(@"EODatabaseContext", + @"[channel isFetchInProgress]=%s", + ([channel isFetchInProgress] ? "YES" : "NO")); + + limit = [fetch fetchLimit];//OK + promptsAfterFetchLimit = [fetch promptsAfterFetchLimit]; + + EOFLOGObjectLevel(@"EODatabaseContext", @"Will Fetch"); + + NS_DURING + { + arp = [NSAutoreleasePool new]; + EOFLOGObjectLevelArgs(@"EODatabaseContext", + @"[channel isFetchInProgress]=%s", + ([channel isFetchInProgress] ? "YES" : "NO")); + + while ((obj = [channel fetchObject])) + { + EOFLOGObjectLevel(@"EODatabaseContext", + @"fetched an object"); + EOFLOGObjectLevelArgs(@"EODatabaseContext", + @"FETCH OBJECT object=%@\n\n", + obj); + EOFLOGObjectLevelArgs(@"EODatabaseContext", + @"%d usesDistinct: %s", + num, + (usesDistinct ? "YES" : "NO")); + EOFLOGObjectLevelArgs(@"EODatabaseContext", + @"object=%@\n\n", obj); + + if (usesDistinct == YES && num) + // (stephane@sente) I thought that DISTINCT was done on server-side?!? + { + for (i = 0; i < num; i++) + { + if ([[array objectAtIndex: i] + isEqual: obj] == YES) + { + obj = nil; + break; + } + } + + if (obj == nil) + continue; + } + + EOFLOGObjectLevel(@"EODatabaseContext", + @"AFTER FETCH"); + [array addObject: obj]; + EOFLOGObjectLevelArgs(@"EODatabaseContext", + @"array count=%d", + [array count]); + num++; + + if (limit > 0 && num >= limit) + { + if ([[context messageHandler] + editingContext: context + shouldContinueFetchingWithCurrentObjectCount: num + originalLimit: limit + objectStore: self] == YES) + limit = 0;//?? + else + break; + } + + if (autoreleaseStep <= 0) + { + DESTROY(arp); + autoreleaseStep = autoreleaseSteps; + arp = [NSAutoreleasePool new]; + } + else + autoreleaseStep--; + + EOFLOGObjectLevel(@"EODatabaseContext", + @"WILL FETCH NEXT OBJECT"); + EOFLOGObjectLevelArgs(@"EODatabaseContext", + @"[channel isFetchInProgress]=%s", + ([channel isFetchInProgress] ? "YES" : "NO")); + } + + EOFLOGObjectLevel(@"EODatabaseContext", + @"finished fetch"); + EOFLOGObjectLevelArgs(@"EODatabaseContext", + @"array=%@", array); + EOFLOGObjectLevelArgs(@"EODatabaseContext", + @"step 0 channel is busy=%d", + (int)[channel isFetchInProgress]); + + [channel cancelFetch]; //OK + + EOFLOGObjectLevelArgs(@"EODatabaseContext", + @"step 1 channel is busy=%d", + (int)[channel isFetchInProgress]); + EOFLOGObjectLevelArgs(@"EODatabaseContext", @"array=%@", + array); + + //TODO + /* + handle exceptio in fetchObject + channel fetchObject + + if eception: + if ([editcontext handleError:localException]) + { + //TODO + } + else + { + //TODO + }; + */ + } + NS_HANDLER + { + EOFLOGObjectLevelArgs(@"EODatabaseContext", + @"AN EXCEPTION: %@", + localException); + + RETAIN(localException); + DESTROY(arp); + [localException autorelease]; + [localException raise]; + } + NS_ENDHANDLER; + } + } + EOFLOGObjectLevelArgs(@"EODatabaseContext", + @"step 2 channel is busy=%d", + (int)[channel isFetchInProgress]); + } +#endif + + else if ([entity cachesObjects] == YES)//OK { ///TODO MG!!! NSMutableArray *cache; @@ -1656,7 +1849,7 @@ userInfo = { @"AN EXCEPTION: %@", localException); - [localException retain]; + RETAIN(localException); DESTROY(arp); [localException autorelease]; [localException raise]; @@ -3927,9 +4120,9 @@ Raises an exception is the adaptor is unable to perform the operations. forKey: key]; } - newRow = [[[NSMutableDictionary alloc] + newRow = [[NSMutableDictionary alloc] initWithDictionary: snapshot - copyItems: NO] autorelease]; + copyItems: NO]; EOFLOGObjectLevelArgs(@"EODatabaseContext", @"newRow=%@", newRow); @@ -3958,6 +4151,7 @@ Raises an exception is the adaptor is unable to perform the operations. [databaseOpe setNewRow: newRow]; [self recordDatabaseOperation: databaseOpe]; + [newRow release]; } } NS_HANDLER @@ -5254,7 +5448,7 @@ Raises an exception is the adaptor is unable to perform the operations. { /*Class targetClass = Nil; void *extraData = NULL;*/ - EOAccessArrayFaultHandler *handler = [EOFault handlerForFault:object]; + EOAccessArrayFaultHandler *handler = (EOAccessArrayFaultHandler *)[EOFault handlerForFault:object]; EOEditingContext *context = [handler editingContext]; NSString *relationshipName= [handler relationshipName]; EOKeyGlobalID *gid = [handler sourceGlobalID]; @@ -5756,7 +5950,7 @@ Raises an exception is the adaptor is unable to perform the operations. else { NSEmitTODO(); - NSWarnLog(@"_uniqueStack is empty. May be there's no runing transaction !"); + NSWarnLog(@"_uniqueStack is empty. May be there's no runing transaction !", ""); [self notImplemented: _cmd]; //TODO } @@ -6196,11 +6390,10 @@ Raises an exception is the adaptor is unable to perform the operations. if ([_uniqueStack count] > 0) { - NSMutableDictionary *snapshotsDict = [[[_uniqueStack lastObject] - retain] autorelease]; - NSMutableDictionary *toManySnapshotsDict = [[[_uniqueArrayStack - lastObject] retain] - autorelease]; + NSMutableDictionary *snapshotsDict = [RETAIN([_uniqueStack lastObject]) autorelease]; + NSMutableDictionary *toManySnapshotsDict = [RETAIN([_uniqueArrayStack + lastObject]) + autorelease]; /*NSMutableDictionary *deleteSnapshotsDict = [[[_deleteStack lastObject] retain] autorelease];*/ //?? diff --git a/EOAccess/EODatabaseDataSource.m b/EOAccess/EODatabaseDataSource.m index 212a082..28d0613 100644 --- a/EOAccess/EODatabaseDataSource.m +++ b/EOAccess/EODatabaseDataSource.m @@ -46,6 +46,7 @@ RCS_ID("$Id$") #import #import #import +#import #import #import @@ -63,6 +64,13 @@ RCS_ID("$Id$") #import +@interface EODatabaseDataSource(Private) +- (id)_partialInitWithEditingContext: (EOEditingContext*)editingContext + entityName: (NSString*)entityName + fetchSpecificationName: (NSString*)fetchSpecificationName; +@end + + @implementation EODatabaseDataSource - initWithEditingContext: (EOEditingContext *)editingContext diff --git a/EOAccess/EODatabaseOperation.m b/EOAccess/EODatabaseOperation.m index 54918b0..cc9de6b 100644 --- a/EOAccess/EODatabaseOperation.m +++ b/EOAccess/EODatabaseOperation.m @@ -38,6 +38,7 @@ RCS_ID("$Id$") #import #import #import +#import #import #import diff --git a/EOAccess/EOEntity.m b/EOAccess/EOEntity.m index 75391a7..d92b4f0 100644 --- a/EOAccess/EOEntity.m +++ b/EOAccess/EOEntity.m @@ -42,8 +42,6 @@ RCS_ID("$Id$") #import -#import - #import #import #import @@ -99,10 +97,13 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat NSArray *array = nil; NSString *tmpString = nil; id tmpObject = nil; - + + _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,6 +153,7 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat [tmpString class], tmpString);*/ //[self setUserInfo:[tmpString propertyList]]; +// ASSIGN(_userInfo, tmpObject); [self setUserInfo: tmpObject]; } @@ -160,8 +162,11 @@ 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]]; @@ -321,7 +326,8 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat } } - [self setCreateMutableObjects: NO]; //?? TC say no, mirko yes + [self setCreateMutableObjects: NO]; //?? TC say no, mirko yes + _flags.updating = NO; } } NS_HANDLER @@ -1004,8 +1010,13 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat for (i = 0; i < count; i++) { +#if 0 NSString *classPropertyName = [classPropertiesList objectAtIndex: i]; +#else + NSString *classPropertyName = ([[classPropertiesList objectAtIndex:i] isKindOfClass:[NSString class]] ? [classPropertiesList objectAtIndex:i]:[[classPropertiesList + objectAtIndex: i] name]); +#endif id classProperty = [self attributeNamed: classPropertyName]; if (!classProperty) @@ -1144,6 +1155,7 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat _flags.relationshipsIsLazy = NO; [EOObserverCenter suppressObserverNotification]; + _flags.updating = YES; NS_DURING { @@ -1250,6 +1262,7 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat DESTROY(relationshipPLists); + _flags.updating = NO; [EOObserverCenter enableObserverNotification]; [localException raise]; } @@ -1257,6 +1270,7 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat DESTROY(relationshipPLists); + _flags.updating = NO; [EOObserverCenter enableObserverNotification]; } else @@ -1308,6 +1322,7 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat _flags.attributesIsLazy = NO; [EOObserverCenter suppressObserverNotification]; + _flags.updating = YES; NS_DURING { @@ -1447,6 +1462,7 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat NS_HANDLER { DESTROY(attributePLists); + _flags.updating = NO; [EOObserverCenter enableObserverNotification]; [localException raise]; } @@ -1454,6 +1470,7 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat DESTROY(attributePLists); + _flags.updating = NO; [EOObserverCenter enableObserverNotification]; [_attributes sortUsingSelector: @selector(eoCompareOnName:)];//Very important to have always the same order. } @@ -1704,7 +1721,7 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat NS_DURING { value = [object valueForKey: key]; - if (value == nil || value == [EONull null] || value == [NSNull null]) + if (value == nil || value == [EONull null]) isValid = NO; } NS_HANDLER @@ -1990,8 +2007,8 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat if ([self createsMutableObjects]) [(GCMutableArray *)_attributes addObject: attribute]; else - _attributes = [[[_attributes autorelease] - arrayByAddingObject: attribute] retain]; + _attributes = RETAIN([[_attributes autorelease] + arrayByAddingObject: attribute]); if (_attributesByName == nil) { @@ -2015,9 +2032,9 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat [(GCMutableArray *)_attributes removeObject: attribute]; else { - _attributes = [[_attributes autorelease] mutableCopy]; + _attributes = [[GCMutableArray alloc] initWithArray:[_attributes autorelease] copyItems:NO]; [(GCMutableArray *)_attributes removeObject: attribute]; - _attributes = [[_attributes autorelease] copy]; + _attributes = [[GCArray alloc] initWithArray:[_attributes autorelease] copyItems:NO]; } [_attributesByName removeObjectForKey: [attribute name]]; [self _setIsEdited];//To clean caches @@ -2047,8 +2064,8 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat if ([self createsMutableObjects]) [(GCMutableArray *)_relationships addObject: relationship]; else - _relationships = [[[_relationships autorelease] - arrayByAddingObject: relationship] retain]; + _relationships = RETAIN([[_relationships autorelease] + arrayByAddingObject: relationship]); [relationship setEntity: self]; [self _setIsEdited];//To clean caches @@ -2063,13 +2080,15 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat { [relationship setEntity:nil]; + if(_relationshipsByName != nil) + [_relationshipsByName removeObjectForKey:[relationship name]]; if ([self createsMutableObjects]) [(GCMutableArray *)_relationships removeObject: relationship]; else { - _relationships = [[_relationships autorelease] mutableCopy]; + _relationships = [[GCMutableArray alloc] initWithArray:[_relationships autorelease] copyItems:NO]; [(GCMutableArray *)_relationships removeObject: relationship]; - _relationships = [[_relationships autorelease] copy]; + _relationships = [[GCArray alloc] initWithArray:[_relationships autorelease] copyItems:NO]; } [self _setIsEdited];//To clean caches } @@ -2092,17 +2111,21 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat @selector(compare:)]); } -- (void)setClassName:(NSString *)name +- (void)_setClassName:(NSString *)name { - //OK - [self willChange]; - if (!name) { NSLog(@"Entity %@ has no class name. Use EOGenericRecord", [self name]); name = @"EOGenericRecord"; } ASSIGN(_className, name); +} + +- (void)setClassName:(NSString *)name +{ + //OK + [self willChange]; + [self _setClassName:name]; [self _setIsEdited]; } @@ -2560,8 +2583,8 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat if (!_classDescription) { - _classDescription = [[EOEntityClassDescription - entityClassDescriptionWithEntity: self] retain]; + _classDescription = RETAIN([EOEntityClassDescription + entityClassDescriptionWithEntity: self]); //NO ? NotifyCenter addObserver:EOEntityClassDescription selector:_eoNowMultiThreaded: name:NSWillBecomeMultiThreadedNotification object:nil } @@ -2587,13 +2610,13 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat if (_flags.createsMutableObjects) { - _attributes = [[_attributes autorelease] mutableCopy]; - _relationships = [[_relationships autorelease] mutableCopy]; + _attributes = [[GCMutableArray alloc] initWithArray:[_attributes autorelease] copyItems:NO]; + _relationships = [[GCMutableArray alloc] initWithArray:[_relationships autorelease] copyItems:NO]; } else { - _attributes = [[_attributes autorelease] copy]; - _relationships = [[_relationships autorelease] copy]; + _attributes = [[GCArray alloc] initWithArray:[_attributes autorelease] copyItems:NO]; + _relationships = [[GCArray alloc] initWithArray:[_relationships autorelease] copyItems:NO]; } NSAssert4(!_attributesToFetch @@ -3097,7 +3120,7 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat [self classProperties], [self relationships] }; - _attributesToFetch = [[GCMutableArray array] retain]; + _attributesToFetch = RETAIN([GCMutableArray array]); EOFLOGObjectLevelArgs(@"EOEntity", @"Entity %@ - _attributesToFetch %p [RC=%d]:%@", [self name], @@ -3327,6 +3350,9 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat #define AUTORELEASE_SETNIL(v) { AUTORELEASE(v); v=nil; } - (void) _setIsEdited { + if(_flags.updating) + return; + EOFLOGObjectLevelArgs(@"EOEntity", @"START entity name=%@", [self name]); NSAssert4(!_attributesToFetch @@ -3801,7 +3827,7 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString*)path } NS_HANDLER { - [localException retain]; + RETAIN(localException); NSLog(@"exception in EOEntity _parseDescription:isFormat:arguments:"); NSLog(@"exception=%@", localException); @@ -4126,6 +4152,7 @@ fromInsertionInEditingContext: (EOEditingContext *)anEditingContext } else //?? { +#if 0 BOOL propagatesPrimaryKey = [relationship propagatesPrimaryKey]; if (propagatesPrimaryKey) @@ -4210,6 +4237,28 @@ fromInsertionInEditingContext: (EOEditingContext *)anEditingContext } } } +#else + if ([relationship isMandatory]) + { + id objectTo = [object storedValueForKey: [relationship name]]; + + if (objectTo == nil) + { + EOEntity *entityTo; + + entityTo = [relationship destinationEntity]; + objectTo = [[entityTo classDescriptionForInstances] + createInstanceWithEditingContext: + anEditingContext + globalID: nil + zone: NULL]; + [anEditingContext insertObject: objectTo]; + [object addObject: objectTo + toBothSidesOfRelationshipWithKey: + [relationship name]]; + } + } +#endif } } } diff --git a/EOAccess/EOModel.m b/EOAccess/EOModel.m index 2561015..3d63d30 100644 --- a/EOAccess/EOModel.m +++ b/EOAccess/EOModel.m @@ -36,6 +36,8 @@ RCS_ID("$Id$") +#include + #import #import #import @@ -44,6 +46,7 @@ RCS_ID("$Id$") #import #import #import +#import #import #import @@ -89,10 +92,7 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification"; NSString *tmpModelName = nil; NSString *tmpPath = nil; NSBundle *bundle = nil; - NSString *paths[] = { @"~/Library/Models", - @"/LocalLibrary/Models", - @"/NextLibrary/Models", - nil }; + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSAllLibrariesDirectory, NSAllDomainsMask, YES); tmpModelName = [modelName lastPathComponent]; NSDebugMLLog(@"gsdb", @"modelName=%@ tmpModelName=%@", @@ -147,13 +147,13 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification"; if (!modelPath) { - int i; + int i, pathCount = [paths count]; - for (i = 0; !modelPath && paths[i]; i++) + for (i = 0; !modelPath && pathCount < i; i++) { - NSDebugMLLog(@"gsdb", @"Trying path:%@", paths[i]); + NSDebugMLLog(@"gsdb", @"Trying path:%@", [paths objectAtIndex:i]); - bundle = [NSBundle bundleWithPath: paths[i]]; + bundle = [NSBundle bundleWithPath: [paths objectAtIndex:i]]; modelPath = [bundle pathForResource: modelName ofType: @"eomodel"]; @@ -756,12 +756,11 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification"; _version = [[propertyList objectForKey: @"EOModelVersion"] floatValue]; - _adaptorName = [[propertyList objectForKey: @"adaptorName"] retain]; - _connectionDictionary = [[propertyList objectForKey: - @"connectionDictionary"] - retain]; - _userInfo = [[propertyList objectForKey: @"userInfo"] retain]; - _docComment = [[propertyList objectForKey: @"docComment"] retain]; + _adaptorName = RETAIN([propertyList objectForKey: @"adaptorName"]); + _connectionDictionary = RETAIN([propertyList objectForKey: + @"connectionDictionary"]); + _userInfo = RETAIN([propertyList objectForKey: @"userInfo"]); + _docComment = RETAIN([propertyList objectForKey: @"docComment"]); propListEntities = [propertyList objectForKey: @"entities"]; propListSt = [propertyList objectForKey: @"storedProcedures"]; @@ -1351,10 +1350,10 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification"; [(GCMutableArray *)_storedProcedures addObject: storedProcedure]; else { - _storedProcedures = [[[_storedProcedures autorelease] mutableCopy] + _storedProcedures = [[[GCMutableArray alloc] initWithArray:[_storedProcedures autorelease] copyItems:NO] autorelease]; [(GCMutableArray *)_storedProcedures addObject: storedProcedure]; - _storedProcedures = [_storedProcedures copy]; + _storedProcedures = [[GCArray alloc] initWithArray:_storedProcedures copyItems:NO]; } } @@ -1366,7 +1365,7 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification"; { _storedProcedures = [[_storedProcedures autorelease] mutableCopy]; [(GCMutableArray *)_storedProcedures removeObject: storedProcedure]; - _storedProcedures = [[_storedProcedures autorelease] copy]; + _storedProcedures = [[GCArray alloc] initWithArray:[_storedProcedures autorelease] copyItems:NO]; } } @@ -1543,9 +1542,9 @@ letter of each embedded word other than the first, which is upper case. Thus, _flags.createsMutableObjects = flag; if (_flags.createsMutableObjects) - _entities = [[_entities autorelease] mutableCopy]; + _entities = [[GCMutableArray alloc] initWithArray:[_entities autorelease] copyItems:NO]; else - _entities = [[_entities autorelease] copy]; + _entities = [[GCArray alloc] initWithArray:[_entities autorelease] copyItems:NO]; } } @@ -1577,7 +1576,7 @@ letter of each embedded word other than the first, which is upper case. Thus, NSDebugMLLog(@"gsdb", @"[self path]=%@", [self path]); basePath = [self path]; - [[entity retain] autorelease]; //so it won't be lost in _removeEntity + [RETAIN(entity) autorelease]; //so it won't be lost in _removeEntity NSDebugMLLog(@"gsdb", @"basePath =%@", basePath); diff --git a/EOAccess/EORelationship.m b/EOAccess/EORelationship.m index ec20527..7acf6fb 100644 --- a/EOAccess/EORelationship.m +++ b/EOAccess/EORelationship.m @@ -1474,10 +1474,10 @@ relationships. Nil if none" **/ else { if (_joins) - _joins = [[[_joins autorelease] - arrayByAddingObject: join] retain]; + _joins = RETAIN([[_joins autorelease] + arrayByAddingObject: join]); else - _joins = [[GCArray arrayWithObject: join] retain]; + _joins = RETAIN([GCArray arrayWithObject: join]); EOFLOGObjectLevelArgs(@"EORelationship", @"XXjoins %p class%@", _joins, [_joins class]); @@ -1721,7 +1721,7 @@ becomes "name", and "FIRST_NAME" becomes "firstName".*/ } else { - _joins = [[_joins autorelease] copy]; + _joins = [[GCArray alloc] initWithArray:[_joins autorelease] copyItems:NO]; EOFLOGObjectLevelArgs(@"EORelationship", @"XXjoins %p class%@", _joins, [_joins class]); diff --git a/EOAccess/EOSQLExpression.m b/EOAccess/EOSQLExpression.m index 89bb081..eaf7a7a 100644 --- a/EOAccess/EOSQLExpression.m +++ b/EOAccess/EOSQLExpression.m @@ -75,6 +75,10 @@ NSString *EOBindVariablePlaceHolderKey = @"EOBindVariablePlaceHolderKey"; NSString *EOBindVariableColumnKey = @"EOBindVariableColumnKey"; +@interface EOSQLExpression(Private) ++ (id)sqlExpressionWithEntity: (EOEntity *)entity; +@end + @implementation EOSQLExpression + (id)sqlExpressionWithEntity: (EOEntity *)entity @@ -2343,6 +2347,7 @@ All relationshipPaths in _aliasesByRelationshipPath are direct paths **/ return [self stringValue]; } +@end @implementation NSObject (EOSQLFormatting) @@ -2419,6 +2424,52 @@ NSString *EODropDatabaseKey = @"EODropDatabaseKey"; return array; } ++ (NSArray *)foreignKeyConstraintStatementsForEntityGroup:(NSArray *)entityGroup +{ + NSMutableArray *sqlExps; + NSEnumerator *relEnum; + EORelationship *rel; + EOEntity *entity; + + EOFLOGClassFnStartOrCond(@"EOSQLExpression"); + + entity = [entityGroup objectAtIndex: 0]; + sqlExps = [NSMutableArray array]; + relEnum = [[entity relationships] objectEnumerator]; + + while ((rel = [relEnum nextObject])) + { + [sqlExps addObjectsFromArray: + [self foreignKeyConstraintStatementsForRelationship: rel]]; + } + + EOFLOGClassFnStopOrCond(@"EOSQLExpression"); + + return sqlExps; +} + ++ (NSArray *)foreignKeyConstraintStatementsForEntityGroups: (NSArray *)entityGroups +{ + NSMutableArray *array; + NSEnumerator *groupsEnum; + NSArray *group; + + EOFLOGClassFnStartOrCond(@"EOSQLExpression"); + + array = [NSMutableArray arrayWithCapacity: [entityGroups count]]; + + groupsEnum = [entityGroups objectEnumerator]; + while ((group = [groupsEnum nextObject])) + { + [array addObjectsFromArray: + [self foreignKeyConstraintStatementsForEntityGroup: group]]; + } + + EOFLOGClassFnStopOrCond(@"EOSQLExpression"); + + return array; +} + // default implementation verifies that relationship joins on foreign key // of destination and calls // prepareConstraintStatementForRelationship:sourceColumns:destinationColumns: @@ -2445,7 +2496,7 @@ NSString *EODropDatabaseKey = @"EODropDatabaseKey"; [sqlExp setStatement: [NSString stringWithFormat:@"CREATE TABLE %@ (%@)", [[entityGroup objectAtIndex: 0] externalName], - [self listString]]]; + [sqlExp listString]]]; EOFLOGClassFnStopOrCond(@"EOSQLExpression"); @@ -2717,20 +2768,20 @@ struct _schema EOEntity *entity; int i, h, count; struct _schema defaults[] = { - {EOCreateTablesKey , @"YES", - @selector(createTableStatementsForEntityGroups:)}, - {EODropTablesKey , @"YES", - @selector(dropTableStatementsForEntityGroups:)}, - {EOCreatePrimaryKeySupportKey, @"YES", - @selector(primaryKeySupportStatementsForEntityGroups:)}, {EODropPrimaryKeySupportKey , @"YES", @selector(dropPrimaryKeySupportStatementsForEntityGroups:)}, + {EODropTablesKey , @"YES", + @selector(dropTableStatementsForEntityGroups:)}, + {EOCreateTablesKey , @"YES", + @selector(createTableStatementsForEntityGroups:)}, + {EOCreatePrimaryKeySupportKey, @"YES", + @selector(primaryKeySupportStatementsForEntityGroups:)}, {EOPrimaryKeyContraintsKey , @"YES", @selector(primaryKeyConstraintStatementsForEntityGroups:)}, {EOForeignKeyConstraintsKey , @"NO", - @selector(foreignKeyConstraintStatementsForRelationship:)}, + @selector(foreignKeyConstraintStatementsForEntityGroups:)}, {nil, nil}, - }; + }; // Order is important! EOFLOGClassFnStartOrCond(@"EOSQLExpression"); @@ -2779,7 +2830,6 @@ struct _schema { NSString *extType = [attribute externalType]; int precision = [attribute precision]; - int scale = [attribute scale]; EOFLOGClassFnStartOrCond(@"EOSQLExpression"); @@ -2787,12 +2837,12 @@ struct _schema { EOFLOGClassFnStopOrCond(@"EOSQLExpression"); return [NSString stringWithFormat:@"%@(%d, %d)", extType, precision, - scale]; + [attribute scale]]; } else if ([attribute width]) { EOFLOGClassFnStopOrCond(@"EOSQLExpression"); - return [NSString stringWithFormat: @"%@(%d)", extType, scale]; + return [NSString stringWithFormat: @"%@(%d)", extType, [attribute width]]; } else { @@ -2825,9 +2875,9 @@ struct _schema columnType, allowsNull]; else str = [NSString stringWithFormat: @"%@ %@", [attribute columnName], - allowsNull]; + columnType]; - [self appendItem:str toListString: _listString]; + [self appendItem:str toListString: /*_listString*/[self listString]]; // Else no chance to get inited (lazy) EOFLOGClassFnStopOrCond(@"EOSQLExpression"); } diff --git a/EOAccess/EOStoredProcedure.m b/EOAccess/EOStoredProcedure.m index f7f6527..0d0a03c 100644 --- a/EOAccess/EOStoredProcedure.m +++ b/EOAccess/EOStoredProcedure.m @@ -36,6 +36,7 @@ RCS_ID("$Id$") #import +#import #import #import @@ -99,7 +100,7 @@ RCS_ID("$Id$") NSEnumerator *enumerator; id attributePList; - _model = [owner retain]; + _model = RETAIN(owner); [self setName: [propertyList objectForKey: @"name"]]; [self setExternalName: [propertyList objectForKey: @"externalName"]]; diff --git a/EOAccess/EOUtilities.h b/EOAccess/EOUtilities.h index 7dc0938..ce74c42 100644 --- a/EOAccess/EOUtilities.h +++ b/EOAccess/EOUtilities.h @@ -74,8 +74,6 @@ extern NSString *EOMoreThanOneException; - (id)objectWithPrimaryKey: (NSDictionary*)pkDict entityNamed: (NSString*)name; -- (NSArray *)objectsOfClass: (Class)class; - - (NSArray*)rawRowsForEntityNamed: (NSString*)name qualifierFormat: (NSString*)format, ...; - (NSArray*)rawRowsMatchingValue: (id)value diff --git a/EOAccess/EOUtilities.m b/EOAccess/EOUtilities.m index e9cda63..510f2d8 100644 --- a/EOAccess/EOUtilities.m +++ b/EOAccess/EOUtilities.m @@ -41,6 +41,7 @@ RCS_ID("$Id$") #import #import #import +#import #import #import @@ -228,7 +229,7 @@ static NSString *EOMoreThanOneException = @"EOMoreThanOneException"; } NS_HANDLER { - NSDebugMLog(@"exception in EOEditingContext (EOUtilities) objectsMatchingValues:entityNamed:"); + NSDebugMLog(@"exception in EOEditingContext (EOUtilities) objectsMatchingValues:entityNamed:", ""); NSLog(@"exception in EOEditingContext (EOUtilities) objectsMatchingValues:entityNamed:"); NSDebugMLog(@"exception=%@", localException); NSLog(@"exception=%@", localException); @@ -1024,7 +1025,7 @@ connectionDictionaryOverrides: (NSDictionary *)overrides EOFLOGObjectFnStartOrCond(@"EOEditingContext"); - classDesc = (EOClassDescription *)[object classDescription]; + classDesc = [(EOGenericRecord *)object classDescription]; if ([classDesc isKindOfClass: [EOEntityClassDescription class]] == NO) [NSException raise: NSInvalidArgumentException @@ -1096,7 +1097,7 @@ connectionDictionaryOverrides: (NSDictionary *)overrides EOFLOGObjectFnStart(); - userInfo = [self userInfo]; + userInfo = (NSMutableDictionary *)[self userInfo]; if (userInfo) [userInfo setObject: modelGroup diff --git a/EOAdaptors/Postgres95/Postgres95Adaptor.m b/EOAdaptors/Postgres95/Postgres95Adaptor.m index 11c846a..21ccaa8 100644 --- a/EOAdaptors/Postgres95/Postgres95Adaptor.m +++ b/EOAdaptors/Postgres95/Postgres95Adaptor.m @@ -149,26 +149,27 @@ static int pgConnCurrentAllocated = 0; }*/ static NSString *externalTypeNames[] = { - @"bool", +#warning (stephane@sente.ch) Needs to be updated!!! + @"boolean", @"bool", @"char", @"char2", @"char4", @"char8", @"char16", @"filename", - @"date", @"reltime", @"time", @"tinterval", @"abstime", - @"float4", @"float8", + @"date", @"reltime", @"time", @"tinterval", @"abstime", @"timestamp", + @"real", @"double precision", @"float4", @"float8", @"int4", @"int2", @"oid", @"oid8", @"oidint2", @"oidint4", @"oidchar16", @"varchar", @"bpchar", - @"cid", @"tid", @"xid", + @"numeric", @"decimal", @"cid", @"tid", @"xid", nil }; static NSString *internalTypeNames[] = { - @"NSNumber", - @"NSNumber", @"NSNumber", @"NSNumber", @"NSNumber", @"NSNumber", @"NSNumber", - @"NSCalendarDate", @"NSCalendarDate", @"NSCalendarDate", @"NSCalendarDate", @"NSCalendarDate", @"NSNumber", @"NSNumber", + @"NSNumber", @"NSNumber", @"NSNumber", @"NSNumber", @"NSNumber", @"NSNumber", + @"NSCalendarDate", @"NSCalendarDate", @"NSCalendarDate", @"NSCalendarDate", @"NSCalendarDate", @"NSCalendarDate", + @"NSNumber", @"NSNumber", @"NSNumber", @"NSNumber", @"NSNumber", @"NSNumber", @"NSNumber", @"NSNumber", @"NSNumber", @"NSNumber", @"NSNumber", @"NSString", @"NSString", - @"NSDecimalNumber", @"NSDecimalNumber", @"NSDecimalNumber", + @"NSDecimalNumber", @"NSDecimalNumber", @"NSDecimalNumber", @"NSDecimalNumber", @"NSDecimalNumber", nil }; @@ -182,7 +183,7 @@ static NSString *internalTypeNames[] = { for (i = 0; externalTypeNames[i]; i++); - externalToInternalTypeMap = [[NSDictionary dictionaryWithObjects: internalTypeNames forKeys: externalTypeNames count: i] retain]; + externalToInternalTypeMap = [[NSDictionary alloc] initWithObjects: internalTypeNames forKeys: externalTypeNames count: i]; } return externalToInternalTypeMap; diff --git a/EOAdaptors/Postgres95/Postgres95Channel.m b/EOAdaptors/Postgres95/Postgres95Channel.m index e27c9ce..baf7d47 100644 --- a/EOAdaptors/Postgres95/Postgres95Channel.m +++ b/EOAdaptors/Postgres95/Postgres95Channel.m @@ -82,13 +82,14 @@ static void __dummy_function_used_for_linking(void) //verify _oidToTypeName = [[NSMutableDictionary alloc] initWithCapacity: 101]; - attr = [[[EOAttribute alloc] init] autorelease]; + attr = [[EOAttribute alloc] init]; [attr setName: @"nextval"]; [attr setColumnName: @"nextval"]; [attr setValueType: @"i"]; [attr setValueClassName: @"NSNumber"]; ASSIGN(_pkAttributeArray, [NSArray arrayWithObject: attr]); + RELEASE(attr); } return self; @@ -261,7 +262,7 @@ zone:zone if ([self advanceRow] == NO) { - NSDebugMLLog(@"gsdb", @"No Advance Row"); + NSDebugMLLog(@"gsdb", @"No Advance Row", ""); // Return nil to indicate that the fetch operation was finished if (_delegateRespondsTo.didFinishFetching) @@ -307,7 +308,7 @@ zone:zone if (PQgetisnull(_pgResult, _currentResultRow, i)) { - values[i] = [nullValue retain]; //to be compatible with others returned values + values[i] = RETAIN(nullValue); //to be compatible with others returned values } else { @@ -511,7 +512,7 @@ zone:zone //call PostgreSQLChannel numberOfAffectedRows /* Send the expression to the SQL server */ - _pgResult = PQexec(_pgConn, (char *)[[expression statement] cString]); + _pgResult = PQexec(_pgConn, (char *)[[[expression statement] stringByAppendingString:@";"] cString]); // stephane@sente.ch: We need to add ; for INSERT, at least NSDebugMLLog(@"gsdb", @"_pgResult=%p", (void*)_pgResult); if (_pgResult == NULL) @@ -575,7 +576,7 @@ zone:zone if (![self _evaluateExpression: expression withAttributes: nil]) { - NSDebugMLLog(@"gsdb", @"_evaluateExpression:withAttributes: return NO"); + NSDebugMLLog(@"gsdb", @"_evaluateExpression:withAttributes: return NO", ""); [self _cancelResults]; } else @@ -630,13 +631,13 @@ zone:zone row the large objects as Oids and to insert them with the large object file-like interface */ - nrow = [[row mutableCopy] autorelease]; + nrow = AUTORELEASE([row mutableCopy]); adaptorContext = (Postgres95Context *)[self adaptorContext]; [self _cancelResults]; //No done by WO - NSDebugMLLog(@"gsdb", @"autoBeginTransaction"); + NSDebugMLLog(@"gsdb", @"autoBeginTransaction", ""); [adaptorContext autoBeginTransaction: YES]; /*: row allKeys @@ -840,10 +841,10 @@ each key [self _evaluateExpression: sqlExpr withAttributes: attributes]; - NSDebugMLLog(@"gsdb", @"After _evaluate"); + NSDebugMLLog(@"gsdb", @"After _evaluate", ""); // NSDebugMLLog(@"gsdb",@"BB attributes=%@",_attributes); [_adaptorContext autoCommitTransaction]; - NSDebugMLLog(@"gsdb", @"After autoCommitTransaction"); + NSDebugMLLog(@"gsdb", @"After autoCommitTransaction", ""); if (_delegateRespondsTo.didSelectAttributes) [_delegate adaptorChannel: self @@ -900,13 +901,12 @@ each key if ([values count] > 0) { - mrow = [[values mutableCopyWithZone: [values zone]] autorelease]; + mrow = AUTORELEASE([values mutableCopyWithZone: [values zone]]); // Get EOAttributes involved in update operation // Modify "inversion" attributes to NSNumber type with the Oid - invAttributes = [[[NSMutableArray alloc] initWithCapacity: [mrow count]] - autorelease]; + invAttributes = AUTORELEASE([[NSMutableArray alloc] initWithCapacity: [mrow count]]); enumerator = [values keyEnumerator]; while ((attrName = [enumerator nextObject])) @@ -1219,7 +1219,7 @@ each key for (i = 0; i < colsNumber; i++) { - EOAttribute *attribute = [[EOAttribute new] autorelease]; + EOAttribute *attribute = AUTORELEASE([EOAttribute new]); NSString *externalName; NSString *valueClass = @"NSString"; NSString *valueType = nil; @@ -1296,9 +1296,9 @@ each key [[attribute entity] attributesToFetch]); } - [self setAttributesToFetch: [[[NSArray alloc] + [self setAttributesToFetch: AUTORELEASE([[NSArray alloc] initWithObjects: attributes - count: colsNumber] autorelease]]; + count: colsNumber])]; } // NSDebugMLLog(@"gsdb",@"_attributes=%@",_attributes); @@ -1316,8 +1316,7 @@ each key NSAssert(_pgConn, @"Channel not opened"); _pgResult = PQexec(_pgConn, - "SELECT tablename FROM pg_tables WHERE -pg_tables.schemaname = 'public'"); + "SELECT tablename FROM pg_tables WHERE pg_tables.schemaname = 'public'"); if (_pgResult == NULL || PQresultStatus(_pgResult) != PGRES_TUPLES_OK) @@ -1358,13 +1357,13 @@ pg_tables.schemaname = 'public'"); EOModel *model; EOEntity *entity; - model = [[[EOModel alloc] init] autorelease]; + model = AUTORELEASE([[EOModel alloc] init]); tableEnum = [tableNames objectEnumerator]; while ((table = [tableEnum nextObject])) { - entity = [[[EOEntity alloc] init] autorelease]; + entity = AUTORELEASE([[EOEntity alloc] init]); [entity setExternalName: table]; [model addEntity: entity]; } @@ -1431,11 +1430,10 @@ pg_tables.schemaname = 'public'"); string = PQgetvalue(_pgResult, _currentResultRow, 0); length = PQgetlength(_pgResult, _currentResultRow, 0); - pkValue = [[Postgres95Values newValueForBytes: string + pkValue = AUTORELEASE([Postgres95Values newValueForBytes: string length: length attribute: [_pkAttributeArray - objectAtIndex: 0]] - autorelease]; + objectAtIndex: 0]]); NSAssert(pkValue, @"no pk value"); key = [[entity primaryKeyAttributeNames] objectAtIndex: 0]; diff --git a/EOAdaptors/Postgres95/Postgres95SQLExpression.m b/EOAdaptors/Postgres95/Postgres95SQLExpression.m index b82d26e..67bcc6f 100644 --- a/EOAdaptors/Postgres95/Postgres95SQLExpression.m +++ b/EOAdaptors/Postgres95/Postgres95SQLExpression.m @@ -40,7 +40,9 @@ RCS_ID("$Id$") #import #import -#import +#import +#import +#import #import @@ -167,7 +169,7 @@ RCS_ID("$Id$") formatted = @"NULL"; } else if (([externalType isEqualToString: @"abstime"]) - || ([externalType isEqualToString: @"datetime"]) + /*|| ([externalType isEqualToString: @"datetime"])*//* stephane@sente.ch: datetime does not exist */ || ([externalType isEqualToString: @"timestamp"])) { EOFLOGObjectLevelArgs(@"EOSQLExpression", @@ -210,7 +212,7 @@ RCS_ID("$Id$") for (i = 0, dif = 0; i < length; i++) { - switch (tempString[i]) + switch (tempString[i + dif]) { case '\\': case '\'': @@ -298,5 +300,37 @@ RCS_ID("$Id$") } -@end ++ (NSArray *)dropTableStatementsForEntityGroup:(NSArray *)entityGroup +{ + // We redefine this method to add the CASCADE: it is needed to delete + // associated foreign key constraints when dropping a table. + // Q: shouldn't we move this into EOSQLExpression.m? + NSArray *newArray = nil; + EOFLOGClassFnStartOrCond(@"EOSQLExpression"); + + newArray = [NSArray arrayWithObject: + [self expressionForString: + [NSString stringWithFormat: @"DROP TABLE %@ CASCADE", + [[entityGroup objectAtIndex: 0] + externalName]]]]; + + EOFLOGClassFnStopOrCond(@"EOSQLExpression"); + + return newArray; +} + +- (void)prepareConstraintStatementForRelationship: (EORelationship *)relationship + sourceColumns: (NSArray *)sourceColumns + destinationColumns: (NSArray *)destinationColumns +{ + // We redefine this method to add "DEFERRABLE INITIALLY DEFERRED": it is needed + // to be able to insert rows into table related to other table rows, before these + // other rows have been inserted (relationship might be bidirectional, or it might + // simply be an operation order problem) + // Q: shouldn't we move this into EOSQLExpression.m? + [super prepareConstraintStatementForRelationship:relationship sourceColumns:sourceColumns destinationColumns:destinationColumns]; + ASSIGN(_statement, [_statement stringByAppendingString:@" DEFERRABLE INITIALLY DEFERRED"]); +} + +@end diff --git a/EOAdaptors/Postgres95/Postgres95Values.h b/EOAdaptors/Postgres95/Postgres95Values.h index 03e6b0d..7dc26e8 100644 --- a/EOAdaptors/Postgres95/Postgres95Values.h +++ b/EOAdaptors/Postgres95/Postgres95Values.h @@ -43,7 +43,7 @@ extern NSString *Postgres95CalendarFormat; -@interface Postgres95Values +@interface Postgres95Values:NSObject { } diff --git a/EOAdaptors/Postgres95/Postgres95Values.m b/EOAdaptors/Postgres95/Postgres95Values.m index 602e0b9..2603bf2 100644 --- a/EOAdaptors/Postgres95/Postgres95Values.m +++ b/EOAdaptors/Postgres95/Postgres95Values.m @@ -95,8 +95,7 @@ For efficiency reasons, the returned value is NOT autoreleased ! length: (int)length attribute: (EOAttribute *)attribute { - NSString *str = [NSString stringWithCString:(char *)bytes - length:length]; + NSString *str = nil; id value = nil; if ([[attribute externalType] isEqualToString: @"bool"]) @@ -107,13 +106,17 @@ For efficiency reasons, the returned value is NOT autoreleased ! return [[NSNumber alloc] initWithBool:NO]; } + str = [[NSString alloc] initWithCString:(char *)bytes length:length]; + if ([[attribute valueClassName] isEqualToString: @"NSDecimalNumber"]) - value = [[NSDecimalNumber decimalNumberWithString: str] retain]; + value = [[NSDecimalNumber alloc] initWithString: str]; else if ([[attribute valueType] isEqualToString: @"i"]) value = [[NSNumber alloc] initWithInt: [str intValue]]; else value = [[NSNumber alloc] initWithDouble: [str doubleValue]]; + [str release]; + return value; } @@ -152,10 +155,9 @@ For efficiency reasons, the returned value is NOT autoreleased ! NSString *str = [NSString stringWithCString: bytes length: length]; NSString *format = [NSCalendarDate postgres95Format]; - d = [[[NSCalendarDate alloc] initWithString: str - calendarFormat: format] - // TODO server TZ ? - retain]; + d = [[NSCalendarDate alloc] initWithString: str + calendarFormat: format]; + // TODO server TZ ? // NSDebugMLLog(@"gsdb",@"str=%@ d=%@ format=%@",str,d,format); NSDebugMLog(@"str=%@ d=%@ format=%@", str, d, format);