gnustep-dl2-0.12.0/0000755000175000017500000000000011147475626013003 5ustar ayersayersgnustep-dl2-0.12.0/GDL2.gsdoc0000644000175000017500000000454011147065766014517 0ustar ayersayers GDL2 GDL2 - GNUstep Database Library 2

The GNUstep Database Library 2 (GDL2) is a set of libraries to map Objective-C objects to rows of relational database management systems (RDBMS). It aims to be compatible with Enterprise Objects Framework (EOF) as released with WebObjects 4.5 from Apple Inc.

GDL2 consists of the following components:

- EOControl

The fundamental abstraction library which includes many non RDBMS related extensions such as KeyValueCoding extensions and other categories. Most importantly it contains the classes which handle the coordination of object graphs namely EOEditingContext.

- EOAccess

This library implements the underlying mechanism to retrieve and store data in RDBMS. It defines the abstract classes like EOAdaptor which are subclassed to interface with concrete RDBMS implementations.

- EOInterface

This library implements classes used to synchronize UI components such as NSTextFields, NSButtons and NSTableViews with the state of objects which an EOEditingContext contains.

gnustep-dl2-0.12.0/EOAccess/0000755000175000017500000000000011147475622014424 5ustar ayersayersgnustep-dl2-0.12.0/EOAccess/EOAdaptorChannel.m0000644000175000017500000004225510645346232017715 0ustar ayersayers/** EOAdaptorChannel.m EOAdaptorChannel Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 $Revision: 25326 $ $Date: 2007-07-12 08:39:22 +0200 (Don, 12. Jul 2007) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EOAdaptorChannel.m 25326 2007-07-12 06:39:22Z ayers $") #ifdef GNUSTEP #include #include #include #include #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include "EOPrivate.h" #include "EOEntityPriv.h" NSString *EOAdaptorOperationsKey = @"EOAdaptorOperationsKey"; NSString *EOFailedAdaptorOperationKey = @"EOFailedAdaptorOperationKey"; NSString *EOAdaptorFailureKey = @"EOAdaptorFailureKey"; NSString *EOAdaptorOptimisticLockingFailure = @"EOAdaptorOptimisticLockingFailure"; @implementation EOAdaptorChannel + (EOAdaptorChannel *)adaptorChannelWithAdaptorContext: (EOAdaptorContext *)adaptorContext { return [[[self alloc] initWithAdaptorContext: adaptorContext] autorelease]; } - (id) initWithAdaptorContext: (EOAdaptorContext *)adaptorContext { if ((self = [super init])) { ASSIGN(_context, adaptorContext); [_context _channelDidInit: self]; //TODO it's _registerAdaptorChannel: } return self; } - (void)dealloc { [_context _channelWillDealloc: self]; DESTROY(_context); [super dealloc]; } - (void)openChannel { [self subclassResponsibility: _cmd]; } - (void)closeChannel { [self subclassResponsibility: _cmd]; } - (void)insertRow: (NSDictionary *)row forEntity: (EOEntity *)entity { [self subclassResponsibility: _cmd]; } - (void)updateValues: (NSDictionary *)values inRowDescribedByQualifier: (EOQualifier *)qualifier entity: (EOEntity *)entity { int rows; rows = [self updateValues: values inRowsDescribedByQualifier: qualifier entity: entity]; if(rows != 1) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: updated %d rows", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, rows]; } - (unsigned)updateValues: (NSDictionary *)values inRowsDescribedByQualifier: (EOQualifier *)qualifier entity: (EOEntity *)entity { [self subclassResponsibility: _cmd]; return 0; } - (void)deleteRowDescribedByQualifier: (EOQualifier *)qualifier entity: (EOEntity *)entity { int rows = 0; rows = [self deleteRowsDescribedByQualifier: qualifier entity: entity]; if (rows != 1) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: deleted %d rows", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, rows]; } - (unsigned)deleteRowsDescribedByQualifier: (EOQualifier *)qualifier entity: (EOEntity *)entity { [self subclassResponsibility: _cmd]; return 0; } - (void)selectAttributes: (NSArray *)attributes fetchSpecification: (EOFetchSpecification *)fetchSpecification lock: (BOOL)flag entity: (EOEntity *)entity { [self subclassResponsibility: _cmd]; } - (void)lockRowComparingAttributes: (NSArray *)attrs entity: (EOEntity *)entity qualifier: (EOQualifier *)qualifier snapshot: (NSDictionary *)snapshot { EOFetchSpecification *fetch = nil; NSDictionary *row = nil; NSEnumerator *attrsEnum = nil; EOAttribute *attr = nil; NSMutableArray *attributes = nil; BOOL isEqual = YES; EOFLOGObjectFnStart(); EOFLOGObjectLevelArgs(@"gsdb", @"attrs=%@", attrs); EOFLOGObjectLevelArgs(@"gsdb", @"entity=%@", entity); EOFLOGObjectLevelArgs(@"gsdb", @"qualifier=%@" ,qualifier); EOFLOGObjectLevelArgs(@"gsdb", @"snapshot=%@", snapshot); if (attrs) attributes = [[attrs mutableCopy] autorelease]; if(attributes == nil) attributes = [NSMutableArray array]; [attributes removeObjectsInArray: [entity primaryKeyAttributes]]; [attributes addObjectsFromArray: [entity primaryKeyAttributes]]; fetch = [EOFetchSpecification fetchSpecificationWithEntityName: [entity name] qualifier: qualifier sortOrderings: nil]; [self selectAttributes: attributes fetchSpecification: fetch lock: YES entity: entity]; row = [self fetchRowWithZone: NULL]; EOFLOGObjectLevelArgs(@"gsdb", @"row=%@", row); if(row == nil || [self fetchRowWithZone: NULL] != nil) { [NSException raise: EOGeneralAdaptorException format: @"%@ -- %@ 0x%x: cannot lock row for entity '%@' with qualifier: %@", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, [entity name], qualifier]; } attrsEnum = [attributes objectEnumerator]; while((attr = [attrsEnum nextObject])) { NSString *name; name = [attr name]; if([[row objectForKey: name] isEqual: [snapshot objectForKey:name]] == NO) { isEqual = NO; break; } } if(isEqual == NO) { [NSException raise: EOGeneralAdaptorException format: @"%@ -- %@ 0x%x: cannot lock row for entity '%@' with qualifier: %@", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, [entity name], qualifier]; } EOFLOGObjectFnStop(); } - (void)evaluateExpression: (EOSQLExpression *)expression { [self subclassResponsibility: _cmd]; } - (BOOL)isFetchInProgress { [self subclassResponsibility: _cmd]; return NO; } - (NSArray *)describeResults { [self subclassResponsibility: _cmd]; return nil; } - (NSMutableDictionary *)fetchRowWithZone: (NSZone *)zone { [self subclassResponsibility: _cmd]; return nil; } - (void)setAttributesToFetch: (NSArray *)attributes { [self subclassResponsibility: _cmd]; } - (NSArray *)attributesToFetch { [self subclassResponsibility: _cmd]; return nil; } - (void)cancelFetch { [self subclassResponsibility: _cmd]; } - (NSDictionary *)primaryKeyForNewRowWithEntity: (EOEntity *)entity { EOFLOGObjectFnStart(); EOFLOGObjectFnStop(); return nil;//no or subclass respo ? } - (NSArray *)describeTableNames { return nil; } - (NSArray *)describeStoredProcedureNames { [self subclassResponsibility: _cmd]; return nil; } - (EOModel *)describeModelWithTableNames: (NSArray *)tableNames { return nil; } - (void)addStoredProceduresNamed: (NSArray *)storedProcedureNames toModel: (EOModel *)model { [self subclassResponsibility: _cmd]; } - (void)setDebugEnabled: (BOOL)flag { _debug = flag; } - (BOOL)isDebugEnabled { return _debug; } - delegate { return _delegate; } - (void)setDelegate:delegate { _delegate = delegate; _delegateRespondsTo.willPerformOperations = [_delegate respondsToSelector: @selector(adaptorChannel:willPerformOperations:)]; _delegateRespondsTo.didPerformOperations = [_delegate respondsToSelector: @selector(adaptorChannel:didPerformOperations:exception:)]; _delegateRespondsTo.shouldSelectAttributes = [_delegate respondsToSelector: @selector(adaptorChannel:shouldSelectAttributes:fetchSpecification:lock:)]; _delegateRespondsTo.didSelectAttributes = [_delegate respondsToSelector: @selector(adaptorChannel:didSelectAttributes:fetchSpecification:lock:)]; _delegateRespondsTo.willFetchRow = [_delegate respondsToSelector: @selector(adaptorChannelWillFetchRow:)]; _delegateRespondsTo.didFetchRow = [_delegate respondsToSelector: @selector(adaptorChannel:didFetchRow:)]; _delegateRespondsTo.didChangeResultSet = [_delegate respondsToSelector: @selector(adaptorChannelDidChangeResultSet:)]; _delegateRespondsTo.didFinishFetching = [_delegate respondsToSelector: @selector(adaptorChannelDidFinishFetching:)]; _delegateRespondsTo.shouldEvaluateExpression = [_delegate respondsToSelector: @selector(adaptorChannel:shouldEvaluateExpression:)]; _delegateRespondsTo.didEvaluateExpression = [_delegate respondsToSelector: @selector(adaptorChannel:didEvaluateExpression:)]; _delegateRespondsTo.shouldExecuteStoredProcedure = [_delegate respondsToSelector: @selector(adaptorChannel:shouldExecuteStoredProcedure:withValues:)]; _delegateRespondsTo.didExecuteStoredProcedure = [_delegate respondsToSelector: @selector(adaptorChannelDidExecuteStoredProcedure:withValues:)]; _delegateRespondsTo.shouldConstructStoredProcedureReturnValues = [_delegate respondsToSelector: @selector(adaptorChannelShouldConstructStoredProcedureReturnValues:)]; _delegateRespondsTo.shouldReturnValuesForStoredProcedure = [_delegate respondsToSelector: @selector(adaptorChannel:shouldReturnValuesForStoredProcedure:)]; } - (NSMutableDictionary *)dictionaryWithObjects: (id *)objects forAttributes: (NSArray *)attributes zone: (NSZone *)zone { //OK (can be improved by calling EOMutableKnownKeyDictionary iini with objects but the order may be different EOMutableKnownKeyDictionary *dict=nil; EOAttribute *anAttribute=[attributes firstObject]; NSAssert(anAttribute, @"No attribute"); if (anAttribute) { EOEntity *entity = [anAttribute entity]; EOMKKDInitializer *initializer; int i = 0; int count = [attributes count]; // We may not have entity for direct SQL calls // We may not have entity for direct SQL calls if (entity) { //NSArray *attributesToFetch = [entity _attributesToFetch]; initializer = [entity _adaptorDictionaryInitializer]; } else { initializer = [EOMKKDInitializer initializerFromKeyArray: [attributes resultsOfPerformingSelector: @selector(name)]]; }; EOFLOGObjectLevelArgs(@"gsdb", @"\ndictionaryWithObjects:forAttributes:zone: attributes=%@ objects=%p\n", attributes,objects); NSAssert(initializer,@"No initializer"); EOFLOGObjectLevelArgs(@"gsdb", @"initializer=%@", initializer); dict = [[[EOMutableKnownKeyDictionary allocWithZone: zone] initWithInitializer:initializer] autorelease]; EOFLOGObjectLevelArgs(@"gsdb", @"dict=%@", dict); for(i = 0; i < count; i++) { EOAttribute *attribute = (EOAttribute *)[attributes objectAtIndex: i]; EOFLOGObjectLevelArgs(@"gsdb", @"Attribute=%@ value=%@", attribute, objects[i]); [dict setObject: objects[i] forKey: [attribute name]]; } } return dict; } - (EOAdaptorContext *)adaptorContext { return _context; } - (BOOL)isOpen { [self subclassResponsibility: _cmd]; return NO; } @end /* EOAdaptorChannel */ @implementation EOAdaptorChannel (EOStoredProcedures) - (void)executeStoredProcedure: (EOStoredProcedure *)storedProcedure withValues: (NSDictionary *)values { [self subclassResponsibility: _cmd]; } - (NSDictionary *)returnValuesForLastStoredProcedureInvocation { [self subclassResponsibility: _cmd]; return nil; } @end @implementation EOAdaptorChannel (EOBatchProcessing) - (void)performAdaptorOperation: (EOAdaptorOperation *)adaptorOperation { EOAdaptorContext *adaptorContext = nil; EOEntity *entity = nil; EOAdaptorOperator operator; NSDictionary *changedValues=nil; EOFLOGObjectFnStart(); adaptorContext = [self adaptorContext]; //adaptorcontext transactionNestingLevel //2fois //... EOFLOGObjectLevelArgs(@"gsdb", @"adaptorOperation=%@", adaptorOperation); entity = [adaptorOperation entity]; operator = [adaptorOperation adaptorOperator]; changedValues = [adaptorOperation changedValues]; EOFLOGObjectLevelArgs(@"gsdb", @"ad op: %d %@", operator, [entity name]); EOFLOGObjectLevelArgs(@"gsdb", @"ad op: %@ %@", [adaptorOperation changedValues], [adaptorOperation qualifier]); NS_DURING switch(operator) { case EOAdaptorLockOperator: EOFLOGObjectLevel(@"gsdb", @"EOAdaptorLockOperator"); [self lockRowComparingAttributes: [adaptorOperation attributes] entity: entity qualifier: [adaptorOperation qualifier] snapshot: changedValues]; break; case EOAdaptorInsertOperator: EOFLOGObjectLevel(@"gsdb", @"EOAdaptorInsertOperator"); /* //self adaptorContext //adaptorcontext transactionNestingLevel NSArray* attributes=[entity attributes]; forech: externaltype name PostgreSQLExpression initWithEntity: //called from ??: expr setUseAliases:NO prepareInsertExpressionWithRow:changedValues [expr staement]; */ [self insertRow: [adaptorOperation changedValues] forEntity: entity]; break; case EOAdaptorUpdateOperator: EOFLOGObjectLevel(@"gsdb", @"EOAdaptorUpdateOperator"); //OK [self updateValues: [adaptorOperation changedValues] inRowDescribedByQualifier: [adaptorOperation qualifier] entity: entity]; break; case EOAdaptorDeleteOperator: EOFLOGObjectLevel(@"gsdb", @"EOAdaptorDeleteOperator"); [self deleteRowDescribedByQualifier: [adaptorOperation qualifier] entity: entity]; break; case EOAdaptorStoredProcedureOperator: EOFLOGObjectLevel(@"gsdb", @"EOAdaptorStoredProcedureOperator"); [self executeStoredProcedure: [adaptorOperation storedProcedure] withValues: [adaptorOperation changedValues]]; break; case EOAdaptorUndefinedOperator: EOFLOGObjectLevel(@"gsdb", @"EOAdaptorUndefinedOperator"); default: [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: Operator %d is not defined", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, (int)operator]; break; } NS_HANDLER { NSDebugMLog(@"EXCEPTION %@", localException); [adaptorOperation setException: localException]; [localException raise]; } NS_ENDHANDLER; //end EOFLOGObjectFnStop(); } - (void)performAdaptorOperations: (NSArray *)adaptorOperations { int i = 0; int count = 0; EOFLOGObjectFnStart(); count=[adaptorOperations count]; for(i = 0; i < count; i++) { EOAdaptorOperation *operation = [adaptorOperations objectAtIndex:i]; NS_DURING [self performAdaptorOperation: operation]; NS_HANDLER { NSException *exp = nil; NSMutableDictionary *userInfo = nil; EOAdaptorOperator operator = 0; NSDebugMLog(@"EXCEPTION %@", localException); operator = [operation adaptorOperator]; userInfo = [NSMutableDictionary dictionaryWithCapacity: 3]; [userInfo setObject: adaptorOperations forKey: EOAdaptorOperationsKey]; [userInfo setObject: operation forKey: EOFailedAdaptorOperationKey]; if(operator == EOAdaptorLockOperator || operator == EOAdaptorUpdateOperator) [userInfo setObject: EOAdaptorOptimisticLockingFailure forKey: EOAdaptorFailureKey]; exp = [NSException exceptionWithName: EOGeneralAdaptorException reason: [NSString stringWithFormat:@"%@ -- %@ 0x%x: failed with exception name:%@ reason:\"%@\"", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, [localException name], [localException reason]] userInfo: userInfo]; [exp raise]; } NS_ENDHANDLER; } EOFLOGObjectFnStop(); } @end gnustep-dl2-0.12.0/EOAccess/EOSQLExpressionPriv.h0000644000175000017500000000341210645346232020375 0ustar ayersayers/* -*-objc-*- EOSQLExpression.h Copyright (C) 2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: Mars 2002 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOSQLExpressionPriv_h__ #define __EOSQLExpressionPriv_h__ #include #include @class NSString; @class EOEntity; @interface EOSQLExpression (EOSQLExpressionPrivate) - (EOEntity *)_rootEntityForExpression; - (NSString*) _aliasForRelationshipPath:(NSString*)relationshipPath; - (NSString*) _flattenRelPath: (NSString*)relationshipPath entity: (EOEntity*)entity; - (NSString *)_sqlStringForJoinSemantic: (EOJoinSemantic)joinSemantic matchSemantic: (int)param1; - (NSString*) _aliasForRelatedAttribute: (EOAttribute*)attribute relationshipPath: (NSString*)relationshipPath; - (id)_entityForRelationshipPath: (id)param0 origin: (id)param1; @end #endif /* __EOSQLExpressionPriv_h__ */ gnustep-dl2-0.12.0/EOAccess/EOModel.h0000644000175000017500000001211110764015646016055 0ustar ayersayers/* -*-objc-*- EOModel.h Copyright (C) 2000-2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOModel_h__ #define __EOModel_h__ #ifdef GNUSTEP #include #else #include #endif #include #include @class NSMutableArray; @class NSArray; @class NSDictionary; @class NSNotification; @class EOEntity; @class EOAttribute; @class EOModelGroup; @class EOStoredProcedure; @interface EOModel : NSObject { NSString *_name; NSString *_path; NSString *_adaptorName; NSString *_adaptorClassName; float _version; NSDictionary *_connectionDictionary; NSDictionary *_userInfo; NSDictionary * _internalInfo; NSString *_docComment; void *_entitiesByClass; /* Garbage collectable objects */ EOModelGroup *_group; NSArray *_entities; NSMutableDictionary *_entitiesByName; NSMutableArray *_storedProcedures; NSMutableDictionary *_subEntitiesCache; //NSMutableDictionary *_prototypesByName; struct { BOOL unused:1; BOOL errors:1; } _flags; } + (EOModel *)model; /** Getting the filename **/ - (NSString *)path; /** Getting the name **/ - (NSString *)name; - (NSString *)adaptorName; - (NSString *)adaptorClassName; /** Using entities **/ - (EOEntity *)entityNamed: (NSString *)name; - (NSArray *)entities; - (NSArray *)entityNames; - (NSArray *)storedProcedureNames; - (EOStoredProcedure *)storedProcedureNamed: (NSString *)name; - (NSArray *)storedProcedures; /** Getting an object's entity **/ - (EOEntity *)entityForObject: (id)object; /** Accessing the connection dictionary **/ - (NSDictionary *)connectionDictionary; /** Accessing the user dictionary **/ - (NSDictionary *)userInfo; /** Accessing documentation comments **/ - (NSString *)docComment; - (EOModelGroup *)modelGroup; - (EOAttribute *)prototypeAttributeNamed: (NSString *)attributeName; @end @interface EOModel (EOModelFileAccess) + (EOModel *)modelWithContentsOfFile: (NSString *)path; - (id)initWithContentsOfFile: (NSString *)path; - (void)writeToFile: (NSString *)path; @end @interface EOModel (EOModelPropertyList) - (id)initWithTableOfContentsPropertyList: (NSDictionary *)tableOfContents path: (NSString *)path; - (void)encodeTableOfContentsIntoPropertyList: (NSMutableDictionary *)propertyList; - (void)encodeIntoPropertyList: (NSMutableDictionary *)propertyList; - (void)awakeWithPropertyList: (NSDictionary *)propertyList; - (id)initWithPropertyList: (NSDictionary *)propertyList owner: (id)owner; @end @interface EOModel (EOModelHidden) - (void)_resetPrototypeCache; - (BOOL)isPrototypesEntity: (id)param0; - (void)_classDescriptionNeeded: (NSNotification *)notification; - (id)_instantiatedEntities; - (void)_setPath: (NSString *)path; - (EOEntity *)_entityForClass: (Class)aClass; - (id)_childrenForEntityNamed: (id)param0; - (void)_registerChild: (id)param0 forParent: (id)param1; - (void)_setInheritanceLinks: (id)param0; - (void)_removeEntity: (EOEntity *)entity; - (EOEntity *)_addEntityWithPropertyList: (NSDictionary *)propertyList; - (void)_addFakeEntityWithPropertyList: (NSDictionary *)propertyList; - (id)_addEntity: (EOEntity *)entity; - (void)_setEntity: (id)entity forEntityName: (NSString *)entityName className: (NSString *)className; @end @interface EOModel (EOModelEditing) /* Accessing the adaptor bundle */ - (void)setName: (NSString *)name; - (void)setAdaptorName: (NSString *)adaptorName; - (void)setConnectionDictionary: (NSDictionary *)connectionDictionary; - (void)setUserInfo: (NSDictionary *)userInfo; - (void)addEntity: (EOEntity *)entity; - (void)removeEntity: (EOEntity *)entity; - (void)removeEntityAndReferences: (EOEntity *)entity; - (void)addStoredProcedure: (EOStoredProcedure *)storedProcedure; - (void)removeStoredProcedure: (EOStoredProcedure *)storedProcedure; - (void)setModelGroup: (EOModelGroup *)group; - (void)loadAllModelObjects; /* Checking references */ - (NSArray *)referencesToProperty: (id)property; - (NSArray *)externalModelsReferenced; @end @interface EOModel (EOModelBeautifier) - (void)beautifyNames; @end GDL2ACCESS_EXPORT NSString *EOEntityLoadedNotification; #endif /* __EOModel_h__ */ gnustep-dl2-0.12.0/EOAccess/EODatabase.h0000644000175000017500000000654310645346232016531 0ustar ayersayers/* -*-objc-*- EODatabase.h Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: Jun 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EODatabase_h__ #define __EODatabase_h__ #ifdef GNUSTEP #include #else #include #endif #include @class NSArray; @class NSMutableArray; @class NSDictionary; @class NSMutableDictionary; @class NSString; @class EOAdaptor; @class EOModel; @class EOEntity; @class EODatabaseContext; @class EOGlobalID; @class EOEditingContext; GDL2ACCESS_EXPORT NSString *EOGeneralDatabaseException; GDL2ACCESS_EXPORT NSTimeInterval EODistantPastTimeInterval; @interface EODatabase : NSObject { NSMutableArray *_registeredContexts; NSMutableDictionary *_snapshots; NSMutableArray *_models; NSMutableDictionary *_entityCache; EOAdaptor *_adaptor; NSMutableDictionary *_toManySnapshots; } + (EODatabase *)databaseWithModel: (EOModel *)model; - (id)initWithAdaptor: (EOAdaptor *)adaptor; - (id)initWithModel: (EOModel *)model; - (NSArray *)registeredContexts; - (void)registerContext: (EODatabaseContext *)context; - (void)unregisterContext: (EODatabaseContext *)context; - (EOAdaptor *)adaptor; - (void)addModel: (EOModel *)model; - (void)removeModel: (EOModel *)model; - (BOOL)addModelIfCompatible: (EOModel *)model; - (NSArray *)models; - (EOEntity *)entityNamed: (NSString *)entityName; - (EOEntity *)entityForObject: (id)object; - (NSArray *)resultCacheForEntityNamed: (NSString *)name; - (void)setResultCache: (NSArray *)cache forEntityNamed: (NSString *)name; - (void)invalidateResultCacheForEntityNamed: (NSString *)name; - (void)invalidateResultCache; - (void)handleDroppedConnection; @end @interface EODatabase (EOUniquing) - (void)recordSnapshot: (NSDictionary *)snapshot forGlobalID: (EOGlobalID *)gid; - (NSDictionary *)snapshotForGlobalID: (EOGlobalID *)gid after: (NSTimeInterval)ti; - (NSDictionary *)snapshotForGlobalID: (EOGlobalID *)gid; - (void)recordSnapshot: (NSArray *)gids forSourceGlobalID: (EOGlobalID *)gid relationshipName: (NSString *)name; - (NSArray *)snapshotForSourceGlobalID: (EOGlobalID *)gid relationshipName: (NSString *)name; - (void)forgetSnapshotForGlobalID: (EOGlobalID *)gid; - (void)forgetSnapshotsForGlobalIDs: (NSArray *)gids; - (void)forgetAllSnapshots; - (void)recordSnapshots: (NSDictionary *)snapshots; - (void)recordToManySnapshots: (NSDictionary *)snapshots; - (NSDictionary *)snapshots; @end #endif /* __EODatabase_h__ */ gnustep-dl2-0.12.0/EOAccess/EOStoredProcedure.m0000644000175000017500000001460411022071506020125 0ustar ayersayers/** EOStoredProcedure.m EOStoredProcedure Class Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 $Revision: 26594 $ $Date: 2008-06-06 01:14:14 +0200 (Fre, 06. Jun 2008) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EOStoredProcedure.m 26594 2008-06-05 23:14:14Z ratmice $") #ifdef GNUSTEP #include #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #endif #include #include #include #include #include @implementation EOStoredProcedure - (EOStoredProcedure *)initWithName:(NSString *)name { self = [super init]; [self setName:name]; _userInfo = [NSDictionary new]; _internalInfo = [NSDictionary new]; return self; } + (EOStoredProcedure *)storedProcedureWithPropertyList: (NSDictionary *)propertyList owner: (id)owner { return [[[self alloc] initWithPropertyList: propertyList owner: owner] autorelease]; } - (id)initWithPropertyList: (NSDictionary *)propertyList owner: (id)owner { NSArray *array; NSEnumerator *enumerator; id attributePList; _model = owner; [self setName: [propertyList objectForKey: @"name"]]; [self setExternalName: [propertyList objectForKey: @"externalName"]]; [self setUserInfo: [propertyList objectForKey: @"userInfo"]]; if (!_userInfo) [self setUserInfo:[propertyList objectForKey:@"userInfo"]]; array = [propertyList objectForKey:@"arguments"]; if (!array) { array = [propertyList objectForKey:@"attributes"]; if (array) { NSLog(@"warning found 'attributes' key in property list you should" @"fix your model files to use the 'arguments' key!!"); } } if ([array count]) { _arguments = [[NSMutableArray alloc] initWithCapacity: [array count]]; enumerator = [array objectEnumerator]; while ((attributePList = [enumerator nextObject])) { EOAttribute *attribute = [EOAttribute attributeWithPropertyList: attributePList owner: self]; [attribute awakeWithPropertyList: attributePList]; [(NSMutableArray *)_arguments addObject: attribute]; } } return self; } - (void)awakeWithPropertyList: (NSDictionary *)propertyList { NSEnumerator *argsEnum; EOAttribute *attribute; argsEnum = [_arguments objectEnumerator]; while ((attribute = [argsEnum nextObject])) [attribute awakeWithPropertyList: propertyList]; } - (void)encodeIntoPropertyList: (NSMutableDictionary *)propertyList { unsigned i, count; if (_name) { [propertyList setObject: _name forKey: @"name"]; } if (_externalName) { [propertyList setObject: _externalName forKey: @"externalName"]; } if (_userInfo) { [propertyList setObject: _userInfo forKey: @"userInfo"]; } if ((count = [_arguments count])) { NSMutableArray *attributesPList = [NSMutableArray arrayWithCapacity: count]; for (i = 0; i < count; i++) { NSMutableDictionary *attributePList = [NSMutableDictionary dictionary]; EOAttribute *attribute = [_arguments objectAtIndex: i]; [attribute encodeIntoPropertyList: attributePList]; [attributesPList addObject: attributePList]; } [propertyList setObject: attributesPList forKey: @"arguments"]; } } - (NSString*) description { NSMutableDictionary *plist; plist = [NSMutableDictionary dictionaryWithCapacity: 6]; [self encodeIntoPropertyList: plist]; return [plist description]; } - (NSString *)name { return _name; } - (NSString *)externalName { return _externalName; } - (EOModel *)model { return _model; } - (NSArray *)arguments { return _arguments; } - (NSDictionary *)userInfo { return _userInfo; } - (void)setName: (NSString *)name { [self willChange]; ASSIGNCOPY(_name, name); } - (void)setExternalName: (NSString *)name { [self willChange]; ASSIGNCOPY(_externalName, name); } - (void)setArguments: (NSArray *)arguments { [self willChange]; ASSIGNCOPY(_arguments, arguments); } - (void)setUserInfo: (NSDictionary *)dictionary { [self willChange]; ASSIGN(_userInfo, dictionary); } @end @implementation EOStoredProcedure (EOModelBeautifier) - (void)beautifyName { NSArray *listItems; NSString *newString = [NSMutableString string]; NSString *tmpString; unsigned anz, i; EOFLOGObjectFnStartOrCond2(@"ModelingClasses", @"EOStoredProcedure"); if ((_name) && ([_name length] > 0)) { listItems = [_name componentsSeparatedByString: @"_"]; tmpString = [listItems objectAtIndex: 0]; tmpString = [tmpString lowercaseString]; newString = [newString stringByAppendingString: tmpString]; anz = [listItems count]; for (i = 1; i < anz; i++) { tmpString = [listItems objectAtIndex: i]; tmpString = [tmpString capitalizedString]; newString = [newString stringByAppendingString: tmpString]; } NS_DURING [self setName: newString]; NS_HANDLER NSLog(@"%@ in Class: EOStoredProcedure , Method: beautifyName >> error : %@", [localException name], [localException reason]); NS_ENDHANDLER; } EOFLOGObjectFnStopOrCond2(@"ModelingClasses", @"EOStoredProcedure"); } @end @implementation EOStoredProcedure (privat) - (void)_setIsEdited { } @end gnustep-dl2-0.12.0/EOAccess/EOSQLQualifier.m0000644000175000017500000003416610745373063017340 0ustar ayersayers/** EOSQLQualifier.m EOSQLQualifier Class Copyright (C) 2002,2003,2004,2005 Free Software Foundation, Inc. Author: Manuel Guesdon Date: February 2002 $Revision: 25994 $ $Date: 2008-01-22 14:57:07 +0100 (Die, 22. Jän 2008) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EOSQLQualifier.m 25994 2008-01-22 13:57:07Z ayers $") #include #include #ifdef GNUSTEP #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include "EOPrivate.h" #include "EOEntityPriv.h" @implementation EOSQLQualifier + (EOQualifier *)qualifierWithQualifierFormat: (NSString *)format, ... { NSEmitTODO(); //TODO [self notImplemented: _cmd]; //TODO return nil; } - (id)initWithEntity: (EOEntity *)entity qualifierFormat: (NSString *)qualifierFormat, ... { NSEmitTODO(); //TODO [self notImplemented: _cmd]; //TODO return nil; } - (EOQualifier *)schemaBasedQualifierWithRootEntity:(EOEntity *)entity { [self notImplemented: _cmd]; return nil; } - (NSString *)sqlStringForSQLExpression:(EOSQLExpression *)sqlExpression { [self notImplemented: _cmd]; return nil; } @end @implementation EOAndQualifier (EOQualifierSQLGeneration) - (NSString *)sqlStringForSQLExpression: (EOSQLExpression *)sqlExpression { //OK? //Ayers: Review (This looks correct, time to cleanup.) return [sqlExpression sqlStringForConjoinedQualifiers: _qualifiers]; /* //TODO finish to add sqlExpression NSEnumerator *qualifiersEnum=nil; EOQualifier *qualifier=nil; NSMutableString *sqlString = nil; qualifiersEnum = [_qualifiers objectEnumerator]; while ((qualifier = [qualifiersEnum nextObject])) { if (!sqlString) { sqlString = [NSMutableString stringWithString: [(id )qualifier sqlStringForSQLExpression:sqlExpression]]; } else { [sqlString appendFormat:@" %@ %@", @"AND", [(id )qualifier sqlStringForSQLExpression:sqlExpression]]; } } return sqlString; */ } - (EOQualifier *)schemaBasedQualifierWithRootEntity: (EOEntity *)entity { EOQualifier *returnedQualifier = self; int qualifierCount = 0; BOOL atLeastOneDifferentQualifier = NO; // YES if we find a changed qualifier EOFLOGObjectFnStart(); qualifierCount = [_qualifiers count]; if (qualifierCount > 0) { NSMutableArray *qualifiers = [NSMutableArray array]; int i; for (i = 0; i < qualifierCount; i++) { EOQualifier *qualifier = [_qualifiers objectAtIndex: i]; EOQualifier *schemaBasedQualifierTmp = [(id )qualifier schemaBasedQualifierWithRootEntity: entity]; if (schemaBasedQualifierTmp != qualifier) atLeastOneDifferentQualifier = YES; // Allows nil schemaBasedQualifier if (schemaBasedQualifierTmp) [qualifiers addObject: schemaBasedQualifierTmp]; } // If we've found at least a different qualifier, return a new EOAndQualifier if (atLeastOneDifferentQualifier) { if ([qualifiers count]>0) { returnedQualifier = [[self class] qualifierWithQualifierArray:qualifiers]; } else returnedQualifier = nil; }; } EOFLOGObjectFnStop(); return returnedQualifier; } @end @implementation EOOrQualifier (EOQualifierSQLGeneration) - (NSString *)sqlStringForSQLExpression: (EOSQLExpression *)sqlExpression { //OK? //Ayers: Review (This looks correct, time to cleanup.) return [sqlExpression sqlStringForDisjoinedQualifiers: _qualifiers]; /* NSEnumerator *qualifiersEnum; EOQualifier *qualifier; NSMutableString *sqlString = nil; qualifiersEnum = [_qualifiers objectEnumerator]; while ((qualifier = [qualifiersEnum nextObject])) { if (!sqlString) { sqlString = [NSMutableString stringWithString: [(id )qualifier sqlStringForSQLExpression: sqlExpression]]; } else { [sqlString appendFormat: @" %@ %@", @"OR", [(id )qualifier sqlStringForSQLExpression: sqlExpression]]; } } return sqlString; */ } - (EOQualifier *)schemaBasedQualifierWithRootEntity: (EOEntity *)entity { EOQualifier *returnedQualifier = self; int qualifierCount = 0; BOOL atLeastOneDifferentQualifier = NO; // YES if we find a changed qualifier EOFLOGObjectFnStart(); qualifierCount = [_qualifiers count]; if (qualifierCount > 0) { NSMutableArray *qualifiers = [NSMutableArray array]; int i; for (i = 0; i < qualifierCount; i++) { EOQualifier *qualifier = [_qualifiers objectAtIndex: i]; EOQualifier *schemaBasedQualifierTmp = [(id )qualifier schemaBasedQualifierWithRootEntity: entity]; if (schemaBasedQualifierTmp != qualifier) atLeastOneDifferentQualifier = YES; // Allows nil schemaBasedQualifier if (schemaBasedQualifierTmp) [qualifiers addObject: schemaBasedQualifierTmp]; } // If we've found at least a different qualifier, return a new EOOrQualifier if (atLeastOneDifferentQualifier) { if ([qualifiers count]>0) { returnedQualifier = [[self class] qualifierWithQualifierArray:qualifiers]; } else returnedQualifier = nil; }; } EOFLOGObjectFnStop(); return returnedQualifier; } @end @implementation EOKeyComparisonQualifier (EOQualifierSQLGeneration) - (NSString *)sqlStringForSQLExpression: (EOSQLExpression *)sqlExpression { return [sqlExpression sqlStringForKeyComparisonQualifier: self]; } - (EOQualifier *)schemaBasedQualifierWithRootEntity: (EOEntity *)entity { return self; // MG: Not sure } @end @implementation EOKeyValueQualifier (EOQualifierSQLGeneration) + (void)initialize { static BOOL initialized=NO; if (!initialized) { initialized=YES; GDL2_EOAccessPrivateInit(); }; }; - (NSString *)sqlStringForSQLExpression: (EOSQLExpression *)sqlExpression { return [sqlExpression sqlStringForKeyValueQualifier: self]; } - (EOQualifier *)schemaBasedQualifierWithRootEntity: (EOEntity *)entity { EOQualifier *qualifier = nil; NSMutableArray *qualifiers = nil; id key; EORelationship *relationship; EOFLOGObjectFnStart(); EOFLOGObjectLevelArgs(@"EOQualifier", @"self=%@", self); key = [self key]; EOFLOGObjectLevelArgs(@"EOQualifier", @"key=%@", key); // 2 cases: key finish by an attrbue name (attrName or rel1.rel2.rel3.attrName) // or by an relationship (rel1 or rel1.rel2.rel3) // So find which one is it for key relationship = [entity relationshipForPath: key]; EOFLOGObjectLevelArgs(@"EOQualifier", @"relationship=%@", relationship); // It's a relationship (case 2), so we'll have to work if (relationship) { EORelationship *destinationRelationship; NSDictionary *keyValues = nil; id value = nil; EOEditingContext* editingContext = nil; EOObjectStore *rootObjectStore = nil; NSMutableArray *destinationAttributeNames = [NSMutableArray array]; NSArray *joins; int i, count; SEL sel = NULL; // keyPrefix for new qualifier attribute names NSString* keyPrefix=nil; NSString* relName=[relationship name]; // Verify if key is a single relationship or a relationship key path if (![key isEqualToString:relName]) { // It is a relationship key path: we'll have to prefix join(s) // attribute name // keyPrefix is the keyPath without last relationship name // ex: rel1.rel2. if key was rel1.rel2.rel3 keyPrefix=[key stringByDeletingSuffix:relName]; }; // if relationship is flattened, we'll have to add // last relationship path prefix to keyPrefix ! if ([relationship isFlattened]) { NSString* relDef=nil; destinationRelationship = [relationship lastRelationship]; relDef=[relationship definition]; // something like rel1.rel2.relA.relB. or relA.relB. if (keyPrefix) keyPrefix=[keyPrefix stringByAppendingString:relDef]; else keyPrefix=relDef; keyPrefix=[keyPrefix stringByAppendingString:@"."]; } else { destinationRelationship = relationship; }; EOFLOGObjectLevelArgs(@"EOQualifier", @"key=%@ keyPrefix=%@", key, keyPrefix); joins = [destinationRelationship joins]; count = [joins count]; for (i = 0; i < count; i++) { EOJoin *join = [joins objectAtIndex: i]; EOAttribute *destinationAttribute = [join destinationAttribute]; NSString *destinationAttributeName = [destinationAttribute name]; [destinationAttributeNames addObject: destinationAttributeName]; } value = [self value]; EOFLOGObjectLevelArgs(@"EOQualifier", @"value=%@", value); editingContext = [value editingContext]; rootObjectStore = [editingContext rootObjectStore]; EOFLOGObjectLevelArgs(@"EOQualifier", @"rootObjectStore=%@", rootObjectStore); EOFLOGObjectLevelArgs(@"EOQualifier", @"destinationAttributeNames=%@", destinationAttributeNames); keyValues = [(EOObjectStoreCoordinator*)rootObjectStore valuesForKeys: destinationAttributeNames object: value]; EOFLOGObjectLevelArgs(@"EOQualifier", @"keyValues=%@", keyValues); sel = [self selector]; for (i = 0; i < count; i++) { EOQualifier *tmpQualifier = nil; NSString *attributeName = nil; NSString *destinationAttributeName; EOJoin *join = [joins objectAtIndex: i]; id attributeValue = nil; EOFLOGObjectLevelArgs(@"EOQualifier",@"join=%@",join); destinationAttributeName = [destinationAttributeNames objectAtIndex: i]; if (destinationRelationship != relationship) { // flattened: take destattr attributeName = destinationAttributeName; } else { EOAttribute *sourceAttribute = [join sourceAttribute]; attributeName = [sourceAttribute name]; } if (keyPrefix) attributeName=[keyPrefix stringByAppendingString:attributeName]; EOFLOGObjectLevelArgs(@"EOQualifier", @"key=%@ keyPrefix=%@ attributeName=%@", key, keyPrefix,attributeName); attributeValue = [keyValues objectForKey:destinationAttributeName]; EOFLOGObjectLevelArgs(@"EOQualifier", @"destinationAttributeName=%@ attributeValue=%@", destinationAttributeName, attributeValue); tmpQualifier = [EOKeyValueQualifier qualifierWithKey: attributeName operatorSelector: sel value: (attributeValue ? attributeValue : GDL2_EONull)]; EOFLOGObjectLevelArgs(@"EOQualifier", @"tmpQualifier=%@", tmpQualifier); if (qualifier)//Already a qualifier { //Create an array of qualifiers qualifiers = [NSMutableArray arrayWithObjects: qualifier, tmpQualifier, nil]; qualifier = nil; } else if (qualifiers) //Already qualifiers //Add this one [qualifiers addObject: tmpQualifier]; else //No previous qualifier qualifier = tmpQualifier; } if (qualifiers) { qualifier = [EOAndQualifier qualifierWithQualifierArray: qualifiers]; } } else // It's not a relationship. Nothing to do. qualifier = self; EOFLOGObjectLevelArgs(@"EOQualifier", @"self=%@", self); EOFLOGObjectLevelArgs(@"EOQualifier", @"result qualifier=%@", qualifier); EOFLOGObjectFnStop(); return qualifier; } @end @implementation EONotQualifier (EOQualifierSQLGeneration) - (NSString *)sqlStringForSQLExpression: (EOSQLExpression *)sqlExpression { return [sqlExpression sqlStringForNegatedQualifier: self]; } - (EOQualifier *)schemaBasedQualifierWithRootEntity: (EOEntity *)entity { //TODO [self notImplemented: _cmd]; return nil; } @end @implementation NSString (NSStringSQLExpression) - (NSString *) valueForSQLExpression: (EOSQLExpression *)sqlExpression { return self; } @end gnustep-dl2-0.12.0/EOAccess/EODatabase.m0000644000175000017500000003653710745373063016547 0ustar ayersayers/** EODatabase.m EODatabase Class Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: June 2000 $Revision: 25994 $ $Date: 2008-01-22 14:57:07 +0100 (Die, 22. Jän 2008) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EODatabase.m 25994 2008-01-22 13:57:07Z ayers $") #ifdef GNUSTEP #include #include #include #include #include #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #endif #include #include #include #include #include #include #include #include #include #include #include "EOPrivate.h" /* TODO Controllare il resultCache, ad ogni forget/invalidate deve essere updatato. */ NSString *EOGeneralDatabaseException = @"EOGeneralDatabaseException"; NSTimeInterval EODistantPastTimeInterval = -603979776.0; @implementation EODatabase /* * Database Global Methods */ static NSMutableArray *databaseInstances; + (void)initialize { static BOOL initialized=NO; if (!initialized) { initialized=YES; GDL2_EOAccessPrivateInit(); // THREAD databaseInstances = [NSMutableArray new]; } } + (void)makeAllDatabasesPerform: (SEL)aSelector withObject: anObject { int i; // THREAD for (i = [databaseInstances count] - 1; i >= 0; i--) [[[databaseInstances objectAtIndex: i] nonretainedObjectValue] performSelector: aSelector withObject: anObject]; } /* * Initializing new instances */ //OK - initWithAdaptor: (EOAdaptor *)adaptor { EOFLOGObjectFnStart(); if (!adaptor) { [self autorelease]; return nil; } if ((self = [super init])) { [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_globalIDChanged:) name: @"EOGlobalIDChangedNotification" object: nil]; // [databaseInstances addObject:[NSValue valueWithNonretainedObject:self]]; ASSIGN(_adaptor,adaptor); _registeredContexts = [NSMutableArray new]; _snapshots = [NSMutableDictionary new]; _models = [NSMutableArray new]; _entityCache = [NSMutableDictionary new]; _toManySnapshots = [NSMutableDictionary new]; } EOFLOGObjectFnStop(); return self; } + (EODatabase *)databaseWithModel: (EOModel *)model { return [[[self alloc] initWithModel: model] autorelease]; } - (id)initWithModel: (EOModel *)model { EOAdaptor *adaptor = [EOAdaptor adaptorWithModel:model]; //Handle exception to deallocate self ? if ((self = [self initWithAdaptor: adaptor])) { [self addModel: model]; } return self; } - (void)dealloc { DESTROY(_adaptor); DESTROY(_registeredContexts); DESTROY(_snapshots); DESTROY(_models); DESTROY(_entityCache); DESTROY(_toManySnapshots); [super dealloc]; } - (NSArray *)registeredContexts { NSMutableArray *array = [NSMutableArray array]; int i, n; for (i = 0, n = [_registeredContexts count]; i < n; i++) [array addObject: [[_registeredContexts objectAtIndex: i] nonretainedObjectValue]]; return array; } - (unsigned int) _indexOfRegisteredContext: (EODatabaseContext *)context { int i; for( i = [_registeredContexts count]-1; i >= 0; i--) if ([[_registeredContexts objectAtIndex: i] nonretainedObjectValue] == context) { return i; } return -1; } - (void)registerContext: (EODatabaseContext *)context { unsigned int index=0; //OK NSAssert(([context database] == self),@"Database context is not me"); index = [self _indexOfRegisteredContext:context]; NSAssert(index == (unsigned int) -1 , @"DatabaseContext already registred"); [_registeredContexts addObject: [NSValue valueWithNonretainedObject: context]]; } - (void)unregisterContext: (EODatabaseContext *)context { //OK unsigned int index = [self _indexOfRegisteredContext:context]; NSAssert(index != (unsigned int) -1, @"DatabaseContext wasn't registred"); [_registeredContexts removeObjectAtIndex:index]; } - (EOAdaptor *)adaptor { return _adaptor; } - (void)addModel: (EOModel *)model { [_models addObject: model]; } - (void)removeModel: (EOModel *)model { [_models removeObject: model]; } - (BOOL)addModelIfCompatible: (EOModel *)model { BOOL modelOk = NO; NSAssert(model, @"No model");//WO simply return NO (doesn't handle this case). if ([_models containsObject:model] == YES) modelOk = YES; else { EOAdaptor *adaptor = [self adaptor]; if ([[model adaptorName] isEqualToString: [adaptor name]] == YES || [_adaptor canServiceModel: model] == YES) { [_models addObject: model]; modelOk = YES; } } return modelOk; } - (NSArray *)models { return _models; } - (EOEntity *)entityNamed: (NSString *)entityName { //OK EOEntity *entity=nil; int i = 0; int count = 0; NSAssert(entityName, @"No entity name"); count = [_models count]; for(i = 0; !entity && i < count; i++) { EOModel *model = [_models objectAtIndex: i]; entity = [model entityNamed: entityName]; } return entity; } - (EOEntity *)entityForObject: (id)object { //OK EOEntity *entity = nil; NSString *entityName = nil; EOFLOGObjectFnStart(); EOFLOGObjectLevelArgs(@"EODatabaseContext", @"object=%p (of class %@)", object, [object class]); NSAssert(!_isNilOrEONull(object), @"No object"); if ([EOFault isFault: object]) { EOFaultHandler *faultHandler = [EOFault handlerForFault: object]; EOKeyGlobalID *gid; EOFLOGObjectLevelArgs(@"EODatabaseContext", @"faultHandler=%p (of class %@)", faultHandler, [faultHandler class]); gid = [(EOAccessFaultHandler *)faultHandler globalID]; NSAssert3(gid, @"No gid for fault handler %p for object %p of class %@", faultHandler, object, [object class]); entityName = [gid entityName]; } else entityName = [object entityName]; NSAssert2(entityName, @"No object entity name for object %@ of class %@", object, [object class]); EOFLOGObjectLevelArgs(@"EODatabaseContext", @"entityName=%@", entityName); entity = [self entityNamed: entityName]; EOFLOGObjectLevelArgs(@"EODatabaseContext", @"entity=%p", entity); EOFLOGObjectFnStop(); return entity; } - (NSArray *)resultCacheForEntityNamed: (NSString *)name { return [_entityCache objectForKey: name]; } - (void)setResultCache: (NSArray *)cache forEntityNamed: (NSString *)name { EOFLOGObjectFnStart(); [_entityCache setObject: cache forKey: name]; EOFLOGObjectFnStop(); } - (void)invalidateResultCacheForEntityNamed: (NSString *)name { [_entityCache removeObjectForKey: name];//?? } - (void)invalidateResultCache { [_entityCache removeAllObjects]; } - (void)handleDroppedConnection { NSArray *dbContextArray; NSEnumerator *contextEnum; EODatabaseContext *dbContext; EOFLOGObjectFnStartOrCond2(@"DatabaseLevel", @"EODatabase"); [_adaptor handleDroppedConnection]; dbContextArray = [self registeredContexts]; contextEnum = [dbContextArray objectEnumerator]; while ((dbContext = [contextEnum nextObject])) [dbContext handleDroppedConnection]; EOFLOGObjectFnStopOrCond2(@"DatabaseLevel", @"EODatabase"); } @end @implementation EODatabase (EOUniquing) - (void)recordSnapshot: (NSDictionary *)snapshot forGlobalID: (EOGlobalID *)gid { EOFLOGObjectFnStart(); EOFLOGObjectLevelArgs(@"EODatabaseContext", @"snapshot %p %@", snapshot, snapshot); EOFLOGObjectLevelArgs(@"EODatabaseContext", @"gid=%@", gid); NSAssert(gid, @"No gid"); NSAssert(snapshot, @"No snapshot"); NSAssert(_snapshots, @"No _snapshots"); [_snapshots setObject: snapshot forKey: gid]; NSAssert([_snapshots objectForKey: gid], @"SNAPSHOT not save !!"); EOFLOGObjectFnStop(); } //"Receive EOGlobalIDChangedNotification notification" /* This method is currently only intended to replace EOTemporaryGlobalIDs with corresponding EOKeyGlobalIDs. Since the globalIDs within the _toManySnapshots can only contain EOKeyGlobalIDs from fetched data, they need not be searched yet. This may change if we add support to allow mutable primary key class attributes or recordToManySnapshots: ever gets called with EOTemporaryGlobalIDs for some obscure reasons. */ - (void)_globalIDChanged: (NSNotification *)notification { NSDictionary *snapshot = nil; NSDictionary *userInfo = nil; NSEnumerator *enumerator = nil; EOGlobalID *tempGID = nil; EOGlobalID *gid = nil; EOFLOGObjectFnStart(); userInfo = [notification userInfo]; enumerator = [userInfo keyEnumerator]; while ((tempGID = [enumerator nextObject])) { EOFLOGObjectLevelArgs(@"EODatabaseContext", @"tempGID=%@", tempGID); gid = [userInfo objectForKey: tempGID]; EOFLOGObjectLevelArgs(@"EODatabaseContext", @"gid=%@", gid); //OK ? snapshot = [_snapshots objectForKey: tempGID]; EOFLOGObjectLevelArgs(@"EODatabaseContext", @"_snapshots snapshot=%@", snapshot); if (snapshot) { [_snapshots removeObjectForKey: tempGID]; [_snapshots setObject: snapshot forKey: gid]; } //OK ? snapshot = [_toManySnapshots objectForKey: tempGID]; EOFLOGObjectLevelArgs(@"EODatabaseContext", @"_toManySnapshots snapshot=%@", snapshot); if (snapshot) { [_toManySnapshots removeObjectForKey: tempGID]; [_toManySnapshots setObject: snapshot forKey: gid]; } } EOFLOGObjectFnStop(); } - (NSDictionary *)snapshotForGlobalID: (EOGlobalID *)gid { return [self snapshotForGlobalID: gid after: EODistantPastTimeInterval]; } - (NSDictionary *)snapshotForGlobalID: (EOGlobalID *)gid after: (NSTimeInterval)ti { //seems OK NSDictionary *snapshot = nil; EOFLOGObjectFnStart(); NSAssert(gid, @"No gid"); snapshot = [_snapshots objectForKey: gid]; EOFLOGObjectFnStop(); return snapshot; } - (void)recordSnapshot: (NSArray*)gids forSourceGlobalID: (EOGlobalID *)gid relationshipName: (NSString *)name { //OK NSMutableDictionary *toMany = nil; EOFLOGObjectFnStart(); NSAssert(gid,@"No snapshot"); NSAssert(gid,@"No Source Global ID"); NSAssert(name,@"No relationship name"); EOFLOGObjectLevelArgs(@"EODatabaseContext", @"self=%p snapshot gids=%@", self, gids); EOFLOGObjectLevelArgs(@"EODatabaseContext", @"SourceGlobalID gid=%@", gid); EOFLOGObjectLevelArgs(@"EODatabaseContext", @"relationshipName=%@", name); toMany = [_toManySnapshots objectForKey: gid]; if (!toMany) { toMany = [NSMutableDictionary dictionaryWithCapacity: 10]; [_toManySnapshots setObject: toMany forKey: gid]; } [toMany setObject: gids forKey: name]; EOFLOGObjectFnStop(); } - (NSArray *)snapshotForSourceGlobalID: (EOGlobalID *)gid relationshipName: (NSString *)name { NSAssert(gid, @"No Source Global ID"); NSAssert(name, @"No relationship name"); return [[_toManySnapshots objectForKey: gid] objectForKey: name]; } - (void)forgetSnapshotForGlobalID: (EOGlobalID *)gid { //Seems OK EOFLOGObjectFnStart(); NSAssert(gid,@"No Global ID"); EOFLOGObjectLevelArgs(@"EODatabaseContext", @"gid=%@", gid); [_snapshots removeObjectForKey: gid]; [_toManySnapshots removeObjectForKey: gid]; [[NSNotificationCenter defaultCenter] postNotificationName: EOObjectsChangedInStoreNotification object: self userInfo: [NSDictionary dictionaryWithObject: [NSArray arrayWithObject: gid] forKey: EOInvalidatedKey]]; EOFLOGObjectFnStop(); }; - (void)forgetSnapshotsForGlobalIDs: (NSArray*)gids { NSEnumerator *gidEnum = nil; id gid = nil; EOFLOGObjectFnStart(); NSAssert(gids, @"No Global IDs"); EOFLOGObjectLevelArgs(@"EODatabaseContext", @"gids=%@", gids); gidEnum = [gids objectEnumerator]; while ((gid = [gidEnum nextObject])) { [_snapshots removeObjectForKey: gid]; [_toManySnapshots removeObjectForKey: gid]; } [[NSNotificationCenter defaultCenter] postNotificationName: EOObjectsChangedInStoreNotification object: self userInfo: [NSDictionary dictionaryWithObject: gids forKey: EOInvalidatedKey]]; EOFLOGObjectFnStop(); } - (void)forgetAllSnapshots { NSMutableSet *gidSet = [NSMutableSet new]; NSMutableArray *gidArray = [NSMutableArray array]; EOFLOGObjectFnStartOrCond2(@"DatabaseLevel", @"EODatabase"); [gidSet addObjectsFromArray: [_snapshots allKeys]]; [gidSet addObjectsFromArray: [_toManySnapshots allKeys]]; [gidArray addObjectsFromArray: [gidSet allObjects]]; [gidSet release]; [_snapshots removeAllObjects]; [_toManySnapshots removeAllObjects]; [[NSNotificationCenter defaultCenter] postNotificationName: EOObjectsChangedInStoreNotification object:self userInfo: [NSDictionary dictionaryWithObject: gidArray forKey: EOInvalidatedKey]]; EOFLOGObjectFnStopOrCond2(@"DatabaseLevel", @"EODatabase"); } - (void)recordSnapshots: (NSDictionary *)snapshots { //OK //VERIFY: be sure to replace all anapshot entries if any ! EOFLOGObjectFnStart(); [_snapshots addEntriesFromDictionary: snapshots]; EOFLOGObjectLevelArgs(@"EODatabaseContext", @"self=%p _snapshots=%@", self, _snapshots); EOFLOGObjectFnStop(); } - (void)recordToManySnapshots: (NSDictionary *)snapshots { //Seems OK NSEnumerator *keyEnum = nil; id key = nil; EOFLOGObjectFnStart(); EOFLOGObjectLevelArgs(@"EODatabaseContext", @"snapshots=%@", snapshots); NSAssert(snapshots, @"No snapshots"); keyEnum = [snapshots keyEnumerator]; while ((key = [keyEnum nextObject])) { NSMutableDictionary *toMany = nil; toMany = [_toManySnapshots objectForKey: key]; // look if already exists if (!toMany) { toMany = [NSMutableDictionary dictionaryWithCapacity: 10]; [_toManySnapshots setObject: toMany forKey: key]; } [toMany addEntriesFromDictionary: [snapshots objectForKey: key]]; } EOFLOGObjectLevelArgs(@"EODatabaseContext", @"snapshots=%@", snapshots); EOFLOGObjectFnStop(); } - (NSDictionary *)snapshots { return AUTORELEASE([_snapshots copy]); } @end /* EODatabase (EOUniquing) */ gnustep-dl2-0.12.0/EOAccess/EOAdaptor.h0000644000175000017500000001331610645346232016413 0ustar ayersayers/* -*-objc-*- EOAdaptor.h Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOAdaptor_h__ #define __EOAdaptor_h__ #ifdef GNUSTEP #include #else #include #endif #include @class NSArray; @class NSMutableArray; @class NSDictionary; @class NSNumber; @class NSException; @class NSCalendarDate; @class NSData; @class NSTimeZone; @class EOModel; @class EOAttribute; @class EOAdaptorContext; @class EOLoginPanel; @class EOEntity; GDL2ACCESS_EXPORT NSString *EOGeneralAdaptorException; @interface EOAdaptor : NSObject { EOModel *_model;//Not in EOFD NSString *_name; NSDictionary *_connectionDictionary; NSMutableArray *_contexts; // values with contexts // Strictly speaking, the _context array is not API compatible // with WO4.5 as the objects in the array are GC-wrappers. // Subclasses should access this array via accessor method. NSString *_expressionClassName; Class _expressionClass; id _delegate; // not retained struct { unsigned processValue:1; } _delegateRespondsTo; } /* Creating an EOAdaptor */ + (id)adaptorWithModel: (EOModel *)model; + (id)adaptorWithName: (NSString *)name; + (void)setExpressionClassName: (NSString *)sqlExpressionClassName adaptorClassName: (NSString *)adaptorClassName; + (EOLoginPanel *)sharedLoginPanelInstance; + (NSArray *)availableAdaptorNames; - (NSArray *)prototypeAttributes; - (id)initWithName: (NSString *)name; /* Getting an adaptor's name */ - (NSString *)name; /* Creating and removing an adaptor context */ - (EOAdaptorContext *)createAdaptorContext; - (NSArray *)contexts; /* Setting the model */ - (void)setModel: (EOModel *)model;//Not in EOFD - (EOModel *)model;//Not in EOFD /* Checking connection status */ - (BOOL)hasOpenChannels; /* Getting adaptor-specific information */ - (Class)expressionClass; - (Class)defaultExpressionClass; /* Reconnection to database */ - (void)handleDroppedConnection; - (BOOL)isDroppedConnectionException: (NSException *)exception; /* Setting connection information */ - (void)setConnectionDictionary: (NSDictionary *)dictionary; - (NSDictionary *)connectionDictionary; - (void)assertConnectionDictionaryIsValid; - (BOOL)canServiceModel: (EOModel *)model; - (NSStringEncoding)databaseEncoding; - (id)fetchedValueForValue: (id)value attribute: (EOAttribute *)attribute; - (NSString *)fetchedValueForStringValue: (NSString *)value attribute: (EOAttribute *)attribute; - (NSNumber *)fetchedValueForNumberValue: (NSNumber *)value attribute: (EOAttribute *)attribute; - (NSCalendarDate *)fetchedValueForDateValue: (NSCalendarDate *)value attribute: (EOAttribute *)attribute; - (NSData *)fetchedValueForDataValue: (NSData *)value attribute: (EOAttribute *)attribute; /* Setting the delegate */ - (id)delegate; - (void)setDelegate: (id)delegate; - (BOOL)isValidQualifierType: (NSString *)attribute model: (EOModel *)model; @end /* EOAdaptor */ @interface EOAdaptor (EOAdaptorLoginPanel) - (BOOL)runLoginPanelAndValidateConnectionDictionary; - (NSDictionary *)runLoginPanel; @end @interface EOAdaptor (EOExternalTypeMapping) + (NSString *)internalTypeForExternalType: (NSString *)extType model: (EOModel *)model; + (NSArray *)externalTypesWithModel: (EOModel *)model; + (void)assignExternalTypeForAttribute: (EOAttribute *)attribute; + (void)assignExternalInfoForAttribute: (EOAttribute *)attribute; + (void)assignExternalInfoForEntity: (EOEntity *)entity; + (void)assignExternalInfoForEntireModel: (EOModel *)model; @end @interface EOAdaptor (EOSchemaGenerationExtensions) - (void)dropDatabaseWithAdministrativeConnectionDictionary: (NSDictionary *)administrativeConnectionDictionary; - (void)createDatabaseWithAdministrativeConnectionDictionary: (NSDictionary *)administrativeConnectionDictionary; @end @interface EOLoginPanel : NSObject - (NSDictionary *)runPanelForAdaptor: (EOAdaptor *)adaptor validate: (BOOL)yn allowsCreation: (BOOL)allowsCreation; - (NSDictionary *)administrativeConnectionDictionaryForAdaptor: (EOAdaptor *)adaptor; @end @interface NSObject (EOAdaptorDelegate) - (id)adaptor: (EOAdaptor *)adaptor fetchedValueForValue: (id)value attribute: (EOAttribute *)attribute; - (NSDictionary *)reconnectionDictionaryForAdaptor: (EOAdaptor *)adaptor; @end /* NSObject (EOAdaptorDelegate) */ /* GDL2 Extensions */ GDL2ACCESS_EXPORT NSString *EOAdministrativeConnectionDictionaryNeededNotification; GDL2ACCESS_EXPORT NSString *EOAdaptorKey; GDL2ACCESS_EXPORT NSString *EOModelKey; GDL2ACCESS_EXPORT NSString *EOConnectionDictionaryKey; GDL2ACCESS_EXPORT NSString *EOAdministrativeConnectionDictionaryKey; #endif /* __EOAdaptor_h__*/ gnustep-dl2-0.12.0/EOAccess/EOJoin.m0000644000175000017500000001162411137323411015714 0ustar ayersayers/** EOJoin.m EOJoin Class Copyright (C) 2000-2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 $Revision: 27695 $ $Date: 2009-01-26 13:05:29 +0100 (Mon, 26. Jän 2009) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EOJoin.m 27695 2009-01-26 12:05:29Z ayers $") #ifdef GNUSTEP #include #include #else #include #endif #ifndef GNUSTEP #include #include #include #endif #include #include #include #include #include #include @implementation EOJoin + (EOJoin *) joinWithSourceAttribute: (EOAttribute *)source destinationAttribute: (EOAttribute *)destination { return [[[self alloc] initWithSourceAttribute: source destinationAttribute: destination] autorelease]; } - (id) initWithSourceAttribute: (EOAttribute *)source destinationAttribute: (EOAttribute *)destination { if ((self = [super init])) { NSAssert((source && destination), @"Source and destination attributes cannot be nil"); ASSIGN(_sourceAttribute, source); ASSIGN(_destinationAttribute, destination); } return self; } - (void)dealloc { DESTROY(_sourceAttribute); DESTROY(_destinationAttribute); [super dealloc]; } - (unsigned)hash { return [_sourceAttribute hash]; } - (NSString *)description { NSString *dscr = nil; /*NSString *joinOperatorDescr = nil; NSString *joinSemanticDescr = nil; switch(joinOperator) { case EOJoinEqualTo: joinOperatorDescr=@"EOJoinEqualTo"; break; case EOJoinNotEqualTo: joinOperatorDescr=@"EOJoinNotEqualTo"; break; case EOJoinGreaterThan: joinOperatorDescr=@"EOJoinGreaterThan"; break; case EOJoinGreaterThanOrEqualTo: joinOperatorDescr=@"EOJoinGreaterThanOrEqualTo"; break; case EOJoinLessThan: joinOperatorDescr=@"EOJoinLessThan"; break; case EOJoinLessThanOrEqualTo: joinOperatorDescr=@"EOJoinLessThanOrEqualTo"; break; }; switch(joinSemantic) { case EOInnerJoin: joinSemanticDescr=@"EOInnerJoin"; break; case EOFullOuterJoin: joinSemanticDescr=@"EOFullOuterJoin"; break; case EOLeftOuterJoin: joinSemanticDescr=@"EOLeftOuterJoin"; break; case EORightOuterJoin: joinSemanticDescr=@"EORightOuterJoin"; break; }; */ dscr = [NSString stringWithFormat: @"<%s %p -", object_get_class_name(self), (void*)self]; dscr = [dscr stringByAppendingFormat: @" sourceAttribute=%@", [_sourceAttribute name]]; dscr = [dscr stringByAppendingFormat: @" destinationAttribute=%@", [_destinationAttribute name]]; /* dscr=[dscr stringByAppendingFormat:@" relationship name=%@", [relationship name]]; dscr=[dscr stringByAppendingFormat:@" joinOperator=%@ joinSemantic=%@>", joinOperatorDescr, joinSemanticDescr];*/ return dscr; } - (EOAttribute *)destinationAttribute { return _destinationAttribute; } - (EOAttribute *)sourceAttribute { return _sourceAttribute; } - (BOOL)isReciprocalToJoin: (EOJoin *)otherJoin { //OK NSDebugMLLog(@"gsdb", @"_sourceAttribute name=%@", [_sourceAttribute name]); NSDebugMLLog(@"gsdb", @"[[otherJoin destinationAttribute] name]=%@", [[otherJoin destinationAttribute] name]); NSDebugMLLog(@"gsdb", @"_destinationAttribute name=%@", [_destinationAttribute name]); NSDebugMLLog(@"gsdb", @"[[otherJoin sourceAttribute] name]=%@", [[otherJoin sourceAttribute] name]); if ([[_sourceAttribute name] isEqual: [[otherJoin destinationAttribute] name]] && [[_destinationAttribute name] isEqual: [[otherJoin sourceAttribute] name]]) return YES; else return NO; } @end gnustep-dl2-0.12.0/EOAccess/EODatabaseOperationPriv.h0000644000175000017500000000233110645346232021242 0ustar ayersayers/* -*-objc-*- EODatabaseOperationPriv.h Copyright (C) 2000,2002,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: July 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EODatabaseOperationPriv_h__ #define __EODatabaseOperationPriv_h__ @class EOGlobalID; @interface EODatabaseOperation (private) - (void)_setGlobalID: (EOGlobalID *)globalID; @end #endif /* __EODatabaseOperationPriv_h__ */ gnustep-dl2-0.12.0/EOAccess/EOSchemaGeneration.m0000644000175000017500000005550110745373063020247 0ustar ayersayers/** EOSchemaGeneration.m EOSchemaGeneration Class Copyright (C) 2006 Free Software Foundation, Inc. Author: David Ayers Date: February 2006 $Revision: 23653 $ $Date: 2006-09-28 17:25:30 +0200 (Don, 28 Sep 2006) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EOSchemaGeneration.m 23653 2006-09-28 15:25:30Z ratmice $") #include #ifdef GNUSTEP #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #include #include #endif #include #include #include #include #include #include #include #include #include #include NSString *EOCreateTablesKey = @"EOCreateTablesKey"; NSString *EODropTablesKey = @"EODropTablesKey"; NSString *EOCreatePrimaryKeySupportKey = @"EOCreatePrimaryKeySupportKey"; NSString *EODropPrimaryKeySupportKey = @"EODropPrimaryKeySupportKey"; NSString *EOPrimaryKeyConstraintsKey = @"EOPrimaryKeyConstraintsKey"; NSString *EOForeignKeyConstraintsKey = @"EOForeignKeyConstraintsKey"; NSString *EOCreateDatabaseKey = @"EOCreateDatabaseKey"; NSString *EODropDatabaseKey = @"EODropDatabaseKey"; @implementation EOSQLExpression (EOSchemaGeneration) + (NSArray *)_administrativeDatabaseStatementsForSelector:(SEL) sel forEntityGroup:(NSArray *)group { EOEntity *entity; EOModel *model; NSDictionary *connDict; NSDictionary *admDict; NSArray *stmts; NSString *notifName; NSMutableDictionary *notifDict; entity = [group lastObject]; model = [entity model]; connDict = [model connectionDictionary]; notifDict = (id)[NSMutableDictionary dictionaryWithCapacity: 2]; [notifDict setObject: model forKey: EOModelKey]; notifName = EOAdministrativeConnectionDictionaryNeededNotification; [[NSNotificationCenter defaultCenter] postNotificationName: notifName object: notifDict]; admDict = [notifDict objectForKey: EOAdministrativeConnectionDictionaryKey]; /* TODO: ayers if (admDict == nil && [admDict count] == 0) { EOAdaptor *adaptor; EOLoginPanel *panel; adaptor = [EOAdaptor adaptorWithModel: model]; panel = [[adaptor class] sharedLoginPanelInstance]; admDict = [panel administrativeConnectionDictionaryForAdaptor: adaptor]; } */ stmts = [self performSelector: sel withObject: connDict withObject: admDict]; return stmts; } + (NSArray *)_dropDatabaseStatementsForEntityGroups: (NSArray *)entityGroups { NSMutableArray *cumStmts; NSArray *stmts; NSArray *group; unsigned i,n; SEL sel; sel = @selector(dropDatabaseStatementsForConnectionDictionary:administrativeConnectionDictionary:); n = [entityGroups count]; cumStmts = [NSMutableArray arrayWithCapacity: n]; for (i=0; iEODatabaseDataSource Class Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: July 2000 Author: Manuel Guesdon Date: December 2001 $Revision: 26323 $ $Date: 2008-03-16 23:59:56 +0100 (Son, 16. Mär 2008) $ This file is part of the GNUstep Database Library. 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EODatabaseDataSource.m 26323 2008-03-16 22:59:56Z ratmice $") #ifdef GNUSTEP #include #include #include #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include @interface EODatabaseDataSource(Private) - (id)_partialInitWithEditingContext: (EOEditingContext*)editingContext entityName: (NSString*)entityName fetchSpecificationName: (NSString*)fetchSpecificationName; @end @implementation EODatabaseDataSource - (id)initWithEditingContext: (EOEditingContext *)editingContext entityName: (NSString *)entityName { return [self initWithEditingContext: editingContext entityName: entityName fetchSpecificationName: nil]; } - (id)initWithEditingContext: (EOEditingContext *)editingContext entityName: (NSString *)entityName fetchSpecificationName: (NSString *)fetchName { NSArray *stores; EODatabaseContext *store = nil; NSEnumerator *storeEnum; EOModel *model; EOEntity *entity = nil; id rootStore; EOFetchSpecification *fetchSpec; if ((self = [super init])) { ASSIGN(_editingContext, editingContext); rootStore = [_editingContext rootObjectStore]; if ([rootStore isKindOfClass: [EOObjectStoreCoordinator class]] == YES) { stores = [rootStore cooperatingObjectStores]; storeEnum = [stores objectEnumerator]; while ((store = [storeEnum nextObject])) { if ([store isKindOfClass: [EODatabaseContext class]] == YES) { if ((entity = [[store database] entityNamed: entityName])) break; } } if (store == nil) { entity = [[EOModelGroup defaultGroup] entityNamed: entityName]; model = [entity model]; store = [EODatabaseContext databaseContextWithDatabase: [EODatabase databaseWithModel: model]]; [rootStore addCooperatingObjectStore: store]; } } else if ([rootStore isKindOfClass: [EODatabaseContext class]] == YES) { if ((entity = [[store database] entityNamed: entityName]) == nil) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: editingContext (%@) cannot handler entity named '%@'", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, editingContext, entityName]; } else [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: editingContext (%@) cannot handler entity named '%@'", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, editingContext, entityName]; fetchSpec = [entity fetchSpecificationNamed: fetchName]; if (fetchSpec == nil) { fetchSpec = [EOFetchSpecification fetchSpecificationWithEntityName: entityName qualifier: nil sortOrderings: nil]; } ASSIGN(_fetchSpecification, fetchSpec); } return self; } - (void)dealloc { DESTROY(_bindings); DESTROY(_auxiliaryQualifier); DESTROY(_fetchSpecification); DESTROY(_editingContext); [super dealloc]; } - (NSString *)description { return [NSString stringWithFormat: @"<%s %p : entity name=%@ editingContext=%p fetchSpecification=%@>", object_get_class_name(self), (void *)self, [[self entity]name], _editingContext, _fetchSpecification]; } - (EOEntity *)entity { EOObjectStore *store; NSString *entityName = [_fetchSpecification entityName]; EOModelGroup *modelGroup = nil; store = [_editingContext rootObjectStore]; if ([store isKindOfClass: [EOObjectStoreCoordinator class]]) { return [[(EOObjectStoreCoordinator *)store modelGroup] entityNamed: entityName]; } else if ([store isKindOfClass:GDL2_EODatabaseContextClass]) { EODatabase *database = [(EODatabaseContext *)store database]; NSArray *models = [database models]; int i, c; for (i = 0, c = [models count]; i < c; i++) { EOEntity *entity; modelGroup = [[models objectAtIndex: i] modelGroup]; entity = [modelGroup entityNamed: entityName]; if (entity) return entity; } return nil; } else if ([store respondsToSelector:@selector(modelGroup:)]) { modelGroup = [store performSelector:@selector(modelGroup:)]; } if (modelGroup != nil) { return [modelGroup entityNamed: entityName]; } else { return [[EOModelGroup defaultModelGroup] entityNamed: entityName]; } } - (EODatabaseContext *)databaseContext { EOModel *model; model = [[self entity] model]; return [EODatabaseContext registeredDatabaseContextForModel:model editingContext:_editingContext]; } - (void)setFetchSpecification: (EOFetchSpecification *)fetchSpecification { ASSIGN(_fetchSpecification, fetchSpecification); } - (EOFetchSpecification *)fetchSpecification { return _fetchSpecification; } - (void)setAuxiliaryQualifier: (EOQualifier *)qualifier { ASSIGN(_auxiliaryQualifier, qualifier);//OK } - (EOQualifier *)auxiliaryQualifier { return _auxiliaryQualifier; } - (EOFetchSpecification *)fetchSpecificationForFetch { EOFetchSpecification *fetch = nil; EOQualifier *qualifier = nil; EOFLOGObjectLevelArgs(@"EODataSource", @"_auxiliaryQualifier=%@", _auxiliaryQualifier); EOFLOGObjectLevelArgs(@"EODataSource", @"_bindings=%@", _bindings); EOFLOGObjectLevelArgs(@"EODataSource", @"_fetchSpecification=%@", _fetchSpecification); qualifier = [_auxiliaryQualifier qualifierWithBindings: _bindings requiresAllVariables: [_fetchSpecification requiresAllQualifierBindingVariables]]; //ret same ? EOFLOGObjectLevelArgs(@"EODataSource", @"qualifier=%@", qualifier); //call _fetchSpecification qualifier //ret nil //TODO fetch = [[_fetchSpecification copy] autorelease]; EOFLOGObjectLevelArgs(@"EODataSource", @"fetch=%@", fetch); [fetch setQualifier:qualifier]; /* fetch = [_fetchSpecification copy]; [fetch setQualifier:[[[EOAndQualifier alloc] initWithQualifiers:[fetch qualifier], _auxiliaryQualifier, nil] autorelease]]; */ EOFLOGObjectLevelArgs(@"EODataSource", @"fetch=%@", fetch); return fetch; } - (void)setFetchEnabled: (BOOL)flag { _flags.fetchEnabled = flag; } - (BOOL)isFetchEnabled { return _flags.fetchEnabled; } - (EODataSource *)dataSourceQualifiedByKey: (NSString *)detailKey { return [EODetailDataSource detailDataSourceWithMasterDataSource: self detailKey: detailKey]; } /** * Overrides superclasses implementation but doesn't do anything * useful. You must insert the object into the editing context * manually. */ - (void)insertObject: (id)object { } - (void)deleteObject: (id)object { [_editingContext deleteObject: object]; } - (NSArray *)fetchObjects { NSArray *objects = nil; EOFLOGObjectLevelArgs(@"EODataSource", @"_editingContext=%@", _editingContext); NSAssert(_editingContext, @"No Editing Context"); //call [self isFetchEnabled]; NS_DURING//For trace purpose { objects = [_editingContext objectsWithFetchSpecification: [self fetchSpecificationForFetch]];//OK } NS_HANDLER { NSLog(@"%@ (%@)", localException, [localException reason]); NSDebugMLog(@"%@ (%@)", localException, [localException reason]); [localException raise]; } NS_ENDHANDLER; EOFLOGObjectLevelArgs(@"EODataSource", @"objects=%p", objects); EOFLOGObjectLevelArgs(@"EODataSource", @"objects count=%d", [objects count]); EOFLOGObjectLevelArgs(@"EODataSource", @"objects=%@", objects); return objects; } - (EOClassDescription *)classDescriptionForObjects { return [[self entity] classDescriptionForInstances]; } - (NSArray *)qualifierBindingKeys { return [_bindings allKeys]; // TODO resolve all bindings question } - (void)setQualifierBindings: (NSDictionary *)bindings { ASSIGN(_bindings, bindings); } - (NSDictionary *)qualifierBindings { return _bindings; } - (id)initWithCoder: (NSCoder *)coder { self = [super init]; ASSIGN(_editingContext, [coder decodeObject]); ASSIGN(_fetchSpecification, [coder decodeObject]); ASSIGN(_auxiliaryQualifier, [coder decodeObject]); ASSIGN(_bindings, [coder decodeObject]); // TODO flags return self; } - (void)encodeWithCoder: (NSCoder *)coder { [coder encodeObject:_editingContext]; [coder encodeObject:_fetchSpecification]; [coder encodeObject:_auxiliaryQualifier]; [coder encodeObject:_bindings]; // TODO flags } - (id)_partialInitWithEditingContext: (EOEditingContext*)editingContext entityName: (NSString*)entityName fetchSpecificationName: (NSString*)fetchSpecificationName { if ((self = [self initWithEditingContext: editingContext entityName: entityName fetchSpecificationName: nil])) { //turbocat ASSIGN(_editingContext,editingContext); ASSIGN(_fetchSpecification, [EOFetchSpecification new]); [_fetchSpecification setEntityName: entityName]; } return self; } - (id) initWithKeyValueUnarchiver: (EOKeyValueUnarchiver *)unarchiver { NSString *entityName = nil; EOFetchSpecification *fetchSpecification = nil; EOQualifier *auxiliaryQualifier = nil; EOEditingContext *editingContext = nil; NSString *fetchSpecificationName = nil; EOFLOGObjectFnStart(); entityName = [unarchiver decodeObjectForKey: @"entityName"]; EOFLOGObjectLevelArgs(@"EODataSource",@"entityName=%@",entityName); fetchSpecification = [unarchiver decodeObjectForKey: @"fetchSpecification"]; EOFLOGObjectLevelArgs(@"EODataSource", @"fetchSpecification=%@", fetchSpecification); auxiliaryQualifier = [unarchiver decodeObjectForKey: @"auxiliaryQualifier"]; EOFLOGObjectLevelArgs(@"EODataSource", @"auxiliaryQualifier=%@", auxiliaryQualifier); editingContext = [unarchiver decodeObjectReferenceForKey: @"editingContext"]; EOFLOGObjectLevelArgs(@"EODataSource", @"editingContext=%@", editingContext); fetchSpecificationName = [unarchiver decodeObjectForKey: @"fetchSpecificationName"]; EOFLOGObjectLevelArgs(@"EODataSource", @"fetchSpecificationName=%@", fetchSpecificationName); if (!entityName) { entityName = [fetchSpecification entityName]; EOFLOGObjectLevelArgs(@"EODataSource", @"entityName=%@", entityName); } if ((self = [self _partialInitWithEditingContext: editingContext entityName: entityName fetchSpecificationName: fetchSpecificationName])) { [self setFetchSpecification: fetchSpecification]; } return self; } - (void) encodeWithKeyValueArchiver: (EOKeyValueUnarchiver *)archiver { [self notImplemented: _cmd]; } - (EOEditingContext*)editingContext { return _editingContext; } @end gnustep-dl2-0.12.0/EOAccess/EOAdaptorContext.h0000644000175000017500000000740310645346232017760 0ustar ayersayers/* -*-objc-*- EOAdaptorContext.h Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOAdaptorContext_h__ #define __EOAdaptorContext_h__ #ifdef GNUSTEP #include #else #include #endif #include @class NSMutableArray; @class NSString; @class EOAdaptor; @class EOAdaptorChannel; typedef enum { EODelegateRejects, EODelegateApproves, EODelegateOverrides } EODelegateResponse; /* The EOAdaptorContext class could be overriden for a concrete database adaptor. You have to override only those methods marked in this header with 'override'. */ @interface EOAdaptorContext : NSObject { EOAdaptor *_adaptor; NSMutableArray *_channels; // values with channels id _delegate; // not retained unsigned short _transactionNestingLevel; BOOL _debug; /* Flags used to check if the delegate responds to several messages */ struct { unsigned shouldConnect:1; unsigned shouldBegin:1; unsigned didBegin:1; unsigned shouldCommit:1; unsigned didCommit:1; unsigned shouldRollback:1; unsigned didRollback:1; } _delegateRespondsTo; } + (EOAdaptorContext *)adaptorContextWithAdaptor: (EOAdaptor *)adaptor; - (id)initWithAdaptor: (EOAdaptor *)adaptor; - (EOAdaptor *)adaptor; - (EOAdaptorChannel *)createAdaptorChannel; // override - (NSArray *)channels; - (BOOL)hasOpenChannels; - (BOOL)hasBusyChannels; - (id)delegate; - (void)setDelegate: (id)delegate; - (void)handleDroppedConnection; @end @interface EOAdaptorContext (EOTransactions) - (void)beginTransaction; - (void)commitTransaction; - (void)rollbackTransaction; - (void)transactionDidBegin; - (void)transactionDidCommit; - (void)transactionDidRollback; - (BOOL)hasOpenTransaction; - (BOOL)canNestTransactions; // override - (unsigned)transactionNestingLevel; + (void)setDebugEnabledDefault: (BOOL)flag; + (BOOL)debugEnabledDefault; - (void)setDebugEnabled: (BOOL)debugEnabled; - (BOOL)isDebugEnabled; @end /* EOAdaptorContext (EOTransactions) */ @interface EOAdaptorContext(Private) - (void)_channelDidInit: (id)channel; - (void)_channelWillDealloc: (id)channel; @end @interface NSObject (EOAdaptorContextDelegation) - (BOOL)adaptorContextShouldConnect: (id)context; - (BOOL)adaptorContextShouldBegin: (id)context; - (void)adaptorContextDidBegin: (id)context; - (BOOL)adaptorContextShouldCommit: (id)context; - (void)adaptorContextDidCommit: (id)context; - (BOOL)adaptorContextShouldRollback: (id)context; - (void)adaptorContextDidRollback: (id)context; @end /* NSObject(EOAdaptorContextDelegate) */ GDL2ACCESS_EXPORT NSString *EOAdaptorContextBeginTransactionNotification; GDL2ACCESS_EXPORT NSString *EOAdaptorContextCommitTransactionNotification; GDL2ACCESS_EXPORT NSString *EOAdaptorContextRollbackTransactionNotification; #endif /* __EOAdaptorContext_h__*/ gnustep-dl2-0.12.0/EOAccess/EOEntityPriv.h0000644000175000017500000001126711146713421017134 0ustar ayersayers/* -*-objc-*- EOEntityPriv.h Copyright (C) 2000,2002,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: July 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOEntityPriv_h__ #define __EOEntityPriv_h__ @class NSString; @class EORelationship; @class EOExpressionArray; @class EOSQLExpression; @interface EOEntity (EOEntityPrivate) - (BOOL)isPrototypeEntity; - (void)_setModel: (EOModel *)model; - (void)_setParentEntity: (EOEntity *)parent; -(Class)_classForInstances; - (void)_setInternalInfo: (NSDictionary *)dictionary; - (NSDictionary *)attributesByName; - (NSDictionary *)relationshipsByName; - (NSArray *)_allFetchSpecifications; - (NSDictionary *)_fetchSpecificationDictionary; - (void)_loadEntity; - (id)parentRelationship; - (int)_numberOfRelationships; - (BOOL)_hasReadOnlyAttributes; - (NSArray *)writableDBSnapshotKeys; - (NSArray *)rootAttributesUsedForLocking; - (BOOL)isSubEntityOf: (id)param0; - (id)initObject: (id)param0 editingContext: (id)param1 globalID: (id)param2; - (id)allocBiggestObjectWithZone: (NSZone *)zone; - (Class)_biggestClass; - (NSArray *)relationshipsPlist; - (id)rootParent; - (void)_setParent: (id)param0; - (NSArray *)_hiddenRelationships; - (NSArray *)_propertyNames; - (id)_flattenAttribute: (id)param0 relationshipPath: (id)param1 currentAttributes: (id)param2; - (NSString *)snapshotKeyForAttributeName: (NSString *)attributeName; - (id)_flattenedAttNameToSnapshotKeyMapping; - (EOMKKDSubsetMapping *)_snapshotToAdaptorRowSubsetMapping; - (EOMutableKnownKeyDictionary *)_dictionaryForPrimaryKey; - (EOMutableKnownKeyDictionary *)_dictionaryForProperties; - (EOMutableKnownKeyDictionary *)_dictionaryForInstanceProperties; - (NSArray *)_relationshipsToFaultForRow: (NSDictionary *)row; - (NSArray *)_classPropertyAttributes; - (NSArray *)_attributesToSave; - (NSArray *)_attributesToFetch; - (EOMKKDInitializer *)_adaptorDictionaryInitializer; - (EOMKKDInitializer *)_snapshotDictionaryInitializer; - (EOMKKDInitializer *)_primaryKeyDictionaryInitializer; - (EOMKKDInitializer *)_propertyDictionaryInitializer; - (EOMKKDInitializer *)_instanceDictionaryInitializer; - (void)_setIsEdited; - (NSArray *)_classPropertyAttributes; - (Class)classForObjectWithGlobalID: (EOKeyGlobalID *)globalID; - (id)globalIDForRow: (NSDictionary *)row isFinal: (BOOL)isFinal; - (BOOL) _hasAttributeNamed:(NSString *)name; @end @interface EOEntity (EOEntityRelationshipPrivate) - (EORelationship *)_inverseRelationshipPathForPath: (NSString *)path; - (NSDictionary *)_keyMapForRelationshipPath: (NSString *)path; - (NSDictionary*)_keyMapForIdenticalKeyRelationshipPath: (NSString *)path; - (EOAttribute*)_mapAttribute: (EOAttribute*)attribute toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path; - (BOOL)_relationshipPathIsToMany: (NSString *)relPath; - (BOOL)_relationshipPathHasIdenticalKeys: (id)param0; @end @interface EOEntity (EOEntitySQLExpression) - (NSString *)valueForSQLExpression: (EOSQLExpression *)sqlExpression; + (NSString *)valueForSQLExpression: (EOSQLExpression *)sqlExpression; @end @interface EOEntity (EOEntityPrivateXX) - (EOExpressionArray *)_parseDescription: (NSString *)description isFormat: (BOOL)isFormat arguments: (char *)param2; - (EOExpressionArray *)_parseRelationshipPath: (NSString *)path; - (id)_parsePropertyName: (NSString *)propertyName; //- (id)_newStringWithBuffer: (unsigned short *)param0 // length: (unsigned int *)param1; @end @interface EOEntity (MethodSet11) - (NSException *)validateObjectForDelete: (id)object; - (NSArray *)classPropertyAttributeNames; - (NSArray *)classPropertyToManyRelationshipNames; - (NSArray *)classPropertyToOneRelationshipNames; - (id)qualifierForDBSnapshot: (id)param0; - (void)_addAttributesToFetchForRelationshipPath: (NSString *)path atts: (NSMutableDictionary *)atts; - (NSArray *)dbSnapshotKeys; - (NSArray *)flattenedAttributes; @end #endif gnustep-dl2-0.12.0/EOAccess/EODefines.h0000644000175000017500000000334511140427401016364 0ustar ayersayers/* -*-objc-*- EODefines.h Copyright (C) 2003,2004,2005 Free Software Foundation, Inc. Author: Stephane Corthesy Date: Feb 2003 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOAccess_EODefines_h__ #define __EOAccess_EODefines_h__ #ifdef __cplusplus extern "C" { #endif #ifdef GNUSTEP_WITH_DLL #if BUILD_libEOAccess_DLL # if defined(__MINGW32__) /* On Mingw, the compiler will export all symbols automatically, so * __declspec(dllexport) is not needed. */ # define GDL2ACCESS_EXPORT extern # define GDL2ACCESS_DECLARE # else # define GDL2ACCESS_EXPORT __declspec(dllexport) # define GDL2ACCESS_DECLARE __declspec(dllexport) # endif #else # define GDL2ACCESS_EXPORT extern __declspec(dllimport) # define GDL2ACCESS_DECLARE __declspec(dllimport) #endif #else /* GNUSTEP_WITH[OUT]_DLL */ # define GDL2ACCESS_EXPORT extern # define GDL2ACCESS_DECLARE #endif #ifdef __cplusplus } #endif #endif /* __EOAccess_EODefines_h__ */ gnustep-dl2-0.12.0/EOAccess/EOSQLExpression.h0000644000175000017500000001736010645346232017543 0ustar ayersayers/* -*-objc-*- EOSQLExpression.h Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOSQLExpression_h__ #define __EOSQLExpression_h__ #ifdef GNUSTEP #include #include #include #else #include #endif #include #include #include @class NSArray; @class NSMutableArray; @class NSDictionary; @class NSMutableDictionary; @class EOAttribute; @class EOEntity; @class EOQualifier; @class EOKeyValueQualifier; @class EOKeyComparisonQualifier; @class EOSortOrdering; @class EOFetchSpecification; GDL2ACCESS_EXPORT NSString *EOBindVariableNameKey; GDL2ACCESS_EXPORT NSString *EOBindVariableAttributeKey; GDL2ACCESS_EXPORT NSString *EOBindVariableValueKey; GDL2ACCESS_EXPORT NSString *EOBindVariablePlaceHolderKey; GDL2ACCESS_EXPORT NSString *EOBindVariableColumnKey; @interface EOSQLExpression : NSObject { NSMutableDictionary *_aliasesByRelationshipPath; EOEntity *_entity; NSMutableString *_listString; NSMutableString *_valueListString; NSString *_whereClauseString; NSMutableString *_joinClauseString; NSMutableString *_orderByString; NSMutableArray *_bindings; NSMutableArray *_contextStack; NSString *_statement; struct { unsigned int useAliases:1; unsigned int hasOuterJoin:1; unsigned int _reserved:30; } _flags; @private int _alias; } + (EOSQLExpression *)expressionForString: (NSString *)string; + (EOSQLExpression *)insertStatementForRow: (NSDictionary *)row entity: (EOEntity *)entity; + (EOSQLExpression *)updateStatementForRow: (NSDictionary *)row qualifier: (EOQualifier *)qualifier entity: (EOEntity *)entity; /* The endity parameter is typed to 'id' for signature compatibility with EOF. Note that only EOEntity * objects should be passed. */ + (EOSQLExpression *)deleteStatementWithQualifier: (EOQualifier *)qualifier entity: (EOEntity *)entity; + (EOSQLExpression *)selectStatementForAttributes: (NSArray *)attributes lock: (BOOL)flag fetchSpecification: (EOFetchSpecification *)fetchSpecification entity: (EOEntity *)entity; + (id)sqlExpressionWithEntity: (EOEntity *)entity; - (id)initWithEntity: (EOEntity *)entity; - (NSMutableDictionary *)aliasesByRelationshipPath; - (EOEntity *)entity; - (NSMutableString *)listString; - (NSMutableString *)valueList; - (NSMutableString *)joinClauseString; - (NSMutableString *)orderByString; - (NSString *)whereClauseString; - (NSString *)statement; - (void)setStatement: (NSString *)statement; - (NSString *)lockClause; - (NSString *)tableListWithRootEntity: (EOEntity *)entity; - (void)prepareInsertExpressionWithRow: (NSDictionary *)row; - (void)prepareUpdateExpressionWithRow: (NSDictionary *)row qualifier: (EOQualifier *)qualifier; - (void)prepareDeleteExpressionForQualifier: (EOQualifier *)qualifier; - (void)prepareSelectExpressionWithAttributes: (NSArray *)attributes lock: (BOOL)flag fetchSpecification: (EOFetchSpecification *)fetchSpecification; - (NSString *)assembleJoinClauseWithLeftName: (NSString *)leftName rightName: (NSString *)rightName joinSemantic: (EOJoinSemantic)semantic; - (void)addJoinClauseWithLeftName: (NSString *)leftName rightName: (NSString *)rightName joinSemantic: (EOJoinSemantic)semantic; - (void)joinExpression; - (NSString *)assembleInsertStatementWithRow: (NSDictionary *)row tableList: (NSString *)tableList columnList: (NSString *)columnList valueList: (NSString *)valueList; - (NSString *)assembleUpdateStatementWithRow: (NSDictionary *)row qualifier: (EOQualifier *)qualifier tableList: (NSString *)tableList updateList: (NSString *)updateList whereClause: (NSString *)whereClause; - (NSString *)assembleDeleteStatementWithQualifier: (EOQualifier *)qualifier tableList: (NSString *)tableList whereClause: (NSString *)whereClause; - (NSString *)assembleSelectStatementWithAttributes: (NSArray *)attributes lock: (BOOL)lock qualifier: (EOQualifier *)qualifier fetchOrder: (NSArray *)fetchOrder selectString: (NSString *)selectString columnList: (NSString *)columnList tableList: (NSString *)tableList whereClause: (NSString *)whereClause joinClause: (NSString *)joinClause orderByClause: (NSString *)orderByClause lockClause: (NSString *)lockClause; - (void)addSelectListAttribute: (EOAttribute *)attribute; - (void)addInsertListAttribute: (EOAttribute *)attribute value: (NSString *)value; - (void)addUpdateListAttribute: (EOAttribute *)attribute value: (NSString *)value; + (NSString *)formatStringValue: (NSString *)string; + (NSString *)formatValue: (id)value forAttribute: (EOAttribute *)attribute; + (NSString *)formatSQLString: (NSString *)sqlString format: (NSString *)format; - (NSString *)sqlStringForConjoinedQualifiers: (NSArray *)qualifiers; - (NSString *)sqlStringForDisjoinedQualifiers: (NSArray *)qualifiers; - (NSString *)sqlStringForNegatedQualifier: (EOQualifier *)qualifier; - (NSString *)sqlStringForKeyValueQualifier: (EOKeyValueQualifier *)qualifier; - (NSString *)sqlStringForKeyComparisonQualifier: (EOKeyComparisonQualifier *)qualifier; - (NSString *)sqlStringForValue: (NSString *)valueString caseInsensitiveLikeKey: (NSString *)keyString; - (void)addOrderByAttributeOrdering: (EOSortOrdering *)sortOrdering; + (BOOL)useQuotedExternalNames; + (void)setUseQuotedExternalNames: (BOOL)flag; - (NSString *)externalNameQuoteCharacter; - (void)setUseAliases: (BOOL)useAliases; - (BOOL)useAliases; - (NSString *)sqlStringForSchemaObjectName: (NSString *)name; - (NSString *)sqlStringForAttributeNamed: (NSString *)name; - (NSString *)sqlStringForSelector: (SEL)selector value: (id)value; - (NSString *)sqlStringForValue: (id)value attributeNamed: (NSString *)attributeName; - (NSString *)sqlStringForAttribute: (EOAttribute *)attribute; - (NSString *)sqlStringForAttributePath: (NSArray *)path; - (void)appendItem: (NSString *)itemString toListString: (NSMutableString *)listString; + (NSString *)sqlPatternFromShellPattern: (NSString *)pattern; + (NSString *)sqlPatternFromShellPattern: (NSString *)pattern withEscapeCharacter: (unichar)escapeCharacter; - (NSMutableDictionary *)bindVariableDictionaryForAttribute: (EOAttribute *)attribute value: (id)value; - (BOOL)shouldUseBindVariableForAttribute: (EOAttribute *)att; - (BOOL)mustUseBindVariableForAttribute: (EOAttribute *)att; + (BOOL)useBindVariables; + (void)setUseBindVariables: (BOOL)flag; - (NSArray *)bindVariableDictionaries; - (void)addBindVariableDictionary: (NSMutableDictionary *)binding; @end @interface NSString (EOSQLFormatting) - (NSString *)sqlString; @end @interface NSNumber (EOSQLFormatting) - (NSString *)sqlString; @end #endif /* __EOSQLExpression_h__ */ gnustep-dl2-0.12.0/EOAccess/EOUtilities.h0000644000175000017500000001027710645346232016777 0ustar ayersayers/* -*-objc-*- EOUtilities.h Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Manuel Guesdon Date: Sep 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOUtilities_h__ #define __EOUtilities_h__ #include #include #include #include @class NSArray; @class NSDictionary; @class NSString; @class EODatabaseContext; @class EOModelGroup; @class EOEntity; GDL2ACCESS_EXPORT NSString *EOMoreThanOneException; @interface EOEditingContext (EOUtilities) - (NSArray *)objectsForEntityNamed: (NSString *)entityName; - (NSArray *)objectsOfClass: (Class)classObject; - (NSArray *)objectsWithFetchSpecificationNamed: (NSString *)fetchSpecName entityNamed: (NSString *)entityName bindings: (NSDictionary *)bindings; - (NSArray *)objectsForEntityNamed: (NSString *)entityName qualifierFormat: (NSString *)format, ...; - (NSArray *)objectsMatchingValue: (id)value forKey: (NSString *)key entityNamed: (NSString *)entityName; - (NSArray *)objectsMatchingValues: (NSDictionary *)values entityNamed: (NSString *)entityName; - (id)objectWithFetchSpecificationNamed: (NSString *)fetchSpecName entityNamed: (NSString *)entityName bindings: (NSDictionary *)bindings; - (id)objectForEntityNamed: (NSString *)entityName qualifierFormat: (NSString *)format, ...; - (id)objectMatchingValue: (id)value forKey: (NSString *)key entityNamed: (NSString *)entityName; - (id)objectMatchingValues: (NSDictionary *)values entityNamed: (NSString *)entityName; - (id)objectWithPrimaryKeyValue: (id)value entityNamed: (NSString *)entityName; - (id)objectWithPrimaryKey: (NSDictionary *)pkDict entityNamed: (NSString *)entityName; - (NSArray *)rawRowsForEntityNamed: (NSString *)entityName qualifierFormat: (NSString *)format, ...; - (NSArray *)rawRowsMatchingValue: (id)value forKey: (NSString *)key entityNamed: (NSString *)entityName; - (NSArray *)rawRowsMatchingValues: (NSDictionary *)values entityNamed: (NSString *)entityName; - (NSArray *)rawRowsWithSQL: (NSString *)sqlString modelNamed: (NSString *)name; - (NSArray *)rawRowsWithStoredProcedureNamed: (NSString *)name arguments: (NSDictionary *)args; - (NSDictionary *)executeStoredProcedureNamed: (NSString *)name arguments: (NSDictionary *)args; - (id)objectFromRawRow: (NSDictionary *)row entityNamed: (NSString *)entityName; - (EODatabaseContext *)databaseContextForModelNamed: (NSString *)name; - (void)connectWithModelNamed: (NSString *)name connectionDictionaryOverrides: (NSDictionary *)overrides; - (id)createAndInsertInstanceOfEntityNamed: (NSString *)entityName; - (NSDictionary *)primaryKeyForObject: (id)object; - (NSDictionary *)destinationKeyForSourceObject: (id)object relationshipNamed: (NSString *)name; - (id)localInstanceOfObject: (id)object; - (NSArray *)localInstancesOfObjects: (NSArray *)objects; - (EOModelGroup *)modelGroup; - (EOEntity *)entityNamed: (NSString *)entityName; - (EOEntity *)entityForClass: (Class)classObject; - (EOEntity *)entityForObject: (id)object; @end @interface EOFetchSpecification (EOAccess) + (EOFetchSpecification *)fetchSpecificationNamed: (NSString *)name entityNamed: (NSString *)entityName; @end #endif gnustep-dl2-0.12.0/EOAccess/EOGenericRecord.h0000644000175000017500000000227511147237512017534 0ustar ayersayers/* -*-objc-*- EOGenericRecord.h Copyright (C) 2009 Free Software Foundation, Inc. Author: David Ayers Date: February 2009 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOAccess_EOGenericRecord_h__ #define __EOAccces_EOGenericRecord_h__ #include @class EOEntity; @interface EOGenericRecord (EOAccessAdditions) - (EOEntity *)entity; @end #endif /* __EOAccess_EOGenericRecord_h__ */ gnustep-dl2-0.12.0/EOAccess/EOExpressionArray.h0000644000175000017500000000573410645346232020164 0ustar ayersayers/* -*-objc-*- EOExpressionArray.h Copyright (C) 1996,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Ovidiu Predescu Date: September 1996 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOExpressionArray_h__ #define __EOExpressionArray_h__ #ifdef GNUSTEP #include #else #include #endif @class NSArray; @class EOAttribute; @class EOEntity; @class EOSQLExpression; @protocol EOExpressionContext - (NSString *)expressionValueForAttribute: (EOAttribute *)attribute; - (NSString *)expressionValueForAttributePath: (NSArray *)path; @end @interface EOExpressionArray : NSMutableArray { NSString *_prefix; NSString *_infix; NSString *_suffix; // NSString *_definition; it's rebuilt EOAttribute *_realAttribute; void *_contents; struct { unsigned int isFlattened:1; //TODO Why ? } _flags; } + (EOExpressionArray *)expressionArray; + (EOExpressionArray *)expressionArrayWithPrefix: (NSString *)prefix infix: (NSString *)infix suffix: (NSString *)suffix; /* Initializing instances */ - (id)initWithPrefix: (NSString *)prefix infix: (NSString *)infix suffix: (NSString *)suffix; - (NSString *)prefix; - (NSString *)infix; - (NSString *)suffix; - (NSString *)definition; - (BOOL)isFlattened; - (EOAttribute *)realAttribute; /* Accessing the components */ - (void)setPrefix: (NSString *)prefix; - (void)setInfix: (NSString *)infix; - (void)setSuffix: (NSString *)suffix; /* Checking contents */ - (BOOL)referencesObject: (id)object; - (NSString *)expressionValueForContext: (id)ctx; /*+ (EOExpressionArray *)parseExpression: (NSString *)expression entity: (EOEntity *)entity replacePropertyReferences: (BOOL)flag;*/ - (NSString *)valueForSQLExpression: (EOSQLExpression *)sqlExpression; @end /* EOExpressionArray */ @interface NSObject (EOExpression) - (NSString *)expressionValueForContext: (id)context; @end @interface NSString (EOAttributeTypeCheck) - (BOOL)isNameOfARelationshipPath; @end #endif /* __EOExpressionArray_h__ */ gnustep-dl2-0.12.0/EOAccess/GNUmakefile0000644000175000017500000000551411147237512016475 0ustar ayersayers# # EOAccess makefile for GNUstep Database Library. # # Copyright (C) 2000-2002,2003,2004,2005 Free Software Foundation, Inc. # # Author: Mirko Viviani # # 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 3 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, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # include ../common.make include $(GNUSTEP_MAKEFILES)/common.make include ../Version # The library to be compiled NATIVE_LIBRARY_NAME=EOAccess EOAccess_NEEDS_GUI = no # The C source files to be compiled EOAccess_C_FILES = # The Objective-C source files to be compiled EOAccess_OBJC_FILES = \ EOModelGroup.m \ EOModel.m \ EOEntity.m \ EOAttribute.m \ EORelationship.m \ EOJoin.m \ EOStoredProcedure.m \ EOExpressionArray.m \ EOAdaptor.m \ EOAdaptorContext.m \ EOAdaptorChannel.m \ EOAdaptorOperation.m \ EODatabaseOperation.m \ EOSchemaGeneration.m \ EOSchemaSynchronization.m \ EOSQLExpression.m \ EOSQLQualifier.m \ EODatabase.m \ EODatabaseChannel.m \ EODatabaseContext.m \ EOAccessFault.m \ EODatabaseDataSource.m \ EOGenericRecord.m \ EOUtilities.m \ EOPrivate.m EOAccess_HEADER_FILES_DIR = . EOAccess_HEADER_FILES = \ EOModelGroup.h \ EOModel.h \ EOEntity.h \ EOAttribute.h \ EORelationship.h \ EOJoin.h \ EOStoredProcedure.h \ EOAdaptor.h \ EOAdaptorContext.h \ EOAdaptorChannel.h \ EODatabaseOperation.h \ EOSQLExpression.h \ EOSQLQualifier.h \ EODatabase.h \ EODatabaseChannel.h \ EODatabaseContext.h \ EOAccessFault.h \ EOPropertyListEncoding.h \ EODatabaseDataSource.h \ EOSchemaSynchronization.h \ EOSchemaGeneration.h \ EOGenericRecord.h \ EOUtilities.h \ EODefines.h \ EODeprecated.h \ EOAccess.h DOCUMENT_NAME = EOAccess # autogsdoc scan the source files corresponding to the headers EOAccess_AGSDOC_FILES = EOAccess.gsdoc \ $(EOAccess_HEADER_FILES) \ $(EOAccess_OBJC_FILES) EOAccess_AGSDOC_FLAGS = \ -Declared EOAccess \ -Project EOAccess \ -Up EOAccess \ $(GDL2_AGSDOC_FLAGS) -include Makefile.preamble -include GNUmakefile.local include $(GNUSTEP_MAKEFILES)/native-library.make # Only build the doc if doc=yes was passed on the command line ifeq ($(doc),yes) include $(GNUSTEP_MAKEFILES)/documentation.make endif -include Makefile.postamble gnustep-dl2-0.12.0/EOAccess/EOSchemaSynchronization.h0000644000175000017500000001427410645346232021347 0ustar ayersayers/* -*-objc-*- EOSchemaSynchronization.h Copyright (C) 2007 Free Software Foundation, Inc. Date: July 2007 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOAccess_EOSchemaSynchronization_h__ #define __EOAccess_EOSchemaSynchronization_h__ #include #include #include GDL2ACCESS_EXPORT NSString *EOSchemaSynchronizationForeignKeyConstraintsKey; GDL2ACCESS_EXPORT NSString *EOSchemaSynchronizationPrimaryKeyConstraintsKey; GDL2ACCESS_EXPORT NSString *EOSchemaSynchronizationPrimaryKeySupportKey; GDL2ACCESS_EXPORT NSString *EOAllowsNullKey; GDL2ACCESS_EXPORT NSString *EOColumnNameKey; GDL2ACCESS_EXPORT NSString *EOExternalNameKey; GDL2ACCESS_EXPORT NSString *EOExternalTypeKey; GDL2ACCESS_EXPORT NSString *EONameKey; GDL2ACCESS_EXPORT NSString *EOPrecisionKey; GDL2ACCESS_EXPORT NSString *EORelationshipsKey; GDL2ACCESS_EXPORT NSString *EOScaleKey; GDL2ACCESS_EXPORT NSString *EOWidthKey; @protocol EOColumnTypes - (NSString *)name; - (unsigned)precision; - (int)scale; - (unsigned)width; @end @interface EOAdaptor (EOSchemaSynchronization) - (NSDictionary *)objectStoreChangesFromAttribute:(EOAttribute *)schemaAttribute toAttribute:(EOAttribute *)modelAttribute; @end @interface EOAdaptorChannel (EOSchemaSynchronization) - (void)beginSchemaSynchronization; - (void)endSchemaSynchronization; @end @interface NSObject (EOSchemaSynchronizationDelegates) - (BOOL)allowsNullForColumnNamed:(NSString *)columnName inSchemaTableNamed:(NSString *)tableName; - (BOOL)isSchemaTableNamed:(NSString *)tableName; - (EOAdaptor *)schemaSynchronizationAdaptor; - (EOAdaptorChannel *)schemaSynchronizationAdaptorChannelForModel:(EOModel *)model; - (void)schemaSynchronizationStatements:(NSArray *)statements willCopyTableNamed:(NSString *)tableName; - (void)schemaSynchronizationStatements:(NSArray *)statements willDeleteTableNamed:(NSString *)tableName; @end @interface EOSQLExpression (EOSchemaSynchronization) + (BOOL)isCaseSensitive; + (BOOL)isColumnType:(id )columnType1 equivalentToColumnType:(id )columnType2 options:(NSDictionary *)options; + (NSArray *)logicalErrorsInChangeDictionary:(NSDictionary *)changes forModel:(EOModel *)model options:(NSDictionary *)options; + (NSString *)phraseCastingColumnNamed:(NSString *)columnName fromType:(id )type toType:(id )castType options:(NSDictionary *)options; + (id)schemaSynchronizationDelegate; + (void)setSchemaSynchronizationDelegate:(id)delegate; + (NSArray *)statementsToCopyTableNamed:(NSString *)tableName intoTableForEntityGroup:(NSArray *)entityGroup withChangeDictionary:(NSDictionary *)changes options:(NSDictionary *)options; + (NSArray *)statementsToModifyColumnNamed:(NSString *)columnName inTableNamed:(NSString *)tableName toNullRule:(BOOL)allowsNull options:(NSDictionary *)options; + (NSArray *)statementsToConvertColumnNamed:(NSString *)columnName inTableNamed:(NSString *)tableName fromType:(id )type toType:(id )newType options:(NSDictionary *)options; + (NSArray *)statementsToDeleteColumnNamed:(NSString *)columnName inTableNamed:(NSString *)tableName options:(NSDictionary *)options; + (NSArray *)statementsToInsertColumnForAttribute:(EOAttribute *)attribute options:(NSDictionary *)options; + (NSArray *)statementsToRenameColumnNamed:(NSString *)columnName inTableNamed:(NSString *)tableName newName:(NSString *)newName options:(NSDictionary *)options; + (NSArray *)statementsToDropForeignKeyConstraintsOnEntityGroups:(NSArray *)entityGroups withChangeDictionary:(NSDictionary *)changes options:(NSDictionary *)options; + (NSArray *)statementsToDropPrimaryKeyConstraintsOnEntityGroups:(NSArray *)entityGroups withChangeDictionary:(NSDictionary *)changes options:(NSDictionary *)options; + (NSArray *)statementsToDropPrimaryKeySupportForEntityGroups:(NSArray *)entityGroups withChangeDictionary:(NSDictionary *)changes options:(NSDictionary *)options; + (NSArray *)statementsToImplementForeignKeyConstraintsOnEntityGroups:(NSArray *)entityGroups withChangeDictionary:(NSDictionary *)changes options:(NSDictionary *)options; + (NSArray *)statementsToImplementPrimaryKeyConstraintsOnEntityGroups:(NSArray *)entityGroups withChangeDictionary:(NSDictionary *)changes options:(NSDictionary *)options; + (NSArray *)statementsToImplementPrimaryKeySupportForEntityGroups:(NSArray *)entityGroups withChangeDictionary:(NSDictionary *)changes options:(NSDictionary *)options; + (NSArray *)statementsToRenameTableNamed:(NSString *)tableName newName:(NSString *)newName options:(NSDictionary *)options; + (NSArray *)statementsToUpdateObjectStoreForModel:(EOModel *)model withChangeDictionary:(NSDictionary *)changes options:(NSDictionary *)options; + (NSArray *)statementsToUpdateObjectStoreForEntityGroups:(NSArray *)entityGroups withChangeDictionary:(NSDictionary *)changes options:(NSDictionary *)options; + (BOOL)supportsDirectColumnNullRuleModification; + (BOOL)supportsDirectColumnCoercion; + (BOOL)supportsDirectColumnDeletion; + (BOOL)supportsDirectColumnInsertion; + (BOOL)supportsDirectColumnRenaming; + (BOOL)supportsSchemaSynchronization; @end #endif gnustep-dl2-0.12.0/EOAccess/EOAccessFault.h0000644000175000017500000000641410645346232017217 0ustar ayersayers/* -*-objc-*- EOAccessFault.h Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: June 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOAccessFault_h__ #define __EOAccessFault_h__ #include #include @class EODatabaseContext; @class EOEditingContext; @class EOKeyGlobalID; @class NSString; @interface EOAccessGenericFaultHandler : EOFaultHandler { unsigned int _generation; EOAccessGenericFaultHandler *_next; EOAccessGenericFaultHandler *_prev; } - (void)linkAfter: (EOAccessGenericFaultHandler *)faultHandler usingGeneration: (unsigned int)gen; - (EOAccessGenericFaultHandler *)next; - (EOAccessGenericFaultHandler *)previous; - (unsigned int)generation; @end @interface EOAccessFaultHandler : EOAccessGenericFaultHandler { EOKeyGlobalID *gid; EODatabaseContext *databaseContext; EOEditingContext *editingContext; } + (EOAccessFaultHandler *)accessFaultHandlerWithGlobalID: (EOKeyGlobalID *)globalID databaseContext: (EODatabaseContext *)dbcontext editingContext: (EOEditingContext *)ec; - (id)initWithGlobalID: (EOKeyGlobalID *)globalID databaseContext: (EODatabaseContext *)dbcontext editingContext: (EOEditingContext *)ec; - (EOKeyGlobalID *)globalID; - (EODatabaseContext *)databaseContext; - (EOEditingContext *)editingContext; @end @interface EOAccessArrayFaultHandler : EOAccessGenericFaultHandler { EOKeyGlobalID *sgid; NSString *relationshipName; EODatabaseContext *databaseContext; EOEditingContext *editingContext; id copy; } + (EOAccessArrayFaultHandler *)accessArrayFaultHandlerWithSourceGlobalID: (EOKeyGlobalID *)sourceGID relationshipName: (NSString *)relName databaseContext: (EODatabaseContext *)dbcontext editingContext: (EOEditingContext *)ec; - (id)initWithSourceGlobalID: (EOKeyGlobalID *)sourceGID relationshipName: (NSString *)relName databaseContext: (EODatabaseContext *)dbcontext editingContext: (EOEditingContext *)ec; - (EOKeyGlobalID *)sourceGlobalID; - (NSString *)relationshipName; - (EODatabaseContext *)databaseContext; - (EOEditingContext *)editingContext; @end @interface NSObject (EOAccessFaultUnableToFaultToOne) - (void)unableToFaultObject: (id)object databaseContext: (EODatabaseContext *)context; @end @interface EOFault (EOAccess) - (EODatabaseContext *)databaseContext; @end GDL2ACCESS_EXPORT NSString *EOAccessFaultObjectNotAvailableException; #endif gnustep-dl2-0.12.0/EOAccess/EOSQLExpression.m0000644000175000017500000022251111147237512017542 0ustar ayersayers/** EOSQLExpression.m EOSQLExpression Class Copyright (C) 2000-2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 Author: Manuel Guesdon Date: November 2001 $Revision: 27922 $ $Date: 2009-02-19 12:15:22 +0100 (Don, 19. Feb 2009) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EOSQLExpression.m 27922 2009-02-19 11:15:22Z ayers $") #include #ifdef GNUSTEP #include #include #include #include #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "EOPrivate.h" #include "EOEntityPriv.h" #include "EOAttributePriv.h" #include "EOSQLExpressionPriv.h" NSString *EOBindVariableNameKey = @"EOBindVariableNameKey"; NSString *EOBindVariableAttributeKey = @"EOBindVariableAttributeKey"; NSString *EOBindVariableValueKey = @"EOBindVariableValueKey"; NSString *EOBindVariablePlaceHolderKey = @"EOBindVariablePlaceHolderKey"; NSString *EOBindVariableColumnKey = @"EOBindVariableColumnKey"; @interface EOSQLExpression(Private) + (id)sqlExpressionWithEntity: (EOEntity *)entity; @end @implementation EOSQLExpression + (void) initialize { static BOOL initialized=NO; if (!initialized) { GDL2_EOAccessPrivateInit(); }; }; + (id)sqlExpressionWithEntity: (EOEntity *)entity { return [[[self alloc] initWithEntity: entity] autorelease]; } - (id) initWithEntity: (EOEntity *)entity { if ((self = [self init])) { ASSIGN(_entity, entity); _aliasesByRelationshipPath = [NSMutableDictionary new]; [_aliasesByRelationshipPath setObject: @"t0" forKey: @""]; _contextStack = [NSMutableArray new]; [_contextStack addObject: @""]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"added '%@' (t0) in contextStack => %@", @"",_contextStack); /*NOT now _listString = [NSMutableString new]; _valueListString = [NSMutableString new]; _joinClauseString = [NSMutableString new]; _orderByString = [NSMutableString new]; _bindings = [NSMutableArray new]; */ _alias++; } return self; } - (void)dealloc { DESTROY(_aliasesByRelationshipPath); DESTROY(_entity); DESTROY(_listString); DESTROY(_valueListString); DESTROY(_whereClauseString); DESTROY(_joinClauseString); DESTROY(_orderByString); DESTROY(_bindings); DESTROY(_contextStack); DESTROY(_statement); [super dealloc]; } + (EOSQLExpression *)expressionForString: (NSString *)string { EOSQLExpression *exp = [self sqlExpressionWithEntity: nil]; ASSIGN(exp->_statement, string); return exp; } + (EOSQLExpression *)insertStatementForRow: (NSDictionary *)row entity: (EOEntity *)entity { EOSQLExpression *sqlExpression; if (!entity) [NSException raise: NSInvalidArgumentException format: @"EOSQLExpression: Entity of insertStatementForRow:entity: can't be the nil object"]; sqlExpression = [self sqlExpressionWithEntity: entity]; NSAssert(sqlExpression, @"No SQLExpression"); [sqlExpression setUseAliases: NO]; [sqlExpression prepareInsertExpressionWithRow: row]; return sqlExpression; } + (EOSQLExpression *)updateStatementForRow: (NSDictionary *)row qualifier: (EOQualifier *)qualifier entity: (EOEntity *)entity { EOSQLExpression *sqlExpression; if(!row || ![row count]) [NSException raise: NSInvalidArgumentException format: @"EOSQLExpression: Row of updateStatementForRow:qualifier:entity: " @"can't be the nil object or empty dictionary"]; if (!qualifier) [NSException raise: NSInvalidArgumentException format: @"EOSQLExpression: Qualifier of updateStatementForRow:qualifier:entity: " @"can't be the nil object"]; if (!entity) [NSException raise: NSInvalidArgumentException format: @"EOSQLExpression: Entity of updateStatementForRow:qualifier:entity: " @"can't be the nil object"]; sqlExpression = [self sqlExpressionWithEntity: entity]; NSAssert(sqlExpression, @"No SQLExpression"); [sqlExpression setUseAliases: NO]; [sqlExpression prepareUpdateExpressionWithRow: row qualifier: qualifier]; return sqlExpression; } + (EOSQLExpression *)deleteStatementWithQualifier: (EOQualifier *)qualifier entity: (EOEntity *)entity { EOSQLExpression *sqlExpression; if (!qualifier) [NSException raise: NSInvalidArgumentException format: @"EOSQLExpression: Qualifier of deleteStatementWithQualifier:entity: " @"can't be the nil object"]; if (!entity) [NSException raise: NSInvalidArgumentException format: @"EOSQLExpression: Entity of deleteStatementWithQualifier:entity: " @"can't be the nil object"]; sqlExpression = [self sqlExpressionWithEntity: entity]; [sqlExpression prepareDeleteExpressionForQualifier: qualifier]; return sqlExpression; } + (EOSQLExpression *)selectStatementForAttributes: (NSArray *)attributes lock: (BOOL)flag fetchSpecification: (EOFetchSpecification *)fetchSpecification entity: (EOEntity *)entity { EOSQLExpression *sqlExpression; if (!attributes || ![attributes count]) [NSException raise: NSInvalidArgumentException format: @"EOSQLExpression: Attributes of selectStatementForAttributes:lock:fetchSpecification:entity: " @"can't be the nil object or empty array"]; if (!fetchSpecification) [NSException raise: NSInvalidArgumentException format: @"EOSQLExpression: FetchSpecification of selectStatementForAttributes:lock:fetchSpecification:entity: " @"can't be the nil object"]; if (!entity) [NSException raise: NSInvalidArgumentException format: @"EOSQLExpression: Entity of selectStatementForAttributes:lock:fetchSpecification:entity: " @"can't be the nil object"]; sqlExpression = [self sqlExpressionWithEntity: entity]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sqlExpression=%@", sqlExpression); [sqlExpression setUseAliases: YES]; [sqlExpression prepareSelectExpressionWithAttributes: attributes lock: flag fetchSpecification: fetchSpecification]; return sqlExpression; } - (NSMutableDictionary *)aliasesByRelationshipPath { return _aliasesByRelationshipPath; } - (EOEntity *)entity { return _entity; } - (NSMutableString *)listString { //OK if (!_listString) _listString = [NSMutableString new]; return _listString; } - (NSMutableString *)valueList { if (!_valueListString) _valueListString = [NSMutableString new]; return _valueListString; } - (NSMutableString *)joinClauseString { if (!_joinClauseString) _joinClauseString = [NSMutableString new]; return _joinClauseString; } - (NSMutableString *)orderByString { //OK if (!_orderByString) _orderByString = [NSMutableString new]; return _orderByString; } - (NSString *)whereClauseString { if (!_whereClauseString) _whereClauseString = [NSMutableString new]; return _whereClauseString; } - (NSString *)statement { return _statement; } - (void)setStatement:(NSString *)statement { ASSIGN(_statement, statement); } - (NSString *)lockClause { [self subclassResponsibility: _cmd]; return nil; } - (NSString *)tableListWithRootEntity: (EOEntity*)entity { //self useAliases //ret 1 for select,0 for insert //enity externalName //self sqlStringForSchemaObjectName:eznti extnam//not always // insert: ret quotation_place ?? / select: ret quotation_place t0 NSMutableString *entitiesString = [NSMutableString string]; IMP entitiesStringAppendStringIMP = NULL; NSEnumerator *relationshipEnum = nil; NSString *relationshipPath = nil; EOEntity *currentEntity = nil; int i = 0; EOFLOGObjectFnStartCond(@"EOSQLExpression"); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"entity=%@", entity); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"_aliasesByRelationshipPath=%@", _aliasesByRelationshipPath); relationshipEnum = [_aliasesByRelationshipPath keyEnumerator]; while ((relationshipPath = [relationshipEnum nextObject])) { currentEntity = entity; if (i) GDL2_AppendStringWithImp(entitiesString, entitiesStringAppendStringIMP,@", "); else entitiesStringAppendStringIMP = [entitiesString methodForSelector:@selector(appendString:)]; if ([relationshipPath isEqualToString: @""]) { NSString *tableName = [currentEntity externalName]; tableName = [self sqlStringForSchemaObjectName: tableName]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"entity %p named %@: " @"externalName=%@ tableName=%@", currentEntity, [currentEntity name], [currentEntity externalName], tableName); NSAssert1([[currentEntity externalName] length]>0, @"No external name for entity %@", [currentEntity name]); GDL2_AppendStringWithImp(entitiesString, entitiesStringAppendStringIMP,tableName); if (_flags.useAliases) [entitiesString appendFormat: @" %@", [_aliasesByRelationshipPath objectForKey: relationshipPath]]; } else { NSEnumerator *defEnum = nil; NSArray *defArray = nil; NSString *relationshipString = nil; NSString *tableName = nil; defArray = [relationshipPath componentsSeparatedByString: @"."]; defEnum = [defArray objectEnumerator]; while ((relationshipString = [defEnum nextObject])) { // use anyRelationshipNamed: to find hidden relationship too EORelationship *relationship=[currentEntity anyRelationshipNamed: relationshipString]; NSAssert2(relationship,@"No relationship named %@ in entity %@", relationshipString, [currentEntity name]); NSAssert2(currentEntity,@"No destination entity. Entity %@ relationship = %@", [currentEntity name], relationship); currentEntity = [relationship destinationEntity]; } tableName = [currentEntity externalName]; tableName = [self sqlStringForSchemaObjectName: tableName]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"entity %p named %@: " @"externalName=%@ tableName=%@", currentEntity, [currentEntity name], [currentEntity externalName], tableName); NSAssert1([[currentEntity externalName] length]>0, @"No external name for entity %@", [currentEntity name]); GDL2_AppendStringWithImp(entitiesString, entitiesStringAppendStringIMP,tableName); if (_flags.useAliases) { NSString *alias = [_aliasesByRelationshipPath objectForKey: relationshipPath]; GDL2_AppendStringWithImp(entitiesString, entitiesStringAppendStringIMP,@" "); GDL2_AppendStringWithImp(entitiesString, entitiesStringAppendStringIMP,alias); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"appending alias %@ in entitiesString", alias); } } i++; } EOFLOGObjectLevelArgs(@"EOSQLExpression", @"entitiesString=%@", entitiesString); EOFLOGObjectFnStopCond(@"EOSQLExpression"); return entitiesString; } - (void)prepareInsertExpressionWithRow: (NSDictionary *)row { //OK EOEntity *rootEntity = nil; NSString *tableList = nil; NSEnumerator *rowEnum; NSString *attributeName; EOFLOGObjectFnStartCond(@"EOSQLExpression"); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"row=%@", row); NS_DURING //Debugging Purpose { rowEnum = [row keyEnumerator]; while ((attributeName = [rowEnum nextObject])) { EOAttribute *attribute = [_entity anyAttributeNamed: attributeName]; id rowValue = [row objectForKey: attributeName]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"attribute name=%@", attributeName); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"rowValue=%@", rowValue); /*NO: in addInsertListAttribute id value=[self sqlStringForValue:rowValue attributeNamed:attributeName];*/ [self addInsertListAttribute: attribute value: rowValue]; } } NS_HANDLER { NSDebugMLog(@"EXCEPTION %@", localException); [localException raise]; } NS_ENDHANDLER; NS_DURING //Debugging Purpose { rootEntity = [self _rootEntityForExpression]; tableList = [self tableListWithRootEntity: _entity]; ASSIGN(_statement, [self assembleInsertStatementWithRow: row tableList: tableList columnList: _listString valueList: _valueListString]); } NS_HANDLER { NSDebugMLog(@"EXCEPTION %@", localException); [localException raise]; } NS_ENDHANDLER; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"_statement=%@", _statement); EOFLOGObjectFnStopCond(@"EOSQLExpression"); } - (void)prepareUpdateExpressionWithRow: (NSDictionary *)row qualifier: (EOQualifier *)qualifier { //OK EOEntity *rootEntity = nil; NSString *whereClauseString = nil; NSString *tableList = nil; NSString *statement = nil; NSEnumerator *rowEnum; NSString *attributeName; EOFLOGObjectFnStartCond(@"EOSQLExpression"); rowEnum = [row keyEnumerator]; while ((attributeName = [rowEnum nextObject])) { id attribute = [_entity attributeNamed: attributeName]; id value = [row objectForKey: attributeName]; [self addUpdateListAttribute: attribute value: value]; } EOFLOGObjectLevelArgs(@"EOSQLExpression", @"qualifier=%@", qualifier); whereClauseString = [(id )qualifier sqlStringForSQLExpression: self]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"whereClauseString=%@", whereClauseString); ASSIGN(_whereClauseString, whereClauseString); rootEntity = [self _rootEntityForExpression]; tableList = [self tableListWithRootEntity: rootEntity]; statement = [self assembleUpdateStatementWithRow: row qualifier: qualifier tableList: tableList updateList: _listString whereClause: whereClauseString]; ASSIGN(_statement, statement); EOFLOGObjectFnStopCond(@"EOSQLExpression"); } - (void)prepareDeleteExpressionForQualifier: (EOQualifier *)qualifier { ASSIGN(_whereClauseString, [(id)qualifier sqlStringForSQLExpression: self]); ASSIGN(_statement, [self assembleDeleteStatementWithQualifier: qualifier tableList: [self tableListWithRootEntity: _entity] whereClause: ([_whereClauseString length] ? _whereClauseString : nil)]); } /* //TC: - (void)prepareSelectExpressionWithAttributes:(NSArray *)attributes lock:(BOOL)flag fetchSpecification:(EOFetchSpecification *)fetchSpecification { NSEnumerator *attrEnum, *sortEnum; EOAttribute *attribute; EOSortOrdering *sort; NSString *tableList; NSString *lockClause = nil; NSArray *sortOrderings; EOFLOGObjectFnStartCond(@"EOSQLExpression"); // Turbocat (RawRow Additions) if ([fetchSpecification rawRowKeyPaths]) { // fill _aliasesByRelationshipPath before calling addSelectListAttribute NSEnumerator *keyPathEnum = [[fetchSpecification rawRowKeyPaths] objectEnumerator]; NSString *keyPath; EOExpressionArray *expressionArray; while (keyPath = [keyPathEnum nextObject]) { if([keyPath isNameOfARelationshipPath]) { // get relationships NSString *newKeyPath = [keyPath stringByDeletingPathExtension]; // cut attributename if (![_aliasesByRelationshipPath objectForKey:newKeyPath]) { //int count = [[_aliasesByRelationshipPath allKeys] count]; NSString *prefix = [NSString stringWithFormat:@"t%d",_alias++]; [_aliasesByRelationshipPath setObject:prefix forKey:newKeyPath]; } } } //NSLog(@"_aliasesByRelationshipPath = %@", _aliasesByRelationshipPath); } // Turbocat (RawRow Additions) attrEnum = [attributes objectEnumerator]; while((attribute = [attrEnum nextObject])) { [self addSelectListAttribute:attribute]; } ASSIGN(_whereClauseString, [(id)[fetchSpecification qualifier] sqlStringForSQLExpression:self]); sortOrderings = [fetchSpecification sortOrderings]; sortEnum = [sortOrderings objectEnumerator]; while((sort = [sortEnum nextObject])) [self addOrderByAttributeOrdering:sort]; [self joinExpression]; tableList = [self tableListWithRootEntity:_entity]; if(flag) lockClause = [self lockClause]; ASSIGN(_statement, [self assembleSelectStatementWithAttributes:attributes lock:flag qualifier:[fetchSpecification qualifier] fetchOrder:sortOrderings selectString:nil //TODO columnList:_listString tableList:tableList whereClause:([_whereClauseString length] ? _whereClauseString : nil) joinClause:([_joinClauseString length] ? _joinClauseString : nil) orderByClause:([_orderByString length] ? _orderByString : nil) lockClause:lockClause]); EOFLOGObjectFnStopCond(@"EOSQLExpression"); } */ - (void)prepareSelectExpressionWithAttributes: (NSArray *)attributes lock: (BOOL)flag fetchSpecification: (EOFetchSpecification *)fetchSpecification { EOQualifier *fetchQualifier = nil; EOQualifier *restrictingQualifier = nil; NSString *whereClauseString = nil; NSArray *sortOrderings = nil; EOEntity *rootEntity = nil; NSString *tableList = nil; NSString *lockClauseString = nil; BOOL usesDistinct = NO; NSString *statement = nil; NSString *selectCommand = nil; //Add Attributes to listString int i, count = [attributes count]; EOFLOGObjectFnStartCond(@"EOSQLExpression"); //OK for (i = 0; i < count; i++) { EOAttribute *attribute = [attributes objectAtIndex: i]; if ([attribute isFlattened]) { NSEmitTODO(); //TODO??? EOFLOGObjectLevelArgs(@"EOSQLExpression", @"flattened attribute=%@", attribute); } else [self addSelectListAttribute: attribute]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"_listString=%@", _listString); } EOFLOGObjectLevelArgs(@"EOSQLExpression", @"_listString=%@", _listString); fetchQualifier = [fetchSpecification qualifier]; //OK //call fetchSpecification -isDeep EOFLOGObjectLevelArgs(@"EOSQLExpression", @"fetchQualifier=%@", fetchQualifier); restrictingQualifier = [_entity restrictingQualifier]; if (fetchQualifier && restrictingQualifier) { fetchQualifier = [[EOAndQualifier alloc] initWithQualifiers:fetchQualifier, restrictingQualifier, nil]; AUTORELEASE(fetchQualifier); } else { fetchQualifier = fetchQualifier ? fetchQualifier : restrictingQualifier; } //Build Where Clause whereClauseString = [(id)fetchQualifier sqlStringForSQLExpression: self]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"whereClauseString=%@", whereClauseString); ASSIGN(_whereClauseString, whereClauseString); //Build Ordering Clause sortOrderings = [fetchSpecification sortOrderings]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sortOrderings=%@", sortOrderings); if ([sortOrderings count] > 0) { int i, count = [sortOrderings count]; for (i = 0; i < count; i++) { EOSortOrdering *order = [sortOrderings objectAtIndex: i]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"order=%@", order); NSAssert3([order isKindOfClass: [EOSortOrdering class]], @"order is not a EOSortOrdering but a %@: %p %@", [order class], order, order); [self addOrderByAttributeOrdering: order]; } } EOFLOGObjectLevelArgs(@"EOSQLExpression", @"_listString=%@", _listString); [self joinExpression]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"_joinClauseString=%@", _joinClauseString); rootEntity = [self _rootEntityForExpression]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"rootEntity=%@", [rootEntity name]); //Build Table List tableList = [self tableListWithRootEntity: rootEntity]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"tableList=%@", tableList); //Build LockClause if (flag) lockClauseString = [self lockClause]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"lockClauseString=%@", lockClauseString); //Build UseDistinct Clause usesDistinct = [fetchSpecification usesDistinct]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"usesDistinct=%d", usesDistinct); if (usesDistinct) selectCommand = @"SELECT distinct "; else selectCommand = @"SELECT "; //Now Build Statement statement = [self assembleSelectStatementWithAttributes: attributes lock: flag qualifier: fetchQualifier fetchOrder: sortOrderings selectString: selectCommand columnList: _listString tableList: tableList whereClause: ([_whereClauseString length] > 0 ? _whereClauseString : nil) joinClause: ([_joinClauseString length] > 0 ? _joinClauseString : nil) orderByClause: ([_orderByString length] > 0 ? _orderByString : nil) lockClause: lockClauseString]; ASSIGN(_statement, statement); EOFLOGObjectFnStopCond(@"EOSQLExpression"); } - (NSString *)assembleJoinClauseWithLeftName: (NSString *)leftName rightName: (NSString *)rightName joinSemantic: (EOJoinSemantic)semantic { NSString *op = nil; NSString *joinClause = nil; EOFLOGObjectFnStartCond(@"EOSQLExpression"); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"join parts=%@ %d %@", leftName, (int)semantic, rightName); //call [self _sqlStringForJoinSemantic:semantic matchSemantic:2 //[self _sqlStringForJoinSemantic:semantic matchSemantic:3 //the 2 ret nil switch (semantic) { case EOInnerJoin: op = @"="; break; case EOLeftOuterJoin: op = @"*="; break; case EORightOuterJoin: op = @"=*"; break; case EOFullOuterJoin: break; } EOFLOGObjectLevelArgs(@"EOSQLExpression", @"op= '%@'", op); if (op) joinClause = [NSString stringWithFormat: @"%@ %@ %@", leftName, op, rightName]; //TODO EOFLOGObjectLevelArgs(@"EOSQLExpression", @"joinClause=%@", joinClause); EOFLOGObjectFnStopCond(@"EOSQLExpression"); return joinClause; } - (void)addJoinClauseWithLeftName: (NSString *)leftName rightName: (NSString *)rightName joinSemantic: (EOJoinSemantic)semantic { NSString *joinClause = nil; EOFLOGObjectFnStartCond(@"EOSQLExpression"); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"join parts=%@ %d %@", leftName, (int)semantic, rightName); joinClause = [self assembleJoinClauseWithLeftName: leftName rightName: rightName joinSemantic: semantic]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"joinClause=%@", joinClause); if (joinClause) { NSMutableString *joinClauseString = [self joinClauseString]; if (![joinClauseString isEqualToString: @""]) [joinClauseString appendString: @" AND "]; [joinClauseString appendString: joinClause]; } EOFLOGObjectLevelArgs(@"EOSQLExpression", @"_joinClauseString=%@", _joinClauseString); EOFLOGObjectFnStopCond(@"EOSQLExpression"); } /** Build join expression for all used relationships (call this) after all other query parts construction) **/ - (void)joinExpression { EOEntity *entity = nil; NSEnumerator *relationshipEnum; NSString *relationshipPath; EOFLOGObjectFnStartCond(@"EOSQLExpression"); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"_aliasesByRelationshipPath=%@", _aliasesByRelationshipPath); // Iterate on each used relationship relationshipEnum = [_aliasesByRelationshipPath keyEnumerator]; while((relationshipPath = [relationshipEnum nextObject])) { EOFLOGObjectLevelArgs(@"EOSQLExpression", @"relationshipPath=%@", relationshipPath); // If this is not the base (root) one if (![relationshipPath isEqualToString: @""]) { EOQualifier *auxiliaryQualifier = nil; EORelationship *rel = nil; NSArray *joins = nil; int i, count=0; //Get the root entity if we haven't got it before if (!entity) entity=[self entity]; // Get the relationship for this path (non flattened by design) rel = [entity relationshipForPath: relationshipPath]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"rel=%@", rel); NSAssert2(rel, @"No relationship for path %@ in entity %@", relationshipPath, [entity name]); //Get the auxiliary qualifier for this relationship auxiliaryQualifier = [rel auxiliaryQualifier]; if (auxiliaryQualifier) { NSEmitTODO(); //TODO [self notImplemented:_cmd]; } // Get relationship joins joins = [rel joins]; count = [joins count]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"joins=%@", joins); // Iterate on each join for (i = 0; i < count; i++) { NSString *sourceRelationshipPath = nil; NSArray *sourceRelationshipPathArray; //Get the join EOJoin *join=[joins objectAtIndex:i]; // Get source and destination attributes EOAttribute *sourceAttribute = [join sourceAttribute]; EOAttribute *destinationAttribute = [join destinationAttribute]; NSString *sourceAttributeAlias = nil; NSString *destinationAttributeAlias = nil; // Build the source relationshipPath sourceRelationshipPathArray = [relationshipPath componentsSeparatedByString: @"."]; sourceRelationshipPathArray = [sourceRelationshipPathArray subarrayWithRange: NSMakeRange(0,[sourceRelationshipPathArray count] - 1)]; sourceRelationshipPath = [sourceRelationshipPathArray componentsJoinedByString: @"."]; // Get the alias for sourceAttribute sourceAttributeAlias = [self _aliasForRelatedAttribute: sourceAttribute relationshipPath: sourceRelationshipPath]; // Get the alias for destinationAttribute destinationAttributeAlias = [self _aliasForRelatedAttribute: destinationAttribute relationshipPath: relationshipPath]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"addJoin=%@ %d %@", sourceAttributeAlias, (int)[rel joinSemantic], destinationAttributeAlias); // Add to join clause [self addJoinClauseWithLeftName: sourceAttributeAlias rightName: destinationAttributeAlias joinSemantic: [rel joinSemantic]]; } } } EOFLOGObjectFnStopCond(@"EOSQLExpression"); } - (NSString *)assembleInsertStatementWithRow: (NSDictionary *)row tableList: (NSString *)tableList columnList: (NSString *)columnList valueList: (NSString *)valueList { //OK if (columnList) return [NSString stringWithFormat: @"INSERT INTO %@ (%@) VALUES (%@)", tableList, columnList, valueList]; else return [NSString stringWithFormat: @"INSERT INTO %@ VALUES (%@)", tableList, valueList]; } - (NSString *)assembleUpdateStatementWithRow: (NSDictionary *)row qualifier: (EOQualifier *)qualifier tableList: (NSString *)tableList updateList: (NSString *)updateList whereClause: (NSString *)whereClause { return [NSString stringWithFormat: @"UPDATE %@ SET %@ WHERE %@", tableList, updateList, whereClause]; } - (NSString *)assembleDeleteStatementWithQualifier: (EOQualifier *)qualifier tableList: (NSString *)tableList whereClause: (NSString *)whereClause { return [NSString stringWithFormat:@"DELETE FROM %@ WHERE %@", tableList, whereClause]; } - (NSString *)assembleSelectStatementWithAttributes: (NSArray *)attributes lock: (BOOL)lock qualifier: (EOQualifier *)qualifier fetchOrder: (NSArray *)fetchOrder selectString: (NSString *)selectString columnList: (NSString *)columnList tableList: (NSString *)tableList whereClause: (NSString *)whereClause joinClause: (NSString *)joinClause orderByClause: (NSString *)orderByClause lockClause: (NSString *)lockClause { //TODO selectString ?? NSMutableString *sqlString; EOFLOGObjectFnStartCond(@"EOSQLExpression"); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"attributes=%@", attributes); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"qualifier=%@", qualifier); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"fetchOrder=%@", fetchOrder); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"selectString=%@", selectString); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"columnList=%@", columnList); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"tableList=%@", tableList); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"whereClause=%@", whereClause); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"joinClause=%@", joinClause); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"orderByClause=%@", orderByClause); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"lockClause=%@", lockClause); sqlString = [NSMutableString stringWithFormat: @"SELECT %@ FROM %@", columnList, tableList]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sqlString=%@", sqlString); if ([lockClause length] > 0) [sqlString appendFormat: @" %@", lockClause]; if ([whereClause length] == 0) whereClause = nil; if ([joinClause length] == 0) joinClause = nil; if (whereClause && joinClause) [sqlString appendFormat: @" WHERE (%@) AND (%@)", whereClause, joinClause]; else if (whereClause || joinClause) [sqlString appendFormat: @" WHERE %@", (whereClause ? whereClause : joinClause)]; if ([orderByClause length] > 0) [sqlString appendFormat: @" ORDER BY %@", orderByClause]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sqlString=%@", sqlString); EOFLOGObjectFnStopCond(@"EOSQLExpression"); return sqlString; } - (void)addSelectListAttribute: (EOAttribute *)attribute { //OK NSMutableString *listString; NSString *string; NSString *sqlStringForAttribute = [self sqlStringForAttribute:attribute]; NSAssert1(sqlStringForAttribute,@"No sqlString for attribute: %@",attribute); string = [[self class] formatSQLString: sqlStringForAttribute format: [attribute readFormat]]; listString = [self listString]; [self appendItem: string toListString: listString]; } - (void)addInsertListAttribute: (EOAttribute *)attribute value: (NSString *)value { //OK NSMutableString *valueList=nil; NSString *writeFormat=nil; NSString *valueSQLString; NSMutableString *listString; NSString *attributeSQLString; EOFLOGObjectFnStartCond(@"EOSQLExpression"); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"attribute name=%@", [attribute name]); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"value=%@", value); listString = [self listString]; NS_DURING // debug purpose { attributeSQLString = [self sqlStringForAttribute: attribute]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"attributeSQLString=%@", attributeSQLString); } NS_HANDLER { NSDebugMLog(@"EXCEPTION %@", localException); [localException raise]; } NS_ENDHANDLER; NS_DURING // debug purpose { [self appendItem: attributeSQLString toListString: listString]; valueSQLString = [self sqlStringForValue: value attributeNamed: [attribute name]]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"valueSQLString=%@", valueSQLString); } NS_HANDLER { NSDebugMLog(@"EXCEPTION %@", localException); [localException raise]; } NS_ENDHANDLER; NS_DURING // debug purpose { writeFormat = [attribute writeFormat]; if ([writeFormat length] > 0) { NSEmitTODO(); //TODO NSDebugMLog(@"writeFormat '%@' not yet handled",writeFormat); } valueList = [self valueList]; [self appendItem: valueSQLString toListString: valueList]; } NS_HANDLER { NSDebugMLog(@"EXCEPTION %@", localException); [localException raise]; } NS_ENDHANDLER; EOFLOGObjectFnStopCond(@"EOSQLExpression"); } - (void)addUpdateListAttribute: (EOAttribute *)attribute value: (NSString *)value { //OK NSString *sqlStringToAdd; NSMutableString *listString; NSString *attributeSQLString; NSString *valueSQLString; NSString *writeFormat; EOFLOGObjectFnStartCond(@"EOSQLExpression"); attributeSQLString = [self sqlStringForAttribute: attribute]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"attributeSQLString=%@", attributeSQLString); valueSQLString = [self sqlStringForValue: value attributeNamed: [attribute name]]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"valueSQLString=%@", valueSQLString); writeFormat = [attribute writeFormat]; if ([writeFormat length] > 0) { NSEmitTODO(); //TODO NSDebugMLog(@"writeFormat '%@' not yet handled",writeFormat); } listString = [self listString]; sqlStringToAdd = [NSString stringWithFormat: @"%@ = %@", attributeSQLString, valueSQLString]; [self appendItem: sqlStringToAdd toListString: listString]; EOFLOGObjectFnStopCond(@"EOSQLExpression"); } + (NSString *)formatStringValue: (NSString *)string { NSString *formatted; EOFLOGObjectLevelArgs(@"EOSQLExpression", @" string=%@", string); if (string == nil) [NSException raise: NSInternalInconsistencyException format: @"EOSQLExpression: Argument of formatStringValue: " @"can't be a nil object"]; formatted = [NSString stringWithFormat: @"%@%@%@", @"'", string, @"'"]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @" formatted=%@", formatted); return formatted; } + (NSString *)formatValue: (id)value forAttribute: (EOAttribute *)attribute { //mirko new:return [value sqlString]; NSString *formattedValue = nil; EOFLOGObjectFnStartCond(@"EOSQLExpression"); EOFLOGObjectLevelArgs(@"EOSQLExpression", @" value=%@ class=%@", value, [value class]); NS_DURING //debug purpose { if (!value) formattedValue = @"NULL"; else { NSString *string; string = [value sqlString]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @" value %p=%@ null %p=%@", value, value, GDL2_EONull, GDL2_EONull); if (value == GDL2_EONull) formattedValue = string; else formattedValue = [self formatSQLString: [self formatStringValue: string] format: [attribute readFormat]]; } } NS_HANDLER { NSDebugMLog(@"EXCEPTION %@", localException); [localException raise]; } NS_ENDHANDLER; EOFLOGObjectFnStopCond(@"EOSQLExpression"); return formattedValue; } + (NSString *)formatSQLString: (NSString *)sqlString format: (NSString *)format { NSString *formatted = nil; EOFLOGObjectFnStartCond(@"EOSQLExpression"); EOFLOGObjectLevelArgs(@"EOSQLExpression", @" sqlString=%@ format=%@", sqlString, format); NSAssert1([sqlString length] > 0, @"No sqlString (%p)", sqlString); NS_DURING //debug purpose { if (!format) formatted = sqlString; else { const char *p = [format cString]; char *s; NSMutableString *str = [NSMutableString stringWithCapacity: [format length]]; IMP appendStringIMP = [str methodForSelector:@selector(appendString:)]; while ((s = strchr(p, '%'))) { switch (*(s + 1)) { case '%': GDL2_AppendStringWithImp(str,appendStringIMP, GDL2_StringWithCStringAndLength(p,s-p+1)); break; case 'P': if (s != p) GDL2_AppendStringWithImp(str,appendStringIMP, GDL2_StringWithCStringAndLength(p,s-p)); [str appendString: sqlString]; break; default: if (s != p) GDL2_AppendStringWithImp(str,appendStringIMP, GDL2_StringWithCStringAndLength(p,s-p)); break; } p = s + 2; } if (*p) GDL2_AppendStringWithImp(str,appendStringIMP,[NSString stringWithCString: p]); formatted = str; } } NS_HANDLER { NSDebugMLog(@"EXCEPTION %@", localException); [localException raise]; } NS_ENDHANDLER; EOFLOGObjectLevelArgs(@"EOSQLExpression", @" formatted=%@", formatted); EOFLOGObjectFnStopCond(@"EOSQLExpression"); return formatted; } //operation must have space before and after. Example: @" AND " - (NSString*) sqlStringForArrayOfQualifiers: (NSArray*)qualifiers operation: (NSString*)operation { //OK NSMutableString *sqlString = nil; int i, count; int nb=0; EOFLOGObjectFnStartCond(@"EOSQLExpression"); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"operation=%@ qualifiers=%@", operation, qualifiers); count = [qualifiers count]; for (i = 0; i < count; i++) { NSString *tmpSqlString=nil; EOQualifier *qualifier = [qualifiers objectAtIndex: i]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"qualifier=%@", qualifier); tmpSqlString=[qualifier sqlStringForSQLExpression:self]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"qualifier=%@ tmpSqlString=%@", qualifier, tmpSqlString); if (tmpSqlString) { if (!sqlString) sqlString = (NSMutableString*)[NSMutableString string]; if (nb > 0) [sqlString appendString: operation]; [sqlString appendString: tmpSqlString]; nb++; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sqlString=%@", sqlString); } } if (nb > 1) { [sqlString insertString: @"(" atIndex: 0]; [sqlString appendString: @")"]; } else if (nb == 0) sqlString = nil; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"operation=%@ qualifiers=%@ count=%d nb=%d sqlString=%@", operation, qualifiers, count, nb, sqlString); EOFLOGObjectFnStopCond(@"EOSQLExpression"); return sqlString; } - (NSString *)sqlStringForConjoinedQualifiers: (NSArray *)qualifiers { //OK NSString *sqlString; EOFLOGObjectFnStartCond(@"EOSQLExpression"); sqlString = [self sqlStringForArrayOfQualifiers: qualifiers operation: @" AND "]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sqlString=%@", sqlString); EOFLOGObjectFnStopCond(@"EOSQLExpression"); return sqlString; } - (NSString *)sqlStringForDisjoinedQualifiers: (NSArray *)qualifiers { //OK NSString *sqlString; EOFLOGObjectFnStartCond(@"EOSQLExpression"); sqlString = [self sqlStringForArrayOfQualifiers: qualifiers operation: @" OR "]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sqlString=%@", sqlString); EOFLOGObjectFnStopCond(@"EOSQLExpression"); return sqlString; } - (NSString *)sqlStringForNegatedQualifier:(EOQualifier *)qualifier { NSString *sqlQual = nil; EOFLOGObjectFnStartCond(@"EOSQLExpression"); sqlQual = [(id)qualifier sqlStringForSQLExpression: self]; if (sqlQual) sqlQual = [NSString stringWithFormat:@"not (%@)", sqlQual]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sqlQual=%@", sqlQual); EOFLOGObjectFnStopCond(@"EOSQLExpression"); return sqlQual; } - (NSString *)sqlStringForKeyValueQualifier: (EOKeyValueQualifier *)qualifier { //Near OK NSString* sqlString=nil; NSString* valueSQLString=nil; NSString* selectorSQLString=nil; NSString *key = nil; id value=nil; NSString* attributeSQLString=nil; EOAttribute* attribute=nil; NSString* readFormat=nil; EOFLOGObjectFnStartCond(@"EOSQLExpression"); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"qualifier=%@", qualifier); NSAssert2([qualifier isKindOfClass:[EOKeyValueQualifier class]], @"qualifier is not a EOKeyValueQualifier but a %@: %@", [qualifier class], qualifier); key = [qualifier key]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"key=%@", key); NSAssert1([key length]>0, @"No key in EOKeyValueQualifier: %@",qualifier); value = [qualifier value]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"value=%@", value); attributeSQLString = [self sqlStringForAttributeNamed: key]; NSAssert1(attributeSQLString, @"No sqlStringForAttributeNamed:%@", key); EOFLOGObjectLevelArgs(@"EOSQLExpression",@"attributeSQLString=%@", attributeSQLString); attribute = [_entity attributeForPath: key]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"attribute=%@", attribute); NSAssert3(attribute, @"No attribute forKeyPath: '%@' in entity named '%@' in EOKeyValueQualifier: %@", key,_entity,qualifier); readFormat = [attribute readFormat]; if (readFormat) { NSEmitTODO(); //TODO NSDebugMLog(@"readFormat '%@' not yet handled",readFormat); } EOFLOGObjectLevelArgs(@"EOSQLExpression", @"valueSQLString=%@ qualifier=%@ [qualifier selector]=%p %@", valueSQLString, qualifier, [qualifier selector], NSStringFromSelector([qualifier selector])); selectorSQLString = [self sqlStringForSelector: [qualifier selector] value: value]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"selectorSQLString=%@", selectorSQLString); if (sel_eq([qualifier selector], EOQualifierOperatorLike)) { value = [[self class] sqlPatternFromShellPattern: value]; valueSQLString = [self sqlStringForValue: value attributeNamed: key]; } else if (sel_eq([qualifier selector], EOQualifierOperatorCaseInsensitiveLike)) { value = [[self class] sqlPatternFromShellPattern: value]; valueSQLString = [self sqlStringForValue: value attributeNamed: key]; attributeSQLString = [NSString stringWithFormat: @"UPPER(%@)", attributeSQLString]; valueSQLString = [NSString stringWithFormat: @"UPPER(%@)", valueSQLString]; } else valueSQLString = [self sqlStringForValue: value attributeNamed: key]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"attributeSQLString=%@", attributeSQLString); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"selectorSQLString=%@", selectorSQLString); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"valueSQLString=%@", valueSQLString); sqlString = [NSString stringWithFormat: @"%@ %@ %@", attributeSQLString, selectorSQLString, valueSQLString]; /* NSString* sqlString = [NSString stringWithFormat: @"%@ %@ %@", [[self class] formatSQLString: [self sqlStringForAttributeNamed:key] format: [[_entity attributeNamed:key] readFormat]], selString, valueString]; */ EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sqlString=%@", sqlString); EOFLOGObjectFnStopCond(@"EOSQLExpression"); return sqlString; //return someting like t1.label = 'XXX' } - (NSString *)sqlStringForKeyComparisonQualifier: (EOKeyComparisonQualifier *)qualifier { return [NSString stringWithFormat:@"%@ %@ %@", [[self class] formatSQLString: [self sqlStringForAttributeNamed: [qualifier leftKey]] format: [[_entity attributeNamed: [qualifier leftKey]] readFormat]], [self sqlStringForSelector:[qualifier selector] value:nil], [[self class] formatSQLString: [self sqlStringForAttributeNamed: [qualifier rightKey]] format:[[_entity attributeNamed: [qualifier rightKey]] readFormat]]]; } - (NSString *)sqlStringForValue:(NSString *)valueString caseInsensitiveLikeKey:(NSString *)keyString { [self notImplemented:_cmd]; //TODO return nil; } - (void)addOrderByAttributeOrdering:(EOSortOrdering *)sortOrdering { SEL orderSelector = NULL; NSString *orderStringFormat = nil; NSString *keyString = nil; id key = nil; orderSelector = [sortOrdering selector]; if (sel_eq(orderSelector, EOCompareAscending)) orderStringFormat = @"(%@) asc"; else if (sel_eq(orderSelector, EOCompareDescending)) orderStringFormat = @"(%@) desc"; else if (sel_eq(orderSelector, EOCompareCaseInsensitiveAscending)) orderStringFormat = @"upper(%@) asc"; else if (sel_eq(orderSelector, EOCompareCaseInsensitiveDescending)) orderStringFormat = @"upper(%@) desc"; key = [sortOrdering key]; NSAssert1(key, @"Key in sort ordering", sortOrdering); keyString = [self sqlStringForAttributeNamed: key];//TODO VERIFY EOFLOGObjectLevelArgs(@"EOSQLExpression", @"keyString=%@", keyString); NSAssert1(keyString, @"No sql string for key named \"%@\"", key); [self appendItem: [NSString stringWithFormat: orderStringFormat, keyString] toListString: [self orderByString]]; } + (BOOL)useQuotedExternalNames { return [[NSUserDefaults standardUserDefaults] boolForKey: @"EOAdaptorQuotesExternalNames"]; } + (void)setUseQuotedExternalNames:(BOOL)flag { NSString *yn = (flag ? @"YES" : @"NO"); [[NSUserDefaults standardUserDefaults] setObject: yn forKey: @"EOAdaptorQuotesExternalNames"]; } - (NSString *)externalNameQuoteCharacter { if ([[self class] useQuotedExternalNames]) return @"\""; return @""; } - (void)setUseAliases: (BOOL)useAliases { _flags.useAliases = useAliases; } - (BOOL)useAliases { return _flags.useAliases; } - (NSString *)sqlStringForSchemaObjectName: (NSString *)name { //OK NSString *quote = [self externalNameQuoteCharacter]; return [NSString stringWithFormat:@"%@%@%@", quote, name, quote]; } - (NSString *)sqlStringForAttributeNamed: (NSString *)name { //OK EOAttribute *attribute = nil; NSString *sqlString = nil; NSArray *keyParts = nil; NSString *key = nil; EOEntity *entity=_entity; NSMutableArray *attributePath = nil; int i, count; EORelationship *rel = nil; EOFLOGObjectFnStartCond(@"EOSQLExpression"); NSAssert(entity,@"no entity"); NSAssert(name,@"no attribute name"); NSAssert([name length]>0,@"attribute name is empty"); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"name=%@", name); keyParts = [name componentsSeparatedByString:@"."]; count = [keyParts count]; for (i = 0; i < count - 1; i++) { key = [keyParts objectAtIndex: i]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"keyPart=%@", key); rel = [entity anyRelationshipNamed: key]; NSAssert2(rel, @"no relationship named %@ in entity %@", key, [entity name]); if (attributePath) [attributePath addObject: rel]; else attributePath = [NSMutableArray arrayWithObject: rel]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"rel=%@", rel); entity = [rel destinationEntity]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"entity name=%@", [entity name]); } key = [keyParts lastObject]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"key=%@", key); attribute = [entity anyAttributeNamed: key]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"attribute=%@", attribute); if (!attribute) { rel = [entity anyRelationshipNamed: key]; if (rel) NSAssert4(attribute, @"no attribute named %@ (only a relationship) in entity %@\nAttributesByName=%@\nattributes=%@", key, [entity name], [entity attributesByName], [entity attributes]); else NSAssert4(attribute, @"no attribute nor relationship named %@ in entity %@\nAttributesByName=%@\nattributes=%@", key, [entity name], [entity attributesByName], [entity attributes]); }; if (attributePath) { [attributePath addObject: attribute]; sqlString = [self sqlStringForAttributePath: attributePath]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sqlString=%@", sqlString); NSAssert1(sqlString, @"no sql string for attribute path %@", attributePath); NSAssert1([sqlString length], @"empty sql string for attribute path %@", attributePath); } else { sqlString = [self sqlStringForAttribute: attribute]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sqlString=%@", sqlString); NSAssert1(sqlString, @"no sql string for attribute %@", attribute); NSAssert1([sqlString length], @"empty sql string for attribute %@", attribute); } EOFLOGObjectFnStopCond(@"EOSQLExpression"); return sqlString; } - (NSString *)sqlStringForSelector: (SEL)selector value: (id)value { //seems OK if (sel_eq(selector, EOQualifierOperatorEqual)) { if (value==GDL2_EONull) return @"is"; else return @"="; } else if (sel_eq(selector, EOQualifierOperatorNotEqual)) { if (value==GDL2_EONull) return @"is not"; else return @"<>"; } else if (sel_eq(selector, EOQualifierOperatorLessThan)) return @"<"; else if (sel_eq(selector, EOQualifierOperatorGreaterThan)) return @">"; else if (sel_eq(selector, EOQualifierOperatorLessThanOrEqualTo)) return @"<="; else if (sel_eq(selector, EOQualifierOperatorGreaterThanOrEqualTo)) return @">="; else if (sel_eq(selector, EOQualifierOperatorLike)) return @"like"; else if (sel_eq(selector, EOQualifierOperatorCaseInsensitiveLike)) return @"like"; //same as sensitive /* //TODO else if(sel_eq(selector, EOQualifierOperatorContains)) return @"like";*/ else { [NSException raise: NSInternalInconsistencyException format: @"EOSQLExpression: Unknown selector of sqlStringForSelector:value: '%@'",NSStringFromSelector(selector)]; } return nil; } - (NSString *)sqlStringForValue: (id)value attributeNamed: (NSString*)attributeName { EOAttribute *attribute; NSString *sqlString = nil; EOFLOGObjectFnStartCond(@"EOSQLExpression"); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"value=%@", value); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"attributeName=%@", attributeName); attribute = [_entity attributeForPath: attributeName]; NSAssert2(attribute, @"No attribute for path \"%@\" in entity \"%@\"", attributeName, [_entity name]); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"attribute=%@", attribute); if ([self shouldUseBindVariableForAttribute: attribute] || [self mustUseBindVariableForAttribute: attribute]) { //TODO verify NSDictionary *binding; binding = [self bindVariableDictionaryForAttribute: attribute value: value]; [_bindings addObject: binding]; sqlString = [binding objectForKey: EOBindVariablePlaceHolderKey]; } else { //attr externalType EOFLOGObjectLevelArgs(@"EOSQLExpression", @" value=%@ class=%@", value, [value class]); EOFLOGObjectLevelArgs(@"EOSQLExpression", @" self %@ class=%@", self, [self class]); //call attribute entity //call entity model sqlString = [[self class] formatValue: value forAttribute: attribute]; //?? EOFLOGObjectLevelArgs(@"EOSQLExpression", @" sqlString=%@", sqlString); NSAssert4([sqlString length] > 0, @"No sqlString (%p) for value '%@' (class %@) for Attribute '%@'", sqlString, value, [value class], attribute); //??? Mirko: sqlString = [[self class] formatSQLString: sqlString format: [attribute readFormat]]; } EOFLOGObjectFnStopCond(@"EOSQLExpression"); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sqlString=%@", sqlString); return sqlString; } - (NSString *)sqlStringForAttribute: (EOAttribute *)attribute { NSString *sqlString = nil; EOFLOGObjectFnStartCond(@"EOSQLExpression"); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"attribute=%@", attribute); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sFlattened=%s", ([attribute isFlattened] ? "YES" : "NO")); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"_definitionArray=%@", [attribute _definitionArray]); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"_definitionArray count=%d", [[attribute _definitionArray]count]); if ([attribute isFlattened]) { sqlString = [self sqlStringForAttributePath: [attribute _definitionArray]]; NSAssert1(sqlString, @"No sqlString for flattened attribute: %@", attribute); } //mirko: /* else if([attribute isDerived] == YES) return [attribute definition]; */ else { if (![self useAliases])//OK { sqlString = [attribute columnName]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sqlString=%@", sqlString); } else { //TODO VERIFY en select: return t0.abbrev NSEnumerator *relationshipEnum; NSEnumerator *defEnum = nil; NSArray *defArray, *attrArray = nil; NSString *relationshipPath; NSString *relationshipString = nil; EOEntity *currentEntity = nil; relationshipEnum = [_aliasesByRelationshipPath keyEnumerator]; while ((relationshipPath = [relationshipEnum nextObject])) { currentEntity = _entity; EOFLOGObjectLevelArgs(@"EOSQLExpression",@"relationshipPath=%@",relationshipPath); if (![relationshipPath isEqualToString: @""]) { defArray = [relationshipPath componentsSeparatedByString: @"."]; defEnum = [defArray objectEnumerator]; while ((relationshipString = [defEnum nextObject])) { // use anyRelationshipNamed: to find hidden relationship too EORelationship *relationship=[currentEntity anyRelationshipNamed: relationshipString]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"relationshipString=%@", relationshipString); NSAssert2(relationship, @"No relationship named %@ in entity %@", relationshipString, [currentEntity name]); NSAssert2(currentEntity, @"No destination entity. Entity %@ relationship = %@", [currentEntity name], relationship); currentEntity = [relationship destinationEntity]; } // TODO entity } attrArray = [currentEntity attributes]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"attrArray=%@", attrArray); if (attrArray) { if ([attrArray containsObject: attribute]) { NSString *columnName = [attribute columnName]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"columnName=%@", columnName); if (!columnName) { NSEmitTODO(); //TODO what to do when there's no column name (definition only like "((firstName || ' ') || lastName)") ? EOFLOGObjectLevelArgs(@"EOSQLExpression", @"attribute=%@", attribute); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"columnName=%@", columnName); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"attrArray=%@", attrArray); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"relationshipPath=%@", relationshipPath); } NSAssert1(columnName, @"No columnName for attribute %@", attribute); sqlString = [NSString stringWithFormat: @"%@.%@", [_aliasesByRelationshipPath objectForKey: relationshipPath], columnName]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sqlString=%@", sqlString); } } } EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sqlString=%@", sqlString); } NSAssert1(sqlString, @"No SQLString for attribute %@", attribute); } EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sqlString=%@", sqlString); EOFLOGObjectFnStopCond(@"EOSQLExpression"); return sqlString; } - (NSString *)sqlStringForAttributePath: (NSArray *)path { NSString *sqlString = nil; EOFLOGObjectFnStartCond(@"EOSQLExpression"); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"path=%@", path); if (!_flags.useAliases) { sqlString = [(EOAttribute *)[path lastObject] columnName]; NSAssert2(sqlString, @"No sqlString for path: %@ (lastObject=%@) (!_useAliases)", path, [path lastObject]); } else { NSMutableString *relationshipPathString = [NSMutableString string]; int i, count = [path count]; if (count > 1) { for (i = 0; i < (count - 1); i++) { EORelationship* relationship = nil; if (i > 0) [relationshipPathString appendString: @"."]; relationship = [path objectAtIndex:i]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"[path objectAtIndex:%d]=%@", i, relationship); NSAssert2([relationship isKindOfClass:[EORelationship class]], @"'%@' is not a relationship but a %@", relationship, [relationship class]); [relationshipPathString appendString: [relationship name]]; } EOFLOGObjectLevelArgs(@"EOSQLExpression", @"[path lastObject]=%@", [path lastObject]); //TODO if ([[path lastObject] isDerived]) { //call attribute _definitionArray NSEmitTODO(); //TODO [self notImplemented:_cmd]; }; sqlString = [self _aliasForRelatedAttribute: [path lastObject] relationshipPath: relationshipPathString]; NSAssert2(sqlString, @"No sqlString for path: %@ (lastObject=%@) (_useAliases)", path, [path lastObject]); } } EOFLOGObjectLevelArgs(@"EOSQLExpression", @"path=%@ sqlString=%@", path, sqlString); EOFLOGObjectFnStopCond(@"EOSQLExpression"); return sqlString; } - (void)appendItem: (NSString *)itemString toListString: (NSMutableString *)listString { //OK NSAssert1(listString,@"No list string when appending %@",itemString); if (listString) { #if 0 str = [listString cString]; while (*str) { if (!isspace(*str++)) [listString appendString: @", "]; } #endif if ([listString length]) [listString appendString: @", "]; [listString appendString: itemString]; } } + (NSString *)sqlPatternFromShellPattern: (NSString *)pattern { NSString* sqlPattern=nil; int patternLength=[pattern length]; if (patternLength==0) sqlPattern=pattern; else { const char *s, *p, *init = [pattern cString]; NSMutableString *str = [NSMutableString stringWithCapacity: patternLength]; IMP appendStringIMP = [str methodForSelector:@selector(appendString:)]; for (s = p = init; *s; s++) { switch (*s) { case '*': if (s != p) GDL2_AppendStringWithImp(str,appendStringIMP, GDL2_StringWithCStringAndLength(p,s-p)); [str appendString: @"%"]; p = s+1; break; case '?': if (s != p) GDL2_AppendStringWithImp(str,appendStringIMP, GDL2_StringWithCStringAndLength(p,s-p)); GDL2_AppendStringWithImp(str,appendStringIMP,@"_"); p = s+1; break; case '%': if (s != p) GDL2_AppendStringWithImp(str,appendStringIMP, GDL2_StringWithCStringAndLength(p,s-p)); if (s != init && *(s-1) == '[' && *(s+1) == ']') { GDL2_AppendStringWithImp(str,appendStringIMP,@"%]"); p = s+2; s++; } else { GDL2_AppendStringWithImp(str,appendStringIMP,@"[%]"); p = s+1; } break; case '_': if (s != p) GDL2_AppendStringWithImp(str,appendStringIMP, GDL2_StringWithCStringAndLength(p,s-p)); if (s != init && *(s-1) == '[' && *(s+1) == ']') { GDL2_AppendStringWithImp(str,appendStringIMP,@"_]"); p = s+2; p++; } else { GDL2_AppendStringWithImp(str,appendStringIMP,@"[_]"); p = s+1; } break; } } if (*p) GDL2_AppendStringWithImp(str,appendStringIMP,[NSString stringWithCString: p]); sqlPattern=str; }; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"pattern=%@ => %@", pattern,sqlPattern); return sqlPattern; } + (NSString *)sqlPatternFromShellPattern: (NSString *)pattern withEscapeCharacter: (unichar)escapeCharacter { const char *s, *p, *init = [pattern cString]; NSMutableString *str = [NSMutableString stringWithCapacity: [pattern length]]; IMP appendStringIMP = [str methodForSelector:@selector(appendString:)]; for (s = p = init; *s; s++) { switch (*s) { case '*': if (s != p) GDL2_AppendStringWithImp(str,appendStringIMP, GDL2_StringWithCStringAndLength(p,s-p)); GDL2_AppendStringWithImp(str,appendStringIMP,@"%"); p = s+1; break; case '?': if (s != p) GDL2_AppendStringWithImp(str,appendStringIMP, GDL2_StringWithCStringAndLength(p,s-p)); GDL2_AppendStringWithImp(str,appendStringIMP,@"_"); p = s+1; break; case '%': if (s != p) GDL2_AppendStringWithImp(str,appendStringIMP, GDL2_StringWithCStringAndLength(p,s-p)); if (s != init && *(s-1) == '[' && *(s+1) == ']') { GDL2_AppendStringWithImp(str,appendStringIMP,@"%]"); p = s+2; s++; } else { GDL2_AppendStringWithImp(str,appendStringIMP,@"[%]"); p = s+1; } break; case '_': if (s != p) GDL2_AppendStringWithImp(str,appendStringIMP, GDL2_StringWithCStringAndLength(p,s-p)); if (s != init && *(s-1) == '[' && *(s+1) == ']') { GDL2_AppendStringWithImp(str,appendStringIMP,@"_]"); p = s+2; p++; } else { GDL2_AppendStringWithImp(str,appendStringIMP,@"[_]"); p = s+1; } break; } } if (*p) GDL2_AppendStringWithImp(str,appendStringIMP,[NSString stringWithCString:p]); return str; } - (NSMutableDictionary *)bindVariableDictionaryForAttribute: (EOAttribute *)attribute value: (id)value { [self subclassResponsibility: _cmd]; return nil; } - (BOOL)shouldUseBindVariableForAttribute: (EOAttribute *)att { return NO; } - (BOOL)mustUseBindVariableForAttribute: (EOAttribute *)att { return NO; } + (BOOL)useBindVariables { return [[NSUserDefaults standardUserDefaults] boolForKey: @"EOAdaptorUseBindVariables"]; } + (void)setUseBindVariables:(BOOL)flag { NSString *yn = (flag ? @"YES" : @"NO"); [[NSUserDefaults standardUserDefaults] setObject:yn forKey:@"EOAdaptorUseBindVariables"]; } - (NSArray *)bindVariableDictionaries { return _bindings; } - (void)addBindVariableDictionary:(NSMutableDictionary *)binding { [_bindings addObject:binding]; } @end /* EOSQLExpression */ @implementation EOSQLExpression (EOSQLExpressionPrivate) - (EOEntity*)_rootEntityForExpression { //return [self notImplemented:_cmd]; //TODO return _entity; }; /** Return the alias (t0,t1,...) for the relationshipPath This add a new alias if there not already one This also add alias for all relationships used by relationshipPath (so joinExpression can build join expressions for really all used relationships) All relationshipPaths in _aliasesByRelationshipPath are direct paths **/ - (NSString*) _aliasForRelationshipPath:(NSString*)relationshipPath { //OK ? NSString *flattenRelPath; NSMutableString *mutableFlattenRelPath; NSString *alias = nil; NSMutableArray *pathElements; int count = 0; int contextStackCurrentIndex = 0; EOFLOGObjectFnStartCond(@"EOSQLExpression"); contextStackCurrentIndex = [_contextStack count]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"relationshipPath=%@", relationshipPath); NSAssert(relationshipPath, @"No relationshipPath"); if ([relationshipPath length] == 0) // "" relationshipPath is handled by _aliasesByRelationshipPath lookup flattenRelPath = relationshipPath; else // Find real path flattenRelPath = [self _flattenRelPath: relationshipPath entity: _entity]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"flattenRelPath=\"%@\"", flattenRelPath); mutableFlattenRelPath = [[flattenRelPath mutableCopy] autorelease]; pathElements = [[[mutableFlattenRelPath componentsSeparatedByString: @"."] mutableCopy] autorelease]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"pathElements=%@", pathElements); count = [pathElements count]; while (count > 0) { NSString *tmpAlias = nil; EOFLOGObjectLevelArgs(@"EOSQLExpression",@"count=%d flattenRelPath=%@", count, mutableFlattenRelPath); tmpAlias = [_aliasesByRelationshipPath objectForKey: mutableFlattenRelPath]; if (!tmpAlias) { NSString* tmpRelPath=nil; tmpAlias = [NSString stringWithFormat: @"t%d", _alias++]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"add alias %@ for %@", tmpAlias, mutableFlattenRelPath); tmpRelPath = [[mutableFlattenRelPath copy] autorelease]; //immuable key ! [_aliasesByRelationshipPath setObject: tmpAlias forKey: tmpRelPath]; // Insert to ensure logical order (i.e. xx BEFORE xx.yy) [_contextStack insertObject:tmpRelPath atIndex:contextStackCurrentIndex]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"inserted '%@' (%@) in contextStack => %@", tmpRelPath,tmpAlias,_contextStack); } if (!alias) alias = tmpAlias; if (count > 0) { NSString *part = [pathElements lastObject]; if (count > 1 || [part length] > 0) //we may have only "" as original path [mutableFlattenRelPath deleteSuffix: part]; if (count > 1) [mutableFlattenRelPath deleteSuffix: @"."]; [pathElements removeLastObject]; } count--; } EOFLOGObjectLevelArgs(@"EOSQLExpression", @"alias=%@", alias); EOFLOGObjectFnStopCond(@"EOSQLExpression"); return alias; } - (NSString*) _flattenRelPath: (NSString*)relationshipPath entity: (EOEntity*)entity { // near OK NSMutableString *flattenRelPath = [NSMutableString string]; EORelationship *relationship = nil; NSArray *pathElements = nil; int i, count; EOFLOGObjectFnStartCond(@"EOSQLExpression"); NSAssert(relationshipPath, @"No relationshipPath"); NSAssert([relationshipPath length] > 0, @"Empty relationshipPath"); pathElements = [relationshipPath componentsSeparatedByString: @"."]; count = [pathElements count]; for (i = 0; i < count; i++) { NSString *relPath = nil; NSString *part = [pathElements objectAtIndex: i]; // use anyRelationshipNamed: to find hidden relationship too relationship = [entity anyRelationshipNamed: part]; NSAssert2(relationship, @"no relationship named %@ in entity %@", part, [entity name]); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"i=%d part=%@ rel=%@", i, part, relationship); // We check if there's outer join has some adaptors may buld things // differently in this case if (!_flags.hasOuterJoin && [relationship joinSemantic]!=EOInnerJoin) _flags.hasOuterJoin=YES; if ([relationship isFlattened]) { NSString *definition = [relationship definition]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"definition=%@ relationship=%@", definition, relationship); relPath = [self _flattenRelPath: definition entity: entity]; } else relPath = [relationship name]; if (i > 0) [flattenRelPath appendString: @"."]; [flattenRelPath appendString: relPath]; entity = [relationship destinationEntity]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"entity name=%@", [entity name]); } EOFLOGObjectLevelArgs(@"EOSQLExpression", @"flattenRelPath=%@", flattenRelPath); EOFLOGObjectFnStopCond(@"EOSQLExpression"); return flattenRelPath; } - (NSString*) _sqlStringForJoinSemantic: (EOJoinSemantic)joinSemantic matchSemantic: (int)param1 { return [self notImplemented: _cmd]; //TODO } - (NSString*) _aliasForRelatedAttribute: (EOAttribute*)attribute relationshipPath: (NSString*)relationshipPath { NSString *alias = nil; NSString *relPathAlias = nil; NSString *attributeColumnName = nil; EOFLOGObjectFnStartCond(@"EOSQLExpression"); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"attribute=%@", attribute); EOFLOGObjectLevelArgs(@"EOSQLExpression", @"relationshipPath=%@", relationshipPath); relPathAlias = [self _aliasForRelationshipPath: relationshipPath]; //ret "t1" attributeColumnName = [attribute columnName]; // ret "label" attributeColumnName = [self sqlStringForSchemaObjectName: attributeColumnName]; // ret quoted columnName NSAssert1([relPathAlias length]>0,@"no relPathAlias or empty relPathAlias ('%@')", relPathAlias); NSAssert1([attributeColumnName length]>0,@"no attributeColumnName or empty attributeColumnName ('%@')", attributeColumnName); alias = [NSString stringWithFormat: @"%@.%@", relPathAlias, attributeColumnName]; EOFLOGObjectLevelArgs(@"EOSQLExpression", @"alias=%@", alias); EOFLOGObjectFnStopCond(@"EOSQLExpression"); return alias;//Like t1.label } - (id) _entityForRelationshipPath: (id)param0 origin: (id)param1 { return [self notImplemented: _cmd]; //TODO } @end @implementation NSString (EOSQLFormatting) - (NSString *)sqlString { return self; } @end @implementation NSNumber (EOSQLFormatting) - (NSString *)sqlString { return [self stringValue]; } @end @implementation NSObject (EOSQLFormatting) - (NSString *)sqlString { return [self description]; } @end gnustep-dl2-0.12.0/EOAccess/EOEntity.m0000644000175000017500000035673511146721052016313 0ustar ayersayers/** EOEntity.m EOEntity Class Copyright (C) 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 Author: Manuel Guesdon Date: October 2000 $Revision: 27910 $ $Date: 2009-02-18 06:52:42 +0100 (Mit, 18. Feb 2009) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EOEntity.m 27910 2009-02-18 05:52:42Z ayers $") #include #ifdef GNUSTEP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "EOPrivate.h" #include "EOEntityPriv.h" #include "EOAttributePriv.h" #include "../EOControl/EOPrivate.h" @interface EOModel (Privat) - (void)_updateCache; @end NSString *EOFetchAllProcedureOperation = @"EOFetchAllProcedureOperation"; NSString *EOFetchWithPrimaryKeyProcedureOperation = @"EOFetchWithPrimaryKeyProcedureOperation"; NSString *EOInsertProcedureOperation = @"EOInsertProcedureOperation"; NSString *EODeleteProcedureOperation = @"EODeleteProcedureOperation"; NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperation"; @implementation EOEntity + (void)initialize { static BOOL initialized=NO; if (!initialized) { initialized=YES; GDL2_EOAccessPrivateInit(); }; }; /* Not documented becuase it is not a public method. */ - (id)initWithPropertyList: (NSDictionary*)propertyList owner: (id)owner { [EOObserverCenter suppressObserverNotification]; EOFLOGObjectLevelArgs(@"EOEntity", @"propertyList=%@", propertyList); NS_DURING { if ((self = [self init]) != nil) { NSArray *array = nil; NSString *tmpString = nil; id tmpObject = nil; _flags.updating = YES; /* set this before validation. */ if ([owner isKindOfClass:[EOModel class]]) [self _setModel:owner]; // else _setParent:?? tmpString = [propertyList objectForKey:@"name"]; /* we dont want it to call _updateCache. So we validate and set the name directly, as we haven't been added to the model yet, and this would causes problems. */ [[self validateName:tmpString] raise]; ASSIGN(_name, tmpString); [self setExternalName: [propertyList objectForKey: @"externalName"]]; tmpObject = [propertyList objectForKey: @"externalQuery"]; [self setExternalQuery: tmpObject]; tmpString = [propertyList objectForKey: @"restrictingQualifier"]; EOFLOGObjectLevelArgs(@"EOEntity",@"tmpString=%@",tmpString); if (tmpString) { EOQualifier *restrictingQualifier = [EOQualifier qualifierWithQualifierFormat: tmpString arguments:nil]; [self setRestrictingQualifier: restrictingQualifier]; } tmpString = [propertyList objectForKey: @"mappingQualifier"]; if (tmpString) { NSEmitTODO(); //TODO } tmpObject = [propertyList objectForKey: @"isReadOnly"]; [self setReadOnly: [tmpObject boolValue]]; tmpObject = [propertyList objectForKey: @"cachesObjects"]; [self setCachesObjects: [tmpObject boolValue]]; tmpObject = [propertyList objectForKey: @"userInfo"]; EOFLOGObjectLevelArgs(@"EOEntity", @"tmpObject=%@", tmpObject); if (tmpObject) { [self setUserInfo: tmpObject]; } else { tmpObject = [propertyList objectForKey: @"userDictionary"]; [self setUserInfo: tmpObject]; } tmpObject = [propertyList objectForKey: @"internalInfo"]; EOFLOGObjectLevelArgs(@"EOEntity", @"tmpObject=%@ [%@]", tmpObject, [tmpObject class]); [self _setInternalInfo: tmpObject]; [self setDocComment:[propertyList objectForKey:@"docComment"]]; [self setClassName: [propertyList objectForKey: @"className"]]; tmpObject = [propertyList objectForKey: @"isAbstractEntity"]; [self setIsAbstractEntity: [tmpObject boolValue]]; tmpString = [propertyList objectForKey: @"isFetchable"]; if (tmpString) { NSEmitTODO(); //TODO } array = [propertyList objectForKey: @"attributes"]; EOFLOGObjectLevelArgs(@"EOEntity", @"Attributes: %@", array); if ([array count] > 0) { ASSIGN(_attributes, array); _flags.attributesIsLazy = YES; } array = [propertyList objectForKey: @"attributesUsedForLocking"]; EOFLOGObjectLevelArgs(@"EOEntity", @"attributesUsedForLocking: %@", array); if ([array count] > 0) { ASSIGN(_attributesUsedForLocking, array); _flags.attributesUsedForLockingIsLazy = YES; } array = [propertyList objectForKey: @"primaryKeyAttributes"]; array = [array sortedArrayUsingSelector: @selector(compare:)]; EOFLOGObjectLevelArgs(@"EOEntity", @"primaryKeyAttributes: %@", array); if ([array count] > 0) { ASSIGN(_primaryKeyAttributes, array); _flags.primaryKeyAttributesIsLazy = YES; } /* * Assign them to _classProperties, not _classPropertyNames, * this will be build after */ array = [propertyList objectForKey: @"classProperties"]; EOFLOGObjectLevelArgs(@"EOEntity", @"classProperties: %@", array); if ([array count] > 0) { ASSIGN(_classProperties, array); _flags.classPropertiesIsLazy = YES; } array = [propertyList objectForKey: @"relationships"]; EOFLOGObjectLevelArgs(@"EOEntity", @"relationships: %@", array); if ([array count] > 0) { ASSIGN(_relationships, array); _flags.relationshipsIsLazy = YES; } array = [propertyList objectForKey: @"storedProcedureNames"]; EOFLOGObjectLevelArgs(@"EOEntity",@"relationships: %@",array); if ([array count] > 0) { NSEmitTODO(); //TODO } tmpString = [propertyList objectForKey: @"maxNumberOfInstancesToBatchFetch"]; EOFLOGObjectLevelArgs(@"EOEntity", @"maxNumberOfInstancesToBatchFetch=%@ [%@]", tmpString, [tmpString class]); if (tmpString) [self setMaxNumberOfInstancesToBatchFetch: [tmpString intValue]]; tmpString=[propertyList objectForKey:@"batchFaultingMaxSize"]; if (tmpString) { NSEmitTODO(); //TODO //[self setBatchFaultingMaxSize: [tmpString intValue]]; } tmpObject = [propertyList objectForKey: @"fetchSpecificationDictionary"]; EOFLOGObjectLevelArgs(@"EOEntity", @"fetchSpecificationDictionary=%@ [%@]", tmpObject, [tmpObject class]); if (tmpObject) { tmpObject = AUTORELEASE([tmpObject mutableCopy]); ASSIGN(_fetchSpecificationDictionary, tmpObject); } else { _fetchSpecificationDictionary = [NSMutableDictionary new]; EOFLOGObjectLevelArgs(@"EOEntity", @"Entity %@ - _fetchSpecificationDictionary %p [RC=%d]:%@", [self name], _fetchSpecificationDictionary, [_fetchSpecificationDictionary retainCount], _fetchSpecificationDictionary); } // load entity's FetchSpecifications { NSDictionary *plist = nil; NSString* fileName; NSString* path; fileName = [NSString stringWithFormat: @"%@.fspec", _name]; path = [(EOModel *)owner path]; path = [path stringByAppendingPathComponent: fileName]; if ([[NSFileManager defaultManager] fileExistsAtPath: path]) plist = [[NSString stringWithContentsOfFile: path] propertyList]; if (plist) { EOKeyValueUnarchiver *unarchiver; NSDictionary *variables; NSEnumerator *variablesEnum; id fetchSpecName; unarchiver = AUTORELEASE([[EOKeyValueUnarchiver alloc] initWithDictionary: [NSDictionary dictionaryWithObject: plist forKey: @"fspecs"]]); variables = [unarchiver decodeObjectForKey: @"fspecs"]; [unarchiver finishInitializationOfObjects]; [unarchiver awakeObjects]; variablesEnum = [variables keyEnumerator]; while ((fetchSpecName = [variablesEnum nextObject])) { id fetchSpec = [variables objectForKey: fetchSpecName]; [self addFetchSpecification: fetchSpec withName: fetchSpecName]; } } } _flags.updating = NO; } } NS_HANDLER { [EOObserverCenter enableObserverNotification]; NSLog(@"exception in EOEntity initWithPropertyList:owner:"); NSLog(@"exception=%@", localException); NSLog(@"exception=%@", localException); [localException raise]; } NS_ENDHANDLER; [EOObserverCenter enableObserverNotification]; return self; } - (void)awakeWithPropertyList: (NSDictionary *)propertyList { NSString *tmp; if ((tmp = [propertyList objectForKey:@"parent"])) { EOEntity *parent = [_model entityNamed:tmp]; /* TODO tests for parents spanning models. */ if (!parent) parent = [[_model modelGroup] entityNamed:tmp]; [parent addSubEntity:self]; } } - (void)encodeIntoPropertyList: (NSMutableDictionary *)propertyList { int i, count; if (_name) [propertyList setObject: _name forKey: @"name"]; if (_className) [propertyList setObject: _className forKey: @"className"]; if (_externalName) [propertyList setObject: _externalName forKey: @"externalName"]; if (_externalQuery) [propertyList setObject: _externalQuery forKey: @"externalQuery"]; if (_userInfo) [propertyList setObject: _userInfo forKey: @"userInfo"]; if (_docComment) [propertyList setObject: _docComment forKey: @"docComment"]; if (_batchCount) [propertyList setObject: [NSString stringWithFormat:@"%d", _batchCount] forKey: @"maxNumberOfInstancesToBatchFetch"]; if (_flags.cachesObjects) [propertyList setObject: @"Y" forKey: @"cachesObjects"]; if (_flags.isAbstractEntity) [propertyList setObject: @"Y" forKey: @"isAbstractEntity"]; if (_parent) [propertyList setObject: [_parent name] forKey: @"parent"]; if ((count = [_attributes count])) { if (_flags.attributesIsLazy) [propertyList setObject: _attributes forKey: @"attributes"]; else { NSMutableArray *attributesPList = [NSMutableArray array]; for (i = 0; i < count; i++) { NSMutableDictionary *attributePList = [NSMutableDictionary dictionary]; [[_attributes objectAtIndex: i] encodeIntoPropertyList: attributePList]; [attributesPList addObject: attributePList]; } [propertyList setObject: attributesPList forKey: @"attributes"]; } } if ((count = [_attributesUsedForLocking count])) { if (_flags.attributesUsedForLockingIsLazy) [propertyList setObject: _attributesUsedForLocking forKey: @"attributesUsedForLocking"]; else { NSMutableArray *attributesUsedForLockingPList = [NSMutableArray array]; for (i = 0; i < count; i++) { NSString *attributePList = [(EOAttribute *)[_attributesUsedForLocking objectAtIndex: i] name]; [attributesUsedForLockingPList addObject: attributePList]; } [propertyList setObject: attributesUsedForLockingPList forKey: @"attributesUsedForLocking"]; } } if ((count = [_classProperties count])) { if (_flags.classPropertiesIsLazy) [propertyList setObject: _classProperties forKey: @"classProperties"]; else { NSMutableArray *classPropertiesPList = [NSMutableArray array]; for (i = 0; i < count; i++) { NSString *classPropertyPList = [(EOAttribute *)[_classProperties objectAtIndex: i] name]; [classPropertiesPList addObject: classPropertyPList]; } [propertyList setObject: classPropertiesPList forKey: @"classProperties"]; } } if ((count = [_primaryKeyAttributes count])) { if (_flags.primaryKeyAttributesIsLazy) [propertyList setObject: _primaryKeyAttributes forKey: @"primaryKeyAttributes"]; else { NSMutableArray *primaryKeyAttributesPList = [NSMutableArray array]; for (i = 0; i < count; i++) { NSString *attributePList= [(EOAttribute *)[_primaryKeyAttributes objectAtIndex: i] name]; [primaryKeyAttributesPList addObject: attributePList]; } [propertyList setObject: primaryKeyAttributesPList forKey: @"primaryKeyAttributes"]; } } { NSArray *relsPlist = [self relationshipsPlist]; if (relsPlist) { [propertyList setObject: relsPlist forKey: @"relationships"]; } } } - (id) init { //OK if ((self = [super init])) { _attributes = [NSMutableArray new]; _subEntities = [NSMutableArray new]; _relationships = [NSMutableArray new]; } return self; } static void performSelectorOnArrayWithEachObjectOfClass(NSArray *arr, SEL selector, id arg, Class class) { int i, c; arr = [arr copy]; for (i = 0, c = [arr count]; i < c; i++) { id obj = [arr objectAtIndex:i]; if ([obj isKindOfClass:class]) { [obj performSelector:selector withObject:arg]; } } RELEASE(arr); } - (void) dealloc { /* these classes may contain NSDictionaries as well as entities, attributes and relationships in the case of delayed instantiation */ performSelectorOnArrayWithEachObjectOfClass(_subEntities, @selector(_setParentEntity:), nil, [EOEntity class]); performSelectorOnArrayWithEachObjectOfClass(_attributes, @selector(setParent:), nil, [EOAttribute class]); performSelectorOnArrayWithEachObjectOfClass(_relationships, @selector(setEntity:), nil, [EORelationship class]); if (_classDescription) [[EOClassDescription class] invalidateClassDescriptionCache]; DESTROY(_adaptorDictionaryInitializer); DESTROY(_instanceDictionaryInitializer); DESTROY(_primaryKeyDictionaryInitializer); DESTROY(_propertyDictionaryInitializer); DESTROY(_snapshotDictionaryInitializer); DESTROY(_attributes); DESTROY(_attributesByName); DESTROY(_attributesToFetch); DESTROY(_attributesToSave); DESTROY(_attributesUsedForLocking); DESTROY(_classDescription); DESTROY(_classForInstances); DESTROY(_className); DESTROY(_classProperties); DESTROY(_classPropertyAttributeNames); DESTROY(_classPropertyNames); DESTROY(_classPropertyToManyRelationshipNames); DESTROY(_classPropertyToOneRelationshipNames); DESTROY(_dbSnapshotKeys); DESTROY(_docComment); DESTROY(_externalName); DESTROY(_externalQuery); DESTROY(_fetchSpecificationDictionary); DESTROY(_fetchSpecificationNames); DESTROY(_hiddenRelationships); DESTROY(_internalInfo); DESTROY(_name); DESTROY(_primaryKeyAttributes); DESTROY(_primaryKeyAttributeNames); DESTROY(_propertiesToFault); // never initialized? DESTROY(_restrictingQualifier); DESTROY(_relationships); DESTROY(_relationshipsByName); DESTROY(_storedProcedures); // never initialized? DESTROY(_snapshotToAdaptorRowSubsetMapping); DESTROY(_subEntities); DESTROY(_userInfo); [super dealloc]; } - (NSString *)description { NSMutableDictionary *plist; plist = [NSMutableDictionary dictionaryWithCapacity: 4]; [self encodeIntoPropertyList: plist]; return [plist description]; } - (NSString *)debugDescription { NSString *dscr = nil; dscr = [NSString stringWithFormat: @"<%s %p - name=%@ className=%@ externalName=%@ externalQuery=%@", object_get_class_name(self), (void*)self, _name, _className, _externalName, _externalQuery]; dscr = [dscr stringByAppendingFormat:@" userInfo=%@", _userInfo]; dscr = [dscr stringByAppendingFormat:@" primaryKeyAttributeNames=%@ classPropertyNames=%@>", [self primaryKeyAttributeNames], [self classPropertyNames]]; NSAssert4(!_attributesToFetch || [_attributesToFetch isKindOfClass:[NSArray class]], @"entity %@ attributesToFetch %p is not an NSArray but a %@\n%@", [self name], _attributesToFetch, [_attributesToFetch class], _attributesToFetch); return dscr; } /*----------------------------------------*/ - (NSString *)name { return _name; } - (EOModel *)model { return _model; } - (NSString *)externalName { EOFLOGObjectLevelArgs(@"EOEntity", @"entity %p (%@): external name=%@", self, [self name], _externalName); return _externalName; } - (NSString *)externalQuery { return _externalQuery; } - (EOQualifier *)restrictingQualifier { return _restrictingQualifier; } - (BOOL)isReadOnly { return _flags.isReadOnly; } - (BOOL)cachesObjects { return _flags.cachesObjects; } - (NSString *)className { return _className; } - (NSDictionary *)userInfo { return _userInfo; } - (NSArray *)attributes { if (_flags.attributesIsLazy) { int count = 0; EOFLOGObjectLevelArgs(@"EOEntity", @"START construct attributes on %p", self); count = [_attributes count]; EOFLOGObjectLevelArgs(@"EOEntity", @"Entity %@: Lazy _attributes=%@", [self name], _attributes); if (count > 0) { int i = 0; NSArray *attributePLists = AUTORELEASE(RETAIN(_attributes)); DESTROY(_attributes); DESTROY(_attributesByName); _attributes = [NSMutableArray new]; _attributesByName = [NSMutableDictionary new]; /* if we've already loaded relationships rebuild the name cache */ if (!_flags.relationshipsIsLazy && _relationshipsByName == nil) [self relationshipsByName]; _flags.attributesIsLazy = NO; [EOObserverCenter suppressObserverNotification]; _flags.updating = YES; NS_DURING { NSArray *attrNames = nil; for (i = 0; i < count; i++) { id attrPList = [attributePLists objectAtIndex: i]; EOAttribute *attribute = nil; NSString *attributeName = nil; // this should validate name against its owner via setName: attribute = [EOAttribute attributeWithPropertyList: attrPList owner: self]; attributeName = [attribute name]; // don't call -addAttribute: because it wipes our name cache [_attributes addObject: attribute]; [_attributesByName setObject: attribute forKey: attributeName]; } attrNames = [_attributes resultsOfPerformingSelector: @selector(name)]; count = [attrNames count]; NSAssert(count == [attributePLists count], @"Error during attribute creations"); { int pass = 0; //We'll first awake non derived/flattened attributes for (pass = 0; pass < 2; pass++) { for (i = 0; i < count; i++) { NSString *attrName = [attrNames objectAtIndex: i]; NSDictionary *attrPList = nil; EOAttribute *attribute = nil; id definition = nil; EOFLOGObjectLevelArgs(@"EOEntity", @"XXX attrName=%@", attrName); attrPList = [attributePLists objectAtIndex: i]; definition = [attrPList objectForKey: @"definition"]; if ((pass == 0 && definition == nil) || (pass == 1 && definition != nil)) { attribute = [self attributeNamed: attrName]; EOFLOGObjectLevelArgs(@"EOEntity", @"XXX 2A ATTRIBUTE: self=%p AWAKE attribute=%@", self, attribute); [attribute awakeWithPropertyList: attrPList]; EOFLOGObjectLevelArgs(@"EOEntity", @"XXX 2B ATTRIBUTE: self=%p attribute=%@", self, attribute); } } } } } NS_HANDLER { _flags.updating = NO; [EOObserverCenter enableObserverNotification]; [localException raise]; } NS_ENDHANDLER; _flags.updating = NO; [EOObserverCenter enableObserverNotification]; [_attributes sortUsingSelector: @selector(eoCompareOnName:)];//Very important to have always the same order. } else _flags.attributesIsLazy = NO; EOFLOGObjectLevelArgs(@"EOEntity", @"STOP construct attributes on %p", self); } return _attributes; } - (EOAttribute *)attributeNamed: (NSString *)attributeName { //OK EOAttribute *attribute = nil; NSDictionary *attributesByName = nil; EOFLOGObjectFnStart(); attributesByName = [self attributesByName]; EOFLOGObjectLevelArgs(@"EOEntity", @"attributesByName [%p] (%@)", attributesByName, [attributesByName class]); NSAssert2((!attributesByName || [attributesByName isKindOfClass: [NSDictionary class]]), @"attributesByName is not a NSDictionary but a %@. attributesByName [%p]", [attributesByName class], attributesByName); // EOFLOGObjectLevelArgs(@"EOEntity",@"attributesByName=%@",attributesByName); attribute = [attributesByName objectForKey: attributeName]; EOFLOGObjectFnStop(); return attribute; } /** returns attribute named attributeName (no relationship) **/ - (EOAttribute *)anyAttributeNamed: (NSString *)attributeName { EOAttribute *attr; NSEnumerator *attrEnum; attr = [self attributeNamed:attributeName]; //VERIFY /* I suppose this is intended to find the 'hidden' attributes mentioned in * the documentation of this method, but if these are in -primaryKeyAttributes * they don't appear to be well hidden, and _primaryKeyAttributes is filled * by calling -attributeNamed: and doesn't appear to be modified outside * -primaryKeyAttributes:, so this check appears to be redundant to the one * above. */ if (!attr) { IMP enumNO=NULL; attrEnum = [[self primaryKeyAttributes] objectEnumerator]; while ((attr = GDL2_NextObjectWithImpPtr(attrEnum,&enumNO))) { if ([[attr name] isEqual: attributeName]) return attr; } } return attr; } - (NSArray *)relationships { //OK if (_flags.relationshipsIsLazy) { int count = 0; EOFLOGObjectLevelArgs(@"EOEntity", @"START construct relationships on %p", self); count = [_relationships count]; EOFLOGObjectLevelArgs(@"EOEntity", @"Lazy _relationships=%@", _relationships); if (count > 0) { int i = 0; NSArray *relationshipPLists = _relationships; DESTROY(_relationshipsByName); _relationships = [NSMutableArray new]; _relationshipsByName = [NSMutableDictionary new]; if (!_flags.attributesIsLazy && _attributesByName == nil) [self attributesByName]; _flags.relationshipsIsLazy = NO; [EOObserverCenter suppressObserverNotification]; _flags.updating = YES; NS_DURING { NSArray *relNames = nil; for (i = 0; i < count; i++) { id attrPList = [relationshipPLists objectAtIndex: i]; EORelationship *relationship = nil; NSString *relationshipName = nil; /* this should cause validation to occur. */ relationship= [EORelationship relationshipWithPropertyList: attrPList owner: self]; relationshipName = [relationship name]; [_relationships addObject: relationship]; [_relationshipsByName setObject: relationship forKey: relationshipName]; } EOFLOGObjectLevel(@"EOEntity", @"Rels added"); relNames = [_relationships resultsOfPerformingSelector: @selector(name)]; EOFLOGObjectLevelArgs(@"EOEntity", @"relNames=%@", relNames); count = [relNames count]; EOFLOGObjectLevelArgs(@"EOEntity", @"self=%p rel count=%d", self, count); NSAssert(count == [relationshipPLists count], @"Error during attribute creations"); { int pass = 0; //We'll first awake non flattened relationships for (pass = 0; pass < 2; pass++) { for (i = 0; i < count; i++) { NSDictionary *relPList = [relationshipPLists objectAtIndex: i]; if ([relPList isKindOfClass: [EORelationship class]]) continue; { NSString *relName = [relNames objectAtIndex: i]; EORelationship *relationship; relationship = [self relationshipNamed: relName]; EOFLOGObjectLevelArgs(@"EOEntity", @"relName=%@", relName); if ((pass == 0 && ![relPList objectForKey: @"definition"]) || (pass == 1 && [relPList objectForKey: @"definition"])) { EOFLOGObjectLevelArgs(@"EOEntity", @"XXX REL: self=%p AWAKE relationship=%@", self, relationship); [relationship awakeWithPropertyList: relPList]; } } } } } } NS_HANDLER { EOFLOGObjectLevelArgs(@"EOEntity", @"localException=%@", localException); DESTROY(relationshipPLists); _flags.updating = NO; [EOObserverCenter enableObserverNotification]; [localException raise]; } NS_ENDHANDLER; DESTROY(relationshipPLists); _flags.updating = NO; [EOObserverCenter enableObserverNotification]; } else _flags.relationshipsIsLazy = NO; EOFLOGObjectLevelArgs(@"EOEntity", @"STOP construct relationships on %p", self); } return _relationships; } - (EORelationship *)relationshipNamed: (NSString *)relationshipName { //OK return [[self relationshipsByName] objectForKey: relationshipName]; } - (EORelationship *)anyRelationshipNamed: (NSString *)relationshipName { EORelationship *rel; NSEnumerator *relEnum = nil; rel = [self relationshipNamed: relationshipName]; //VERIFY if (!rel) { EORelationship *tmpRel = nil; IMP enumNO=NULL; relEnum = [_hiddenRelationships objectEnumerator]; while (!rel && (tmpRel = GDL2_NextObjectWithImpPtr(relEnum,&enumNO))) { if ([[tmpRel name] isEqual: relationshipName]) rel = tmpRel; } } return rel; } - (NSArray *)classProperties { //OK EOFLOGObjectFnStart(); if (_flags.classPropertiesIsLazy) { int count = [_classProperties count]; EOFLOGObjectLevelArgs(@"EOEntity", @"Lazy _classProperties=%@", _classProperties); if (count > 0) { NSArray *classPropertiesList = _classProperties; int i; _classProperties = [NSMutableArray new]; _flags.classPropertiesIsLazy = NO; for (i = 0; i < count; i++) { #if 0 NSString *classPropertyName = [classPropertiesList objectAtIndex: i]; #else id classPropertyName = ( [[classPropertiesList objectAtIndex:i] isKindOfClass:[NSString class]] ? [classPropertiesList objectAtIndex:i] : [(EOEntity *)[classPropertiesList objectAtIndex: i] name]); #endif id classProperty = [self attributeNamed: classPropertyName]; if (!classProperty) classProperty = [self relationshipNamed: classPropertyName]; NSAssert4(classProperty, @"No attribute or relationship named '%@' (property at index %d) to use as classProperty in entity name '%@' : %@", classPropertyName, i+1, [self name], self); if ([self isValidClassProperty: classProperty]) [_classProperties addObject: classProperty]; else { //TODO NSAssert2(NO, @"not valid class prop %@ in %@", classProperty, [self name]); } } DESTROY(classPropertiesList); [_classProperties sortUsingSelector: @selector(eoCompareOnName:)]; //Very important to have always the same order. [self _setIsEdited]; //To Clean Buffers } else _flags.classPropertiesIsLazy = NO; } EOFLOGObjectFnStop(); return _classProperties; } - (NSArray *)classPropertyNames { //OK EOFLOGObjectFnStart(); if (!_classPropertyNames) { NSArray *classProperties = [self classProperties]; NSAssert2(!classProperties || [classProperties isKindOfClass: [NSArray class]], @"classProperties is not an NSArray but a %@\n%@", [classProperties class], classProperties); ASSIGN(_classPropertyNames, [classProperties resultsOfPerformingSelector: @selector(name)]); } NSAssert4(!_attributesToFetch || [_attributesToFetch isKindOfClass: [NSArray class]], @"entity %@ attributesToFetch %p is not an NSArray but a %@\n%@", [self name], _attributesToFetch, [_attributesToFetch class], _attributesToFetch); EOFLOGObjectFnStop(); return _classPropertyNames; } - (NSArray *)fetchSpecificationNames { return _fetchSpecificationNames; } - (EOFetchSpecification *)fetchSpecificationNamed: (NSString *)fetchSpecName { return [_fetchSpecificationDictionary objectForKey: fetchSpecName]; } - (NSArray *)sharedObjectFetchSpecificationNames { NSEmitTODO(); //TODO [self notImplemented: _cmd]; return nil; } - (NSArray*)primaryKeyAttributes { //OK if (_flags.primaryKeyAttributesIsLazy) { int count = [_primaryKeyAttributes count]; EOFLOGObjectLevelArgs(@"EOEntity", @"Lazy _primaryKeyAttributes=%@", _primaryKeyAttributes); if (count > 0) { int i = 0; NSArray *primaryKeyAttributes = _primaryKeyAttributes; _primaryKeyAttributes = [NSMutableArray new]; _flags.primaryKeyAttributesIsLazy = NO; for (i = 0; i < count; i++) { NSString *attributeName = [primaryKeyAttributes objectAtIndex: i]; EOAttribute *attribute = [self attributeNamed: attributeName]; NSAssert3(attribute, @"In entity %@: No attribute named %@ " @"to use for locking (attributes: %@)", [self name], attributeName, [[self attributes] resultsOfPerformingSelector: @selector(name)]); if ([self isValidPrimaryKeyAttribute: attribute]) [_primaryKeyAttributes addObject: attribute]; else { NSAssert2(NO, @"not valid pk attribute %@ in %@", attribute, [self name]); } } DESTROY(primaryKeyAttributes); [_primaryKeyAttributes sortUsingSelector: @selector(eoCompareOnName:)]; //Very important to have always the same order. [self _setIsEdited]; //To Clean Buffers } else _flags.primaryKeyAttributesIsLazy = NO; } return _primaryKeyAttributes; } - (NSArray *)primaryKeyAttributeNames { //OK if (!_primaryKeyAttributeNames) { NSArray *primaryKeyAttributes = [self primaryKeyAttributes]; NSArray *primaryKeyAttributeNames = [primaryKeyAttributes resultsOfPerformingSelector: @selector(name)]; primaryKeyAttributeNames = [primaryKeyAttributeNames sortedArrayUsingSelector: @selector(compare:)]; //Not necessary: they are already sorted ASSIGN(_primaryKeyAttributeNames, primaryKeyAttributeNames); } return _primaryKeyAttributeNames; } - (NSArray *)attributesUsedForLocking { //OK if (_flags.attributesUsedForLockingIsLazy) { int count = [_attributesUsedForLocking count]; EOFLOGObjectLevelArgs(@"EOEntity", @"Lazy _attributesUsedForLocking=%@", _attributesUsedForLocking); if (count > 0) { int i = 0; NSArray *attributesUsedForLocking = _attributesUsedForLocking; _attributesUsedForLocking = [NSMutableArray new]; _flags.attributesUsedForLockingIsLazy = NO; for (i = 0; i < count; i++) { NSString *attributeName = [attributesUsedForLocking objectAtIndex: i]; EOAttribute *attribute = [self attributeNamed: attributeName]; NSAssert1(attribute, @"No attribute named %@ to use for locking", attribute); if ([self isValidAttributeUsedForLocking: attribute]) [_attributesUsedForLocking addObject: attribute]; else { NSEmitTODO(); //TODO [self notImplemented: _cmd]; //TODO } } EOFLOGObjectLevelArgs(@"EOEntity", @"_attributesUsedForLocking class=%@", [_attributesUsedForLocking class]); DESTROY(attributesUsedForLocking); [self _setIsEdited]; //To Clean Buffers } else _flags.attributesUsedForLockingIsLazy = NO; } return _attributesUsedForLocking; } - (NSArray *)attributesToFetch { //OK NSAssert3(!_attributesToFetch | [_attributesToFetch isKindOfClass: [NSArray class]], @"entity %@ attributesToFetch %p is not an NSArray but a %@", [self name], _attributesToFetch, [_attributesToFetch class]); return [self _attributesToFetch]; } - (EOQualifier *)qualifierForPrimaryKey: (NSDictionary *)row { //OK EOQualifier *qualifier = nil; NSArray *primaryKeyAttributeNames = [self primaryKeyAttributeNames]; int count = [primaryKeyAttributeNames count]; if (count == 1) { //OK NSString *key = [primaryKeyAttributeNames objectAtIndex: 0]; id value = [row objectForKey: key]; qualifier = [EOKeyValueQualifier qualifierWithKey: key operatorSelector: EOQualifierOperatorEqual value: value]; } else { //Seems OK NSMutableArray *array = AUTORELEASE([GDL2_alloc(NSMutableArray) initWithCapacity: count]); IMP pkanOAI=NULL; IMP rowOFK=NULL; IMP arrayAO=NULL; int i; for (i = 0; i < count; i++) { NSString *key = GDL2_ObjectAtIndexWithImpPtr(primaryKeyAttributeNames,&pkanOAI,i); id value = GDL2_ObjectForKeyWithImpPtr(row,&rowOFK,key); GDL2_AddObjectWithImpPtr(array,&arrayAO, [EOKeyValueQualifier qualifierWithKey: key operatorSelector: EOQualifierOperatorEqual value: value]); } qualifier = [EOAndQualifier qualifierWithQualifierArray: array]; } return qualifier; } - (BOOL)isQualifierForPrimaryKey: (EOQualifier *)qualifier { int count = [[self primaryKeyAttributeNames] count]; if (count == 1) { if ([qualifier isKindOfClass: [EOKeyValueQualifier class]] == YES) return YES; else return NO; } else { } //TODO NSEmitTODO(); //TODO [self notImplemented:_cmd]; return NO; } - (NSDictionary *)primaryKeyForRow: (NSDictionary *)row { NSMutableDictionary *dict = nil; int i, count; NSArray *primaryKeyAttributes = [self primaryKeyAttributes]; IMP pkaOAI=NULL; IMP rowOFK=NULL; IMP dictSOFK=NULL; count = [primaryKeyAttributes count]; dict = [NSMutableDictionary dictionaryWithCapacity: count]; for (i = 0; i < count; i++) { EOAttribute *attr = GDL2_ObjectAtIndexWithImpPtr(primaryKeyAttributes,&pkaOAI,i); NSString* attrName = [attr name]; id value = GDL2_ObjectForKeyWithImpPtr(row,&rowOFK,attrName); if (!value) value = GDL2_EONull; GDL2_SetObjectForKeyWithImpPtr(dict,&dictSOFK,value,attrName); } return dict; } - (BOOL)isValidAttributeUsedForLocking: (EOAttribute *)attribute { if (!([attribute isKindOfClass: GDL2_EOAttributeClass] && ([self attributeNamed: [attribute name]] == attribute))) return NO; if ([attribute isDerived]) return NO; return YES; } - (BOOL)isValidPrimaryKeyAttribute: (EOAttribute *)attribute { if (!([attribute isKindOfClass: GDL2_EOAttributeClass] && ([self attributeNamed: [attribute name]] == attribute))) return NO; if ([attribute isDerived]) return NO; return YES; } - (BOOL)isPrimaryKeyValidInObject: (id)object { NSArray *primaryKeyAttributeNames = nil; NSString *key = nil; id value = nil; int i, count; BOOL isValid = YES; IMP pkanOAI=NULL; IMP objectVFK=NULL; primaryKeyAttributeNames = [self primaryKeyAttributeNames]; count = [primaryKeyAttributeNames count]; for (i = 0; isValid && i < count; i++) { key = GDL2_ObjectAtIndexWithImpPtr(primaryKeyAttributeNames,&pkanOAI,i); NS_DURING { value = GDL2_ValueForKeyWithImpPtr(object,&objectVFK,key); if (_isNilOrEONull(value)) isValid = NO; } NS_HANDLER { isValid = NO; } NS_ENDHANDLER; } return isValid; } - (BOOL)isValidClassProperty: (id)property { id thePropertyName; if (!([property isKindOfClass: GDL2_EOAttributeClass] || [property isKindOfClass: [EORelationship class]])) return NO; thePropertyName = [(EOAttribute *)property name]; if ([[self attributesByName] objectForKey: thePropertyName] == property || [[self relationshipsByName] objectForKey: thePropertyName] == property) return YES; return NO; } - (NSArray *)subEntities { return _subEntities; } - (EOEntity *)parentEntity { return _parent; } - (BOOL)isAbstractEntity { return _flags.isAbstractEntity; } - (unsigned int)maxNumberOfInstancesToBatchFetch { return _batchCount; } - (EOGlobalID *)globalIDForRow: (NSDictionary *)row { EOGlobalID *gid = [self globalIDForRow: row isFinal: NO]; NSAssert(gid, @"No gid"); //TODO /* pas toutjur: la suite editingc objectForGlobalID: EODatabaseContext snapshotForGlobalID: if no snpashot: { database recordSnapshot:forGlobalID: self classDescriptionForInstances createInstanceWithEditingContext:globalID:zone: } */ return gid; } - (NSDictionary *)primaryKeyForGlobalID: (EOKeyGlobalID *)gid { //OK NSMutableDictionary *dictionaryForPrimaryKey = nil; if ([gid isKindOfClass: [EOKeyGlobalID class]]) //if ([gid isFinal])//?? or class test ??//TODO { NSArray *primaryKeyAttributeNames = [self primaryKeyAttributeNames]; int count = [primaryKeyAttributeNames count]; if (count > 0) { int i; id *gidkeyValues = [gid keyValues]; if (gidkeyValues) { IMP pkanOAI=NULL; IMP dfpkSOFK=NULL; dictionaryForPrimaryKey = [self _dictionaryForPrimaryKey]; NSAssert1(dictionaryForPrimaryKey, @"No dictionaryForPrimaryKey in entity %@", [self name]); for (i = 0; i < count; i++) { id key = GDL2_ObjectAtIndexWithImpPtr(primaryKeyAttributeNames,&pkanOAI,i); GDL2_SetObjectForKeyWithImpPtr(dictionaryForPrimaryKey,&dfpkSOFK, gidkeyValues[i],key); } } } } else { NSDebugLog(@"EOEntity (%@): primaryKey is *nil* for globalID = %@", _name, gid); } return dictionaryForPrimaryKey; } @end @implementation EOEntity (EOEntityEditing) - (void)setName: (NSString *)name { if (name && [name isEqual: _name]) return; [[self validateName: name] raise]; [self willChange]; ASSIGNCOPY(_name, name); [_model _updateCache]; } - (void)setExternalName: (NSString *)name { //OK EOFLOGObjectLevelArgs(@"EOEntity", @"entity %p (%@): external name=%@", self, [self name], name); [self willChange]; ASSIGNCOPY(_externalName,name); [self _setIsEdited]; } - (void)setExternalQuery: (NSString *)query { //OK [self willChange]; ASSIGNCOPY(_externalQuery, query); [self _setIsEdited]; } - (void)setRestrictingQualifier: (EOQualifier *)qualifier { [self willChange]; ASSIGN(_restrictingQualifier, qualifier); } - (void)setReadOnly: (BOOL)flag { //OK [self willChange]; _flags.isReadOnly = flag; } - (void)setCachesObjects: (BOOL)flag { //OK [self willChange]; _flags.cachesObjects = flag; } - (void)addAttribute: (EOAttribute *)attribute { NSString *attributeName = [attribute name]; NSAssert2([[self attributesByName] objectForKey: attributeName] == nil, @"'%@': attribute '%@' already used in the entity", [self name], attributeName); NSAssert2([[self relationshipsByName] objectForKey: attributeName] == nil, @"'%@': attribute '%@' already used in entity as relationship", [self name], attributeName); NSAssert4([attribute parent] == nil, @"'%@': attribute '%@' already owned by '%@' '%@'", [self name], attributeName, NSStringFromClass([[attribute parent] class]), [(EOEntity *)[attribute parent] name]); [self willChange]; [_attributes addObject: attribute]; [self _setIsEdited]; //To clean caches [attribute setParent: self]; } /** * Removes the attribute from the -attributes array, and the * -classProperties, and -primaryKeyAttributes arrays if they contain it. * does not remove any references to the attribute from other properties. * the caller should insure that no such references exist by calling * -referencesProperty: or [EOModel -referencesToProperty:]. */ - (void) removeAttribute: (EOAttribute *)attribute { if (attribute) { [self willChange]; [attribute setParent: nil]; NSEmitTODO(); //TODO [_attributes removeObject: attribute]; [_classProperties removeObject:attribute]; [_primaryKeyAttributes removeObject:attribute]; [self _setIsEdited];//To clean caches } } - (void)addRelationship: (EORelationship *)relationship { NSString *relationshipName = [relationship name]; if ([[self attributesByName] objectForKey: relationshipName]) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: \"%@\" already used in the model as attribute", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, relationshipName]; if ([[self relationshipsByName] objectForKey: relationshipName]) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: \"%@\" already used in the model", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, relationshipName]; [self willChange]; [_relationships addObject: relationship]; if (_relationshipsByName == nil) { _relationshipsByName = [NSMutableDictionary new]; } [_relationshipsByName setObject: relationship forKey: relationshipName]; [relationship setEntity: self]; [self _setIsEdited];//To clean caches } /** * Removes the relationship from the -relationships array and * the -classProperties array if it contains the relationship. * The caller should insure that no references to the * relationship exist by calling -referencesProperty: or * [EOModel -referencesToProperty]. */ - (void)removeRelationship: (EORelationship *)relationship { if (relationship) { [self willChange]; if(_relationshipsByName != nil) [_relationshipsByName removeObjectForKey:[relationship name]]; [_relationships removeObject: relationship]; [_classProperties removeObject: relationship]; /* We call this after adjusting the arrays so that setEntity: has the opportunity to check the relationships before calling removeRelationshipt which would lead to an infinite loop. */ [relationship setEntity:nil]; [self _setIsEdited];//To clean caches } } - (void)addFetchSpecification: (EOFetchSpecification *)fetchSpec withName: (NSString *)name { if (_fetchSpecificationDictionary == nil) { _fetchSpecificationDictionary = [NSMutableDictionary new]; } [self willChange]; [_fetchSpecificationDictionary setObject: fetchSpec forKey: name]; ASSIGN(_fetchSpecificationNames, [[_fetchSpecificationDictionary allKeys] sortedArrayUsingSelector: @selector(compare:)]); } - (void)removeFetchSpecificationNamed: (NSString *)name { [self willChange]; [_fetchSpecificationDictionary removeObjectForKey:name]; ASSIGN(_fetchSpecificationNames, [[_fetchSpecificationDictionary allKeys] sortedArrayUsingSelector: @selector(compare:)]); } - (void)setSharedObjectFetchSpecificationsByName: (NSArray *)names { NSEmitTODO(); //TODO [self notImplemented:_cmd]; } - (void)addSharedObjectFetchSpecificationByName: (NSString *)name { NSEmitTODO(); //TODO [self notImplemented:_cmd]; } - (void)removeSharedObjectFetchSpecificationByName: (NSString *)name { NSEmitTODO(); //TODO [self notImplemented:_cmd]; } - (void)setClassName:(NSString *)name { //OK [self willChange]; if (!name) { NSLog(@"Entity %@ has no class name. Use EOGenericRecord", [self name]); name = @"EOGenericRecord"; } ASSIGNCOPY(_className, name); [self _setIsEdited]; } - (void)setUserInfo: (NSDictionary *)dictionary { //OK [self willChange]; ASSIGN(_userInfo, dictionary); [self _setIsEdited]; } - (BOOL)setClassProperties: (NSArray *)properties { int i, count = [properties count]; for (i = 0; i < count; i++) if (![self isValidClassProperty: [properties objectAtIndex:i]]) return NO; [self willChange]; DESTROY(_classProperties); _classProperties = [[NSMutableArray alloc] initWithArray: properties]; //TODO [self _setIsEdited]; //To clean cache return YES; } - (BOOL)setPrimaryKeyAttributes: (NSArray *)keys { int i, count = [keys count]; for (i = 0; i < count; i++) if (![self isValidPrimaryKeyAttribute: [keys objectAtIndex:i]]) return NO; [self willChange]; DESTROY(_primaryKeyAttributes); _primaryKeyAttributes = [[NSMutableArray alloc] initWithArray: keys]; // TODO [self _setIsEdited];//To clean cache return YES; } - (BOOL) setAttributesUsedForLocking: (NSArray *)attributes { int i, count = [attributes count]; for (i = 0; i < count; i++) if (![self isValidAttributeUsedForLocking: [attributes objectAtIndex: i]]) return NO; [self willChange]; DESTROY(_attributesUsedForLocking); _attributesUsedForLocking = [[NSMutableArray alloc] initWithArray: attributes]; [self _setIsEdited]; //To clean cache return YES; } - (NSException *)validateName: (NSString *)name { const char *p, *s = [name cString]; int exc = 0; NSArray *storedProcedures; if ([_name isEqual:name]) return nil; if (!name || ![name length]) exc++; if (!exc) { p = s; while (*p) { if (!isalnum(*p) && *p != '@' && *p != '#' && *p != '_' && *p != '$') { exc++; break; } p++; } if (!exc && *s == '$') exc++; if (exc) return [NSException exceptionWithName: NSInvalidArgumentException reason: [NSString stringWithFormat:@"%@ -- %@ 0x%x: argument \"%@\" contains invalid char '%c'", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, name, *p] userInfo: nil]; if ([_model entityNamed: name]) exc++; else if ((storedProcedures = [[self model] storedProcedures])) { NSEnumerator *stEnum = [storedProcedures objectEnumerator]; EOStoredProcedure *st; while ((st = [stEnum nextObject])) { NSEnumerator *attrEnum; EOAttribute *attr; attrEnum = [[st arguments] objectEnumerator]; while ((attr = [attrEnum nextObject])) { if ([name isEqualToString: [attr name]]) { exc++; break; } } if (exc) break; } } } if (exc) { return [NSException exceptionWithName: NSInvalidArgumentException reason: [NSString stringWithFormat: @"%@ -- %@ 0x%x: \"%@\" already used in the model", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, name] userInfo: nil]; } return nil; } - (void)addSubEntity: (EOEntity *)child { [self willChange]; [_subEntities addObject: child]; [[child parentEntity] removeSubEntity:child]; [child _setParentEntity: self]; } - (void)removeSubEntity: (EOEntity *)child { [self willChange]; if ([child parentEntity] == self) [child _setParentEntity: nil]; [_subEntities removeObject: child]; } - (void)setIsAbstractEntity: (BOOL)flag { //OK [self willChange]; _flags.isAbstractEntity = flag; } - (void)setMaxNumberOfInstancesToBatchFetch: (unsigned int)size { [self willChange]; _batchCount = size; } @end @implementation EOEntity (EOModelReferentialIntegrity) - (BOOL)referencesProperty: (id)property { NSEnumerator *enumerator; EORelationship *rel; EOAttribute *attr; IMP enumNO=NULL; enumerator = [[self attributes] objectEnumerator]; enumNO=NULL; while ((attr = GDL2_NextObjectWithImpPtr(enumerator,&enumNO))) { if ([attr isFlattened] && [[attr realAttribute] isEqual: property]) return YES; } enumerator = [[self relationships] objectEnumerator]; enumNO=NULL; while ((rel = GDL2_NextObjectWithImpPtr(enumerator,&enumNO))) { if ([rel referencesProperty: property]) return YES; } return NO; } - (NSArray *)externalModelsReferenced { NSEmitTODO(); //TODO return nil; // TODO } @end @implementation EOEntity (EOModelBeautifier) - (void)beautifyName { //VERIFY NSString *name = [self name]; [self setName: name]; [[self attributes] makeObjectsPerformSelector: @selector(beautifyName)]; [[self relationships] makeObjectsPerformSelector: @selector(beautifyName)]; [[self flattenedAttributes] makeObjectsPerformSelector: @selector(beautifyName)]; //Turbocat: /* // Make the entity name and all of its components conform // to the Next naming style // NAME -> name, FIRST_NAME -> firstName + NSArray *listItems; NSString *newString=[NSString string]; int anz,i; EOFLOGObjectFnStartOrCond2(@"ModelingClasses",@"EOEntity"); // Makes the receiver's name conform to a standard convention. Names that conform to this style are all lower-case except for the initial letter of each embedded word other than the first, which is upper case. Thus, "NAME" becomes "name", and "FIRST_NAME" becomes "firstName". if ((_name) && ([_name length]>0)) { listItems=[_name componentsSeparatedByString:@"_"]; newString=[newString stringByAppendingString:[[listItems objectAtIndex:0] lowercaseString]]; anz=[listItems count]; for (i=1; i < anz; i++) { newString=[newString stringByAppendingString:[[listItems objectAtIndex:i] capitalizedString]]; } //#warning ergaenzen um alle components (attributes, ...) // Exception abfangen NS_DURING [self setName:newString]; NS_HANDLER NSLog(@"%@ in Class: EOEntity , Method: beautifyName >> error : %@",[localException name],[localException reason]); NS_ENDHANDLER } EOFLOGObjectFnStopOrCond2(@"ModelingClasses",@"EOEntity"); */ } @end @implementation EOEntity (GDL2Extenstions) - (NSString *)docComment { return _docComment; } - (void)setDocComment: (NSString *)docComment { //OK [self willChange]; ASSIGNCOPY(_docComment, docComment); [self _setIsEdited]; } @end @implementation EOEntity (EOStoredProcedures) - (EOStoredProcedure *)storedProcedureForOperation: (NSString *)operation { return [_storedProcedures objectForKey: operation]; } - (void)setStoredProcedure: (EOStoredProcedure *)storedProcedure forOperation: (NSString *)operation { [self willChange]; [_storedProcedures setObject: storedProcedure forKey: operation]; } @end @implementation EOEntity (EOPrimaryKeyGeneration) - (NSString *)primaryKeyRootName { if (_parent) return [_parent primaryKeyRootName]; return _externalName; } @end @implementation EOEntity (EOEntityClassDescription) - (EOClassDescription *)classDescriptionForInstances { EOFLOGObjectFnStart(); // EOFLOGObjectLevelArgs(@"EOEntity", @"in classDescriptionForInstances"); EOFLOGObjectLevelArgs(@"EOEntity", @"_classDescription=%@", _classDescription); if (!_classDescription) { _classDescription = [[EOEntityClassDescription alloc] initWithEntity: self]; //NO ? NotifyCenter addObserver:EOEntityClassDescription selector:_eoNowMultiThreaded: name:NSWillBecomeMultiThreadedNotification object:nil } EOFLOGObjectFnStop(); return _classDescription; } @end /** Useful private methods made public in GDL2 **/ @implementation EOEntity (EOEntityGDL2Additions) /** Returns attribute (if any) for path **/ - (EOAttribute*) attributeForPath: (NSString*)path { //OK EOAttribute *attribute = nil; NSArray *pathElements = nil; NSString *part = nil; EOEntity *entity = self; int i, count = 0; EOFLOGObjectFnStart(); EOFLOGObjectLevelArgs(@"EOEntity", @"path=%@", path); pathElements = [path componentsSeparatedByString: @"."]; EOFLOGObjectLevelArgs(@"EOEntity", @"pathElements=%@", pathElements); count = [pathElements count]; for (i = 0; i < count - 1; i++) { EORelationship *rel = nil; part = [pathElements objectAtIndex: i]; EOFLOGObjectLevelArgs(@"EOEntity", @"i=%d part=%@", i, part); rel = [entity anyRelationshipNamed: part]; NSAssert2(rel, @"no relationship named %@ in entity %@", part, [entity name]); EOFLOGObjectLevelArgs(@"EOEntity", @"i=%d part=%@ rel=%@", i, part, rel); entity = [rel destinationEntity]; EOFLOGObjectLevelArgs(@"EOEntity", @"entity name=%@", [entity name]); } part = [pathElements lastObject]; EOFLOGObjectLevelArgs(@"EOEntity", @"part=%@", part); attribute = [entity anyAttributeNamed: part]; EOFLOGObjectLevelArgs(@"EOEntity", @"resulting attribute=%@", attribute); EOFLOGObjectFnStop(); return attribute; } /** Returns relationship (if any) for path **/ - (EORelationship*) relationshipForPath: (NSString*)path { //OK ? EORelationship *relationship = nil; EOEntity *entity = self; NSArray *pathElements = nil; int i, count; EOFLOGObjectFnStart(); EOFLOGObjectLevelArgs(@"EOEntity", @"path=%@", path); pathElements = [path componentsSeparatedByString: @"."]; count = [pathElements count]; for (i = 0; i < count; i++) { NSString *part = [pathElements objectAtIndex: i]; relationship = [entity anyRelationshipNamed: part]; EOFLOGObjectLevelArgs(@"EOEntity", @"i=%d part=%@ rel=%@", i, part, relationship); if (relationship) { entity = [relationship destinationEntity]; EOFLOGObjectLevelArgs(@"EOEntity", @"entity name=%@", [entity name]); } else if (i < (count - 1)) // Not the last part { NSAssert2(relationship, @"no relationship named %@ in entity %@", part, [entity name]); } } EOFLOGObjectFnStop(); EOFLOGObjectLevelArgs(@"EOEntity", @"relationship=%@", relationship); return relationship; } @end @implementation EOEntity (EOEntityPrivate) /* private method for finding out if there is an attribute with a name without triggering lazy loading */ - (BOOL) _hasAttributeNamed:(NSString *)name { return [[_attributes valueForKey:@"name"] containsObject:name]; } - (BOOL)isPrototypeEntity { [self notImplemented:_cmd]; return NO; // TODO } /* throws an exception if _model is not nil, and the model argument is not * identical to the _model ivar. As a special case EOModel -removeEntity: * is allowed to call this with a nil model, but removeEntity: is responsible * for any bookeeping. * * in other words, this method should not be used to change an entity's model. */ - (void)_setModel: (EOModel *)model { EOFLOGObjectLevelArgs(@"EOEntity", @"setModel=%p", model); NSAssert4(!_attributesToFetch || [_attributesToFetch isKindOfClass:[NSArray class]], @"entity %@ attributesToFetch %p is not an NSArray but a %@\n%@", [self name], _attributesToFetch, [_attributesToFetch class], _attributesToFetch); NSAssert3((_model == nil || _model == model || model == nil), @"Attempt to set entity: %@ owned by model: %@ to model: @%.", [self name], [_model name], [model name]); _model = model; } /* only for private usage of -addSubEntity: and -removeSubEntity: */ - (void)_setParentEntity: (EOEntity *)parent { [self willChange]; // TODO: verify _parent = parent; } - (NSDictionary *)snapshotForRow: (NSDictionary *)aRow { NSArray *array = [self attributesUsedForLocking]; int i, n = [array count]; NSMutableDictionary *dict = AUTORELEASE([GDL2_alloc(NSMutableDictionary) initWithCapacity: n]); IMP arrayOAI=NULL; IMP dictSOFK=NULL; IMP aRowOFK=NULL; for (i = 0; i < n; i++) { id key = [(EOAttribute *)GDL2_ObjectAtIndexWithImpPtr(array,&arrayOAI,i) name]; GDL2_SetObjectForKeyWithImpPtr(dict,&dictSOFK, GDL2_ObjectForKeyWithImpPtr(aRow,&aRowOFK,key), key); } return dict; } - (Class)_classForInstances { EOFLOGObjectFnStart(); if (!_classForInstances) { NSString *className = nil; Class objectClass = Nil; className = [self className]; EOFLOGObjectLevelArgs(@"EOEntity", @"className=%@", className); objectClass = NSClassFromString(className); if (!objectClass) { NSLog(@"Error: No class named %@", className); } else { EOFLOGObjectLevelArgs(@"EOEntity", @"objectClass=%@", objectClass); ASSIGN(_classForInstances, objectClass); } } EOFLOGObjectFnStop(); return _classForInstances; } - (void)_setInternalInfo: (NSDictionary *)dictionary { //OK [self willChange]; ASSIGN(_internalInfo, dictionary); [self _setIsEdited]; } - (id) globalIDForRow: (NSDictionary*)row isFinal: (BOOL)isFinal { EOKeyGlobalID *globalID = nil; NSArray *primaryKeyAttributeNames = nil; int count = 0; NSAssert([row count] > 0, @"Empty Row."); primaryKeyAttributeNames = [self primaryKeyAttributeNames]; count = [primaryKeyAttributeNames count]; { id keyArray[count]; int i; IMP rowOFK=NULL; IMP pkanOAI=NULL; memset(keyArray, 0, sizeof(id) * count); for (i = 0; i < count; i++) { keyArray[i] = GDL2_ObjectForKeyWithImpPtr(row,&rowOFK, GDL2_ObjectAtIndexWithImpPtr(primaryKeyAttributeNames, &pkanOAI,i)); globalID = [EOKeyGlobalID globalIDWithEntityName: [self name] keys: keyArray keyCount: count zone: [self zone]]; } }; //NSEmitTODO(); //TODO //TODO isFinal ?? return globalID; } -(Class)classForObjectWithGlobalID: (EOKeyGlobalID*)globalID { //near OK Class classForInstances = _classForInstances; EOFLOGObjectFnStart(); //TODO:use globalID ?? if (!classForInstances) { classForInstances = [self _classForInstances]; } EOFLOGObjectFnStop(); return _classForInstances; } //DESTROY v later because it may be still in use #define AUTORELEASE_SETNIL(v) { AUTORELEASE(v); v=nil; } - (void)_setIsEdited { if(_flags.updating) return; EOFLOGObjectLevelArgs(@"EOEntity", @"START entity name=%@", [self name]); NSAssert4(!_attributesToFetch || [_attributesToFetch isKindOfClass: [NSArray class]], @"entity %@ attributesToFetch %p is not an NSArray but a %@\n%@", [self name], _attributesToFetch, [_attributesToFetch class], _attributesToFetch); //Destroy cached ivar EOFLOGObjectLevelArgs(@"EOEntity", @"_classPropertyNames: void:%p [%p] %s", (void*)nil, (void*)_classPropertyNames, (_classPropertyNames ? "Not NIL" : "NIL")); AUTORELEASE_SETNIL(_classPropertyNames); EOFLOGObjectLevelArgs(@"EOEntity", @"_primaryKeyAttributeNames: %p %s", (void*)_primaryKeyAttributeNames, (_primaryKeyAttributeNames ? "Not NIL" : "NIL")); AUTORELEASE_SETNIL(_primaryKeyAttributeNames); EOFLOGObjectLevelArgs(@"EOEntity", @"_classPropertyAttributeNames: %p %s", _classPropertyAttributeNames, (_classPropertyAttributeNames ? "Not NIL" : "NIL")); AUTORELEASE_SETNIL(_classPropertyAttributeNames); EOFLOGObjectLevelArgs(@"EOEntity", @"_classPropertyToOneRelationshipNames: %p %s", _classPropertyToOneRelationshipNames, (_classPropertyToOneRelationshipNames ? "Not NIL" : "NIL")); AUTORELEASE_SETNIL(_classPropertyToOneRelationshipNames); EOFLOGObjectLevelArgs(@"EOEntity", @"_classPropertyToManyRelationshipNames: %p %s", _classPropertyToManyRelationshipNames, (_classPropertyToManyRelationshipNames ? "Not NIL" : "NIL")); AUTORELEASE_SETNIL(_classPropertyToManyRelationshipNames); EOFLOGObjectLevelArgs(@"EOEntity", @"_attributesToFetch: %p %s", _attributesToFetch, (_attributesToFetch ? "Not NIL" : "NIL")); AUTORELEASE_SETNIL(_attributesToFetch); EOFLOGObjectLevelArgs(@"EOEntity", @"_dbSnapshotKeys: %p %s", _dbSnapshotKeys, (_dbSnapshotKeys ? "Not NIL" : "NIL")); AUTORELEASE_SETNIL(_dbSnapshotKeys); EOFLOGObjectLevelArgs(@"EOEntity", @"_attributesToSave: %p %s", _attributesToSave, (_attributesToSave ? "Not NIL" : "NIL")); AUTORELEASE_SETNIL(_attributesToSave); EOFLOGObjectLevelArgs(@"EOEntity", @"_propertiesToFault: %p %s", _propertiesToFault, (_propertiesToFault ? "Not NIL" : "NIL")); AUTORELEASE_SETNIL(_propertiesToFault); EOFLOGObjectLevelArgs(@"EOEntity", @"_adaptorDictionaryInitializer: %p %s", _adaptorDictionaryInitializer, (_adaptorDictionaryInitializer ? "Not NIL" : "NIL")); AUTORELEASE_SETNIL(_adaptorDictionaryInitializer); EOFLOGObjectLevelArgs(@"EOEntity", @"_snapshotDictionaryInitializer: %p %s", _snapshotDictionaryInitializer, (_snapshotDictionaryInitializer ? "Not NIL" : "NIL")); AUTORELEASE_SETNIL(_snapshotDictionaryInitializer); EOFLOGObjectLevelArgs(@"EOEntity",@"_primaryKeyDictionaryInitializer: %p %s", _primaryKeyDictionaryInitializer, (_primaryKeyDictionaryInitializer ? "Not NIL" : "NIL")); AUTORELEASE_SETNIL(_primaryKeyDictionaryInitializer); EOFLOGObjectLevelArgs(@"EOEntity",@"_propertyDictionaryInitializer: %p %s", _propertyDictionaryInitializer, (_propertyDictionaryInitializer ? "Not NIL" : "NIL")); AUTORELEASE_SETNIL(_propertyDictionaryInitializer); EOFLOGObjectLevelArgs(@"EOEntity",@"_instanceDictionaryInitializer: %p %s", _instanceDictionaryInitializer, (_instanceDictionaryInitializer ? "Not NIL" : "NIL")); AUTORELEASE_SETNIL(_instanceDictionaryInitializer); EOFLOGObjectLevelArgs(@"EOEntity",@"_relationshipsByName: %p %s", _relationshipsByName, (_relationshipsByName ? "Not NIL" : "NIL")); AUTORELEASE_SETNIL(_relationshipsByName); AUTORELEASE_SETNIL(_attributesByName); //TODO call _flushCache on each attr NSAssert4(!_attributesToFetch || [_attributesToFetch isKindOfClass: [NSArray class]], @"entity %@ attributesToFetch %p is not an NSArray but a %@\n%@", [self name], _attributesToFetch, [_attributesToFetch class], _attributesToFetch); EOFLOGObjectLevelArgs(@"EOEntity", @"STOP%s", ""); } /** Returns attributes by name (only attributes, not relationships) **/ - (NSDictionary*)attributesByName { if (_flags.attributesIsLazy) [self attributes]; if (!_attributesByName) { unsigned int i, c; _attributesByName = [[NSMutableDictionary alloc] init]; for (i = 0, c = [_attributes count]; i < c; i++) { [_attributesByName setObject:[_attributes objectAtIndex:i] forKey:[[_attributes objectAtIndex:i] name]]; } } return _attributesByName; } - (NSDictionary*)relationshipsByName { if (_flags.relationshipsIsLazy) [self relationships]; if (!_relationshipsByName) { unsigned int i, c; _relationshipsByName = [[NSMutableDictionary alloc] init]; for (i = 0, c = [_relationships count]; i < c; i++) { [_relationshipsByName setObject:[_relationships objectAtIndex:i] forKey:[[_relationships objectAtIndex:i] name]]; } } return _relationshipsByName; } - (NSArray*) _allFetchSpecifications { //OK NSDictionary *fetchSpecificationDictionary = [self _fetchSpecificationDictionary]; NSArray *fetchSpecValues = [fetchSpecificationDictionary allValues]; return fetchSpecValues; } - (NSDictionary*) _fetchSpecificationDictionary { //OK return _fetchSpecificationDictionary; } - (void) _loadEntity { //TODO [self notImplemented: _cmd]; } - (id) parentRelationship { //TODO return [self notImplemented: _cmd]; } - (int) _numberOfRelationships { //OK return [[self relationships] count]; } - (BOOL) _hasReadOnlyAttributes { //OK BOOL hasReadOnlyAttributes = NO; NSArray *attributes = [self attributes]; int i, count=[attributes count]; for (i = 0; !hasReadOnlyAttributes && i < count; i++) hasReadOnlyAttributes = [[attributes objectAtIndex: i] isReadOnly]; return hasReadOnlyAttributes; } - (NSArray*) writableDBSnapshotKeys { //OK NSArray *writableDBSnapshotKeys=nil; if (![self isReadOnly]) { NSArray *attributesToFetch = [self _attributesToFetch]; int i, count = [attributesToFetch count]; IMP atfOAI=NULL; IMP sAO=NULL; NSMutableArray* tmpArray = AUTORELEASE([GDL2_alloc(NSMutableArray) initWithCapacity: count]); NSAssert3(!attributesToFetch || [attributesToFetch isKindOfClass: [NSArray class]], @"entity %@ attributesToFetch is not an NSArray but a %@\n%@", [self name], [attributesToFetch class], attributesToFetch); for (i = 0; i < count; i++) { EOAttribute *attribute = GDL2_ObjectAtIndexWithImpPtr(attributesToFetch,&atfOAI,i); if (![attribute isReadOnly]) GDL2_AddObjectWithImpPtr(tmpArray,&sAO,[attribute name]); } writableDBSnapshotKeys=tmpArray; } else writableDBSnapshotKeys=GDL2_NSArray; return writableDBSnapshotKeys; } - (NSArray*) rootAttributesUsedForLocking { //OK ? NSArray *rootAttributesUsedForLocking = nil; NSArray *attributesUsedForLocking = [self attributesUsedForLocking]; int count = [attributesUsedForLocking count]; if (count>0) { int i=0; NSMutableArray *tmpArray = AUTORELEASE([GDL2_alloc(NSMutableArray) initWithCapacity: count]); IMP auflOAI=NULL; IMP tAO=NULL; for (i = 0; i < count; i++) { EOAttribute *attribute = GDL2_ObjectAtIndexWithImpPtr(attributesUsedForLocking, &auflOAI,i); if (![attribute isDerived]) GDL2_AddObjectWithImpPtr(tmpArray,&tAO,attribute); } rootAttributesUsedForLocking=tmpArray; } else rootAttributesUsedForLocking=GDL2_NSArray; return rootAttributesUsedForLocking; } - (BOOL) isSubEntityOf: (id)param0 { //TODO [self notImplemented: _cmd]; return NO; } - (id) initObject: (id)param0 editingContext: (id)param1 globalID: (id)param2 { //TODO return [self notImplemented: _cmd]; } - (id) allocBiggestObjectWithZone: (NSZone*)zone { //TODO return [self notImplemented: _cmd]; } - (Class) _biggestClass { //OK Class biggestClass = Nil; biggestClass = [self classForObjectWithGlobalID: nil]; return biggestClass; } - (NSArray*) relationshipsPlist { //OK NSMutableArray *relsPlist; if (_flags.relationshipsIsLazy) { relsPlist = _relationships; } else { NSArray *relationships; int relCount; relsPlist = [NSMutableArray array]; relationships = [self relationships]; relCount = [relationships count]; if (relCount > 0) { int i; for (i = 0; i < relCount; i++) { NSMutableDictionary *relPlist = [NSMutableDictionary dictionary]; EORelationship *rel = [relationships objectAtIndex: i]; [rel encodeIntoPropertyList: relPlist]; [relsPlist addObject: relPlist]; } } } return relsPlist; } - (id) rootParent { id prevParent = self; id parent = self; while (parent) { prevParent = parent; parent = [prevParent parentEntity]; } return prevParent; } - (void) _setParent: (id)param0 { //TODO [self notImplemented: _cmd]; } - (NSArray*) _hiddenRelationships { //OK if (!_hiddenRelationships) _hiddenRelationships = [NSMutableArray new]; return _hiddenRelationships; } - (NSArray*) _propertyNames { //OK NSMutableArray *propertyNames = nil; NSArray *attributes = [self attributes]; NSArray *attributeNames = [attributes resultsOfPerformingSelector: @selector(name)]; NSArray *relationships = [self relationships]; NSArray *relationshipNames = [relationships resultsOfPerformingSelector: @selector(name)]; propertyNames = [NSMutableArray arrayWithArray: attributeNames]; [propertyNames addObjectsFromArray: relationshipNames]; return propertyNames; } - (id) _flattenAttribute: (id)param0 relationshipPath: (id)param1 currentAttributes: (id)param2 { //TODO return [self notImplemented: _cmd]; } - (NSString*) snapshotKeyForAttributeName: (NSString*)attributeName { NSString *attName = [self _flattenedAttNameToSnapshotKeyMapping]; if (attName) { NSEmitTODO(); //TODO [self notImplemented: _cmd]; } else attName = attributeName; //TODO-VERIFY return attName; } - (id) _flattenedAttNameToSnapshotKeyMapping { // NSArray *attributesToSave = [self _attributesToSave]; //NSEmitTODO(); //TODO return nil; //[self notImplemented:_cmd]; //TODO } - (EOMKKDSubsetMapping*) _snapshotToAdaptorRowSubsetMapping { if (!_snapshotToAdaptorRowSubsetMapping) { EOMKKDInitializer *snapshotDictionaryInitializer = [self _snapshotDictionaryInitializer]; EOMKKDInitializer *adaptorDictionaryInitializer = [self _adaptorDictionaryInitializer]; EOMKKDSubsetMapping *subsetMapping = [snapshotDictionaryInitializer subsetMappingForSourceDictionaryInitializer: adaptorDictionaryInitializer]; ASSIGN(_snapshotToAdaptorRowSubsetMapping,subsetMapping); } return _snapshotToAdaptorRowSubsetMapping; } - (EOMutableKnownKeyDictionary*) _dictionaryForPrimaryKey { //OK EOMKKDInitializer *primaryKeyDictionaryInitializer = [self _primaryKeyDictionaryInitializer]; EOMutableKnownKeyDictionary *dictionaryForPrimaryKey = [EOMutableKnownKeyDictionary dictionaryWithInitializer: primaryKeyDictionaryInitializer]; return dictionaryForPrimaryKey; } - (EOMutableKnownKeyDictionary*) _dictionaryForProperties { //OK EOMKKDInitializer *propertyDictionaryInitializer = nil; EOMutableKnownKeyDictionary *dictionaryForProperties = nil; propertyDictionaryInitializer = [self _propertyDictionaryInitializer]; dictionaryForProperties = [EOMutableKnownKeyDictionary dictionaryWithInitializer: propertyDictionaryInitializer]; return dictionaryForProperties; } /** returns a new autoreleased mutable dictionary to store properties returns nil if there's no key in the instanceDictionaryInitializer **/ - (EOMutableKnownKeyDictionary*) _dictionaryForInstanceProperties { //OK EOMKKDInitializer *instanceDictionaryInitializer = nil; EOMutableKnownKeyDictionary *dictionaryForProperties = nil; instanceDictionaryInitializer = [self _instanceDictionaryInitializer]; // No need to build the dictionary if there's no key. // The only drawback I see is if someone use extraData feature of MKK dictionary if ([instanceDictionaryInitializer count]>0) { dictionaryForProperties = [EOMutableKnownKeyDictionary dictionaryWithInitializer: instanceDictionaryInitializer]; } return dictionaryForProperties; } - (NSArray*) _relationshipsToFaultForRow: (NSDictionary*)row { NSMutableArray *rels = [NSMutableArray array]; NSArray *classProperties = [self classProperties]; int i, count = [classProperties count]; for (i = 0; i < count; i++) { EORelationship *classProperty = [classProperties objectAtIndex: i]; if ([classProperty isKindOfClass: [EORelationship class]]) { EORelationship *relsubs = [classProperty _substitutionRelationshipForRow: row]; [rels addObject: relsubs]; } } return rels; } - (NSArray*) _classPropertyAttributes { //OK //IMPROVE We can improve this by caching the result.... NSArray *classPropertyAttributes = nil; //Get classProperties (EOAttributes + EORelationships) NSArray *classProperties = [self classProperties]; int count = [classProperties count]; if (count>0) { int i=0; NSMutableArray *tmpArray = AUTORELEASE([GDL2_alloc(NSMutableArray) initWithCapacity: count]); IMP cpOAI=NULL; IMP tAO=NULL; for (i = 0; i < count; i++) { id object = GDL2_ObjectAtIndexWithImpPtr(classProperties,&cpOAI,i); if ([object isKindOfClass: GDL2_EOAttributeClass]) GDL2_AddObjectWithImpPtr(tmpArray,&tAO,object); } classPropertyAttributes = tmpArray; } else classPropertyAttributes=GDL2_NSArray; return classPropertyAttributes; } - (NSArray*) _attributesToSave { //Near OK EOFLOGObjectLevelArgs(@"EOEntity", @"START Entity _attributesToSave entityname=%@", [self name]); if (!_attributesToSave) { NSArray *attributesToFetch = [self _attributesToFetch]; int i, count = [attributesToFetch count]; NSMutableArray *attributesToSave = [NSMutableArray arrayWithCapacity:count]; NSAssert3(!attributesToFetch || [attributesToFetch isKindOfClass: [NSArray class]], @"entity %@ attributesToFetch is not an NSArray but a %@\n%@", [self name], [_attributesToFetch class], _attributesToFetch); for (i = 0; i < count; i++) { EOAttribute *attribute = [attributesToFetch objectAtIndex: i]; BOOL isFlattened = [attribute isFlattened]; if (!isFlattened) [attributesToSave addObject: attribute]; } ASSIGN(_attributesToSave, attributesToSave); } EOFLOGObjectLevelArgs(@"EOEntity", @"STOP Entity _attributesToSave entityname=%@ attrs:%@", [self name], _attributesToSave); return _attributesToSave; } //sorted by name attributes - (NSArray*) _attributesToFetch { //Seems OK EOFLOGObjectLevelArgs(@"EOEntity", @"START Entity _attributesToFetch entityname=%@", [self name]); EOFLOGObjectLevelArgs(@"EOEntity", @"AttributesToFetch:%p", _attributesToFetch); EOFLOGObjectLevelArgs(@"EOEntity", @"AttributesToFetch:%@", _attributesToFetch); NSAssert2(!_attributesToFetch || [_attributesToFetch isKindOfClass: [NSArray class]], @"entity %@ attributesToFetch is not an NSArray but a %@", [self name], [_attributesToFetch class]); if (!_attributesToFetch) { NSMutableDictionary *attributesDict = [NSMutableDictionary dictionary]; NS_DURING { int iArray = 0; NSArray *arrays[] = { [self attributesUsedForLocking], [self primaryKeyAttributes], [self classProperties], [self relationships] }; _attributesToFetch = RETAIN([NSMutableArray array]); EOFLOGObjectLevelArgs(@"EOEntity", @"Entity %@ - _attributesToFetch %p [RC=%d]:%@", [self name], _attributesToFetch, [_attributesToFetch retainCount], _attributesToFetch); for (iArray = 0; iArray < 4; iArray++) { int i, count = 0; EOFLOGObjectLevelArgs(@"EOEntity", @"Entity %@ - arrays[iArray]:%@", [self name], arrays[iArray]); count = [arrays[iArray] count]; for (i = 0; i < count; i++) { id property = [arrays[iArray] objectAtIndex: i]; NSString *propertyName = [(EOAttribute*)property name]; //VERIFY EOFLOGObjectLevelArgs(@"EOEntity", @"propertyName=%@ - property=%@", propertyName, property); if ([property isKindOfClass: GDL2_EOAttributeClass]) { EOAttribute *attribute = property; if ([attribute isFlattened]) { attribute = [[attribute _definitionArray] objectAtIndex: 0]; propertyName = [attribute name]; } } if ([property isKindOfClass: [EORelationship class]]) { [self _addAttributesToFetchForRelationshipPath: [(EORelationship*)property relationshipPath] atts: attributesDict]; } else if ([property isKindOfClass: GDL2_EOAttributeClass]) { [attributesDict setObject: property forKey: propertyName]; } else { NSEmitTODO(); //TODO } } } } NS_HANDLER { NSDebugMLog(@"Exception: %@",localException); [localException raise]; } NS_ENDHANDLER; NS_DURING { NSDebugMLog(@"Attributes to fetch classes %@", [_attributesToFetch resultsOfPerformingSelector: @selector(class)]); [_attributesToFetch addObjectsFromArray: [attributesDict allValues]]; NSDebugMLog(@"Attributes to fetch classes %@", [_attributesToFetch resultsOfPerformingSelector: @selector(class)]); [_attributesToFetch sortUsingSelector: @selector(eoCompareOnName:)]; //Very important to have always the same order. } NS_HANDLER { NSDebugMLog(@"Exception: %@",localException); [localException raise]; } NS_ENDHANDLER; } NSAssert3(!_attributesToFetch || [_attributesToFetch isKindOfClass: [NSArray class]], @"Entity %@: _attributesToFetch is not an NSArray but a %@\n%@", [self name], [_attributesToFetch class], _attributesToFetch); EOFLOGObjectLevelArgs(@"EOEntity", @"Stop Entity %@ - _attributesToFetch %p [RC=%d]:%@", [self name], _attributesToFetch, [_attributesToFetch retainCount], _attributesToFetch); return _attributesToFetch; } - (EOMKKDInitializer*) _adaptorDictionaryInitializer { //OK EOFLOGObjectLevelArgs(@"EOEntity", @"Start _adaptorDictionaryInitializer=%@", _adaptorDictionaryInitializer); if (!_adaptorDictionaryInitializer) { NSArray *attributesToFetch = [self _attributesToFetch]; NSArray *attributeToFetchNames = [attributesToFetch resultsOfPerformingSelector: @selector(name)]; EOFLOGObjectLevelArgs(@"EOEntity", @"attributeToFetchNames=%@", attributeToFetchNames); NSAssert3(!attributesToFetch || [attributesToFetch isKindOfClass: [NSArray class]], @"entity %@ attributesToFetch is not an NSArray but a %@\n%@", [self name], [attributesToFetch class], attributesToFetch); NSAssert1([attributesToFetch count] > 0, @"No Attributes to fetch in entity %@", [self name]); NSAssert1([attributeToFetchNames count] > 0, @"No Attribute names to fetch in entity %@", [self name]); EOFLOGObjectLevelArgs(@"EOEntity", @"entity named %@: attributeToFetchNames=%@", [self name], attributeToFetchNames); ASSIGN(_adaptorDictionaryInitializer, [EOMutableKnownKeyDictionary initializerFromKeyArray: attributeToFetchNames]); EOFLOGObjectLevelArgs(@"EOEntity", @"entity named %@ _adaptorDictionaryInitializer=%@", [self name], _adaptorDictionaryInitializer); } EOFLOGObjectLevelArgs(@"EOEntity", @"Stop _adaptorDictionaryInitializer=%p", _adaptorDictionaryInitializer); EOFLOGObjectLevelArgs(@"EOEntity", @"Stop _adaptorDictionaryInitializer=%@", _adaptorDictionaryInitializer); return _adaptorDictionaryInitializer; } - (EOMKKDInitializer*) _snapshotDictionaryInitializer { if (!_snapshotDictionaryInitializer) { NSArray *dbSnapshotKeys = [self dbSnapshotKeys]; ASSIGN(_snapshotDictionaryInitializer, [EOMutableKnownKeyDictionary initializerFromKeyArray: dbSnapshotKeys]); } return _snapshotDictionaryInitializer; } - (EOMKKDInitializer*) _primaryKeyDictionaryInitializer { //OK if (!_primaryKeyDictionaryInitializer) { NSArray *primaryKeyAttributeNames = [self primaryKeyAttributeNames]; NSAssert1([primaryKeyAttributeNames count] > 0, @"No primaryKeyAttributeNames in entity %@", [self name]); EOFLOGObjectLevelArgs(@"EOEntity", @"entity named %@: primaryKeyAttributeNames=%@", [self name], primaryKeyAttributeNames); _primaryKeyDictionaryInitializer = [EOMKKDInitializer newWithKeyArray: primaryKeyAttributeNames]; EOFLOGObjectLevelArgs(@"EOEntity", @"entity named %@: _primaryKeyDictionaryInitializer=%@", [self name], _primaryKeyDictionaryInitializer); } return _primaryKeyDictionaryInitializer; } - (EOMKKDInitializer*) _propertyDictionaryInitializer { //OK // If not already built, built it if (!_propertyDictionaryInitializer) { // Get class properties (EOAttributes + EORelationships) NSArray *classProperties = [self classProperties]; NSArray *classPropertyNames = [classProperties resultsOfPerformingSelector: @selector(name)]; EOFLOGObjectLevelArgs(@"EOEntity", @"entity %@ classPropertyNames=%@", [self name], classPropertyNames); NSAssert1([classProperties count] > 0, @"No classProperties in entity %@", [self name]); NSAssert1([classPropertyNames count] > 0, @"No classPropertyNames in entity %@", [self name]); //Build the multiple known key initializer _propertyDictionaryInitializer = [EOMKKDInitializer newWithKeyArray: classPropertyNames]; } return _propertyDictionaryInitializer; } - (EOMKKDInitializer*) _instanceDictionaryInitializer { //OK // If not already built, built it if (!_instanceDictionaryInitializer) { // Get class properties (EOAttributes + EORelationships) NSArray *classProperties = [self classProperties]; NSArray* excludedPropertyNames=nil; NSArray *classPropertyNames = nil; Class classForInstances = [self _classForInstances]; classPropertyNames = [classProperties resultsOfPerformingSelector: @selector(name)]; EOFLOGObjectLevelArgs(@"EOEntity", @"entity %@ classPropertyNames=%@", [self name], classPropertyNames); excludedPropertyNames = [classForInstances _instanceDictionaryInitializerExcludedPropertyNames]; EOFLOGObjectLevelArgs(@"EOEntity", @"entity %@ excludedPropertyNames=%@", [self name], excludedPropertyNames); if ([excludedPropertyNames count]>0) { NSMutableArray* mutableClassPropertyNames=[classPropertyNames mutableCopy]; [mutableClassPropertyNames removeObjectsInArray:excludedPropertyNames]; classPropertyNames=AUTORELEASE(mutableClassPropertyNames); } EOFLOGObjectLevelArgs(@"EOEntity", @"entity %@ classPropertyNames=%@", [self name], classPropertyNames); NSAssert1([classProperties count] > 0, @"No classProperties in entity %@", [self name]); NSAssert1([classPropertyNames count] > 0, @"No classPropertyNames in entity %@", [self name]); //Build the multiple known key initializer _instanceDictionaryInitializer = [EOMKKDInitializer newWithKeyArray: classPropertyNames]; EOFLOGObjectLevelArgs(@"EOEntity", @"_instanceDictionaryInitializer=%@", _instanceDictionaryInitializer); } return _instanceDictionaryInitializer; } @end @implementation EOEntity (EOEntityRelationshipPrivate) - (EORelationship*) _inverseRelationshipPathForPath: (NSString*)path { //TODO return [self notImplemented: _cmd]; } - (NSDictionary*) _keyMapForIdenticalKeyRelationshipPath: (NSString*)path { NSDictionary *keyMap = nil; EORelationship *rel; NSMutableArray *sourceAttributeNames = [NSMutableArray array]; NSMutableArray *destinationAttributeNames = [NSMutableArray array]; NSArray *joins; int count = 0; //use path,not only one element ? rel = [self relationshipNamed: path]; joins = [rel joins]; count = [joins count]; if (count>0) { int i=0; IMP joinsOAI=NULL; IMP sanAO=NULL; IMP danAO=NULL; for (i = 0; i < count; i++) { EOJoin *join = GDL2_ObjectAtIndexWithImpPtr(joins,&joinsOAI,i); EOAttribute *sourceAttribute = [join sourceAttribute]; EOAttribute *destinationAttribute = [self _mapAttribute:sourceAttribute toDestinationAttributeInLastComponentOfRelationshipPath: path]; GDL2_AddObjectWithImpPtr(sourceAttributeNames,&sanAO, [sourceAttribute name]); GDL2_AddObjectWithImpPtr(destinationAttributeNames,&danAO, [destinationAttribute name]); } }; keyMap = [NSDictionary dictionaryWithObjectsAndKeys: sourceAttributeNames, @"sourceKeys", destinationAttributeNames, @"destinationKeys", nil, nil]; //return something like {destinationKeys = (code); sourceKeys = (languageCode); } return keyMap; } - (EOAttribute *)_mapAttribute: (EOAttribute *)attribute toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path { NSArray *components = nil; EORelationship *rel = nil; NSArray *sourceAttributes = nil; NSArray *destinationAttributes = nil; EOEntity *destinationEntity = nil; NSAssert(attribute, @"No attribute"); NSAssert(path, @"No path"); NSAssert([path length] > 0, @"Empty path"); components = [path componentsSeparatedByString: @"."]; NSAssert([components count] > 0, @"Empty components array"); rel = [self relationshipNamed: [components lastObject]]; sourceAttributes = [rel sourceAttributes]; destinationAttributes = [rel destinationAttributes]; destinationEntity = [rel destinationEntity]; NSEmitTODO(); //TODO return [self notImplemented: _cmd]; } - (BOOL) _relationshipPathIsToMany: (NSString*)relPath { //Seems OK BOOL isToMany = NO; NSArray *parts = [relPath componentsSeparatedByString: @"."]; EOEntity *entity = self; int i, count = [parts count]; for (i = 0 ; !isToMany && i < count; i++) //VERIFY Stop when finding the 1st isToMany ? { EORelationship *rel = [entity relationshipNamed: [parts objectAtIndex: i]]; isToMany = [rel isToMany]; if (!isToMany) entity = [rel destinationEntity]; } return isToMany; } - (BOOL) _relationshipPathHasIdenticalKeys: (id)param0 { [self notImplemented: _cmd]; return NO; } - (NSDictionary *)_keyMapForRelationshipPath: (NSString *)path { //Ayers: Review //NearOK NSMutableArray *sourceKeys = [NSMutableArray array]; NSMutableArray *destinationKeys = [NSMutableArray array]; //NSArray *attributesToFetch = [self _attributesToFetch]; //Use It !! EORelationship *relationship = [self anyRelationshipNamed: path]; //?? iterate on path ? //TODO NSEmitTODO(); //TODO if (relationship) { NSArray *joins = [relationship joins]; int count = [joins count]; if (count>0) { int i=0; IMP joinsOAI=NULL; IMP skAO=NULL; IMP dkAO=NULL; for(i = 0; i < count; i++) { EOJoin *join = GDL2_ObjectAtIndexWithImpPtr(joins,&joinsOAI,i); EOAttribute *sourceAttribute = [join sourceAttribute]; EOAttribute *destinationAttribute = [join destinationAttribute]; GDL2_AddObjectWithImpPtr(sourceKeys,&skAO,[sourceAttribute name]); GDL2_AddObjectWithImpPtr(destinationKeys,&dkAO,[destinationAttribute name]); } }; } return [NSDictionary dictionaryWithObjectsAndKeys: sourceKeys, @"sourceKeys", destinationKeys, @"destinationKeys", nil]; //{destinationKeys = (code); sourceKeys = (countryCode); } } @end @implementation EOEntity (EOEntitySQLExpression) - (NSString*) valueForSQLExpression: (EOSQLExpression*)sqlExpression { return [self notImplemented: _cmd]; //TODO } + (NSString*) valueForSQLExpression: (EOSQLExpression*)sqlExpression { return [self notImplemented: _cmd]; //TODO } @end @implementation EOEntity (MethodSet11) - (NSException *)validateObjectForDelete: (id)object { //OK ?? NSArray *relationships = nil; NSEnumerator *relEnum = nil; EORelationship *relationship = nil; NSMutableArray *expArray = nil; relationships = [self relationships]; relEnum = [relationships objectEnumerator]; while ((relationship = [relEnum nextObject])) { //classproperties //rien pour nullify if ([relationship deleteRule] == EODeleteRuleDeny) { if (!expArray) expArray = [NSMutableArray arrayWithCapacity:5]; [expArray addObject: [NSException validationExceptionWithFormat: @"delete operation for relationship key %@ refused", [relationship name]]]; } } if (expArray) return [NSException aggregateExceptionWithExceptions:expArray]; else return nil; } /** Retain an array of name of all EOAttributes **/ - (NSArray*) classPropertyAttributeNames { //Should be OK if (!_classPropertyAttributeNames) { int i=0; NSArray *classProperties = [self classProperties]; int count = [classProperties count]; _classPropertyAttributeNames = [NSMutableArray new]; for (i = 0; i < count; i++) { EOAttribute *property = [classProperties objectAtIndex: i]; if ([property isKindOfClass: GDL2_EOAttributeClass]) [(NSMutableArray*)_classPropertyAttributeNames addObject: [property name]]; }; EOFLOGObjectLevelArgs(@"EOEntity", @"_classPropertyAttributeNames=%@", _classPropertyAttributeNames); } return _classPropertyAttributeNames; } - (NSArray*) classPropertyToManyRelationshipNames { //Should be OK if (!_classPropertyToManyRelationshipNames) { NSArray *classProperties = [self classProperties]; int i, count = [classProperties count]; Class relClass = [EORelationship class]; _classPropertyToManyRelationshipNames = [NSMutableArray new]; for (i = 0; i < count; i++) { EORelationship *property = [classProperties objectAtIndex: i]; if ([property isKindOfClass: relClass] && [property isToMany]) [(NSMutableArray*)_classPropertyToManyRelationshipNames addObject: [property name]]; } } return _classPropertyToManyRelationshipNames; } - (NSArray*) classPropertyToOneRelationshipNames { //Should be OK if (!_classPropertyToOneRelationshipNames) { NSArray *classProperties = [self classProperties]; int i, count = [classProperties count]; Class relClass = [EORelationship class]; _classPropertyToOneRelationshipNames = [NSMutableArray new]; //or GC ? for (i = 0; i 0, @"Empty relationship path"); //Verify when multi part path and not _relationshipPathIsToMany:path parts = [relPath componentsSeparatedByString: @"."]; rel = [self relationshipNamed: [parts objectAtIndex: 0]]; if (!rel) { NSEmitTODO(); //TODO //TODO } else { NSArray *joins = [rel joins]; int count = [joins count]; if (count>0) { int i=0; IMP joinsOAI=NULL; IMP attributesSOFK=NULL; for (i = 0; i < count; i++) { EOJoin *join = GDL2_ObjectAtIndexWithImpPtr(joins,&joinsOAI,i); EOAttribute *attribute = [join sourceAttribute]; GDL2_SetObjectForKeyWithImpPtr(attributes,&attributesSOFK, attribute,[attribute name]); } }; } } - (NSArray*) dbSnapshotKeys { //OK EOFLOGObjectFnStart(); if (!_dbSnapshotKeys) { NSArray *attributesToFetch = [self _attributesToFetch]; EOFLOGObjectLevelArgs(@"EOEntity", @"attributesToFetch=%@", attributesToFetch); NSAssert3(!attributesToFetch || [attributesToFetch isKindOfClass: [NSArray class]], @"entity %@ attributesToFetch is not an NSArray but a %@\n%@", [self name], [attributesToFetch class], attributesToFetch); ASSIGN(_dbSnapshotKeys, [NSArray arrayWithArray: [attributesToFetch resultsOfPerformingSelector: @selector(name)]]); } EOFLOGObjectFnStop(); return _dbSnapshotKeys; } - (NSArray*) flattenedAttributes { //OK NSArray *flattenedAttributes = nil; NSArray *attributesToFetch = [self _attributesToFetch]; int count = [attributesToFetch count]; NSAssert3(!attributesToFetch || [attributesToFetch isKindOfClass: [NSArray class]], @"entity %@ attributesToFetch is not an NSArray but a %@\n%@", [self name], [attributesToFetch class], attributesToFetch); if (count>0) { int i=0; IMP atfOAI=NULL; IMP tAO=NULL; NSMutableArray* tmpArray = AUTORELEASE([GDL2_alloc(NSMutableArray) initWithCapacity: count]); for (i = 0; i < count; i++) { EOAttribute *attribute = GDL2_ObjectAtIndexWithImpPtr(attributesToFetch,&atfOAI,i); if ([attribute isFlattened]) GDL2_AddObjectWithImpPtr(tmpArray,&tAO,attribute); }; flattenedAttributes=tmpArray; } else flattenedAttributes=GDL2_NSArray; return flattenedAttributes; } @end @implementation EOEntity (EOEntityPrivateXX) - (EOExpressionArray*) _parseDescription: (NSString*)description isFormat: (BOOL)isFormat arguments: (char*)param2 { // definition = "(((text(code) || ' ') || upper(abbreviation)) || ' ')"; EOExpressionArray *expressionArray = nil; const char *s = NULL; const char *start = NULL; id objectToken = nil; id pool = nil; EOFLOGObjectFnStart(); EOFLOGObjectLevelArgs(@"EOEntity", @"expression=%@", description); expressionArray = AUTORELEASE([EOExpressionArray new]); s = [description cString]; if (s) { IMP eaAO=NULL; pool = [NSAutoreleasePool new]; NS_DURING { /* Divide the expression string in alternating substrings that obey the following simple grammar: I = [a-zA-Z0-9@_#]([a-zA-Z0-9@_.#$])+ O = \'.*\' | \".*\" | [^a-zA-Z0-9@_#]+ S -> I S | O S | nothing */ while (s && *s) { /* Determines an I token. */ if (isalnum(*s) || *s == '@' || *s == '_' || *s == '#') { EOExpressionArray *expr = nil; start = s; for (++s; *s; s++) if (!isalnum(*s) && *s != '@' && *s != '_' && *s != '.' && *s != '#' && *s != '$') break; objectToken = GDL2_StringWithCStringAndLength(start, (unsigned)(s - start)); EOFLOGObjectLevelArgs(@"EOEntity", @"objectToken: '%@'", objectToken); expr = [self _parsePropertyName: objectToken]; EOFLOGObjectLevelArgs(@"EOEntity", @"expr: '%@'", expr); if (expr) objectToken = expr; EOFLOGObjectLevelArgs(@"EOEntity", @"addObject I Token: '%@'", objectToken); GDL2_AddObjectWithImpPtr(expressionArray,&eaAO,objectToken); } /* Determines an O token. */ start = s; for (; *s && !isalnum(*s) && *s != '@' && *s != '_' && *s != '#'; s++) { if (*s == '\'' || *s == '"') { char quote = *s; for (++s; *s; s++) if (*s == quote) break; else if (*s == '\\') s++; /* Skip the escaped characters */ if (!*s) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: unterminated character string", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self]; } } if (s != start) { objectToken = GDL2_StringWithCStringAndLength(start, (unsigned)(s - start)); EOFLOGObjectLevelArgs(@"EOEntity", @"addObject O Token: '%@'", objectToken); GDL2_AddObjectWithImpPtr(expressionArray,&eaAO,objectToken); } } } NS_HANDLER { RETAIN(localException); NSLog(@"exception in EOEntity _parseDescription:isFormat:arguments:"); NSLog(@"exception=%@", localException); [pool release];//Release the pool ! AUTORELEASE(localException); [localException raise]; } NS_ENDHANDLER; [pool release]; } // return nil if expressionArray is empty if ([expressionArray count] == 0) expressionArray = nil; // if expressionArray contains only one element and this element is a expressionArray, use it (otherwise, isFlatten will not be accurate) else if ([expressionArray count] == 1) { id expr = [expressionArray lastObject]; if ([expr isKindOfClass: [EOExpressionArray class]]) expressionArray = expr; } EOFLOGObjectLevelArgs(@"EOEntity", @"expressionArray=%@\nexpressionArray count=%d isFlattened=%s\n", expressionArray, [expressionArray count], ([expressionArray isFlattened] ? "YES" : "NO")); return expressionArray; } - (EOExpressionArray*) _parseRelationshipPath: (NSString*)path { EOEntity *entity = self; EOExpressionArray *expressionArray = nil; NSArray *components = nil; int i, count = 0; EOFLOGObjectFnStart(); EOFLOGObjectLevelArgs(@"EOEntity",@"self=%p (name=%@) path=%@", self,[self name],path); NSAssert1([path length] > 0, @"Path is empty (%p)", path); expressionArray = [EOExpressionArray expressionArrayWithPrefix: nil infix: @"." suffix: nil]; EOFLOGObjectLevelArgs(@"EOEntity", @"self=%p expressionArray=%@", self, expressionArray); components = [path componentsSeparatedByString: @"."]; count = [components count]; for (i = 0; i < count; i++) { NSString *part = [components objectAtIndex: i]; EORelationship *relationship; NSAssert1([part length] > 0, @"part is empty (path=%@)", path); relationship = [entity anyRelationshipNamed: part]; EOFLOGObjectLevelArgs(@"EOEntity", @"part=%@ relationship=%@", part, relationship); if (relationship) { NSAssert2([relationship isKindOfClass: [EORelationship class]], @"relationship is not a EORelationship but a %@. relationship:\n%@", [relationship class], relationship); if ([relationship isFlattened]) { EOExpressionArray *definitionArray=[relationship _definitionArray]; NSDebugMLog(@"entityName=%@ path=%@",[self name],path); NSDebugMLog(@"relationship=%@",relationship); NSDebugMLog(@"relationship definitionArray=%@",definitionArray); // For flattened relationships, we add relationship definition array [expressionArray addObjectsFromArray:definitionArray]; // Use last relationship to find destinationEntity,... relationship=[expressionArray lastObject]; } else { [expressionArray addObject: relationship]; } entity = [relationship destinationEntity]; } else { NSDebugMLog(@"self %p name=%@: relationship \"%@\" used in \"%@\" doesn't exist in entity \"%@\"", self, [self name], part, path, [entity name]); //EOF don't throw exception. But we do ! [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: entity name=%@: relationship \"%@\" used in \"%@\" doesn't exist in entity \"%@\"", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, [self name], part, path, [entity name]]; } } EOFLOGObjectLevelArgs(@"EOEntity", @"self=%p expressionArray=%@", self, expressionArray); // return nil if expressionArray is empty if ([expressionArray count] == 0) expressionArray = nil; // if expressionArray contains only one element and this element is a expressionArray, use it (otherwise, isFlatten will not be accurate) else if ([expressionArray count] == 1) { id expr = [expressionArray lastObject]; if ([expr isKindOfClass: [EOExpressionArray class]]) expressionArray = expr; } EOFLOGObjectLevelArgs(@"EOEntity", @"self=%p expressionArray=%@", self, expressionArray); EOFLOGObjectFnStop(); return expressionArray; } - (id) _parsePropertyName: (NSString*)propertyName { EOEntity *entity = self; EOExpressionArray *expressionArray = nil; NSArray *components = nil; int i, count = 0; EOFLOGObjectFnStart(); EOFLOGObjectLevelArgs(@"EOEntity", @"self=%p self name=%@ propertyName=%@", self, [self name], propertyName); expressionArray = [EOExpressionArray expressionArrayWithPrefix: nil infix: @"." suffix: nil]; EOFLOGObjectLevelArgs(@"EOEntity", @"self=%p expressionArray=%@", self, expressionArray); components = [propertyName componentsSeparatedByString: @"."]; count = [components count]; for (i = 0; i < count; i++) { NSString *part = [components objectAtIndex: i]; EORelationship *relationship = [entity anyRelationshipNamed: part]; EOFLOGObjectLevelArgs(@"EOEntity", @"self=%p entity name=%@ part=%@ relationship=%@ relationship name=%@", self, [entity name], part, relationship, [relationship name]); if (relationship) { NSAssert2([relationship isKindOfClass: [EORelationship class]], @"relationship is not a EORelationship but a %@. relationship:\n%@", [relationship class], relationship); if ([relationship isFlattened]) { NSEmitTODO(); //TODO [self notImplemented: _cmd];//TODO } else { EOFLOGObjectLevelArgs(@"EOEntity",@"self=%p expressionArray addObject=%@ (name=%@)", self, relationship, [relationship name]); [expressionArray addObject: relationship]; } entity = [relationship destinationEntity]; } else { EOAttribute *attribute = [entity anyAttributeNamed: part]; EOFLOGObjectLevelArgs(@"EOEntity", @"self=%p entity name=%@ part=%@ attribute=%@ attribute name=%@", self, [entity name], part, attribute, [attribute name]); if (attribute) [expressionArray addObject: attribute]; else if (i < (count - 1)) { //EOF don't throw exception ? But we do ! [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: attribute \"%@\" used in \"%@\" doesn't exist in entity %@", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, propertyName, part, entity]; } } } EOFLOGObjectLevelArgs(@"EOEntity", @"self=%p expressionArray=%@", self, expressionArray); // return nil if expression is empty if ([expressionArray count] == 0) expressionArray = nil; else if ([expressionArray count] == 1) expressionArray = [expressionArray objectAtIndex: 0]; EOFLOGObjectLevelArgs(@"EOEntity", @"self=%p expressionArray=\"%@\"", self, expressionArray); EOFLOGObjectFnStop(); return expressionArray; } @end @implementation EOEntity (Deprecated) + (EOEntity *)entity { return AUTORELEASE([[self alloc] init]); } + (EOEntity *)entityWithPropertyList: (NSDictionary *)propertyList owner: (id)owner { return AUTORELEASE([[self alloc] initWithPropertyList: propertyList owner: owner]); } @end @implementation EOEntityClassDescription - (id)initWithEntity: (EOEntity *)entity { if ((self = [super init])) { ASSIGN(_entity, entity); } return self; } - (void) dealloc { //OK EOFLOGObjectLevelArgs(@"EOEntity", @"Deallocate EOEntityClassDescription %p", self); fflush(stdout); fflush(stderr); DESTROY(_entity); [super dealloc]; } - (NSString *) description { return [NSString stringWithFormat: @"<%s %p - Entity: %@>", object_get_class_name(self), self, [self entityName]]; } - (EOEntity *)entity { return _entity; } - (EOFetchSpecification *)fetchSpecificationNamed: (NSString *)name { NSEmitTODO(); //TODO [self notImplemented: _cmd]; return nil; } - (NSString *)entityName { return [_entity name]; } - (NSArray *)attributeKeys { //OK return [_entity classPropertyAttributeNames]; } - (void)awakeObject: (id)object fromFetchInEditingContext: (EOEditingContext *)context { //OK EOFLOGObjectFnStart(); [super awakeObject: object fromFetchInEditingContext: context]; //nothing to do EOFLOGObjectFnStop(); } /** * Overrides [EOClassDescription-awakeObject:fromInsertionInEditingContext:] * to initialize the class property relationships. The toMany relationships * properties are initialized with a mutable array, while toOne relationships * which propagate the primary key of the object get instantiated with a * freshly initialzed instance. Whether a relationship is manditory or not * is irrelevant at this point. */ - (void)awakeObject: (id)object fromInsertionInEditingContext: (EOEditingContext *)context { NSArray *relationships; NSArray *classProperties; EORelationship *relationship; int i, count; IMP relOAI=NULL; IMP objectSVFK=NULL; IMP objectTSVFK=NULL; IMP objectVFK=NULL; EOFLOGObjectFnStart(); [super awakeObject: object fromInsertionInEditingContext: context]; relationships = [_entity relationships]; classProperties = [_entity classProperties]; count = [relationships count]; for (i = 0; i < count; i++) { relationship = GDL2_ObjectAtIndexWithImpPtr(relationships,&relOAI,i); if ([classProperties containsObject: relationship]) { if ([relationship isToMany]) { NSString *name = [relationship name]; id relationshipValue = GDL2_StoredValueForKeyWithImpPtr(object,&objectSVFK,name); /* We put a value only if there's not already one */ if (relationshipValue == nil) { /* [Ref: Assigns empty arrays to to-many relationship properties of newly inserted enterprise objects] */ GDL2_TakeStoredValueForKeyWithImpPtr(object,&objectTSVFK, [EOCheapCopyMutableArray array], name); } } else { if ([relationship propagatesPrimaryKey]) { NSString *name = [relationship name]; id relationshipValue = GDL2_ValueForKeyWithImpPtr(object,&objectVFK,name); if (relationshipValue == nil) { EOEntity *destinationEntity = [relationship destinationEntity]; EOClassDescription *classDescription = [destinationEntity classDescriptionForInstances]; relationshipValue = [classDescription createInstanceWithEditingContext: context globalID: nil zone: NULL]; [object addObject: relationshipValue toBothSidesOfRelationshipWithKey: name]; [context insertObject: relationshipValue]; } } } } } EOFLOGObjectFnStop(); } - (EOClassDescription *)classDescriptionForDestinationKey: (NSString *)detailKey { EOClassDescription *cd = nil; EOEntity *destEntity = nil; EORelationship *rel = nil; EOFLOGObjectFnStart(); EOFLOGObjectLevelArgs(@"EOEntity", @"detailKey=%@", detailKey); EOFLOGObjectLevelArgs(@"EOEntity", @"_entity name=%@", [_entity name]); rel = [_entity relationshipNamed: detailKey]; EOFLOGObjectLevelArgs(@"EOEntity", @"rel=%@", rel); destEntity = [rel destinationEntity]; EOFLOGObjectLevelArgs(@"EOEntity", @"destEntity name=%@", [destEntity name]); cd = [destEntity classDescriptionForInstances]; EOFLOGObjectLevelArgs(@"EOEntity", @"cd=%@", cd); EOFLOGObjectFnStop(); return cd; } - (id)createInstanceWithEditingContext: (EOEditingContext *)editingContext globalID: (EOGlobalID *)globalID zone: (NSZone *)zone { id obj = nil; Class objectClass; EOFLOGObjectFnStart(); NSAssert1(_entity, @"No _entity in %@", self); objectClass = [_entity classForObjectWithGlobalID: (EOKeyGlobalID*)globalID]; EOFLOGObjectLevelArgs(@"EOEntity", @"objectClass=%p", objectClass); NSAssert2(objectClass, @"No objectClass for globalID=%@. EntityName=%@", globalID, [_entity name]); if (objectClass) { EOFLOGObjectLevelArgs(@"EOEntity", @"objectClass=%@", objectClass); obj = AUTORELEASE([[objectClass allocWithZone:zone] initWithEditingContext: editingContext classDescription: self globalID: globalID]); } EOFLOGObjectFnStop(); return obj; } - (NSFormatter *)defaultFormatterForKey: (NSString *)key { [self notImplemented: _cmd]; return nil; } - (NSFormatter *)defaultFormatterForKeyPath: (NSString *)keyPath { [self notImplemented: _cmd]; return nil; //TODO } - (EODeleteRule)deleteRuleForRelationshipKey: (NSString *)relationshipKey { EORelationship *rel = nil; EODeleteRule deleteRule = 0; EOFLOGObjectFnStart(); rel = [_entity relationshipNamed: relationshipKey]; EOFLOGObjectLevelArgs(@"EOEntity", @"relationship %p=%@", rel, rel); deleteRule = [rel deleteRule]; EOFLOGObjectLevelArgs(@"EOEntity", @"deleteRule=%d", (int)deleteRule); EOFLOGObjectFnStop(); return deleteRule; } - (NSString *)inverseForRelationshipKey: (NSString *)relationshipKey { //Ayers: Review //Near OK NSString *inverseName = nil; EORelationship *relationship = [_entity relationshipNamed: relationshipKey]; //EOEntity *parentEntity = [_entity parentEntity]; //TODO what if parentEntity EORelationship *inverseRelationship = [relationship inverseRelationship]; if (inverseRelationship) { EOEntity *inverseEntity = [inverseRelationship entity]; NSArray *classPropertieNames = [inverseEntity classPropertyNames]; inverseName = [inverseRelationship name]; if (![classPropertieNames containsObject: inverseName]) inverseName = nil; } return inverseName; } - (BOOL)ownsDestinationObjectsForRelationshipKey: (NSString*)relationshipKey { //OK return [[_entity relationshipNamed: relationshipKey] ownsDestination]; } - (NSArray *)toManyRelationshipKeys { //OK return [_entity classPropertyToManyRelationshipNames]; } - (NSArray *)toOneRelationshipKeys { //OK return [_entity classPropertyToOneRelationshipNames]; } - (EORelationship *)relationshipNamed: (NSString *)relationshipName { //OK return [_entity relationshipNamed:relationshipName]; } - (EORelationship *)anyRelationshipNamed: (NSString *)relationshipName { return [_entity anyRelationshipNamed:relationshipName]; } - (NSException *) validateObjectForDelete: (id)object { return [_entity validateObjectForDelete:object]; } - (NSException *)validateObjectForSave: (id)object { return nil; //Does Nothing ? works is done in record } - (NSException *)validateValue: (id *)valueP forKey: (NSString *)key { NSException *exception = nil; EOAttribute *attr; EORelationship *relationship; NSAssert(valueP, @"No value pointer"); attr = [_entity attributeNamed: key]; if (attr) { exception = [attr validateValue: valueP]; } else { relationship = [_entity relationshipNamed: key]; if (relationship) { exception = [relationship validateValue: valueP]; } else { NSEmitTODO(); //TODO } } return exception; } @end @implementation EOEntityClassDescription (GDL2Extenstions) /** returns a new autoreleased mutable dictionary to store properties returns nil if there's no key in the instanceDictionaryInitializer **/ - (EOMutableKnownKeyDictionary*) dictionaryForInstanceProperties { EOMutableKnownKeyDictionary* dict = nil; EOFLOGObjectFnStart(); NSAssert(_entity,@"No entity"); dict = [_entity _dictionaryForInstanceProperties]; EOFLOGObjectFnStop(); return dict; } @end @implementation EOEntityClassDescription (Deprecated) + (EOEntityClassDescription*)entityClassDescriptionWithEntity: (EOEntity *)entity { return AUTORELEASE([[self alloc] initWithEntity: entity]); } @end @implementation NSString (EODatabaseNameConversion) + (NSString *)nameForExternalName: (NSString *)externalName separatorString: (NSString *)separatorString initialCaps: (BOOL)initialCaps { NSEmitTODO(); //TODO [self notImplemented: _cmd]; return nil; } + (NSString *)externalNameForInternalName: (NSString *)internalName separatorString: (NSString *)separatorString useAllCaps: (BOOL)allCaps { NSEmitTODO(); //TODO [self notImplemented: _cmd]; return nil; } @end @implementation NSObject (EOEntity) /** should returns a set of property names to exclude from entity instanceDictionaryInitializer **/ + (NSArray *)_instanceDictionaryInitializerExcludedPropertyNames { // default implementation returns nil return nil; } @end gnustep-dl2-0.12.0/EOAccess/EODatabaseContext.h0000644000175000017500000003646410645346232020103 0ustar ayersayers/* -*-objc-*- EODatabaseContext.h Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: July 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EODatabaseContext_h__ #define __EODatabaseContext_h__ #ifdef GNUSTEP #include #include #include #include #include #else #include #endif #include #include @class NSMutableSet; @class EOAdaptorContext; @class EOAdaptorChannel; @class EOAdaptorOperation; @class EOEntity; @class EOModel; @class EORelationship; @class EOAttribute; @class EODatabase; @class EODatabaseChannel; @class EODatabaseOperation; typedef enum { EOUpdateWithOptimisticLocking, EOUpdateWithPessimisticLocking, EOUpdateWithNoLocking } EOUpdateStrategy; struct _EOTransactionScope; @interface EODatabaseContext : EOCooperatingObjectStore { EODatabase *_database; EOAdaptorContext *_adaptorContext; EOUpdateStrategy _updateStrategy; NSMutableArray *_uniqueStack; /* simple snapshots */ NSMutableArray *_deleteStack; NSMutableArray *_registeredChannels; NSMapTable *_dbOperationsByGlobalID; EOObjectStoreCoordinator *_coordinator; /* unretained */ EOEditingContext *_editingContext; /* unretained */ NSHashTable *_lockedObjects;//void* /*TO ADD unsigned int _currentGeneration; unsigned int _concurentFetches; */ NSMutableDictionary *_batchFaultBuffer; NSMutableDictionary *_batchToManyFaultBuffer; EOEntity* _lastEntity; /*TOADD EOGlobalID *_currentGlobalID; NSDictionary *_currentSnapshot; objc_object *_currentBatch; */ NSMutableArray *_uniqueArrayStack; /* to-many snapshots */ NSHashTable *_nonPrimaryKeyGenerators; struct { unsigned int preparingForSave:1; unsigned int beganTransaction:1; unsigned int ignoreEntityCaching:1; unsigned int _reserved:29; } _flags; id _delegate; /* unretained */ struct { unsigned int willRunLoginPanelToOpenDatabaseChannel:1; unsigned int newPrimaryKey:1; unsigned int willPerformAdaptorOperations:1; unsigned int shouldInvalidateObject:1; unsigned int willOrderAdaptorOperations:1; unsigned int shouldLockObject:1; unsigned int shouldRaiseForLockFailure:1; unsigned int shouldFetchObjects:1; unsigned int didFetchObjects:1; unsigned int shouldFetchObjectFault:1; unsigned int shouldFetchArrayFault:1; unsigned int _reserved:21; } _delegateRespondsTo; NSRecursiveLock *_lock; //TODO: not lock object ! } + (EODatabaseContext *)databaseContextWithDatabase: (EODatabase *)database; - (id)initWithDatabase: (EODatabase *)database; + (EODatabaseContext *)registeredDatabaseContextForModel: (EOModel *)model editingContext: (EOEditingContext *)editingContext; + (Class)contextClassToRegister; + (void)setContextClassToRegister: (Class)contextClass; - (BOOL)hasBusyChannels; - (NSArray *)registeredChannels; - (void)registerChannel: (EODatabaseChannel *)channel; - (void)unregisterChannel: (EODatabaseChannel *)channel; - (EODatabaseChannel *)_availableChannelFromRegisteredChannels; - (EODatabaseChannel *)availableChannel; - (EODatabase *)database; - (EOObjectStoreCoordinator *)coordinator; - (EOAdaptorContext *)adaptorContext; - (void)setUpdateStrategy: (EOUpdateStrategy)strategy; - (EOUpdateStrategy)updateStrategy; - (id)delegate; - (void)setDelegate: (id)delegate; - (void)handleDroppedConnection; @end /* EODatabaseContext */ @interface EODatabaseContext (EOObjectStoreSupport) - (id)faultForRawRow: (NSDictionary *)row entityNamed: (NSString *)entityName editingContext: (EOEditingContext *)context; - (id)entityForGlobalID: (EOGlobalID *)globalID; - (id)faultForGlobalID: (EOGlobalID *)globalID editingContext: (EOEditingContext *)context; - (NSArray *)arrayFaultWithSourceGlobalID: (EOGlobalID *)globalID relationshipName: (NSString *)relationshipName editingContext: (EOEditingContext *)context; - (void)initializeObject: (id)object withGlobalID: (EOGlobalID *)globalID editingContext: (EOEditingContext *)context; - (NSArray *)objectsForSourceGlobalID: (EOGlobalID *)globalID relationshipName: (NSString *)name editingContext: (EOEditingContext *)context; - (void)_registerSnapshot: (NSArray *)snapshot forSourceGlobalID: (EOGlobalID *)globalID relationshipName: (NSString *)name editingContext: (EOEditingContext *)context; - (void)refaultObject: (id)object withGlobalID: (EOGlobalID *)globalID editingContext: (EOEditingContext *)context; - (void)saveChangesInEditingContext: (EOEditingContext *)context; - (NSArray *)objectsWithFetchSpecification: (EOFetchSpecification *)fetchSpecification editingContext: (EOEditingContext *)context; - (BOOL)isObjectLockedWithGlobalID: (EOGlobalID *)gid editingContext: (EOEditingContext *)context; - (void)lockObjectWithGlobalID: (EOGlobalID *)globalID editingContext: (EOEditingContext *)context; - (void)invalidateAllObjects; - (void)invalidateObjectsWithGlobalIDs: (NSArray *)globalIDs; @end @interface EODatabaseContext (EOCooperatingObjectStoreSupport) - (BOOL)ownsGlobalID: (EOGlobalID *)globalID; - (BOOL)ownsObject: (id)object; - (BOOL)ownsEntityNamed: (NSString *)entityName; - (BOOL)handlesFetchSpecification: (EOFetchSpecification *)fetchSpecification; - (void)prepareForSaveWithCoordinator: (EOObjectStoreCoordinator *)coordinator editingContext: (EOEditingContext *)context; /** The method overrides the inherited implementation to create a list of EODatabaseOperations for EOEditingContext objects changes (only objects owned by the receiver). It forwards any relationship changes found which are not owned by the receiver to the EOObjectStoreCoordinator. It's invoked during EOObjectStoreCoordinator saving changes (saveChangesInEditingContext:) method. It's invoked after prepareForSaveWithCoordinator:editingContext: and before ownsGlobalID:. **/ - (void)recordChangesInEditingContext; - (void)recordUpdateForObject: (id)object changes: (NSDictionary *)changes; - (void)performChanges; - (void)commitChanges; - (void)rollbackChanges; - (NSDictionary *)valuesForKeys: (NSArray *)keys object: (id)object; -(void)relayPrimaryKey: (NSDictionary *)pk object: (id)object entity: (EOEntity *)entity; -(void)nullifyAttributesInRelationship: (EORelationship *)relationship sourceObject: (id)sourceObject destinationObjects: (NSArray *)destinationObjects; -(void)nullifyAttributesInRelationship: (EORelationship *)relationship sourceObject: (id)sourceObject destinationObject: (id)destinationObject; -(void)relayAttributesInRelationship: (EORelationship *)relationship sourceObject: (id)sourceObject destinationObjects: (NSArray *)destinationObjects; -(NSDictionary *)relayAttributesInRelationship: (EORelationship *)relationship sourceObject: (id)sourceObject destinationObject: (id)destinationObject; - (EODatabaseOperation*)databaseOperationForObject: (id)object; - (EODatabaseOperation*)databaseOperationForGlobalID: (EOGlobalID *)gid; - (void)recordDatabaseOperation: (EODatabaseOperation*)databaseOpe; - (void)recordDeleteForObject: (id)object; - (void)recordInsertForObject: (id)object; - (void)createAdaptorOperationsForDatabaseOperation: (EODatabaseOperation *)dbOpe attributes: (NSArray *)attributes; - (void)createAdaptorOperationsForDatabaseOperation: (EODatabaseOperation *)dbOpe; - (NSArray *)orderAdaptorOperations; - (NSArray *)entitiesOnWhichThisEntityDepends: (EOEntity *)entity; - (NSArray *)entityNameOrderingArrayForEntities: (NSArray *)entities; - (BOOL)isValidQualifierTypeForAttribute: (EOAttribute *)attribute; - (id)lockingNonQualifiableAttributes: (NSArray *)attributes; - (NSArray *)lockingAttributesForAttributes: (NSArray *)attributes entity: (EOEntity *)entity; - (NSArray *)primaryKeyAttributesForAttributes: (NSArray *)attributes entity: (EOEntity *)entity; - (EOQualifier *)qualifierForLockingAttributes: (NSArray *)attributes primaryKeyAttributes: (NSArray *)primaryKeyAttributes entity: (EOEntity *)entity snapshot: (NSDictionary *)snapshot; - (void)insertEntity: (EOEntity *)entity intoOrderingArray: (NSMutableArray *)orderingArray withDependencies: (NSDictionary *)dependencies processingSet: (NSMutableSet *)processingSet; - (void)processSnapshotForDatabaseOperation: (EODatabaseOperation *)dbOpe; - (NSDictionary *)valuesToWriteForAttributes: (NSArray *)attributes entity: (EOEntity *)entity changedValues: (NSDictionary *)changedValues; @end @interface EODatabaseContext(EOBatchFaulting) - (void)batchFetchRelationship: (EORelationship *)relationship forSourceObjects: (NSArray *)objects editingContext: (EOEditingContext *)editingContext; @end @interface EODatabaseContext (EODatabaseSnapshotting) - (void)recordSnapshot: (NSDictionary *)snapshot forGlobalID: (EOGlobalID *)gid; /** Returns snapshot for globalID. (nil if there's no snapshot for the globalID or if the corresponding tsimestamp is less than ti). Searches first locally (in the transaction scope) and after in the EODatabase. **/ - (NSDictionary *)snapshotForGlobalID: (EOGlobalID *)gid after: (NSTimeInterval)ti; /** Returns snapshot for globalID by calling snapshotForGlobalID:after: with EODistantPastTimeInterval as time interval. Searches first locally (in the transaction scope) and after in the EODatabase. **/ - (NSDictionary *)snapshotForGlobalID: (EOGlobalID *)gid; - (void)recordSnapshot: (NSArray *)gids forSourceGlobalID: (EOGlobalID *)gid relationshipName: (NSString *)name; - (NSArray *)snapshotForSourceGlobalID: (EOGlobalID *)gid relationshipName: (NSString *)name; /** Returns the snapshot for the globalID (nil if there's none). Only searches locally (in the transaction scope), not in the EODatabase. **/ - (NSDictionary *)localSnapshotForGlobalID: (EOGlobalID *)gid; - (NSArray *)localSnapshotForSourceGlobalID: (EOGlobalID *)gid relationshipName: (NSString *)name; - (void)forgetSnapshotForGlobalID: (EOGlobalID *)gid; - (void)forgetSnapshotsForGlobalIDs: (NSArray *)gids; - (void)recordSnapshots: (NSDictionary *)snapshots; - (void)recordToManySnapshots: (NSDictionary *)snapshots; - (void)registerLockedObjectWithGlobalID: (EOGlobalID *)globalID; - (BOOL)isObjectLockedWithGlobalID: (EOGlobalID *)globalID; - (void)forgetAllLocks; - (void)forgetLocksForObjectsWithGlobalIDs: (NSArray *)gids; - (void)_rollbackTransaction; - (void)_commitTransaction; - (void)_beginTransaction; - (EODatabaseChannel *)_obtainOpenChannel; - (BOOL)_openChannelWithLoginPanel: (EODatabaseChannel *)databaseChannel; - (void)_forceDisconnect; - (void)initializeObject: (id)object row: (NSDictionary *)row entity: (EOEntity *)entity editingContext: (EOEditingContext *)context; @end @interface EODatabaseContext(EOMultiThreaded) - (void)lock; - (void)unlock; @end GDL2ACCESS_EXPORT NSString *EODatabaseChannelNeededNotification; @interface NSObject (EODatabaseContextDelegation) - (BOOL)databaseContext: (EODatabaseContext *)context willRunLoginPanelToOpenDatabaseChannel: (EODatabaseChannel *)channel; - (NSDictionary *)databaseContext: (EODatabaseContext *)context newPrimaryKeyForObject: (id)object entity: (EOEntity *)entity; - (BOOL)databaseContext: (EODatabaseContext *)context failedToFetchObject: (id)object globalID: (EOGlobalID *)gid; - (NSArray *)databaseContext: (EODatabaseContext *)context willOrderAdaptorOperationsFromDatabaseOperations: (NSArray *)databaseOps; - (NSArray *)databaseContext: (EODatabaseContext *)context willPerformAdaptorOperations: (NSArray *)adaptorOps adaptorChannel: (EOAdaptorChannel *)adaptorChannel; - (BOOL)databaseContext: (EODatabaseContext *)context shouldInvalidateObjectWithGlobalID: (EOGlobalID *)globalId snapshot: (NSDictionary *)snapshot; - (NSArray *)databaseContext: (EODatabaseContext *)context shouldFetchObjectsWithFetchSpecification: (EOFetchSpecification *)fetchSpecification editingContext: (EOEditingContext *)editingContext; - (void)databaseContext: (EODatabaseContext *)context didFetchObjects: (NSArray *)objects fetchSpecification: (EOFetchSpecification *)fetchSpecification editingContext: (EOEditingContext *)editingContext; - (BOOL)databaseContext: (EODatabaseContext *)context shouldSelectObjectsWithFetchSpecification: (EOFetchSpecification *)fetchSpecification databaseChannel: (EODatabaseChannel *)channel; - (BOOL)databaseContext: (EODatabaseContext *)context shouldUsePessimisticLockWithFetchSpecification: (EOFetchSpecification *)fetchSpecification databaseChannel: (EODatabaseChannel *)channel; - (void)databaseContext: (EODatabaseContext *)context didSelectObjectsWithFetchSpecification: (EOFetchSpecification *)fetchSpecification databaseChannel: (EODatabaseChannel *)channel; - (NSDictionary *)databaseContext: (EODatabaseContext *)context shouldUpdateCurrentSnapshot: (NSDictionary *)currentSnapshot newSnapshot: (NSDictionary *)newSnapshot globalID: (EOGlobalID *)globalID databaseChannel: (EODatabaseChannel *)channel; - (BOOL)databaseContext: (EODatabaseContext *)databaseContext shouldLockObjectWithGlobalID: (EOGlobalID *)globalID snapshot: (NSDictionary *)snapshot; - (BOOL)databaseContext: (EODatabaseContext *)databaseContext shouldRaiseExceptionForLockFailure: (NSException *)exception; - (BOOL)databaseContext: (EODatabaseContext *)databaseContext shouldFetchObjectFault: (id)fault; - (BOOL)databaseContext: (EODatabaseContext *)databaseContext shouldFetchArrayFault: (id)fault; @end GDL2ACCESS_EXPORT NSString *EOCustomQueryExpressionHintKey; GDL2ACCESS_EXPORT NSString *EOStoredProcedureNameHintKey; GDL2ACCESS_EXPORT NSString *EODatabaseContextKey; GDL2ACCESS_EXPORT NSString *EODatabaseOperationsKey; GDL2ACCESS_EXPORT NSString *EOFailedDatabaseOperationKey; #endif /* __EODatabaseContext_h__ */ gnustep-dl2-0.12.0/EOAccess/EORelationship.m0000644000175000017500000017710611147017576017503 0ustar ayersayers/** EORelationship.m EORelationship Copyright (C) 2000-2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 Author: Manuel Guesdon Date: October 2000 $Revision: 27916 $ $Date: 2009-02-18 15:47:26 +0100 (Mit, 18. Feb 2009) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EORelationship.m 27916 2009-02-18 14:47:26Z ratmice $") #ifdef GNUSTEP #include #include #include #else #include #endif #ifndef GNUSTEP #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include "EOPrivate.h" #include "EOAttributePriv.h" #include "EOEntityPriv.h" @interface EORelationship (EORelationshipPrivate) - (void)_setInverseRelationship: (EORelationship *)relationship; @end @implementation EORelationship + (void)initialize { static BOOL initialized = NO; if (!initialized) { initialized = YES; GDL2_EOAccessPrivateInit(); } } + (id) relationshipWithPropertyList: (NSDictionary *)propertyList owner: (id)owner { return AUTORELEASE([[self alloc] initWithPropertyList: propertyList owner: owner]); } - (id)init { //OK if ((self = [super init])) { /* _sourceNames = [NSMutableDictionary new]; _destinationNames = [NSMutableDictionary new]; _userInfo = [NSDictionary new]; _sourceToDestinationKeyMap = [NSDictionary new]; */ _joins = [NSMutableArray new]; } return self; } - (void)dealloc { [self _flushCache]; DESTROY(_name); DESTROY(_qualifier); DESTROY(_sourceNames); DESTROY(_destinationNames); DESTROY(_userInfo); DESTROY(_internalInfo); DESTROY(_docComment); DESTROY(_joins); DESTROY(_sourceToDestinationKeyMap); DESTROY(_sourceRowToForeignKeyMapping); DESTROY(_definitionArray); _entity = nil; _destination = nil; [super dealloc]; } - (unsigned)hash { return [_name hash]; } - (id) initWithPropertyList: (NSDictionary *)propertyList owner: (id)owner { //Near OK if ((self = [self init])) { NSString *joinSemanticString = nil; EOModel *model; NSString* destinationEntityName = nil; EOEntity* destinationEntity = nil; NSString* deleteRuleString = nil; NSString* relationshipName; EOFLOGObjectFnStart(); model = [owner model]; relationshipName = [propertyList objectForKey: @"name"]; /* so setName: can validate against the owner */ [self setEntity: owner]; [self setName: relationshipName]; destinationEntityName = [propertyList objectForKey: @"destination"]; if (destinationEntityName) //If not, this is because it's a definition { destinationEntity = [model entityNamed: destinationEntityName]; _destination = destinationEntity; } [self setToMany: [[propertyList objectForKey: @"isToMany"] isEqual: @"Y"]]; [self setIsMandatory: [[propertyList objectForKey: @"isMandatory"] isEqual:@"Y"]]; [self setOwnsDestination: [[propertyList objectForKey: @"ownsDestination"] isEqual: @"Y"]]; [self setPropagatesPrimaryKey: [[propertyList objectForKey: @"propagatesPrimaryKey"] isEqual: @"Y"]]; [self setIsBidirectional: [[propertyList objectForKey: @"isBidirectional"] isEqual: @"Y"]]; [self setUserInfo: [propertyList objectForKey: @"userInfo"]]; if(!_userInfo) [self setUserInfo: [propertyList objectForKey: @"userDictionary"]]; [self setInternalInfo: [propertyList objectForKey: @"internalInfo"]]; [self setDocComment: [propertyList objectForKey: @"docComment"]]; joinSemanticString = [propertyList objectForKey: @"joinSemantic"]; if (joinSemanticString) { if ([joinSemanticString isEqual: @"EOInnerJoin"]) [self setJoinSemantic: EOInnerJoin]; else if ([joinSemanticString isEqual: @"EOFullOuterJoin"]) [self setJoinSemantic: EOFullOuterJoin]; else if ([joinSemanticString isEqual: @"EOLeftOuterJoin"]) [self setJoinSemantic: EOLeftOuterJoin]; else if ([joinSemanticString isEqual: @"EORightOuterJoin"]) [self setJoinSemantic: EORightOuterJoin]; else { EOFLOGObjectLevelArgs(@"EORelationship", @"Unknown joinSemanticString=%@. entityName=%@ relationshipName=%@", joinSemanticString, [(EOEntity*)owner name], relationshipName); NSEmitTODO(); //TODO [self notImplemented: _cmd]; //TODO } } else { if (destinationEntityName) { EOFLOGObjectLevelArgs(@"EORelationship", @"!joinSemanticString but destinationEntityName. entityName=%@ relationshipName=%@", [(EOEntity*)owner name], relationshipName); NSEmitTODO(); //TODO [self notImplemented: _cmd]; //TODO } } deleteRuleString = [propertyList objectForKey: @"deleteRule"]; EOFLOGObjectLevelArgs(@"EORelationship", @"entityName=%@ relationshipName=%@ deleteRuleString=%@", [(EOEntity*)owner name], relationshipName, deleteRuleString); if (deleteRuleString) { EODeleteRule deleteRule = [self _deleteRuleFromString: deleteRuleString]; EOFLOGObjectLevelArgs(@"EORelationship", @"entityName=%@ relationshipName=%@ deleteRule=%d", [(EOEntity*)owner name], relationshipName, (int)deleteRule); NSAssert2(deleteRule >= 0 && deleteRule < 4, @"Bad deleteRule numeric value: %@ (%d)", deleteRuleString, deleteRule); [self setDeleteRule: deleteRule]; } } EOFLOGObjectFnStop(); return self; } - (void)awakeWithPropertyList: (NSDictionary *)propertyList //TODO { //OK for definition NSString *definition; EOFLOGObjectFnStart(); EOFLOGObjectLevelArgs(@"EORelationship", @"self=%@", self); definition = [propertyList objectForKey: @"definition"]; EOFLOGObjectLevelArgs(@"EORelationship", @"definition=%@", definition); if (definition) { [self setDefinition: definition]; } else { NSString *dataPath = [propertyList objectForKey: @"dataPath"]; EOFLOGObjectLevelArgs(@"EORelationship", @"dataPath=%@", dataPath); if (dataPath) { NSEmitTODO(); //TODO [self notImplemented: _cmd]; // TODO } else { NSArray *joins = [propertyList objectForKey: @"joins"]; int count = [joins count]; EOFLOGObjectLevelArgs(@"EORelationship", @"joins=%@", joins); if (count > 0) { int i; for (i = 0; i < count; i++) { NSDictionary *joinPList; NSString *joinSemantic; NSString *sourceAttributeName; EOAttribute *sourceAttribute; EOEntity *destinationEntity; NSString *destinationAttributeName = nil; EOAttribute *destinationAttribute = nil; EOJoin *join = nil; joinPList = [joins objectAtIndex: i]; joinSemantic = [joinPList objectForKey: @"joinSemantic"]; sourceAttributeName = [joinPList objectForKey: @"sourceAttribute"]; sourceAttribute = [_entity attributeNamed: sourceAttributeName]; NSAssert4(sourceAttribute, @"No sourceAttribute named \"%@\" in entity \"%@\" in relationship %@\nEntity: %@", sourceAttributeName, [_entity name], self, _entity); destinationEntity = [self destinationEntity]; NSAssert3(destinationEntity,@"No destination entity for relationship named '%@' in entity named '%@': %@", [self name], [[self entity]name], self); destinationAttributeName = [joinPList objectForKey: @"destinationAttribute"]; destinationAttribute = [destinationEntity attributeNamed: destinationAttributeName]; NSAssert4(destinationAttribute, @"No destinationAttribute named \"%@\" in entity \"%@\" in relationship %@\nEntity: %@", destinationAttributeName, [destinationEntity name], self, destinationEntity); NS_DURING { join = [EOJoin joinWithSourceAttribute: sourceAttribute destinationAttribute: destinationAttribute]; } NS_HANDLER { [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: cannot create join for relationship '%@': %@", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, [self name], [localException reason]]; } NS_ENDHANDLER; EOFLOGObjectLevelArgs(@"EORelationship", @"join=%@", join); [self addJoin: join]; } } /* NSArray *array; NSEnumerator *enumerator; EOModel *model = [_entity model]; id joinPList; if(_destination) { id destinationEntityName = [_destination autorelease]; _destination = [[model entityNamed:destinationEntityName] retain]; if(!_destination) { NSEmitTODO(); //TODO [self notImplemented:_cmd]; // TODO } } */ } } /* ?? if(!(_destination || _definitionArray)) { NSEmitTODO(); //TODO [self notImplemented:_cmd]; // TODO }; */ EOFLOGObjectFnStop(); } - (void)encodeIntoPropertyList: (NSMutableDictionary *)propertyList { NS_DURING //Just for debugging { //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 } { int joinsCount = [_joins count]; if (joinsCount > 0) { 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"]; NSAssert([[join destinationAttribute] name], @"No destination attribute name"); [joinDict setObject: [[join destinationAttribute] name] forKey: @"destinationAttribute"]; [joinsArray addObject: joinDict]; } [propertyList setObject: joinsArray forKey: @"joins"]; } NSAssert([self joinSemanticString], @"No joinSemanticString"); [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 { NSString *dscr = nil; NS_DURING //Just for debugging { dscr = [NSString stringWithFormat: @"<%s %p - name=%@ entity=%@ destinationEntity=%@ definition=%@", object_get_class_name(self), (void*)self, [self name], [[self entity]name], [[self destinationEntity] name], [self definition]]; dscr = [dscr stringByAppendingFormat: @" userInfo=%@", [self userInfo]]; dscr = [dscr stringByAppendingFormat: @" joins=%@", [self joins]]; dscr = [dscr stringByAppendingFormat: @" sourceAttributes=%@", [self sourceAttributes]]; dscr = [dscr stringByAppendingFormat: @" destinationAttributes=%@", [self destinationAttributes]]; /*TODO dscr = [dscr stringByAppendingFormat:@" componentRelationships=%@", [self componentRelationships]];*/ dscr = [dscr stringByAppendingFormat: @" isCompound=%s isFlattened=%s isToMany=%s isBidirectional=%s>", ([self isCompound] ? "YES" : "NO"), ([self isFlattened] ? "YES" : "NO"), ([self isToMany] ? "YES" : "NO"), ([self isBidirectional] ? "YES" : "NO")]; } NS_HANDLER { NSLog(@"exception in EORelationship description: self=%p class=%@", self, [self class]); NSDebugMLog(@"exception in EORelationship description: self=%p class=%@", self, [self class]); NSLog(@"exception=%@", localException); NSDebugMLog(@"exception=%@", localException); [localException raise]; } NS_ENDHANDLER; return dscr; } - (NSString *)name { return _name; } /** Returns the relationship's source entity. **/ - (EOEntity *)entity { return _entity; } /** Returns the relationship's destination entity (direct destination entity or destination entity of the last relationship in definition. **/ - (EOEntity *)destinationEntity { //OK // May be we could cache destination ? Hard to do because klast relationship may have its destination entity change. EOEntity *destinationEntity = _destination; if (!destinationEntity) { if ([self isFlattened]) { EORelationship *lastRelationship = [_definitionArray lastObject]; destinationEntity = [lastRelationship destinationEntity]; NSAssert3(destinationEntity, @"No destinationEntity in last relationship: %@ of relationship %@ in entity %@", lastRelationship, self, [_entity name]); } else { [self _joinsChanged]; destinationEntity = _destination; } } else if ([destinationEntity isKindOfClass: [NSString class]] == YES) destinationEntity = [[_entity model] entityNamed: (NSString*)destinationEntity]; return destinationEntity; } - (BOOL) isParentRelationship { BOOL isParentRelationship = NO; /*EOEntity *destinationEntity = [self destinationEntity]; EOEntity *parentEntity = [_entity parentEntity];*///nil NSEmitTODO(); //TODO // [self notImplemented:_cmd]; //TODO... return isParentRelationship; } /** Returns YES when the relationship traverses at least two entities (exemple: aRelationship.anotherRelationship), NO otherwise. **/ - (BOOL)isFlattened { if (_definitionArray) return [_definitionArray isFlattened]; else return NO; } /** return YES if the relation if a to-many one, NO otherwise (please read books to know what to-many mean :-) **/ - (BOOL)isToMany { return _flags.isToMany; } /** Returns YES if the relationship have more than 1 join (i.e. join on more that one (sourceAttribute/destinationAttribute), NO otherwise (1 or less join) **/ - (BOOL)isCompound { //OK return [_joins count] > 1; } - (NSArray *)joins { return _joins; } - (NSArray *)sourceAttributes { //OK if (!_sourceAttributes) { int i, count = [_joins count]; _sourceAttributes = [NSMutableArray new]; for (i = 0; i < count; i++) { EOJoin *join = [_joins objectAtIndex: i]; [(NSMutableArray*)_sourceAttributes addObject: [join sourceAttribute]]; } } return _sourceAttributes; } - (NSArray *)destinationAttributes { //OK if (!_destinationAttributes) { int i, count = [_joins count]; _destinationAttributes = [NSMutableArray new]; for (i = 0; i < count; i++) { EOJoin *join = [_joins objectAtIndex: i]; [(NSMutableArray *)_destinationAttributes addObject: [join destinationAttribute]]; } } return _destinationAttributes; } - (EOJoinSemantic)joinSemantic { return _joinSemantic; } - (NSString*)joinSemanticString { NSString *joinSemanticString = nil; switch ([self joinSemantic]) { case EOInnerJoin: joinSemanticString = @"EOInnerJoin"; break; case EOFullOuterJoin: joinSemanticString = @"EOFullOuterJoin"; break; case EOLeftOuterJoin: joinSemanticString = @"EOLeftOuterJoin"; break; case EORightOuterJoin: joinSemanticString = @"EORightOuterJoin"; break; default: NSAssert1(NO, @"Unknwon join semantic code %d", (int)[self joinSemantic]); break; } return joinSemanticString; } /** * Returns the array of relationships composing this flattend relationship. * Returns nil of the reciever isn't flattend. */ - (NSArray *)componentRelationships { /* FIXME:TODO: Have this method deterimne the components dynamically without caching them in the ivar. Possibly add some tracing code to see if caching the values can actually improve performance. (Unlikely that it's worth the trouble this may cause for entity edititng). */ if (!_componentRelationships) { return _definitionArray; //OK ?????? NSEmitTODO(); //TODO [self notImplemented: _cmd]; //TODO } return _componentRelationships; } - (NSDictionary *)userInfo { return _userInfo; } - (NSString *)docComment { return _docComment; } - (NSString *)definition { //OK NSString *definition = nil; NS_DURING //Just for debugging { definition = [_definitionArray valueForSQLExpression: nil]; } NS_HANDLER { NSLog(@"exception in EORelationship definition: self=%p class=%@", self, [self class]); NSLog(@"exception in EORelationship definition: self=%@ _definitionArray=%@", self, _definitionArray); NSLog(@"exception=%@", localException); [localException raise]; } NS_ENDHANDLER; return definition; } /** Returns the value to use in an EOSQLExpression. **/ - (NSString*) valueForSQLExpression: (EOSQLExpression*)sqlExpression { EOFLOGObjectLevelArgs(@"EORelationship", @"EORelationship %p", self); NSEmitTODO(); //TODO // return [self notImplemented:_cmd]; //TODO //return name ?? return [self name]; } - (BOOL)referencesProperty: (id)property { BOOL referencesProperty = NO; NSArray *srcAttribs = [self sourceAttributes]; NSArray *destAttribs = [self destinationAttributes]; NSArray *compRels = [self componentRelationships]; NSEmitTODO(); //TODO EOFLOGObjectLevelArgs(@"EORelationship", @"in referencesProperty:%@", property); referencesProperty = ((srcAttribs && [srcAttribs indexOfObject: property] != NSNotFound) || (destAttribs && [destAttribs indexOfObject: property] != NSNotFound) || (compRels && [compRels indexOfObject: property] != NSNotFound)); return referencesProperty; } - (EODeleteRule)deleteRule { EOFLOGObjectFnStart(); EOFLOGObjectFnStop(); return _flags.deleteRule; } - (BOOL)isMandatory { return _flags.isMandatory; } - (BOOL)propagatesPrimaryKey { return _flags.propagatesPrimaryKey; } - (BOOL)isBidirectional { return _flags.isBidirectional; } - (BOOL)isReciprocalToRelationship: (EORelationship *)relationship { //Should be OK //Ayers: Review BOOL isReciprocal = NO; EOEntity *entity; EOEntity *relationshipDestinationEntity = nil; EOFLOGObjectFnStart(); entity = [self entity]; //OK relationshipDestinationEntity = [relationship destinationEntity]; EOFLOGObjectLevelArgs(@"EORelationship", @"entity %p name=%@", entity, [entity name]); EOFLOGObjectLevelArgs(@"EORelationship", @"relationshipDestinationEntity %p name=%@", relationshipDestinationEntity, [relationshipDestinationEntity name]); if (entity == relationshipDestinationEntity) //Test like that ? { if ([self isFlattened]) //OK { if ([relationship isFlattened]) //OK { //Now compare each components in reversed order NSArray *selfComponentRelationships = [self componentRelationships]; NSArray *relationshipComponentRelationships = [relationship componentRelationships]; int selfComponentRelationshipsCount = [selfComponentRelationships count]; int relationshipComponentRelationshipsCount = [relationshipComponentRelationships count]; //May be we can imagine that they may not have the same number of components //TODO if (selfComponentRelationshipsCount == relationshipComponentRelationshipsCount) { int i, j; BOOL foundEachInverseComponent = YES; for(i = (selfComponentRelationshipsCount - 1), j = 0; foundEachInverseComponent && i >= 0; i--, j++) { EORelationship *selfRel = [selfComponentRelationships objectAtIndex: i]; EORelationship *relationshipRel = [relationshipComponentRelationships objectAtIndex: j]; foundEachInverseComponent = [selfRel isReciprocalToRelationship: relationshipRel]; } if (foundEachInverseComponent) isReciprocal = YES; } } else { //Just do nothing and try another relationship. // Is it the good way ? /* NSEmitTODO(); //TODO NSDebugMLog(@"entity %p name=%@ self name=%@ relationship name=%@ relationshipDestinationEntity %p name=%@", entity, [entity name], [self name], [relationship name], relationshipDestinationEntity, [relationshipDestinationEntity name]); [self notImplemented: _cmd]; //TODO */ } } else { //WO doens't test inverses entity EOEntity *relationshipEntity = [relationship entity]; EOEntity *destinationEntity = [self destinationEntity]; EOFLOGObjectLevelArgs(@"EORelationship", @"relationshipEntity %p name=%@", relationshipEntity, [relationshipEntity name]); EOFLOGObjectLevelArgs(@"EORelationship", @"destinationEntity %p name=%@", destinationEntity, [destinationEntity name]); if (relationshipEntity == destinationEntity) { NSArray *joins = [self joins]; NSArray *relationshipJoins = [relationship joins]; int joinsCount = [joins count]; int relationshipJoinsCount = [relationshipJoins count]; EOFLOGObjectLevelArgs(@"EORelationship", @"joinsCount=%d,relationshipJoinsCount=%d", joinsCount, relationshipJoinsCount); if (joinsCount == relationshipJoinsCount) { BOOL foundEachInverseJoin = YES; int iJoin; for (iJoin = 0; foundEachInverseJoin && iJoin < joinsCount; iJoin++) { EOJoin *join = [joins objectAtIndex: iJoin]; int iRelationshipJoin; BOOL foundInverseJoin = NO; EOFLOGObjectLevelArgs(@"EORelationship", @"%d join=%@", iJoin, join); for (iRelationshipJoin = 0; !foundInverseJoin && iRelationshipJoin < joinsCount; iRelationshipJoin++) { EOJoin *relationshipJoin = [relationshipJoins objectAtIndex:iRelationshipJoin]; EOFLOGObjectLevelArgs(@"EORelationship", @"%d relationshipJoin=%@", iRelationshipJoin, relationshipJoin); foundInverseJoin = [relationshipJoin isReciprocalToJoin: join]; EOFLOGObjectLevelArgs(@"EORelationship", @"%d foundInverseJoin=%s", iRelationshipJoin, (foundInverseJoin ? "YES" : "NO")); } if (!foundInverseJoin) foundEachInverseJoin = NO; EOFLOGObjectLevelArgs(@"EORelationship", @"%d foundEachInverseJoin=%s", iJoin, (foundEachInverseJoin ? "YES" : "NO")); } EOFLOGObjectLevelArgs(@"EORelationship", @"foundEachInverseJoin=%s", (foundEachInverseJoin ? "YES" : "NO")); if (foundEachInverseJoin) isReciprocal = YES; } } } } EOFLOGObjectFnStop(); return isReciprocal; } /** "Search only already created inverse relationship in destination entity relationships. Nil if none" **/ - (EORelationship *)inverseRelationship { //OK EOFLOGObjectFnStart(); if (!_inverseRelationship) { EOEntity *destinationEntity; NSArray *destinationEntityRelationships; destinationEntity = [self destinationEntity]; NSDebugLog(@"destinationEntity name=%@", [destinationEntity name]); destinationEntityRelationships = [destinationEntity relationships]; NSDebugLog(@"destinationEntityRelationships=%@", destinationEntityRelationships); if ([destinationEntityRelationships count] > 0) { int i, count = [destinationEntityRelationships count]; for (i = 0; !_inverseRelationship && i < count; i++) { EORelationship *testRelationship = [destinationEntityRelationships objectAtIndex: i]; NSDebugLog(@"testRelationship=%@", testRelationship); if ([self isReciprocalToRelationship: testRelationship]) { ASSIGN(_inverseRelationship, testRelationship); } } } NSDebugLog(@"_inverseRelationship=%@", _inverseRelationship); } EOFLOGObjectFnStop(); return _inverseRelationship; } - (EORelationship *) _makeFlattenedInverseRelationship { //OK EORelationship *inverseRelationship = nil; NSMutableString *invDefinition = nil; NSString *name = nil; int i, count; EOFLOGObjectFnStart(); NSAssert([self isFlattened], @"Not Flatten Relationship"); EOFLOGObjectLevel(@"EORelationship", @"add joins"); count = [_definitionArray count]; for (i = count - 1; i >= 0; i--) { EORelationship *rel = [_definitionArray objectAtIndex: i]; EORelationship *invRel = [rel anyInverseRelationship]; NSString *invRelName = [invRel name]; if (invDefinition) { if (i < (count - 1)) [invDefinition appendString: @"."]; [invDefinition appendString: invRelName]; } else invDefinition = [NSMutableString stringWithString: invRelName]; } inverseRelationship = [[EORelationship new] autorelease]; [inverseRelationship setEntity: [self destinationEntity]]; name = [NSString stringWithFormat: @"_eofInv_%@_%@", [_entity name], _name]; [inverseRelationship setName: name]; [inverseRelationship setDefinition: invDefinition]; EOFLOGObjectLevel(@"EORelationship", @"add inverse rel"); [(NSMutableArray*)[[self destinationEntity] _hiddenRelationships] addObject: inverseRelationship]; //not very clean !!! EOFLOGObjectLevel(@"EORelationship", @"set inverse rel"); [inverseRelationship _setInverseRelationship: self]; EOFLOGObjectFnStop(); return inverseRelationship; } - (EORelationship*) _makeInverseRelationship { //OK EORelationship *inverseRelationship; NSString *name; NSArray *joins = nil; unsigned int i, count; EOFLOGObjectFnStart(); NSAssert(![self isFlattened], @"Flatten Relationship"); inverseRelationship = [[EORelationship new] autorelease]; name = [NSString stringWithFormat: @"_eofInv_%@_%@", [_entity name], _name]; [inverseRelationship setName: name]; joins = [self joins]; count = [joins count]; EOFLOGObjectLevel(@"EORelationship", @"add joins"); for (i = 0; i < count; i++) { EOJoin *join = [joins objectAtIndex: i]; EOAttribute *sourceAttribute = [join sourceAttribute]; EOAttribute *destinationAttribute = [join destinationAttribute]; EOJoin *inverseJoin = [EOJoin joinWithSourceAttribute: destinationAttribute //inverse souce<->destination attributes destinationAttribute: sourceAttribute]; [inverseRelationship addJoin: inverseJoin]; } EOFLOGObjectLevel(@"EORelationship",@"add inverse rel"); [(NSMutableArray*)[[self destinationEntity] _hiddenRelationships] addObject: inverseRelationship]; //not very clean !!! EOFLOGObjectLevel(@"EORelationship", @"set inverse rel"); [inverseRelationship _setInverseRelationship: self]; /* call this last to avoid calls to [_destination _setIsEdited] */ [inverseRelationship setEntity: _destination]; EOFLOGObjectFnStop(); return inverseRelationship; } - (EORelationship*) hiddenInverseRelationship { //OK EOFLOGObjectFnStart(); if (!_hiddenInverseRelationship) { if ([self isFlattened]) _hiddenInverseRelationship = [self _makeFlattenedInverseRelationship]; else _hiddenInverseRelationship = [self _makeInverseRelationship]; } EOFLOGObjectFnStop(); return _hiddenInverseRelationship; } - (EORelationship *)anyInverseRelationship { //OK EORelationship *inverseRelationship = [self inverseRelationship]; if (!inverseRelationship) inverseRelationship = [self hiddenInverseRelationship]; return inverseRelationship; } - (unsigned int)numberOfToManyFaultsToBatchFetch { return _batchCount; } - (BOOL)ownsDestination { return _flags.ownsDestination; } - (EOQualifier *)qualifierWithSourceRow: (NSDictionary *)sourceRow { [self notImplemented: _cmd];//TODO return nil; } @end /* EORelationship */ @implementation EORelationship (EORelationshipEditing) - (NSException *)validateName: (NSString *)name { //Seems OK const char *p, *s = [name cString]; int exc = 0; NSArray *storedProcedures = nil; if ([_name isEqual:name]) return nil; if (!name || ![name length]) exc++; if (!exc) { p = s; while (*p) { if(!isalnum(*p) && *p != '@' && *p != '#' && *p != '_' && *p != '$') { exc++; break; } p++; } if (!exc && *s == '$') exc++; if (exc) return [NSException exceptionWithName: NSInvalidArgumentException reason: [NSString stringWithFormat: @"%@ -- %@ 0x%x: argument \"%@\" contains invalid char '%c'", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, name, *p] userInfo: nil]; if ([[self entity] _hasAttributeNamed: name]) exc++; else if ([[self entity] anyRelationshipNamed: name]) exc++; else if ((storedProcedures = [[[self entity] model] storedProcedures])) { NSEnumerator *stEnum = [storedProcedures objectEnumerator]; EOStoredProcedure *st; while ((st = [stEnum nextObject])) { NSEnumerator *attrEnum; EOAttribute *attr; attrEnum = [[st arguments] objectEnumerator]; while ((attr = [attrEnum nextObject])) { if ([name isEqualToString: [attr name]]) { exc++; break; } } if (exc) break; } } } if (exc) { return [NSException exceptionWithName: NSInvalidArgumentException reason: [NSString stringWithFormat: @"%@ -- %@ 0x%x: \"%@\" already used in the model", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, name] userInfo: nil]; } return nil; } - (void)setToMany: (BOOL)flag { //OK if ([self isFlattened]) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: receiver is a flattened relationship", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self]; if (_flags.isToMany != flag) { [self willChange]; [_entity _setIsEdited]; _flags.isToMany = flag; } } - (void)setName: (NSString *)name { //OK [[self validateName: name] raise]; [self willChange]; [_entity _setIsEdited]; ASSIGNCOPY(_name, name); } - (void)setDefinition: (NSString *)definition { //Near OK EOFLOGObjectFnStart(); EOFLOGObjectLevelArgs(@"EORelationship", @"definition=%@", definition); [self _flushCache]; [self willChange]; if (definition) { _flags.isToMany = NO; NSAssert1(_entity,@"No entity for relationship %@", self); ASSIGN(_definitionArray, [_entity _parseRelationshipPath: definition]); EOFLOGObjectLevelArgs(@"EORelationship", @"_definitionArray=%@", _definitionArray); EOFLOGObjectLevelArgs(@"EORelationship", @"[self definition]=%@", [self definition]); _destination = nil; { //TODO VERIFY //TODO better ? int i, count = [_definitionArray count]; EOFLOGObjectLevelArgs(@"EORelationship", @"==> _definitionArray=%@", _definitionArray); for (i = 0; !_flags.isToMany && i < count; i++) { EORelationship *rel = [_definitionArray objectAtIndex: i]; if ([rel isKindOfClass: [EORelationship class]]) { if ([rel isToMany]) _flags.isToMany = YES; } else break; } } } else /* definition == nil */ { DESTROY(_definitionArray); } /* Ayers: Not sure what justifies this. */ [_entity _setIsEdited]; EOFLOGObjectFnStop(); } /** *

Sets the entity of the reciever.

*

If the receiver already has an entity assigned to it the old relationship * will will be removed first.

*

This method is used by [EOEntity-addRelationship:] and * [EOEntity-removeRelationship:] which should be used for general relationship * manipulations. This method should only be useful * when creating flattend relationships programmatically.

*/ - (void)setEntity: (EOEntity *)entity { //OK if (entity != _entity) { [self _flushCache]; [self willChange]; if (_entity) { NSString *relationshipName; EORelationship *relationship; /* Check if we are still in the entities arrays to avoid recursive loop when removeRelationship: calls this method. */ relationshipName = [self name]; relationship = [_entity relationshipNamed: relationshipName]; if (self == relationship) { [_entity removeRelationship: self]; } } _entity = entity; } /* This method is used by EOEntity's remove/addRelatinship: and is not responsible for calling _setIsEdited on the entity. */ } - (void)setUserInfo: (NSDictionary *)dictionary { //OK [self willChange]; ASSIGN(_userInfo, dictionary); /* Ayers: Not sure what justifies this. */ [_entity _setIsEdited]; } - (void)setInternalInfo: (NSDictionary *)dictionary { //OK [self willChange]; ASSIGN(_internalInfo, dictionary); /* Ayers: Not sure what justifies this. */ [_entity _setIsEdited]; } - (void)setDocComment: (NSString *)docComment { //OK [self willChange]; ASSIGNCOPY(_docComment, docComment); /* Ayers: Not sure what justifies this. */ [_entity _setIsEdited]; } - (void)setPropagatesPrimaryKey: (BOOL)flag { //OK if (_flags.propagatesPrimaryKey != flag) [self willChange]; _flags.propagatesPrimaryKey = flag; } - (void)setIsBidirectional: (BOOL)flag { //OK if (_flags.isBidirectional != flag) [self willChange]; _flags.isBidirectional = flag; } - (void)setOwnsDestination: (BOOL)flag { if (_flags.ownsDestination != flag) [self willChange]; _flags.ownsDestination = flag; } - (void)addJoin: (EOJoin *)join { EOAttribute *sourceAttribute = nil; EOAttribute *destinationAttribute = nil; EOFLOGObjectFnStart(); EOFLOGObjectLevelArgs(@"EORelationship", @"Add join: %@\nto %@", join, self); if ([self isFlattened] == YES) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: receiver is a flattened relationship", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self]; else { EOEntity *destinationEntity = [self destinationEntity]; EOEntity *sourceEntity = [self entity]; EOFLOGObjectLevelArgs(@"EORelationship", @"destinationEntity=%@", destinationEntity); if (!destinationEntity) { NSEmitTODO(); //TODO EOFLOGObjectLevelArgs(@"EORelationship", @"self=%@", self); //TODO ?? }; sourceAttribute = [join sourceAttribute]; NSAssert3(sourceAttribute, @"No source attribute in join %@ in relationship %@ of entity %@", join, self, sourceEntity); destinationAttribute = [join destinationAttribute]; NSAssert3(destinationAttribute, @"No destination attribute in join %@ in relationship %@ of entity %@", join, self, sourceEntity); if ([sourceAttribute isFlattened] == YES || [destinationAttribute isFlattened] == YES) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: join's attributes are flattened", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self]; else { EOEntity *joinDestinationEntity = [destinationAttribute entity]; EOEntity *joinSourceEntity = [sourceAttribute entity]; /* if (destinationEntity && ![[destinationEntity name] isEqual:[joinSourceEntity name]]) { [NSException raise:NSInvalidArgumentException format:@"%@ -- %@ 0x%x: join source entity (%@) is not equal to last join entity (%@)", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, [joinSourceEntity name], [destinationEntity name]]; }*/ if (sourceEntity && ![[joinSourceEntity name] isEqual: [sourceEntity name]]) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x (%@): join source entity (%@) is not equal to relationship entity (%@)", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, [self name], [joinSourceEntity name], [sourceEntity name]]; else if (destinationEntity && ![[joinDestinationEntity name] isEqual: [destinationEntity name]]) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x (%@): join destination entity (%@) is not equal to relationship destination entity (%@)", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, [self name], [joinDestinationEntity name], [destinationEntity name]]; else { if ([_sourceAttributes count]) { EOAttribute *sourceAttribute = [join sourceAttribute]; EOAttribute *destinationAttribute; destinationAttribute = [join destinationAttribute]; if (([_sourceAttributes indexOfObject: sourceAttribute] != NSNotFound) && ([_destinationAttributes indexOfObject: destinationAttribute] != NSNotFound)) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: TODO", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self]; } [self _flushCache]; [self willChange]; EOFLOGObjectLevel(@"EORelationship", @"really add"); EOFLOGObjectLevelArgs(@"EORelationship", @"XXjoins %p class%@", _joins, [_joins class]); if (!_joins) _joins = [NSMutableArray new]; [(NSMutableArray *)_joins addObject: join]; EOFLOGObjectLevelArgs(@"EORelationship", @"XXjoins %p class%@", _joins, [_joins class]); EOFLOGObjectLevel(@"EORelationship", @"added"); [self _joinsChanged]; /* Ayers: Not sure what justifies this. */ [_entity _setIsEdited]; } } } EOFLOGObjectFnStop(); } - (void)removeJoin: (EOJoin *)join { EOFLOGObjectFnStart(); [self _flushCache]; if ([self isFlattened] == YES) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: receiver is a flattened relationship", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self]; else { [self willChange]; [(NSMutableArray *)_joins removeObject: join]; /*NO: will be recomputed [(NSMutableArray *)_sourceAttributes removeObject:[join sourceAttribute]]; [(NSMutableArray *)_destinationAttributes removeObject:[join destinationAttribute]]; */ EOFLOGObjectLevelArgs(@"EORelationship", @"XXjoins %p class%@", _joins, [_joins class]); [self _joinsChanged]; /* Ayers: Not sure what justifies this. */ [_entity _setIsEdited]; } EOFLOGObjectFnStop(); } - (void)setJoinSemantic: (EOJoinSemantic)joinSemantic { //OK [self willChange]; _joinSemantic = joinSemantic; } - (void)beautifyName { /*+ Make the name conform to the Next naming style NAME -> name, FIRST_NAME -> firstName +*/ NSArray *listItems; NSString *newString = [NSString string]; int anz, i; EOFLOGObjectFnStartOrCond2(@"ModelingClasses", @"EORelationship"); /* Makes the receiver's name conform to a standard convention. Names that conform to this style are all lower-case except for the initial letter of each embedded word other than the first, which is upper case. Thus, "NAME" becomes "name", and "FIRST_NAME" becomes "firstName".*/ if ((_name) && ([_name length] > 0)) { listItems = [_name componentsSeparatedByString: @"_"]; newString = [newString stringByAppendingString: [[listItems objectAtIndex: 0] lowercaseString]]; anz = [listItems count]; for (i = 1; i < anz; i++) { newString = [newString stringByAppendingString: [[listItems objectAtIndex: i] capitalizedString]]; } // Exception abfangen NS_DURING { [self setName:newString]; } NS_HANDLER { NSLog(@"%@ in Class: EORlationship , Method: beautifyName >> error : %@", [localException name], [localException reason]); } NS_ENDHANDLER; } EOFLOGObjectFnStopOrCond2(@"ModelingClasses", @"EORelationship"); } - (void)setNumberOfToManyFaultsToBatchFetch: (unsigned int)size { [self willChange]; _batchCount = size; } - (void)setDeleteRule: (EODeleteRule)deleteRule { NSAssert1(deleteRule >= 0 && deleteRule < 4, @"Bad deleteRule numeric value: %d", deleteRule); [self willChange]; _flags.deleteRule = deleteRule; } - (void)setIsMandatory: (BOOL)isMandatory { //OK [self willChange]; _flags.isMandatory = isMandatory; } @end @implementation EORelationship (EORelationshipValueMapping) /** * If the reciever is a manditory relationship, this method * returns an exception if the value pointed to by VALUEP is * either nil or the EONull instance for to-one relationships * or an empty NSArray for to-many relationships. Otherwise * it returns nil. EOClassDescription adds further information * to this exception before it gets passed to the application or * user. */ - (NSException *)validateValue: (id*)valueP { //OK NSException *exception = nil; EOFLOGObjectFnStart(); NSAssert(valueP, @"No value pointer"); if ([self isMandatory]) { BOOL isToMany = [self isToMany]; if ((isToMany == NO && _isNilOrEONull(*valueP)) || (isToMany == YES && [*valueP count] == 0)) { EOEntity *destinationEntity = [self destinationEntity]; EOEntity *entity = [self entity]; exception = [NSException validationExceptionWithFormat: @"The %@ property of %@ must have a %@ assigned", [self name], [entity name], [destinationEntity name]]; } } EOFLOGObjectFnStop(); return exception; } @end @implementation EORelationship (EORelationshipPrivate) /* This method is private to GDL2 to allow the inverse relationship to be set from the original relationship. It exists to avoid the ASSIGN(inverseRelationship->_inverseRelationship, self); and to insure that associations will be updated if we ever display inverse relationships in DBModeler. */ - (void)_setInverseRelationship: (EORelationship*)relationship { [self willChange]; ASSIGN(_inverseRelationship,relationship); } @end @implementation EORelationship (EORelationshipXX) - (NSArray*) _intermediateAttributes { //Verify !! NSMutableArray *intermediateAttributes; EORelationship *rel; NSArray *joins; //all this works on flattened and non flattened relationship. intermediateAttributes = [NSMutableArray array]; rel = [self firstRelationship]; joins = [rel joins]; //?? [intermediateAttributes addObjectsFromArray: [joins resultsOfPerformingSelector: @selector(destinationAttribute)]]; rel = [self lastRelationship]; joins = [rel joins]; // attribute = [joins sourceAttribute]; //?? [intermediateAttributes addObjectsFromArray: [joins resultsOfPerformingSelector: @selector(sourceAttribute)]]; return [NSArray arrayWithArray: intermediateAttributes]; } /** Return the last relationship if self is flattened, self otherwise. **/ - (EORelationship*) lastRelationship { EORelationship *lastRel; if ([self isFlattened]) { NSAssert(!_definitionArray || [_definitionArray count] > 0, @"Definition array is empty"); lastRel = [[self _definitionArray] lastObject]; } else lastRel = self; return lastRel; } /** Return the 1st relationship if self is flattened, self otherwise. **/ - (EORelationship*) firstRelationship { EORelationship *firstRel; if ([self isFlattened]) { NSAssert(!_definitionArray || [_definitionArray count] > 0, @"Definition array is empty"); firstRel = [[self _definitionArray] objectAtIndex: 0]; } else firstRel = self; return firstRel; } - (EOEntity*) intermediateEntity { //TODO verify id intermediateEntity = nil; if ([self isToManyToOne]) { int i, count = [_definitionArray count]; for (i = (count - 1); !intermediateEntity && i >= 0; i--) { EORelationship *rel = [_definitionArray objectAtIndex: i]; if ([rel isToMany]) intermediateEntity = [rel destinationEntity]; } } return intermediateEntity; } - (BOOL) isMultiHop { //TODO verify BOOL isMultiHop = NO; if ([self isFlattened]) { isMultiHop = YES; } return isMultiHop; } - (void) _setSourceToDestinationKeyMap: (id)param0 { [self notImplemented: _cmd]; // TODO } - (id) qualifierForDBSnapshot: (id)param0 { return [self notImplemented: _cmd]; // TODO } - (id) primaryKeyForTargetRowFromSourceDBSnapshot: (id)param0 { return [self notImplemented:_cmd]; // TODO } /** Return relationship path (like toRel1.toRel2) if self is flattened, slef name otherwise. **/ - (NSString*)relationshipPath { //Seems OK NSString *relationshipPath = nil; EOFLOGObjectFnStart(); if ([self isFlattened]) { int i, count = [_definitionArray count]; for (i = 0; i < count; i++) { EORelationship *relationship = [_definitionArray objectAtIndex: i]; NSString *relationshipName = [relationship name]; if (relationshipPath) [(NSMutableString*)relationshipPath appendString: @"."]; else relationshipPath = [NSMutableString string]; [(NSMutableString*)relationshipPath appendString: relationshipName]; } } else relationshipPath = [self name]; EOFLOGObjectFnStop(); return relationshipPath; } -(BOOL)isToManyToOne { BOOL isToManyToOne = NO; EOFLOGObjectFnStart(); if ([self isFlattened]) { BOOL isToMany = YES; int count = [_definitionArray count]; if (count >= 2) { EORelationship *firstRelationship = [_definitionArray objectAtIndex: 0]; isToMany = [firstRelationship isToMany]; if (!isToMany) { if ([firstRelationship isParentRelationship]) { NSEmitTODO(); //TODO EOFLOGObjectLevelArgs(@"EORelationship", @"self=%@", self); EOFLOGObjectLevelArgs(@"EORelationship", @"firstRelationship=%@", firstRelationship); [self notImplemented: _cmd]; //TODO } } if (isToMany) { EORelationship *secondRelationship = [_definitionArray objectAtIndex: 0]; if (![secondRelationship isToMany]) { EORelationship *invRel = [secondRelationship anyInverseRelationship]; if (invRel) secondRelationship = invRel; isToManyToOne = YES; if ([secondRelationship isParentRelationship]) { NSEmitTODO(); //TODO EOFLOGObjectLevelArgs(@"EORelationship", @"self=%@", self); EOFLOGObjectLevelArgs(@"EORelationship", @"secondRelationship=%@", secondRelationship); [self notImplemented: _cmd]; //TODO } } } } } EOFLOGObjectFnStop(); return isToManyToOne; } -(NSDictionary*)_sourceToDestinationKeyMap { //OK EOFLOGObjectFnStart(); if (!_sourceToDestinationKeyMap) { NSString *relationshipPath = [self relationshipPath]; ASSIGN(_sourceToDestinationKeyMap, [_entity _keyMapForRelationshipPath: relationshipPath]); } EOFLOGObjectFnStop(); return _sourceToDestinationKeyMap; } - (BOOL)foreignKeyInDestination { NSArray *destAttributes = nil; NSArray *primaryKeyAttributes = nil; int destAttributesCount = 0; int primaryKeyAttributesCount = 0; BOOL foreignKeyInDestination = NO; EOFLOGObjectFnStart(); destAttributes = [self destinationAttributes]; primaryKeyAttributes = [[self destinationEntity] primaryKeyAttributes]; destAttributesCount = [destAttributes count]; primaryKeyAttributesCount = [primaryKeyAttributes count]; EOFLOGObjectLevelArgs(@"EORelationship", @"destAttributes=%@", destAttributes); EOFLOGObjectLevelArgs(@"EORelationship", @"primaryKeyAttributes=%@", primaryKeyAttributes); if (destAttributesCount > 0 && primaryKeyAttributesCount > 0) { int i; for (i = 0; !foreignKeyInDestination && i < destAttributesCount; i++) { EOAttribute *attribute = [destAttributes objectAtIndex: i]; int pkAttrIndex = [primaryKeyAttributes indexOfObjectIdenticalTo: attribute]; foreignKeyInDestination = (pkAttrIndex == NSNotFound); } } EOFLOGObjectFnStop(); EOFLOGObjectLevelArgs(@"EORelationship", @"foreignKeyInDestination=%s", (foreignKeyInDestination ? "YES" : "NO")); return foreignKeyInDestination; } @end @implementation EORelationship (EORelationshipPrivate2) - (BOOL) isPropagatesPrimaryKeyPossible { /* NSArray* joins=[self joins]; NSArray* joinsSourceAttributes=[joins resultsOfPerformingSelector:@selector(sourceAttribute)]; NSArray* joinsDestinationAttributes=[joins resultsOfPerformingSelector:@selector(destinationAttribute)]; joinsSourceAttributes names sortedArrayUsingSelector:compare: result count joinsDestinationAttributes names sortedArrayUsingSelector:compare: inverseRelationship inv entity [EOEntity]: inv ventity primaryKeyAttributeNames count dest entity dst entity primaryKeyAttributeNames */ EOFLOGObjectFnStart(); [self notImplemented: _cmd]; // TODO EOFLOGObjectFnStop(); return NO; }; - (id) qualifierOmittingAuxiliaryQualifierWithSourceRow: (id)param0 { return [self notImplemented: _cmd]; // TODO } - (id) auxiliaryQualifier { return nil; //[self notImplemented:_cmd]; // TODO } - (void) setAuxiliaryQualifier: (id)param0 { [self notImplemented:_cmd]; // TODO } /** Return dictionary of key/value for destination object of source row/object **/ - (EOMutableKnownKeyDictionary *) _foreignKeyForSourceRow: (NSDictionary*)row { EOMutableKnownKeyDictionary *foreignKey = nil; EOMKKDSubsetMapping *sourceRowToForeignKeyMapping = nil; EOFLOGObjectFnStart(); sourceRowToForeignKeyMapping = [self _sourceRowToForeignKeyMapping]; EOFLOGObjectLevelArgs(@"EORelationship", @"self=%@",self); EOFLOGObjectLevelArgs(@"EORelationship", @"sourceRowToForeignKeyMapping=%@", sourceRowToForeignKeyMapping); foreignKey = [EOMutableKnownKeyDictionary dictionaryFromDictionary: row subsetMapping: sourceRowToForeignKeyMapping]; EOFLOGObjectLevelArgs(@"EORelationship", @"row=%@\nforeignKey=%@", row, foreignKey); EOFLOGObjectFnStop(); return foreignKey; } - (EOMKKDSubsetMapping*) _sourceRowToForeignKeyMapping { EOFLOGObjectFnStart(); if (!_sourceRowToForeignKeyMapping) { NSDictionary *sourceToDestinationKeyMap; NSArray *sourceKeys; NSArray *destinationKeys; EOEntity *destinationEntity; EOMKKDInitializer *destinationDictionaryInitializer = nil; EOMKKDInitializer *adaptorDictionaryInitializer; EOMKKDSubsetMapping *sourceRowToForeignKeyMapping; sourceToDestinationKeyMap = [self _sourceToDestinationKeyMap]; EOFLOGObjectLevelArgs(@"EORelationship", @"rel=%@ sourceToDestinationKeyMap=%@", [self name], sourceToDestinationKeyMap); sourceKeys = [sourceToDestinationKeyMap objectForKey: @"sourceKeys"]; EOFLOGObjectLevelArgs(@"EORelationship", @"rel=%@ sourceKeys=%@", [self name], sourceKeys); destinationKeys = [sourceToDestinationKeyMap objectForKey: @"destinationKeys"]; EOFLOGObjectLevelArgs(@"EORelationship", @"rel=%@ destinationKeys=%@", [self name], destinationKeys); destinationEntity = [self destinationEntity]; destinationDictionaryInitializer = [destinationEntity _adaptorDictionaryInitializer]; EOFLOGObjectLevelArgs(@"EORelationship", @"destinationEntity named %@ primaryKeyDictionaryInitializer=%@", [destinationEntity name], destinationDictionaryInitializer); adaptorDictionaryInitializer = [_entity _adaptorDictionaryInitializer]; EOFLOGObjectLevelArgs(@"EORelationship",@"entity named %@ adaptorDictionaryInitializer=%@", [_entity name], adaptorDictionaryInitializer); sourceRowToForeignKeyMapping = [destinationDictionaryInitializer subsetMappingForSourceDictionaryInitializer: adaptorDictionaryInitializer sourceKeys: sourceKeys destinationKeys: destinationKeys]; ASSIGN(_sourceRowToForeignKeyMapping, sourceRowToForeignKeyMapping); EOFLOGObjectLevelArgs(@"EORelationship",@"%@ to %@: _sourceRowToForeignKeyMapping=%@", [_entity name], [destinationEntity name], _sourceRowToForeignKeyMapping); } EOFLOGObjectFnStop(); return _sourceRowToForeignKeyMapping; } - (NSArray*) _sourceAttributeNames { //Seems OK return [[self sourceAttributes] resultsOfPerformingSelector: @selector(name)]; } - (EOJoin*) joinForAttribute: (EOAttribute*)attribute { //OK EOJoin *join = nil; int i, count = [_joins count]; for (i = 0; !join && i < count; i++) { EOJoin *aJoin = [_joins objectAtIndex: i]; EOAttribute *sourceAttribute = [aJoin sourceAttribute]; if ([attribute isEqual: sourceAttribute]) join = aJoin; } return join; } - (void) _flushCache { //VERIFY //[self notImplemented:_cmd]; // TODO DESTROY(_sourceAttributes); DESTROY(_destinationAttributes); DESTROY(_inverseRelationship); DESTROY(_hiddenInverseRelationship); DESTROY(_componentRelationships); _destination = nil; } - (EOExpressionArray*) _definitionArray { //VERIFY return _definitionArray; } - (NSString*) _stringFromDeleteRule: (EODeleteRule)deleteRule { NSString *deleteRuleString = nil; switch(deleteRule) { case EODeleteRuleNullify: deleteRuleString = @""; break; case EODeleteRuleCascade: deleteRuleString = @""; break; case EODeleteRuleDeny: deleteRuleString = @""; break; case EODeleteRuleNoAction: deleteRuleString = @""; break; default: [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: invalid deleteRule code for relationship '%@': %d", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, [self name], (int)deleteRule]; break; } return deleteRuleString; } - (EODeleteRule) _deleteRuleFromString: (NSString*)deleteRuleString { EODeleteRule deleteRule = 0; if ([deleteRuleString isEqualToString: @"EODeleteRuleNullify"]) deleteRule = EODeleteRuleNullify; else if ([deleteRuleString isEqualToString: @"EODeleteRuleCascade"]) deleteRule = EODeleteRuleCascade; else if ([deleteRuleString isEqualToString: @"EODeleteRuleDeny"]) deleteRule = EODeleteRuleDeny; else if ([deleteRuleString isEqualToString: @"EODeleteRuleNoAction"]) deleteRule = EODeleteRuleNoAction; else [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: invalid deleteRule string for relationship '%@': %@", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, [self name], deleteRuleString]; return deleteRule; } - (NSDictionary*) _rightSideKeyMap { NSDictionary *keyMap = nil; NSEmitTODO(); //TODO [self notImplemented: _cmd]; // TODO if ([self isToManyToOne]) { int count = [_definitionArray count]; if (count >= 2) //?? { EORelationship *rel0 = [_definitionArray objectAtIndex: 0]; if ([rel0 isToMany]) //?? { EOEntity *entity = [rel0 destinationEntity]; EORelationship *rel1 = [_definitionArray objectAtIndex: 1]; keyMap = [entity _keyMapForIdenticalKeyRelationshipPath: [rel1 name]]; } } } return keyMap; } - (NSDictionary *) _leftSideKeyMap { NSDictionary *keyMap = nil; NSEmitTODO(); //TODO [self notImplemented: _cmd]; // TODO if ([self isToManyToOne]) { int count = [_definitionArray count]; if (count >= 2) //?? { EORelationship *rel = [_definitionArray objectAtIndex: 0]; if ([rel isToMany]) //?? { EOEntity *entity = [rel entity]; keyMap = [entity _keyMapForIdenticalKeyRelationshipPath: [rel name]]; } } } return keyMap; } - (EORelationship*)_substitutionRelationshipForRow: (NSDictionary*)row { EOEntity *entity = [self entity]; EOModel *model = [entity model]; EOModelGroup *modelGroup = [model modelGroup]; if (modelGroup) { //?? //NSEmitTODO(); //TODO } return self; } - (void) _joinsChanged { //VERIFIED DA int count = [_joins count]; EOFLOGObjectFnStart(); EOFLOGObjectLevelArgs(@"EORelationship", @"_joinsChanged:%@\nin %@", _joins, self); if (count > 0) { EOJoin *join = [_joins objectAtIndex: 0]; EOAttribute *destinationAttribute = [join destinationAttribute]; EOEntity *destinationEntity = [destinationAttribute entity]; _destination = destinationEntity; } else { _destination = nil; } EOFLOGObjectFnStop(); } @end gnustep-dl2-0.12.0/EOAccess/Makefile.postamble0000644000175000017500000000347611147455374020065 0ustar ayersayers# -*-makefile-*- # Makefile.postamble # # Copyright (C) 1997,2002,2004,2005 Free Software Foundation, Inc. # # Written by: Scott Christley # # 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 3 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, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # # Makefile.postamble # # Project specific makefile rules # # Uncomment the targets you want. # The double colons (::) are important, do not make them single colons # otherwise the normal makefile rules will not be performed. # # Things to do before compiling # before-all:: # Things to do after compiling # after-all:: # Things to do before installing # before-install:: # Things to do after installing # after-install:: # Things to do before uninstalling # before-uninstall:: # Things to do after uninstalling # after-uninstall:: # Things to do before cleaning # before-clean:: # Things to do after cleaning # after-clean:: # Things to do before distcleaning # before-distclean:: # Things to do after distcleaning # after-distclean:: # Things to do before checking # before-check:: # Things to do after checking # after-check: gnustep-dl2-0.12.0/EOAccess/EOAccessFault.m0000644000175000017500000002163510645346232017226 0ustar ayersayers/** EOAccessFault.m EOAccessFault Class Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: June 2000 $Revision: 25326 $ $Date: 2007-07-12 08:39:22 +0200 (Don, 12. Jul 2007) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EOAccessFault.m 25326 2007-07-12 06:39:22Z ayers $") #ifdef GNUSTEP #include #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #include #endif #include #include #include #include #include #include "EOAccessFaultPriv.h" #include "EODatabaseContextPriv.h" 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; faultHandler->_next = self; if(_next) _next->_prev = self; } - (void)_linkNext: (EOAccessGenericFaultHandler *)next { if(_next) _next->_prev = nil; _next = next; if(next) next->_prev = self; } - (void)_linkPrev: (EOAccessGenericFaultHandler *)prev { if(_prev) _prev->_next = nil; _prev = prev; if(prev) prev->_next = self; } - (EOAccessGenericFaultHandler *)next { return _next; } - (EOAccessGenericFaultHandler *)previous { return _prev; } - (unsigned int)generation { return _generation; } - (void)faultWillFire: (id)object { //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 @implementation EOAccessFaultHandler - (id) init { if ((self = [super init])) { NSDebugFLog(@"INIT EOAccessFaultHandler %p. ThreadID=%@", (void*)self,GSCurrentThread()); } return self; } + (EOAccessFaultHandler *)accessFaultHandlerWithGlobalID: (EOKeyGlobalID *)globalID databaseContext: (EODatabaseContext *)dbcontext editingContext: (EOEditingContext *)ec { EOAccessFaultHandler* handler= [[[self alloc] initWithGlobalID: globalID databaseContext: dbcontext editingContext: ec] autorelease]; return handler; } - (id) initWithGlobalID: (EOKeyGlobalID *)globalID databaseContext: (EODatabaseContext *)dbcontext editingContext: (EOEditingContext *)ec { if ((self = [self init])) { EOFLOGObjectFnStartOrCond(@"EOAccesFaultHandler"); ASSIGNCOPY(gid, globalID); ASSIGN(databaseContext, dbcontext); ASSIGN(editingContext, ec); EOFLOGObjectFnStopOrCond(@"EOAccesFaultHandler"); } return self; } - (void)dealloc { #ifdef DEBUG NSDebugFLog(@"Dealloc EOAccessFaultHandler %p. ThreadID=%@", (void*)self, GSCurrentThread()); #endif DESTROY(gid); DESTROY(databaseContext); DESTROY(editingContext); [super dealloc]; } - (EOKeyGlobalID *)globalID { #ifdef DEBUG EOFLOGObjectFnStartOrCond(@"EOAccesFaultHandler"); EOFLOGObjectFnStopOrCond(@"EOAccesFaultHandler"); #endif return gid; } - (EODatabaseContext *)databaseContext { return databaseContext; } - (EOEditingContext *)editingContext { return editingContext; } - (void)completeInitializationOfObject:(id)anObject { EOFLOGObjectFnStart(); // We want to be sure that we will not be autoreleased // in an autorelease pool of another thread! AUTORELEASE(RETAIN(self)); [databaseContext _fireFault: anObject]; //MIRKO: replaced /* [databaseContext _batchToOne:anObject withHandler:self]; */ if ([EOFault isFault: anObject] == YES) { NSDebugMLLog(@"error", @"UnableToFaultObject: %p of class %@", anObject, [EOFault targetClassForFault: anObject]); [self unableToFaultObject: anObject databaseContext: databaseContext]; } EOFLOGObjectFnStop(); } - (BOOL)shouldPerformInvocation: (NSInvocation *)invocation { NSDebugFLLog(@"gsdb",@"invocation selector=%@ target: %p", NSStringFromSelector([invocation selector]), [invocation target]); return YES; } @end @implementation NSObject (EOAccessFaultUnableToFaultToOne) - (void)unableToFaultObject: (id)object databaseContext: (EODatabaseContext *)context { EOFaultHandler *handler = [EOFault handlerForFault:object]; EOGlobalID *globalID = nil; if ([handler respondsToSelector: @selector(globalID)]) globalID = [(EOAccessFaultHandler *)handler globalID]; NSDebugMLLog(@"gsdb", @"Fault Handler=%@ (%@)", handler, [handler class]); [NSException raise: EOAccessFaultObjectNotAvailableException format: @"%@ -- %@ 0x%x: cannot fault to-one for object %@ of class %@ databaseContext %@ handler %@ (globalID=%@)", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, object, [EOFault targetClassForFault: object], context, handler, globalID]; } @end @implementation EOAccessArrayFaultHandler + (EOAccessArrayFaultHandler *)accessArrayFaultHandlerWithSourceGlobalID: (EOKeyGlobalID *)sourceGID relationshipName: (NSString *)relName databaseContext: (EODatabaseContext *)dbcontext editingContext: (EOEditingContext *)ec { return [[[self alloc] initWithSourceGlobalID: sourceGID relationshipName: relName databaseContext: dbcontext editingContext: ec] autorelease]; } - (id)init { if ((self = [super init])) { } return self; } - (id)initWithSourceGlobalID: (EOKeyGlobalID *)sourceGID relationshipName: (NSString *)relName databaseContext: (EODatabaseContext *)dbcontext editingContext: (EOEditingContext *)ec { if ((self = [self init])) { ASSIGN(sgid, sourceGID); ASSIGN(relationshipName, relName); ASSIGN(databaseContext, dbcontext); ASSIGN(editingContext, ec); } return self; } - (void)dealloc { #ifdef DEBUG NSDebugFLog(@"Dealloc EOAccessArrayFaultHandler %p. ThreadID=%@", (void*)self,GSCurrentThread()); #endif DESTROY(sgid); DESTROY(relationshipName); DESTROY(databaseContext); DESTROY(editingContext); [super dealloc]; } - (EOKeyGlobalID *)sourceGlobalID { return sgid; } - (NSString *)relationshipName { return relationshipName; } - (EODatabaseContext *)databaseContext { return databaseContext; } - (EOEditingContext *)editingContext { return editingContext; } - (void)completeInitializationOfObject: (id)anObject { EOFLOGObjectFnStart(); // We want to be sure that we will not be autoreleased // in an autorelease pool of another thread! AUTORELEASE(RETAIN(self)); [databaseContext _fireArrayFault: anObject]; [(EOCheapCopyMutableArray *)anObject _setCopy: NO]; NSDebugMLLog(@"gsdb", @"anObject %p=%@", anObject, anObject); EOFLOGObjectFnStop(); /*MIRKO replaced [databaseContext _batchToMany:anObject withHandler:self]; */ } - (id) descriptionForObject: (id)object { //OK return [NSString stringWithFormat: @"", object, sgid, relationshipName]; } - (BOOL)shouldPerformInvocation: (NSInvocation *)invocation { NSDebugFLLog(@"gsdb",@"invocation selector=%@ target: %p", NSStringFromSelector([invocation selector]), [invocation target]); return YES; } @end @implementation EOFault (EOAccess) - (EODatabaseContext *)databaseContext { if ([_handler respondsToSelector: @selector(databaseContext)]) return [(id)_handler databaseContext]; else { [_handler completeInitializationOfObject: self]; return [self databaseContext]; } } @end gnustep-dl2-0.12.0/EOAccess/EOAccessFaultPriv.h0000644000175000017500000000233710645346232020060 0ustar ayersayers/* -*-objc-*- EOAccessFaultPriv.h Copyright (C) 2000,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: July 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOAccessFaultPriv_h__ #define __EOAccessFaultPriv_h__ @interface EOAccessGenericFaultHandler (EOAccessFaultPrivate) - (void)_linkNext: (EOAccessGenericFaultHandler *)next; - (void)_linkPrev: (EOAccessGenericFaultHandler *)prev; @end #endif gnustep-dl2-0.12.0/EOAccess/EOAdaptorPriv.h0000644000175000017500000000246310645346232017255 0ustar ayersayers/* -*-objc-*- EOAdaptorPriv.h Copyright (C) 2002,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: Nov 2002 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOAdaptorPriv_h__ #define __EOAdaptorPriv_h__ @interface EOAdaptor(EOAdaptorPrivate) - (void)_requestConcreteImplementationForSelector: (SEL)param0; - (void)_unregisterAdaptorContext: (EOAdaptorContext *)adaptorContext; - (void)_registerAdaptorContext: (EOAdaptorContext *)adaptorContext; @end #endif /* __EOAdaptorPriv_h__ */ gnustep-dl2-0.12.0/EOAccess/EODeprecated.h0000644000175000017500000000242110645346232017054 0ustar ayersayers/* -*-objc-*- EODeprecated.h Copyright (C) 2002,2003,2004,2005 Free Software Foundation, Inc. Author: Stephane Corthesy Date: Feb 2003 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOAccess_EODeprecated_h__ #define __EOAccess_EODeprecated_h__ #include #include @interface EOLoginPanel (Deprecated) /** * Use runPanelForAdaptor:validate:allowsCreation: instead. */ - (NSDictionary *)runPanelForAdaptor: (EOAdaptor *)adaptor validate: (BOOL)yn; @end #endif gnustep-dl2-0.12.0/EOAccess/EODatabaseContext.m0000644000175000017500000075244311006403422020075 0ustar ayersayers/** EODatabaseContext.m EODatabaseContext Class Copyright (C) 2000-2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: June 2000 Author: Manuel Guesdon Date: October 2000 $Revision: 26481 $ $Date: 2008-05-01 20:08:18 +0200 (Don, 01. Mai 2008) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EODatabaseContext.m 26481 2008-05-01 18:08:18Z ayers $") #ifdef GNUSTEP #include #include #include #include #include #include #include #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "EOPrivate.h" #include "EOEntityPriv.h" #include "EOAccessFaultPriv.h" #include "EODatabaseContextPriv.h" #include #define _LOCK_BUFFER 128 NSString *EODatabaseChannelNeededNotification = @"EODatabaseChannelNeededNotification"; NSString *EODatabaseContextKey = @"EODatabaseContextKey"; NSString *EODatabaseOperationsKey = @"EODatabaseOperationsKey"; NSString *EOFailedDatabaseOperationKey = @"EOFailedDatabaseOperationKey"; NSString *EOCustomQueryExpressionHintKey = @"EOCustomQueryExpressionHintKey"; NSString *EOStoredProcedureNameHintKey = @"EOStoredProcedureNameHintKey"; @interface EODatabaseContext(EOObjectStoreSupportPrivate) - (id) entityForGlobalID: (EOGlobalID *)globalID; @end @implementation EODatabaseContext // Initializing instances static Class _contextClass = Nil; + (void)initialize { static BOOL initialized=NO; if (!initialized) { initialized=YES; GDL2_EOAccessPrivateInit(); _contextClass = GDL2_EODatabaseContextClass; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_registerDatabaseContext:) name: EOCooperatingObjectStoreNeeded object: nil]; } } + (EODatabaseContext*)databaseContextWithDatabase: (EODatabase *)database { return AUTORELEASE([[self alloc] initWithDatabase: database]); } + (void)_registerDatabaseContext:(NSNotification *)notification { EOObjectStoreCoordinator *coordinator = [notification object]; EODatabaseContext *dbContext = nil; EOModel *model = nil; NSString *entityName = nil; id keyValue = nil; keyValue = [[notification userInfo] objectForKey: @"globalID"]; if (keyValue == nil) keyValue = [[notification userInfo] objectForKey: @"fetchSpecification"]; if (keyValue == nil) keyValue = [[notification userInfo] objectForKey: @"object"]; if (keyValue) entityName = [keyValue entityName]; if (entityName) model = [[[EOModelGroup defaultGroup] entityNamed:entityName] model]; if (model == nil) NSLog(@"%@ -- %@ 0x%x: No model for entity named %@", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, entityName); dbContext = [EODatabaseContext databaseContextWithDatabase: [EODatabase databaseWithModel: model]]; [coordinator addCooperatingObjectStore:dbContext]; } - (void) registerForAdaptorContextNotifications: (EOAdaptorContext*)adaptorContext { //OK [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_beginTransaction) name: EOAdaptorContextBeginTransactionNotification object: adaptorContext]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_commitTransaction) name: EOAdaptorContextCommitTransactionNotification object: adaptorContext]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_rollbackTransaction) name: EOAdaptorContextRollbackTransactionNotification object: adaptorContext]; } - (id) initWithDatabase: (EODatabase *)database { //OK EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext",@"database=%p",database); if ((self = [self init])) { _adaptorContext = RETAIN([[database adaptor] createAdaptorContext]); if (_adaptorContext == nil) { NSLog(@"EODatabaseContext could not create adaptor context"); AUTORELEASE(self); return nil; } _database = RETAIN(database); // Register this object into database [_database registerContext: self]; [self setUpdateStrategy: EOUpdateWithOptimisticLocking]; _uniqueStack = [NSMutableArray new]; _deleteStack = [NSMutableArray new]; _uniqueArrayStack = [NSMutableArray new]; _registeredChannels = [NSMutableArray new]; _batchFaultBuffer = [NSMutableDictionary new]; _batchToManyFaultBuffer = [NSMutableDictionary new]; // We want to know when snapshots change in database [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_snapshotsChangedInDatabase:) name: EOObjectsChangedInStoreNotification object: _database]; // We want to know when objects change [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_objectsChanged:) name: EOObjectsChangedInStoreNotification object: self]; [self registerForAdaptorContextNotifications: _adaptorContext]; //??? /*NO _snapshots = [NSMutableDictionary new]; _toManySnapshots = [NSMutableDictionary new]; */ //NO _lock = [NSRecursiveLock new]; /* //TODO ? transactionStackTop = NULL; transactionNestingLevel = 0; isKeepingSnapshots = YES; isUniquingObjects = [database uniquesObjects]; [database contextDidInit:self];*/ } EOFLOGObjectFnStop(); return self; } - (void)_snapshotsChangedInDatabase: (NSNotification *)notification { //OK EOObjectsChangedInStoreNotification EODatabase EOFLOGObjectFnStart(); if ([notification object] == _database)//?? [[NSNotificationCenter defaultCenter] postNotificationName: [notification name] object: self userInfo: [notification userInfo]];//==> _objectsChanged EOFLOGObjectFnStop(); } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver: self]; [_database unregisterContext: self]; DESTROY(_adaptorContext); DESTROY(_database); if (_dbOperationsByGlobalID) { NSDebugMLog(@"MEMORY: dbOperationsByGlobalID count=%u", NSCountMapTable(_dbOperationsByGlobalID)); NSFreeMapTable(_dbOperationsByGlobalID); _dbOperationsByGlobalID = NULL; } /*NO DESTROY(_snapshots); DESTROY(_toManySnapshots); */ DESTROY(_uniqueStack); DESTROY(_deleteStack); DESTROY(_uniqueArrayStack); DESTROY(_registeredChannels); DESTROY(_batchFaultBuffer); DESTROY(_batchToManyFaultBuffer); DESTROY(_lastEntity); if (_nonPrimaryKeyGenerators) { NSDebugMLog(@"MEMORY: nonPrimaryKeyGnerators count=%u", NSCountHashTable(_nonPrimaryKeyGenerators)); NSFreeHashTable(_nonPrimaryKeyGenerators); _nonPrimaryKeyGenerators = NULL; } if (_lockedObjects) { NSResetHashTable(_lockedObjects); } DESTROY(_lock); [super dealloc]; } + (EODatabaseContext *)registeredDatabaseContextForModel: (EOModel *)model editingContext: (EOEditingContext *)editingContext { EOObjectStoreCoordinator *edObjectStore; NSArray *cooperatingObjectStores; NSEnumerator *storeEnum; EOCooperatingObjectStore *coObjectStore; EODatabase *anDatabase; NSArray *models; EODatabaseContext *dbContext = nil; EOFLOGClassFnStartOrCond2(@"DatabaseLevel", @"EODatabaseContext"); if (model && editingContext) { IMP enumNO=NULL; // nextObject edObjectStore = (EOObjectStoreCoordinator *)[editingContext rootObjectStore]; cooperatingObjectStores = [edObjectStore cooperatingObjectStores]; // get all EODatabaseContexts storeEnum = [cooperatingObjectStores objectEnumerator]; while ((coObjectStore = GDL2_NextObjectWithImpPtr(storeEnum,&enumNO))) { if ([coObjectStore isKindOfClass: [EODatabaseContext class]]) { anDatabase = [(EODatabaseContext *)coObjectStore database]; if (anDatabase && (models = [anDatabase models])) { if ([models containsObject: model]) { dbContext = (EODatabaseContext *)coObjectStore; break; } } } } if (!dbContext) { // no EODatabaseContext found, create a new one dbContext = [EODatabaseContext databaseContextWithDatabase: [EODatabase databaseWithModel: model]]; if (dbContext) { [edObjectStore addCooperatingObjectStore: dbContext]; } } } EOFLOGClassFnStopOrCond2(@"DatabaseLevel", @"EODatabaseContext"); return dbContext; } + (Class)contextClassToRegister { NSEmitTODO(); // TODO; return _contextClass; } + (void)setContextClassToRegister: (Class)contextClass { _contextClass = contextClass; } /** Returns YES if we have at least one busy channel **/ - (BOOL)hasBusyChannels { BOOL busy = NO; int count = 0; count = [_registeredChannels count]; if (count>0) { int i = 0; IMP oaiIMP=[_registeredChannels methodForSelector: @selector(objectAtIndex:)]; for (i = 0 ; !busy && i < count; i++) { EODatabaseChannel *channel = [GDL2_ObjectAtIndexWithImp(_registeredChannels,oaiIMP,i) nonretainedObjectValue]; busy = [channel isFetchInProgress]; } }; return busy; } - (NSArray *)registeredChannels { NSMutableArray *array = nil; int i, count; count = [_registeredChannels count]; array = [NSMutableArray arrayWithCapacity: count]; if (count>0) { IMP oaiIMP=[_registeredChannels methodForSelector: @selector(objectAtIndex:)]; for (i = 0; i < count; i++) [array addObject: [GDL2_ObjectAtIndexWithImp(_registeredChannels,oaiIMP,i) nonretainedObjectValue]]; }; return array; } - (void)registerChannel: (EODatabaseChannel *)channel { //call channel databaseContext //test if not exists _registeredChannels indexOfObjectIdenticalTo:channel NSDebugLog(@"** REGISTER channel ** debug:%d ** total registered:%d", [[channel adaptorChannel] isDebugEnabled], [_registeredChannels count] + 1); [_registeredChannels addObject: [NSValue valueWithNonretainedObject: channel]]; [channel setDelegate: nil]; } - (void)unregisterChannel: (EODatabaseChannel *)channel { int i; int count= [_registeredChannels count]; if (count>0) { IMP oaiIMP=[_registeredChannels methodForSelector: @selector(objectAtIndex:)]; for (i = count - 1; i >= 0; i--) { if ([GDL2_ObjectAtIndexWithImp(_registeredChannels,oaiIMP,i) nonretainedObjectValue] == channel) { [_registeredChannels removeObjectAtIndex: i]; break; } } }; } /** returns a non busy channel if any, nil otherwise **/ -(EODatabaseChannel *)_availableChannelFromRegisteredChannels { NSEnumerator *channelsEnum; NSValue *channel = nil; IMP enumNO=NULL; // nextObject channelsEnum = [_registeredChannels objectEnumerator]; NSDebugMLLog(@"EODatabaseContext",@"REGISTERED CHANNELS nb=%d", [_registeredChannels count]); while ((channel = GDL2_NextObjectWithImpPtr(channelsEnum,&enumNO))) { if ([(EODatabaseChannel *)[channel nonretainedObjectValue] isFetchInProgress] == NO) { NSDebugMLLog(@"EODatabaseContext",@"CHANNEL %p is not busy", [channel nonretainedObjectValue]); return [channel nonretainedObjectValue]; } else { NSDebugMLLog(@"EODatabaseContext",@"CHANNEL %p is busy", [channel nonretainedObjectValue]); } } return nil; } /** return a non busy channel **/ - (EODatabaseChannel *)availableChannel { EODatabaseChannel *channel = nil; int num = 2; while (!channel && num) { channel = [self _availableChannelFromRegisteredChannels]; if (!channel) { //If not channel and last try: send a EODatabaseChannelNeededNotification notification before this last try if (--num) [[NSNotificationCenter defaultCenter] postNotificationName: EODatabaseChannelNeededNotification object: self]; } } if (!channel) channel = [EODatabaseChannel databaseChannelWithDatabaseContext: self]; return channel; } /** returns the database **/ - (EODatabase *)database { return _database; } /** returns the coordinator **/ - (EOObjectStoreCoordinator *)coordinator { return _coordinator; } /** returns the adaptor context **/ - (EOAdaptorContext *)adaptorContext { return _adaptorContext; } /** Set the update strategy to 'strategy' May raise an exception if transaction has began or if you want pessimistic lock when there's already a snapshot recorded **/ - (void)setUpdateStrategy: (EOUpdateStrategy)strategy { if (_flags.beganTransaction) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: transaction in progress", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self]; //Can't set pessimistic locking where there's already snapshosts ! if (strategy == EOUpdateWithPessimisticLocking && [_database snapshots]) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: can't set EOUpdateWithPessimisticLocking when receive's EODatabase already has snapshots", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self]; _updateStrategy = strategy; } /** Get the update strategy **/ - (EOUpdateStrategy)updateStrategy { return _updateStrategy; } /** Get the delegate **/ - (id)delegate { return _delegate; } /** Set the delegate **/ - (void)setDelegate:(id)delegate { NSEnumerator *channelsEnum = [_registeredChannels objectEnumerator]; EODatabaseChannel *channel = nil; IMP enumNO=NULL; // nextObject _delegate = delegate; _delegateRespondsTo.willRunLoginPanelToOpenDatabaseChannel = [delegate respondsToSelector: @selector(databaseContext:willRunLoginPanelToOpenDatabaseChannel:)]; _delegateRespondsTo.newPrimaryKey = [delegate respondsToSelector: @selector(databaseContext:newPrimaryKeyForObject:entity:)]; _delegateRespondsTo.willPerformAdaptorOperations = [delegate respondsToSelector: @selector(databaseContext:willPerformAdaptorOperations:adaptorChannel:)]; _delegateRespondsTo.shouldInvalidateObject = [delegate respondsToSelector: @selector(databaseContext:shouldInvalidateObjectWithGlobalID:snapshot:)]; _delegateRespondsTo.willOrderAdaptorOperations = [delegate respondsToSelector: @selector(databaseContext:willOrderAdaptorOperationsFromDatabaseOperations:)]; _delegateRespondsTo.shouldLockObject = [delegate respondsToSelector: @selector(databaseContext:shouldLockObjectWithGlobalID:snapshot:)]; _delegateRespondsTo.shouldRaiseForLockFailure = [delegate respondsToSelector: @selector(databaseContext:shouldRaiseExceptionForLockFailure:)]; _delegateRespondsTo.shouldFetchObjects = [delegate respondsToSelector: @selector(databaseContext:shouldFetchObjectsWithFetchSpecification:editingContext:)]; _delegateRespondsTo.didFetchObjects = [delegate respondsToSelector: @selector(databaseContext:didFetchObjects:fetchSpecification:editingContext:)]; _delegateRespondsTo.shouldFetchObjectFault = [delegate respondsToSelector: @selector(databaseContext:shouldFetchObjectsWithFetchSpecification:editingContext:)]; _delegateRespondsTo.shouldFetchArrayFault = [delegate respondsToSelector: @selector(databaseContext:shouldFetchArrayFault:)]; while ((channel = GDL2_NextObjectWithImpPtr(channelsEnum,&enumNO))) [channel setDelegate: delegate]; } - (void)handleDroppedConnection { int i; EOFLOGObjectFnStartOrCond2(@"DatabaseLevel", @"EODatabaseContext"); DESTROY(_adaptorContext); for (i = [_registeredChannels count] - 1; i >= 0; i--) { RELEASE((EODatabaseChannel *)[[_registeredChannels objectAtIndex: i] nonretainedObjectValue]); } DESTROY(_registeredChannels); _adaptorContext = RETAIN([[[self database] adaptor] createAdaptorContext]); _registeredChannels = [NSMutableArray new]; EOFLOGObjectFnStopOrCond2(@"DatabaseLevel", @"EODatabaseContext"); } @end @implementation EODatabaseContext (EOObjectStoreSupport) /** Return a fault for row 'row' **/ - (id)faultForRawRow: (NSDictionary *)row entityNamed: (NSString *)entityName editingContext: (EOEditingContext *)context { EOEntity *entity; EOGlobalID *gid; id object; EOFLOGObjectFnStart(); entity = [_database entityNamed: entityName]; gid = [entity globalIDForRow: row]; object = [self faultForGlobalID: gid editingContext: context]; NSDebugMLLog(@"EODatabaseContext", @"object=%p of class (%@)", object, [object class]); EOFLOGObjectFnStop(); return object; } /** return entity corresponding to 'globalID' **/ - (id) entityForGlobalID: (EOGlobalID *)globalID { //OK NSString *entityName; EOEntity *entity; DESTROY(_lastEntity); entityName = [globalID entityName]; entity = [_database entityNamed: entityName]; ASSIGN(_lastEntity, entity); return entity; } /** Make object a fault **/ - (void) _turnToFault: (id)object gid: (EOGlobalID *)globalID editingContext: (EOEditingContext *)context isComplete: (BOOL)isComplete { //OK EOAccessFaultHandler *handler; EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"object=%p", object); NSDebugMLLog(@"EODatabaseContext", @"globalID=%@", globalID); NSAssert(globalID, @"No globalID"); NSAssert1([globalID isKindOfClass: [EOKeyGlobalID class]], @"globalID is not a EOKeyGlobalID but a %@", [globalID class]); if ([(EOKeyGlobalID*)globalID areKeysAllNulls]) NSWarnLog(@"All key of globalID %p (%@) are nulls", globalID, globalID); handler = [EOAccessFaultHandler accessFaultHandlerWithGlobalID: (EOKeyGlobalID*)globalID databaseContext: self editingContext: context]; NSDebugMLLog(@"EODatabaseContext", @"handler=%@", handler); NSDebugMLLog(@"EODatabaseContext", @"object->class_pointer=%p", GSObjCClass(object)); [EOFault makeObjectIntoFault: object withHandler: handler]; NSDebugMLLog(@"EODatabaseContext", @"object->class_pointer=%p", GSObjCClass(object)); [self _addBatchForGlobalID: (EOKeyGlobalID*)globalID fault: object]; EOFLOGObjectFnStop(); //TODO: use isComplete } /** Get a fault for 'globalID' **/ - (id)faultForGlobalID: (EOGlobalID *)globalID editingContext: (EOEditingContext *)context { //Seems OK EOClassDescription *classDescription = nil; EOEntity *entity; id object = nil; BOOL isFinal; EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"globalID=%@", globalID); isFinal = [(EOKeyGlobalID *)globalID isFinal]; entity = [self entityForGlobalID: globalID]; NSAssert(entity, @"no entity"); classDescription = [entity classDescriptionForInstances]; NSDebugMLLog(@"EODatabaseContext", @"classDescription=%@", classDescription); object = [classDescription createInstanceWithEditingContext: context globalID: globalID zone: NULL]; NSAssert1(object, @"No Object. classDescription=%@", classDescription); /*mirko: NO NSDictionary *pk; NSEnumerator *pkEnum; NSString *pkKey; NSArray *classPropertyNames; classPropertyNames = [entity classPropertyNames]; pk = [entity primaryKeyForGlobalID:(EOKeyGlobalID *)globalID]; pkEnum = [pk keyEnumerator]; while ((pkKey = [pkEnum nextObject])) { if ([classPropertyNames containsObject:pkKey] == YES) [obj takeStoredValue:[pk objectForKey:pkKey] forKey:pkKey]; } */ NSDebugMLLog(@"EODatabaseContext", @"object=%p", object); if ([(EOKeyGlobalID *)globalID areKeysAllNulls]) NSWarnLog(@"All key of globalID %p (%@) are nulls", globalID, globalID); [self _turnToFault: object gid: globalID editingContext: context isComplete: isFinal];//?? NSDebugMLLog(@"EODatabaseContext", @"Record Object"); EOEditingContext_recordObjectGlobalIDWithImpPtr(context,NULL,object,globalID); EOFLOGObjectFnStop(); return object; } /** Get an array fault for globalID for relationshipName **/ - (NSArray *)arrayFaultWithSourceGlobalID: (EOGlobalID *)globalID relationshipName: (NSString *)relationshipName editingContext: (EOEditingContext *)context { //Seems OK NSArray *obj = nil; if (![globalID isKindOfClass: [EOKeyGlobalID class]]) { [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ The globalID %@ must be an EOKeyGlobalID to be able to construct a fault", NSStringFromSelector(_cmd), NSStringFromClass([self class]), globalID]; } else { EOAccessArrayFaultHandler *handler = nil; obj = [EOCheapCopyMutableArray array]; handler = [EOAccessArrayFaultHandler accessArrayFaultHandlerWithSourceGlobalID: (EOKeyGlobalID*)globalID relationshipName: relationshipName databaseContext: self editingContext: context]; [EOFault makeObjectIntoFault: obj withHandler: handler]; [self _addToManyBatchForSourceGlobalID: (EOKeyGlobalID *)globalID relationshipName: relationshipName fault: (EOFault*)obj]; } return obj; } - (void)initializeObject: (id)object withGlobalID: (EOGlobalID *)globalID editingContext: (EOEditingContext *)context { //near OK EOEntity *entity = nil; EOFLOGObjectFnStart(); if ([globalID isTemporary]) { NSEmitTODO(); [self notImplemented: _cmd]; //TODO } if (![(EOKeyGlobalID *)globalID isFinal]) { NSEmitTODO(); [self notImplemented: _cmd]; //TODO } //mirko: if (_updateStrategy == EOUpdateWithPessimisticLocking) [self registerLockedObjectWithGlobalID: globalID]; entity = [self entityForGlobalID: globalID]; /*Mirko: if ([object respondsToSelector:@selector(entity)]) entity = [object entity]; else entity = [_database entityNamed:[globalID entityName]]; */ [self initializeObject: object row: EODatabaseContext_snapshotForGlobalIDWithImpPtr(self,NULL,globalID) //shound be _currentSnapshot entity: entity editingContext: context]; EOFLOGObjectFnStop(); } - (void) _objectsChanged: (NSNotification*)notification { EOFLOGObjectFnStart(); /*object==self EOObjectsChangedInStoreNotification userInfo = { deleted = (List Of GlobalIDs); inserted = (List Of GlobalIDs); updated = (List Of GlobalIDs); */ if ([notification object] != self) { NSEmitTODO(); [self notImplemented: _cmd]; //TODO } else { //OK for update //TODO-NOW for insert/delete NSDictionary *userInfo = [notification userInfo]; NSArray *updatedObjects = [userInfo objectForKey: EOUpdatedKey]; //NSArray *insertedObjects = [userInfo objectForKey: EOInsertedKey]; //NSArray *deletedObjects = [userInfo objectForKey: EODeletedKey]; int i, count = [updatedObjects count]; NSDebugMLLog(@"EODatabaseContext", @"updatedObjects=%@", updatedObjects); if (count>0) { IMP oaiIMP=[updatedObjects methodForSelector: @selector(objectAtIndex:)]; for (i = 0; i < count; i++) { EOKeyGlobalID *gid=GDL2_ObjectAtIndexWithImp(updatedObjects,oaiIMP,i); NSString *entityName; NSDebugMLLog(@"EODatabaseContext", @"gid=%@", gid); entityName = [gid entityName]; NSDebugMLLog(@"EODatabaseContext", @"entityName=%@", entityName); [_database invalidateResultCacheForEntityNamed: entityName]; } }; } EOFLOGObjectFnStop(); } - (void) _snapshotsChangedInDatabase: (NSNotification*)notification { EOFLOGObjectFnStart(); /* userInfo = { deleted = (List Of GlobalIDs); inserted = (List Of GlobalIDs); updated = (List Of GlobalIDs); }} */ if ([notification object] != self) { [[NSNotificationCenter defaultCenter] postNotificationName: EOObjectsChangedInStoreNotification object: self userInfo: [notification userInfo]]; //call _objectsChanged: and ObjectStoreCoordinator _objectsChangedInSubStore: } EOFLOGObjectFnStop(); } - (NSArray *)objectsForSourceGlobalID: (EOGlobalID *)globalID relationshipName: (NSString *)name editingContext: (EOEditingContext *)context { //Near OK NSArray *objects = nil; id sourceObjectFault = nil; id relationshipValue = nil; NSArray *sourceSnapshot = nil; int sourceSnapshotCount = 0; EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"globalID=%@", globalID); //First get the id from which we search the source object sourceObjectFault = [context faultForGlobalID: globalID editingContext: context]; NSDebugMLLog(@"EODatabaseContext", @"sourceObjectFault %p=%@", sourceObjectFault, sourceObjectFault); // Get the fault value from source object NSDebugMLLog(@"EODatabaseContext", @"relationshipName=%@", name); relationshipValue = [sourceObjectFault storedValueForKey: name]; NSDebugMLLog(@"EODatabaseContext", @"relationshipValue %p=%@", relationshipValue, relationshipValue); //Try to see if there is a snapshot for the source object sourceSnapshot = [_database snapshotForSourceGlobalID: globalID relationshipName: name]; NSDebugMLLog(@"EODatabaseContext", @"sourceSnapshot %p (%@)=%@", sourceSnapshot, [sourceSnapshot class], sourceSnapshot); sourceSnapshotCount = [sourceSnapshot count]; if (sourceSnapshotCount > 0) { EOGlobalID *snapGID = nil; id snapFault = nil; int i; IMP addObjectIMP=NULL; IMP oaiIMP=NULL; [EOFault clearFault: relationshipValue]; // Be carefull: Never call methodForSelector before clearing fault ! addObjectIMP=[relationshipValue methodForSelector:@selector(addObject:)]; oaiIMP=[sourceSnapshot methodForSelector: @selector(objectAtIndex:)]; for (i = 0; i < sourceSnapshotCount; i++) { snapGID = GDL2_ObjectAtIndexWithImp(sourceSnapshot,oaiIMP,i); NSDebugMLLog(@"EODatabaseContext", @"snapGID=%@", snapGID); snapFault = [context faultForGlobalID: snapGID editingContext: context]; NSDebugMLLog(@"EODatabaseContext", @"snapFault=%@", snapFault); GDL2_AddObjectWithImp(relationshipValue,addObjectIMP,snapFault); } objects = relationshipValue; } else { EOEntity *entity; EORelationship *relationship; unsigned int maxBatch = 0; BOOL isToManyToOne = NO; EOEntity *destinationEntity = nil; EOModel *destinationEntityModel = nil; NSArray *models = nil; EOQualifier *auxiliaryQualifier = nil; NSDictionary *contextSourceSnapshot = nil; id sourceObject = nil; EORelationship *inverseRelationship = nil; EOEntity *invRelEntity = nil; NSArray *invRelEntityClassProperties = nil; NSString *invRelName = nil; EOQualifier *qualifier = nil; EOFetchSpecification *fetchSpec = nil; // Get the source object entity entity = [self entityForGlobalID: globalID]; NSDebugMLLog(@"EODatabaseContext", @"entity name=%@", [entity name]); //Get the relationship named 'name' relationship = [entity relationshipNamed: name]; NSDebugMLLog(@"EODatabaseContext", @"relationship=%@", relationship); //Get the max number of fault to fetch maxBatch = [relationship numberOfToManyFaultsToBatchFetch]; isToManyToOne = [relationship isToManyToOne];//NO if (isToManyToOne) { NSEmitTODO(); [self notImplemented: _cmd]; //TODO if isToManyToOne } //Get the fault entity (aka relationsip destination entity) destinationEntity = [relationship destinationEntity]; NSDebugMLLog(@"EODatabaseContext", @"destinationEntity name=%@", [destinationEntity name]); //Get the destination entity model destinationEntityModel = [destinationEntity model]; //and _database model to verify if the destinationEntityModel is in database models models = [_database models]; if ([models indexOfObjectIdenticalTo: destinationEntityModel] == NSNotFound) { NSEmitTODO(); [self notImplemented: _cmd]; //TODO error } //Get the relationship qualifier if any auxiliaryQualifier = [relationship auxiliaryQualifier];//nil if (auxiliaryQualifier) { NSEmitTODO(); [self notImplemented: _cmd]; //TODO if auxqualif } //?? contextSourceSnapshot = EODatabaseContext_snapshotForGlobalIDWithImpPtr(self,NULL,globalID); //NSEmitTODO(); //TODO Why first asking for faultForGlobalID and now asking objectForGlobalID ?? sourceObject = [context objectForGlobalID: globalID]; NSDebugMLLog(@"EODatabaseContext", @"sourceObject=%@", sourceObject); inverseRelationship = [relationship inverseRelationship]; NSDebugMLLog(@"EODatabaseContext", @"inverseRelationship=%@", inverseRelationship); if (!inverseRelationship) { NSEmitTODO(); //[self notImplemented: _cmd]; //TODO if !inverseRelationship inverseRelationship = [relationship hiddenInverseRelationship]; //VERIFY (don't know if this is the good way) } invRelEntity = [inverseRelationship entity]; invRelEntityClassProperties = [invRelEntity classProperties]; invRelName = [inverseRelationship name]; NSDebugMLLog(@"EODatabaseContext", @"invRelName=%@", invRelName); NSDebugMLLog(@"EODatabaseContext", @"sourceObject=%@", sourceObject); qualifier = [EOKeyValueQualifier qualifierWithKey: invRelName operatorSelector: @selector(isEqualTo:) value: sourceObject]; NSDebugMLLog(@"EODatabaseContext", @"qualifier=%@", qualifier); fetchSpec = [EOFetchSpecification fetchSpecification]; [fetchSpec setQualifier: qualifier]; [fetchSpec setEntityName: [destinationEntity name]]; NSDebugMLLog(@"EODatabaseContext", @"fetchSpec=%@", fetchSpec); objects = [context objectsWithFetchSpecification: fetchSpec editingContext: context]; [self _registerSnapshot: objects forSourceGlobalID: globalID relationshipName: name editingContext: context];//OK } NSDebugMLLog(@"EODatabaseContext", @"objects=%@", objects); EOFLOGObjectFnStop(); return objects; } - (void)_registerSnapshot: (NSArray*)snapshot forSourceGlobalID: (EOGlobalID*)globalID relationshipName: (NSString*)name editingContext: (EOEditingContext*)context { //OK NSArray *gids; EOFLOGObjectFnStart(); gids = [context resultsOfPerformingSelector: @selector(globalIDForObject:) withEachObjectInArray: snapshot]; [_database recordSnapshot: gids forSourceGlobalID: globalID relationshipName: name]; EOFLOGObjectFnStop(); } - (void)refaultObject: object withGlobalID: (EOGlobalID *)globalID editingContext: (EOEditingContext *)context { EOFLOGObjectFnStart(); [EOObserverCenter suppressObserverNotification]; NS_DURING { [object clearProperties];//OK } NS_HANDLER { [EOObserverCenter enableObserverNotification]; NSDebugMLLog(@"EODatabaseContext", @"EXCEPTION %@", localException); [localException raise]; } NS_ENDHANDLER; [EOObserverCenter enableObserverNotification]; if ([(EOKeyGlobalID *)globalID areKeysAllNulls]) NSWarnLog(@"All key of globalID %p (%@) are nulls", globalID, globalID); [self _turnToFault: object gid: globalID editingContext: context isComplete: YES]; //Why YES ? [self forgetSnapshotForGlobalID:globalID]; EOFLOGObjectFnStop(); } - (void)saveChangesInEditingContext: (EOEditingContext *)context { //TODO: locks ? NSException *exception = nil; EOFLOGObjectFnStart(); [self prepareForSaveWithCoordinator: nil editingContext: context]; [self recordChangesInEditingContext]; NS_DURING { [self performChanges]; } NS_HANDLER { NSDebugMLog(@"EXCEPTION: %@", localException); exception = localException; } NS_ENDHANDLER; //I don't know if this is really the good place to catch exception and rollback... if (exception) { [self rollbackChanges]; [exception raise]; } else [self commitChanges]; EOFLOGObjectFnStop(); } - (void)_fetchRelationship: (EORelationship *)relationship withObjects: (NSArray *)objsArray editingContext: (EOEditingContext *)context { NSMutableArray *qualArray = nil; NSEnumerator *objEnum = nil; NSEnumerator *relEnum = nil; NSDictionary *snapshot = nil; id obj = nil; id relObj = nil; EOFLOGObjectFnStart(); if ([objsArray count] > 0) { IMP globalIDForObjectIMP=NULL; IMP enumNO=NULL; // nextObject qualArray = [NSMutableArray arrayWithCapacity: 5]; if ([relationship isFlattened] == YES) { NSDebugMLLog(@"EODatabaseContext", @"relationship %@ isFlattened", relationship); relEnum = [[relationship componentRelationships] objectEnumerator]; enumNO=NULL; while ((relationship = GDL2_NextObjectWithImpPtr(relEnum,&enumNO))) { // TODO rebuild object array for relationship path [self _fetchRelationship: relationship withObjects: objsArray editingContext: context]; } } objEnum = [objsArray objectEnumerator]; enumNO=NULL; while ((obj = GDL2_NextObjectWithImpPtr(objEnum,&enumNO))) { EOGlobalID* gid=nil; relObj = [obj storedValueForKey: [relationship name]]; gid = EOEditingContext_globalIDForObjectWithImpPtr(context,&globalIDForObjectIMP,relObj); snapshot = EODatabaseContext_snapshotForGlobalIDWithImpPtr(self,NULL,gid); [qualArray addObject: [relationship qualifierWithSourceRow: snapshot]]; } [self objectsWithFetchSpecification: [EOFetchSpecification fetchSpecificationWithEntityName: [[relationship destinationEntity] name] qualifier: [EOAndQualifier qualifierWithQualifierArray: qualArray] sortOrderings: nil] editingContext: context]; } EOFLOGObjectFnStop(); } - (NSArray *)objectsWithFetchSpecification: (EOFetchSpecification *)fetchSpecification editingContext: (EOEditingContext *)context { // TODO EODatabaseChannel *channel = nil; NSMutableArray *array = nil; NSDictionary *snapshot = nil; NSString *entityName = nil; EOEntity *entity = nil; NSString *relationshipKeyPath = nil; NSEnumerator *relationshipKeyPathEnum = nil; NSMutableArray *qualArray = nil; /*NSEnumerator *subEntitiesEnum = nil; EOEntity *subEntity = nil; NSArray *subEntities = nil;*/ NSArray* rawRowKeyPaths = nil; BOOL usesDistinct = NO; int num = 0; int limit=0; id obj = nil; EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"fetchSpecification=%@", fetchSpecification); if (_delegateRespondsTo.shouldFetchObjects == YES) { array = (id)[_delegate databaseContext: self shouldFetchObjectsWithFetchSpecification: fetchSpecification editingContext: context]; } if (!array) { IMP enumNO=NULL; // nextObject array = [NSMutableArray arrayWithCapacity: 8]; entityName = [fetchSpecification entityName];//OK entity = [_database entityNamed: entityName];//OK NSAssert1(entity,@"No entity named %@", entityName); /* moved in EODatabaseChannel _selectWithFetchSpecification:(EOFetchSpecification *)fetchSpecification editingContext:(EOEditingContext *)context limit = [fetchSpecification fetchLimit]; usesDistinct = [fetchSpecification usesDistinct]; subEntities = [entity subEntities]; if ([subEntities count] && [fetchSpecification isDeep] == YES) { subEntitiesEnum = [subEntities objectEnumerator]; while ((subEntity = [subEntitiesEnum nextObject])) { EOFetchSpecification *fetchSubEntity; fetchSubEntity = AUTORELEASE([fetchSpecification copy]); [fetchSubEntity setEntityName:[entity name]]; [array addObjectsFromArray:[context objectsWithFetchSpecification: fetchSubEntity]]; } } */ rawRowKeyPaths = [fetchSpecification 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 (!channel) { NSEmitTODO(); [self notImplemented: _cmd];//TODO } else { NSDebugMLLog(@"EODatabaseContext", @"channel class %@ [channel isFetchInProgress]=%s", [channel class], ([channel isFetchInProgress] ? "YES" : "NO")); //mirko: #if 0 if (_flags.beganTransaction == NO && _updateStrategy == EOUpdateWithPessimisticLocking) { [_adaptorContext beginTransaction]; NSDebugMLLog(@"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: fetchSpecification editingContext: context];//OK NSDebugMLLog(@"EODatabaseContext", @"[channel isFetchInProgress]=%s", ([channel isFetchInProgress] ? "YES" : "NO")); limit = [fetchSpecification fetchLimit];//OK promptsAfterFetchLimit = [fetchSpecification promptsAfterFetchLimit]; NSDebugMLLog(@"EODatabaseContext", @"Will Fetch"); NS_DURING { IMP channelFetchObjectIMP= [channel methodForSelector:@selector(fetchObject)]; IMP arrayAddObjectIMP= [array methodForSelector:@selector(addObject:)]; GDL2IMP_UINT arrayIndexOfObjectIdenticalToIMP= (GDL2IMP_UINT)[array methodForSelector:@selector(indexOfObjectIdenticalTo:)]; arp = GDL2_NSAutoreleasePool_new(); NSDebugMLLog(@"EODatabaseContext", @"[channel isFetchInProgress]=%s", ([channel isFetchInProgress] ? "YES" : "NO")); while ((obj = (*channelFetchObjectIMP)(channel,@selector(fetchObject)))) { NSDebugMLLog(@"EODatabaseContext", @"fetched an object"); NSDebugMLLog(@"EODatabaseContext", @"FETCH OBJECT object=%@\n", obj); NSDebugMLLog(@"EODatabaseContext", @"%d usesDistinct: %s", num, (usesDistinct ? "YES" : "NO")); NSDebugMLLog(@"EODatabaseContext", @"object=%@\n\n", obj); if (usesDistinct == YES && num > 0 && GDL2_IndexOfObjectIdenticalToWithImp(array,arrayIndexOfObjectIdenticalToIMP,obj)!=NSNotFound) // (stephane@sente) I thought that DISTINCT was done on server-side?!? { obj = nil; } else { NSDebugMLLog(@"EODatabaseContext", @"AFTER FETCH"); GDL2_AddObjectWithImp(array,arrayAddObjectIMP,obj); NSDebugMLLog(@"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 { DESTROY(arp); break; }; }; }; if (autoreleaseStep <= 0) { DESTROY(arp); autoreleaseStep = autoreleaseSteps; arp = GDL2_NSAutoreleasePool_new(); } else autoreleaseStep--; NSDebugMLLog(@"EODatabaseContext", @"WILL FETCH NEXT OBJECT"); NSDebugMLLog(@"EODatabaseContext", @"[channel isFetchInProgress]=%s", ([channel isFetchInProgress] ? "YES" : "NO")); } NSDebugMLLog(@"EODatabaseContext", @"finished fetch"); NSDebugMLLog(@"EODatabaseContext", @"array=%@", array); NSDebugMLLog(@"EODatabaseContext", @"step 0 channel is busy=%d", (int)[channel isFetchInProgress]); [channel cancelFetch]; //OK NSDebugMLLog(@"EODatabaseContext", @"step 1 channel is busy=%d", (int)[channel isFetchInProgress]); NSDebugMLLog(@"EODatabaseContext", @"array=%@", array); //TODO /* handle exceptio in fetchObject channel fetchObject if eception: if ([editcontext handleError:localException]) { //TODO } else { //TODO }; */ DESTROY(arp); } NS_HANDLER { NSDebugMLLog(@"EODatabaseContext", @"AN EXCEPTION: %@", localException); RETAIN(localException); DESTROY(arp); AUTORELEASE(localException); [localException raise]; } NS_ENDHANDLER; } } NSDebugMLLog(@"EODatabaseContext", @"step 2 channel is busy=%d", (int)[channel isFetchInProgress]); } #endif else if ([entity cachesObjects] == YES)//OK { ///TODO MG!!! NSMutableArray *cache; EOQualifier *qualifier; EOGlobalID *gid; BOOL isFault; qualifier = [fetchSpecification qualifier]; cache = (id)[_database resultCacheForEntityNamed: entityName]; if (cache == nil) { NSMutableDictionary *row = nil; EOAdaptorChannel *adaptorChannel = nil; IMP channelFetchRowWithZoneIMP=NULL; IMP entityGlobalIDForRowIMP=[entity methodForSelector:@selector(globalIDForRow:)]; IMP databaseRecordSnapshotForGlobalID=[_database methodForSelector:@selector(recordSnapshot:forGlobalID:)]; IMP cacheAddObjectIMP=NULL; channel = [self availableChannel]; adaptorChannel = [channel adaptorChannel]; channelFetchRowWithZoneIMP= [adaptorChannel methodForSelector:@selector(fetchRowWithZone:)]; if (_flags.beganTransaction == NO && _updateStrategy == EOUpdateWithPessimisticLocking) { [_adaptorContext beginTransaction]; NSDebugMLLog(@"EODatabaseContext", @"BEGAN TRANSACTION FLAG==>YES"); _flags.beganTransaction = YES; } [adaptorChannel selectAttributes: [entity attributesToFetch] fetchSpecification: [EOFetchSpecification fetchSpecificationWithEntityName: entityName qualifier: nil sortOrderings: nil] lock: NO entity: entity]; cache = [NSMutableArray arrayWithCapacity: 16]; cacheAddObjectIMP=[cache methodForSelector:@selector(addObject:)]; while ((row = (*channelFetchRowWithZoneIMP) (adaptorChannel,@selector(fetchRowWithZone:),NULL))) { NSDebugMLLog(@"EODatabaseContext", @"row=%@", row); gid = (*entityGlobalIDForRowIMP)(entity,@selector(globalIDForRow:),row); NSDebugMLLog(@"EODatabaseContext", @"gid=%@", gid); (*databaseRecordSnapshotForGlobalID) (_database,@selector(recordSnapshot:forGlobalID:),row,gid); GDL2_AddObjectWithImp(cache,cacheAddObjectIMP,gid); } NSDebugMLLog(@"EODatabaseContext", @"Finished fetch"); [channel cancelFetch]; NSDebugMLLog(@"EODatabaseContext", @"setResultCache"); [_database setResultCache: cache forEntityNamed: entityName]; } if ([cache count]>0) { IMP arrayAddObjectIMP= [array methodForSelector:@selector(addObject:)]; GDL2IMP_UINT arrayIndexOfObjectIdenticalToIMP= (GDL2IMP_UINT)[array methodForSelector:@selector(indexOfObjectIdenticalTo:)]; NSEnumerator *cacheEnum = [cache objectEnumerator]; IMP cacheEnumNextObjectIMP=[cacheEnum methodForSelector:@selector(nextObject)]; EOClassDescription* classDescriptionForInstances= [entity classDescriptionForInstances]; GDL2IMP_BOOL qualifierEvaluateWithObjectIMP= (GDL2IMP_BOOL)[qualifier methodForSelector:@selector(evaluateWithObject:)]; IMP ecObjectForGlobalIDIMP=NULL; IMP ecRecordObjectGlobalIDIMP=NULL; while ((gid = GDL2_NextObjectWithImp(cacheEnum,cacheEnumNextObjectIMP))) { NSDebugMLLog(@"EODatabaseContext", @"gid=%@", gid); snapshot = EODatabaseContext_snapshotForGlobalIDWithImpPtr(self,NULL,gid); if (snapshot) { if (!qualifier || (*qualifierEvaluateWithObjectIMP)(qualifier,@selector(evaluateWithObject:),snapshot) == YES) { obj = EOEditingContext_objectForGlobalIDWithImpPtr(context,&ecObjectForGlobalIDIMP,gid); isFault = _isFault(obj); if (obj == nil || isFault == YES) { if (isFault == NO) { obj = [classDescriptionForInstances createInstanceWithEditingContext: context globalID: gid zone: NULL]; NSAssert1(obj, @"No Object. [entity classDescriptionForInstances]=%@", [entity classDescriptionForInstances]); EOEditingContext_recordObjectGlobalIDWithImpPtr(context,&ecRecordObjectGlobalIDIMP,obj,gid); } else { [self _removeBatchForGlobalID: (EOKeyGlobalID *)gid fault: obj]; [EOFault clearFault: obj]; } [context initializeObject: obj withGlobalID: gid editingContext: context]; [obj awakeFromFetchInEditingContext: context]; } if (usesDistinct == YES && num > 0 && GDL2_IndexOfObjectIdenticalToWithImp(array,arrayIndexOfObjectIdenticalToIMP,obj)!=NSNotFound) { obj = nil; } else { GDL2_AddObjectWithImp(array,arrayAddObjectIMP,obj); num++; if (limit && num >= limit) { if ([[context messageHandler] editingContext: context shouldContinueFetchingWithCurrentObjectCount: num originalLimit: limit objectStore: self] == YES) limit = 0; else break; } }; }; } } } NSDebugMLLog(@"EODatabaseContext", @"array before sort: %@", array); if ([fetchSpecification sortOrderings]) array = (id)[array sortedArrayUsingKeyOrderArray: [fetchSpecification sortOrderings]]; } else { //cachesObject //fetchspe isDeep ret 1 channel = [self _obtainOpenChannel]; if (!channel) { NSEmitTODO(); [self notImplemented: _cmd];//TODO } else { NSDebugMLLog(@"EODatabaseContext", @"channel class %@ [channel isFetchInProgress]=%s", [channel class], ([channel isFetchInProgress] ? "YES" : "NO")); //mirko: if (_flags.beganTransaction == NO && _updateStrategy == EOUpdateWithPessimisticLocking) { [_adaptorContext beginTransaction]; NSDebugMLLog(@"EODatabaseContext", @"BEGAN TRANSACTION FLAG==>YES"); _flags.beganTransaction = YES; } if ([entity isAbstractEntity] == NO) //Mirko ??? { 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: fetchSpecification editingContext: context];//OK NSDebugMLLog(@"EODatabaseContext", @"[channel isFetchInProgress]=%s", ([channel isFetchInProgress] ? "YES" : "NO")); limit = [fetchSpecification fetchLimit];//OK promptsAfterFetchLimit = [fetchSpecification promptsAfterFetchLimit]; NSDebugMLLog(@"EODatabaseContext", @"Will Fetch"); NS_DURING { IMP channelFetchObjectIMP= [channel methodForSelector:@selector(fetchObject)]; IMP arrayAddObjectIMP= [array methodForSelector:@selector(addObject:)]; GDL2IMP_UINT arrayIndexOfObjectIdenticalToIMP= (GDL2IMP_UINT)[array methodForSelector:@selector(indexOfObjectIdenticalTo:)]; arp = GDL2_NSAutoreleasePool_new(); NSDebugMLLog(@"EODatabaseContext", @"[channel isFetchInProgress]=%s", ([channel isFetchInProgress] ? "YES" : "NO")); while ((obj = (*channelFetchObjectIMP)(channel,@selector(fetchObject)))) { NSDebugMLLog(@"EODatabaseContext", @"fetched an object"); NSDebugMLLog(@"EODatabaseContext", @"FETCH OBJECT object=%@\n", obj); NSDebugMLLog(@"EODatabaseContext", @"%d usesDistinct: %s", num, (usesDistinct ? "YES" : "NO")); NSDebugMLLog(@"EODatabaseContext", @"object=%@\n\n", obj); if (usesDistinct == YES && num > 0 && GDL2_IndexOfObjectIdenticalToWithImp(array,arrayIndexOfObjectIdenticalToIMP,obj)!=NSNotFound) { NSDebugMLLog(@"EODatabaseContext", @"Already fetched object=%@\n\n", obj); obj = nil; } else { NSDebugMLLog(@"EODatabaseContext", @"AFTER FETCH"); NSAssert(obj,@"No object"); GDL2_AddObjectWithImp(array,arrayAddObjectIMP,obj); NSDebugMLLog(@"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 = GDL2_NSAutoreleasePool_new(); } else autoreleaseStep--; NSDebugMLLog(@"EODatabaseContext", @"WILL FETCH NEXT OBJECT"); NSDebugMLLog(@"EODatabaseContext", @"[channel isFetchInProgress]=%s", ([channel isFetchInProgress] ? "YES" : "NO")); } NSDebugMLLog(@"EODatabaseContext", @"finished fetch"); NSDebugMLLog(@"EODatabaseContext", @"array=%@", array); NSDebugMLLog(@"EODatabaseContext", @"step 0 channel is busy=%d", (int)[channel isFetchInProgress]); [channel cancelFetch]; //OK NSDebugMLLog(@"EODatabaseContext", @"step 1 channel is busy=%d", (int)[channel isFetchInProgress]); NSDebugMLLog(@"EODatabaseContext", @"array=%@", array); //TODO /* handle exceptio in fetchObject channel fetchObject if eception: if ([editcontext handleError:localException]) { //TODO } else { //TODO }; */ DESTROY(arp); } NS_HANDLER { NSDebugMLLog(@"EODatabaseContext", @"AN EXCEPTION: %@", localException); RETAIN(localException); DESTROY(arp); AUTORELEASE(localException); [localException raise]; } NS_ENDHANDLER; } } NSDebugMLLog(@"EODatabaseContext", @"step 2 channel is busy=%d", (int)[channel isFetchInProgress]); } //VERIFY NSDebugMLLog(@"EODatabaseContext", @"array before prefetchingRelationshipKeyPaths: %@", array); if ([fetchSpecification prefetchingRelationshipKeyPaths]) //OK qualArray = [NSMutableArray arrayWithCapacity: 5]; relationshipKeyPathEnum = [[fetchSpecification prefetchingRelationshipKeyPaths] objectEnumerator]; enumNO=NULL; while ((relationshipKeyPath = GDL2_NextObjectWithImpPtr(relationshipKeyPathEnum,&enumNO))) { IMP rkeyEnumNO=NULL; // nextObject NSArray *relationshipKeyArray = [relationshipKeyPath componentsSeparatedByString: @"."]; NSEnumerator *relationshipKeyEnum; EORelationship *relationship; EOEntity *currentEntity = entity; NSString *relationshipKey; relationshipKeyEnum = [relationshipKeyArray objectEnumerator]; while ((relationshipKey = GDL2_NextObjectWithImpPtr(relationshipKeyEnum,&rkeyEnumNO))) { relationship = [currentEntity relationshipNamed: relationshipKey]; currentEntity = [relationship destinationEntity]; // TODO rebuild object array for relationship path [self _fetchRelationship: relationship withObjects: array editingContext: context]; } } if (_delegateRespondsTo.didFetchObjects == YES) [_delegate databaseContext: self didFetchObjects: array fetchSpecification: fetchSpecification editingContext: context]; NSDebugMLLog(@"EODatabaseContext",@"step 1 channel is busy=%d", (int)[channel isFetchInProgress]); } //NSDebugMLLog(@"EODatabaseContext", @"array: %@", array); EOFLOGObjectFnStop(); return array; } - (BOOL)isObjectLockedWithGlobalID: (EOGlobalID *)gid editingContext: (EOEditingContext *)context { return [self isObjectLockedWithGlobalID: gid]; } - (void)lockObjectWithGlobalID: (EOGlobalID *)globalID editingContext: (EOEditingContext *)context { // TODO EOKeyGlobalID *gid = (EOKeyGlobalID *)globalID; EODatabaseChannel *channel; EOEntity *entity; NSArray *attrsUsedForLocking, *primaryKeyAttributes; NSDictionary *snapshot; NSMutableDictionary *qualifierSnapshot, *lockSnapshot; NSMutableArray *lockAttributes; NSEnumerator *attrsEnum; EOQualifier *qualifier = nil; EOAttribute *attribute; if ([self isObjectLockedWithGlobalID: gid] == NO) { IMP enumNO=NULL; // nextObject snapshot = EODatabaseContext_snapshotForGlobalIDWithImpPtr(self,NULL,gid); if (_delegateRespondsTo.shouldLockObject == YES && [_delegate databaseContext: self shouldLockObjectWithGlobalID: gid snapshot: snapshot] == NO) return; /* If we do not have a snapshot yet, the the object is probably faulted. The reference implementation seems to ignore the lock in this case. We will try to do better and if we can't, we'll acually raise as documented. */ if (snapshot == nil) { id obj = [context objectForGlobalID: gid]; if ([EOFault isFault: obj]) [obj self]; snapshot = [self snapshotForGlobalID: gid]; } NSAssert1(snapshot,@"Could not obtain snapshot for %@", gid); channel = [self availableChannel]; entity = [_database entityNamed: [gid entityName]]; NSAssert1(entity, @"No entity named %@", [gid entityName]); attrsUsedForLocking = [entity attributesUsedForLocking]; primaryKeyAttributes = [entity primaryKeyAttributes]; qualifierSnapshot = [NSMutableDictionary dictionaryWithCapacity: 16]; lockSnapshot = [NSMutableDictionary dictionaryWithCapacity: 8]; lockAttributes = [NSMutableArray arrayWithCapacity: 8]; attrsEnum = [primaryKeyAttributes objectEnumerator]; enumNO=NULL; while ((attribute = GDL2_NextObjectWithImpPtr(attrsEnum,&enumNO))) { NSString *name = [attribute name]; [lockSnapshot setObject: [snapshot objectForKey:name] forKey: name]; } attrsEnum = [attrsUsedForLocking objectEnumerator]; enumNO=NULL; while ((attribute = GDL2_NextObjectWithImpPtr(attrsEnum,&enumNO))) { NSString *name = [attribute name]; if ([primaryKeyAttributes containsObject:attribute] == NO) { if ([attribute adaptorValueType] == EOAdaptorBytesType) { [lockAttributes addObject: attribute]; [lockSnapshot setObject: [snapshot objectForKey:name] forKey: name]; } else [qualifierSnapshot setObject: [snapshot objectForKey:name] forKey: name]; } } // Turbocat if ([[qualifierSnapshot allKeys] count] > 0) qualifier = [EOAndQualifier qualifierWithQualifiers: [entity qualifierForPrimaryKey: [entity primaryKeyForGlobalID: gid]], [EOQualifier qualifierToMatchAllValues: qualifierSnapshot], nil]; if ([lockAttributes count] == 0) lockAttributes = nil; if ([lockSnapshot count] == 0) lockSnapshot = nil; if (_flags.beganTransaction == NO) { [[[channel adaptorChannel] adaptorContext] beginTransaction]; NSDebugMLLog(@"EODatabaseContext", @"BEGAN TRANSACTION FLAG==>YES"); _flags.beganTransaction = YES; } NS_DURING [[channel adaptorChannel] lockRowComparingAttributes: lockAttributes entity: entity qualifier: qualifier snapshot: lockSnapshot]; NS_HANDLER { if (_delegateRespondsTo.shouldRaiseForLockFailure == YES) { if ([_delegate databaseContext: self shouldRaiseExceptionForLockFailure:localException] == YES) [localException raise]; } else [localException raise]; } NS_ENDHANDLER; [self registerLockedObjectWithGlobalID: gid]; } } - (void)invalidateAllObjects { NSDictionary *snapshots; NSArray *gids; [_database invalidateResultCache]; snapshots = [_database snapshot]; gids = [snapshots allKeys]; [self invalidateObjectsWithGlobalIDs: gids]; [[NSNotificationCenter defaultCenter] postNotificationName: EOInvalidatedAllObjectsInStoreNotification object: self]; } - (void)invalidateObjectsWithGlobalIDs: (NSArray *)globalIDs { NSMutableArray *array = nil; NSEnumerator *enumerator; EOKeyGlobalID *gid; if (_delegateRespondsTo.shouldInvalidateObject == YES) { IMP enumNO=NULL; // nextObject array = [NSMutableArray array]; enumerator = [globalIDs objectEnumerator]; while ((gid = GDL2_NextObjectWithImpPtr(enumerator,&enumNO))) { if ([_delegate databaseContext: self shouldInvalidateObjectWithGlobalID: gid snapshot: EODatabaseContext_snapshotForGlobalIDWithImpPtr(self,NULL,gid)] == YES) [array addObject: gid]; } } [self forgetSnapshotsForGlobalIDs: ((id)array ? (id)array : globalIDs)]; } @end @implementation EODatabaseContext(EOCooperatingObjectStoreSupport) - (BOOL)ownsGlobalID: (EOGlobalID *)globalID { if ([globalID isKindOfClass: [EOKeyGlobalID class]] && [_database entityNamed: [globalID entityName]]) return YES; return NO; } - (BOOL)ownsObject: (id)object { if ([_database entityForObject: object]) return YES; return NO; } - (BOOL)ownsEntityNamed: (NSString *)entityName { if ([_database entityNamed: entityName]) return YES; return NO; } - (BOOL)handlesFetchSpecification: (EOFetchSpecification *)fetchSpecification { //OK if ([_database entityNamed: [fetchSpecification entityName]]) return YES; else return NO; } /* //Mirko: - (EODatabaseOperation *)_dbOperationWithObject:object operator:(EODatabaseOperator)operator { NSMapEnumerator gidEnum; EODatabaseOperation *op; EOGlobalID *gid; gidEnum = NSEnumerateMapTable(_dbOperationsByGlobalID); while (NSNextMapEnumeratorPair(&gidEnum, (void **)&gid, (void **)&op)) { if ([[op object] isEqual:object] == YES) { if ([op databaseOperator] == operator) return op; return nil; } } return nil; } - (void)_setGlobalID:(EOGlobalID *)globalID forDatabaseOperation:(EODatabaseOperation *)op { EOGlobalID *oldGlobalID = [op globalID]; [op _setGlobalID:globalID]; NSMapInsert(_dbOperationsByGlobalID, globalID, op); NSMapRemove(_dbOperationsByGlobalID, oldGlobalID); } - (EODatabaseOperation *)_dbOperationWithGlobalID:(EOGlobalID *)globalID object:object entity:(EOEntity *)entity operator:(EODatabaseOperator)operator { EODatabaseOperation *op; NSMutableDictionary *newRow; NSMapEnumerator gidEnum; EOAttribute *attribute; EOGlobalID *gid; NSString *key; NSArray *classProperties; BOOL found = NO; int i, count; id val; gidEnum = NSEnumerateMapTable(_dbOperationsByGlobalID); while (NSNextMapEnumeratorPair(&gidEnum, (void **)&gid, (void **)&op)) { if ([[op object] isEqual:object] == YES) { found = YES; break; } } if (found == YES) return op; if (globalID == nil) globalID = AUTORELEASE([[EOTemporaryGlobalID alloc] init]); op = AUTORELEASE([[EODatabaseOperation alloc] initWithGlobalID:globalID object:object entity:entity]); [op setDatabaseOperator:operator]; [op setDBSnapshot:EODatabaseContext_snapshotForGlobalIDWithImpPtr(self,NULL,globalID)]; newRow = [op newRow]; classProperties = [entity classProperties]; count = [classProperties count]; if (count>0) { IMP oaiIMP=[classProperties methodForSelector: @selector(objectAtIndex:)]; for (i = 0; i < count; i++) { attribute = GDL2_ObjectAtIndexWithImp(classProperties,oaiIMP,i); if ([attribute isKindOfClass:GDL2_EOAttributeClass] == NO) continue; key = [attribute name]; if ([attribute isFlattened] == NO) { val = [object storedValueForKey:key]; if (val == nil) val = GDL2_EONull; [newRow setObject:val forKey:key]; } } }; NSMapInsert(_dbOperationsByGlobalID, globalID, op); return op; } */ // Prepares to save changes. Obtains primary keys for any inserted objects // in the EditingContext that are owned by this context. - (void)prepareForSaveWithCoordinator: (EOObjectStoreCoordinator *)coordinator editingContext: (EOEditingContext *)context { //near OK //Ayers: Review NSArray *insertedObjects = nil; NSMutableArray *noPKObjects = nil; int round = 0; EOFLOGObjectFnStart(); NSAssert(context, @"No editing context"); _flags.preparingForSave = YES; _coordinator=coordinator;//RETAIN ? _editingContext=context;//RETAIN ? // First, create dbOperation map if there's none if (!_dbOperationsByGlobalID) _dbOperationsByGlobalID = NSCreateMapTable(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 32); // Next, build list of Entity which need PK generator [self _buildPrimaryKeyGeneratorListForEditingContext: context]; // Now get newly inserted objects // For each object, we will recordInsertForObject: and relay PK if it is !nil insertedObjects = [context insertedObjects]; // We can make 2 rounds to try to get primary key for dependant objects for(round=0;round<2;round++) { NSDebugMLLog(@"EODatabaseContext", @"round=%d [noPKObjects count]=%d", round, [noPKObjects count]); if (round==1 && [noPKObjects count]==0) break; else { NSArray* array=nil; int i = 0; int count = 0; if (round==0) array=insertedObjects; else { array=noPKObjects; NSDebugMLLog(@"EODatabaseContext",@"noPKObjects=%@", noPKObjects); } count = [array count]; if (count>0) { IMP oaiIMP=[array methodForSelector: @selector(objectAtIndex:)]; for (i = 0; i < count; i++) { id object = GDL2_ObjectAtIndexWithImp(array,oaiIMP,i); NSDebugMLLog(@"EODatabaseContext",@"object=%@",object); if ([self ownsObject:object]) { NSDictionary *objectPK = nil; EODatabaseOperation *dbOpe = nil; NSMutableDictionary *newRow = nil; EOEntity *entity = [_database entityForObject:object]; if (round==0) [self recordInsertForObject: object]; objectPK = [self _primaryKeyForObject: object raiseException: round>0]; NSDebugMLLog(@"EODatabaseContext",@"objectPK=%@", objectPK); if (objectPK) { dbOpe = [self databaseOperationForObject: object]; NSDebugMLLog(@"EODatabaseContext", @"object=%p dbOpe=%@", object,dbOpe); newRow=[dbOpe newRow]; NSDebugMLLog(@"EODatabaseContext", @"newRow=%@", newRow); [self relayPrimaryKey: objectPK object: object entity: entity]; if (round>0) { [noPKObjects removeObjectAtIndex:i]; i--; }; } else if (round>0) { if (!noPKObjects) noPKObjects=(NSMutableArray*)[NSMutableArray array]; [noPKObjects addObject:object]; } }; } } } } EOFLOGObjectFnStop(); } - (void)recordChangesInEditingContext { IMP selfGIDFO=NULL; // _globalIDForObject: int which = 0; int c=0; int i=0; NSArray *objects[3] = {nil, nil, nil}; EOFLOGObjectFnStart(); [self _assertValidStateWithSelector: @selector(recordChangesInEditingContext)]; NSAssert(_editingContext, @"No editing context"); // We'll examin object in the following order: // insertedObjects, // deletedObjects (because re-inserted object should be removed from deleteds) // updatedObjects (because inserted/deleted objects may cause some other objects to be updated). NSMutableArray* recordToManySnapshot_dbOpes=[NSMutableArray array]; NSMutableArray* recordToManySnapshot_valuesGIDs=[NSMutableArray array]; NSMutableArray* recordToManySnapshot_relationshipNames=[NSMutableArray array]; NSMutableArray* nullifyAttributesInRelationship_relationships=[NSMutableArray array]; NSMutableArray* nullifyAttributesInRelationship_sourceObjects=[NSMutableArray array]; NSMutableArray* nullifyAttributesInRelationship_destinationObjects=[NSMutableArray array]; NSMutableArray* relayAttributesInRelationship_relationships=[NSMutableArray array]; NSMutableArray* relayAttributesInRelationship_sourceObjects=[NSMutableArray array]; NSMutableArray* relayAttributesInRelationship_destinationObjects=[NSMutableArray array]; for (which = 0; which < 3; which++) { int count = 0; NSDebugMLLog(@"EODatabaseContext", @"Unprocessed: %@", [_editingContext unprocessedDescription]); NSDebugMLLog(@"EODatabaseContext", @"Objects: %@", [_editingContext objectsDescription]); NSDebugMLLog(@"EODatabaseContext", @"which=%d", which); if (which == 0) objects[which] = [_editingContext insertedObjects]; else if (which == 1) objects[which] = [_editingContext deletedObjects]; else objects[which] = [_editingContext updatedObjects]; count = [objects[which] count]; NSDebugMLLog(@"EODatabaseContext", @"objects count[%d]=%d", which, count); NSDebugMLLog(@"EODatabaseContext", @"objects[%d]=%@", which, objects[which]); if (count>0) { IMP oaiIMP=[objects[which] methodForSelector: @selector(objectAtIndex:)]; int i = 0; // For each object for (i = 0; i < count; i++) { NSDictionary *currentCommittedSnapshot = nil; NSArray *relationships = nil; EODatabaseOperation *dbOpe = nil; EOEntity *entity = nil; id object = GDL2_ObjectAtIndexWithImp(objects[which],oaiIMP,i); int relationshipsCount = 0; IMP relObjectAtIndexIMP= NULL; //Mirko ?? if ([self ownsObject:object] == YES) NSDebugMLLog(@"EODatabaseContext", @"object %p (class=%@):\n%@", object, [object class], object); entity = [_database entityForObject: object]; //OK for Update if (which == 0 || which == 2)//insert or update { NSDictionary *pk = nil; NSDictionary *snapshot; [self recordUpdateForObject: object //Why ForUpdate ? Becuase PK already generated ? changes: nil]; //OK for update // Get a dictionary of object properties+PK+relationships CURRENT values snapshot = [object snapshot]; //OK for Update+Insert NSDebugMLLog(@"EODatabaseContext", @"snapshot %p: %@", snapshot, snapshot); NSDebugMLLog(@"EODatabaseContext", @"currentCommittedSnapshot %p: %@", currentCommittedSnapshot, currentCommittedSnapshot); // Get a dictionary of object properties+PK+relationships DATABASES values if (!currentCommittedSnapshot) currentCommittedSnapshot = [self _currentCommittedSnapshotForObject:object]; //OK For Update NSDebugMLLog(@"EODatabaseContext", @"currentCommittedSnapshot %p: %@", currentCommittedSnapshot, currentCommittedSnapshot); //TODO so what ? // Get the PK pk = [self _primaryKeyForObject: object];//OK for Update NSDebugMLLog(@"EODatabaseContext", @"pk=%@", pk); if (pk) [self relayPrimaryKey: pk object: object entity: entity]; //OK for Update } relationships = [entity relationships]; //OK for Update NSDebugMLLog(@"EODatabaseContext",@"object=%p relationships: %@", object,relationships); relationshipsCount = [relationships count]; relObjectAtIndexIMP=[relationships methodForSelector: @selector(objectAtIndex:)]; if (which == 1) //delete //Not in insert //not in update { if (relationshipsCount>0) { int iRelationship = 0; for (iRelationship = 0; iRelationship < relationshipsCount; iRelationship++) { EORelationship *relationship = GDL2_ObjectAtIndexWithImp(relationships,relObjectAtIndexIMP,iRelationship); if ([relationship isToManyToOne]) { NSEmitTODO(); [self notImplemented: _cmd]; //TODO } } }; NSDebugMLLog(@"EODatabaseContext",@"object: %@", object); [self recordDeleteForObject: object]; } dbOpe = [self databaseOperationForObject: object]; NSDebugMLLog(@"EODatabaseContext", @"dbOpe=%@", dbOpe); if (which == 0 || which == 2) //insert or update { //En update: dbsnapshot //en insert : snapshot ? en insert:dbsnap aussi int iRelationship = 0; NSDictionary *snapshot = nil; if (which == 0) //Insert //see wotRelSaveChanes.1.log seems to use dbSna for insert ! { snapshot=[object snapshot];//NEW2 //snapshot=[dbOpe dbSnapshot]; //NEW NSDebugMLog(@"[dbOpe dbSnapshot]=%@", [dbOpe dbSnapshot]); NSDebugMLLog(@"EODatabaseContext", @"Insert: [dbOpe snapshot] %p=%@", snapshot, snapshot); } else //Update { //NEWsnapshot=[dbOpe dbSnapshot]; snapshot = [object snapshot]; NSDebugMLLog(@"EODatabaseContext", @"Update: [object snapshot] %p=%@", snapshot, snapshot); } if (relationshipsCount>0) { for (iRelationship = 0; iRelationship < relationshipsCount; iRelationship++) { NSArray *classProperties = nil; EORelationship *substitutionRelationship = nil; EORelationship *relationship = GDL2_ObjectAtIndexWithImp(relationships,relObjectAtIndexIMP,iRelationship); /* get rel entity entity model model modelGroup */ NSDebugMLLog(@"EODatabaseContext", @"HANDLE relationship %@ " @"for object %p (class=%@):\n%@", [relationship name], object, [object class], object); substitutionRelationship = [relationship _substitutionRelationshipForRow: snapshot]; classProperties = [entity classProperties]; /* rel name ==> toCountry rel isToMany (0) nullifyAttributesInRelationship:rel sourceObject:object destinationObject:nil (snapshot objectForKey: rel name ) ? */ NSDebugMLLog(@"EODatabaseContext", @"relationship: %@", relationship); NSDebugMLLog(@"EODatabaseContext", @"classProperties: %@", classProperties); if ([classProperties indexOfObjectIdenticalTo: relationship] != NSNotFound) //(or subst) { BOOL valuesAreEqual = NO; BOOL isToMany = NO; id relationshipCommitedSnapshotValue = nil; NSString *relationshipName = [relationship name]; id relationshipSnapshotValue = nil; NSDebugMLLog(@"EODatabaseContext", @"dbOpe=%@", dbOpe); NSDebugMLLog(@"EODatabaseContext", @"which=%d", which); //NSDebugMLLog(@"EODatabaseContext",@"OBJECT SNAPSHOT %p:\n%@\n\n",[object snapshot]); NSDebugMLLog(@"EODatabaseContext", @"snapshot for object %p:\n" @"snapshot %p (count=%d)= \n%@\n\n", object, snapshot, [snapshot count], snapshot); // substitutionRelationship objectForKey: relationshipSnapshotValue = [snapshot objectForKey: relationshipName]; NSDebugMLLog(@"EODatabaseContext", @"relationshipSnapshotValue " @"(snapshot %p rel name=%@): %@", snapshot, relationshipName, relationshipSnapshotValue); if (which == 0) //Insert currentCommittedSnapshot = [dbOpe dbSnapshot]; else //Update { if (!currentCommittedSnapshot) currentCommittedSnapshot = [self _currentCommittedSnapshotForObject: object]; //OK For Update } //update: _commited //insert: dbSn NSDebugMLLog(@"EODatabaseContext", @"currentCommittedSnapshot %p: %@", currentCommittedSnapshot, currentCommittedSnapshot); relationshipCommitedSnapshotValue = [currentCommittedSnapshot objectForKey: relationshipName]; NSDebugMLLog(@"EODatabaseContext", @"relationshipCommitedSnapshotValue " @"(snapshot %p rel name=%@): %p", currentCommittedSnapshot, relationshipName, relationshipCommitedSnapshotValue); isToMany = [relationship isToMany]; NSDebugMLLog(@"EODatabaseContext", @"isToMany: %s", (isToMany ? "YES" : "NO")); NSDebugMLLog(@"EODatabaseContext", @"relationshipSnapshotValue %p=%@", relationshipSnapshotValue, relationshipSnapshotValue); NSDebugMLLog(@"EODatabaseContext", @"relationshipCommitedSnapshotValue %p=%@", relationshipCommitedSnapshotValue, (_isFault(relationshipCommitedSnapshotValue) ? (NSString*)@"[Fault]" : (NSString*)relationshipCommitedSnapshotValue)); NSDebugMLLog(@"EODatabaseContext", @"rel name=%@ relationshipCommitedSnapshotValue=%p relationshipSnapshotValue=%p", relationshipName, relationshipCommitedSnapshotValue, relationshipSnapshotValue); 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]; else // ToOne bu not same object valuesAreEqual = NO; NSDebugMLLog(@"EODatabaseContext", @"object=%p valuesAreEqual: %s", object,(valuesAreEqual ? "YES" : "NO")); if (valuesAreEqual) { //Equal Values ! } else { if (isToMany) { NSDebugMLog(@"relationshipCommitedSnapshotValue=%@",relationshipCommitedSnapshotValue); NSDebugMLog(@"relationshipSnapshotValue=%@",relationshipSnapshotValue); //relationshipSnapshotValue shallowCopy // Old Values are removed values NSArray *oldValues = [relationshipCommitedSnapshotValue arrayExcludingObjectsInArray: relationshipSnapshotValue]; // Old Values are newly added values NSArray *newValues = [relationshipSnapshotValue arrayExcludingObjectsInArray: relationshipCommitedSnapshotValue]; NSDebugMLog(@"oldValues=%@",oldValues); NSDebugMLog(@"newValues=%@",newValues); int oldValuesCount=[oldValues count]; int newValuesCount=[newValues count]; NSDebugMLLog(@"EODatabaseContext", @"oldValues count=%d", [oldValues count]); NSDebugMLLog(@"EODatabaseContext", @"oldValues=%@", oldValues); NSDebugMLLog(@"EODatabaseContext", @"newValues count=%d", [newValues count]); NSDebugMLLog(@"EODatabaseContext", @"newValues=%@", newValues); // Record ALL values snapshots if (newValuesCount > 0) { int valuesCount = [relationshipSnapshotValue count]; int iValue = 0; NSMutableArray *valuesGIDs = [NSMutableArray array]; IMP valuesGIDsAddObjectIMP=[valuesGIDs methodForSelector:@selector(addObject:)]; IMP svObjectAtIndexIMP=[relationshipSnapshotValue methodForSelector: @selector(objectAtIndex:)]; for (iValue = 0; iValue < valuesCount; iValue++) { id aValue = GDL2_ObjectAtIndexWithImp(relationshipSnapshotValue,svObjectAtIndexIMP,iValue); EOGlobalID *aValueGID = EODatabaseContext_globalIDForObjectWithImpPtr(self,&selfGIDFO,aValue); NSDebugMLLog(@"EODatabaseContext", @"YYYY valuesGIDs=%@", valuesGIDs); NSDebugMLLog(@"EODatabaseContext", @"YYYY aValueGID=%@", aValueGID); GDL2_AddObjectWithImp(valuesGIDs,valuesGIDsAddObjectIMP,aValueGID); } NSDebugMLog(@"TEST20060216 relationshipName=%@ valuesGIDs=%@",relationshipName,valuesGIDs); [recordToManySnapshot_dbOpes addObject:dbOpe]; [recordToManySnapshot_valuesGIDs addObject:valuesGIDs]; [recordToManySnapshot_relationshipNames addObject:relationshipName]; /* [dbOpe recordToManySnapshot:valuesGIDs relationshipName: relationshipName]; */ } // Nullify removed object relation attributes if (oldValuesCount > 0) { NSDebugMLLog(@"EODatabaseContext", @"will call nullifyAttributes from source %p (class %@)", object, [object class]); NSDebugMLLog(@"EODatabaseContext", @"object %p=%@ (class=%@)", object, object, [object class]); NSDebugMLLog(@"EODatabaseContext", @"relationshipName=%@", relationshipName); [nullifyAttributesInRelationship_relationships addObject:relationship]; [nullifyAttributesInRelationship_sourceObjects addObject:object]; [nullifyAttributesInRelationship_destinationObjects addObject:oldValues]; /* [self nullifyAttributesInRelationship: relationship sourceObject: object destinationObjects: oldValues]; */ } // Relay relationship attributes in new objects if (newValuesCount > 0) { NSDebugMLLog(@"EODatabaseContext", @"will call relay from source %p (class %@)", object, [object class]); NSDebugMLLog(@"EODatabaseContext", @"object %p=%@ (class=%@)", object, object, [object class]); NSDebugMLLog(@"EODatabaseContext", @"relationshipName=%@", relationshipName); [relayAttributesInRelationship_relationships addObject:relationship]; [relayAttributesInRelationship_sourceObjects addObject:object]; [relayAttributesInRelationship_destinationObjects addObject:newValues]; /* [self relayAttributesInRelationship: relationship sourceObject: object destinationObjects: newValues]; */ } } else // To One { //id destinationObject=[object storedValueForKey:relationshipName]; if (!_isNilOrEONull(relationshipCommitedSnapshotValue)) // a value was removed { NSDebugMLLog(@"EODatabaseContext", @"will call nullifyAttributes from source %p (class %@)", object, [object class]); NSDebugMLLog(@"EODatabaseContext", @"object %p=%@ (class=%@)", object, object, [object class]); NSDebugMLLog(@"EODatabaseContext", @"relationshipName=%@", relationshipName); NSDebugMLLog(@"EODatabaseContext", @"destinationObject %p=%@ (class=%@)", relationshipCommitedSnapshotValue, relationshipCommitedSnapshotValue, [relationshipCommitedSnapshotValue class]); [nullifyAttributesInRelationship_relationships addObject:relationship]; [nullifyAttributesInRelationship_sourceObjects addObject:object]; [nullifyAttributesInRelationship_destinationObjects addObject:[NSArray arrayWithObject:relationshipCommitedSnapshotValue]]; /* [self nullifyAttributesInRelationship: relationship sourceObject: object destinationObject: relationshipCommitedSnapshotValue]; */ } if (!_isNilOrEONull(relationshipSnapshotValue)) // a value was added { NSDebugMLLog(@"EODatabaseContext", @"will call relay from source %p relname=%@", object, relationshipName); NSDebugMLLog(@"EODatabaseContext", @"object %p=%@ (class=%@)", object, object, [object class]); NSDebugMLLog(@"EODatabaseContext", @"relationshipName=%@", relationshipName); NSDebugMLLog(@"EODatabaseContext", @"destinationObject %p=%@ (class=%@)", relationshipSnapshotValue, relationshipSnapshotValue, [relationshipSnapshotValue class]); [relayAttributesInRelationship_relationships addObject:relationship]; [relayAttributesInRelationship_sourceObjects addObject:object]; [relayAttributesInRelationship_destinationObjects addObject:[NSArray arrayWithObject:relationshipSnapshotValue]]; /* [self relayAttributesInRelationship: relationship sourceObject: object destinationObject: relationshipSnapshotValue]; */ } } } } else { //!toMany: //dbSnapshot was empty NSDebugMLLog(@"EODatabaseContext", @"will call nullifyAttributesInRelationship on source %p relname=%@", object, [relationship name]); NSDebugMLLog(@"EODatabaseContext", @"object %p=%@ (class=%@)", object, object, [object class]); NSDebugMLLog(@"EODatabaseContext", @"relationshipName=%@", [relationship name]); [nullifyAttributesInRelationship_relationships addObject:relationship]; [nullifyAttributesInRelationship_sourceObjects addObject:object]; [nullifyAttributesInRelationship_destinationObjects addObject:[NSArray array]]; /* [self nullifyAttributesInRelationship: relationship sourceObject: object //CountryLabel destinationObjects: nil]; */ } /* NSMutableDictionary *row; NSMutableArray *toManySnapshot, *newToManySnapshot; NSArray *joins = [(EORelationship *)property joins]; NSString *joinName; EOJoin *join; int h, count; id value; name = [(EORelationship *)property name]; row = [NSMutableDictionary dictionaryWithCapacity:4]; count = [joins count]; NSDebugMLLog(@"EODatabaseContext",@"rel name=%@", name); if ([property isToMany] == YES) { NSMutableArray *toManyGIDArray; NSArray *toManyObjects; EOGlobalID *toManyGID; id toManyObj; NSDebugMLLog(@"EODatabaseContext",@"rel 1 sourceGID=%@", gid); toManySnapshot = AUTORRELEASE([[self snapshotForSourceGlobalID:gid relationshipName:name] mutableCopy]); if (toManySnapshot == nil) toManySnapshot = [NSMutableArray array]; NSDebugMLLog(@"EODatabaseContext",@"rel 1", name); newToManySnapshot = [NSMutableArray arrayWithCapacity:10]; NSDebugMLLog(@"EODatabaseContext",@"rel 1", name); toManyObjects = [object storedValueForKey:name]; toManyGIDArray = [NSMutableArray arrayWithCapacity: [toManyObjects count]]; NSDebugMLLog(@"EODatabaseContext",@"rel 1", name); enumerator = [toManyObjects objectEnumerator]; while ((toManyObj = [enumerator nextObject])) { toManyGID = [_editingContext globalIDForObject: toManyObj]; [toManyGIDArray addObject:toManyGID]; if ([toManySnapshot containsObject:toManyGID] == NO) { [newToManySnapshot addObject:toManyGID]; for (h=0; h0) { IMP dbOpes_oaiIMP= [recordToManySnapshot_dbOpes methodForSelector: @selector(objectAtIndex:)]; IMP valuesGIDs_oaiIMP= [recordToManySnapshot_valuesGIDs methodForSelector: @selector(objectAtIndex:)]; IMP relationshipNames_oaiIMP= [recordToManySnapshot_relationshipNames methodForSelector: @selector(objectAtIndex:)]; for(i=0;i0) { IMP relationships_oaiIMP= [nullifyAttributesInRelationship_relationships methodForSelector: @selector(objectAtIndex:)]; IMP sourceObjects_oaiIMP= [nullifyAttributesInRelationship_sourceObjects methodForSelector: @selector(objectAtIndex:)]; IMP destinationObjects_oaiIMP= [nullifyAttributesInRelationship_destinationObjects methodForSelector: @selector(objectAtIndex:)]; for(i=0;i0) { IMP relationships_oaiIMP= [relayAttributesInRelationship_relationships methodForSelector: @selector(objectAtIndex:)]; IMP sourceObjects_oaiIMP= [relayAttributesInRelationship_sourceObjects methodForSelector: @selector(objectAtIndex:)]; IMP destinationObjects_oaiIMP= [relayAttributesInRelationship_destinationObjects methodForSelector: @selector(objectAtIndex:)]; for(i=0;i 0) { EOAdaptorChannel *adaptorChannel = nil; EODatabaseChannel *dbChannel = [self _obtainOpenChannel]; NSDebugMLLog(@"EODatabaseContext", @"self=%p preparingForSave=%d beganTransaction=%d", self, (int)_flags.preparingForSave, (int)_flags.beganTransaction); if (_flags.beganTransaction == NO)//MIRKO { NSDebugMLLog(@"EODatabaseContext", @"self=%p [_adaptorContext transactionNestingLevel]=%d", self, (int)[_adaptorContext transactionNestingLevel]); if ([_adaptorContext transactionNestingLevel] == 0) //?? [_adaptorContext beginTransaction]; NSDebugMLLog(@"EODatabaseContext", @"BEGAN TRANSACTION FLAG==>YES"); _flags.beganTransaction = YES; } adaptorChannel = [dbChannel adaptorChannel]; if (_delegateRespondsTo.willPerformAdaptorOperations == YES) orderedAdaptorOperations = [_delegate databaseContext: self willPerformAdaptorOperations: orderedAdaptorOperations adaptorChannel: adaptorChannel]; NS_DURING { NSDebugMLLog(@"EODatabaseContext", @"performAdaptorOperations:"); NSDebugMLLog(@"EODatabaseContext", @"self=%p preparingForSave=%d beganTransaction=%d", self, (int)_flags.preparingForSave, (int)_flags.beganTransaction); [adaptorChannel performAdaptorOperations: orderedAdaptorOperations]; NSDebugMLLog(@"EODatabaseContext", @"self=%p preparingForSave=%d beganTransaction=%d", self, (int)_flags.preparingForSave, (int)_flags.beganTransaction); NSDebugMLLog(@"EODatabaseContext", @"after performAdaptorOperations:"); } NS_HANDLER { NSDebugMLLog(@"EODatabaseContext", @"Exception in performAdaptorOperations:%@", localException); [localException raise]; //MIRKO //TODO /* NSException *exp; NSMutableDictionary *userInfo; EOAdaptorOperation *adaptorOp; userInfo = [NSMutableDictionary dictionaryWithCapacity:10]; [userInfo addEntriesFromDictionary:[localException userInfo]]; [userInfo setObject:self forKey:EODatabaseContextKey]; [userInfo setObject:dbOps forKey:EODatabaseOperationsKey]; adaptorOp = [userInfo objectForKey:EOFailedAdaptorOperationKey]; dbEnum = [dbOps objectEnumerator]; while ((op = [dbEnum nextObject])) if ([[op adaptorOperations] containsObject:adaptorOp] == YES) { [userInfo setObject:op forKey:EOFailedDatabaseOperationKey]; break; } exp = [NSException exceptionWithName:EOGeneralDatabaseException reason:[NSString stringWithFormat: @"%@ -- %@ 0x%x: failed with exception name:%@ reason:\"%@\"", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, [localException name], [localException reason]] userInfo:userInfo]; [exp raise]; */ } NS_ENDHANDLER; //This is not done by mirko: NSDebugMLLog(@"EODatabaseContext", @"self=%p preparingForSave=%d beganTransaction=%d", self, (int)_flags.preparingForSave, (int)_flags.beganTransaction); NSDebugMLLog(@"EODatabaseContext", @"self=%p _uniqueStack %p=%@", self, _uniqueStack, _uniqueStack); dbOpeEnum = NSEnumerateMapTable(_dbOperationsByGlobalID); while (NSNextMapEnumeratorPair(&dbOpeEnum, (void **)&gid, (void **)&dbOpe)) { EODatabaseOperator databaseOperator = EODatabaseNothingOperator; //call dbOpe adaptorOperations ? if ([dbOpe databaseOperator] == EODatabaseNothingOperator) { NSDebugMLLog(@"EODatabaseContext", @"Db Ope %@ for Nothing !!!", dbOpe); } else { EOEntity *entity = nil; NSArray *dbSnapshotKeys = nil; NSMutableDictionary *newRow = nil; NSDictionary *values = nil; id object = nil; NSArray *adaptorOpe = nil; NSDebugMLLog(@"EODatabaseContext", @"dbOpe=%@", dbOpe); object = [dbOpe object]; adaptorOpe = [dbOpe adaptorOperations]; databaseOperator = [dbOpe databaseOperator]; entity = [dbOpe entity]; dbSnapshotKeys = [entity dbSnapshotKeys]; NSDebugMLLog(@"EODatabaseContext", @"dbSnapshotKeys=%@", dbSnapshotKeys); newRow = [dbOpe newRow]; NSDebugMLLog(@"EODatabaseContext", @"newRow=%@", newRow); values = [newRow valuesForKeys: dbSnapshotKeys]; NSDebugMLLog(@"EODatabaseContext", @"RECORDSNAPSHOT values=%@", values); //if update: forgetSnapshotForGlobalID: [self recordSnapshot: values forGlobalID: gid]; NSDebugMLLog(@"EODatabaseContext", @"self=%p _uniqueStack %p=%@", self, _uniqueStack, _uniqueStack); if (databaseOperator == EODatabaseUpdateOperator) //OK for update //Do it forInsert too //TODO { NSDictionary *toManySnapshots = [dbOpe toManySnapshots]; if (toManySnapshots) { NSDebugMLog(@"toManySnapshots=%@", toManySnapshots); NSEmitTODO(); //TODONOW [self notImplemented: _cmd]; //TODO } } } } } EOFLOGObjectFnStop(); } - (void)commitChanges { BOOL doIt = NO; NSMutableArray *deletedObjects = [NSMutableArray array]; NSMutableArray *insertedObjects = [NSMutableArray array]; NSMutableArray *updatedObjects = [NSMutableArray array]; NSMutableDictionary *gidChangedUserInfo = nil; EOFLOGObjectFnStart(); [self _assertValidStateWithSelector: @selector(commitChanges)]; //REVOIR: don't do it if no adaptor ope { NSMapEnumerator dbOpeEnum; EOGlobalID *gid = nil; EODatabaseOperation *dbOpe = nil; dbOpeEnum = NSEnumerateMapTable(_dbOperationsByGlobalID); while (!doIt && NSNextMapEnumeratorPair(&dbOpeEnum, (void **)&gid, (void **)&dbOpe)) { doIt = ([dbOpe adaptorOperations] != nil); } } /* If a transaction is open, it could be holding locks which we want to release. */ if (doIt || _flags.beganTransaction) { if (_flags.beganTransaction == NO)//it is not set here in WO { NSEmitTODO(); [self notImplemented: _cmd]; //TODO } else if ([_adaptorContext transactionNestingLevel] == 0) { NSEmitTODO(); [self notImplemented: _cmd]; //TODO } else { NSMapEnumerator dbOpeEnum; EOGlobalID *gid = nil; EODatabaseOperation *dbOpe = nil; NSDebugMLLog(@"EODatabaseContext", @"BEGAN TRANSACTION FLAG==>NO"); _flags.beganTransaction = NO; [_adaptorContext commitTransaction]; //adaptorcontext transactionDidCommit dbOpeEnum = NSEnumerateMapTable(_dbOperationsByGlobalID); while (NSNextMapEnumeratorPair(&dbOpeEnum, (void **)&gid, (void **)&dbOpe)) { EODatabaseOperator databaseOperator = EODatabaseNothingOperator; EOGlobalID *dbOpeGID = nil; EOGlobalID *newGID = nil; EOEntity *entity = nil; NSDebugMLLog(@"EODatabaseContext", @"dbOpe=%@", dbOpe); [EOObserverCenter suppressObserverNotification]; NS_DURING { databaseOperator = [dbOpe databaseOperator]; entity = [dbOpe entity]; if (databaseOperator == EODatabaseInsertOperator || databaseOperator == EODatabaseUpdateOperator)//OK for update { id object = nil; NSDictionary *newRowValues = nil; //gid isTemporary NSDictionary *primaryKeyDiffs = [dbOpe primaryKeyDiffs];//OK for update if (primaryKeyDiffs) { NSEmitTODO(); NSAssert3(NO,@"primaryKeyDiffs=%@ dbOpe=%@ object=%@", primaryKeyDiffs,dbOpe,[dbOpe object]); //TODO: if primaryKeyDiffs } if (databaseOperator == EODatabaseInsertOperator) { NSArray *classPropertyAttributeNames = [entity classPropertyAttributeNames]; NSDictionary *newRow = [dbOpe newRow]; newRowValues = [newRow valuesForKeys: classPropertyAttributeNames]; //TODO REVOIR !! newGID = [entity globalIDForRow: newRow isFinal: YES]; } else { NSArray *classPropertyAttributes = [entity _classPropertyAttributes];//OK for update newRowValues = [dbOpe rowDiffsForAttributes: classPropertyAttributes];//OK for update } object = [dbOpe object];//OK for update [object takeStoredValuesFromDictionary: newRowValues];//OK for update /*mirko instead: [object takeStoredValuesFromDictionary: [op rowDiffsForAttributes:attributes]]; NSDebugMLLog(@"EODatabaseContext",@"-_+ %@ # %@", gid, object); NSDebugMLLog(@"EODatabaseContext",@"-_* %@", [op newRow]); [_database recordSnapshot:[op newRow] forGlobalID:gid]; toManySnapshots = [op toManySnapshots]; toManyEnum = [toManySnapshots keyEnumerator]; while ((key = [toManyEnum nextObject])) [_database recordSnapshot:[toManySnapshots objectForKey:key] forSourceGlobalID:gid relationshipName:key]; */ } } NS_HANDLER { [EOObserverCenter enableObserverNotification]; NSDebugMLLog(@"EODatabaseContext", @"EXCEPTION %@", localException); [localException raise]; } NS_ENDHANDLER; [EOObserverCenter enableObserverNotification]; NSDebugMLLog(@"EODatabaseContext", @"dbOpe=%@", dbOpe); dbOpeGID = [dbOpe globalID]; //OK for update NSDebugMLLog(@"EODatabaseContext", @"dbOpeGID=%@", dbOpeGID); switch (databaseOperator) { case EODatabaseInsertOperator: [insertedObjects addObject: dbOpeGID]; if (!gidChangedUserInfo) gidChangedUserInfo = (NSMutableDictionary *) [NSMutableDictionary dictionary]; [gidChangedUserInfo setObject: newGID forKey: dbOpeGID]; //[_editingContext globalIDForObject:object]]; break; case EODatabaseDeleteOperator: [deletedObjects addObject: dbOpeGID]; [_database forgetSnapshotForGlobalID: dbOpeGID]; //Mirko/?? break; case EODatabaseUpdateOperator: [updatedObjects addObject: dbOpeGID]; break; case EODatabaseNothingOperator: break; } } } } NSDebugMLLog(@"EODatabaseContext", @"call _cleanUpAfterSave"); [self _cleanUpAfterSave];//OK for update if (doIt) { //from mirko. seems ok if (gidChangedUserInfo) { NSDebugMLLog(@"EODatabaseContext", @"post EOGlobalIDChangedNotification"); [[NSNotificationCenter defaultCenter] postNotificationName: EOGlobalIDChangedNotification object: nil userInfo: gidChangedUserInfo]; } NSDebugMLLog(@"EODatabaseContext", @"post EOObjectsChangedInStoreNotification"); [[NSNotificationCenter defaultCenter] postNotificationName: @"EOObjectsChangedInStoreNotification" object: _database userInfo: [NSDictionary dictionaryWithObjectsAndKeys: deletedObjects, EODeletedKey, insertedObjects, EOInsertedKey, updatedObjects, EOUpdatedKey, nil, nil]]; //call self _snapshotsChangedInDatabase: } EOFLOGObjectFnStop(); } - (void)rollbackChanges { // TODO //adaptorcontext transactionNestingLevel //if 0 ? _cleanUpAfterSave EOFLOGObjectFnStart(); if (_flags.beganTransaction == YES) { [_adaptorContext rollbackTransaction]; NSDebugMLLog(@"EODatabaseContext", @"BEGAN TRANSACTION FLAG==>NO"); _flags.beganTransaction = NO; if (_lockedObjects) { NSResetHashTable(_lockedObjects); } NSResetMapTable(_dbOperationsByGlobalID); /* //TODO [_snapshots removeAllObjects]; [_toManySnapshots removeAllObjects]; */ } EOFLOGObjectFnStop(); } - (NSDictionary *)valuesForKeys: (NSArray *)keys object: (id)object { //OK EOEntity *entity; EODatabaseOperation *dbOpe; NSDictionary *newRow; NSDictionary *values = nil; EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext",@"object=%p keys=%@", object, keys); NSDebugMLLog(@"EODatabaseContext", @"object=%p (class=%@)", object, [object class]); //NSAssert(object, @"No object"); if (!_isNilOrEONull(object)) { entity = [_database entityForObject: object]; NSAssert1(entity, @"No entity for object %@", object); NSDebugMLLog(@"EODatabaseContext", @"entity name=%@", [entity name]); dbOpe = [self databaseOperationForObject: object]; NSDebugMLLog(@"EODatabaseContext", @"dbOpe=%p", dbOpe); NSDebugMLLog(@"EODatabaseContext", @"dbOpe=%@", dbOpe); newRow = [dbOpe newRow]; NSDebugMLLog(@"EODatabaseContext", @"newRow=%p", newRow); NSDebugMLLog(@"EODatabaseContext", @"newRow=%@", newRow); values = [newRow valuesForKeys: keys]; } else { NSDebugMLLog(@"EODatabaseContext", @"No object"); values = [NSDictionary dictionary]; } // NSDebugMLLog(@"EODatabaseContext", @"values=%@", values); EOFLOGObjectFnStop(); return values; } -(void)nullifyAttributesInRelationship: (EORelationship*)relationship sourceObject: (id)sourceObject destinationObject: (id)destinationObject { EODatabaseOperation *sourceDBOpe = nil; EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"relationship=%@", relationship); NSDebugMLLog(@"EODatabaseContext", @"sourceObject=%@", sourceObject); NSDebugMLLog(@"EODatabaseContext", @"destinationObject=%@", destinationObject); if (destinationObject) { //Get SourceObject database operation sourceDBOpe = [self databaseOperationForObject: sourceObject]; //TODO: useIt NSDebugMLLog(@"EODatabaseContext", @"sourceDBOpe=%@", sourceDBOpe); if ([relationship isToManyToOne]) { NSEmitTODO(); [self notImplemented: _cmd]; //TODO } else { // Key a dictionary of two array: destinationKeys and sourceKeys NSDictionary *sourceToDestinationKeyMap = [relationship _sourceToDestinationKeyMap]; //{destinationKeys = (customerCode); sourceKeys = (code); } BOOL foreignKeyInDestination = [relationship foreignKeyInDestination]; NSDebugMLLog(@"EODatabaseContext", @"sourceToDestinationKeyMap=%@", sourceToDestinationKeyMap); NSDebugMLLog(@"EODatabaseContext", @"foreignKeyInDestination=%d", foreignKeyInDestination); if (foreignKeyInDestination) { NSArray *destinationKeys = [sourceToDestinationKeyMap objectForKey: @"destinationKeys"];//(customerCode) int i, destinationKeysCount = [destinationKeys count]; NSMutableDictionary *changes = [NSMutableDictionary dictionaryWithCapacity: destinationKeysCount]; if (destinationKeysCount>0) { IMP oaiIMP=[destinationKeys methodForSelector: @selector(objectAtIndex:)]; for (i = 0 ;i < destinationKeysCount; i++) { id destinationKey = GDL2_ObjectAtIndexWithImp(destinationKeys,oaiIMP,i); [changes setObject: GDL2_EONull forKey: destinationKey]; } } NSAssert1(destinationObject, @"No destinationObject for call of recordUpdateForObject:changes: changes: %@", changes); [self recordUpdateForObject: destinationObject changes: changes]; } else { //Do nothing ? NSEmitTODO(); //[self notImplemented: _cmd]; //TODO } } } } - (void)nullifyAttributesInRelationship: (EORelationship*)relationship sourceObject: (id)sourceObject destinationObjects: (NSArray*)destinationObjects { int destinationObjectsCount = 0; EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"relationship=%@", relationship); NSDebugMLLog(@"EODatabaseContext", @"sourceObject=%@", sourceObject); NSDebugMLLog(@"EODatabaseContext", @"destinationObjects=%@", destinationObjects); destinationObjectsCount = [destinationObjects count]; if (destinationObjectsCount > 0) { int i; IMP oaiIMP=[destinationObjects methodForSelector: @selector(objectAtIndex:)]; for (i = 0; i < destinationObjectsCount; i++) { id object = GDL2_ObjectAtIndexWithImp(destinationObjects,oaiIMP,i); NSDebugMLLog(@"EODatabaseContext", @"destinationObject %p=%@ (class %@)", object, object, [object class]); [self nullifyAttributesInRelationship: relationship sourceObject: sourceObject destinationObject: object]; } } EOFLOGObjectFnStop(); } - (void)relayAttributesInRelationship: (EORelationship*)relationship sourceObject: (id)sourceObject destinationObjects: (NSArray*)destinationObjects { int destinationObjectsCount = 0; EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"relationship=%@", relationship); NSDebugMLLog(@"EODatabaseContext", @"sourceObject=%@", sourceObject); NSDebugMLLog(@"EODatabaseContext", @"destinationObjects=%@", destinationObjects); destinationObjectsCount = [destinationObjects count]; if (destinationObjectsCount > 0) { int i; IMP oaiIMP=[destinationObjects methodForSelector: @selector(objectAtIndex:)]; for (i = 0; i < destinationObjectsCount; i++) { id object = GDL2_ObjectAtIndexWithImp(destinationObjects,oaiIMP,i); NSDebugMLLog(@"EODatabaseContext", @"destinationObject %p=%@ (class %@)", object, object, [object class]); [self relayAttributesInRelationship: (EORelationship*)relationship sourceObject: (id)sourceObject destinationObject: object]; } } EOFLOGObjectFnStop(); } - (NSDictionary*)relayAttributesInRelationship: (EORelationship*)relationship sourceObject: (id)sourceObject destinationObject: (id)destinationObject { //OK NSMutableDictionary *relayedValues = nil; EODatabaseOperation *sourceDBOpe = nil; EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"relationship=%@", relationship); NSDebugMLLog(@"EODatabaseContext", @"sourceObject %p=%@ (class=%@)", sourceObject, sourceObject, [sourceObject class]); NSDebugMLLog(@"EODatabaseContext", @"destinationObject %p=%@ (class=%@)", destinationObject, destinationObject, [destinationObject class]); //Get SourceObject database operation sourceDBOpe = [self databaseOperationForObject: sourceObject]; NSDebugMLLog(@"EODatabaseContext", @"sourceDBOpe=%@", sourceDBOpe); if ([sourceDBOpe databaseOperator] == EODatabaseNothingOperator) { NSDebugMLLog(@"EODatabaseContext", @"Db Ope %@ for Nothing !!!", sourceDBOpe); } if ([relationship isToManyToOne]) { NSEmitTODO(); [self notImplemented: _cmd]; //TODO } else { // Key a dictionary of two array: destinationKeys and sourceKeys NSDictionary *sourceToDestinationKeyMap = [relationship _sourceToDestinationKeyMap];//{destinationKeys = (customerCode); sourceKeys = (code); } NSArray *destinationKeys = [sourceToDestinationKeyMap objectForKey: @"destinationKeys"];//(customerCode) NSArray *sourceKeys = [sourceToDestinationKeyMap objectForKey: @"sourceKeys"];//(code) NSMutableDictionary *sourceNewRow = [sourceDBOpe newRow];//OK in foreignKeyInDestination BOOL foreignKeyInDestination = [relationship foreignKeyInDestination]; int i, count; NSDebugMLLog(@"EODatabaseContext", @"relationship=%@", relationship); NSDebugMLLog(@"EODatabaseContext", @"sourceToDestinationKeyMap=%@", sourceToDestinationKeyMap); NSDebugMLLog(@"EODatabaseContext", @"destinationKeys=%@", destinationKeys); NSDebugMLLog(@"EODatabaseContext", @"sourceKeys=%@", sourceKeys); NSDebugMLLog(@"EODatabaseContext", @"sourceNewRow=%@", sourceNewRow); NSDebugMLLog(@"EODatabaseContext", @"foreignKeyInDestination=%s", (foreignKeyInDestination ? "YES" : "NO")); NSAssert([destinationKeys count] == [sourceKeys count], @"destination keys count!=source keys count"); if (foreignKeyInDestination || [relationship propagatesPrimaryKey]) { IMP srcObjectAIndexIMP=[sourceKeys methodForSelector: @selector(objectAtIndex:)]; IMP dstObjectAIndexIMP=[destinationKeys methodForSelector: @selector(objectAtIndex:)]; relayedValues = AUTORELEASE([[sourceNewRow valuesForKeys: sourceKeys] mutableCopy]);// {code = 0; } NSDebugMLLog(@"EODatabaseContext", @"relayedValues=%@", relayedValues); count = [relayedValues count]; for (i = 0; i < count; i++) { NSString *sourceKey = GDL2_ObjectAtIndexWithImp(sourceKeys,srcObjectAIndexIMP,i); NSString *destKey = GDL2_ObjectAtIndexWithImp(destinationKeys,dstObjectAIndexIMP,i); id sourceValue = [relayedValues objectForKey: sourceKey]; NSDebugMLLog(@"EODatabaseContext", @"sourceKey=%@", sourceKey); NSDebugMLLog(@"EODatabaseContext", @"destKey=%@", destKey); NSDebugMLLog(@"EODatabaseContext", @"sourceValue=%@", sourceValue); [relayedValues removeObjectForKey: sourceKey]; [relayedValues setObject: sourceValue forKey: destKey]; } NSDebugMLLog(@"EODatabaseContext", @"relayedValues=%@", relayedValues); NSAssert1(destinationObject, @"No destinationObject for call of " @"recordUpdateForObject:changes: relayedValues: %@", relayedValues); [self recordUpdateForObject: destinationObject changes: relayedValues]; } else { //Verify !! NSDictionary *destinationValues; IMP srcObjectAIndexIMP=[sourceKeys methodForSelector: @selector(objectAtIndex:)]; IMP dstObjectAIndexIMP=[destinationKeys methodForSelector: @selector(objectAtIndex:)]; NSDebugMLLog(@"EODatabaseContext", @"Call valuesForKeys destinationObject (%p-<%@>)", destinationObject, [destinationObject class]); NSDebugMLLog(@"EODatabaseContext", @"destinationKeys=%@", destinationKeys); NSDebugMLLog(@"EODatabaseContext", @"relationship=%@", relationship); NSDebugMLLog(@"EODatabaseContext", @"sourceKeys=%@", sourceKeys); //Now take destinationKeys values destinationValues = [self valuesForKeys: destinationKeys object: destinationObject]; NSDebugMLLog(@"EODatabaseContext", @"destinationValues=%@", destinationValues); //And put these values for source keys in the return object (sourceValues) count = [destinationKeys count]; relayedValues = (NSMutableDictionary*)[NSMutableDictionary dictionary]; NSDebugMLLog(@"EODatabaseContext", @"relayedValues=%@", relayedValues); for (i = 0; i < count; i++) { NSString *sourceKey = GDL2_ObjectAtIndexWithImp(sourceKeys,srcObjectAIndexIMP,i); NSString *destinationKey = GDL2_ObjectAtIndexWithImp(destinationKeys,dstObjectAIndexIMP,i); id destinationValue = [destinationValues objectForKey: destinationKey]; NSDebugMLLog(@"EODatabaseContext", @"destinationKey=%@", destinationKey); NSDebugMLLog(@"EODatabaseContext", @"sourceKey=%@", sourceKey); NSDebugMLLog(@"EODatabaseContext", @"destinationValue=%@", destinationValue); if (!_isNilOrEONull(destinationValue))//?? or always [relayedValues setObject: destinationValue forKey: sourceKey]; } //Put these values in source object database ope new row NSDebugMLLog(@"EODatabaseContext", @"relayedValues=%@", relayedValues); [sourceNewRow takeValuesFromDictionary: relayedValues]; } } if ([sourceDBOpe databaseOperator] == EODatabaseNothingOperator) { NSDebugMLLog(@"EODatabaseContext", @"Db Ope %@ for Nothing !!!", sourceDBOpe); } EOFLOGObjectFnStop(); return relayedValues; //Mirko Code: /* NSMutableArray *keys; NSDictionary *values; EOGlobalID *relationshipGID; id objectTo; objectTo = [object storedValueForKey:name]; relationshipGID = [_editingContext globalIDForObject:objectTo]; if ([self ownsObject:objectTo] == YES) { for (h=0; h0) { IMP oaiIMP=[classPropertyNames methodForSelector: @selector(objectAtIndex:)]; for (i = 0; i < propNamesCount; i++) { id value = nil; NSString *key = GDL2_ObjectAtIndexWithImp(classPropertyNames,oaiIMP,i); NSDebugMLLog(@"EODatabaseContext", @"key=%@", key); /*NO !! if ([attribute isKindOfClass:[EOAttribute class]] == NO) continue; // if ([attribute isFlattened] == NO) */ value = [object storedValueForKey: key]; //OK NSDebugMLLog(@"EODatabaseContext", @"key=%@ value=%@", key, value); if (!value) { value = GDL2_EONull; [[[entity attributeNamed: key] validateValue: &value] raise]; } NSDebugMLLog(@"EODatabaseContext", @"key=%@ value=%@", key, value); [row setObject: value forKey: key]; } }; newRow = [[NSMutableDictionary alloc] initWithDictionary: snapshot copyItems: NO]; NSDebugMLLog(@"EODatabaseContext", @"newRow=%@", newRow); dbSnapshotKeys = [entity dbSnapshotKeys]; //OK (numcode, code, a3code) NSDebugMLLog(@"EODatabaseContext", @"dbSnapshotKeys=%@", dbSnapshotKeys); snapKeyCount = [dbSnapshotKeys count]; if (snapKeyCount>0) { IMP oaiIMP=[dbSnapshotKeys methodForSelector: @selector(objectAtIndex:)]; for (i = 0; i < snapKeyCount; i++) { id key = GDL2_ObjectAtIndexWithImp(dbSnapshotKeys,oaiIMP,i); id value = [row objectForKey: key]; //Really this key ? NSDebugMLLog(@"EODatabaseContext", @"key=%@ value=%@", key, value); // NSAssert1(value,@"No value for %@",key); if (value) [newRow setObject: value forKey: key]; } }; NSDebugMLLog(@"EODatabaseContext", @"newRow=%@", newRow); [databaseOpe setNewRow: newRow]; [self recordDatabaseOperation: databaseOpe]; RELEASE(newRow); } } NS_HANDLER { NSDebugMLLog(@"EODatabaseContext", @"EXCEPTION %@", localException); [localException raise]; } NS_ENDHANDLER; EOFLOGObjectFnStop(); return databaseOpe; } - (void)relayPrimaryKey: (NSDictionary*)pk sourceObject: (id)sourceObject destObject: (id)destObject relationship: (EORelationship*)relationship { //OK NSDictionary *relayedAttributes = nil; EOEntity *destEntity = nil; NSArray *destAttributes = nil; NSArray *destAttributeNames = nil; NSDictionary *keyValues = nil; NSArray *values = nil; int i, count; BOOL nullPKValues = YES; EOFLOGObjectFnStart(); NSAssert3(destObject, @"No destinationObject. pk=%@ relationship=%@ sourceObject=%@", pk,relationship,sourceObject); destAttributes = [relationship destinationAttributes]; NSDebugMLLog(@"EODatabaseContext", @"destAttributes=%@", destAttributes); destAttributeNames = [destAttributes resultsOfPerformingSelector: @selector(name)]; NSDebugMLLog(@"EODatabaseContext", @"destAttributeNames=%@", destAttributeNames); keyValues = [self valuesForKeys: destAttributeNames object: destObject]; NSDebugMLLog(@"EODatabaseContext", @"keyValues=%@", keyValues); values = [keyValues allValues]; NSDebugMLLog(@"EODatabaseContext", @"values=%@", values); //Now test if null values count = [values count]; if (count>0) { IMP oaiIMP=[values methodForSelector: @selector(objectAtIndex:)]; for (i = 0; nullPKValues && i < count; i++) nullPKValues = _isNilOrEONull(GDL2_ObjectAtIndexWithImp(values,oaiIMP,i)); }; NSDebugMLLog(@"EODatabaseContext", @"nullPKValues=%s", (nullPKValues ? "YES" : "NO")); if (nullPKValues) { relayedAttributes = [self relayAttributesInRelationship: relationship sourceObject: sourceObject destinationObject: destObject]; destEntity = [relationship destinationEntity]; [self relayPrimaryKey: relayedAttributes object: destObject entity: destEntity]; } EOFLOGObjectFnStop(); } - (void)relayPrimaryKey: (NSDictionary*)pk object: (id)object entity: (EOEntity*)entity { //TODO finish NSArray *relationships = nil; NSArray *classPropertyNames = nil; EODatabaseOperation *dbOpe = nil; NSDictionary *dbSnapshot = nil; int i, count; EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"pk=%@", pk); NSDebugMLLog(@"EODatabaseContext", @"object=%@", object); NSDebugMLLog(@"EODatabaseContext", @"entity=%@", [entity name]); relationships = [entity relationships]; //OK classPropertyNames = [entity classPropertyNames]; dbOpe = [self databaseOperationForObject: object]; NSDebugMLLog(@"EODatabaseContext", @"dbOpe=%@", dbOpe); dbSnapshot = [dbOpe dbSnapshot]; //OK NSDebugMLLog(@"EODatabaseContext", @"dbSnapshot=%@", dbSnapshot); count = [relationships count]; if (count>0) { IMP oaiIMP=[relationships methodForSelector: @selector(objectAtIndex:)]; for (i = 0; i < count; i++) { EORelationship *relationship = GDL2_ObjectAtIndexWithImp(relationships,oaiIMP,i); EORelationship *substRelationship = nil; BOOL propagatesPrimaryKey = NO; NSDebugMLLog(@"EODatabaseContext", @"relationship=%@", relationship); substRelationship = [relationship _substitutionRelationshipForRow: dbSnapshot]; propagatesPrimaryKey = [substRelationship propagatesPrimaryKey]; //substRelationship or relationship? NSDebugMLLog(@"EODatabaseContext", @"object=%p relationship name=%@ ==> " @"propagatesPrimaryKey=%s", object, [relationship name], (propagatesPrimaryKey ? "YES" : "NO")); if (propagatesPrimaryKey) { NSString *relName = [substRelationship name]; //this one ?? NSDebugMLLog(@"EODatabaseContext", @"relName=%@", relName); if ([classPropertyNames containsObject: relName]) { id value = nil; id snapshot = nil; id snapshotValue = nil; BOOL isToMany = NO; value = [object storedValueForKey: relName]; NSDebugMLLog(@"EODatabaseContext", @"value=%@", value); snapshot = [self _currentCommittedSnapshotForObject: object]; NSDebugMLLog(@"EODatabaseContext", @"snapshot=%@", snapshot); snapshotValue = [snapshot objectForKey:relName];//ret nil NSDebugMLLog(@"EODatabaseContext", @"snapshotValue=%@", snapshotValue); isToMany = [substRelationship isToMany]; //this one ?? NSDebugMLLog(@"EODatabaseContext", @"isToMany=%s", (isToMany ? "YES" : "NO")); if (isToMany) { int valueValuesCount = 0; value = [((NSArray*)value) shallowCopy]; valueValuesCount = [value count]; if (valueValuesCount>0) { int iValueValue = 0; IMP vObjectAtIndexIMP=[value methodForSelector: @selector(objectAtIndex:)]; for (iValueValue = 0; iValueValue < valueValuesCount; iValueValue++) { id valueValue = GDL2_ObjectAtIndexWithImp(value,vObjectAtIndexIMP,iValueValue); NSDebugMLLog(@"EODatabaseContext", @"valueValue=%@", valueValue); [self relayPrimaryKey: pk sourceObject: object destObject: valueValue relationship: substRelationship]; //this one ?? } }; } else { NSDebugMLLog(@"EODatabaseContext", @"value=%@", value); // 1:1 relationships may be optional so we may have no value here if (value) { [self relayPrimaryKey: pk sourceObject: object destObject: value relationship: substRelationship]; //this one ?? }; } } } } } EOFLOGObjectFnStop(); } - (void) createAdaptorOperationsForDatabaseOperation: (EODatabaseOperation*)dbOpe attributes: (NSArray*)attributes { //NEAR OK BOOL isSomethingTodo = YES; EOEntity *entity = nil; EODatabaseOperator dbOperator = EODatabaseNothingOperator; NSDictionary *changedValues = nil; EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"dbOpe=%@", dbOpe); NSAssert(dbOpe, @"No operation"); entity = [dbOpe entity]; //OK dbOperator = [dbOpe databaseOperator]; //OK NSDebugMLLog(@"EODatabaseContext", @"attributes=%@", attributes); NSDebugMLLog(@"EODatabaseContext", @"dbOperator=%d", (int)dbOperator); switch (dbOperator) { case EODatabaseUpdateOperator: { changedValues = [dbOpe rowDiffsForAttributes:attributes]; NSDebugMLLog(@"EODatabaseContext", @"changedValues %p=%@", changedValues, changedValues); if ([changedValues count] == 0) isSomethingTodo = NO; else { } } break; case EODatabaseInsertOperator: { changedValues = [dbOpe newRow]; //OK NSDebugMLLog(@"EODatabaseContext", @"changedValues %p=%@", changedValues, changedValues); } break; case EODatabaseDeleteOperator: { isSomethingTodo = YES; } break; case EODatabaseNothingOperator: { //Nothing! } break; default: { NSEmitTODO(); // [self notImplemented:_cmd]; //TODO } break; } if (isSomethingTodo) { EOAdaptorOperation *adaptorOpe = nil; NSString *procedureOpeName = nil; EOAdaptorOperator adaptorOperator = EOAdaptorUndefinedOperator; EOStoredProcedure *storedProcedure = nil; NSDictionary *valuesToWrite = nil; EOQualifier *lockingQualifier = nil; switch (dbOperator) { case EODatabaseUpdateOperator: case EODatabaseDeleteOperator: { NSArray *pkAttributes; NSArray *lockingAttributes; NSDictionary *dbSnapshot; pkAttributes = [self primaryKeyAttributesForAttributes: attributes entity: entity]; lockingAttributes = [self lockingAttributesForAttributes: attributes entity: entity]; dbSnapshot = [dbOpe dbSnapshot]; lockingQualifier = [self qualifierForLockingAttributes: lockingAttributes primaryKeyAttributes: pkAttributes entity: entity snapshot: dbSnapshot]; NSEmitTODO(); //TODO=self lockingNonQualifiableAttributes:##### ret nil NSDebugMLLog(@"EODatabaseContext", @"lockingQualifier=%@", lockingQualifier); /*MIRKO for UPDATE: //TODO-NOW { if ([self isObjectLockedWithGlobalID:gid] == NO) { EOAdaptorOperation *lockOperation; EOQualifier *qualifier; EOAttribute *attribute; NSEnumerator *attrsEnum; NSArray *attrsUsedForLocking, *primaryKeyAttributes; NSMutableDictionary *qualifierSnapshot, *lockSnapshot; NSMutableArray *lockAttributes; lockOperation = [EOAdaptorOperation adaptorOperationWithEntity: entity]; attrsUsedForLocking = [entity attributesUsedForLocking]; primaryKeyAttributes = [entity primaryKeyAttributes]; qualifierSnapshot = [NSMutableDictionary dictionaryWithCapacity:16]; lockSnapshot = [NSMutableDictionary dictionaryWithCapacity:8]; lockAttributes = [NSMutableArray arrayWithCapacity:8]; NSDebugMLLog(@"EODatabaseContext",@"lock start %@", snapshot); attrsEnum = [primaryKeyAttributes objectEnumerator]; while ((attribute = [attrsEnum nextObject])) { NSString *name = [attribute name]; NSDebugMLLog(@"EODatabaseContext",@" %@", name); [lockSnapshot setObject:[snapshot objectForKey:name] forKey:name]; } NSDebugMLLog(@"EODatabaseContext",@"lock stop"); NSDebugMLLog(@"EODatabaseContext",@"lock start2"); attrsEnum = [attrsUsedForLocking objectEnumerator]; while ((attribute = [attrsEnum nextObject])) { NSString *name = [attribute name]; if ([primaryKeyAttributes containsObject:attribute] == NO) { if ([attribute adaptorValueType] == EOAdaptorBytesType) { [lockAttributes addObject:attribute]; [lockSnapshot setObject:[snapshot objectForKey:name] forKey:name]; } else [qualifierSnapshot setObject:[snapshot objectForKey:name] forKey:name]; } } NSDebugMLLog(@"EODatabaseContext",@"lock stop2"); qualifier = AUTORELEASE([[EOAndQualifier alloc] initWithQualifiers: [entity qualifierForPrimaryKey: [entity primaryKeyForGlobalID: (EOKeyGlobalID *)gid]], [EOQualifier qualifierToMatchAllValues: qualifierSnapshot], nil]); if ([lockAttributes count] == 0) lockAttributes = nil; if ([lockSnapshot count] == 0) lockSnapshot = nil; [lockOperation setAdaptorOperator:EOAdaptorLockOperator]; [lockOperation setQualifier:qualifier]; [lockOperation setAttributes:lockAttributes]; [lockOperation setChangedValues:lockSnapshot]; NSDebugMLLog(@"EODatabaseContext",@"*+ %@", lockSnapshot); [op addAdaptorOperation:lockOperation]; } */ } break; case EODatabaseInsertOperator: break; case EODatabaseNothingOperator: break; } adaptorOpe = [EOAdaptorOperation adaptorOperationWithEntity: entity]; NSDebugMLLog(@"EODatabaseContext", @"adaptorOpe=%@", adaptorOpe); switch (dbOperator) { case EODatabaseInsertOperator: procedureOpeName = @"EOInsertProcedure"; adaptorOperator = EOAdaptorInsertOperator; NSDebugMLLog(@"EODatabaseContext", @"changedValues %p=%@", changedValues, changedValues); valuesToWrite = [self valuesToWriteForAttributes: attributes entity: entity changedValues: changedValues]; break; case EODatabaseUpdateOperator: procedureOpeName = @"EOUpdateProcedure"; adaptorOperator = EOAdaptorUpdateOperator; valuesToWrite = [self valuesToWriteForAttributes: attributes entity: entity changedValues: changedValues]; break; case EODatabaseDeleteOperator: procedureOpeName = @"EODeleteProcedure"; adaptorOperator = EOAdaptorDeleteOperator; /* MIRKO NSMutableArray *newKeys = AUTORELEASE([[NSMutableArray alloc] initWithCapacity:count]); NSMutableArray *newVals = AUTORELEASE([[NSMutableArray alloc] initWithCapacity:count]); if ([entity isReadOnly] == YES) { [NSException raise:NSInvalidArgumentException format:@"%@ -- %@ 0x%x: cannot delete object for readonly entity %@", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, [entity name]]; } [aOp setAdaptorOperator:EOAdaptorDeleteOperator]; count = [primaryKeys count]; for (i = 0; i < count; i++) { EOAttribute *attribute = [primaryKeys objectAtIndex:i]; NSString *key = [attribute name]; id val; if ([attribute isFlattened] == NO) { // Turbocat //val = [object storedValueForKey:key]; if (currentSnapshot) { val = [currentSnapshot objectForKey:key]; } if (!val) { [NSException raise:NSInvalidArgumentException format:@"%@ -- %@ 0x%x: cannot delete object (snapshot) '%@' for unkown primarykey value '%@'", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, currentSnapshot, key]; } if (val == nil) val = GDL2_EONull; [newKeys addObject:key]; [newVals addObject:val]; } } row = [NSDictionary dictionaryWithObjects:newVals forKeys:newKeys]; [aOp setQualifier:[entity qualifierForPrimaryKey:[op newRow]]]; ==>NO? in _commitTransaction [self forgetSnapshotForGlobalID:[op globalID]]; */ break; case EODatabaseNothingOperator: NSDebugMLLog(@"EODatabaseContext", @"Db Ope %@ for Nothing !!!", dbOpe); //Nothing? break; default: NSEmitTODO(); [self notImplemented: _cmd]; //TODO break; } NSDebugMLLog(@"EODatabaseContext", @"adaptorOperator=%d", adaptorOperator); // only for insert ?? storedProcedure = [entity storedProcedureForOperation: procedureOpeName]; if (storedProcedure) { adaptorOperator = EOAdaptorStoredProcedureOperator; NSEmitTODO(); [self notImplemented: _cmd]; //TODO } NSDebugMLLog(@"EODatabaseContext", @"adaptorOperator=%d", adaptorOperator); NSDebugMLLog(@"EODatabaseContext", @"adaptorOpe=%@", adaptorOpe); if (adaptorOpe) { [adaptorOpe setAdaptorOperator: adaptorOperator]; NSDebugMLLog(@"EODatabaseContext", @"valuesToWrite=%@", valuesToWrite); if (valuesToWrite) [adaptorOpe setChangedValues: valuesToWrite]; NSDebugMLLog(@"EODatabaseContext", @"lockingQualifier=%@", lockingQualifier); if (lockingQualifier) [adaptorOpe setQualifier: lockingQualifier]; [dbOpe addAdaptorOperation: adaptorOpe]; } NSDebugMLLog(@"EODatabaseContext", @"adaptorOpe=%@", adaptorOpe); } EOFLOGObjectFnStop(); } - (void) createAdaptorOperationsForDatabaseOperation: (EODatabaseOperation*)dbOpe { //OK for Update - Test for others NSArray *attributesToSave = nil; NSMutableArray *attributes = nil; int count=0; EODatabaseOperator dbOperator = EODatabaseNothingOperator; EOEntity *entity = [dbOpe entity]; //OK NSDictionary *rowDiffs = nil; NSDebugMLLog(@"EODatabaseContext", @"dbOpe=%@", dbOpe); [self processSnapshotForDatabaseOperation: dbOpe]; //OK dbOperator = [dbOpe databaseOperator]; //OK if (dbOperator == EODatabaseUpdateOperator) //OK { rowDiffs = [dbOpe rowDiffs]; NSDebugMLLog(@"EODatabaseContext", @"rowDiffs=%@", rowDiffs); } attributesToSave = [entity _attributesToSave]; //OK for update, OK for insert attributes = [NSMutableArray array]; count = [attributesToSave count]; if (count>0) { int i=0; IMP attributesAddObjectIMP=[attributes methodForSelector:@selector(addObject:)]; IMP attributesToSaveObjectAtIndexIMP=[attributesToSave methodForSelector:@selector(objectAtIndex:)]; for (i = 0; i < count; i++) { EOAttribute *attribute = GDL2_ObjectAtIndexWithImp(attributesToSave,attributesToSaveObjectAtIndexIMP,i); NSDebugMLLog(@"EODatabaseContext", @"attribute=%@", attribute); if (![attribute isFlattened] && ![attribute isDerived]) //VERIFY { GDL2_AddObjectWithImp(attributes,attributesAddObjectIMP,attribute); if ([rowDiffs objectForKey: [attribute name]] && [attribute isReadOnly]) { NSEmitTODO(); [self notImplemented: _cmd]; //TODO: excption ??? } } } }; NSDebugMLLog(@"EODatabaseContext", @"dbOpe=%@", dbOpe); NSDebugMLLog(@"EODatabaseContext", @"attributes=%@", attributes); [self createAdaptorOperationsForDatabaseOperation: dbOpe attributes: attributes]; } - (NSArray*) orderAdaptorOperations { //seems OK NSMutableArray *orderedAdaptorOpe = (NSMutableArray*)[NSMutableArray array]; EOFLOGObjectFnStart(); //MIRKO if (_delegateRespondsTo.willOrderAdaptorOperations == YES) orderedAdaptorOpe = (NSMutableArray*) [_delegate databaseContext: self willOrderAdaptorOperationsFromDatabaseOperations: NSAllMapTableValues(_dbOperationsByGlobalID)]; else { NSArray *entities = nil; NSMutableArray *adaptorOperations = [NSMutableArray array]; NSMapEnumerator dbOpeEnum; EOGlobalID *gid = nil; EODatabaseOperation *dbOpe = nil; NSHashTable *entitiesHashTable = NSCreateHashTable(NSNonOwnedPointerHashCallBacks,32); dbOpeEnum = NSEnumerateMapTable(_dbOperationsByGlobalID); while (NSNextMapEnumeratorPair(&dbOpeEnum, (void **)&gid, (void **)&dbOpe)) { NSArray *dbOpeAdaptorOperations = [dbOpe adaptorOperations]; int count = [dbOpeAdaptorOperations count]; NSDebugMLLog(@"EODatabaseContext", @"dbOpe=%@", dbOpe); NSDebugMLLog(@"EODatabaseContext", @"gid=%@", gid); if (count>0) { IMP oaiIMP=[dbOpeAdaptorOperations methodForSelector: @selector(objectAtIndex:)]; int i=0; for (i = 0; i < count; i++) { EOAdaptorOperation *adaptorOpe = GDL2_ObjectAtIndexWithImp(dbOpeAdaptorOperations,oaiIMP,i); EOEntity *entity = nil; NSDebugMLLog(@"EODatabaseContext", @"adaptorOpe=%@", adaptorOpe); [adaptorOperations addObject: adaptorOpe]; entity = [adaptorOpe entity]; NSDebugMLLog(@"EODatabaseContext", @"entity=%@", [entity name]); NSHashInsertIfAbsent(entitiesHashTable, entity); } }; } entities = NSAllHashTableObjects(entitiesHashTable); NSFreeHashTable(entitiesHashTable); entitiesHashTable = NULL; NSDebugMLLog(@"EODatabaseContext", @"entities=%@", entities); { NSArray *entityNameOrderingArray = [self entityNameOrderingArrayForEntities:entities]; int iAdaptoOpe = 0; int adaptorOpeCount = [adaptorOperations count]; int entitiesCount = [entityNameOrderingArray count]; if (entitiesCount>0) { IMP entityObjectAtIndexIMP=[entityNameOrderingArray methodForSelector: @selector(objectAtIndex:)]; IMP opeObjectAtIndexIMP=[adaptorOperations methodForSelector: @selector(objectAtIndex:)]; int iEntity=0; for (iEntity = 0; iEntity < entitiesCount; iEntity++) { EOEntity *entity = GDL2_ObjectAtIndexWithImp(entityNameOrderingArray,entityObjectAtIndexIMP,iEntity); NSDebugMLLog(@"EODatabaseContext", @"entity=%@", [entity name]); for (iAdaptoOpe = 0; iAdaptoOpe < adaptorOpeCount; iAdaptoOpe++) { EOAdaptorOperation *adaptorOpe = GDL2_ObjectAtIndexWithImp(adaptorOperations,opeObjectAtIndexIMP,iAdaptoOpe); EOEntity *opeEntity = [adaptorOpe entity]; if (opeEntity == entity) [orderedAdaptorOpe addObject: adaptorOpe]; } } }; NSAssert2([orderedAdaptorOpe count] == adaptorOpeCount, @"Different ordered (%d) an unordered adaptor operations count (%d)", [orderedAdaptorOpe count], adaptorOpeCount); } } EOFLOGObjectFnStop(); return orderedAdaptorOpe; } - (NSArray*) entitiesOnWhichThisEntityDepends: (EOEntity*)entity { NSMutableArray *entities = nil; NSArray *relationships = nil; int count; EOFLOGObjectFnStart(); relationships = [entity relationships]; count = [relationships count]; if (count>0) { IMP oaiIMP=[relationships methodForSelector: @selector(objectAtIndex:)]; int i=0; for (i = 0; i < count; i++) { EORelationship *relationship = GDL2_ObjectAtIndexWithImp(relationships,oaiIMP,i); NSDebugMLLog(@"EODatabaseContext", @"relationship=%@", relationship); if (![relationship isToMany]) //If to many: do nothing { if ([relationship isFlattened]) { //TODO VERIFY EOExpressionArray *definitionArray=[relationship _definitionArray]; EORelationship *firstRelationship=[definitionArray objectAtIndex:0]; EOEntity *firstDefEntity=[firstRelationship destinationEntity]; NSArray *defDependEntities=[self entitiesOnWhichThisEntityDepends:firstDefEntity]; if ([defDependEntities count]>0) { if (!entities) entities = [NSMutableArray array]; [entities addObjectsFromArray: defDependEntities]; }; } else { //Here ?? EOEntity *destinationEntity = [relationship destinationEntity]; EORelationship *inverseRelationship = [relationship anyInverseRelationship]; if ([inverseRelationship isToMany]) { //Do nothing ? } else { if ([inverseRelationship propagatesPrimaryKey]) { //OK if (!entities) entities = [NSMutableArray array]; [entities addObject: destinationEntity]; } else { if ([inverseRelationship ownsDestination]) { NSEmitTODO(); [self notImplemented: _cmd]; //TODO } } } } } } } EOFLOGObjectFnStop(); return entities; } - (NSArray*)entityNameOrderingArrayForEntities: (NSArray*)entities { //TODO NSMutableArray *ordering = [NSMutableArray array]; NSMutableSet *orderedEntities = [NSMutableSet set]; /*EODatabase *database = [self database]; NSArray *models = [database models];*/ NSMutableDictionary *dependsDict = [NSMutableDictionary dictionary]; int count = [entities count]; //TODO NSArray* originalOrdering=... /*TODO for each mdoel: userInfo (ret nil) */ if (count>0) { IMP oaiIMP=[entities methodForSelector: @selector(objectAtIndex:)]; int i=0; for (i = 0; i < count; i++) { //OK EOEntity *entity=GDL2_ObjectAtIndexWithImp(entities,oaiIMP,i); NSArray *dependsEntities = [self entitiesOnWhichThisEntityDepends: entity]; if ([dependsEntities count]) [dependsDict setObject: dependsEntities forKey: [entity name]]; } ordering = [NSMutableArray array]; for (i = 0; i < count; i++) { EOEntity *entity=GDL2_ObjectAtIndexWithImp(entities,oaiIMP,i); [self insertEntity: entity intoOrderingArray: ordering withDependencies: dependsDict processingSet: orderedEntities]; } } //TODO /* model userInfo //ret nil setUserInfo: {EOEntityOrdering = ordering; } */ return ordering; } - (BOOL) isValidQualifierTypeForAttribute: (EOAttribute*)attribute { //OK BOOL isValid = NO; EOEntity *entity = nil; EOModel *model = nil; EODatabase *database = nil; EOAdaptor *adaptor = nil; NSString *externalType = nil; EOFLOGObjectFnStart(); entity = [attribute entity]; NSAssert1(entity, @"No entity for attribute %@", attribute); model = [entity model]; database = [self database]; adaptor = [database adaptor]; externalType = [attribute externalType]; isValid = [adaptor isValidQualifierType: externalType model: model]; //TODO REMOVE if (!isValid) { NSDebugMLLog(@"EODatabaseContext",@"attribute=%@", attribute); NSDebugMLLog(@"EODatabaseContext",@"externalType=%@", externalType); NSDebugMLLog(@"EODatabaseContext",@"entity name=%@", entity); } EOFLOGObjectFnStop(); return isValid; } - (id) lockingNonQualifiableAttributes: (NSArray*)attributes { //TODO finish EOEntity *entity = nil; NSArray *attributesUsedForLocking = nil; int count = 0; count = [attributes count]; if (count>0) { IMP oaiIMP=[attributes methodForSelector: @selector(objectAtIndex:)]; int i=0; for (i = 0; i < count; i++) { id attribute = GDL2_ObjectAtIndexWithImp(attributes,oaiIMP,i); if (!entity) { entity = [attribute entity]; attributesUsedForLocking = [entity attributesUsedForLocking]; } if (![self isValidQualifierTypeForAttribute: attribute]) { NSEmitTODO(); // [self notImplemented:_cmd]; //TODO } else { NSEmitTODO(); //Nothing ?? // [self notImplemented:_cmd]; //TODO ?? } } }; return nil;//?? } - (NSArray*) lockingAttributesForAttributes: (NSArray*)attributes entity: (EOEntity*)entity { //TODO NSArray *retAttributes = nil; int count = 0; NSArray *attributesUsedForLocking = nil; EOFLOGObjectFnStart(); attributesUsedForLocking = [entity attributesUsedForLocking]; count = [attributes count]; if (count>0) { IMP oaiIMP=[attributes methodForSelector: @selector(objectAtIndex:)]; int i=0; for (i = 0; i < count; i++) { id attribute = GDL2_ObjectAtIndexWithImp(attributes,oaiIMP,i); //do this on 1st only BOOL isFlattened = [attribute isFlattened]; if (isFlattened) { NSEmitTODO(); [self notImplemented: _cmd]; //TODO } else { NSArray *rootAttributesUsedForLocking = [entity rootAttributesUsedForLocking]; retAttributes = rootAttributesUsedForLocking; } } }; EOFLOGObjectFnStop(); return retAttributes; //TODO } - (NSArray*) primaryKeyAttributesForAttributes: (NSArray*)attributes entity: (EOEntity*)entity { //TODO NSArray *retAttributes = nil; int count = 0; EOFLOGObjectFnStart(); //TODO count = [attributes count]; if (count>0) { IMP oaiIMP=[attributes methodForSelector: @selector(objectAtIndex:)]; int i=0; for (i = 0; i < count; i++) { id attribute = GDL2_ObjectAtIndexWithImp(attributes,oaiIMP,i); BOOL isFlattened = [attribute isFlattened]; //call isFlattened on 1st only if (isFlattened) { NSEmitTODO(); [self notImplemented: _cmd]; //TODO } else { NSArray *primaryKeyAttributes = [entity primaryKeyAttributes]; retAttributes = primaryKeyAttributes; } } }; EOFLOGObjectFnStop(); return retAttributes; } - (EOQualifier*) qualifierForLockingAttributes: (NSArray*)attributes primaryKeyAttributes: (NSArray*)primaryKeyAttributes entity: (EOEntity*)entity snapshot: (NSDictionary*)snapshot { //OK EOQualifier *qualifier = nil; NSMutableArray *qualifiers = nil; int which; EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"attributes=%@", attributes); NSDebugMLLog(@"EODatabaseContext", @"primaryKeyAttributes=%@", primaryKeyAttributes); NSDebugMLLog(@"EODatabaseContext", @"snapshot=%@", snapshot); //First use primaryKeyAttributes, next use attributes for (which = 0; which < 2; which++) { NSArray *array = (which == 0 ? primaryKeyAttributes : attributes); int count = [array count]; if (count>0) { IMP oaiIMP=[array methodForSelector: @selector(objectAtIndex:)]; int i=0; for (i = 0; i < count; i++) { EOAttribute *attribute = GDL2_ObjectAtIndexWithImp(array,oaiIMP,i); NSDebugMLLog(@"EODatabaseContext", @"attribute=%@", attribute); if (which == 0 || ![primaryKeyAttributes containsObject: attribute])// Test if we haven't already processed it { if (![self isValidQualifierTypeForAttribute: attribute]) { NSLog(@"Invalid externalType for attribute '%@' of entity named '%@' - model '%@'", [attribute name], [[attribute entity] name], [[[attribute entity] model] name]); NSEmitTODO(); [self notImplemented: _cmd]; //TODO } else { NSString *attributeName = nil; NSString *snapName = nil; id value = nil; EOQualifier *aQualifier = nil; attributeName = [attribute name]; NSAssert1(attributeName, @"no attribute name for attribute %@", attribute); snapName = [entity snapshotKeyForAttributeName: attributeName]; NSAssert2(snapName, @"no snapName for attribute %@ in entity %@", attributeName, [entity name]); value = [snapshot objectForKey:snapName]; if (!value) { NSDebugMLLog(@"EODatabaseContext", @"NO VALUE"); } NSAssert4(value, @"no value for snapshotKey '%@' in snapshot (address=%p) %@ for entity %@", snapName, snapshot, snapshot, [entity name]); aQualifier = [EOKeyValueQualifier qualifierWithKey: attributeName operatorSelector: @selector(isEqualTo:) value: value]; NSDebugMLLog(@"EODatabaseContext", @"aQualifier=%@", aQualifier); if (!qualifiers) qualifiers = [NSMutableArray array]; [qualifiers addObject: aQualifier]; NSDebugMLLog(@"EODatabaseContext", @"qualifiers=%@", qualifiers); } } } } } if ([qualifiers count] == 1) qualifier = [qualifiers objectAtIndex: 0]; else qualifier = [EOAndQualifier qualifierWithQualifierArray: qualifiers]; NSDebugMLLog(@"EODatabaseContext", @"qualifier=%@", qualifier); EOFLOGObjectFnStop(); return qualifier; } - (void) insertEntity: (EOEntity*)entity intoOrderingArray: (NSMutableArray*)orderingArray withDependencies: (NSDictionary*)dependencies processingSet: (NSMutableSet*)processingSet { //TODO: manage dependencies {CustomerCredit = (); } // and processingSet [orderingArray addObject: entity]; [processingSet addObject: [entity name]]; } - (void) processSnapshotForDatabaseOperation: (EODatabaseOperation*)dbOpe { //Near OK EOAdaptor *adaptor = [_database adaptor];//OK EOEntity *entity = [dbOpe entity];//OK NSDictionary *newRow = nil; NSDictionary *dbSnapshot = nil; NSEnumerator *attrNameEnum = nil; id attrName = nil; IMP enumNO=NULL; // nextObject EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"dbOpe=%@", dbOpe); newRow = [dbOpe newRow]; //OK{a3code = Q77; code = Q7; numcode = 007; } //ALLOK NSDebugMLLog(@"EODatabaseContext", @"newRow %p=%@", newRow, newRow); dbSnapshot = [dbOpe dbSnapshot]; NSDebugMLLog(@"EODatabaseContext", @"dbSnapshot %p=%@", dbSnapshot, dbSnapshot); attrNameEnum = [newRow keyEnumerator]; enumNO=NULL; while ((attrName = GDL2_NextObjectWithImpPtr(attrNameEnum,&enumNO))) { EOAttribute *attribute = [entity attributeNamed: attrName]; id newRowValue = nil; id dbSnapshotValue = nil; NSDebugMLLog(@"EODatabaseContext", @"attribute=%@", attribute); newRowValue = [newRow objectForKey:attrName]; NSDebugMLLog(@"EODatabaseContext", @"newRowValue=%@", newRowValue); dbSnapshotValue = [dbSnapshot objectForKey: attrName]; NSDebugMLLog(@"EODatabaseContext", @"dbSnapshotValue=%@", dbSnapshotValue); if (dbSnapshotValue && ![newRowValue isEqual: dbSnapshotValue]) { id adaptorValue = [adaptor fetchedValueForValue: newRowValue attribute: attribute]; //this call is OK NSDebugMLLog(@"EODatabaseContext", @"adaptorValue=%@", adaptorValue); //TODO-NOW SO WHAT ?? may be replacing newRow diff values by adaptorValue if different ???? } } EOFLOGObjectFnStop(); } - (NSDictionary*) valuesToWriteForAttributes: (NSArray*)attributes entity: (EOEntity*)entity changedValues: (NSDictionary*)changedValues { //NEAR OK NSMutableDictionary *valuesToWrite = [NSMutableDictionary dictionary]; BOOL isReadOnlyEntity = NO; EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"attributes=%@", attributes); NSDebugMLLog(@"EODatabaseContext", @"entity=%@", [entity name]); NSDebugMLLog(@"EODatabaseContext", @"changedValues=%@", changedValues); isReadOnlyEntity = [entity isReadOnly]; NSDebugMLLog(@"EODatabaseContext", @"isReadOnlyEntity=%s", (isReadOnlyEntity ? "YES" : "NO")); if (isReadOnlyEntity) { NSEmitTODO(); [self notImplemented: _cmd]; //TODO } else { int count = [attributes count]; if (count>0) { IMP oaiIMP=[attributes methodForSelector: @selector(objectAtIndex:)]; int i=0; for (i = 0; i < count; i++) { EOAttribute *attribute = GDL2_ObjectAtIndexWithImp(attributes,oaiIMP,i); BOOL isReadOnly = [attribute isReadOnly]; NSDebugMLLog(@"EODatabaseContext", @"attribute=%@", attribute); NSDebugMLLog(@"EODatabaseContext", @"isReadOnly=%s", (isReadOnly ? "YES" : "NO")); if (isReadOnly) { NSEmitTODO(); NSDebugMLog(@"attribute=%@", attribute); [self notImplemented: _cmd]; //TODO } else { NSString *attrName = [attribute name]; NSString *snapName = nil; id value = nil; NSDebugMLLog(@"EODatabaseContext", @"attrName=%@", attrName); snapName = [entity snapshotKeyForAttributeName: attrName]; NSDebugMLLog(@"EODatabaseContext", @"snapName=%@", snapName); value = [changedValues objectForKey: snapName]; NSDebugMLLog(@"EODatabaseContext", @"value=%@", value); if (value) [valuesToWrite setObject: value forKey: attrName]; } } } } NSDebugMLLog(@"EODatabaseContext", @"valuesToWrite=%@", valuesToWrite); EOFLOGObjectFnStop(); return valuesToWrite; } @end @implementation EODatabaseContext(EOBatchFaulting) - (void)batchFetchRelationship: (EORelationship *)relationship forSourceObjects: (NSArray *)objects editingContext: (EOEditingContext *)editingContext { // TODO NSMutableArray *qualifierArray, *valuesArray, *toManySnapshotArray; NSMutableDictionary *values; NSArray *array; NSEnumerator *objsEnum, *joinsEnum, *keyEnum; NSString *key; EOFetchSpecification *fetch; EOQualifier *qualifier; EOFault *fault; EOJoin *join; BOOL equal; int i, count; id object; NSString* relationshipName = nil; IMP globalIDForObjectIMP=NULL; IMP toManySnapArrayObjectAtIndexIMP=NULL; IMP objsEnumNO=NULL; IMP objectsOAI=NULL; qualifierArray = AUTORELEASE([GDL2_alloc(NSMutableArray) init]); valuesArray = AUTORELEASE([GDL2_alloc(NSMutableArray) init]); toManySnapshotArray = AUTORELEASE([GDL2_alloc(NSMutableArray) init]); toManySnapArrayObjectAtIndexIMP=[toManySnapshotArray methodForSelector: @selector(objectAtIndex:)]; relationshipName = [relationship name]; objsEnum = [objects objectEnumerator]; objsEnumNO=NULL; while ((object = GDL2_NextObjectWithImpPtr(objsEnum,&objsEnumNO))) { IMP joinsEnumNO=NO; values = AUTORELEASE([GDL2_alloc(NSMutableDictionary) initWithCapacity: 4]); fault = [object valueForKey: relationshipName]; [EOFault clearFault: fault]; joinsEnum = [[relationship joins] objectEnumerator]; while ((join = GDL2_NextObjectWithImpPtr(joinsEnum,&joinsEnumNO))) { [values setObject: [object valueForKey: [[join sourceAttribute] name]] forKey: [[join destinationAttribute] name]]; } [valuesArray addObject: values]; [toManySnapshotArray addObject: AUTORELEASE([GDL2_alloc(NSMutableArray) init])]; [qualifierArray addObject: [EOQualifier qualifierToMatchAllValues: values]]; } if ([qualifierArray count] == 1) qualifier = [qualifierArray objectAtIndex: 0]; else qualifier = [EOOrQualifier qualifierWithQualifierArray: qualifierArray]; fetch = [EOFetchSpecification fetchSpecificationWithEntityName: [[relationship destinationEntity] name] qualifier: qualifier sortOrderings: nil]; array = [self objectsWithFetchSpecification: fetch editingContext: editingContext]; count = [valuesArray count]; if (count>0) { IMP oaiIMP=[valuesArray methodForSelector: @selector(objectAtIndex:)]; objsEnum = [array objectEnumerator]; objsEnumNO=NULL; while ((object = GDL2_NextObjectWithImpPtr(objsEnum,&objsEnumNO))) { IMP objectVFK=NULL; // valueForKey: for (i = 0; i < count; i++) { IMP keyEnumNO=NULL; // nextObject IMP valuesOFK=NULL; // objectForKey: equal = YES; values = GDL2_ObjectAtIndexWithImp(valuesArray,oaiIMP,i); keyEnum = [values keyEnumerator]; while ((key = GDL2_NextObjectWithImpPtr(keyEnum,&keyEnumNO))) { if ([GDL2_ValueForKeyWithImpPtr(object,&objectVFK,key) isEqual: GDL2_ObjectForKeyWithImpPtr(values,&valuesOFK,key)] == NO) { equal = NO; break; } } if (equal == YES) { EOGlobalID* gid = nil; id snapshot = GDL2_ObjectAtIndexWithImp(toManySnapshotArray,toManySnapArrayObjectAtIndexIMP,i); [[GDL2_ObjectAtIndexWithImpPtr(objects,&objectsOAI,i) valueForKey: relationshipName] addObject: object]; gid=EOEditingContext_globalIDForObjectWithImpPtr(editingContext,&globalIDForObjectIMP,object); [snapshot addObject: gid]; break; } } } } NSDebugMLLog(@"EODatabaseContext",@"** 3"); //==> see _registerSnapshot:forSourceGlobalID:relationshipName:editingContext: if (count>0) { for (i = 0; i < count; i++) { id snapshot = GDL2_ObjectAtIndexWithImp(toManySnapshotArray,toManySnapArrayObjectAtIndexIMP,i); EOGlobalID* gid=EOEditingContext_globalIDForObjectWithImpPtr(editingContext, &globalIDForObjectIMP, GDL2_ObjectAtIndexWithImpPtr(objects,&objectsOAI,i)); [_database recordSnapshot: snapshot forSourceGlobalID: gid relationshipName: relationshipName]; }; } NSDebugMLLog(@"EODatabaseContext", @"** 4"); } @end @implementation EODatabaseContext (EODatabaseContextPrivate) - (void) _fireArrayFault: (id)object { //OK ?? BOOL fetchIt = YES; EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"object=%p", object); if (_delegateRespondsTo.shouldFetchObjectFault == YES) fetchIt = [_delegate databaseContext: self shouldFetchObjectFault: object]; if (fetchIt) { /*Class targetClass = Nil; void *extraData = NULL;*/ EOAccessArrayFaultHandler *handler = (EOAccessArrayFaultHandler *)[EOFault handlerForFault:object]; EOEditingContext *context = [handler editingContext]; NSString *relationshipName= [handler relationshipName]; EOKeyGlobalID *gid = [handler sourceGlobalID]; NSArray *objects = nil; NSDebugMLLog(@"EODatabaseContext", @"relationshipName=%@", relationshipName); NSDebugMLLog(@"EODatabaseContext", @"gid=%@", gid); objects = [context objectsForSourceGlobalID: gid relationshipName: relationshipName editingContext: context]; [EOFault clearFault: object]; //?? /* in clearFault [handler faultWillFire:object]; targetClass=[handler targetClass]; extraData=[handler extraData]; RELEASE(handler); */ NSDebugMLLog(@"EODatabaseContext", @"NEAR FINISHED 1 object count=%d %p %@", [object count], object, object); NSDebugMLLog(@"EODatabaseContext", @"NEAR FINISHED 1 objects count=%d %p %@", [objects count], objects, objects); if (objects != object) { //No, not needed [object removeObjectsInArray:objects];//Because some objects may be here. We don't want duplicate. It's a hack because I don't see why there's objects in object ! NSDebugMLLog(@"EODatabaseContext", @"NEAR FINISHED 1 object count=%d %p %@", [object count], object, object); [object addObjectsFromArray: objects]; NSDebugMLLog(@"EODatabaseContext", @"NEAR FINISHED 2 object count=%d %@", [object count], object); } } //END! /* } - (void)_batchToMany:(id)fault withHandler:(EOAccessArrayFaultHandler *)handler { */ /* EOAccessArrayFaultHandler *usedHandler, *firstHandler, *lastHandler; EOAccessArrayFaultHandler *bufHandler; NSMutableDictionary *batchBuffer; EOEditingContext *context; NSMutableArray *objects; EOKeyGlobalID *gid; EOEntity *entity; EORelationship *relationship; unsigned int maxBatch; BOOL batch = YES, changeBatch = NO; gid = [handler sourceGlobalID];//OK context = [handler editingContext];//OK entity = [_database entityNamed:[gid entityName]];//-done relationship = [entity relationshipNamed:[handler relationshipName]];//-done maxBatch = [relationship numberOfToManyFaultsToBatchFetch];//-done batchBuffer = [_batchToManyFaultBuffer objectForKey:[entity name]]; bufHandler = [batchBuffer objectForKey:[relationship name]]; objects = [NSMutableArray array]; [objects addObject:[context objectForGlobalID:gid]];//-done firstHandler = lastHandler = nil; usedHandler = handler; if (bufHandler && [bufHandler isEqual:usedHandler] == YES) changeBatch = YES; if (maxBatch > 1) { maxBatch--; while (maxBatch--) { if (lastHandler == nil) { usedHandler = (EOAccessArrayFaultHandler *)[usedHandler previous]; if (usedHandler) firstHandler = usedHandler; else lastHandler = usedHandler = (EOAccessArrayFaultHandler *) [handler next]; } else { usedHandler = (EOAccessArrayFaultHandler *)[lastHandler next]; if (usedHandler) lastHandler = usedHandler; } if (usedHandler == nil) break; if (bufHandler && [bufHandler isEqual:usedHandler] == YES) changeBatch = YES; [objects addObject:[context objectForGlobalID:[usedHandler sourceGlobalID]]]; } } if (firstHandler == nil) firstHandler = handler; if (lastHandler == nil) lastHandler = handler; usedHandler = (id)[firstHandler previous]; bufHandler = (id)[lastHandler next]; if (usedHandler) [usedHandler _linkNext:bufHandler]; usedHandler = bufHandler; if (usedHandler) { [usedHandler _linkPrev:[firstHandler previous]]; if (bufHandler == nil) bufHandler = usedHandler; } if (changeBatch == YES) { if (bufHandler) [batchBuffer setObject:bufHandler forKey:[relationship name]]; else [batchBuffer removeObjectForKey:[relationship name]]; } [self batchFetchRelationship:relationship forSourceObjects:objects editingContext:context]; */ EOFLOGObjectFnStop(); } - (void) _fireFault: (id)object { //TODO BOOL fetchIt = YES;//MIRKO EOFLOGObjectFnStart(); //MIRKO NSDebugMLLog(@"EODatabaseContext",@"Fire Fault: object %p of class %@", object,[object class]); if (_delegateRespondsTo.shouldFetchObjectFault == YES) { fetchIt = [_delegate databaseContext: self shouldFetchObjectFault: object]; } if (fetchIt) { EOAccessFaultHandler *handler; EOEditingContext *context; EOGlobalID *gid; NSDictionary *snapshot; EOEntity *entity = nil; NSString *entityName = nil; handler = (EOAccessFaultHandler *)[EOFault handlerForFault: object]; context = [handler editingContext]; gid = [handler globalID]; snapshot = EODatabaseContext_snapshotForGlobalIDWithImpPtr(self,NULL,gid); //nil if (snapshot) { //TODO _fireFault snapshot NSEmitTODO(); // [self notImplemented: _cmd]; //TODO } entity = [self entityForGlobalID: gid]; entityName = [entity name]; if ([entity cachesObjects]) { //TODO _fireFault [entity cachesObjects] NSEmitTODO(); [self notImplemented: _cmd]; //TODO } //??? generation # EOAccessGenericFaultHandler//ret 2 { EOAccessFaultHandler *previousHandler; EOAccessFaultHandler *nextHandler; EOFetchSpecification *fetchSpecif; NSArray *objects; EOQualifier *qualifier; /*int maxNumberOfInstancesToBatchFetch = [entity maxNumberOfInstancesToBatchFetch]; NSDictionary *snapshot = [self snapshotForGlobalID: gid];*///nil //TODO use it ! NSDictionary *pk = [entity primaryKeyForGlobalID: (EOKeyGlobalID *)gid]; EOQualifier *pkQualifier = [entity qualifierForPrimaryKey: pk]; NSMutableArray *qualifiers = [NSMutableArray array]; [qualifiers addObject: pkQualifier]; previousHandler = (EOAccessFaultHandler *)[handler previous]; nextHandler = (EOAccessFaultHandler *)[handler next]; //nil fetchSpecif = AUTORELEASE([EOFetchSpecification new]); [fetchSpecif setEntityName: entityName]; qualifier = [EOOrQualifier qualifierWithQualifierArray: qualifiers]; [fetchSpecif setQualifier: qualifier]; objects = [self objectsWithFetchSpecification: fetchSpecif editingContext: context]; NSDebugMLLog(@"EODatabaseContext", @"objects %p=%@ class=%@", objects, objects, [objects class]); } } EOFLOGObjectFnStop(); } /* - (void)_batchToOne:(id)fault withHandler:(EOAccessFaultHandler *)handler { EOAccessFaultHandler *usedHandler, *firstHandler, *lastHandler; EOAccessFaultHandler *bufHandler; EOFetchSpecification *fetch; EOEditingContext *context; EOKeyGlobalID *gid; EOQualifier *qualifier; EOEntity *entity; NSMutableArray *qualifierArray; BOOL batch = YES, changeBatch = NO; unsigned int maxBatch; if (_delegateRespondsTo.shouldFetchObjectFault == YES)//-done batch = [_delegate databaseContext:self shouldFetchObjectFault:fault];//-done if (batch == NO)//-done return;//-done gid = [handler globalID];//-done context = [handler editingContext];//-done entity = [_database entityNamed:[gid entityName]];//-done maxBatch = [entity maxNumberOfInstancesToBatchFetch];//-done bufHandler = [_batchFaultBuffer objectForKey:[entity name]]; firstHandler = lastHandler = nil; usedHandler = handler; if (bufHandler && [bufHandler isEqual:usedHandler] == YES) changeBatch = YES; if (maxBatch <= 1) { qualifier = [entity qualifierForPrimaryKey: [entity primaryKeyForGlobalID:gid]]; } else { qualifierArray = [NSMutableArray array]; [qualifierArray addObject: [entity qualifierForPrimaryKey: [entity primaryKeyForGlobalID:gid]]]; maxBatch--; while (maxBatch--) { if (lastHandler == nil) { usedHandler = (EOAccessFaultHandler *)[usedHandler previous]; if (usedHandler) firstHandler = usedHandler; else lastHandler = usedHandler = (EOAccessFaultHandler *)[handler next]; } else { usedHandler = (EOAccessFaultHandler *)[lastHandler next]; if (usedHandler) lastHandler = usedHandler; } if (usedHandler == nil) break; if (changeBatch == NO && bufHandler && [bufHandler isEqual:usedHandler] == YES) changeBatch = YES; [qualifierArray addObject: [entity qualifierForPrimaryKey: [entity primaryKeyForGlobalID: [usedHandler globalID]]]]; } qualifier = AUTORELEASE([[EOOrQualifier alloc] initWithQualifierArray:qualifierArray]); } if (firstHandler == nil) firstHandler = handler; if (lastHandler == nil) lastHandler = handler; usedHandler = (id)[firstHandler previous]; bufHandler = (id)[lastHandler next]; if (usedHandler) [usedHandler _linkNext:bufHandler]; usedHandler = bufHandler; if (usedHandler) { [usedHandler _linkPrev:[firstHandler previous]]; if (bufHandler == nil) bufHandler = usedHandler; } if (changeBatch == YES) { if (bufHandler) [_batchFaultBuffer setObject:bufHandler forKey:[entity name]]; else [_batchFaultBuffer removeObjectForKey:[entity name]]; } fetch = [EOFetchSpecification fetchSpecificationWithEntityName:[entity name] qualifier:qualifier sortOrderings:nil];//-done [context objectsWithFetchSpecification:fetch];//-done }*/ // Clear all the faults for the relationship pointed by the source objects and // make sure to perform only a single, efficient, fetch (two fetches if the // relationship is many to many). - (void)_addBatchForGlobalID: (EOKeyGlobalID *)globalID fault: (EOFault *)fault { EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"globalID=%@", globalID); NSDebugMLLog(@"EODatabaseContext", @"fault=%@", fault); if (fault) { EOAccessGenericFaultHandler *handler = nil; NSString *entityName = [globalID entityName]; NSDebugMLLog(@"EODatabaseContext", @"entityName=%@", entityName); handler = [_batchFaultBuffer objectForKey: entityName]; NSDebugMLLog(@"EODatabaseContext", @"handler=%@", handler); if (handler) { [(EOAccessGenericFaultHandler *) [EOFault handlerForFault: fault] linkAfter: handler usingGeneration: [handler generation]]; } else { handler = (EOAccessGenericFaultHandler *)[EOFault handlerForFault: fault]; NSAssert1(handler, @"No handler for fault:%@", fault); [_batchFaultBuffer setObject: handler forKey: entityName]; } } EOFLOGObjectFnStop(); } - (void)_removeBatchForGlobalID: (EOKeyGlobalID *)globalID fault: (EOFault *)fault { EOAccessGenericFaultHandler *handler, *prevHandler, *nextHandler; NSString *entityName = [globalID entityName]; handler = (EOAccessGenericFaultHandler *)[EOFault handlerForFault: fault]; prevHandler = [handler previous]; nextHandler = [handler next]; if (prevHandler) [prevHandler _linkNext: nextHandler]; if (nextHandler) [nextHandler _linkPrev: prevHandler]; if ([_batchFaultBuffer objectForKey: entityName] == handler) { if (prevHandler) [_batchFaultBuffer setObject: prevHandler forKey: entityName]; else if (nextHandler) [_batchFaultBuffer setObject: nextHandler forKey: entityName]; else [_batchFaultBuffer removeObjectForKey: entityName]; } } - (void)_addToManyBatchForSourceGlobalID: (EOKeyGlobalID *)globalID relationshipName: (NSString *)relationshipName fault: (EOFault *)fault { if (fault) { NSMutableDictionary *buf; EOAccessGenericFaultHandler *handler; NSString *entityName = [globalID entityName]; buf = [_batchToManyFaultBuffer objectForKey: entityName]; if (buf == nil) { buf = [NSMutableDictionary dictionaryWithCapacity: 8]; [_batchToManyFaultBuffer setObject: buf forKey: entityName]; } handler = [buf objectForKey: relationshipName]; if (handler) { [(EOAccessGenericFaultHandler *) [EOFault handlerForFault: fault] linkAfter: handler usingGeneration: [handler generation]]; } else [buf setObject: [EOFault handlerForFault: fault] forKey: relationshipName]; } } @end @implementation EODatabaseContext (EODatabaseSnapshotting) - (void)recordSnapshot: (NSDictionary *)snapshot forGlobalID: (EOGlobalID *)gid { EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"self=%p database=%p", self, _database); NSDebugMLLog(@"EODatabaseContext", @"self=%p _uniqueStack %p=%@", self, _uniqueStack, _uniqueStack); if ([_uniqueStack count] > 0) { NSMutableDictionary *snapshots = [_uniqueStack lastObject]; [snapshots setObject: snapshot forKey: gid]; } else { NSEmitTODO(); NSWarnLog(@"_uniqueStack is empty. May be there's no runing transaction !", ""); [self notImplemented: _cmd]; //TODO } NSDebugMLLog(@"EODatabaseContext", @"self=%p _uniqueStack %p=%@", self, _uniqueStack, _uniqueStack); EOFLOGObjectFnStop(); } - (NSDictionary *)snapshotForGlobalID: (EOGlobalID *)gid { return [self snapshotForGlobalID: gid after: EODistantPastTimeInterval]; } - (NSDictionary *)snapshotForGlobalID: (EOGlobalID *)gid after: (NSTimeInterval)ti { //OK NSDictionary *snapshot = nil; EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"self=%p database=%p", self, _database); NSDebugMLLog(@"EODatabaseContext", @"gid %p=%@", gid, gid); snapshot = [self localSnapshotForGlobalID: gid]; if (!snapshot) { NSAssert(_database, @"No database"); snapshot = [_database snapshotForGlobalID: gid after: ti]; } NSDebugMLLog(@"EODatabaseContext", @"snapshot for gid %@: %p %@", gid, snapshot, snapshot); EOFLOGObjectFnStop(); return snapshot; } - (void)recordSnapshot: (NSArray *)gids forSourceGlobalID: (EOGlobalID *)gid relationshipName: (NSString *)name { EOFLOGObjectFnStart(); NSEmitTODO(); [self notImplemented: _cmd]; //TODO /* NSMutableDictionary *toMany = [_toManySnapshots objectForKey:gid]; if (toMany == nil) { toMany = [NSMutableDictionary dictionaryWithCapacity:16]; [_toManySnapshots setObject:toMany forKey:gid]; } [toMany setObject:gids forKey:name]; */ EOFLOGObjectFnStop(); } - (NSArray *)snapshotForSourceGlobalID: (EOGlobalID *)gid relationshipName: (NSString *)name { NSArray *snapshot = nil; EOFLOGObjectFnStart(); NSEmitTODO(); [self notImplemented: _cmd]; //TODO /* snapshot = [[_toManySnapshots objectForKey:gid] objectForKey:name]; if (!snapshot) snapshot=[_database snapshotForSourceGlobalID:gid relationshipName:name]; */ EOFLOGObjectFnStop(); return snapshot; } - (NSDictionary *)localSnapshotForGlobalID: (EOGlobalID *)gid { //OK NSDictionary *snapshot = nil; int snapshotsDictCount = 0; EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"self=%p database=%p", self, _database); snapshotsDictCount = [_uniqueStack count]; if (snapshotsDictCount>0) { int i = 0; IMP oaiIMP=[_uniqueStack methodForSelector: @selector(objectAtIndex:)]; for (i = 0; !snapshot && i < snapshotsDictCount; i++) { NSDictionary *snapshots = GDL2_ObjectAtIndexWithImp(_uniqueStack,oaiIMP,i); snapshot = [snapshots objectForKey: gid]; } }; NSDebugMLLog(@"EODatabaseContext", @"snapshot for gid %@: %p %@", gid, snapshot, snapshot); EOFLOGObjectFnStop(); return snapshot; } - (NSArray *)localSnapshotForSourceGlobalID: (EOGlobalID *)gid relationshipName: (NSString *)name { NSArray *snapshot = nil; //TODO EOFLOGObjectFnStart(); NSEmitTODO(); [self notImplemented: _cmd]; //TODO /* return [[_toManySnapshots objectForKey:gid] objectForKey:name]; */ EOFLOGObjectFnStop(); return snapshot; } - (void)forgetSnapshotForGlobalID: (EOGlobalID *)gid { //TODO-VERIFY deleteStack EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"self=%p database=%p [_uniqueStack count]=%d", self, _database,[_uniqueStack count]); if ([_uniqueStack count] > 0) { NSMutableDictionary *uniqueSS = [_uniqueStack lastObject]; NSMutableDictionary *uniqArSS = [_uniqueArrayStack lastObject]; NSMutableSet *deleteSS = [_deleteStack lastObject]; [deleteSS addObject: gid]; [uniqueSS removeObjectForKey: gid]; [uniqArSS removeObjectForKey: gid]; } EOFLOGObjectFnStop(); } - (void)forgetSnapshotsForGlobalIDs: (NSArray *)gids { unsigned i, j, n, m; NSMutableDictionary *snapshots; NSMutableSet *deleteGIDs; EOGlobalID *gid; EOFLOGObjectFnStart(); n = [_uniqueStack count]; if (n>0) { IMP oaiIMP=[_uniqueStack methodForSelector: @selector(objectAtIndex:)]; for (i=0; i0) { IMP oaiIMP = [_uniqueArrayStack methodForSelector: @selector(objectAtIndex:)]; for (i=0; i0) { IMP oaiIMP=[_deleteStack methodForSelector: @selector(objectAtIndex:)]; IMP oaiIMP2=[gids methodForSelector: @selector(objectAtIndex:)]; m = [gids count]; for (i=0; i 0) { NSMutableDictionary *toManySnapshots = [_uniqueArrayStack lastObject]; NSArray *keys = [snapshots allKeys]; int count = [keys count]; if (count>0) { IMP oaiIMP=[keys methodForSelector: @selector(objectAtIndex:)]; int i = 0; for (i = 0; i < count; i++) { id key = GDL2_ObjectAtIndexWithImp(keys,oaiIMP,i); NSDictionary *snapshotsDict = [snapshots objectForKey: key]; NSMutableDictionary *currentSnapshotsDict = [toManySnapshots objectForKey: key]; if (!currentSnapshotsDict) { currentSnapshotsDict = (NSMutableDictionary *)[NSMutableDictionary dictionary]; [toManySnapshots setObject: currentSnapshotsDict forKey: key]; } [currentSnapshotsDict addEntriesFromDictionary: snapshotsDict]; } }; } EOFLOGObjectFnStop(); } - (void)registerLockedObjectWithGlobalID: (EOGlobalID *)globalID { EOFLOGObjectFnStart(); if (!_lockedObjects) { _lockedObjects = NSCreateHashTable(NSNonOwnedPointerHashCallBacks, _LOCK_BUFFER); } NSHashInsert(_lockedObjects, globalID); EOFLOGObjectFnStop(); } - (BOOL)isObjectLockedWithGlobalID: (EOGlobalID *)globalID { BOOL result; EOFLOGObjectFnStart(); result = (_lockedObjects && NSHashGet(_lockedObjects, globalID) != nil); EOFLOGObjectFnStop(); return result; } - (void)initializeObject: (id)object row: (NSDictionary*)row entity: (EOEntity*)entity editingContext: (EOEditingContext*)context { //really near ok NSArray *relationships = nil; NSArray *classPropertyAttributeNames = nil; int count = 0; IMP objectTakeStoredValueForKeyIMP=NULL; IMP rowObjectForKeyIMP=NULL; EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"object=0x%x", object); classPropertyAttributeNames = [entity classPropertyAttributeNames]; count = [classPropertyAttributeNames count]; NSDebugMLLog(@"EODatabaseContext", @"count=%d", count); NSDebugMLLog(@"EODatabaseContext", @"row=%@ class=%@", row,[row class]); //row is usuallly a EOMutableKnownKeyDictionary so will use EOMKKD_objectForKeyWithImpPtr if (count>0) { int i=0; IMP oaiIMP=[classPropertyAttributeNames methodForSelector:@selector(objectAtIndex:)]; NSAssert(!_isFault(object), @"Object is a fault. call -methodForSelector: on it is a bad idea"); objectTakeStoredValueForKeyIMP=[object methodForSelector:@selector(takeStoredValue:forKey:)]; for (i = 0; i < count; i++) { id key = GDL2_ObjectAtIndexWithImp(classPropertyAttributeNames,oaiIMP,i); id value = nil; NSDebugMLLog(@"EODatabaseContext", @"key=%@", key); value = EOMKKD_objectForKeyWithImpPtr(row,&rowObjectForKeyIMP,key); if (value == GDL2_EONull) value = nil; NSDebugMLLog(@"EODatabaseContext", @"value (%p)", value); NSDebugMLLog(@"EODatabaseContext", @"value (%p)=%@ (class: %@)", value, value, [value class]); GDL2_TakeStoredValueForKeyWithImp(object,objectTakeStoredValueForKeyIMP, value,key); } }; relationships = [entity _relationshipsToFaultForRow: row]; NSDebugMLLog(@"EODatabaseContext", @"relationships=%@", relationships); count = [relationships count]; if (count>0) { int i=0; IMP oaiIMP=[relationships methodForSelector:@selector(objectAtIndex:)]; if (!objectTakeStoredValueForKeyIMP) { NSAssert(!_isFault(object), @"Object is a fault. call -methodForSelector: on it is a bad idea"); objectTakeStoredValueForKeyIMP=[object methodForSelector:@selector(takeStoredValue:forKey:)]; }; for (i = 0; i < count; i++) { id relObject = nil; EORelationship *relationship = GDL2_ObjectAtIndexWithImp(relationships,oaiIMP,i); NSString *relName = [relationship name]; NSDebugMLLog(@"EODatabaseContext", @"relationship=%@", relationship); if ([relationship isToMany]) { EOGlobalID *gid = [entity globalIDForRow: row]; relObject = [self arrayFaultWithSourceGlobalID: gid relationshipName: relName editingContext: context]; } else if ([relationship isFlattened]) { // to one flattened relationship like aRelationship.anotherRelationship... // I don't know how to handle this case.... May be we shouldn't treat this as real property ?? NSEmitTODO(); relObject = nil; } else { EOMutableKnownKeyDictionary *foreignKeyForSourceRow = nil; NSDebugMLLog(@"EODatabaseContext", @"relationship=%@ foreignKeyInDestination:%d", relName, [relationship foreignKeyInDestination]); foreignKeyForSourceRow = [relationship _foreignKeyForSourceRow: row]; NSDebugMLLog(@"EODatabaseContext", @"row=%@\nforeignKeyForSourceRow:%@", row, foreignKeyForSourceRow); if (![foreignKeyForSourceRow containsObjectsNotIdenticalTo: GDL2_EONull]) { NSLog(@"foreignKeyForSourceRow=%@",[foreignKeyForSourceRow debugDescription]); NSEmitTODO();//TODO: what to do if rel is mandatory ? relObject = nil; } else { EOEntity *destinationEntity = [relationship destinationEntity]; EOGlobalID *relRowGid = [destinationEntity globalIDForRow: foreignKeyForSourceRow]; NSDebugMLLog(@"EODatabaseContext", @"relRowGid=%@", relRowGid); if ([(EOKeyGlobalID*)relRowGid areKeysAllNulls]) NSWarnLog(@"All key of relRowGid %p (%@) are nulls", relRowGid, relRowGid); relObject = [context faultForGlobalID: relRowGid editingContext: context]; NSDebugMLLog(@"EODatabaseContext", @"relObject=%p (%@)", relObject, [relObject class]); //end /* NSArray *joins = [(EORelationship *)prop joins]; EOJoin *join; NSMutableDictionary *row; EOGlobalID *faultGID; int h, count; id value, realValue = nil; row = [NSMutableDictionary dictionaryWithCapacity:4]; count = [joins count]; for (h=0; h0) { IMP oaiIMP=[gids methodForSelector: @selector(objectAtIndex:)]; unsigned i = 0; for (i=0; i 0) { [self forgetAllLocks]; [_uniqueStack removeLastObject]; [_uniqueArrayStack removeLastObject]; [_deleteStack removeLastObject]; } EOFLOGObjectFnStop(); } - (void)_commitTransaction { EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"self=%p _uniqueStack %p=%@", self, _uniqueStack, _uniqueStack); if ([_uniqueStack count] > 0) { NSMutableDictionary *snapshotsDict = [_uniqueStack lastObject]; NSMutableDictionary *toManySnapshotsDict = [_uniqueArrayStack lastObject]; NSMutableSet *deleteSnapshotsSet = [_deleteStack lastObject]; NSEnumerator *deletedGIDEnum = [deleteSnapshotsSet objectEnumerator]; EOGlobalID *gid; while ((gid = [deletedGIDEnum nextObject])) { [_database forgetSnapshotForGlobalID: gid]; } [_database recordSnapshots: snapshotsDict]; [_database recordToManySnapshots: toManySnapshotsDict]; [self forgetAllLocks]; [_uniqueStack removeLastObject]; [_uniqueArrayStack removeLastObject]; [_deleteStack removeLastObject]; } NSDebugMLLog(@"EODatabaseContext", @"self=%p _uniqueStack %p=%@", self, _uniqueStack, _uniqueStack); EOFLOGObjectFnStop(); } - (void) _beginTransaction { EOFLOGObjectFnStart(); [_uniqueStack addObject: [NSMutableDictionary dictionary]]; [_uniqueArrayStack addObject: [NSMutableDictionary dictionary]]; [_deleteStack addObject: [NSMutableSet set]]; NSDebugMLLog(@"EODatabaseContext", @"self=%p _uniqueStack %p=%@", self, _uniqueStack, _uniqueStack); EOFLOGObjectFnStop(); } - (EODatabaseChannel*) _obtainOpenChannel { EODatabaseChannel *channel = [self availableChannel]; if (![self _openChannelWithLoginPanel: channel]) { NSEmitTODO(); [self notImplemented: _cmd];//TODO } return channel; } - (BOOL) _openChannelWithLoginPanel: (EODatabaseChannel*)databaseChannel { // veridy: LoginPanel ??? EOAdaptorChannel *adaptorChannel = [databaseChannel adaptorChannel]; if (![adaptorChannel isOpen]) //?? { [adaptorChannel openChannel]; } return [adaptorChannel isOpen]; } - (void) _forceDisconnect { // TODO NSEmitTODO(); [self notImplemented: _cmd]; } @end @implementation EODatabaseContext(EOMultiThreaded) - (void)lock { [_lock lock]; } - (void)unlock { [_lock unlock]; } @end @implementation EODatabaseContext (EODatabaseContextPrivate2) - (void) _verifyNoChangesToReadonlyEntity: (EODatabaseOperation*)dbOpe { //TODO EOEntity *entity = nil; EOFLOGObjectFnStart(); entity = [dbOpe entity]; NSDebugMLLog(@"EODatabaseContext", @"dbOpe=%@", dbOpe); if ([entity isReadOnly]) { //?? exception I presume } else { [dbOpe databaseOperator]; //SoWhat } EOFLOGObjectFnStop(); } - (void) _cleanUpAfterSave { //TODO EOFLOGObjectFnStart(); _coordinator = nil; //realesae ? _editingContext = nil; //realesae ? if (_dbOperationsByGlobalID) { //Really free it because we don't want to record some db ope (select for exemple). NSFreeMapTable(_dbOperationsByGlobalID); _dbOperationsByGlobalID = NULL; } _flags.preparingForSave = NO; //TODO HERE or in _commitTransaction ? if (_lockedObjects) { NSResetHashTable(_lockedObjects); } EOFLOGObjectFnStop(); } - (EOGlobalID*)_globalIDForObject: (id)object { EOEditingContext *objectEditingContext = nil; EOGlobalID *gid = nil; EOFLOGObjectFnStart(); NSAssert(object, @"No object"); NSDebugMLLog(@"EODatabaseContext",@"object=%p of class %@", object,[object class]); NSDebugMLLog(@"EODatabaseContext", @"_editingContext=%p", _editingContext); objectEditingContext = [object editingContext]; NSAssert2(objectEditingContext, @"No editing context for object %p: %@", object,object); gid=EOEditingContext_globalIDForObjectWithImpPtr(objectEditingContext, NULL, object); NSDebugMLLog(@"EODatabaseContext", @"gid=%@", gid); if (!gid) { NSEmitTODO(); NSLog(@"TODO: no GID in EODatabaseContext _globalIDForObject:"); //TODO exception ? ==> RollbackCh } EOFLOGObjectFnStop(); return gid; } - (NSDictionary*)_primaryKeyForObject: (id)object { //Ayers: Review return [self _primaryKeyForObject: object raiseException: YES]; } - (NSDictionary*)_primaryKeyForObject: (id)object raiseException: (BOOL)raiseException { //NEAR OK //Ayers: Review NSDictionary *pk = nil; EOEntity *entity = nil; NSArray *pkNames = nil; BOOL shouldGeneratePrimaryKey = NO; EOFLOGObjectFnStart(); NSDebugMLLog(@"EODatabaseContext", @"object=%@", object); NSAssert(!_isNilOrEONull(object), @"No object"); entity = [_database entityForObject: object]; shouldGeneratePrimaryKey = [self _shouldGeneratePrimaryKeyForEntityName: [entity name]]; NSDebugMLLog(@"EODatabaseContext", @"object=%p shouldGeneratePrimaryKey=%d", object, shouldGeneratePrimaryKey); /* if (shouldGeneratePrimaryKey) */ { BOOL isPKValid = NO; EOGlobalID *gid = EODatabaseContext_globalIDForObjectWithImpPtr(self,NULL,object); NSDebugMLLog(@"EODatabaseContext", @"gid=%@", gid); pk = [entity primaryKeyForGlobalID: (EOKeyGlobalID*)gid]; //OK NSDebugMLLog(@"EODatabaseContext",@"object=%p pk=%@", object, pk); { NSDictionary *pk2 = nil; pkNames = [entity primaryKeyAttributeNames]; pk2 = [self valuesForKeys: pkNames object: object]; NSDebugMLLog(@"EODatabaseContext",@"object=%p pk2=%@", object, pk2); if (pk) { //merge pk2 into pk NSEnumerator *pk2Enum = [pk2 keyEnumerator]; IMP pk2EnumNO=NULL; // nextObject NSMutableDictionary *realPK = [NSMutableDictionary dictionaryWithDictionary: pk];//revoir id key = nil; while ((key = GDL2_NextObjectWithImpPtr(pk2Enum,&pk2EnumNO))) { [realPK setObject: [pk2 objectForKey: key] forKey: key]; } pk = realPK; } else pk=pk2; } NSDebugMLLog(@"EODatabaseContext",@"object=%p pk=%@", object, pk); isPKValid = [entity isPrimaryKeyValidInObject: pk]; NSDebugMLLog(@"EODatabaseContext",@"object=%p isPKValid=%d", object, isPKValid); if (isPKValid == NO) pk = nil; NSDebugMLLog(@"EODatabaseContext", @"object=%p isPKValid=%d shouldGeneratePrimaryKey=%d", object, isPKValid, shouldGeneratePrimaryKey); if (isPKValid == NO && shouldGeneratePrimaryKey) { pk = nil; if (_delegateRespondsTo.newPrimaryKey == YES) pk = [_delegate databaseContext: self newPrimaryKeyForObject: object entity: entity]; if (!pk) { NSArray *pkAttributes = nil; EOAdaptorChannel *channel = nil; EOStoredProcedure *nextPKProcedure = nil; nextPKProcedure = [entity storedProcedureForOperation: EONextPrimaryKeyProcedureOperation]; #if 0 // TODO execute storedProcedure and fetch results; if (nextPKProcedure) [[[self _obtainOpenChannel] adaptorChannel] executeStoredProcedure: nextPKProcedure withValues:]; #endif pkAttributes = [entity primaryKeyAttributes]; NSDebugMLLog(@"EODatabaseContext", @"object=%p pk=%@ [pkAttributes count]=%d", object, pk, [pkAttributes count]); if (pk == nil && [pkAttributes count] == 1) { EOAttribute *pkAttr = [pkAttributes objectAtIndex: 0]; //TODO attr: adaptorValueType //returned EOAdaptorNumberType //TODO [entity rootParent];//so what if (channel == nil) { channel = [[self _obtainOpenChannel] adaptorChannel]; if ([[channel adaptorContext] transactionNestingLevel] == 0) [[channel adaptorContext] beginTransaction]; if (_flags.beganTransaction == NO) { NSDebugMLLog(@"EODatabaseContext", @"BEGAN TRANSACTION FLAG==>NO"); _flags.beganTransaction = YES; } } pk = [channel primaryKeyForNewRowWithEntity: entity]; NSDebugMLLog(@"EODatabaseContext", @"** prepare pk %@", pk); if (pk == nil && [[pkAttr valueClassName] isEqual:@"NSData"] == YES) { unsigned char data[EOUniqueBinaryKeyLength]; [EOTemporaryGlobalID assignGloballyUniqueBytes: data]; pk = [NSDictionary dictionaryWithObject: [NSData dataWithBytes: data length: EOUniqueBinaryKeyLength] forKey: [pkAttr name]]; }; } } if (!pk && raiseException) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: cannot generate primary key for object '%@'", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, object]; } } /* else // !shouldGeneratePrimaryKey */ if (!pk) { // MG // Here we'll find if there is a "parent" objects which relay pk // I'm not sure if we could do it here but it's handle this case: // object is a new child of a previous existing object. // if we don't generate it's pk here, the chld object // will relay it's pk to parent which is not good NSDictionary *objectSnapshot=nil; NSArray *relationships=nil; int relationshipsCount=0; NSDebugMLLog(@"EODatabaseContext", @"object=%@", object); // get object snapshot objectSnapshot = [object snapshot]; NSDebugMLLog(@"EODatabaseContext", @"objectSnapshot=%@", objectSnapshot); // Get object relationships relationships = [entity relationships]; NSDebugMLLog(@"EODatabaseContext", @"relationships=%@", relationships); relationshipsCount = [relationships count]; if (relationshipsCount>0) { IMP oaiIMP=[relationships methodForSelector: @selector(objectAtIndex:)]; int i = 0; for (i = 0; i < relationshipsCount; i++) { EORelationship *inverseRelationship = nil; EORelationship *relationship = GDL2_ObjectAtIndexWithImp(relationships,oaiIMP,i); NSDebugMLLog(@"EODatabaseContext", @"relationship=%@", relationship); inverseRelationship = [relationship inverseRelationship]; NSDebugMLLog(@"EODatabaseContext", @"inverseRelationship=%@", inverseRelationship); // if there's inverse relationship with propagates primary key if ([inverseRelationship propagatesPrimaryKey]) { NSString *relationshipName= [relationship name]; NSDictionary *relationshipValuePK = nil; // get object value for the relationship id relationshipValue = [objectSnapshot valueForKey:relationshipName]; NSDebugMLLog(@"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]; NSDebugMLLog(@"EODatabaseContext", @"relationshipValuePK=%@", relationshipValuePK); // force object to relay pk now ! [self relayPrimaryKey: relationshipValuePK object: relationshipValue entity: [_database entityForObject: relationshipValue]]; }; }; }; pk = [self valuesForKeys: pkNames object: object]; if (![entity isPrimaryKeyValidInObject: pk]) pk=nil; }; if (pk) { EODatabaseOperation *dbOpe = [self databaseOperationForObject: object]; NSMutableDictionary *newRow = [dbOpe newRow]; [newRow addEntriesFromDictionary: pk];// VERIFY Here we replace // previous key } NSDebugMLLog(@"EODatabaseContext", @"pk=%@", pk); NSDebugMLog(@"object %p=%@\npk=%@",object, object, pk); EOFLOGObjectFnStop(); return pk; } - (BOOL) _shouldGeneratePrimaryKeyForEntityName: (NSString*)entityName { //OK BOOL shouldGeneratePK = YES; EOFLOGObjectFnStart(); if (_nonPrimaryKeyGenerators) shouldGeneratePK = !NSHashGet(_nonPrimaryKeyGenerators, entityName); NSDebugMLLog(@"EODatabaseContext", @"shouldGeneratePK for %@: %s", entityName, (shouldGeneratePK ? "YES" : "NO")); NSAssert(![entityName isEqualToString: @"Country"] || shouldGeneratePK, @"MGVALID: Failed"); EOFLOGObjectFnStop(); return shouldGeneratePK; } - (void)_buildPrimaryKeyGeneratorListForEditingContext: (EOEditingContext*)context { NSArray *objects[3]; NSHashTable *processedEntities = NULL; NSMutableArray *entityToProcess = nil; int which; EOFLOGObjectFnStart(); if (_nonPrimaryKeyGenerators) { NSResetHashTable(_nonPrimaryKeyGenerators); } processedEntities = NSCreateHashTable(NSObjectHashCallBacks, 32); objects[0] = [context updatedObjects]; objects[1] = [context insertedObjects]; objects[2] = [context deletedObjects]; for (which = 0; which < 3; which++) { int count = [objects[which] count]; if (count>0) { IMP oaiIMP=[objects[which] methodForSelector: @selector(objectAtIndex:)]; int i = 0; for (i = 0; i < count; i++) { id object = GDL2_ObjectAtIndexWithImp(objects[which],oaiIMP,i); EOEntity *entity = [_database entityForObject: object]; NSDebugMLLog(@"EODatabaseContext", @"add entity to process: %@", [entity name]); if (entityToProcess) [entityToProcess addObject: entity]; else entityToProcess = [NSMutableArray arrayWithObject: entity]; } }; } while ([entityToProcess count]) { EOEntity *entity = [entityToProcess lastObject]; NSDebugMLLog(@"EODatabaseContext", @"test entity: %@", [entity name]); [entityToProcess removeLastObject]; if (!NSHashInsertIfAbsent(processedEntities, entity)) //Already processed ? { NSArray *relationships = [entity relationships]; int relationshipsCount = [relationships count]; if (relationshipsCount>0) { IMP relObjectAtIndexIMP=[relationships methodForSelector: @selector(objectAtIndex:)]; int iRelationship = 0; for (iRelationship = 0; iRelationship < relationshipsCount; iRelationship++) { EORelationship *relationship = GDL2_ObjectAtIndexWithImp(relationships,relObjectAtIndexIMP,iRelationship); NSDebugMLLog(@"EODatabaseContext", @"test entity: %@ relationship=%@", [entity name], relationship); if ([relationship propagatesPrimaryKey]) { EOEntity *destinationEntity = [relationship destinationEntity]; NSDebugMLLog(@"EODatabaseContext", @"test entity: %@ destinationEntity=%@", [entity name], [destinationEntity name]); if (destinationEntity) { NSArray *destAttrs; NSArray *pkAttrs; int count; BOOL destPK = NO; destAttrs = [relationship destinationAttributes]; pkAttrs = [destinationEntity primaryKeyAttributes]; count = [destAttrs count]; if (count>0) { IMP destAttrsObjectAtIndexIMP=[relationships methodForSelector: @selector(objectAtIndex:)]; int i=0; for (i = 0; i < count; i++) { if ([pkAttrs containsObject: GDL2_ObjectAtIndexWithImp(destAttrs,destAttrsObjectAtIndexIMP,i)]) destPK = YES; } }; if (destPK) { NSDebugMLLog(@"EODatabaseContext", @"destination entity: %@ " @"No PK generation [Rel = %@]", [destinationEntity name], [relationship name]); if (!_nonPrimaryKeyGenerators) _nonPrimaryKeyGenerators = NSCreateHashTable(NSObjectHashCallBacks, 32); NSHashInsertIfAbsent(_nonPrimaryKeyGenerators, [destinationEntity name]); [entityToProcess addObject: destinationEntity]; } } } } } } } NSDebugMLLog(@"EODatabaseContext", @"_nonPrimaryKeyGenerators=%@", NSStringFromHashTable(_nonPrimaryKeyGenerators)); EOFLOGObjectFnStop(); NSFreeHashTable(processedEntities); } /** Returns a dictionary containing a snapshot of object that reflects its committed values (last values putted in the database; i.e. values before changes were made on the object). It is updated after commiting new values. If the object has been just inserted, the dictionary is empty. **/ - (NSDictionary*)_currentCommittedSnapshotForObject: (id)object { NSDictionary *snapshot = nil; EOGlobalID *gid = nil; EODatabaseOperation *dbOpe = nil; EODatabaseOperator dbOperator = (EODatabaseOperator)0; EOFLOGObjectFnStart(); gid = EOEditingContext_globalIDForObjectWithImpPtr(_editingContext,NULL,object); dbOpe = [self databaseOperationForGlobalID: gid]; //I'm not sure. Retrieve it directly ? dbOperator = [dbOpe databaseOperator]; switch (dbOperator) { case EODatabaseUpdateOperator: snapshot = [_editingContext committedSnapshotForObject: object];//OK NSDebugMLLog(@"EODatabaseContext", @"snapshot %p=%@", snapshot, snapshot); break; case EODatabaseInsertOperator: snapshot = [NSDictionary dictionary]; break; //TODO /* else snapshot=XX;//TODO */ case EODatabaseDeleteOperator: break; case EODatabaseNothingOperator: break; } NSDebugMLLog(@"EODatabaseContext", @"snapshot %p=%@", snapshot, snapshot); EOFLOGObjectFnStop(); return snapshot; } - (void) _assertValidStateWithSelector: (SEL)sel { // [self notImplemented:_cmd]; //TODO } - (id) _addDatabaseContextStateToException: (id)param0 { NSEmitTODO(); return [self notImplemented: _cmd]; //TODO } - (id) _databaseContextState { NSEmitTODO(); return [self notImplemented: _cmd]; //TODO } @end gnustep-dl2-0.12.0/EOAccess/EOUtilities.m0000644000175000017500000007303010767323154017003 0ustar ayersayers/** EOUtilities.m Copyright (C) 2000-2002,2003,2004,2005 Free Software Foundation, Inc. Author: Manuel Guesdon Date: Sep 2000 $Revision: 26323 $ $Date: 2008-03-16 23:59:56 +0100 (Son, 16. Mär 2008) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EOUtilities.m 26323 2008-03-16 22:59:56Z ratmice $") #ifdef GNUSTEP #include #include #include #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "EOPrivate.h" NSString *EOMoreThanOneException = @"EOMoreThanOneException"; @implementation EOEditingContext (EOUtilities) - (NSArray *)objectsForEntityNamed: (NSString *)entityName { NSArray *objects; EOFetchSpecification *fetchSpecif; NSAssert([entityName length] > 0, @"No entity name"); fetchSpecif = [EOFetchSpecification fetchSpecificationWithEntityName: entityName qualifier: nil sortOrderings: nil]; objects = [self objectsWithFetchSpecification: fetchSpecif]; return objects; } - (NSArray *)objectsOfClass: (Class)classObject { EOEntity *entity; NSArray *objects; EOFLOGObjectFnStartOrCond(@"EOEditingContext"); entity = [self entityForClass: classObject]; objects = [self objectsForEntityNamed: [entity name]]; EOFLOGObjectFnStopOrCond(@"EOEditingContext"); return objects; } - (NSArray *)objectsWithFetchSpecificationNamed: (NSString *)fetchSpecName entityNamed: (NSString *)entityName bindings: (NSDictionary *)bindings { EOModelGroup *modelGroup; EOFetchSpecification *unboundFetchSpec; EOFetchSpecification *boundFetchSpec; NSArray *results; modelGroup = [self modelGroup]; unboundFetchSpec = [modelGroup fetchSpecificationNamed: fetchSpecName entityNamed: entityName]; if ( !unboundFetchSpec ) { [NSException raise: NSObjectNotAvailableException format: @"%@: Fetch specification '%@' not found in entity named '%@'", NSStringFromSelector(_cmd), fetchSpecName, entityName]; } boundFetchSpec = [unboundFetchSpec fetchSpecificationWithQualifierBindings: bindings]; results = [self objectsWithFetchSpecification: boundFetchSpec]; return results; } - (NSArray *)objectsForEntityNamed: (NSString *)entityName qualifierFormat: (NSString *)format,... { EOQualifier *qualifier; EOFetchSpecification *fetchSpec; NSArray *results; va_list args; va_start(args, format); qualifier = [EOQualifier qualifierWithQualifierFormat: format varargList: args]; va_end(args); fetchSpec = [EOFetchSpecification fetchSpecificationWithEntityName: entityName qualifier: qualifier sortOrderings: nil]; results = [self objectsWithFetchSpecification: fetchSpec]; return results; } - (NSArray *)objectsMatchingValue: (id)value forKey: (NSString *)key entityNamed: (NSString *)entityName { //OK NSArray *objects; EOFLOGObjectFnStart(); NSDebugMLLog(@"gsdb", @"START value=%@ key=%@ entityName=%@", value, key, entityName); if (!value) value=GDL2_EONull; NSAssert(value, @"No Value"); //Transform it to EONull ? NSAssert(key, @"No Key"); NSAssert([entityName length] > 0, @"No entity name"); objects = [self objectsMatchingValues: [NSDictionary dictionaryWithObject: value forKey: key] entityNamed: entityName]; EOFLOGObjectFnStop(); return objects; //TC: /* EOKeyValueQualifier *qualifier; EOFetchSpecification *fetch; NSArray *newArray; EOFLOGObjectFnStartOrCond(@"EOEditingContext"); qualifier = [[EOKeyValueQualifier alloc] initWithKey:key operatorSelector:EOQualifierOperatorEqual value:value]; fetch = [EOFetchSpecification fetchSpecificationWithEntityName:name qualifier:[qualifier autorelease] sortOrderings:nil]; newArray = [self objectsWithFetchSpecification:fetch]; EOFLOGObjectFnStopOrCond(@"EOEditingContext"); return newArray; */ } - (NSArray *)objectsMatchingValues: (NSDictionary *)values entityNamed: (NSString *)entityName { //OK NSArray *objects = nil; EOFetchSpecification *fetchSpec; EOQualifier *qualifier; NSEnumerator *valuesEnum; id key=nil; NSMutableArray* kvQualifiers=nil; EOFLOGObjectFnStart(); NSDebugMLLog(@"gsdb", @"START values=%@ entityName=%@", values, entityName); NS_DURING { NSAssert([entityName length] > 0, @"No entity name"); valuesEnum = [values keyEnumerator]; kvQualifiers = [NSMutableArray array]; while ((key = [valuesEnum nextObject])) { id value = [values objectForKey: key]; EOKeyValueQualifier *tmpQualifier = [EOKeyValueQualifier qualifierWithKey: key operatorSelector: @selector(isEqualTo:) value: value]; [kvQualifiers addObject: tmpQualifier]; } qualifier = [EOAndQualifier qualifierWithQualifierArray: kvQualifiers]; fetchSpec = [EOFetchSpecification fetchSpecificationWithEntityName: entityName qualifier: qualifier sortOrderings: nil]; NSDebugMLLog(@"gsdb", @"fetchSpec=%@", fetchSpec); objects = [self objectsWithFetchSpecification: fetchSpec]; } NS_HANDLER { NSDebugMLog(@"exception in EOEditingContext (EOUtilities) objectsMatchingValues:entityNamed:", ""); NSLog(@"exception in EOEditingContext (EOUtilities) objectsMatchingValues:entityNamed:"); NSDebugMLog(@"exception=%@", localException); NSLog(@"exception=%@", localException); /* localException=ExceptionByAddingUserInfoObjectFrameInfo(localException, @"In EOEditingContext (EOUtilities) objectsMatchingValues:entityNamed:"); */ NSLog(@"exception=%@", localException); [localException raise]; } NS_ENDHANDLER; EOFLOGObjectFnStop(); return objects; //TC: /* EOQualifier *qualifier; EOFetchSpecification *fetchSpec; NSArray *results; qualifier = [EOQualifier qualifierToMatchAllValues:values]; fetchSpec = [EOFetchSpecification fetchSpecificationWithEntityName:name qualifier:qualifier sortOrderings:nil]; results = [self objectsWithFetchSpecification:fetchSpec]; return results; */ } - (id)objectWithFetchSpecificationNamed: (NSString *)fetchSpecName entityNamed: (NSString *)entityName bindings: (NSDictionary *)bindings { id object = nil; int count; NSArray *objects; NSAssert([entityName length] > 0, @"No entity name"); objects = [self objectsWithFetchSpecificationNamed:fetchSpecName entityNamed:entityName bindings:bindings]; count = [objects count]; switch (count) { case 0: [NSException raise: NSInvalidArgumentException format: @"%@: No item selected for fetch specification %@ in entity %@ with bindings %@", NSStringFromSelector(_cmd), fetchSpecName, entityName, bindings]; break; case 1: object = [objects objectAtIndex: 0]; break; default: [NSException raise: EOMoreThanOneException format: @"%@: Selected more than one item for fetch specification %@ in entity %@ with bindings %@", NSStringFromSelector(_cmd), fetchSpecName, entityName, bindings]; break; } return object; } - (id)objectForEntityNamed: (NSString *)entityName qualifierFormat: (NSString *)format,... { id object = nil; int count; EOQualifier *qualifier; EOFetchSpecification *fetchSpec; NSArray *objects; va_list args; va_start(args, format); qualifier = [EOQualifier qualifierWithQualifierFormat: format varargList: args]; va_end(args); fetchSpec = [EOFetchSpecification fetchSpecificationWithEntityName: entityName qualifier: qualifier sortOrderings: nil]; objects = [self objectsWithFetchSpecification: fetchSpec]; count = [objects count]; switch (count) { case 0: [NSException raise: NSInvalidArgumentException format: @"%@: No item selected for entity %@ qualified by %@", NSStringFromSelector(_cmd), entityName, format]; break; case 1: object = [objects objectAtIndex: 0]; break; default: [NSException raise: EOMoreThanOneException format: @"%@: Selected more than one item for entity %@ qualified by %@", NSStringFromSelector(_cmd), entityName, format]; } return object; } - (id)objectMatchingValue: (id)value forKey: (NSString *)key entityNamed: (NSString *)entityName { //OK id object = nil; int count; NSArray *objects; EOFLOGObjectFnStart(); NSDebugMLLog(@"gsdb", @"START value=%@ key=%@ entityName=%@", value, key, entityName); NS_DURING //Debugging Purpose { NSAssert([entityName length] > 0, @"No entity name"); objects = [self objectsMatchingValue: value forKey: key entityNamed: entityName]; NSDebugMLLog(@"gsdb", @"objects count=%d", [objects count]); NSDebugMLLog(@"gsdb", @"objects=%@", objects); count = [objects count]; switch (count) { case 0: [NSException raise: NSObjectNotAvailableException format: @"%@: No %@ found with key %@ matching %@", NSStringFromSelector(_cmd), entityName, key, value]; break; case 1: object = [objects objectAtIndex: 0]; break; default: [NSException raise: EOMoreThanOneException format: @"%@: Selected more than one %@ with key %@ matching %@", NSStringFromSelector(_cmd), entityName, key, value]; break; } } NS_HANDLER { NSLog(@"exception in EOEditingContext (EOUtilities) objectMatchingValue:forKey:entityNamed:"); NSLog(@"exception=%@", localException); /* localException=ExceptionByAddingUserInfoObjectFrameInfo(localException, @"In EOEditingContext (EOUtilities) objectMatchingValue:forKey:entityNamed:"); */ NSLog(@"exception=%@", localException); [localException raise]; } NS_ENDHANDLER; NSDebugMLLog(@"gsdb", @"object=%@", object); EOFLOGObjectFnStop(); return object; } - (id)objectMatchingValues: (NSDictionary *)values entityNamed: (NSString *)entityName { id object = nil; int count; NSArray *objects; EOFLOGObjectFnStart(); NSAssert([entityName length] > 0, @"No entity name"); objects = [self objectsMatchingValues: values entityNamed: entityName]; count = [objects count]; switch(count) { case 0: [NSException raise: NSInvalidArgumentException format: @"%@: No %@ found matching %@", NSStringFromSelector(_cmd), entityName, values]; break; case 1: object = [objects objectAtIndex: 0]; break; default: [NSException raise: EOMoreThanOneException format: @"%@: Selected more than one %@ matching %@", NSStringFromSelector(_cmd), entityName, values]; break; } EOFLOGObjectFnStop(); return object; } - (id)objectWithPrimaryKeyValue: (id)value entityNamed: (NSString *)entityName { //OK id object = nil; EOEntity *entity; NSAssert([entityName length] > 0, @"No entity name"); entity = [self entityNamed: entityName]; if (!entity) [NSException raise: NSInvalidArgumentException format: @"objectWithPrimaryKeyValue:%@ entityNamed:%@; no entity", value, entityName]; else { NSArray *primaryKeyAttributes = [entity primaryKeyAttributes]; if ([primaryKeyAttributes count] != 1) { [NSException raise: NSInvalidArgumentException format: @"objectWithPrimaryKeyValue:%@ entityNamed:%@ may only be called for entities with one primary key attribute. For entities with compound primary keys, use objectWithPrimaryKey:entityNamed and provide a dictionary for the primary key.", value, entityName]; } else { NSDictionary* pk; if (!value) value=GDL2_EONull; pk = [NSDictionary dictionaryWithObject: value forKey: [(EOAttribute*)[primaryKeyAttributes objectAtIndex: 0] name]]; object = [self objectWithPrimaryKey: pk entityNamed: entityName]; } } return object; } - (id)objectWithPrimaryKey: (NSDictionary *)pkDict entityNamed: (NSString *)entityName { //OK id object = nil; EOEntity *entity; NSAssert([pkDict count] > 0, @"Empty primary key."); NSAssert([entityName length] > 0, @"No entity name"); entity = [self entityNamed: entityName]; if (!entity) [NSException raise: NSInvalidArgumentException format: @"objectWithPrimaryKeyValue:%@ entityNamed:%@; no entity", pkDict, entityName]; else { EOGlobalID *gid = [entity globalIDForRow: pkDict]; object = [self faultForGlobalID: gid editingContext: self]; } return object; } - (NSArray *)rawRowsForEntityNamed: (NSString *)entityName qualifierFormat: (NSString *)format,... { EOQualifier *qualifier; EOFetchSpecification *fetchSpec; NSArray *results; va_list args; va_start(args, format); qualifier = [EOQualifier qualifierWithQualifierFormat: format varargList: args]; va_end(args); NSAssert([entityName length] > 0, @"No entity name"); fetchSpec = [EOFetchSpecification fetchSpecificationWithEntityName: entityName qualifier: qualifier sortOrderings: nil]; [fetchSpec setFetchesRawRows: YES]; results = [self objectsWithFetchSpecification: fetchSpec]; return results; } - (NSArray *)rawRowsMatchingValue: (id)value forKey: (NSString *)key entityNamed: (NSString *)entityName { NSDictionary *valueDict; NSArray *results; NSAssert([entityName length]>0,@"No entity name"); if (!value) value=GDL2_EONull; valueDict = [NSDictionary dictionaryWithObject: value forKey: key]; results = [self rawRowsMatchingValues: valueDict entityNamed: entityName]; return results; } - (NSArray *)rawRowsMatchingValues: (NSDictionary *)values entityNamed: (NSString *)entityName { EOQualifier *qualifier; EOFetchSpecification *fetchSpec; NSArray *results; NSAssert([entityName length] > 0, @"No entity name"); qualifier = [EOQualifier qualifierToMatchAllValues: values]; fetchSpec = [EOFetchSpecification fetchSpecificationWithEntityName: entityName qualifier: qualifier sortOrderings: nil]; [fetchSpec setFetchesRawRows: YES]; results = [self objectsWithFetchSpecification: fetchSpec]; return results; } - (NSArray *)rawRowsWithSQL: (NSString *)sqlString modelNamed: (NSString *)name { EODatabaseContext *databaseContext; EODatabaseChannel *databaseChannel; EOAdaptorChannel *adaptorChannel; NSMutableArray *results = nil; NSDictionary *row; databaseContext = [self databaseContextForModelNamed: name]; [databaseContext lock]; NS_DURING { databaseChannel = [databaseContext availableChannel]; adaptorChannel = [databaseChannel adaptorChannel]; if (![adaptorChannel isOpen]) [adaptorChannel openChannel]; [adaptorChannel evaluateExpression: [EOSQLExpression expressionForString: sqlString]]; [adaptorChannel setAttributesToFetch:[adaptorChannel describeResults]]; results = [NSMutableArray array]; while ((row = [adaptorChannel fetchRowWithZone: [self zone]])) [results addObject: row]; [databaseContext unlock]; } NS_HANDLER { [databaseContext unlock]; [localException raise]; } NS_ENDHANDLER; return results; } - (NSArray *)rawRowsWithStoredProcedureNamed: (NSString *)name arguments: (NSDictionary *)args { EODatabaseContext *databaseContext; EODatabaseChannel *databaseChannel; EOAdaptorChannel *adaptorChannel; EOStoredProcedure *storedProcedure; NSMutableArray *results; NSDictionary *row; storedProcedure = [[self modelGroup] storedProcedureNamed: name]; databaseContext = [self databaseContextForModelNamed: [[storedProcedure model] name]]; [databaseContext lock]; NS_DURING { databaseChannel = [databaseContext availableChannel]; adaptorChannel = [databaseChannel adaptorChannel]; if (![adaptorChannel isOpen]) [adaptorChannel openChannel]; [adaptorChannel executeStoredProcedure: storedProcedure withValues: args]; [adaptorChannel setAttributesToFetch: [adaptorChannel describeResults]]; results = [NSMutableArray array]; while ((row = [adaptorChannel fetchRowWithZone: [self zone]])) [results addObject: row]; [databaseContext unlock]; } NS_HANDLER { [databaseContext unlock]; [localException raise]; } NS_ENDHANDLER; return results; } - (NSDictionary *)executeStoredProcedureNamed: (NSString *)name arguments: (NSDictionary *)args { EODatabaseContext *databaseContext; EODatabaseChannel *databaseChannel; EOAdaptorChannel *adaptorChannel; EOStoredProcedure *storedProcedure; NSDictionary *returnValues = nil; storedProcedure = [[self modelGroup] storedProcedureNamed: name]; databaseContext = [self databaseContextForModelNamed: [[storedProcedure model] name]]; [databaseContext lock]; NS_DURING { databaseChannel = [databaseContext availableChannel]; adaptorChannel = [databaseChannel adaptorChannel]; if (![adaptorChannel isOpen]) [adaptorChannel openChannel]; [adaptorChannel executeStoredProcedure: storedProcedure withValues: args]; returnValues = [adaptorChannel returnValuesForLastStoredProcedureInvocation]; [databaseContext unlock]; } NS_HANDLER { [databaseContext unlock]; [localException raise]; } NS_ENDHANDLER; return returnValues; } - (id)objectFromRawRow: (NSDictionary *)row entityNamed: (NSString *)entityName { NSAssert([entityName length] > 0, @"No entity name"); return [self faultForRawRow: row entityNamed: entityName]; } - (EODatabaseContext *)databaseContextForModelNamed: (NSString *)name { EOModelGroup *modelGroup; EOModel *model; EODatabaseContext *databaseContext; modelGroup = [self modelGroup]; model = [modelGroup modelNamed: name]; if ( !model ) [NSException raise: NSInvalidArgumentException format: @"%@: cannot find model named %@ associated with this EOEditingContext", NSStringFromSelector(_cmd), name]; databaseContext = [EODatabaseContext registeredDatabaseContextForModel: model editingContext: self]; return databaseContext; } - (void)connectWithModelNamed: (NSString *)name connectionDictionaryOverrides: (NSDictionary *)overrides { EOModel *model; model = [[self modelGroup] modelNamed: name]; [self notImplemented: _cmd]; } - (id)createAndInsertInstanceOfEntityNamed: (NSString *)entityName { id object; EOClassDescription *classDescription; EOFLOGObjectFnStartOrCond(@"EOEditingContext"); classDescription = [EOClassDescription classDescriptionForEntityName: entityName]; if (!classDescription) [NSException raise: NSInvalidArgumentException format: @"%@ could not find class description for entity named %@", NSStringFromSelector(_cmd), entityName]; object = [classDescription createInstanceWithEditingContext: self globalID: nil zone: [self zone]]; [self insertObject: object]; EOFLOGObjectFnStopOrCond(@"EOEditingContext"); return object; } - (NSDictionary *)primaryKeyForObject: (id)object { EOKeyGlobalID *gid; EOEntity *entity; NSDictionary *newDict; EOFLOGObjectFnStartOrCond(@"EOEditingContext"); gid = (EOKeyGlobalID *)[self globalIDForObject: object]; entity = [self entityForObject: object]; newDict = [entity primaryKeyForGlobalID: gid]; EOFLOGObjectFnStopOrCond(@"EOEditingContext"); return newDict; } - (NSDictionary *)destinationKeyForSourceObject: (id)object relationshipNamed: (NSString*)name { EODatabaseContext *databaseContext; EODatabase *database; EOEntity *sourceEntity; EORelationship *relationship; NSArray *joins; EOJoin *join; NSString *sourceAttributeName; NSString *destinationAttributeName; NSDictionary *snapshot; NSMutableDictionary *result = nil; int i, count; sourceEntity = [self entityForObject: object]; relationship = [sourceEntity relationshipNamed: name]; if (!relationship) [NSException raise: NSInvalidArgumentException format: @"%@: entity %@ does not have relationship named %@", NSStringFromSelector(_cmd), [sourceEntity name], name]; databaseContext = [self databaseContextForModelNamed: [[sourceEntity model] name]]; [databaseContext lock]; NS_DURING { database = [databaseContext database]; snapshot = [database snapshotForGlobalID:[self globalIDForObject: object]]; joins = [relationship joins]; count = [joins count]; result = (NSMutableDictionary *)[NSMutableDictionary dictionary]; for (i = 0 ; i < count ; i++) { join = [joins objectAtIndex: i]; sourceAttributeName = [[join sourceAttribute] name]; destinationAttributeName = [[join destinationAttribute] name]; [result setObject: [snapshot objectForKey: sourceAttributeName] forKey: destinationAttributeName]; } [databaseContext unlock]; } NS_HANDLER { [databaseContext unlock]; [localException raise]; } NS_ENDHANDLER; return result; } - (id)localInstanceOfObject: (id)object { EOGlobalID *gid; id newInstance; EOFLOGObjectFnStartOrCond(@"EOEditingContext"); gid = [[object editingContext] globalIDForObject:object]; newInstance = [self faultForGlobalID: gid editingContext: self]; EOFLOGObjectFnStopOrCond(@"EOEditingContext"); return newInstance; } - (NSArray *)localInstancesOfObjects: (NSArray *)objects { NSMutableArray *array; int i, count = [objects count]; id obj; EOFLOGObjectFnStartOrCond(@"EOEditingContext"); array = [NSMutableArray arrayWithCapacity: count]; for (i = 0; i < count; i++) { obj = [self localInstanceOfObject: [objects objectAtIndex: i]]; [array addObject: obj]; } EOFLOGObjectFnStopOrCond(@"EOEditingContext"); return array; } - (EOModelGroup *)modelGroup { EOObjectStore *rootObjectStore; EOObjectStoreCoordinator *objectStoreCoordinator; EOModelGroup *modelGroup; EOFLOGObjectFnStartOrCond(@"EOEditingContext"); rootObjectStore = [self rootObjectStore]; if (![rootObjectStore isKindOfClass: [EOObjectStoreCoordinator class]]) [NSException raise: NSInvalidArgumentException format: @"%@: an EOEditingContext's root object store must be an EOObjectStoreCoordinator for this method to function.", NSStringFromSelector(_cmd)]; objectStoreCoordinator = (EOObjectStoreCoordinator *)rootObjectStore; modelGroup = [objectStoreCoordinator modelGroup]; EOFLOGObjectFnStopOrCond(@"EOEditingContext"); return modelGroup; } - (EOEntity *)entityNamed: (NSString *)entityName { EOEntity *entity; EOModelGroup *modelGroup; EOFLOGObjectFnStart(); NSAssert([entityName length] > 0, @"No entity name"); modelGroup = [self modelGroup]; NSAssert(modelGroup, @"No model group"); entity = [modelGroup entityNamed: entityName]; if (!entity) [NSException raise: NSInvalidArgumentException format: @"%@: could not find entity named:%@", NSStringFromSelector(_cmd), entityName]; EOFLOGObjectFnStop(); return entity; } - (EOEntity *)entityForClass: (Class)classObject { EOModelGroup *modelGroup; NSArray *models; EOModel *model; int modelCount; NSArray *entities; EOEntity *entity; NSString *className; NSString *entityClassName; int i, j, entityCount; EOEntity *result = nil; BOOL matchesClassName; EOFLOGObjectFnStartOrCond(@"EOEditingContext"); className = NSStringFromClass(classObject); modelGroup = [self modelGroup]; models = [modelGroup models]; modelCount = [models count]; for (i = 0 ; i < modelCount ; i++) { model = [models objectAtIndex: i]; entities = [model entities]; entityCount = [entities count]; for (j = 0 ; j < entityCount ; j++) { entity = [entities objectAtIndex: j]; entityClassName = [entity className]; matchesClassName = [className isEqualToString: entityClassName]; // Java class names in the Objective-C run-time system use '/' instead of '.' to separate package names, so we also check for a class name in which we replaced '.' with '/'. if (!matchesClassName && ([entityClassName rangeOfString:@"."].length != 0)) matchesClassName = [className isEqualToString: [[entityClassName componentsSeparatedByString: @"."] componentsJoinedByString: @"/"]]; if (matchesClassName) { if (result) [NSException raise: EOMoreThanOneException format: @"%@ found more than one entity for class named %@", NSStringFromSelector(_cmd), className]; else result = entity; } } } if (!result) [NSException raise: NSObjectNotAvailableException format: @"%@ could not find entity for class named %@", NSStringFromSelector(_cmd), className]; EOFLOGObjectFnStopOrCond(@"EOEditingContext"); return result; } - (EOEntity *)entityForObject: (id)object { EOClassDescription *classDesc; EOEntity *newEntity; EOFLOGObjectFnStartOrCond(@"EOEditingContext"); classDesc = [(EOGenericRecord *)object classDescription]; if ([classDesc isKindOfClass: [EOEntityClassDescription class]] == NO) [NSException raise: NSInvalidArgumentException format: @"%@ - %@: the object's class description must be an EOEntityClassDescription", NSStringFromSelector(_cmd), object]; newEntity = [(EOEntityClassDescription *)classDesc entity]; EOFLOGObjectFnStopOrCond(@"EOEditingContext"); return newEntity; } @end @implementation EOFetchSpecification (EOAccess) + (EOFetchSpecification *)fetchSpecificationNamed: (NSString *)name entityNamed: (NSString *)entityName { EOFetchSpecification *newEOFetchSpecification = nil; EOModelGroup *anModelGroup; EOFLOGClassFnStartOrCond(@"EOFetchSpecification"); anModelGroup = [EOModelGroup defaultGroup]; if (anModelGroup) newEOFetchSpecification = [anModelGroup fetchSpecificationNamed: name entityNamed: entityName]; EOFLOGObjectFnStopOrCond(@"EOFetchSpecification"); return newEOFetchSpecification; } @end gnustep-dl2-0.12.0/EOAccess/EOAttributePriv.h0000644000175000017500000000305010645346232017617 0ustar ayersayers/* -*-objc-*- EOAttributePriv.h Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: July 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOAttributePriv_h__ #define __EOAttributePriv_h__ @interface EOAttribute (EOAttributePrivate) - (NSMutableArray *)_definitionArray; - (void)setParent: (id)parent; - (EOAttribute *)realAttribute; - (Class)_valueClass; - (unichar)_valueTypeCharacter; @end @interface EOAttribute (EOAttributePrivate2) - (BOOL)_hasAnyOverrides; - (void)_resetPrototype; - (void)_updateFromPrototype; - (void)_setOverrideForKeyEnum: (int)keyEnum; - (BOOL)_isKeyEnumOverriden: (int)param0; - (BOOL)_isKeyEnumDefinedByPrototype: (int)param0; @end #endif /* __EOAttributePriv_h__ */ gnustep-dl2-0.12.0/EOAccess/EOJoin.h0000644000175000017500000000346011137323411015706 0ustar ayersayers/* -*-objc-*- EOJoin.h Copyright (C) 1996,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Ovidiu Predescu Date: August 1996 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOJoin_h__ #define __EOJoin_h__ @class NSString; @class EOEntity; @class EOAttribute; @interface EOJoin : NSObject { EOAttribute *_sourceAttribute; EOAttribute *_destinationAttribute; } - (id)initWithSourceAttribute: (EOAttribute *)source destinationAttribute: (EOAttribute *)destination; - (NSString *)description; - (EOAttribute *)sourceAttribute; - (EOAttribute *)destinationAttribute; - (BOOL)isReciprocalToJoin: (EOJoin *)otherJoin; @end @interface EOJoin (EOJoinPrivate) //+ (EOJoin *)joinFromPropertyList: (id)propertyList; //- (void)replaceStringsWithObjectsInRelationship: (EORelationship *)entity; //- (id)propertyList; + (EOJoin *)joinWithSourceAttribute: (EOAttribute *)source destinationAttribute: (EOAttribute *)destination; @end /* EOJoin (EOJoinPrivate) */ #endif /* __EOJoin_h__ */ gnustep-dl2-0.12.0/EOAccess/EOEntity.h0000644000175000017500000002246110764015646016302 0ustar ayersayers/* -*-objc-*- EOEntity.h Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOEntity_h__ #define __EOEntity_h__ #ifdef GNUSTEP #include #include #else #include #endif #include #include #include @class EOModel; @class EOAttribute; @class EOQualifier; @class EORelationship; @class EOEntity; @class EOStoredProcedure; @class EOKeyGlobalID; @class EOFetchSpecification; @class EOGlobalID; @class EOMutableKnownKeyDictionary; @class EOMKKDInitializer; @class EOMKKDSubsetMapping; @interface EOEntity : NSObject { NSString *_name; NSString *_className; NSString *_externalName; NSString *_externalQuery; NSDictionary *_userInfo; NSString* _docComment; NSDictionary * _internalInfo; EOQualifier *_restrictingQualifier; NSMutableDictionary *_fetchSpecificationDictionary; NSArray *_fetchSpecificationNames; NSMutableDictionary *_storedProcedures; NSArray *_classPropertyNames; NSArray *_primaryKeyAttributeNames; NSArray *_classPropertyAttributeNames; NSArray *_classPropertyToOneRelationshipNames; NSArray *_classPropertyToManyRelationshipNames; EOClassDescription *_classDescription; NSMutableArray *_hiddenRelationships; unsigned int _batchCount; EOMKKDInitializer* _adaptorDictionaryInitializer; EOMKKDInitializer* _snapshotDictionaryInitializer; EOMKKDInitializer* _primaryKeyDictionaryInitializer; EOMKKDInitializer* _propertyDictionaryInitializer; EOMKKDInitializer* _instanceDictionaryInitializer; EOMKKDSubsetMapping* _snapshotToAdaptorRowSubsetMapping; Class _classForInstances; /* Garbage collectable objects */ EOModel *_model; NSMutableArray *_attributes; NSMutableDictionary *_attributesByName; NSMutableArray *_relationships; NSMutableDictionary *_relationshipsByName; // name/EORelationship NSMutableArray *_primaryKeyAttributes; NSMutableArray *_classProperties; // EOAttribute/EORelationship NSMutableArray *_attributesUsedForLocking; NSMutableArray *_attributesToFetch; NSMutableArray *_attributesToSave; NSMutableArray *_propertiesToFault; NSArray* _dbSnapshotKeys; NSMutableArray *_subEntities; EOEntity *_parent; struct { unsigned int attributesIsLazy:1; unsigned int relationshipsIsLazy:1; unsigned int classPropertiesIsLazy:1; unsigned int primaryKeyAttributesIsLazy:1; unsigned int attributesUsedForLockingIsLazy:1; unsigned int isReadOnly:1; unsigned int isAbstractEntity:1; unsigned int updating:1; unsigned int cachesObjects:1; unsigned int unused:1; unsigned int extraRefCount:22; } _flags; } - (NSString *)name; - (EOModel *)model; - (NSString *)externalName; - (NSString *)externalQuery; - (EOQualifier *)restrictingQualifier; /* see also: EOEntityEditing */ /* Caching */ - (BOOL)isReadOnly; - (BOOL)cachesObjects; /* EOClass name */ - (NSString *)className; - (NSDictionary *)userInfo; /* Accessing attributes */ - (NSArray *)attributes; - (EOAttribute *)attributeNamed: (NSString *)attributeName; - (EOAttribute *)anyAttributeNamed: (NSString *)attributeName; /* Accessing relationships */ - (NSArray *)relationships; - (EORelationship *)relationshipNamed: (NSString *)relationshipName; - (EORelationship *)anyRelationshipNamed: (NSString *)relationshipName; /* Accessing class properties */ - (NSArray *)classProperties; - (NSArray *)classPropertyNames; - (NSArray *)fetchSpecificationNames; - (EOFetchSpecification *)fetchSpecificationNamed: (NSString *)fetchSpecName; - (NSArray *)sharedObjectFetchSpecificationNames; /* Accessing primary key attributes */ - (NSArray *)primaryKeyAttributes; - (NSArray *)primaryKeyAttributeNames; /* Accessing locking attributes */ - (NSArray *)attributesUsedForLocking; - (NSArray *)attributesToFetch; /* Getting primary keys and snapshot for row */ - (EOQualifier *)qualifierForPrimaryKey: (NSDictionary *)row; - (BOOL)isQualifierForPrimaryKey: (EOQualifier *)qualifier; - (NSDictionary *)primaryKeyForRow: (NSDictionary *)row; - (BOOL)isValidAttributeUsedForLocking: (EOAttribute *)attribute; - (BOOL)isValidPrimaryKeyAttribute: (EOAttribute *)attribute; - (BOOL)isPrimaryKeyValidInObject: (id)object; - (BOOL)isValidClassProperty: (id)property; - (NSArray *)subEntities; - (EOEntity *)parentEntity; - (BOOL)isAbstractEntity; - (unsigned int)maxNumberOfInstancesToBatchFetch; - (EOGlobalID *)globalIDForRow: (NSDictionary *)row; - (NSDictionary *)primaryKeyForGlobalID: (EOKeyGlobalID *)gid; @end @interface EOEntity (EOEntityEditing) - (void)setName: (NSString *)name; - (void)setExternalName: (NSString *)name; - (void)setExternalQuery: (NSString *)query; - (void)setRestrictingQualifier: (EOQualifier *)qualifier; - (void)setReadOnly: (BOOL)flag; - (void)setCachesObjects: (BOOL)flag; - (void)addAttribute: (EOAttribute *)attribute; - (void)removeAttribute: (EOAttribute *)attribute; - (void)addRelationship: (EORelationship *)relationship; - (void)removeRelationship: (EORelationship *)relationship; - (void)addFetchSpecification: (EOFetchSpecification *)fetchSpec withName: (NSString *)name; - (void)removeFetchSpecificationNamed: (NSString *)name; - (void)setSharedObjectFetchSpecificationsByName: (NSArray *)names; - (void)addSharedObjectFetchSpecificationByName: (NSString *)name; - (void)removeSharedObjectFetchSpecificationByName: (NSString *)name; - (void)setClassName: (NSString *)name; - (void)setUserInfo: (NSDictionary *)dictionary; - (BOOL)setClassProperties: (NSArray *)properties; - (BOOL)setPrimaryKeyAttributes: (NSArray *)keys; - (BOOL)setAttributesUsedForLocking: (NSArray *)attributes; - (NSException *)validateName: (NSString *)name; - (void)addSubEntity: (EOEntity *)child; - (void)removeSubEntity: (EOEntity *)child; - (void)setIsAbstractEntity: (BOOL)flag; - (void)setMaxNumberOfInstancesToBatchFetch: (unsigned int)size; @end @interface EOEntity (EOModelReferentialIntegrity) - (BOOL)referencesProperty: (id)property; - (NSArray *)externalModelsReferenced; @end @interface EOEntity (EOModelBeautifier) - (void)beautifyName; @end @interface EOEntity (GDL2Extenstions) - (NSString *)docComment; - (void)setDocComment: (NSString *)docComment; @end GDL2ACCESS_EXPORT NSString *EOFetchAllProcedureOperation; GDL2ACCESS_EXPORT NSString *EOFetchWithPrimaryKeyProcedureOperation; GDL2ACCESS_EXPORT NSString *EOInsertProcedureOperation; GDL2ACCESS_EXPORT NSString *EODeleteProcedureOperation; GDL2ACCESS_EXPORT NSString *EONextPrimaryKeyProcedureOperation; @interface EOEntity (EOStoredProcedures) - (EOStoredProcedure *)storedProcedureForOperation: (NSString *)operation; - (void)setStoredProcedure: (EOStoredProcedure *)storedProcedure forOperation: (NSString *)operation; @end @interface EOEntity (EOPrimaryKeyGeneration) - (NSString *)primaryKeyRootName; @end @interface EOEntity (EOEntityClassDescription) - (EOClassDescription *)classDescriptionForInstances; @end /** Useful private methods made public in GDL2 **/ @interface EOEntity (EOEntityGDL2Additions) /** Returns attribute (if any) for path **/ - (EOAttribute *)attributeForPath: (NSString *)path; /** Returns relationship (if any) for path **/ - (EORelationship *)relationshipForPath: (NSString *)path; @end @interface EOEntityClassDescription : EOClassDescription { EOEntity *_entity; unsigned int extraRefCount; } - (id)initWithEntity: (EOEntity *)entity; - (EOEntity *)entity; - (EOFetchSpecification *)fetchSpecificationNamed: (NSString *)name; @end @interface EOEntityClassDescription (GDL2Extenstions) /** returns a new autoreleased mutable dictionary to store properties returns nil if there's no key in the instanceDictionaryInitializer **/ - (EOMutableKnownKeyDictionary *)dictionaryForInstanceProperties; @end @interface NSString (EODatabaseNameConversion) + (NSString *)nameForExternalName: (NSString *)externalName separatorString: (NSString *)separatorString initialCaps: (BOOL)initialCaps; + (NSString *)externalNameForInternalName: (NSString *)internalName separatorString: (NSString *)separatorString useAllCaps: (BOOL)allCaps; @end @interface NSObject (EOEntity) /** should returns an array of property names to exclude from entity instanceDictionaryInitializer **/ + (NSArray *)_instanceDictionaryInitializerExcludedPropertyNames; @end #endif /* __EOEntity_h__ */ gnustep-dl2-0.12.0/EOAccess/EOStoredProcedure.h0000644000175000017500000000401110645346232020122 0ustar ayersayers/* -*-objc-*- EOStoredProcedure.h Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOStoredProcedure_h__ #define __EOStoredProcedure_h__ #include @class NSDictionary; @class EOModel; @class EOAttribute; @class EOStoredProcedure; @interface EOStoredProcedure : NSObject { NSString *_name; NSString *_externalName; NSDictionary *_userInfo; NSDictionary *_internalInfo; /* Garbage collectable objects */ EOModel *_model; NSArray *_arguments; } + (EOStoredProcedure *)storedProcedureWithPropertyList: (NSDictionary *)propertyList owner: (id)owner; - (EOStoredProcedure *)initWithName: (NSString *)name; - (NSString *)name; - (NSString *)externalName; - (EOModel *)model; - (NSArray *)arguments; - (NSDictionary *)userInfo; - (void)setName: (NSString *)name; - (void)setExternalName: (NSString *)name; - (void)setArguments: (NSArray *)arguments; - (void)setUserInfo: (NSDictionary *)dictionary; @end @interface EOStoredProcedure (EOModelBeautifier) - (void)beautifyName; @end #endif gnustep-dl2-0.12.0/EOAccess/EOSQLQualifier.h0000644000175000017500000000522010645346232017315 0ustar ayersayers/* -*-objc-*- EOSQLQualifier.h Copyright (C) 2000-2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 Author: Manuel Guesdon Date: February 2002 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOSQLQualifier_h__ #define __EOSQLQualifier_h__ #ifdef GNUSTEP #include #else #include #endif #include @class EOSQLExpression; @class EOExpressionArray; @class EOEntity; @class EOModel; /** Protocol for all qualifiers used used to generate SQL queries **/ @protocol EOQualifierSQLGeneration - (NSString *)sqlStringForSQLExpression: (EOSQLExpression *)sqlExpression; /** Returns an equivalent EOQualifier yet having the object references replaced by foreign key references. **/ - (EOQualifier *)schemaBasedQualifierWithRootEntity: (EOEntity *)entity; @end @interface EOAndQualifier (EOQualifierSQLGeneration) @end @interface EOOrQualifier (EOQualifierSQLGeneration) @end @interface EOKeyComparisonQualifier (EOQualifierSQLGeneration) @end @interface EOKeyValueQualifier (EOQualifierSQLGeneration) @end @interface EONotQualifier (EOQualifierSQLGeneration) @end @interface EOSQLQualifier : EOQualifier { EOEntity *_entity; EOExpressionArray *_contents; struct { unsigned int usesDistinct:1; unsigned int _RESERVED:31; } _flags; } + (EOQualifier *)qualifierWithQualifierFormat: (NSString *)format, ...; - (id)initWithEntity: (EOEntity *)entity qualifierFormat: (NSString *)qualifierFormat, ...; @end @interface NSString (NSStringSQLExpression) - (NSString *)valueForSQLExpression: (EOSQLExpression *)sqlExpression; @end #endif gnustep-dl2-0.12.0/EOAccess/EOAttribute.h0000644000175000017500000001527711137323411016763 0ustar ayersayers/* -*-objc-*- EOAttribute.h Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: Feb 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOAttribute_h__ #define __EOAttribute_h__ #ifdef GNUSTEP #include #include #else #include #endif #include @class NSDictionary; @class NSData; @class NSException; @class NSCalendarDate; @class NSTimeZone; @class EOEntity; @class EOExpressionArray; @class EOStoredProcedure; typedef enum { EOFactoryMethodArgumentIsNSData = 0, EOFactoryMethodArgumentIsNSString, EOFactoryMethodArgumentIsBytes } EOFactoryMethodArgumentType; typedef enum { EOAdaptorNumberType, EOAdaptorCharactersType, EOAdaptorBytesType, EOAdaptorDateType } EOAdaptorValueType; typedef enum { EOVoid = 0, EOInParameter, EOOutParameter, EOInOutParameter } EOParameterDirection; @interface EOAttribute : NSObject { NSString *_name; NSString *_columnName; NSString *_externalType; NSString *_valueType; NSString *_valueClassName; NSString *_readFormat; NSString *_writeFormat; NSTimeZone *_serverTimeZone; unsigned int _width; unsigned short _precision; short _scale; unichar _valueTypeCharacter; /** First char of _valueType or \0 **/ Class _valueClass; EOAdaptorValueType _adaptorValueType; EOFactoryMethodArgumentType _argumentType; NSString *_valueFactoryMethodName; NSString *_adaptorValueConversionMethodName; SEL _valueFactoryMethod; SEL _adaptorValueConversionMethod; struct { unsigned int allowsNull:1; unsigned int isReadOnly:1; unsigned int isParentAnEOEntity:1; unsigned int protoOverride:18; unsigned int isAttributeValueInitialized:1; unsigned int unused : 10; } _flags; unsigned int extraRefCount; NSDictionary *_sourceToDestinationKeyMap; EOParameterDirection _parameterDirection; NSDictionary *_userInfo; NSDictionary *_internalInfo; NSString *_docComment; id _parent; /* unretained */ EOAttribute *_prototype; EOExpressionArray *_definitionArray; EOAttribute *_realAttribute; // if the attribute is flattened //Not in EOF ! } /** returns an autoreleased attribute owned by onwer and built from propertyList **/ + (id)attributeWithPropertyList: (NSDictionary *)propertyList owner: (id)owner; /* Accessing the entity */ - (NSString *)name; - (EOEntity *)entity; - (EOStoredProcedure *)storedProcedure; - (id)parent; - (NSString *)prototypeName; - (EOAttribute *)prototype; - (NSString *)externalType; - (NSString *)columnName; - (NSString *)definition; - (BOOL)isFlattened; - (BOOL)isDerived; - (BOOL)isReadOnly; - (NSString *)valueClassName; - (NSString *)valueType; - (unsigned int)width; - (unsigned int)precision; - (int)scale; - (BOOL)allowsNull; - (NSString *)writeFormat; - (NSString *)readFormat; - (EOParameterDirection)parameterDirection; - (NSDictionary *)userInfo; - (NSString *)docComment; - (BOOL)isKeyDefinedByPrototype: (NSString *)key; @end @interface EOAttribute (EOAttributeEditing) - (NSException *)validateName: (NSString *)name; - (void)setName: (NSString *)name; - (void)setPrototype: (EOAttribute *)prototype; - (void)setReadOnly: (BOOL)yn; - (void)setColumnName: (NSString *)columnName; - (void)setDefinition: (NSString *)definition; - (void)setExternalType: (NSString *)type; - (void)setValueType: (NSString *)type; - (void)setValueClassName: (NSString *)name; - (void)setWidth: (unsigned int)length; - (void)setPrecision: (unsigned int)precision; - (void)setScale: (int)scale; - (void)setAllowsNull: (BOOL)allowsNull; - (void)setWriteFormat: (NSString *)string; - (void)setReadFormat: (NSString *)string; - (void)setParameterDirection: (EOParameterDirection)parameterDirection; - (void)setUserInfo: (NSDictionary *)dictionary; - (void)setInternalInfo: (NSDictionary *)dictionary; - (void)setDocComment: (NSString *)docComment; - (id)_normalizeDefinition: (EOExpressionArray *)definition path: (id)path; @end @interface EOAttribute(EOModelBeautifier) - (void)beautifyName; @end @interface EOAttribute (NSCalendarDateSupport) - (NSTimeZone *)serverTimeZone; @end @interface EOAttribute(NSCalendarDateSupportEditing) - (void)setServerTimeZone: (NSTimeZone *)tz; @end @interface EOAttribute (EOAttributeValueCreation) - (id)newValueForBytes: (const void *)bytes length: (int)length; - (id)newValueForBytes: (const void *)bytes length: (int)length encoding: (NSStringEncoding)encoding; - (NSCalendarDate *)newDateForYear: (int)year month: (unsigned int)month day: (unsigned int)day hour: (unsigned int)hour minute: (unsigned int)minute second: (unsigned int)second millisecond: (unsigned int)millisecond timezone: (NSTimeZone *)timezone zone: (NSZone *)zone; - (NSString *)valueFactoryMethodName; - (SEL)valueFactoryMethod; - (id)adaptorValueByConvertingAttributeValue: (id)value; - (NSString *)adaptorValueConversionMethodName; - (SEL)adaptorValueConversionMethod; - (EOAdaptorValueType)adaptorValueType; - (EOFactoryMethodArgumentType)factoryMethodArgumentType; @end @interface EOAttribute(EOAttributeValueCreationEditing) - (void)setValueFactoryMethodName: (NSString *)factoryMethodName; - (void)setAdaptorValueConversionMethodName: (NSString *)conversionMethodName; - (void)setFactoryMethodArgumentType: (EOFactoryMethodArgumentType)argumentType; @end @interface EOAttribute(EOAttributeValueMapping) - (NSException *)validateValue: (id *)valueP; @end @interface NSObject (EOCustomClassArchiving) + (id)objectWithArchiveData: (NSData *)data; - (NSData *)archiveData; @end #endif /* __EOAttribute_h__ */ gnustep-dl2-0.12.0/EOAccess/EOAccess.h0000644000175000017500000000326110645346232016220 0ustar ayersayers/* EOAccess.h Copyright (C) 2000-2002,2003,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOAccess_h__ #define __EOAccess_h__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif /* __EOAccess_h__ */ gnustep-dl2-0.12.0/EOAccess/EOAdaptorChannel.h0000644000175000017500000001562610645346232017712 0ustar ayersayers/* -*-objc-*- EOAdaptorChannel.h Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOAdaptorChannel_h__ #define __EOAdaptorChannel_h__ #ifdef GNUSTEP #include #include #else #include #endif #include @class NSArray; @class NSMutableArray; @class NSDictionary; @class NSMutableDictionary; @class NSString; @class NSMutableString; @class NSCalendarDate; @class NSException; @class EOModel; @class EOEntity; @class EOAttribute; @class EOAdaptorContext; @class EOQualifier; @class EOStoredProcedure; @class EOAdaptorOperation; @class EOSQLExpression; @class EOFetchSpecification; /* The EOAdaptorChannel class could be overriden for a concrete database adaptor. You have to override only those methods marked in this header with `override'. */ @interface EOAdaptorChannel : NSObject { EOAdaptorContext *_context; id _delegate; // not retained BOOL _debug; /* Flags used to check if the delegate responds to several messages */ struct { unsigned willPerformOperations:1; unsigned didPerformOperations:1; unsigned shouldSelectAttributes:1; unsigned didSelectAttributes:1; unsigned willFetchRow:1; unsigned didFetchRow:1; unsigned didChangeResultSet:1; unsigned didFinishFetching:1; unsigned shouldEvaluateExpression:1; unsigned didEvaluateExpression:1; unsigned shouldExecuteStoredProcedure:1; unsigned didExecuteStoredProcedure:1; unsigned shouldConstructStoredProcedureReturnValues:1; unsigned shouldReturnValuesForStoredProcedure:1; } _delegateRespondsTo; } + (EOAdaptorChannel *)adaptorChannelWithAdaptorContext: (EOAdaptorContext *)adaptorContext; /* Initializing an adaptor context */ - (id)initWithAdaptorContext: (EOAdaptorContext *)adaptorContext; /* Getting the adaptor context */ - (EOAdaptorContext *)adaptorContext; /* Opening and closing a channel */ - (BOOL)isOpen; - (void)openChannel; - (void)closeChannel; /* Modifying rows */ - (void)insertRow: (NSDictionary *)row forEntity: (EOEntity *)entity; - (void)updateValues: (NSDictionary *)values inRowDescribedByQualifier: (EOQualifier *)qualifier entity: (EOEntity *)entity; - (unsigned)updateValues: (NSDictionary *)values inRowsDescribedByQualifier: (EOQualifier *)qualifier entity: (EOEntity *)entity; - (void)deleteRowDescribedByQualifier: (EOQualifier *)qualifier entity: (EOEntity *)entity; - (unsigned)deleteRowsDescribedByQualifier: (EOQualifier *)qualifier entity: (EOEntity *)entity; /* Fetching rows */ - (void)selectAttributes: (NSArray *)attributes fetchSpecification: (EOFetchSpecification *)fetchSpecification lock: (BOOL)flag entity: (EOEntity *)entity; - (void)lockRowComparingAttributes: (NSArray *)attrs entity: (EOEntity *)entity qualifier: (EOQualifier *)qualifier snapshot: (NSDictionary *)snapshot; - (void)evaluateExpression: (EOSQLExpression *)expression; - (BOOL)isFetchInProgress; - (NSArray *)describeResults; - (NSMutableDictionary *)fetchRowWithZone: (NSZone *)zone; - (void)setAttributesToFetch: (NSArray *)attributes; - (NSArray *)attributesToFetch; - (void)cancelFetch; - (NSDictionary *)primaryKeyForNewRowWithEntity: (EOEntity *)entity; - (NSArray *)describeTableNames; - (NSArray *)describeStoredProcedureNames; - (EOModel *)describeModelWithTableNames: (NSArray *)tableNames; - (void)addStoredProceduresNamed: (NSArray *)storedProcedureNames toModel: (EOModel *)model; - (void)setDebugEnabled: (BOOL)flag; - (BOOL)isDebugEnabled; - (id)delegate; - (void)setDelegate: (id)delegate; - (NSMutableDictionary *)dictionaryWithObjects: (id *)objects forAttributes: (NSArray *)attributes zone: (NSZone *)zone; @end @interface EOAdaptorChannel (EOStoredProcedures) - (void)executeStoredProcedure: (EOStoredProcedure *)storedProcedure withValues: (NSDictionary *)values; - (NSDictionary *)returnValuesForLastStoredProcedureInvocation; @end @interface EOAdaptorChannel (EOBatchProcessing) - (void)performAdaptorOperation: (EOAdaptorOperation *)adaptorOperation; - (void)performAdaptorOperations: (NSArray *)adaptorOperations; @end @interface NSObject (EOAdaptorChannelDelegation) - (NSArray *)adaptorChannel: (id)channel willPerformOperations: (NSArray *)operations; - (NSException *)adaptorChannel: (id)channel didPerformOperations: (NSArray *)operations exception: (NSException *)exception; - (BOOL)adaptorChannel: (id)channel shouldSelectAttributes: (NSArray *)attributes fetchSpecification: (EOFetchSpecification *)fetchSpecification lock: (BOOL)flag entity: (EOEntity *)entity; - (void)adaptorChannel: (id)channel didSelectAttributes: (NSArray *)attributes fetchSpecification: (EOFetchSpecification *)fetchSpecification lock: (BOOL) flag entity: (EOEntity *)entity; - (void)adaptorChannelWillFetchRow: (id)channel; - (void)adaptorChannel: (id)channel didFetchRow: (NSMutableDictionary *)row; - (void)adaptorChannelDidChangeResultSet: (id)channel; - (void)adaptorChannelDidFinishFetching: (id)channel; - (BOOL)adaptorChannel: (id)channel shouldEvaluateExpression: (EOSQLExpression *)expression; - (void)adaptorChannel: (id)channel didEvaluateExpression: (EOSQLExpression *)expression; - (NSDictionary *)adaptorChannel: (id)channel shouldExecuteStoredProcedure: (EOStoredProcedure *)procedure withValues: (NSDictionary *)values; - (void)adaptorChannel: (id)channel didExecuteStoredProcedure: (EOStoredProcedure *)procedure withValues: (NSDictionary *)values; - (NSDictionary *)adaptorChannelShouldConstructStoredProcedureReturnValues: (id)channel; - (NSDictionary *)adaptorChannel: (id)channel shouldReturnValuesForStoredProcedure: (NSDictionary *)returnValues; @end /* NSObject(EOAdaptorChannelDelegation) */ GDL2ACCESS_EXPORT NSString *EOAdaptorOperationsKey; GDL2ACCESS_EXPORT NSString *EOFailedAdaptorOperationKey; GDL2ACCESS_EXPORT NSString *EOAdaptorFailureKey; GDL2ACCESS_EXPORT NSString *EOAdaptorOptimisticLockingFailure; #endif /* __EOAdaptorChannel_h__ */ gnustep-dl2-0.12.0/EOAccess/EOGenericRecord.m0000644000175000017500000000303611147237512017535 0ustar ayersayers/* -*-objc-*- EOGenericRecord.m EOGenericRecord Category Copyright (C) 2009 Free Software Foundation, Inc. Author: David Ayers Date: February 2009 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" RCS_ID("$Id: EOEntity.m 27910 2009-02-18 05:52:42Z ayers $") #ifndef GNUSTEP #include #include #include #endif #include #include @implementation EOGenericRecord (EOAccessAdditions) /** * Determins and returns the receivers entity. */ - (EOEntity *)entity { if ([classDescription respondsToSelector:@selector(entity)]) return [(EOEntityClassDescription *)classDescription entity]; return nil; } @end gnustep-dl2-0.12.0/EOAccess/Makefile.preamble0000644000175000017500000000476210765761345017670 0ustar ayersayers# # Makefile.preamble # # Copyright (C) 1997,2002,2004,2005 Free Software Foundation, Inc. # # Written by: Scott Christley # # 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 3 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, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # # Makefile.preamble # # Project specific makefile variables, and additional # # Do not put any Makefile rules in this file, instead they should # be put into Makefile.postamble. # # # Flags dealing with compiling and linking # # Additional flags to pass to the preprocessor ADDITIONAL_CPPFLAGS = $(FND_DEFINE) $(RUNTIME_DEFINE) -g # Additional flags to pass to the Objective-C compiler ADDITIONAL_OBJCFLAGS = $(TEST_CFLAGS) # Additional flags to pass to the C compiler ADDITIONAL_CFLAGS = $(TEST_CFLAGS) # Additional include directories the compiler should search ADDITIONAL_INCLUDE_DIRS = -I../EOControl/$(GNUSTEP_TARGET_DIR) -I.. # Additional LDFLAGS to pass to the linker ADDITIONAL_LDFLAGS = $(TEST_LDFLAGS) # Additional library directories the linker should search ADDITIONAL_LIB_DIRS = # # Flags dealing with installing and uninstalling # # Additional directories to be created during installation ADDITIONAL_INSTALL_DIRS = # What are the libraries this library depends upon. This is needed for some # systems where building a shared library requires to pass to the linker # all the libraries the target library depends upon. ifneq ($(FOUNDATION_LIBRARY_NAME),) LIBRARIES_DEPEND_UPON = $(FND_LIBS) endif ifneq ($(FOUNDATION_LIB),gnu) LIBRARIES_DEPEND_UPON += -lgnustep-baseadd endif LIBRARIES_DEPEND_UPON += $(TEST_COVERAGE_LIBS) ADDITIONAL_NATIVE_LIBS += EOControl ADDITIONAL_NATIVE_LIB_DIRS+=../EOControl ifeq ($(FOUNDATION_HAS_KVC), yes) ADDITIONAL_OBJCFLAGS := $(ADDITIONAL_OBJCFLAGS) -DFOUNDATION_HAS_KVC=1 endif gnustep-dl2-0.12.0/EOAccess/EOAttribute.m0000644000175000017500000015215611022201266016762 0ustar ayersayers/** EOAttribute.m EOAttribute Class Copyright (C) 2000-2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 Author: Manuel Guesdon Date: October 2000 $Revision: 26597 $ $Date: 2008-06-06 11:26:14 +0200 (Fre, 06. Jun 2008) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EOAttribute.m 26597 2008-06-06 09:26:14Z ayers $") #include #include #ifdef GNUSTEP #include #include #include #include #include #include #include #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include "EOPrivate.h" #include "EOEntityPriv.h" #include "EOAttributePriv.h" @implementation EOAttribute + (void)initialize { static BOOL initialized=NO; if (!initialized) { initialized=YES; GDL2_EOAccessPrivateInit(); } } + (id) attributeWithPropertyList: (NSDictionary *)propertyList owner: (id)owner { return [[[self alloc] initWithPropertyList: propertyList owner: owner] autorelease]; } - (id) initWithPropertyList: (NSDictionary *)propertyList owner: (id)owner { if ((self = [self init])) { NSString *tmpString = nil; id tmpObject = nil; // set this first so the name can validate against the parent. [self setParent: owner]; [self setName: [propertyList objectForKey: @"name"]]; [self setExternalType: [propertyList objectForKey: @"externalType"]]; tmpString = [propertyList objectForKey: @"allowsNull"]; if (tmpString) [self setAllowsNull: [tmpString boolValue]]; [self setValueType: [propertyList objectForKey: @"valueType"]]; [self setValueClassName: [propertyList objectForKey: @"valueClassName"]]; tmpString = [propertyList objectForKey: @"writeFormat"]; if (tmpString) [self setWriteFormat: tmpString]; else { tmpString = [propertyList objectForKey: @"updateFormat"]; if (tmpString) [self setWriteFormat: tmpString]; else { tmpString = [propertyList objectForKey: @"insertFormat"]; if (tmpString) [self setWriteFormat: tmpString]; } } tmpString = [propertyList objectForKey: @"readFormat"]; if (tmpString) [self setReadFormat: tmpString]; else { tmpString = [propertyList objectForKey: @"selectFormat"]; [self setReadFormat: tmpString]; } /* tmpString = [propertyList objectForKey: @"maximumLength"]; if (tmpString) [self setMaximumLength: [tmpString intValue]]; */ tmpString = [propertyList objectForKey: @"width"]; if (tmpString) [self setWidth: [tmpString intValue]]; tmpString = [propertyList objectForKey: @"valueFactoryMethodName"]; if (tmpString) [self setValueFactoryMethodName: tmpString]; tmpString = [propertyList objectForKey: @"adaptorValueConversionMethodName"]; if (tmpString) [self setAdaptorValueConversionMethodName: tmpString]; tmpString = [propertyList objectForKey: @"factoryMethodArgumentType"]; if(tmpString) { EOFactoryMethodArgumentType argType = EOFactoryMethodArgumentIsBytes; if ([tmpString isEqual: @"EOFactoryMethodArgumentIsNSData"]) argType = EOFactoryMethodArgumentIsNSData; else if ([tmpString isEqual: @"EOFactoryMethodArgumentIsNSString"]) argType = EOFactoryMethodArgumentIsNSString; [self setFactoryMethodArgumentType: argType]; } tmpString = [propertyList objectForKey: @"precision"]; if (tmpString) [self setPrecision: [tmpString intValue]]; tmpString = [propertyList objectForKey: @"scale"]; if (tmpString) [self setScale: [tmpString intValue]]; tmpString = [propertyList objectForKey: @"serverTimeZone"]; if (tmpString) [self setServerTimeZone: [NSTimeZone timeZoneWithName: tmpString]]; tmpString = [propertyList objectForKey: @"parameterDirection"]; if (tmpString) { EOParameterDirection tmpDir = [tmpString intValue]; EOParameterDirection eDirection = EOVoid; if ([tmpString isEqual: @"in"] || tmpDir == EOInParameter) eDirection = EOInParameter; else if ([tmpString isEqual: @"out"] || tmpDir == EOOutParameter) eDirection = EOOutParameter; else if ([tmpString isEqual: @"inout"] || tmpDir == EOInOutParameter) eDirection = EOInOutParameter; [self setParameterDirection: eDirection]; } tmpObject = [propertyList objectForKey: @"userInfo"]; if (tmpObject) [self setUserInfo: tmpObject]; else { tmpObject = [propertyList objectForKey: @"userDictionary"]; if (tmpObject) [self setUserInfo: tmpObject]; } tmpObject = [propertyList objectForKey: @"internalInfo"]; if (tmpObject) [self setInternalInfo: tmpObject]; tmpString = [propertyList objectForKey: @"docComment"]; if (tmpString) [self setDocComment: tmpString]; tmpString = [propertyList objectForKey: @"isReadOnly"]; [self setReadOnly: [tmpString boolValue]]; } return self; } - (void)awakeWithPropertyList: (NSDictionary *)propertyList { //Seems OK NSString *definition; NSString *columnName; NSString *tmpString; definition = [propertyList objectForKey: @"definition"]; if (definition) [self setDefinition: definition]; columnName = [propertyList objectForKey: @"columnName"]; if (columnName) [self setColumnName: columnName]; tmpString = [propertyList objectForKey: @"prototypeName"]; if (tmpString) { EOAttribute *attr = [[_parent model] prototypeAttributeNamed: tmpString]; if (attr) [self setPrototype: attr]; } EOFLOGObjectLevelArgs(@"gsdb", @"Attribute %@ awakeWithPropertyList:%@", self, propertyList); } - (void)encodeIntoPropertyList: (NSMutableDictionary *)propertyList { if (_name) [propertyList setObject: _name forKey: @"name"]; if (_prototype) [propertyList setObject: [_prototype name] forKey: @"prototypeName"]; if (_serverTimeZone) [propertyList setObject: [_serverTimeZone name] forKey: @"serverTimeZone"]; if (_columnName) [propertyList setObject: _columnName forKey: @"columnName"]; if (_definitionArray) [propertyList setObject: [_definitionArray definition] forKey: @"definition"]; if (_externalType) [propertyList setObject: _externalType forKey: @"externalType"]; if (_valueClassName) [propertyList setObject: _valueClassName forKey: @"valueClassName"]; if (_valueType) [propertyList setObject: _valueType forKey: @"valueType"]; if (_valueFactoryMethodName) { NSString *methodArg; [propertyList setObject: _valueFactoryMethodName forKey: @"valueFactoryMethodName"]; switch (_argumentType) { case EOFactoryMethodArgumentIsNSData: methodArg = @"EOFactoryMethodArgumentIsNSData"; break; case EOFactoryMethodArgumentIsNSString: methodArg = @"EOFactoryMethodArgumentIsNSString"; break; case EOFactoryMethodArgumentIsBytes: methodArg = @"EOFactoryMethodArgumentIsBytes"; break; default: methodArg = nil; [NSException raise: NSInternalInconsistencyException format: @"%@ -- %@ 0x%x: Invalid value for _argumentType:%d", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, _argumentType]; } [propertyList setObject: methodArg forKey: @"factoryMethodArgumentType"]; } if (_adaptorValueConversionMethodName) [propertyList setObject: _adaptorValueConversionMethodName forKey: @"adaptorValueConversionMethodName"]; if (_readFormat) [propertyList setObject: _readFormat forKey: @"readFormat"]; if (_writeFormat) [propertyList setObject: _writeFormat forKey: @"writeFormat"]; if (_width > 0) [propertyList setObject: [NSString stringWithFormat:@"%u", _width] forKey: @"width"]; if (_precision > 0) [propertyList setObject: [NSString stringWithFormat:@"%hu", _precision] forKey: @"precision"]; if (_scale != 0) [propertyList setObject: [NSString stringWithFormat:@"%hi", _scale] forKey: @"scale"]; if (_parameterDirection != 0) [propertyList setObject: [NSString stringWithFormat:@"%d", (int)_parameterDirection] forKey: @"parameterDirection"]; if (_userInfo) [propertyList setObject: _userInfo forKey: @"userInfo"]; if (_docComment) [propertyList setObject: _docComment forKey: @"docComment"]; if (_flags.isReadOnly) [propertyList setObject: @"Y" forKey: @"isReadOnly"]; if (_flags.allowsNull) [propertyList setObject: @"Y" forKey: @"allowsNull"]; } - (void)dealloc { DESTROY(_name); DESTROY(_prototype); DESTROY(_columnName); DESTROY(_externalType); DESTROY(_valueType); DESTROY(_valueClassName); DESTROY(_readFormat); DESTROY(_writeFormat); DESTROY(_serverTimeZone); DESTROY(_valueFactoryMethodName); DESTROY(_adaptorValueConversionMethodName); DESTROY(_sourceToDestinationKeyMap); DESTROY(_userInfo); DESTROY(_internalInfo); DESTROY(_docComment); [super dealloc]; } - (unsigned)hash { return [_name hash]; } - (NSString *)description { NSString *dscr = [NSString stringWithFormat: @"<%s %p - name=%@ entity=%@ columnName=%@ definition=%@ ", object_get_class_name(self), (void*)self, [self name], [[self entity] name], [self columnName], [self definition]]; dscr = [dscr stringByAppendingFormat: @"valueClassName=%@ valueType=%@ externalType=%@ allowsNull=%s isReadOnly=%s isDerived=%s isFlattened=%s>", [self valueClassName], [self valueType], [self externalType], ([self allowsNull] ? "YES" : "NO"), ([self isReadOnly] ? "YES" : "NO"), ([self isDerived] ? "YES" : "NO"), ([self isFlattened] ? "YES" : "NO")]; return dscr; } /* We override NSObjects default implementation as attributes cannot be copied */ - (id)copyWithZone:(NSZone *)zone { [self notImplemented: _cmd]; return nil; } - (EOEntity *)entity { if (_flags.isParentAnEOEntity) return _parent; else return nil; } - (NSString *)name { return _name; } - (NSString *)columnName { if (_columnName) return _columnName; return [_prototype columnName]; } - (NSString *)definition { NSString *definition = nil; // EOFLOGObjectFnStart(); // EOFLOGObjectLevel(@"gsdb",@"_definitionArray:%@",_definitionArray); definition = [_definitionArray valueForSQLExpression: nil]; // EOFLOGObjectLevel(@"gsdb",@"definition:%@",definition); // EOFLOGObjectFnStop(); return definition; } - (NSString *)readFormat { if (_readFormat) return _readFormat; return [_prototype readFormat]; } - (NSString *)writeFormat { if (_writeFormat) return _writeFormat; return [_prototype writeFormat]; } - (NSDictionary *)userInfo { return _userInfo; } - (NSString *)docComment { return _docComment; } - (int)scale { if (_scale) return _scale; if (_prototype) return [_prototype scale]; return 0; } - (unsigned)precision { if (_precision) return _precision; if (_prototype) return [_prototype precision]; return 0; } - (unsigned)width { if (_width) return _width; if (_prototype) return [_prototype width]; return 0; } - (id)parent { return _parent; } - (EOAttribute *)prototype { return _prototype; } - (NSString *)prototypeName { return [_prototype name]; } - (EOParameterDirection)parameterDirection { return _parameterDirection; } - (BOOL)allowsNull { if (_flags.allowsNull) return _flags.allowsNull; if (_prototype) return [_prototype allowsNull]; return NO; } - (BOOL)isKeyDefinedByPrototype:(NSString *)key { return NO; // TODO } - (EOStoredProcedure *)storedProcedure { if ([_parent isKindOfClass: [EOStoredProcedure class]]) return _parent; return nil; } - (BOOL)isReadOnly { //call isDerived if (_flags.isReadOnly) return _flags.isReadOnly; if (_prototype) return [_prototype isReadOnly]; return NO; } /** * Return NO when the attribute corresponds to one SQL column in its entity * associated table return YES otherwise. * An attribute with a definition such as * "anotherAttributeName * 2" is derived. * A Flattened attribute is also a derived attributes. **/ - (BOOL)isDerived { //Seems OK if(_definitionArray) return YES; return NO; } /** * Returns YES if the attribute is flattened, NO otherwise. * A flattened attribute is an attribute with a definition * using a relationship to another entity. * A Flattened attribute is also a derived attribute. **/ - (BOOL)isFlattened { BOOL isFlattened = NO; // Seems OK if(_definitionArray) isFlattened = [_definitionArray isFlattened]; return isFlattened; } /** *

Returns the name of the class values of this attribute * are represented by. The standard classes are NSNumber, * NSString, NSData and NSDate for the corresponding * [-adaptorValueType]. A model can define more specific * classes like NSDecimalNumber, NSCalendarDate and NSImage * or custom classes which implement a factory method * specified by [-valueFactoryMethodName] to create instances * with the data supplied by the data source.

*

If the valueClassName has not been set explicitly and the * reciever [-isFlattened], the valueClassName of the flattened * attribute is returned.

*

Otherwise, if the reciever has a prototype then the * valueClassName of the prototype is returned.

*

If all that fails, this method returns nil.

*

See also:[setValueClassName:]

*/ - (NSString *)valueClassName { if (_valueClassName) return _valueClassName; if ([self isFlattened]) return [[_definitionArray realAttribute] valueClassName]; return [_prototype valueClassName]; } /** *

Returns the adaptor specific name of externalType. This is * the name use during SQL generation.

*

If the externalType has not been set explicitly and the * reciever [-isFlattened], the valueClassName of the flattened * attribute is returned.

*

Otherwise, if the reciever has a prototype then the * externalType of the prototype is returned.

*

If all that fails, this method returns nil.

*/ - (NSString *)externalType { if (_externalType) return _externalType; if ([self isFlattened]) return [[_definitionArray realAttribute] externalType]; return [_prototype externalType]; } /** *

Returns a one character string identifiying the underlying * C type of an NSNumber [-valueType]. The legal values in GDL2 are:

* * @"c": char * @"C": unsigned char * @"s": short * @"S": unsigned short * @"i": int * @"I": unsigned int * @"l": long * @"L": unsigned long * @"u": long long * @"U": unsigned long long * @"f": float * @"d": double * *

If the valueType has not been set explicitly and the * reciever [-isFlattened], the valueClassName of the flattened * attribute is returned.

*

Otherwise, if the reciever has a prototype then the * valueType of the prototype is returned.

*

If all that fails, this method returns nil.

*/ - (NSString *)valueType { if (_valueType) return _valueType; else if([self isFlattened]) return [[_definitionArray realAttribute] valueType]; else return [_prototype valueType]; } @end @implementation EOAttribute (EOAttributeSQLExpression) /** * Returns the value to use in an EOSQLExpression. **/ - (NSString *) valueForSQLExpression: (EOSQLExpression *)sqlExpression { NSString *value=nil; // EOFLOGObjectLevel(@"gsdb",@"EOAttribute %p",self); NSEmitTODO(); //TODO if (_definitionArray) value = [_definitionArray valueForSQLExpression: sqlExpression]; else value = [self name]; return value; } @end @implementation EOAttribute (EOAttributeEditing) - (NSException *)validateName:(NSString *)name { NSArray *storedProcedures; const char *p, *s = [name cString]; int exc = 0; if ([_name isEqual:name]) return nil; if (!name || ![name length]) exc++; if (!exc) { p = s; while (*p) { if (!isalnum(*p) && *p != '@' && *p != '#' && *p != '_' && *p != '$') { exc++; break; } p++; } if (!exc && *s == '$') exc++; if (exc) return [NSException exceptionWithName: NSInvalidArgumentException reason: [NSString stringWithFormat:@"%@ -- %@ 0x%x: argument \"%@\" contains invalid char '%c'", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, name, *p] userInfo: nil]; if ([[self entity] _hasAttributeNamed:name]) exc++; else if ((storedProcedures = [[[self entity] model] storedProcedures])) { NSEnumerator *stEnum = [storedProcedures objectEnumerator]; EOStoredProcedure *st; while ((st = [stEnum nextObject])) { NSEnumerator *attrEnum; EOAttribute *attr; attrEnum = [[st arguments] objectEnumerator]; while ((attr = [attrEnum nextObject])) { if ([name isEqualToString: [attr name]]) { exc++; break; } } if (exc) break; } } } if (exc) { return [NSException exceptionWithName: NSInvalidArgumentException reason: [NSString stringWithFormat: @"%@ -- %@ 0x%x: \"%@\" already used in the model", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, name] userInfo: nil]; } return nil; } - (void)setName: (NSString *)name { if ([_name isEqual: name]==NO) { NSString *oldName = nil; [[self validateName: name] raise]; oldName = AUTORELEASE(RETAIN(_name)); [self willChange]; ASSIGNCOPY(_name, name); if (_flags.isParentAnEOEntity) { [_parent _setIsEdited]; } } } - (void)setPrototype: (EOAttribute *)prototype { [self willChange]; ASSIGN(_prototype, prototype); } - (void)setColumnName: (NSString *)columnName { //seems OK [self willChange]; ASSIGNCOPY(_columnName, columnName); DESTROY(_definitionArray); [_parent _setIsEdited]; [self _setOverrideForKeyEnum:1]; } - (void)_setDefinitionWithoutFlushingCaches: (NSString *)definition { EOExpressionArray *expressionArray=nil; [self willChange]; expressionArray = [_parent _parseDescription: definition isFormat: NO arguments: NULL]; expressionArray = [self _normalizeDefinition: expressionArray path: nil]; /* //TODO finish l un est code entity primaryKeyAttributes (code) ?? [self _removeFromEntityArray:code selector:setPrimaryKeyAttributes: */ ASSIGN(_definitionArray, expressionArray); } -(id)_normalizeDefinition: (EOExpressionArray*)definition path: (id)path { //TODO /* definition _isPropertyPath //NO count object atindex self _normalizeDefinition:ret path:NSArray() adddobject if attribute if isderived //NO ?? ret attr return nexexp */ return definition; } /** *

Sets the definition of a derived attribute.

*

An EOAttribute can either reference column from the entites * external representation or define a derived attribute such a * cacluclated value or a key path. The values to these attributes * are cached in memory.

*

To set the definition of an attribute, the attribute must * already be contained by its parent entity.

*

Setting the the definition clears the column name.

*/ - (void)setDefinition:(NSString *)definition { if(definition) { [self willChange]; [self _setDefinitionWithoutFlushingCaches: definition]; DESTROY(_columnName); [_parent _setIsEdited]; } } - (void)setReadOnly: (BOOL)yn { if(!yn && ([self isDerived] && ![self isFlattened])) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: cannot set to NO while the attribute is derived but not flattened.", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self]; [self willChange]; _flags.isReadOnly = yn; } - (void)setExternalType: (NSString *)type { //OK [self willChange]; ASSIGNCOPY(_externalType, type); [_parent _setIsEdited]; [self _setOverrideForKeyEnum: 0];//TODO } - (void)setValueType: (NSString *)type { //OK [self willChange]; ASSIGNCOPY(_valueType, type); if ([_valueType length]==1) _valueTypeCharacter = [_valueType characterAtIndex:0]; else _valueTypeCharacter = '\0'; [self _setOverrideForKeyEnum: 4];//TODO } - (void)setValueClassName: (NSString *)name { [self willChange]; ASSIGNCOPY(_valueClassName, name); _valueClass = NSClassFromString(_valueClassName); _flags.isAttributeValueInitialized = NO; [self _setOverrideForKeyEnum: 3];//TODO } - (void)setWidth: (unsigned)length { [self willChange]; _width = length; } - (void)setPrecision: (unsigned)precision { [self willChange]; _precision = precision; } - (void)setScale: (int)scale { [self willChange]; _scale = scale; } - (void)setAllowsNull: (BOOL)allowsNull { //OK [self willChange]; _flags.allowsNull = allowsNull; [self _setOverrideForKeyEnum: 15];//TODO } - (void)setWriteFormat: (NSString *)string { [self willChange]; ASSIGNCOPY(_writeFormat, string); } - (void)setReadFormat: (NSString *)string { [self willChange]; ASSIGNCOPY(_readFormat, string); } - (void)setParameterDirection: (EOParameterDirection)parameterDirection { [self willChange]; _parameterDirection = parameterDirection; } - (void)setUserInfo: (NSDictionary *)dictionary { //OK [self willChange]; ASSIGN(_userInfo, dictionary); [_parent _setIsEdited]; [self _setOverrideForKeyEnum: 10];//TODO } - (void)setInternalInfo: (NSDictionary *)dictionary { //OK [self willChange]; ASSIGN(_internalInfo, dictionary); [_parent _setIsEdited]; [self _setOverrideForKeyEnum: 10]; //TODO } - (void)setDocComment: (NSString *)docComment { //OK [self willChange]; ASSIGNCOPY(_docComment, docComment); [_parent _setIsEdited]; } @end @implementation EOAttribute (EOBeautifier) /*+ Make the name conform to the Next naming style NAME -> name, FIRST_NAME -> firstName +*/ - (void)beautifyName { NSArray *listItems; NSString *newString=[NSMutableString string]; int anz,i; EOFLOGObjectFnStartOrCond2(@"ModelingClasses", @"EOAttribute"); // Makes the receiver's name conform to a standard convention. Names that conform to this style are all lower-case except for the initial letter of each embedded word other than the first, which is upper case. Thus, "NAME" becomes "name", and "FIRST_NAME" becomes "firstName". if ((_name) && ([_name length]>0)) { listItems = [_name componentsSeparatedByString: @"_"]; newString = [newString stringByAppendingString: [[listItems objectAtIndex: 0] lowercaseString]]; anz = [listItems count]; for(i = 1; i < anz; i++) { newString = [newString stringByAppendingString: [[listItems objectAtIndex: i] capitalizedString]]; } //#warning add all components (attributes, ...) // Exception abfangen NS_DURING { [self setName: newString]; } NS_HANDLER { NSLog(@"%@ in Class: EOAttribute , Method: beautifyName >> error : %@", [localException name], [localException reason]); } NS_ENDHANDLER; } EOFLOGObjectFnStopOrCond2(@"ModelingClasses", @"EOAttribute"); } @end @implementation EOAttribute (EOCalendarDateSupport) - (NSTimeZone *)serverTimeZone { if (_serverTimeZone) return _serverTimeZone; return [_prototype serverTimeZone]; } @end @implementation EOAttribute (EOCalendarDateSupportEditing) - (void)setServerTimeZone: (NSTimeZone *)tz { [self willChange]; ASSIGN(_serverTimeZone, tz); } @end @implementation EOAttribute (EOAttributeValueCreation) /** * Returns an NSData or a custom-class value object * from the supplied set of bytes. * The Adaptor calls this method during value creation * when fetching objects from the database. * For efficiency, the returned value is NOT autoreleased. * * NB: The documentation of the reference implementation * mistakenly claims that it returns an NSString. **/ - (id)newValueForBytes: (const void *)bytes length: (int)length { NSData *value = nil; Class valueClass = [self _valueClass]; if (valueClass != Nil && valueClass != GDL2_NSDataClass) { switch (_argumentType) { case EOFactoryMethodArgumentIsNSData: { //For efficiency reasons, the returned value is NOT autoreleased ! value = [GDL2_alloc(NSData) initWithBytes: bytes length: length]; // If we have a value factiry method, call it to get the final value if(_valueFactoryMethod != NULL) { NSData* tmp = value; // valueFactoryMethod returns an autoreleased value value = [(id)valueClass performSelector: _valueFactoryMethod withObject: value]; if (value != tmp) { RETAIN(value); RELEASE(tmp); }; }; break; } case EOFactoryMethodArgumentIsBytes: { NSMethodSignature *aSignature = nil; NSInvocation *anInvocation = nil; // TODO: verify with WO NSAssert2(_valueFactoryMethod, @"No _valueFactoryMethod (valueFactoryMethodName=%@) in attribute %@", _valueFactoryMethodName,self); // First find signature for method aSignature = [valueClass methodSignatureForSelector: _valueFactoryMethod]; // Create the invocation object anInvocation = [NSInvocation invocationWithMethodSignature: aSignature]; // Put the selector [anInvocation setSelector: _valueFactoryMethod]; // The target is the custom value class [anInvocation setTarget: valueClass]; // arguments are buffer pointer and length [anInvocation setArgument: &bytes atIndex: 2]; [anInvocation setArgument: &length atIndex: 3]; // Let's invoke the method [anInvocation invoke]; // Get the returned value [anInvocation getReturnValue: &value]; //For efficiency reasons, the returned value is NOT autoreleased ! // valueFactoryMethod returns an autoreleased value RETAIN(value); break; } case EOFactoryMethodArgumentIsNSString: // TODO: verify with WO break; } } if(!value) { //For efficiency reasons, the returned value is NOT autoreleased ! value = [GDL2_alloc(NSData) initWithBytes: bytes length: length]; } return value; } /** * Returns a NSString or a custom-class value object * from the supplied set of bytes using encoding. * The Adaptor calls this method during value creation * when fetching objects from the database. * For efficiency, the returned value is NOT autoreleased. **/ - (id)newValueForBytes: (const void *)bytes length: (int)length encoding: (NSStringEncoding)encoding { NSString* value = nil; Class valueClass = [self _valueClass]; if (valueClass != Nil && valueClass != GDL2_NSStringClass) { switch (_argumentType) { case EOFactoryMethodArgumentIsNSString: { NSString *string = nil; string = [(GDL2_alloc(NSString)) initWithBytes: bytes length: length encoding: encoding]; // If we have a value factiry method, call it to get the final value if(_valueFactoryMethod != NULL) { value = [((id)valueClass) performSelector: _valueFactoryMethod withObject: string]; if ( value != string) { //For efficiency reasons, the returned value is NOT autoreleased ! RETAIN(value); RELEASE(string); }; } else { //For efficiency reasons, the returned value is NOT autoreleased ! value = string; }; break; } case EOFactoryMethodArgumentIsBytes: { NSMethodSignature *aSignature = nil; NSInvocation *anInvocation = nil; // TODO: verify with WO NSAssert2(_valueFactoryMethod, @"No _valueFactoryMethod (valueFactoryMethodName=%@) in attribute %@", _valueFactoryMethodName,self); // First find signature for method aSignature = [valueClass methodSignatureForSelector: _valueFactoryMethod]; // Create the invocation object anInvocation = [NSInvocation invocationWithMethodSignature: aSignature]; // Put the selector [anInvocation setSelector: _valueFactoryMethod]; // The target is the custom value class [anInvocation setTarget: valueClass]; // arguments are buffer pointer, length and encoding [anInvocation setArgument: &bytes atIndex: 2]; [anInvocation setArgument: &length atIndex: 3]; [anInvocation setArgument: &encoding atIndex: 4]; // Let's invoke the method [anInvocation invoke]; // Get the returned value [anInvocation getReturnValue: &value]; //For efficiency reasons, the returned value is NOT autoreleased ! // valueFactoryMethod returns an autoreleased value RETAIN(value); break; } case EOFactoryMethodArgumentIsNSData: // TODO: verify with WO break; } } if(!value) { //For efficiency reasons, the returned value is NOT autoreleased ! value = [(GDL2_alloc(NSString)) initWithBytes: bytes length: length encoding: encoding]; } return value; } /** * Returns an NSCalendarDate object * from the supplied time information. * The Adaptor calls this method during value creation * when fetching objects from the database. * For efficiency, the returned value is NOT autoreleased. * Milliseconds are dropped since they cannot be easily be stored in * NSCalendarDate. **/ - (NSCalendarDate *)newDateForYear: (int)year month: (unsigned)month day: (unsigned)day hour: (unsigned)hour minute: (unsigned)minute second: (unsigned)second millisecond: (unsigned)millisecond timezone: (NSTimeZone *)timezone zone: (NSZone *)zone { NSCalendarDate *date = nil; // FIXME: extend initializer to include Milliseconds //For efficiency reasons, the returned value is NOT autoreleased ! date = [(GDL2_allocWithZone(NSCalendarDate,zone)) initWithYear: year month: month day: day hour: hour minute: minute second: second timeZone: timezone]; return date; } /** *

Returns the name of the method to use for creating a custom class * value for this attribute.

* See Also: [-valueFactoryMethod], [-newValueForBytes:length:] */ - (NSString *)valueFactoryMethodName { return _valueFactoryMethodName; } /** *

Returns the selector of the method to use for creating a custom class * value for this attribute.

*

Default implementation returns selector for name returned by * [-valueFactoryMethodName] or NULL if no selector is found.

* * See Also: [-valueFactoryMethodName], [-newValueForBytes:length:] */ - (SEL)valueFactoryMethod { return _valueFactoryMethod; } /** * Depending on [-adaptorValueType] this method checks whether the value * is a NSNumber, NSString, NSData or NSDate instance respectively. * If not, it attempts to retrieve the -adaptorValueConversionMethod * which should be used to convert the value accordingly. If none * has been specified and the -adaptorValueType is EOAdaptorBytesType, * it tries to convert the value by invoking -archiveData. * The EONull instance is not converted. * Returns the converted value. * Note: This implementation currently raises if -adaptorValueType is of * an unknown type or if conversion is necessary but not possible. This * maybe contrary to the reference implementation but it seems like useful * behavior. If this is causing problems please submit a bug report. */ - (id)adaptorValueByConvertingAttributeValue: (id)value { EOAdaptorValueType adaptorValueType = [self adaptorValueType]; // No conversion for an EONull value if (value != GDL2_EONull) { BOOL convert = NO; // Find if we need a conversion switch (adaptorValueType) { case EOAdaptorNumberType: convert = [value isKindOfClass: GDL2_NSNumberClass] ? NO : YES; break; case EOAdaptorCharactersType: convert = [value isKindOfClass: GDL2_NSStringClass] ? NO : YES; break; case EOAdaptorBytesType: convert = [value isKindOfClass: GDL2_NSDataClass] ? NO : YES; break; case EOAdaptorDateType: convert = [value isKindOfClass: GDL2_NSDateClass] ? NO : YES; break; default: [NSException raise: NSInvalidArgumentException format: @"Illegal adaptorValueType: %d", adaptorValueType]; } // Do value need conversion ? if (convert) { SEL sel; sel = [self adaptorValueConversionMethod]; if (sel == 0) { if (adaptorValueType == EOAdaptorBytesType) { value = [value archiveData]; } else { /* This exception might not be conformant, but seems helpful. */ [NSException raise: NSInvalidArgumentException format: @"Value of class: %@ needs conversion " @"yet no conversion method specified. " @"Attribute is %@. adaptorValueType=%d", NSStringFromClass([value class]), self,adaptorValueType]; } } else { value = [value performSelector: sel]; } } }; return value; } /** *

Returns method name to use to convert value of a class * different than attribute adaptor value type.

* * See also: [-adaptorValueByConvertingAttributeValue:], * [-adaptorValueConversionMethod] */ - (NSString *)adaptorValueConversionMethodName { return _adaptorValueConversionMethodName; } /** *

Returns selector of the method to use to convert value of a class * different than attribute adaptor value type.

*

The default implementation returns the selector corresponding to * [-adaptorValueConversionMethodName] or NULL if there's not selector * for the method.

* * See also: [-adaptorValueByConvertingAttributeValue:], * [-adaptorValueConversionMethodName] */ - (SEL)adaptorValueConversionMethod { return _adaptorValueConversionMethod; } /** *

Returns an EOAdaptorValueType describing the adaptor * (i.e. database) type of data for this attribute.

* *

Returned value can be:

* * EOAdaptorBytesType * Raw bytes (default type) * EOAdaptorNumberType * Number value (attribute valueClass is kind of NSNumber) * EOAdaptorCharactersType * String value (attribute valueClass is kind of NSString) * EOAdaptorDateType * Date value (attribute valueClass is kind of NSDate) * */ - (EOAdaptorValueType)adaptorValueType { if (!_flags.isAttributeValueInitialized) { Class adaptorClasses[] = { GDL2_NSNumberClass, GDL2_NSStringClass, GDL2_NSDateClass }; EOAdaptorValueType values[] = { EOAdaptorNumberType, EOAdaptorCharactersType, EOAdaptorDateType }; Class valueClass = Nil; int i = 0; _adaptorValueType = EOAdaptorBytesType; for ( i = 0; i < 3 && !_flags.isAttributeValueInitialized; i++) { for ( valueClass = [self _valueClass]; valueClass != Nil; valueClass = GSObjCSuper(valueClass)) { if (valueClass == adaptorClasses[i]) { _adaptorValueType=values[i]; _flags.isAttributeValueInitialized = YES; break; } } } _flags.isAttributeValueInitialized = YES; }; return _adaptorValueType; } /** Returns the type of argument needed by the factoryMethod. Type can be: EOFactoryMethodArgumentIsNSData method need one parameter: a NSData EOFactoryMethodArgumentIsNSString method need one parameter: a NSString EOFactoryMethodArgumentIsBytes method need 2 parameters (for data type valueClass): a raw bytes buffer and its length or 3 parameters (for string type valueClass): a raw bytes buffer, its length and the encoding See also: -valueFactoryMethod, -setFactoryMethodArgumentType: **/ - (EOFactoryMethodArgumentType)factoryMethodArgumentType { return _argumentType; } @end @implementation EOAttribute (EOAttributeValueCreationEditing) /** Set the "factory method" name (the method to invoke to create custom class attribute value). This method must be a class method returning an autoreleased value of attribute valueClass. See also: -setFactoryMethodArgumentType: **/ - (void)setValueFactoryMethodName: (NSString *)factoryMethodName { [self willChange]; ASSIGNCOPY(_valueFactoryMethodName, factoryMethodName); _valueFactoryMethod = NSSelectorFromString(_valueFactoryMethodName); } /** *

Set method name to use to convert value of a class * different than attribute adaptor value type.

* * See also: [-adaptorValueByConvertingAttributeValue:], * [-adaptorValueConversionMethod], [-adaptorValueConversionMethodName] */ - (void)setAdaptorValueConversionMethodName: (NSString *)conversionMethodName { [self willChange]; ASSIGNCOPY(_adaptorValueConversionMethodName, conversionMethodName); _adaptorValueConversionMethod = NSSelectorFromString(_adaptorValueConversionMethodName); } /** Set the type of argument needed by the factoryMethod. Type can be: EOFactoryMethodArgumentIsNSData method need one parameter: a NSData EOFactoryMethodArgumentIsNSString method need one parameter: a NSString EOFactoryMethodArgumentIsBytes method need 2 parameters (for data type valueClass): a raw bytes buffer and its length or 3 parameters (for string type valueClass): a raw bytes buffer, its length and the encoding See also: -setValueFactoryMethodName:, -factoryMethodArgumentType **/ - (void)setFactoryMethodArgumentType: (EOFactoryMethodArgumentType)argumentType { [self willChange]; _argumentType = argumentType; } @end @implementation EOAttribute (EOAttributeValueMapping) /** Validates value pointed by valueP, may set changed validated value in valueP and return an validation exception if constraints validation fails. valueP must not be NULL. More details: 1. raise an exception if [self allowsNull] == NO but *valueP is nil or EONull except if attribute is a primaryKey attribute (reason of this process exception is currently unknown). 2. if valueClassName isn't set, return nil and leave *valueP unchanged 3. if it can't find the class by name, log message, return nil and leave *valueP unchanged 4. do the fancy type conversions as necessary (Pretty much the current handling we have) 5. THEN if width is not 0 call adaptorValueByConvertingAttributeValue: on the new value and the if returned value is NSString or NSData validate length with width and return a corresponding exception if it's longer than allowed. **/ - (NSException *)validateValue: (id*)valueP { NSException *exception=nil; EOFLOGObjectFnStart(); NSAssert(valueP, @"No value pointer"); NSDebugMLog(@"In EOAttribute validateValue: value (class=%@) = %@ attribute = %@", [*valueP class],*valueP,self); // First check if value is nil or EONull if (_isNilOrEONull(*valueP)) { // Check if this is not allowed if ([self allowsNull] == NO) { NSArray *pkAttributes = [[self entity] primaryKeyAttributes]; // "Primary key attributes are ignored when enforcing allowsNull // property for attributes. The values could be handled later // by automatic PK-generation later if ([pkAttributes indexOfObjectIdenticalTo: self] == NSNotFound) { exception = [NSException validationExceptionWithFormat: @"attribute '%@' of entity '%@' cannot be nil or EONull ", [self name],[[self entity] name]]; }; } } else // There's a value. { NSString* valueClassName=[self valueClassName]; // if there's no valueClassName, leave the value unchanged // and don't return an exception if (valueClassName) { Class valueClass=[self _valueClass]; // There's a className but no class ! if (!valueClass) { //Log this problem, leave the value unchanged // and don't return an exception NSLog(@"No valueClass for valueClassName '%@' in attribute %@", valueClassName,self); } else { unsigned int width = 0; IMP isKindOfClassIMP=[*valueP methodForSelector:@selector(isKindOfClass:)]; // If the value has not the good class we'll try to convert it if ((*isKindOfClassIMP)(*valueP,@selector(isKindOfClass:), valueClass) == NO) { // Is it a string ? if ((*isKindOfClassIMP)(*valueP,@selector(isKindOfClass:), GDL2_NSStringClass)) { if (valueClass == GDL2_NSNumberClass) { unichar valueTypeCharacter = [self _valueTypeCharacter]; switch(valueTypeCharacter) { case 'i': *valueP = [GDL2_alloc(NSNumber) initWithInt: [*valueP intValue]]; AUTORELEASE(*valueP); break; case 'I': *valueP = [GDL2_alloc(NSNumber) initWithUnsignedInt: [*valueP unsignedIntValue]]; AUTORELEASE(*valueP); break; case 'c': *valueP = [GDL2_alloc(NSNumber) initWithChar: [*valueP intValue]]; AUTORELEASE(*valueP); break; case 'C': *valueP = [GDL2_alloc(NSNumber) initWithUnsignedChar: [*valueP unsignedIntValue]]; AUTORELEASE(*valueP); break; case 's': *valueP = [GDL2_alloc(NSNumber) initWithShort: [*valueP shortValue]]; AUTORELEASE(*valueP); break; case 'S': *valueP = [GDL2_alloc(NSNumber) initWithUnsignedShort: [*valueP unsignedShortValue]]; AUTORELEASE(*valueP); break; case 'l': *valueP = [GDL2_alloc(NSNumber) initWithLong: [*valueP longValue]]; AUTORELEASE(*valueP); break; case 'L': *valueP = [GDL2_alloc(NSNumber) initWithUnsignedLong: [*valueP unsignedLongValue]]; AUTORELEASE(*valueP); break; case 'u': *valueP = [GDL2_alloc(NSNumber) initWithLongLong: [*valueP longLongValue]]; AUTORELEASE(*valueP); break; case 'U': *valueP = [GDL2_alloc(NSNumber) initWithUnsignedLongLong: [*valueP unsignedLongLongValue]]; AUTORELEASE(*valueP); break; case 'f': *valueP = [GDL2_alloc(NSNumber) initWithFloat: [*valueP floatValue]]; AUTORELEASE(*valueP); break; default: *valueP = [GDL2_alloc(NSNumber) initWithDouble: [*valueP doubleValue]]; AUTORELEASE(*valueP); break; }; } else if (valueClass == GDL2_NSDecimalNumberClass) { *valueP = [GDL2_alloc(NSDecimalNumber) initWithString: *valueP]; AUTORELEASE(*valueP); } else if (valueClass == GDL2_NSDataClass) { //TODO Verify here. *valueP = [*valueP dataUsingEncoding: [NSString defaultCStringEncoding]]; } else if (valueClass == GDL2_NSCalendarDateClass) { *valueP = AUTORELEASE([(GDL2_alloc(NSCalendarDate)) initWithString: *valueP]); } } }; // Now, test width if any width = [self width]; if (width>0) { // First convert value to adaptor value id testValue = [self adaptorValueByConvertingAttributeValue: *valueP]; if (testValue) { IMP testIsKindOfClassIMP=[testValue methodForSelector:@selector(isKindOfClass:)]; // We can test NSString and NSData type only if ((*testIsKindOfClassIMP)(testValue,@selector(isKindOfClass:), GDL2_NSStringClass) || (*testIsKindOfClassIMP)(testValue,@selector(isKindOfClass:), GDL2_NSDataClass)) { unsigned int testValueLength = [testValue length]; if (testValueLength > width) { exception = [NSException validationExceptionWithFormat: @"Value %@ for attribute '%@' is too large", testValue,[self name]]; }; }; }; }; } } } EOFLOGObjectFnStop(); return exception; } @end @implementation NSObject (EOCustomClassArchiving) + objectWithArchiveData: (NSData *)data { return [NSUnarchiver unarchiveObjectWithData:data]; } - (NSData *)archiveData { return [NSArchiver archivedDataWithRootObject:self]; } @end @implementation EOAttribute (EOAttributePrivate) - (void)setParent: (id)parent { //OK [self willChange]; _parent = parent; _flags.isParentAnEOEntity = [_parent isKindOfClass: [EOEntity class]];//?? } - (EOAttribute *)realAttribute { return _realAttribute; } - (NSMutableArray *)_definitionArray { return _definitionArray; } - (Class)_valueClass { if (_valueClass) return _valueClass; else if ([self isFlattened]) return [[_definitionArray realAttribute] _valueClass]; else return [_prototype _valueClass]; } /* * This method returns the valueType as a unichar character. * The value of the instance variable get set implicitly * if the valueType is set explicitly with a legal value. * Otherwise the effective valueType of reciever is used. * TODO: Once this has been set later implicit changes to the * valueType via flattend attrubutes or prototypes will not * be honored. Value validation can be a hot spot so this method * (or rather it's only use in validateValue:) should remain efficient. */ - (unichar)_valueTypeCharacter { unichar valueTypeCharacter = _valueTypeCharacter; if (valueTypeCharacter == '\0') { NSString* valueType = [self valueType]; if ([valueType length] == 1) valueTypeCharacter = [valueType characterAtIndex:0]; } return valueTypeCharacter; }; @end @implementation EOAttribute (EOAttributePrivate2) - (BOOL) _hasAnyOverrides { [self notImplemented: _cmd]; //TODO return NO; } - (void) _resetPrototype { [self notImplemented: _cmd]; //TODO } - (void) _updateFromPrototype { [self notImplemented: _cmd]; //TODO } - (void) _setOverrideForKeyEnum: (int)keyEnum { //[self notImplemented:_cmd]; //TODO } - (BOOL) _isKeyEnumOverriden: (int)param0 { [self notImplemented: _cmd]; //TODO return NO; } - (BOOL) _isKeyEnumDefinedByPrototype: (int)param0 { [self notImplemented: _cmd]; //TODO return NO; } @end gnustep-dl2-0.12.0/EOAccess/EOPropertyListEncoding.h0000644000175000017500000000276710645346232021160 0ustar ayersayers/* -*-objc-*- EOPropertyListEncoding.h Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOPropertyListEncoding_h__ #define __EOPropertyListEncoding_h__ #ifdef GNUSTEP #include #else #include #endif @class NSDictionary; @class NSMutableDictionary; @protocol EOPropertyListEncoding - (id)initWithPropertyList: (NSDictionary *)propertyList owner: (id)owner; - (void)awakeWithPropertyList: (NSDictionary *)propertyList; - (void)encodeIntoPropertyList: (NSMutableDictionary *)propertyList; @end #endif /* __EOPropertyListEncoding_h__ */ gnustep-dl2-0.12.0/EOAccess/EOModelGroup.m0000644000175000017500000002565310745373063017115 0ustar ayersayers/** EOModelGroup.m EOModelGroup Class Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: June 2000 $Revision: 25994 $ $Date: 2008-01-22 14:57:07 +0100 (Die, 22. Jän 2008) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EOModelGroup.m 25994 2008-01-22 13:57:07Z ayers $") #ifdef GNUSTEP #include #include #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #include #endif #include #include #include #include #include @implementation EOModelGroup NSString *EOModelAddedNotification = @"EOModelAddedNotification"; NSString *EOModelInvalidatedNotification = @"EOModelInvalidatedNotification"; static id classDelegate = nil; static int delegateDefaultModelGroup = 0; static EOModelGroup *defaultModelGroup = nil; static EOModelGroup *globalModelGroup = nil; + (EOModelGroup *)defaultGroup { EOModelGroup *modelGroup = nil; EOFLOGObjectFnStart(); NSDebugMLLog(@"gsdb", @"defaultModelGroup=%p",defaultModelGroup); if (defaultModelGroup) modelGroup = defaultModelGroup; else if (delegateDefaultModelGroup) modelGroup = [classDelegate defaultModelGroup]; else modelGroup = [EOModelGroup globalModelGroup]; if (!modelGroup) { NSLog(@"WARNING: No default Group"); } NSDebugMLLog(@"gsdb", @"modelGroup=%p",modelGroup); EOFLOGObjectFnStop(); return modelGroup; } + (void)setDefaultGroup: (EOModelGroup *)group { NSDebugMLLog(@"gsdb", @"group=%p defaultModelGroup=%p", group,defaultModelGroup); if (group != defaultModelGroup) { if (defaultModelGroup) DESTROY(defaultModelGroup); if (delegateDefaultModelGroup) group = [classDelegate defaultModelGroup]; ASSIGN(defaultModelGroup, group); } } + (EOModelGroup *)globalModelGroup { EOFLOGObjectFnStart(); if (globalModelGroup == nil) { NSMutableArray *bundles = [NSMutableArray arrayWithCapacity: 2]; NSBundle *bundle = nil; NSMutableArray *paths = nil; NSEnumerator *pathsEnum = nil; NSEnumerator *bundleEnum = nil; NSString *path = nil; id tmp; globalModelGroup = [EOModelGroup new]; NSDebugMLLog(@"gsdb", @"globalModelGroup=%p",globalModelGroup); [bundles addObjectsFromArray: [NSBundle allBundles]]; [bundles addObjectsFromArray: [NSBundle allFrameworks]]; bundleEnum = [bundles objectEnumerator]; while ((bundle = [bundleEnum nextObject])) { paths = (id)[NSMutableArray array]; tmp = [bundle pathsForResourcesOfType: @"eomodeld" inDirectory: nil]; [paths addObjectsFromArray: tmp]; tmp = [bundle pathsForResourcesOfType: @"eomodel" inDirectory: nil]; [paths addObjectsFromArray: tmp]; if (!paths) { NSLog(@"WARNING: paths for resource of type eomodeld" @" in bundle %@",bundle); } pathsEnum = [paths objectEnumerator]; while ((path = [pathsEnum nextObject])) { [globalModelGroup addModelWithFile: path]; } } } EOFLOGObjectFnStop(); return globalModelGroup; } /** returns a model group composed of all models in the resource directory of the mainBundle, and all bundles and frameworks loaded into the app. **/ + (void)setDelegate: (id)delegate { classDelegate = delegate; delegateDefaultModelGroup = [delegate respondsToSelector: @selector(defaultModelGroup)]; } + (id)delegate { return classDelegate; } - init { if ((self = [super init])) { NSDebugMLLog(@"gsdb", @"model group=%p",self); _modelsByName = [NSMutableDictionary new]; }; return self; } - (void)dealloc { DESTROY(_modelsByName); [super dealloc]; } - (NSArray *)models { return [_modelsByName allValues]; } - (NSArray *)modelNames { return [_modelsByName allKeys]; } - (EOModel *)modelNamed: (NSString *)name { return [_modelsByName objectForKey: name]; } - (EOModel *)modelWithPath: (NSString *)path { NSEnumerator *modelEnum; EOModel *model; modelEnum = [_modelsByName objectEnumerator]; while ((model = [modelEnum nextObject])) if ([[path stringByStandardizingPath] isEqual: [[model path] stringByStandardizingPath]] == YES) return model; return nil; } - (void)addModel: (EOModel *)model { //OK //call model entityNames NSString *modelName; EOFLOGObjectFnStart(); NSDebugMLLog(@"gsdb", @"model=%p", model); modelName = [model name]; [model setModelGroup: self]; NSDebugMLLog(@"gsdb", @"model=%p name=%@", model, modelName); if (!modelName) { [NSException raise: NSInvalidArgumentException format: [NSString stringWithFormat: @"The model name is emtpy"]]; } NSAssert1(modelName, @"No name for model %@", model); if ([_modelsByName objectForKey: modelName]) { [NSException raise: NSInvalidArgumentException format: [NSString stringWithFormat: @"The modelname '%@' already exists in modelGroup", modelName]]; } [_modelsByName setObject: model forKey: modelName]; NSDebugMLLog(@"gsdb", @"Notification for model:%p", model); [[NSNotificationCenter defaultCenter] postNotificationName: EOModelAddedNotification object: model]; EOFLOGObjectFnStop(); } - (EOModel *)addModelWithFile: (NSString *)path { EOModel *model; EOFLOGObjectFnStart(); model = [EOModel modelWithContentsOfFile: path]; NSDebugMLLog(@"gsdb", @"model=%p", model); if (model) [self addModel: model]; EOFLOGObjectFnStop(); return model; } - (void)removeModel: (EOModel *)model { [_modelsByName removeObjectForKey: [model name]]; [model setModelGroup: nil]; [[NSNotificationCenter defaultCenter] postNotificationName: EOModelInvalidatedNotification object: model]; } - (EOEntity *)entityNamed: (NSString *)entityName { NSEnumerator *modelEnum; EOModel *model; EOEntity *entity; modelEnum = [_modelsByName objectEnumerator]; while ((model = [modelEnum nextObject])) if ((entity = [model entityNamed: entityName])) return entity; return nil; } - (EOEntity *)entityForObject: (id)object { NSEnumerator *modelEnum; EOModel *model; EOEntity *entity; modelEnum = [_modelsByName objectEnumerator]; while ((model = [modelEnum nextObject])) if ((entity = [model entityForObject: object])) return entity; return nil; } - (NSArray *)availablePrototypesForAdaptorName: (NSString *)adaptorName { [self notImplemented: _cmd]; return nil; } - (EOAttribute *)prototypeAttributeForAttribute: (EOAttribute *)attribute { [self notImplemented: _cmd]; return nil; } - (void)loadAllModelObjects { NSEnumerator *modelEnum; EOModel *model; modelEnum = [_modelsByName objectEnumerator]; while ((model = [modelEnum nextObject])) [model loadAllModelObjects]; } - (id)delegate { return _delegate; } - (void)setDelegate: (id)delegate { EOFLOGObjectFnStartOrCond2(@"ModelingClasses", @"EOModelGroup"); ASSIGN(_delegate, delegate); _delegateRespondsTo.entityNamed = [_delegate respondsToSelector: @selector(modelGroup:entityNamed:)]; _delegateRespondsTo.failedToLookupClassNamed = [_delegate respondsToSelector: @selector(entity:failedToLookupClassNamed:)]; _delegateRespondsTo.classForObjectWithGlobalID = [_delegate respondsToSelector: @selector(entity:classForObjectWithGlobalID:)]; _delegateRespondsTo.subEntityForEntity = [_delegate respondsToSelector: @selector(subEntityForEntity:primaryKey:isFinal:)]; _delegateRespondsTo.relationshipForRow = [_delegate respondsToSelector: @selector(entity:relationshipForRow:relationship:)]; EOFLOGObjectFnStopOrCond2(@"ModelingClasses", @"EOModelGroup"); } - (EOFetchSpecification *)fetchSpecificationNamed: (NSString *)fetchSpecName entityNamed: (NSString *)entityName { EOFetchSpecification *newFetchSpecification = nil; EOEntity *anEntity; EOFLOGObjectFnStartOrCond2(@"ModelingClasses", @"EOModelGroup"); if (fetchSpecName && entityName && (anEntity = [self entityNamed: entityName])) { newFetchSpecification = [anEntity fetchSpecificationNamed: fetchSpecName]; } EOFLOGObjectFnStopOrCond2(@"ModelingClasses", @"EOModelGroup"); return newFetchSpecification; } - (EOStoredProcedure *)storedProcedureNamed: (NSString *)name { EOStoredProcedure *newStoredProcedure = nil; NSEnumerator *modelEnum; EOModel *model; EOFLOGObjectFnStartOrCond2(@"ModelingClasses", @"EOModelGroup"); modelEnum = [_modelsByName objectEnumerator]; while ((model = [modelEnum nextObject])) { if ((newStoredProcedure = [model storedProcedureNamed: name])) { EOFLOGObjectFnStopOrCond2(@"ModelingClasses", @"EOModelGroup"); return newStoredProcedure; } } EOFLOGObjectFnStopOrCond2(@"ModelingClasses", @"EOModelGroup"); return nil; } @end @implementation EOObjectStoreCoordinator (EOModelGroup) - (EOModelGroup *)modelGroup { //Seems OK EOModelGroup *modelGroup; NSDictionary *userInfo; EOFLOGObjectFnStart(); userInfo = [self userInfo]; modelGroup = [userInfo objectForKey: @"EOModelGroup"]; if (!modelGroup) { modelGroup = [EOModelGroup defaultGroup]; [self setModelGroup: modelGroup]; } EOFLOGObjectFnStop(); return modelGroup; } - (void)setModelGroup: (EOModelGroup *)modelGroup { NSMutableDictionary *userInfo; EOFLOGObjectFnStart(); userInfo = (NSMutableDictionary *)[self userInfo]; if (userInfo) [userInfo setObject: modelGroup forKey: @"EOModelGroup"]; else { userInfo = (id)[NSMutableDictionary dictionary]; [userInfo setObject: modelGroup forKey: @"EOModelGroup"]; [self setUserInfo: userInfo]; } EOFLOGObjectFnStop(); } @end gnustep-dl2-0.12.0/EOAccess/EOModelGroup.h0000644000175000017500000000730210645346232017074 0ustar ayersayers/* -*-objc-*- EOModelGroup.h Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOModelGroup_h__ #define __EOModelGroup_h__ #include #include @class NSArray; @class NSDictionary; @class NSMutableDictionary; @class NSString; @class EOModel; @class EOEntity; @class EORelationship; @class EOGlobalID; @class EOAttribute; @class EOStoredProcedure; @class EOFetchSpecification; @interface EOModelGroup : NSObject { NSMutableDictionary *_modelsByName; id _delegate; struct { unsigned int entityNamed:1; unsigned int relationshipForRow:1; unsigned int subEntityForEntity:1; unsigned int failedToLookupClassNamed:1; unsigned int classForObjectWithGlobalID:1; unsigned int _RESERVED:27; } _delegateRespondsTo; } + (EOModelGroup *)defaultGroup; + (void)setDefaultGroup: (EOModelGroup *)group; + (EOModelGroup *)globalModelGroup; + (void)setDelegate: (id)delegate; + (id)delegate; - (NSArray *)models; - (NSArray *)modelNames; - (EOModel *)modelNamed: (NSString *)name; - (EOModel *)modelWithPath: (NSString *)path; - (void)addModel: (EOModel *)model; - (EOModel *)addModelWithFile: (NSString *)path; - (void)removeModel: (EOModel *)model; - (EOEntity *)entityNamed: (NSString *)entityName; - (NSArray *)availablePrototypesForAdaptorName: (NSString *)adaptorName; - (EOAttribute *)prototypeAttributeForAttribute: (EOAttribute *)attribute; - (EOEntity *)entityForObject: (id)object; - (void)loadAllModelObjects; - (id)delegate; - (void)setDelegate: (id)delegate; - (EOFetchSpecification *)fetchSpecificationNamed: (NSString *)fetchSpecName entityNamed: (NSString *)entityName; - (EOStoredProcedure *)storedProcedureNamed: (NSString *)name; @end GDL2ACCESS_EXPORT NSString *EOModelAddedNotification; GDL2ACCESS_EXPORT NSString *EOModelInvalidatedNotification; @interface NSObject (EOModelGroupClassDelegation) - (EOModelGroup *)defaultModelGroup; @end @interface NSObject (EOModelGroupDelegation) - (EOModel *)modelGroup: (EOModelGroup *)group entityNamed: (NSString *)name; - (EORelationship *)entity: (EOEntity *)entity relationshipForRow: (NSDictionary *)row relationship: (EORelationship *)relationship; - (EOEntity *)subEntityForEntity: (EOEntity *)entity primaryKey: (NSDictionary *)primaryKey isFinal: (BOOL *)flag; - (Class)entity: (EOEntity *)entity failedToLookupClassNamed: (NSString *)className; - (Class)entity: (EOEntity *)entity classForObjectWithGlobalID: (EOGlobalID *)globalID; - (EOEntity *)relationship: (EORelationship *)relationship failedToLookupDestinationNamed: (NSString *)entityName; @end @interface EOObjectStoreCoordinator (EOModelGroupSupport) - (void)setModelGroup: (EOModelGroup *)group; - (EOModelGroup *)modelGroup; @end #endif gnustep-dl2-0.12.0/EOAccess/EOExpressionArray.m0000644000175000017500000003305010745373063020164 0ustar ayersayers/** EOExpressionArray.m EOExpressionArray Copyright (C) 1996-2002,2003,2004,2005 Free Software Foundation, Inc. Author: Ovidiu Predescu Date: September 1996 Author: Mirko Viviani Date: February 2000 $Revision: 25994 $ $Date: 2008-01-22 14:57:07 +0100 (Die, 22. Jän 2008) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EOExpressionArray.m 25994 2008-01-22 13:57:07Z ayers $") #include #ifdef GNUSTEP #include #include #include #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #include #include #endif #define GSI_ARRAY_TYPES GSUNION_OBJ #include #include #include #include #include static SEL eqSel; @interface EOExpressionArray (PrivateExceptions) - (void) _raiseRangeExceptionWithIndex:(unsigned) index from:(SEL)selector; @end @implementation EOExpressionArray + (void) initialize { eqSel = NSSelectorFromString(@"isEqual:"); } + (EOExpressionArray*)expressionArray { return [[self new] autorelease]; } - (void)dealloc { DESTROY(_realAttribute); //TODO mettere nei metodi GC // DESTROY(_definition); DESTROY(_prefix); DESTROY(_infix); DESTROY(_suffix); GSIArrayEmpty(_contents); NSZoneFree([self zone], _contents); [super dealloc]; } - (id) init { EOFLOGObjectFnStart(); self = [self initWithCapacity:0]; EOFLOGObjectFnStop(); return self; } /* designated initializer */ - (id) initWithCapacity:(unsigned)capacity { self = [super init]; _contents = NSZoneMalloc([self zone], sizeof(GSIArray_t)); _contents = GSIArrayInitWithZoneAndCapacity(_contents, [self zone], capacity); return self; } - (id) initWithObjects:(id *)objects count:(unsigned)count { int i; self = [self initWithCapacity:count]; for (i = 0; i < count; i++) GSIArrayAddItem(_contents, (GSIArrayItem)objects[i]); return self; } + (EOExpressionArray*)expressionArrayWithPrefix: (NSString *)prefix infix: (NSString *)infix suffix: (NSString *)suffix { return [[[self alloc]initWithPrefix: prefix infix: infix suffix: suffix] autorelease]; } - (id)initWithPrefix: (NSString *)prefix infix: (NSString *)infix suffix: (NSString *)suffix { EOFLOGObjectFnStart(); if ((self = [self init])) { ASSIGN(_prefix, prefix); ASSIGN(_infix, infix); ASSIGN(_suffix, suffix); } EOFLOGObjectFnStop(); return self; } - (BOOL)referencesObject: (id)anObject { return [self indexOfObject: anObject] != NSNotFound; } - (NSString *)expressionValueForContext: (id)ctx { if (ctx && [self count] && [[self objectAtIndex: 0] isKindOfClass: [EORelationship class]]) return [ctx expressionValueForAttributePath: self]; else { int i, count = [self count]; id result = [[NSMutableString new] autorelease]; SEL sel = @selector(appendString:); IMP imp = [result methodForSelector: sel]; if (_prefix) [result appendString:_prefix]; if (count) { (*imp)(result, sel, [[self objectAtIndex: 0] expressionValueForContext: ctx]); for (i = 1 ; i < count; i++) { if (_infix) (*imp)(result, sel, _infix); (*imp)(result, sel, [[self objectAtIndex: i] expressionValueForContext: ctx]); } } if(_suffix) [result appendString: _suffix]; return result; } } - (void)setPrefix: (NSString *)prefix { ASSIGN(_prefix, prefix); } - (void)setInfix: (NSString *)infix { ASSIGN(_infix, infix); } - (void)setSuffix: (NSString *)suffix { ASSIGN(_suffix, suffix); } - (NSString *)prefix { return _prefix; } - (NSString *)infix { return _infix; } - (NSString *)suffix { return _suffix; } - (NSString *)definition { // return _definition; return [self valueForSQLExpression: nil]; } - (BOOL)isFlattened { // return _flags.isFlattened; return ([self count] > 1); } - (EOAttribute *)realAttribute { return _realAttribute; } /* + (EOExpressionArray *)parseExpression:(NSString *)expression entity:(EOEntity *)entity replacePropertyReferences:(BOOL)replacePropertyReferences { EOExpressionArray *array = nil; const char *s = NULL; const char *start=NULL; id objectToken=nil; EOFLOGObjectFnStart(); NSDebugMLLog(@"gsdb",@"expression=%@",expression); NSDebugMLLog(@"gsdb",@"entity=%@",entity); array = [[EOExpressionArray new] autorelease]; s = [expression cString]; // ASSIGN(array->_definition, expression); array->_flags.isFlattened = NO; if([expression isNameOfARelationshipPath]) { NSArray *defArray; NSString *realAttributeName; int count, i; array->_flags.isFlattened = YES; defArray = [expression componentsSeparatedByString:@"."]; count = [defArray count]; for(i = 0; i < count - 1; i++) { id relationshipName = [defArray objectAtIndex:i]; id relationship=nil; relationship = [entity relationshipNamed:relationshipName]; if(!relationship) [NSException raise:NSInvalidArgumentException format:@"%@ -- %@ 0x%x: '%@' for entity '%@' is an invalid property", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, relationshipName, entity]; // if([relationship isToMany]) // [NSException raise:NSInvalidArgumentException format:@"%@ -- %@ 0x%x: '%@' for entity '%@' must be a to one relationship", //NSStringFromSelector(_cmd), //NSStringFromClass([self class]), //self, //relationshipName, //entity]; [array addObject:relationship]; entity = [relationship destinationEntity]; } realAttributeName = [defArray lastObject]; ASSIGN(array->_realAttribute, [entity attributeNamed:realAttributeName]); if(!array->_realAttribute) ASSIGN(array->_realAttribute, [entity relationshipNamed:realAttributeName]); if(!array->_realAttribute) [NSException raise:NSInvalidArgumentException format:@"%@ -- %@ 0x%x: '%@' for entity '%@' is an invalid property", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, realAttributeName, entity]; [array addObject:array->_realAttribute]; } else { //IN eoentity persedescr } NSDebugMLLog(@"gsdb",@"_prefix=%@",array->_prefix); NSDebugMLLog(@"gsdb",@"_infix=%@",array->_infix); NSDebugMLLog(@"gsdb",@"_suffix=%@",array->_suffix); // NSDebugMLLog(@"gsdb",@"_definition=%@",array->_definition); NSDebugMLLog(@"gsdb",@"_realAttribute=%@",array->_realAttribute); EOFLOGObjectFnStop(); return array; } */ - (BOOL)_isPropertyPath { /* int i=0; int count=0; count=[self count]; objectAtIndex:i if it's a string return NO */ //TODO return NO; } - (NSString *)valueForSQLExpression: (EOSQLExpression*)sqlExpression { //TODO verify NSMutableString *value = [NSMutableString string]; volatile int i; int count; NS_DURING //Just for debugging { count = [self count]; for(i = 0; i < count; i++) { id obj = [self objectAtIndex: i]; NSString *relValue; relValue = [obj valueForSQLExpression: sqlExpression]; if (i > 0) [value appendString: @"."]; [value appendString: relValue]; } } NS_HANDLER { NSLog(@"exception in EOExpressionArray valueForSQLExpression: self=%p class=%@ i=%d", self, [self class], i); NSLog(@"exception in EOExpressionArray valueForSQLExpression: self=%@ class=%@ i=%d", self, [self class], i); NSLog(@"exception=%@", localException); [localException raise]; } NS_ENDHANDLER; return value; } /* These are *this* subclasses responsibility */ - (unsigned) count { return GSIArrayCount(_contents); } - (id) objectAtIndex:(unsigned) index { if (index >= GSIArrayCount(_contents)) [self _raiseRangeExceptionWithIndex:index from:_cmd]; return GSIArrayItemAtIndex(_contents, index).obj; } - (void) addObject:(id)object { if (object == nil) { [NSException raise: NSInvalidArgumentException format: @"Attempt to add nil to an array"]; return; } GSIArrayAddItem(_contents, (GSIArrayItem)object); } - (void) replaceObjectAtIndex:(unsigned)index withObject:(id)object { if (object == nil) { [NSException raise: NSInvalidArgumentException format: @"Attempt to add nil to an array"]; return; } else if (index >= GSIArrayCount(_contents)) { [self _raiseRangeExceptionWithIndex:index from:_cmd]; return; } GSIArraySetItemAtIndex(_contents, (GSIArrayItem)object, index); } - (void) insertObject:(id)object atIndex:(unsigned)index { if (object == nil) { [NSException raise: NSInvalidArgumentException format: @"Attempt to add nil to an array"]; return; } else if (index >= GSIArrayCount(_contents)) { [self _raiseRangeExceptionWithIndex:index from:_cmd]; } GSIArrayInsertItem(_contents, (GSIArrayItem)object, index); } - (void) removeObjectAtIndex:(unsigned)index { if (index >= GSIArrayCount(_contents)) { [self _raiseRangeExceptionWithIndex:index from:_cmd]; } GSIArrayRemoveItemAtIndex(_contents, index); } - (void) removeAllObjects { GSIArrayRemoveAllItems(_contents); } /* might as well also implement because we can do it faster */ - (id) lastObject { return GSIArrayLastItem(_contents).obj; } - (id) firstObject { if (GSIArrayCount(_contents) == 0) return nil; return GSIArrayItemAtIndex(_contents, 0).obj; } /* not only make it faster but work around for old buggy implementations of * NSArray in gnustep with an extra release */ - (void) removeObject:(id)anObject { int index = GSIArrayCount(_contents); BOOL (*eq)(id,SEL,id) = (BOOL (*)(id, SEL, id))[anObject methodForSelector:eqSel]; /* iterate backwards, so that all objects equal to 'anObject' * can safely be removed from the array while iterating. */ while (index-- > 0) { if ((*eq)(anObject, eqSel, GSIArrayItemAtIndex(_contents, index).obj)) { GSIArrayRemoveItemAtIndex(_contents, index); } } } /* private methods. */ - (void) _raiseRangeExceptionWithIndex: (unsigned)index from: (SEL)sel { NSDictionary *info; NSException *exception; NSString *reason; unsigned count = GSIArrayCount(_contents); info = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithUnsignedInt: index], @"Index", [NSNumber numberWithUnsignedInt: count], @"Count", self, @"Array", nil, nil]; reason = [NSString stringWithFormat: @"Index %d is out of range %d (in '%@')", index, count, NSStringFromSelector(sel)]; exception = [NSException exceptionWithName: NSRangeException reason: reason userInfo: info]; [exception raise]; } @end /* EOExpressionArray */ @implementation NSObject (EOExpression) - (NSString*)expressionValueForContext: (id)ctx { if ([self respondsToSelector: @selector(stringValue)]) return [(id)self stringValue]; else return [self description]; } @end @implementation NSString (EOExpression) /* Avoid returning the description in case of NSString because if the string contains whitespaces it will be quoted. Particular adaptors have to override -formatValue:forAttribute: and they have to quote with the specific database character the returned string. */ - (NSString*)expressionValueForContext: (id)ctx { return self; } @end @implementation NSString (EOAttributeTypeCheck) - (BOOL)isNameOfARelationshipPath { const char *s = [self cString]; BOOL result = NO; if (isalnum(*s) || *s == '@' || *s == '_' || *s == '#') { for (++s; *s; s++) { if (!isalnum(*s) && *s != '@' && *s != '_' && *s != '#' && *s != '$' && *s != '.') return NO; if (*s == '.') result = YES; } } return result; } @end gnustep-dl2-0.12.0/EOAccess/EOAdaptorContext.m0000644000175000017500000001522410745373063017770 0ustar ayersayers/** EOAdaptorContext.m EOAdaptorContext Class Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 $Revision: 25994 $ $Date: 2008-01-22 14:57:07 +0100 (Die, 22. Jän 2008) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EOAdaptorContext.m 25994 2008-01-22 13:57:07Z ayers $") #ifdef GNUSTEP #include #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #include #endif #include #include #include #include #include #include "EOAdaptorPriv.h" NSString *EOAdaptorContextBeginTransactionNotification = @"EOAdaptorContextBeginTransactionNotofication"; NSString *EOAdaptorContextCommitTransactionNotification = @"EOAdaptorContextCommitTransactionNotofication"; NSString *EOAdaptorContextRollbackTransactionNotification = @"EOAdaptorContextRollbackTransactionNotofication"; @implementation EOAdaptorContext + (EOAdaptorContext *)adaptorContextWithAdaptor: (EOAdaptor *)adaptor { return [[[self alloc] initWithAdaptor: adaptor] autorelease]; } - (id) initWithAdaptor: (EOAdaptor *)adaptor { if ((self = [super init])) { [adaptor _registerAdaptorContext: self]; ASSIGN(_adaptor, adaptor); _channels = [NSMutableArray new]; _transactionNestingLevel = 0; [self setDebugEnabled: [[self class] debugEnabledDefault]]; } return self; } - (void)dealloc { [_adaptor _unregisterAdaptorContext: self]; DESTROY(_adaptor); DESTROY(_channels); [super dealloc]; } - (EOAdaptorChannel *)createAdaptorChannel { [self subclassResponsibility: _cmd]; return nil; } - (NSArray *)channels { SEL sel = @selector(nonretainedObjectValue); return [_channels resultsOfPerformingSelector: sel]; } - (BOOL)hasOpenChannels { int i, count = [_channels count]; for (i = 0; i < count; i++) if ([[[_channels objectAtIndex: i] nonretainedObjectValue] isOpen]) return YES; return NO; } - (BOOL)hasBusyChannels { int i, count = [_channels count]; for (i = 0; i < count; i++) if ([[[_channels objectAtIndex: i] nonretainedObjectValue] isFetchInProgress]) return YES; return NO; } - (void)setDelegate:delegate { _delegate = delegate; _delegateRespondsTo.shouldConnect = [delegate respondsToSelector:@selector(adaptorContextShouldConnect:)]; _delegateRespondsTo.shouldBegin = [delegate respondsToSelector:@selector(adaptorContextShouldBegin:)]; _delegateRespondsTo.didBegin = [delegate respondsToSelector:@selector(adaptorContextDidBegin:)]; _delegateRespondsTo.shouldCommit = [delegate respondsToSelector:@selector(adaptorContextShouldCommit:)]; _delegateRespondsTo.didCommit = [delegate respondsToSelector:@selector(adaptorContextDidCommit:)]; _delegateRespondsTo.shouldRollback = [delegate respondsToSelector:@selector(adaptorContextShouldRollback:)]; _delegateRespondsTo.didRollback = [delegate respondsToSelector:@selector(adaptorContextDidRollback:)]; } - (EOAdaptor *)adaptor { return _adaptor; } - delegate { return _delegate; } - (void)handleDroppedConnection { [self subclassResponsibility: _cmd]; } @end @implementation EOAdaptorContext (EOTransactions) - (void)beginTransaction { [self subclassResponsibility: _cmd]; } - (void)commitTransaction { [self subclassResponsibility: _cmd]; } - (void)rollbackTransaction { [self subclassResponsibility: _cmd]; } - (void)transactionDidBegin { // Increment the transaction scope _transactionNestingLevel++; [[NSNotificationCenter defaultCenter] postNotificationName: EOAdaptorContextBeginTransactionNotification object: self]; //the notification call dbcontext _beginTransaction } - (void)transactionDidCommit { EOFLOGObjectFnStart(); // Decrement the transaction scope _transactionNestingLevel--;//OK //OK [[NSNotificationCenter defaultCenter] postNotificationName: EOAdaptorContextCommitTransactionNotification object: self]; EOFLOGObjectFnStop(); } - (void)transactionDidRollback { // Decrement the transaction scope _transactionNestingLevel--; [[NSNotificationCenter defaultCenter] postNotificationName: EOAdaptorContextRollbackTransactionNotification object: self]; } - (BOOL)hasOpenTransaction { if (_transactionNestingLevel > 0) return YES; return NO; } - (BOOL)canNestTransactions { [self subclassResponsibility: _cmd]; return NO; } - (unsigned)transactionNestingLevel { return _transactionNestingLevel; } + (void)setDebugEnabledDefault: (BOOL)flag { NSString *yn = (flag ? @"YES" : @"NO"); [[NSUserDefaults standardUserDefaults] setObject: yn forKey: @"EOAdaptorDebugEnabled"]; } + (BOOL)debugEnabledDefault { //OK return [[NSUserDefaults standardUserDefaults] boolForKey: @"EOAdaptorDebugEnabled"]; } - (void)setDebugEnabled:(BOOL)debugEnabled { _debug = debugEnabled; } - (BOOL)isDebugEnabled { return _debug; } @end /* EOAdaptorContext (EOTransactions) */ @implementation EOAdaptorContext (EOAdaptorContextPrivate) //_registerAdaptorChannel: - (void)_channelDidInit: channel { [_channels addObject: [NSValue valueWithNonretainedObject: channel]]; [channel setDebugEnabled: [self isDebugEnabled]]; //call self delegate //call channel setDelegate: returned ? } - (void)_channelWillDealloc:channel { int i; for (i = [_channels count] - 1; i >= 0; i--) { if ([[_channels objectAtIndex: i] nonretainedObjectValue] == channel) { [_channels removeObjectAtIndex: i]; break; } } } @end gnustep-dl2-0.12.0/EOAccess/EODatabaseOperation.h0000644000175000017500000001400310645346232020400 0ustar ayersayers/* -*-objc-*- EODatabaseOperation.h Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EODatabaseOperation_h__ #define __EODatabaseOperation_h__ #ifdef GNUSTEP #include #else #include #endif @class NSArray; @class NSMutableArray; @class NSDictionary; @class NSMutableDictionary; @class NSException; @class NSString; @class EOStoredProcedure; @class EOEntity; @class EOQualifier; @class EOGlobalID; typedef enum { EOAdaptorUndefinedOperator = 0, EOAdaptorLockOperator, EOAdaptorInsertOperator, EOAdaptorUpdateOperator, EOAdaptorDeleteOperator, EOAdaptorStoredProcedureOperator } EOAdaptorOperator; /** EOAdaptorOperation represent an adaptor 'elementaty' operation. Instance objects are created by EODatabaseOperation **/ @interface EOAdaptorOperation : NSObject { EOAdaptorOperator _adaptorOperator; /** Database Adaptor **/ EOEntity *_entity; /** Main concerned entity **/ EOQualifier *_qualifier; /** qualifier **/ NSDictionary *_changedValues; /** dictionary of changed fields/values **/ NSArray *_attributes; EOStoredProcedure *_storedProcedure; /** Stored Procedure **/ NSException *_exception; } + (EOAdaptorOperation *)adaptorOperationWithEntity: (EOEntity *)entity; /** Init the instance with the main concerned entity **/ - (id)initWithEntity: (EOEntity *)entity; /** returns adaptor operator **/ - (EOAdaptorOperator)adaptorOperator; /** set adaptor operator **/ - (void)setAdaptorOperator: (EOAdaptorOperator)adaptorOperator; /** returns entity **/ - (EOEntity *)entity; /** returns qualifier **/ - (EOQualifier *)qualifier; /** set Qualifier **/ - (void)setQualifier: (EOQualifier *)qualifier; /** returns dictionary of changed values **/ - (NSDictionary *)changedValues; /** set dictionary of changed values **/ - (void)setChangedValues: (NSDictionary *)changedValues; - (NSArray *)attributes; - (void)setAttributes: (NSArray *)attributes; - (EOStoredProcedure *)storedProcedure; - (void)setStoredProcedure: (EOStoredProcedure *)storedProcedure; - (NSException *)exception; - (void)setException: (NSException *)exception; /** compare 2 adaptor operations **/ - (NSComparisonResult)compareAdaptorOperation: (EOAdaptorOperation *)adaptorOp; @end typedef enum { EODatabaseNothingOperator = 0, EODatabaseInsertOperator, EODatabaseUpdateOperator, EODatabaseDeleteOperator } EODatabaseOperator; /** EODatabaseOperation represent a database high level operation on an object (record) It creates EOAdaptorOperations. You generally don't need to create such objects by yourself. They are created by EOEditingContext **/ @interface EODatabaseOperation : NSObject { EODatabaseOperator _databaseOperator; //** Database Operator **/ NSMutableDictionary *_newRow; //** New Row (new state of the object) **/ EOGlobalID *_globalID; /** global ID of the object **/ EOEntity *_entity; /** entity **/ NSMutableArray *_adaptorOps; /** EOAdaptorOperations generated to perfor this DatabaseOperation **/ id _object; /** object (record) **/ NSDictionary *_dbSnapshot; /** The last known database values for the object (i.e. values from last fetch or last commited operation) **/ NSMutableDictionary *_toManySnapshots; /** **/ } + (EODatabaseOperation *)databaseOperationWithGlobalID: (EOGlobalID *)globalID object: (id)object entity: (EOEntity *)entity; - (id)initWithGlobalID: (EOGlobalID *)globalID object: (id)object entity: (EOEntity *)entity; /** Returns the database snapshot for the object. The snapshot contains the last known database values for the object. If the object has just been inserted (i.e. not yet in database), the returned dictionary is empty **/ - (NSDictionary *)dbSnapshot; /** sets the snapshot for the object (should be empty if the object has just been inserted into an EOEditingContext **/ - (void)setDBSnapshot: (NSDictionary *)dbSnapshot; /** Returns a dictionary with (new) values (properties+primary keys...) of the object. The newRow dictionary is created when creating the database operation (in EODatabaseChannel -databaseOperationForObject: for exemple). Values come from object state in database and overrides by changes made on the object **/ - (NSMutableDictionary *)newRow; - (void)setNewRow: (NSMutableDictionary *)newRow; - (EOGlobalID *)globalID; - (id)object; - (EOEntity *)entity; - (EODatabaseOperator)databaseOperator; - (void)setDatabaseOperator: (EODatabaseOperator)dbOpe; - (NSDictionary *)rowDiffs; - (NSDictionary *)rowDiffsForAttributes: (NSArray *)attributes; - (NSDictionary *)primaryKeyDiffs; /** returns array of EOAdaptorOperations to perform **/ - (NSArray *)adaptorOperations; /** adds an Adaptor Operation Raises an exception if adaptorOperation is nil **/ - (void)addAdaptorOperation: (EOAdaptorOperation *)adaptorOperation; /** removes an Adaptor Operation **/ - (void)removeAdaptorOperation: (EOAdaptorOperation *)adaptorOperation; - (void)recordToManySnapshot: (NSArray *)gids relationshipName: (NSString *)name; - (NSDictionary *)toManySnapshots; @end #endif /* __EODatabaseOperation_h__ */ gnustep-dl2-0.12.0/EOAccess/EOSchemaSynchronization.m0000644000175000017500000001366710645346232021361 0ustar ayersayers/* -*-objc-*- EOSchemaSynchronization.m Copyright (C) 2007 Free Software Foundation, Inc. Date: July 2007 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "EOSchemaSynchronization.h" NSString *EOSchemaSynchronizationForeignKeyConstraintsKey = @"EOSchemaSynchronizationForeignKeyConstraintsKey"; NSString *EOSchemaSynchronizationPrimaryKeyConstraintsKey = @"EOSchemaSynchronizationPrimaryKeyConstraintsKey"; NSString *EOSchemaSynchronizationPrimaryKeySupportKey = @"EOSchemaSynchronizationPrimaryKeySupportKey"; NSString *EOAllowsNullKey = @"allowsNull"; NSString *EOColumnNameKey = @"columnName"; NSString *EOExternalNameKey = @"externalName"; NSString *EOExternalTypeKey = @"externalType"; NSString *EONameKey = @"name"; NSString *EOPrecisionKey = @"precision"; NSString *EORelationshipsKey = @"relationships"; NSString *EOScaleKey = @"scale"; NSString *EOWidthKey = @"width"; @implementation EOAdaptor (EOSchemaSynchronization) - (NSDictionary *)objectStoreChangesFromAttribute:(EOAttribute *)schemaAttribute toAttribute:(EOAttribute *)modelAttribute { return nil; } @end @implementation EOAdaptorChannel (EOSchemaSynchronization) - (void)beginSchemaSynchronization { } - (void)endSchemaSynchronization { } @end @implementation EOSQLExpression (EOSchemaSynchronization) + (BOOL)isCaseSensitive { return NO; } + (BOOL)isColumnType:(id )columnType1 equivalentToColumnType:(id )columnType2 options:(NSDictionary *)options { return NO; } + (NSArray *)logicalErrorsInChangeDictionary:(NSDictionary *)changes forModel:(EOModel *)model options:(NSDictionary *)options { return nil; } + (NSString *)phraseCastingColumnNamed:(NSString *)columnName fromType:(id )type toType:(id )castType options:(NSDictionary *)options { return nil; } + (id)schemaSynchronizationDelegate { return nil; } + (void)setSchemaSynchronizationDelegate:(id)delegate { } + (NSArray *)statementsToCopyTableNamed:(NSString *)tableName intoTableForEntityGroup:(NSArray *)entityGroup withChangeDictionary:(NSDictionary *)changes options:(NSDictionary *)options { return nil; } + (NSArray *)statementsToModifyColumnNamed:(NSString *)columnName inTableNamed:(NSString *)tableName toNullRule:(BOOL)allowsNull options:(NSDictionary *)options { return nil; } + (NSArray *)statementsToConvertColumnNamed:(NSString *)columnName inTableNamed:(NSString *)tableName fromType:(id )type toType:(id )newType options:(NSDictionary *)options { return nil; } + (NSArray *)statementsToDeleteColumnNamed:(NSString *)columnName inTableNamed:(NSString *)tableName options:(NSDictionary *)options { return nil; } + (NSArray *)statementsToInsertColumnForAttribute:(EOAttribute *)attribute options:(NSDictionary *)options { return nil; } + (NSArray *)statementsToRenameColumnNamed:(NSString *)columnName inTableNamed:(NSString *)tableName newName:(NSString *)newName options:(NSDictionary *)options { return nil; } + (NSArray *)statementsToDropForeignKeyConstraintsOnEntityGroups:(NSArray *)entityGroups withChangeDictionary:(NSDictionary *)changes options:(NSDictionary *)options { return nil; } + (NSArray *)statementsToDropPrimaryKeyConstraintsOnEntityGroups:(NSArray *)entityGroups withChangeDictionary:(NSDictionary *)changes options:(NSDictionary *)options { return nil; } + (NSArray *)statementsToDropPrimaryKeySupportForEntityGroups:(NSArray *)entityGroups withChangeDictionary:(NSDictionary *)changes options:(NSDictionary *)options { return nil; } + (NSArray *)statementsToImplementForeignKeyConstraintsOnEntityGroups:(NSArray *)entityGroups withChangeDictionary:(NSDictionary *)changes options:(NSDictionary *)options { return nil; } + (NSArray *)statementsToImplementPrimaryKeyConstraintsOnEntityGroups:(NSArray *)entityGroups withChangeDictionary:(NSDictionary *)changes options:(NSDictionary *)options { return nil; } + (NSArray *)statementsToImplementPrimaryKeySupportForEntityGroups:(NSArray *)entityGroups withChangeDictionary:(NSDictionary *)changes options:(NSDictionary *)options { return nil; } + (NSArray *)statementsToRenameTableNamed:(NSString *)tableName newName:(NSString *)newName options:(NSDictionary *)options { return nil; } + (NSArray *)statementsToUpdateObjectStoreForModel:(EOModel *)model withChangeDictionary:(NSDictionary *)changes options:(NSDictionary *)options { return nil; } + (NSArray *)statementsToUpdateObjectStoreForEntityGroups:(NSArray *)entityGroups withChangeDictionary:(NSDictionary *)changes options:(NSDictionary *)options { return nil; } + (BOOL)supportsDirectColumnNullRuleModification { return NO; } + (BOOL)supportsDirectColumnCoercion { return NO; } + (BOOL)supportsDirectColumnDeletion { return NO; } + (BOOL)supportsDirectColumnInsertion { return NO; } + (BOOL)supportsDirectColumnRenaming { return NO; } + (BOOL)supportsSchemaSynchronization { return NO; } @end gnustep-dl2-0.12.0/EOAccess/EOPrivate.h0000644000175000017500000000343610645346232016435 0ustar ayersayers/* -*-objc-*- EOPrivat.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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOAccess_EOPrivat_h__ #define __EOAccess_EOPrivat_h__ #include "EODefines.h" #include "../EOControl/EOPrivate.h" @class EODatabaseContext; // ==== Classes ==== GDL2ACCESS_EXPORT Class GDL2_EODatabaseContextClass; GDL2ACCESS_EXPORT Class GDL2_EOAttributeClass; // ==== IMPs ==== GDL2ACCESS_EXPORT IMP GDL2_EODatabaseContext_snapshotForGlobalIDIMP; GDL2ACCESS_EXPORT IMP GDL2_EODatabaseContext__globalIDForObjectIMP; // ==== Init Method ==== GDL2ACCESS_EXPORT void GDL2_EOAccessPrivateInit(); // ==== EODatabaseContext ==== GDL2ACCESS_EXPORT NSDictionary* EODatabaseContext_snapshotForGlobalIDWithImpPtr(EODatabaseContext* dbContext,IMP* impPtr,EOGlobalID* gid); GDL2ACCESS_EXPORT EOGlobalID* EODatabaseContext_globalIDForObjectWithImpPtr(EODatabaseContext* dbContext,IMP* impPtr,id object); #endif /* __EOAccess_EOPrivat_h__ */ gnustep-dl2-0.12.0/EOAccess/EOAdaptor.m0000644000175000017500000007361710767323154016435 0ustar ayersayers/** EOAdaptor.m EOAdaptor Class Copyright (C) 1996-2001,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Ovidiu Predescu Date: October 1996 Author: Mirko Viviani Date: February 2000 $Revision: 26323 $ $Date: 2008-03-16 23:59:56 +0100 (Son, 16. Mär 2008) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EOAdaptor.m 26323 2008-03-16 22:59:56Z ratmice $") #if HAVE_LIBC_H # include #else #ifndef __WIN32__ # include #endif /* !__WIN32__ */ #endif #ifdef GNUSTEP #include #include #include #include #include #include #include #include #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #include #endif #include #include #include #include "EOAccess/EOAdaptor.h" #include "EOAccess/EOAdaptorContext.h" #include "EOAccess/EOAdaptorChannel.h" #include "EOAccess/EOAttribute.h" #include "EOAccess/EOEntity.h" #include "EOAccess/EOModel.h" #include "EOAccess/EOSQLExpression.h" #include "EOAdaptorPriv.h" NSString *EOGeneralAdaptorException = @"EOGeneralAdaptorException"; NSString *EOAdministrativeConnectionDictionaryNeededNotification = @"EOAdministrativeConnectionDictionaryNeededNotification"; NSString *EOAdaptorKey = @"EOAdaptorKey"; NSString *EOModelKey = @"EOModelKey"; NSString *EOConnectionDictionaryKey = @"EOConnectionDictionaryKey"; NSString *EOAdministrativeConnectionDictionaryKey = @"EOAdministrativeConnectionDictionaryKey"; /* This mapping should be kept in sync with NSStringEncoding in NSString.h. */ static struct { NSString *name; NSStringEncoding encoding; } encodingMap[] = { { @"NSASCIIStringEncoding", NSASCIIStringEncoding }, { @"NSNEXTSTEPStringEncoding", NSNEXTSTEPStringEncoding }, { @"NSJapaneseEUCStringEncoding", NSJapaneseEUCStringEncoding }, { @"NSUTF8StringEncoding", NSUTF8StringEncoding }, { @"NSISOLatin1StringEncoding", NSISOLatin1StringEncoding }, { @"NSSymbolStringEncoding", NSSymbolStringEncoding }, { @"NSNonLossyASCIIStringEncoding", NSNonLossyASCIIStringEncoding }, { @"NSShiftJISStringEncoding", NSShiftJISStringEncoding }, { @"NSISOLatin2StringEncoding", NSISOLatin2StringEncoding }, { @"NSUnicodeStringEncoding", NSUnicodeStringEncoding }, { @"NSWindowsCP1251StringEncoding", NSWindowsCP1251StringEncoding }, { @"NSWindowsCP1252StringEncoding", NSWindowsCP1252StringEncoding }, { @"NSWindowsCP1253StringEncoding", NSWindowsCP1253StringEncoding }, { @"NSWindowsCP1254StringEncoding", NSWindowsCP1254StringEncoding }, { @"NSWindowsCP1250StringEncoding", NSWindowsCP1250StringEncoding }, { @"NSISO2022JPStringEncoding", NSISO2022JPStringEncoding }, { @"NSMacOSRomanStringEncoding", NSMacOSRomanStringEncoding }, #if defined(GNUSTEP_BASE_LIBRARY) || OS_API_VERSION(GS_API_NONE,MAC_OS_X_VERSION_10_5) { @"NSProprietaryStringEncoding", NSProprietaryStringEncoding }, #endif { @"NSKOI8RStringEncoding", NSKOI8RStringEncoding }, { @"NSISOLatin3StringEncoding", NSISOLatin3StringEncoding }, { @"NSISOLatin4StringEncoding", NSISOLatin4StringEncoding }, { @"NSISOCyrillicStringEncoding", NSISOCyrillicStringEncoding }, { @"NSISOArabicStringEncoding", NSISOArabicStringEncoding }, { @"NSISOGreekStringEncoding", NSISOGreekStringEncoding }, { @"NSISOHebrewStringEncoding", NSISOHebrewStringEncoding }, { @"NSISOLatin5StringEncoding", NSISOLatin5StringEncoding }, { @"NSISOLatin6StringEncoding", NSISOLatin6StringEncoding }, { @"NSISOThaiStringEncoding", NSISOThaiStringEncoding }, { @"NSISOLatin7StringEncoding", NSISOLatin7StringEncoding }, { @"NSISOLatin8StringEncoding", NSISOLatin8StringEncoding }, { @"NSISOLatin9StringEncoding", NSISOLatin9StringEncoding }, { @"NSGB2312StringEncoding", NSGB2312StringEncoding }, { @"NSUTF7StringEncoding", NSUTF7StringEncoding }, { @"NSGSM0338StringEncoding", NSGSM0338StringEncoding }, { @"NSBIG5StringEncoding", NSBIG5StringEncoding }, { @"NSKoreanEUCStringEncoding", NSKoreanEUCStringEncoding }, { nil, 0 } }; @implementation EOAdaptor + (id)adaptorWithModel: (EOModel *)model { //OK /* Check first to see if the adaptor class exists in the running program by testing the existence of [_model adaptorClassName]. */ EOAdaptor *adaptor = nil; if(!model) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: no model specified", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self]; else { NSString *adaptorName = [model adaptorName]; if (!adaptorName) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: no adaptor name in model named %@", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, [model name]]; else { NSString *className; Class adaptorClass; className = [adaptorName stringByAppendingString: @"Adaptor"]; adaptorClass = NSClassFromString(className); if(adaptorClass) adaptor = AUTORELEASE([[adaptorClass alloc] initWithName: adaptorName]); else adaptor = [self adaptorWithName: adaptorName]; [adaptor setModel: model]; [adaptor setConnectionDictionary: [model connectionDictionary]]; } } return adaptor; } + (id) adaptorWithName: (NSString *)name { //OK NSBundle *bundle = [NSBundle mainBundle]; NSString *adaptorBundlePath; NSArray *paths; Class adaptorClass; NSString *adaptorClassName; unsigned i, count; /* Check error */ if ([name length] == 0) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: adaptor name can't be nil", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self]; // append EOAdaptor if ([name hasSuffix: @"EOAdaptor"] == NO) name = [name stringByAppendingString: @"EOAdaptor"]; /* Look in application bundle */ adaptorBundlePath = [bundle pathForResource: name ofType: @"framework"]; // should be NSString *path=[NSBundle pathForLibraryResource:libraryResource type:@"framework" directory:@"Frameworks"]; ? /* Look in standard paths */ if (!adaptorBundlePath) { SEL sel = @selector(stringByAppendingPathComponent:); /* The path of where to search for the adaptor files. */ paths = NSSearchPathForDirectoriesInDomains(NSAllLibrariesDirectory, NSAllDomainsMask, NO); paths = [paths resultsOfPerformingSelector: sel withObject: @"Frameworks"]; /* Loop through the paths and check each one */ for(i = 0, count = [paths count]; i < count; i++) { bundle = [NSBundle bundleWithPath: [paths objectAtIndex: i]]; adaptorBundlePath = [bundle pathForResource: name ofType: @"framework"]; if(adaptorBundlePath && [adaptorBundlePath length]) break; } } /* Make adaptor bundle */ if(adaptorBundlePath) bundle = [NSBundle bundleWithPath: adaptorBundlePath]; else bundle = nil; /* Check bundle */ if (!bundle) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: the adaptor bundle '%@' does not exist", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, name]; /* Get the adaptor bundle "infoDictionary", and pricipal class, ie. the adaptor class. Other info about the adaptor should be put in the bundle's "Info.plist" file (property list format - see NSBundle class documentation for details about reserved keys in this dictionary property list containing one entry whose key is adaptorClassName. It identifies the actual adaptor class from the bundle. */ if(![bundle isLoaded]) EOFLOGClassLevelArgs(@"gsdb", @"Loaded %@? %@", bundle, ([bundle load]? @"YES":@"NO")); adaptorClassName = [[bundle infoDictionary] objectForKey: @"EOAdaptorClassName"]; EOFLOGClassLevelArgs(@"gsdb", @"adaptorClassName is %@", adaptorClassName); adaptorClass = NSClassFromString(adaptorClassName); if (adaptorClass == Nil) { adaptorClass = [bundle principalClass]; } if(adaptorClass == Nil) { [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: value of EOAdaptorClassName '%@' is not a valid class and bundle does not contain a principal class", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, name]; } if ([adaptorClass isSubclassOfClass: [self class]] == NO) { [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: principal class is not a subclass of EOAdaptor:%@", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, NSStringFromClass([adaptorClass class])]; } return AUTORELEASE([[adaptorClass alloc] initWithName: name]); } + (void)setExpressionClassName: (NSString *)sqlExpressionClassName adaptorClassName: (NSString *)adaptorClassName { // TODO [self notImplemented: _cmd]; } + (EOLoginPanel *)sharedLoginPanelInstance { static NSMutableDictionary *panelDict = nil; NSString *name; EOLoginPanel *panel = nil; if ([self isMemberOfClass: [EOAdaptor class]] == NO) { if (panelDict == nil) { panelDict = [NSMutableDictionary new]; } name = NSStringFromClass(self); panel = [panelDict objectForKey: name]; if (panel == nil && NSClassFromString(@"NSApplication") != nil) { NSBundle *adaptorFramework; NSBundle *loginBundle; NSString *path; Class loginClass; adaptorFramework = [NSBundle bundleForClass: self]; path = [adaptorFramework pathForResource: @"LoginPanel" ofType: @"bundle"]; loginBundle = [NSBundle bundleWithPath: path]; loginClass = [loginBundle principalClass]; panel = [loginClass new]; if (panel != nil) { [panelDict setObject: panel forKey: name]; } } } return panel; } /** * Returns an array of EOAdaptor frameworks found in the standard * framework locations. If an adaptor is found in multiple locations * the name is listed only once. An adaptor framework is recognized * the the "EOAdaptor.framework" suffix. The framework name without * this suffix is the name returned in the array. */ + (NSArray *)availableAdaptorNames { NSArray *pathArray = NSStandardLibraryPaths(); NSEnumerator *pathEnum = [pathArray objectEnumerator]; NSString *searchPath; NSFileManager *defaultManager = [NSFileManager defaultManager]; NSArray *fileNames; NSEnumerator *filesEnum; NSString *fileName; NSMutableSet *adaptorNames = [NSMutableSet set]; NSString *adaptorSuffix = @"EOAdaptor.framework"; EOFLOGObjectFnStartOrCond2(@"AdaptorLevel", @"EOAdaptor"); while ((searchPath = [pathEnum nextObject])) { searchPath = [searchPath stringByAppendingPathComponent: @"Frameworks"]; fileNames = [defaultManager directoryContentsAtPath: searchPath]; filesEnum = [fileNames objectEnumerator]; NSDebugMLLog(@"EOAdaptor", @"path = %@", searchPath); while ((fileName = [filesEnum nextObject])) { NSDebugMLLog(@"EOAdaptor", @"fileName = %@", fileName); if ([fileName hasSuffix: adaptorSuffix]) { fileName = [fileName stringByDeletingSuffix: adaptorSuffix]; [adaptorNames addObject: fileName]; } } } EOFLOGObjectFnStopOrCond2(@"AdaptorLevel", @"EOAdaptor"); return [adaptorNames allObjects]; } - (void)_performAdministativeStatementsForSelector: (SEL)sel connectionDictionary: (NSDictionary *)connDict administrativeConnectionDictionary: (NSDictionary *)admConnDict { if (admConnDict == nil) { admConnDict = [[[self class] sharedLoginPanelInstance] administrativeConnectionDictionaryForAdaptor: self]; } if (connDict == nil) { connDict = [self connectionDictionary]; } if (admConnDict != nil) { EOAdaptor *admAdaptor; EOAdaptorContext *admContext; EOAdaptorChannel *admChannel; NSArray *stmts; unsigned i; stmts = [(id)[self expressionClass] performSelector: sel withObject: connDict withObject: admConnDict]; /*TODO: check if we need a model. */ admAdaptor = [EOAdaptor adaptorWithName: [self name]]; [admAdaptor setConnectionDictionary: admConnDict]; admContext = [admAdaptor createAdaptorContext]; admChannel = [admContext createAdaptorChannel]; NS_DURING { unsigned stmtsCount=0; [admChannel openChannel]; stmtsCount=[stmts count]; for (i = 0; i < stmtsCount; i++) { [admChannel evaluateExpression: [stmts objectAtIndex: i]]; } [admChannel closeChannel]; } NS_HANDLER { if ([admChannel isOpen]) { [admChannel closeChannel]; } [localException raise]; } NS_ENDHANDLER; } } - (NSArray *)prototypeAttributes { NSBundle *bundle; NSString *path; NSString *modelName; EOModel *model; NSMutableArray *attributes = nil; EOFLOGObjectFnStart(); bundle = [NSBundle bundleForClass: [self class]]; modelName = [NSString stringWithFormat: @"EO%@Prototypes.eomodeld", _name]; path = [[bundle resourcePath] stringByAppendingPathComponent: modelName]; model = [[EOModel alloc] initWithContentsOfFile: path]; if (model) { NSArray *entities; unsigned i, count; attributes = [NSMutableArray arrayWithCapacity: 20]; entities = [model entities]; count = [entities count]; for (i = 0; i < count; i++) { EOEntity *entity = [entities objectAtIndex: i]; [attributes addObjectsFromArray: [entity attributes]]; } RELEASE(model); } EOFLOGObjectFnStop(); return attributes; } - initWithName:(NSString *)name { if ((self = [super init])) { ASSIGN(_name, name); _contexts = [NSMutableArray new]; } return self; } - (void)dealloc { DESTROY(_model); DESTROY(_name); DESTROY(_connectionDictionary); DESTROY(_contexts); [super dealloc]; } - (void)setConnectionDictionary: (NSDictionary *)dictionary { //OK if ([self hasOpenChannels]) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: cannot set the connection dictionary while the adaptor is connected!", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self]; ASSIGN(_connectionDictionary, dictionary); // [model setConnectionDictionary:dictionary]; // TODO ?? } - (void)assertConnectionDictionaryIsValid { return; } - (EOAdaptorContext *)createAdaptorContext { [self subclassResponsibility: _cmd]; return nil; } - (NSArray *)contexts { SEL sel = @selector(nonretainedObjectValue); return [_contexts resultsOfPerformingSelector: sel]; } - (BOOL)hasOpenChannels { unsigned i; i = [_contexts count]; while (i--) { EOAdaptorContext *ctx = [[_contexts objectAtIndex: i] nonretainedObjectValue]; if([ctx hasOpenChannels] == YES) return YES; } return NO; } - (void)setDelegate:delegate { _delegate = delegate; _delegateRespondsTo.processValue = [delegate respondsToSelector: @selector(adaptor:fetchedValueForValue:attribute:)]; } - (void)setModel: (EOModel *)model { ASSIGN(_model, model); } - (NSString *)name { return _name; } - (NSDictionary *)connectionDictionary { return _connectionDictionary; } - (EOModel *)model { return _model; } - delegate { return _delegate; } - (Class)expressionClass { Class expressionClass = Nil; EOFLOGObjectFnStart(); /* retrieve EOAdaptorQuotesExternalNames from ? or from user default */ expressionClass = _expressionClass; if(!expressionClass) expressionClass = [self defaultExpressionClass]; EOFLOGObjectFnStop(); return expressionClass; } - (Class)defaultExpressionClass { [self subclassResponsibility: _cmd]; return Nil; //TODO vedere setExpressionClass } - (BOOL)canServiceModel: (EOModel *)model { return [_connectionDictionary isEqual: [model connectionDictionary]]; } - (NSStringEncoding)databaseEncoding { static NSMutableDictionary *encodingDictionary = nil; NSDictionary *connectionDictionary; NSString *encodingName; NSString *encodingValue; NSStringEncoding stringEncoding; EOFLOGObjectFnStartOrCond2(@"AdaptorLevel",@"EOAdaptor"); if (encodingDictionary == nil) { unsigned int i; encodingDictionary = [[NSMutableDictionary alloc] initWithCapacity: 64]; for (i = 0; encodingMap[i].name != nil; i++) { NSNumber *val = [NSNumber numberWithInt: encodingMap[i].encoding]; [encodingDictionary setObject: val forKey: encodingMap[i].name]; } } connectionDictionary = [self connectionDictionary]; encodingName = [connectionDictionary objectForKey: @"databaseEncoding"]; encodingValue = [encodingDictionary objectForKey: encodingName]; if (encodingValue == nil) { stringEncoding = [NSString defaultCStringEncoding]; } else { stringEncoding = [encodingValue intValue]; } EOFLOGObjectFnStopOrCond2(@"AdaptorLevel", @"EOAdaptor"); return stringEncoding; } - (id)fetchedValueForValue: (id)value attribute: (EOAttribute *)attribute { //Should be OK SEL valueFactoryMethod; EOFLOGObjectFnStart(); EOFLOGObjectLevelArgs(@"gsdb", @"value=%@", value); EOFLOGObjectLevelArgs(@"gsdb", @"attribute=%@", attribute); valueFactoryMethod = [attribute valueFactoryMethod]; if (valueFactoryMethod) { NSEmitTODO(); [self notImplemented: _cmd]; //TODO } else { if ([value isKindOfClass: [NSString class]]) [self fetchedValueForStringValue: value attribute: attribute]; else if ([value isKindOfClass: [NSNumber class]]) value = [self fetchedValueForNumberValue: value attribute: attribute]; else if ([value isKindOfClass: [NSDate class]]) value = [self fetchedValueForDateValue: value attribute: attribute]; else if ([value isKindOfClass: [NSData class]]) value = [self fetchedValueForDataValue: value attribute: attribute]; EOFLOGObjectLevelArgs(@"gsdb",@"value=%@",value); } if(_delegateRespondsTo.processValue) value = [_delegate adaptor: self fetchedValueForValue: value attribute: attribute]; EOFLOGObjectLevelArgs(@"gsdb", @"value=%@", value); EOFLOGObjectFnStop(); return value; } - (NSString *)fetchedValueForStringValue: (NSString *)value attribute: (EOAttribute *)attribute { NSString *resultValue = nil; EOFLOGObjectFnStart(); EOFLOGObjectLevelArgs(@"gsdb", @"value=%@", value); EOFLOGObjectLevelArgs(@"gsdb", @"attribute=%@", attribute); if([value length]>0) { //TODO-NOW: correct this code which loop! /* const char *cstr=NULL; unsigned i=0, spc=0; cstr = [value cString]; while(*cstr) { if(*cstr == ' ') spc++; else spc = 0; i++; } cstr = &cstr[-i]; if(!spc) resultValue=value; else if(!(&cstr[i-spc]-cstr)) resultValue=nil; else resultValue=[NSString stringWithCString:cstr length:&cstr[i-spc]-cstr]; */ resultValue = value; } EOFLOGObjectFnStop(); return resultValue; } - (NSNumber *)fetchedValueForNumberValue: (NSNumber *)value attribute: (EOAttribute *)attribute { return value; } - (NSCalendarDate *)fetchedValueForDateValue: (NSCalendarDate *)value attribute: (EOAttribute *)attribute { return value; } - (NSData *)fetchedValueForDataValue: (NSData *)value attribute: (EOAttribute *)attribute { return value; } /* Reconnection to database */ - (void)handleDroppedConnection { NSDictionary *newConnectionDictionary = nil; unsigned i; for (i = [_contexts count] - 1; i >= 0; i--) { EOAdaptorContext *ctx = [[_contexts objectAtIndex:i] nonretainedObjectValue]; [ctx handleDroppedConnection]; } [_contexts removeAllObjects]; if (_delegate && [_delegate respondsToSelector: @selector(reconnectionDictionaryForAdaptor:)]) { if ((newConnectionDictionary = [_delegate reconnectionDictionaryForAdaptor: self])) { [self setConnectionDictionary: newConnectionDictionary]; } } } - (BOOL)isDroppedConnectionException: (NSException *)exception { EOFLOGObjectFnStartOrCond2(@"AdaptorLevel", @"EOAdaptor"); EOFLOGObjectFnStopOrCond2(@"AdaptorLevel", @"EOAdaptor"); return NO; } /** * Attempts to create a database using * the statments returned by the Adaptor's expression class * for @selector(createDatabaseStatementsForConnectionDictionary:administrativeConnectionDictionary:); * using the connectionDictionary as the administrative connection dictionary. */ - (void)createDatabaseWithAdministrativeConnectionDictionary: (NSDictionary *)connectionDictionary { SEL sel; sel = @selector(createDatabaseStatementsForConnectionDictionary:administrativeConnectionDictionary:); [self _performAdministativeStatementsForSelector: sel connectionDictionary: [self connectionDictionary] administrativeConnectionDictionary: connectionDictionary]; } /** * Attempts to drop a database using * the statments returned by the Adaptor's expression class * for @selector(dropDatabaseStatementsForConnectionDictionary:administrativeConnectionDictionary:); * using the connectionDictionary as the administrative connection dictionary. */ - (void)dropDatabaseWithAdministrativeConnectionDictionary: (NSDictionary *)connectionDictionary { SEL sel; sel = @selector(dropDatabaseStatementsForConnectionDictionary:administrativeConnectionDictionary:); [self _performAdministativeStatementsForSelector: sel connectionDictionary: [self connectionDictionary] administrativeConnectionDictionary: connectionDictionary]; } - (BOOL) isValidQualifierType: (NSString *)attribute model: (EOModel *)model { [self subclassResponsibility: _cmd]; return NO; } @end /* EOAdaptor */ @implementation EOAdaptor (EOAdaptorLoginPanel) /** * Invokes [EOLoginPanel-runPanelForAdaptor:validate:allowsCreation:] * for the adaptor's [+sharedLoginPanelInstance], * with YES as the validate flag. * If the user supplies valid connection information, * the reciever's connection dictionary is updated, * and the method return YES. Otherwise it returns NO. * Subclass shouldn't need to override this method, * yet if the do, they should call this implementation. */ - (BOOL)runLoginPanelAndValidateConnectionDictionary { EOLoginPanel *panel; NSDictionary *connDict; panel = [[self class] sharedLoginPanelInstance]; connDict = [panel runPanelForAdaptor: self validate: YES allowsCreation: NO]; if (connDict != nil) { [self setConnectionDictionary: connDict]; } return (connDict != nil ? YES : NO); } /** * Invokes [EOLoginPanel-runPanelForAdaptor:validate:allowsCreation:] * for the adaptor's [+sharedLoginPanelInstance], * with YES as the validate flag. * Returns the dictionary without * changing the recievers connection dictionary. * Subclass shouldn't need to override this method, * yet if the do, they should call this implementation. */ - (NSDictionary *)runLoginPanel { EOLoginPanel *panel; NSDictionary *connDict; panel = [[self class] sharedLoginPanelInstance]; connDict = [panel runPanelForAdaptor: self validate: NO allowsCreation: NO]; return connDict; } @end @implementation EOAdaptor (EOExternalTypeMapping) /** * Subclasses must override this method without invoking this implementation * to return the name of the class used internal to the database * for the extType provided. * A subclass may use information provided by * an optional model to determine the exact type. */ + (NSString *)internalTypeForExternalType: (NSString *)extType model: (EOModel *)model { [self subclassResponsibility: _cmd]; return nil; } /** * Subclasses must override this method without invoking this implementation * to return an array of types available for the RDBMS. * A subclass may use information provided by * an optional model to determine the exact available types. */ + (NSArray *)externalTypesWithModel: (EOModel *)model { [self subclassResponsibility: _cmd]; return nil; } /** * Subclasses must override this method without invoking this implementation * to set the the external type according to the internal type information. * It should take into account width, precesion and scale accordingly. */ + (void)assignExternalTypeForAttribute: (EOAttribute *)attribute { [self subclassResponsibility: _cmd]; } /** * Invokes [+assignExternalTypeForAttribute:] * and unless the attribute is derived * it sets the column name if it hasn't been set. * An 'attributeName' result in a column named 'ATTRIBUTE_NAME'.
* NOTE: This differs from the EOF implementation as EOF unconditionally * sets the the external name attributes that are not derived. * This can cause trouble on certain RDMS which may not support * the extended names used internally in an application. * Subclass shouldn't need to override this method, * yet if the do, they should call this implementation. */ + (void)assignExternalInfoForAttribute: (EOAttribute *)attribute { if ([[attribute columnName] length] == 0 && [attribute isFlattened] == NO) { NSString *name; name = [NSString externalNameForInternalName: [attribute name] separatorString: @"_" useAllCaps: YES]; [attribute setColumnName: name]; } [self assignExternalTypeForAttribute: attribute]; } /** * Invokes [+assignExternalInfoForAttribute:] * for each of the model's entities. * If the externalName of the entity hasn't been set, * this method sets it to a standardized name * according to the entities name. * An 'entityName' will be converted to 'ENTITY_NAME'.
* Subclass shouldn't need to override this method, * yet if the do, they should call this implementation. */ + (void)assignExternalInfoForEntity: (EOEntity *)entity { NSArray *attributes=nil; unsigned i=0; unsigned attributesCount=0; if ([[entity externalName] length] == 0) { NSString *name; name = [NSString externalNameForInternalName: [entity name] separatorString: @"_" useAllCaps: YES]; [entity setExternalName: name]; } attributes = [entity attributes]; attributesCount=[attributes count]; for (i = 0; i < attributesCount; i++) { [self assignExternalInfoForAttribute: [attributes objectAtIndex: i]]; } } /** * Invokes [+assignExternalInfoForEntity:] * for each of the model's entities. * Subclass shouldn't need to override this method, * yet if the do, they should call this implementation. */ + (void)assignExternalInfoForEntireModel: (EOModel *)model { NSArray *entities=nil; unsigned i=0; unsigned entitiesCount=0; entities = [model entities]; entitiesCount=[entities count]; for (i = 0; i < entitiesCount; i++) { [self assignExternalInfoForEntity: [entities objectAtIndex: i]]; } } @end @implementation EOAdaptor (EOAdaptorPrivate) - (void) _requestConcreteImplementationForSelector: (SEL)param0 { [self notImplemented: _cmd]; //TODO } - (void) _unregisterAdaptorContext: (EOAdaptorContext*)adaptorContext { unsigned i = 0; for (i = [_contexts count] - 1; i >= 0; i--) { if ([[_contexts objectAtIndex: i] nonretainedObjectValue] == adaptorContext) { [_contexts removeObjectAtIndex: i]; break; } } } - (void) _registerAdaptorContext: (EOAdaptorContext*)adaptorContext { [_contexts addObject: [NSValue valueWithNonretainedObject: adaptorContext]]; } @end @implementation EOLoginPanel - (NSDictionary *) runPanelForAdaptor: (EOAdaptor *)adaptor validate: (BOOL)yn allowsCreation: (BOOL)allowsCreation { [self subclassResponsibility: _cmd]; return nil; } /** Subclasses should implement this method to return a connection dictionary for an administrative user able to create databases etc. Or nil if the the user cancels. */ - (NSDictionary *) administrativeConnectionDictionaryForAdaptor: (EOAdaptor *)adaptor { [self subclassResponsibility: _cmd]; return nil; } @end @implementation EOLoginPanel (Deprecated) - (NSDictionary *) runPanelForAdaptor: (EOAdaptor *)adaptor validate: (BOOL)yn { return [self runPanelForAdaptor: adaptor validate: yn allowsCreation: NO]; } @end gnustep-dl2-0.12.0/EOAccess/EOSchemaGeneration.h0000644000175000017500000001307310645346232020235 0ustar ayersayers/* -*-objc-*- EOSchemaGeneration.h Copyright (C) 2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: April 2004 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EOSchemaGeneration_h__ #define __EOSchemaGeneration_h__ #include @interface EOSQLExpression (EOSchemaGeneration) /** * Generates the statements to create a database. */ + (NSArray *)createDatabaseStatementsForConnectionDictionary:(NSDictionary *)connectionDictionary administrativeConnectionDictionary:(NSDictionary *)administrativeConnectionDictionary; /** * Generates the statements to drop the database. */ + (NSArray *)dropDatabaseStatementsForConnectionDictionary:(NSDictionary *)connectionDictionary administrativeConnectionDictionary:(NSDictionary *)administrativeConnectionDictionary; /** Generates the statements necessary to implement the schema generation for * an entityGroup like creating/dropping a table, a primary key constaint or * a primary key generation support such as a sequence. */ + (NSArray *)createTableStatementsForEntityGroup: (NSArray *)entityGroup; + (NSArray *)dropTableStatementsForEntityGroup: (NSArray *)entityGroup; + (NSArray *)primaryKeyConstraintStatementsForEntityGroup: (NSArray *)entityGroup; + (NSArray *)primaryKeySupportStatementsForEntityGroup: (NSArray *)entityGroup; + (NSArray *)dropPrimaryKeySupportStatementsForEntityGroup: (NSArray *)entityGroup; /** * Generates statements to create/drop a specific schema generation for a * list of entityGroups. */ + (NSArray *)createTableStatementsForEntityGroups: (NSArray *)entityGroups; + (NSArray *)dropTableStatementsForEntityGroups: (NSArray *)entityGroups; + (NSArray *)primaryKeyConstraintStatementsForEntityGroups: (NSArray *)entityGroups; + (NSArray *)primaryKeySupportStatementsForEntityGroups: (NSArray *)entityGroups; + (NSArray *)dropPrimaryKeySupportStatementsForEntityGroups: (NSArray *)entityGroups; /** * The default implementation verifies the relationship joins and calls * prepareConstraintStatementForRelationship:sourceColumns:destinationColumns: */ + (NSArray *)foreignKeyConstraintStatementsForRelationship: (EORelationship *)relationship; /** * Assembles an adaptor specific string for using in a create table * statement. */ - (NSString *)columnTypeStringForAttribute: (EOAttribute *)attribute; /** * Generates a string to be used in a create table statement */ - (NSString *)allowsNullClauseForConstraint: (BOOL)allowsNull; /** * Assembles the create table statement for the given attribute */ - (void)addCreateClauseForAttribute: (EOAttribute *)attribute; /** * Assembles an adaptor specific constraint statement for relationship and the * given source and destination columns */ - (void)prepareConstraintStatementForRelationship: (EORelationship *)relationship sourceColumns: (NSArray *)sourceColumns destinationColumns: (NSArray *)destinationColumns; /** * Append expression statement to an executable script. * The default implementation appends the ';' */ + (void)appendExpression:(EOSQLExpression *)expression toScript:(NSMutableString *)script; /** * Returns a script to create the schema for the given entities specific for * the target db. Options are the same as * [+schemaCreationStatementsForEntities:options:] */ + (NSString *)schemaCreationScriptForEntities:(NSArray *)entities options:(NSDictionary *)options; /** *

* Returns an array of EOSQLExpression suitable to create the schema for the * given entities specific for the target db. * Possible options are:

* * Name Value Default * * createTables YES/NO YES * dropTables YES/NO YES * createPrimaryKeySupport YES/NO YES * dropPrimaryKeySupport YES/NO YES * primaryKeyConstraints YES/NO YES * foreignKeyConstraints YES/NO NO * createDatabase YES/NO NO * dropDatabase YES/NO NO * */ + (NSArray *)schemaCreationStatementsForEntities: (NSArray *)entities options: (NSDictionary *)options; + (EOSQLExpression *)selectStatementForContainerOptions; @end /** Keys to use the options dictionary for * +schemaCreationScriptForEntities:options: * and +schemaCreationStatementsForEntities:options: */ GDL2ACCESS_EXPORT NSString *EOCreateTablesKey; GDL2ACCESS_EXPORT NSString *EODropTablesKey; GDL2ACCESS_EXPORT NSString *EOCreatePrimaryKeySupportKey; GDL2ACCESS_EXPORT NSString *EODropPrimaryKeySupportKey; GDL2ACCESS_EXPORT NSString *EOPrimaryKeyConstraintsKey; GDL2ACCESS_EXPORT NSString *EOForeignKeyConstraintsKey; GDL2ACCESS_EXPORT NSString *EOCreateDatabaseKey; GDL2ACCESS_EXPORT NSString *EODropDatabaseKey; #endif gnustep-dl2-0.12.0/EOAccess/EOPrivate.m0000644000175000017500000000717011022340040016416 0ustar ayersayers/** EOPrivate.m EOPrivate: various definitions Copyright (C) 2005 Free Software Foundation, Inc. Date: Jan 2005 $Revision: 26601 $ $Date: 2008-06-07 00:54:24 +0200 (Sam, 07. Jun 2008) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EOPrivate.m 26601 2008-06-06 22:54:24Z ratmice $") #include #ifndef GNUSTEP #include #include #endif #include #include #include #include #include "EOPrivate.h" // ==== Classes ==== Class GDL2_EODatabaseContextClass=Nil; Class GDL2_EOAttributeClass=Nil; // ==== IMPs ==== IMP GDL2_EODatabaseContext_snapshotForGlobalIDIMP=NULL; IMP GDL2_EODatabaseContext__globalIDForObjectIMP=NULL; // ==== Init Method ==== void GDL2_EOAccessPrivateInit() { static BOOL initialized=NO; if (!initialized) { initialized = YES; GDL2_PrivateInit(); // ==== Classes ==== GDL2_EODatabaseContextClass = [EODatabaseContext class]; GDL2_EOAttributeClass = [EOAttribute class]; GDL2_EODatabaseContext_snapshotForGlobalIDIMP=[GDL2_EODatabaseContextClass instanceMethodForSelector:@selector(snapshotForGlobalID:)]; GDL2_EODatabaseContext__globalIDForObjectIMP=[GDL2_EODatabaseContextClass instanceMethodForSelector:@selector(_globalIDForObject:)]; }; } // ==== EODatabaseContext ==== NSDictionary * EODatabaseContext_snapshotForGlobalIDWithImpPtr(EODatabaseContext* dbContext, IMP* impPtr, EOGlobalID* gid) { if (dbContext) { IMP imp=NULL; if (impPtr) imp=*impPtr; if (!imp) { if (GSObjCClass(dbContext)==GDL2_EODatabaseContextClass && GDL2_EODatabaseContext_snapshotForGlobalIDIMP) imp=GDL2_EODatabaseContext_snapshotForGlobalIDIMP; else imp=[dbContext methodForSelector:@selector(snapshotForGlobalID:)]; if (impPtr) *impPtr=imp; } return (*imp)(dbContext,@selector(snapshotForGlobalID:),gid); } else return nil; }; EOGlobalID* EODatabaseContext_globalIDForObjectWithImpPtr(EODatabaseContext* dbContext,IMP* impPtr,id object) { if (dbContext) { IMP imp=NULL; if (impPtr) imp=*impPtr; if (!imp) { if (GSObjCClass(dbContext)==GDL2_EODatabaseContextClass && GDL2_EODatabaseContext__globalIDForObjectIMP) imp=GDL2_EODatabaseContext__globalIDForObjectIMP; else imp=[dbContext methodForSelector:@selector(_globalIDForObject:)]; if (impPtr) *impPtr=imp; } return (*imp)(dbContext,@selector(_globalIDForObject:),object); } else return nil; }; gnustep-dl2-0.12.0/EOAccess/EODatabaseContextPriv.h0000644000175000017500000000501210645346232020725 0ustar ayersayers/* -*-objc-*- EODatabaseContextPriv.h Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: July 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EODatabaseContextPriv_h__ #define __EODatabaseContextPriv_h__ @class EOAccessFaultHandler; @class EOAccessArrayFaultHandler; @class EOKeyGlobalID; @class EOFault; @interface EODatabaseContext (EODatabaseContextPrivate) - (void)_fireArrayFault: (id)object; - (void)_fireFault: (id)object; - (void)_addBatchForGlobalID: (EOKeyGlobalID *)globalID fault: (EOFault *)fault; - (void)_removeBatchForGlobalID: (EOKeyGlobalID *)globalID fault: (EOFault *)fault; - (void)_addToManyBatchForSourceGlobalID: (EOKeyGlobalID *)globalID relationshipName: (NSString *)relationshipName fault: (EOFault *)fault; /* - (void)_batchToOne: (id)fault withHandler: (EOAccessFaultHandler *)handler; - (void)_batchToMany: (id)fault withHandler: (EOAccessArrayFaultHandler *)handler; */ @end @interface EODatabaseContext (EODatabaseContextPrivate2) - (void)_verifyNoChangesToReadonlyEntity: (EODatabaseOperation *)dbOpe; - (EOGlobalID *)_globalIDForObject: (id)object; - (NSDictionary *)_primaryKeyForObject: (id)object; - (NSDictionary *)_primaryKeyForObject: (id)object raiseException: (BOOL)raiseException; - (NSDictionary *)_currentCommittedSnapshotForObject: (id)object; - (id)_addDatabaseContextStateToException: (id)param0; - (id)_databaseContextState; - (void)_cleanUpAfterSave; - (void)_assertValidStateWithSelector: (SEL)sel; - (BOOL)_shouldGeneratePrimaryKeyForEntityName: (NSString *)entityName; - (void)_buildPrimaryKeyGeneratorListForEditingContext: (EOEditingContext *)context; @end #endif /* __EODatabaseContextPriv_h__ */ gnustep-dl2-0.12.0/EOAccess/EODatabaseChannel.h0000644000175000017500000000530710645346232020017 0ustar ayersayers/* -*-objc-*- EODatabaseChannel.h Copyright (C) 2000-2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: July 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EODatabaseChannel_h__ #define __EODatabaseChannel_h__ #ifdef GNUSTEP #include #else #include #endif @class NSMutableArray; @class EOEntity; @class EOAdaptorChannel; @class EORelationship; @class EODatabaseContext; @class EOEditingContext; @class EOFetchSpecification; @interface EODatabaseChannel : NSObject { EODatabaseContext *_databaseContext; id _delegate; EOAdaptorChannel *_adaptorChannel; EOEntity *_currentEntity; EOEditingContext *_currentEditingContext; NSMutableArray *_fetchProperties; NSMutableArray *_fetchSpecifications; BOOL _isLocking; BOOL _isRefreshingObjects; struct { unsigned int shouldSelectObjects:1; unsigned int didSelectObjects:1; unsigned int shouldUsePessimisticLock:1; unsigned int shouldUpdateSnapshot:1; unsigned int _reserved:28; } _delegateRespondsTo; } + (EODatabaseChannel *)databaseChannelWithDatabaseContext: (EODatabaseContext *)databaseContext; - (id)initWithDatabaseContext: (EODatabaseContext *)databaseContext; - (void)setCurrentEntity: (EOEntity *)entity; - (void)setEntity: (EOEntity *)entity; - (void)setCurrentEditingContext: (EOEditingContext *)context; - (void)selectObjectsWithFetchSpecification: (EOFetchSpecification *)fetchSpecification editingContext: (EOEditingContext *)context; - (id)fetchObject; - (BOOL)isFetchInProgress; - (void)cancelFetch; - (EODatabaseContext *)databaseContext; - (EOAdaptorChannel *)adaptorChannel; - (BOOL)isRefreshingObjects; - (void)setIsRefreshingObjects: (BOOL)yn; - (BOOL)isLocking; - (void)setIsLocking: (BOOL)isLocking; - (void)setDelegate: (id)delegate; - (id)delegate; @end #endif /* __EODatabaseChannel_h__ */ gnustep-dl2-0.12.0/EOAccess/EODatabaseChannelPriv.h0000644000175000017500000000321410645346232020653 0ustar ayersayers/* -*-objc-*- EODatabaseChannelPriv.h Copyright (C) 2002,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: Mars 2002 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EODatabaseChannelPriv_h__ #define __EODatabaseChannelPriv_h__ @class NSArray; @class EOFetchSpecification; @class EOEditingContext; @interface EODatabaseChannel (EODatabaseChannelPrivate) - (NSArray *)_propertiesToFetch; - (void)_setCurrentEntityAndRelationshipWithFetchSpecification: (EOFetchSpecification *)fetch; -(void)_selectWithFetchSpecification: (EOFetchSpecification *)fetch editingContext: (EOEditingContext *)context; - (void)_buildNodeList: (id)param0 withParent: (id)param1; - (id)currentEditingContext; - (void)_cancelInternalFetch; - (void)_closeChannel; - (void)_openChannel; @end #endif /* __EODatabaseChannelPriv_h__ */ gnustep-dl2-0.12.0/EOAccess/EORelationship.h0000644000175000017500000001366711022200637017457 0ustar ayersayers/* -*-objc-*- EORelationship.h Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EORelationship_h__ #define __EORelationship_h__ #include #include #include @class NSString; @class NSArray; @class NSMutableArray; @class NSDictionary; @class NSMutableDictionary; @class NSException; @class EOEntity; @class EOAttribute; @class EOExpressionArray; @class EOMutableKnownKeyDictionary; @class EOMKKDSubsetMapping; @class EOQualifier; typedef enum { EOInnerJoin = 0, EOFullOuterJoin, EOLeftOuterJoin, EORightOuterJoin } EOJoinSemantic; @interface EORelationship : NSObject { NSString *_name; EOQualifier *_qualifier; NSMutableDictionary *_sourceNames; NSMutableDictionary *_destinationNames; NSDictionary *_userInfo; NSDictionary *_internalInfo; NSString *_docComment; NSDictionary *_sourceToDestinationKeyMap; unsigned int _batchCount; EOJoinSemantic _joinSemantic; struct { unsigned int isToMany:1; unsigned int useBatchFaulting:1; unsigned int deleteRule:2; unsigned int isMandatory:1; unsigned int ownsDestination:1; unsigned int propagatesPrimaryKey:1; unsigned int unused:1; unsigned int isBidirectional:1; unsigned int extraRefCount:23; } _flags; id _sourceRowToForeignKeyMapping; /* Garbage collectable objects */ EOExpressionArray *_definitionArray; EORelationship *_inverseRelationship; EORelationship *_hiddenInverseRelationship; EOEntity *_entity; // unretained EOEntity *_destination; // unretained NSMutableArray *_joins; /* Computed values */ NSArray *_sourceAttributes; NSArray *_destinationAttributes; NSMutableArray *_componentRelationships;//Used ???? } + (id)relationshipWithPropertyList: (NSDictionary *)propertyList owner: (id)owner; - (NSString *)name; - (EOEntity *)entity; - (EOEntity *)destinationEntity; - (NSString *)definition; - (BOOL)isFlattened; - (BOOL)isToMany; - (BOOL)isCompound; - (BOOL)isParentRelationship; - (NSArray *)sourceAttributes; - (NSArray *)destinationAttributes; - (NSArray *)joins; - (EOJoinSemantic)joinSemantic; - (NSString *)joinSemanticString; - (NSArray *)componentRelationships; - (NSDictionary *)userInfo; - (BOOL)referencesProperty: (id)property; - (EODeleteRule)deleteRule; - (BOOL)isMandatory; - (BOOL)propagatesPrimaryKey; - (BOOL)isBidirectional; - (EORelationship *)hiddenInverseRelationship; - (EORelationship *)inverseRelationship; - (EORelationship *)anyInverseRelationship; - (unsigned int)numberOfToManyFaultsToBatchFetch; - (BOOL)ownsDestination; - (EOQualifier *)qualifierWithSourceRow: (NSDictionary *)sourceRow; /** Accessing documentation comments **/ - (NSString *)docComment; @end @interface EORelationship(EORelationshipEditing) - (NSException *)validateName: (NSString *)name; - (void)setName: (NSString *)name; - (void)setDefinition: (NSString *)definition; - (void)setEntity: (EOEntity *)entity; - (void)setToMany: (BOOL)flag; - (void)setPropagatesPrimaryKey: (BOOL)flag; - (void)setIsBidirectional: (BOOL)flag; - (void)setOwnsDestination: (BOOL)flag; - (void)addJoin: (EOJoin *)join; - (void)removeJoin: (EOJoin *)join; - (void)setJoinSemantic: (EOJoinSemantic)joinSemantic; - (void)setUserInfo: (NSDictionary *)dictionary; - (void)setInternalInfo: (NSDictionary *)dictionary; - (void)beautifyName; - (void)setNumberOfToManyFaultsToBatchFetch: (unsigned int)size; - (void)setDeleteRule: (EODeleteRule)deleteRule; - (void)setIsMandatory: (BOOL)isMandatory; - (void)setDocComment: (NSString *)docComment; @end @interface EORelationship(EORelationshipValueMapping) - (NSException *)validateValue: (id *)valueP; @end @interface EORelationship (EORelationshipXX) - (NSArray *)_intermediateAttributes; - (EORelationship *)lastRelationship; - (EORelationship *)firstRelationship; - (EOEntity*) intermediateEntity; - (BOOL)isMultiHop; - (void)_setSourceToDestinationKeyMap: (id)param0; - (id)qualifierForDBSnapshot: (id)param0; - (id)primaryKeyForTargetRowFromSourceDBSnapshot: (id)param0; - (NSString *)relationshipPath; - (BOOL)isToManyToOne; - (NSDictionary *)_sourceToDestinationKeyMap; - (BOOL)foreignKeyInDestination; @end @interface EORelationship (EORelationshipPrivate2) - (BOOL)isPropagatesPrimaryKeyPossible; - (id)qualifierOmittingAuxiliaryQualifierWithSourceRow: (id)param0; - (id)auxiliaryQualifier; - (void)setAuxiliaryQualifier: (id)param0; - (EOMutableKnownKeyDictionary *)_foreignKeyForSourceRow: (NSDictionary *)row; - (EOMKKDSubsetMapping *)_sourceRowToForeignKeyMapping; - (NSArray *)_sourceAttributeNames; - (EOJoin *)joinForAttribute: (EOAttribute *)attribute; - (void)_flushCache; - (EOExpressionArray *)_definitionArray; - (NSString *)_stringFromDeleteRule: (EODeleteRule)deleteRule; - (EODeleteRule)_deleteRuleFromString: (NSString *)deleteRuleString; - (NSDictionary *)_rightSideKeyMap; - (NSDictionary *)_leftSideKeyMap; - (EORelationship *)_substitutionRelationshipForRow: (NSDictionary *)row; - (void)_joinsChanged; @end #endif /* __EORelationship_h__ */ gnustep-dl2-0.12.0/EOAccess/EODatabaseDataSource.h0000644000175000017500000000434610645346232020503 0ustar ayersayers/* -*-objc-*- EODatabaseDataSource.m Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: July 2000 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __EODatabaseDataSource_h__ #define __EODatabaseDataSource_h__ #include @class NSDictionary; @class NSString; @class EOEntity; @class EODatabaseContext; @class EOEditingContext; @class EOFetchSpecification; @class EOQualifier; @interface EODatabaseDataSource : EODataSource { EOEditingContext *_editingContext; EOFetchSpecification *_fetchSpecification; EOQualifier *_auxiliaryQualifier; NSDictionary *_bindings; struct { unsigned int fetchEnabled:1; unsigned int _reserved:31; } _flags; } - (id)initWithEditingContext: (EOEditingContext *)editingContext entityName: (NSString *)entityName; - (id)initWithEditingContext: (EOEditingContext *)editingContext entityName: (NSString *)entityName fetchSpecificationName: (NSString *)fetchName; - (EOEntity *)entity; - (EODatabaseContext *)databaseContext; - (void)setFetchSpecification: (EOFetchSpecification *)fetchSpecification; - (EOFetchSpecification *)fetchSpecification; - (void)setAuxiliaryQualifier: (EOQualifier *)qualifier; - (EOQualifier *)auxiliaryQualifier; - (EOFetchSpecification *)fetchSpecificationForFetch; - (void)setFetchEnabled: (BOOL)flag; - (BOOL)isFetchEnabled; @end #endif /* __EODatabaseDataSource_h__ */ gnustep-dl2-0.12.0/EOAccess/EOAccess.gsdoc0000644000175000017500000000153710502276775017102 0ustar ayersayers GDL2 - EOAccess GDL2 - EOAccess

...

gnustep-dl2-0.12.0/EOAccess/EOAdaptorOperation.m0000644000175000017500000001162410645346232020301 0ustar ayersayers/** EOAdaptorOperation.m EOAdaptorOperation Class Copyright (C) 2000-2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 $Revision: 25326 $ $Date: 2007-07-12 08:39:22 +0200 (Don, 12. Jul 2007) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EOAdaptorOperation.m 25326 2007-07-12 06:39:22Z ayers $") #ifdef GNUSTEP #include #include #else #include #endif #ifndef GNUSTEP #include #include #include #endif #include #include #include #include #include @implementation EOAdaptorOperation + (EOAdaptorOperation *)adaptorOperationWithEntity: (EOEntity *)entity { return [[[self alloc] initWithEntity: entity] autorelease]; } - (id) initWithEntity: (EOEntity *)entity { if ((self = [self init])) { ASSIGN(_entity, entity); } return self; } - (void)dealloc { DESTROY(_entity); DESTROY(_qualifier); DESTROY(_changedValues); DESTROY(_attributes); DESTROY(_storedProcedure); DESTROY(_exception); [super dealloc]; } - (EOAdaptorOperator)adaptorOperator { return _adaptorOperator; } - (void)setAdaptorOperator: (EOAdaptorOperator)adaptorOperator { NSDebugMLLog(@"gsdb", @"adaptorOperator=%d", adaptorOperator); _adaptorOperator = adaptorOperator; NSDebugMLLog(@"gsdb", @"_adaptorOperator=%d", _adaptorOperator); } - (EOEntity *)entity { return _entity; } - (EOQualifier *)qualifier { return _qualifier; } - (void)setQualifier: (EOQualifier *)qualifier { ASSIGN(_qualifier, qualifier); } - (NSDictionary *)changedValues { return _changedValues; } - (void)setChangedValues: (NSDictionary *)changedValues { ASSIGN(_changedValues, changedValues); } - (NSArray *)attributes { return _attributes; } - (void)setAttributes: (NSArray *)attributes { ASSIGN(_attributes, attributes); } - (EOStoredProcedure *)storedProcedure { return _storedProcedure; } - (void)setStoredProcedure: (EOStoredProcedure *)storedProcedure { ASSIGN(_storedProcedure, storedProcedure); } - (NSException *)exception { return _exception; } - (void)setException: (NSException *)exception { ASSIGN(_exception, exception); } - (NSComparisonResult)compareAdaptorOperation: (EOAdaptorOperation *)adaptorOp { NSComparisonResult res; EOAdaptorOperator otherOp = [adaptorOp adaptorOperator]; res = [[_entity name] compare: [[adaptorOp entity] name]]; if(res == NSOrderedSame) { if(_adaptorOperator == otherOp) res = NSOrderedSame; else if(_adaptorOperator < otherOp) res = NSOrderedAscending; else res = NSOrderedDescending; } return res; } - (NSString *)description { //TODO revoir NSString *operatorString = nil; NSString *desc = nil; EOFLOGObjectFnStart(); switch(_adaptorOperator) { case EOAdaptorUndefinedOperator: operatorString = @"EOAdaptorUndefinedOperator"; break; case EOAdaptorLockOperator: operatorString = @"EOAdaptorLockOperator"; break; case EOAdaptorInsertOperator: operatorString = @"EOAdaptorInsertOperator"; break; case EOAdaptorUpdateOperator: operatorString = @"EOAdaptorUpdateOperator"; break; case EOAdaptorDeleteOperator: operatorString = @"EOAdaptorDeleteOperator"; break; case EOAdaptorStoredProcedureOperator: operatorString = @"EOAdaptorStoredProcedureOperator"; break; default: operatorString = @"Unknwon"; break; } desc = [NSString stringWithFormat: @"<%s %p : operator: %@ entity: %@ qualifier:%@\nchangedValues: %@\nattributes:%@\nstoredProcedure: %@\nexception: %@>", object_get_class_name(self), (void*)self, operatorString, [_entity name], _qualifier, _changedValues, _attributes, _storedProcedure, _exception]; EOFLOGObjectFnStop(); return desc; } @end gnustep-dl2-0.12.0/EOAccess/EODatabaseChannel.m0000644000175000017500000006072610645346232020032 0ustar ayersayers/** EODatabaseChannel.m EODatabaseChannel Copyright (C) 2000-2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: June 2000 Author: Manuel Guesdon Date: October 2000 $Revision: 25326 $ $Date: 2007-07-12 08:39:22 +0200 (Don, 12. Jul 2007) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EODatabaseChannel.m 25326 2007-07-12 06:39:22Z ayers $") #ifdef GNUSTEP #include #include #include #include #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "EOPrivate.h" #include "EOEntityPriv.h" #include "EODatabaseContextPriv.h" #include "EODatabaseChannelPriv.h" @implementation EODatabaseChannel + (void)initialize { static BOOL initialized=NO; if (!initialized) { initialized=YES; GDL2_EOAccessPrivateInit(); [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_registerDatabaseChannel:) name: EODatabaseChannelNeededNotification object: nil]; } } + (void)_registerDatabaseChannel: (NSNotification *)notification { // TODO who release it ? [[EODatabaseChannel alloc] initWithDatabaseContext: [notification object]]; } + (EODatabaseChannel*)databaseChannelWithDatabaseContext: (EODatabaseContext *)databaseContext { return [[[self alloc] initWithDatabaseContext: databaseContext] autorelease]; } - (id) initWithDatabaseContext:(EODatabaseContext *)databaseContext { if ((self = [super init])) { ASSIGN(_databaseContext, databaseContext); ASSIGN(_adaptorChannel, [[_databaseContext adaptorContext] createAdaptorChannel]); //TODO NO<<<< [_adaptorChannel openChannel]; _fetchProperties = [NSMutableArray new]; _fetchSpecifications = [NSMutableArray new]; //NO>>>>>>> [_databaseContext registerChannel: self];//should be in caller } return self; } - (void)dealloc { [_databaseContext unregisterChannel: self]; DESTROY(_databaseContext); [_adaptorChannel closeChannel]; DESTROY(_adaptorChannel); DESTROY(_currentEntity); DESTROY(_currentEditingContext); DESTROY(_fetchProperties); DESTROY(_fetchSpecifications); [super dealloc]; } - (void)setCurrentEntity: (EOEntity *)entity { //OK ASSIGN(_currentEntity, entity); [self setEntity: entity]; } - (void) setEntity: (EOEntity *)entity { //Near OK NSArray *relationships = [entity relationships]; int i = 0; int count = [relationships count]; EOFLOGObjectLevelArgs(@"gsdb", @"relationships=%@", relationships); for (i = 0; i < count; i++) { EORelationship *relationship = [relationships objectAtIndex:i]; EOEntity *destinationEntity = [relationship destinationEntity]; EOModel *destinationEntityModel = [destinationEntity model]; EOEntity *entity = [relationship entity]; EOModel *entityModel = [entity model]; EOFLOGObjectLevelArgs(@"gsdb", @"relationship=%@", relationship); EOFLOGObjectLevelArgs(@"gsdb", @"destinationEntity=%@", [destinationEntity name]); NSAssert2(destinationEntity, @"No destinationEntity in relationship: %@ of entity %@", relationship, [entity name]); //TODO: flattened relationship EOFLOGObjectLevelArgs(@"gsdb", @"entity=%@", [entity name]); EOFLOGObjectLevelArgs(@"gsdb", @"destinationEntityModel=%p", destinationEntityModel); EOFLOGObjectLevelArgs(@"gsdb", @"entityModel=%p", entityModel); //If different: try to add destinationEntityModel if (destinationEntityModel != entityModel) { EOEditingContext *editingContext = [self currentEditingContext]; //EODatabaseContext *databaseContext = [self databaseContext]; EOObjectStore *rootObjectStore = [editingContext rootObjectStore]; NSArray *cooperatingObjectStores = [(EOObjectStoreCoordinator *)rootObjectStore cooperatingObjectStores]; int cosCount = [cooperatingObjectStores count]; int i; for (i = 0; i < cosCount; i++) { id objectStore = [cooperatingObjectStores objectAtIndex: i]; EODatabase *objectStoreDatabase = [objectStore database]; BOOL modelOK = [objectStoreDatabase addModelIfCompatible: destinationEntityModel]; if (!modelOK) { /*EODatabase *dbDatabase = [[[EODatabase alloc] initWithModel: destinationEntityModel] autorelease];*/ [self notImplemented: _cmd]; //TODO: finish it } } } } } - (void)setCurrentEditingContext: (EOEditingContext*)context { //OK EOCooperatingObjectStore *cooperatingObjectStore = [self databaseContext]; EOObjectStore *objectStore = [context rootObjectStore]; [(EOObjectStoreCoordinator*)objectStore addCooperatingObjectStore: cooperatingObjectStore]; ASSIGN(_currentEditingContext, context); } - (void)selectObjectsWithFetchSpecification: (EOFetchSpecification *)fetchSpecification editingContext: (EOEditingContext *)context { //should be OK NSString *entityName = nil; EODatabase *database = nil; EOEntity *entity = nil; EOQualifier *qualifier = nil; EOQualifier *schemaBasedQualifier = nil; EOFLOGObjectFnStart(); entityName = [fetchSpecification entityName]; database = [_databaseContext database]; EOFLOGObjectLevelArgs(@"gsdb", @"database=%@", database); entity = [database entityNamed: entityName]; EOFLOGObjectLevelArgs(@"gsdb", @"entity name=%@", [entity name]); qualifier=[fetchSpecification qualifier]; EOFLOGObjectLevelArgs(@"gsdb", @"qualifier=%@", qualifier); schemaBasedQualifier = [(id)qualifier schemaBasedQualifierWithRootEntity: entity]; EOFLOGObjectLevelArgs(@"gsdb", @"schemaBasedQualifier=%@", schemaBasedQualifier); EOFLOGObjectLevelArgs(@"gsdb", @"qualifier=%@", qualifier); if (schemaBasedQualifier && schemaBasedQualifier != qualifier) { EOFetchSpecification *newFetch = nil; EOFLOGObjectLevelArgs(@"gsdb", @"fetchSpecification=%@", fetchSpecification); //howto avoid copy of uncopiable qualifiers (i.e. those who contains uncopiable key or value) EOFLOGObjectLevelArgs(@"gsdb", @"fetchSpecification=%@", fetchSpecification); newFetch = [[fetchSpecification copy] autorelease]; EOFLOGObjectLevelArgs(@"gsdb", @"newFetch=%@", newFetch); [newFetch setQualifier: schemaBasedQualifier]; EOFLOGObjectLevelArgs(@"gsdb", @"newFetch=%@", newFetch); fetchSpecification = newFetch; } EOFLOGObjectLevelArgs(@"gsdb", @"%@ -- %@ 0x%x: isFetchInProgress=%s", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, ([self isFetchInProgress] ? "YES" : "NO")); [self _selectWithFetchSpecification:fetchSpecification editingContext:context]; EOFLOGObjectFnStop(); } - (id)fetchObject { //seems OK EODatabase *database=nil; id object = nil; EOFLOGObjectFnStart(); database = [_databaseContext database]; if (![self isFetchInProgress]) { NSLog(@"No Fetch in progress"); NSDebugMLog(@"No Fetch in progress", ""); [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: no fetch in progress", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self]; } else { NSArray *propertiesToFetch=nil; NSDictionary *row =nil; NSAssert(_currentEditingContext, @"No current editing context"); NSAssert(_adaptorChannel,@"No adaptor channel"); propertiesToFetch = [self _propertiesToFetch]; EOFLOGObjectLevel(@"gsdb", @"Will fetchRow"); row = [_adaptorChannel fetchRowWithZone: NULL]; EOFLOGObjectLevelArgs(@"gsdb", @"row=%@", row); if (!row) { //TODO //VERIFY /* if no more obj: if transactionNestingLevel 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 EOGlobalID *gid; NSDictionary *snapshot = nil; NSAssert(_currentEntity, @"Not current Entity"); gid = [_currentEntity globalIDForRow: row isFinal: YES];//OK EOFLOGObjectLevelArgs(@"gsdb", @"gid=%@", gid); object = [_currentEditingContext objectForGlobalID: gid]; //OK //nil EOFLOGObjectLevelArgs(@"gsdb", @"object=%@", object); if (object) isObjectNew = NO; NSAssert(_databaseContext,@"No database context"); snapshot = [_databaseContext snapshotForGlobalID: gid]; //OK EOFLOGObjectLevelArgs(@"gsdb", @"snapshot=%@", snapshot); if (snapshot) { EOFLOGObjectLevelArgs(@"gsdb", @"_delegateRespondsTo.shouldUpdateSnapshot=%d", (int)_delegateRespondsTo.shouldUpdateSnapshot); EOFLOGObjectLevelArgs(@"gsdb", @"[self isLocking]=%d", (int)[self isLocking]); EOFLOGObjectLevelArgs(@"gsdb", @"[self isRefreshingObjects]=%d", (int)[self isRefreshingObjects]); //mirko: if((_delegateRespondsTo.shouldUpdateSnapshot == NO && ([self isLocking] == YES || [self isRefreshingObjects] == YES)) || (_delegateRespondsTo.shouldUpdateSnapshot == YES && (row = (id)[_delegate databaseContext: _databaseContext shouldUpdateCurrentSnapshot: snapshot newSnapshot: row globalID: gid databaseChannel: self]))) { // TODO delegate not correct ! EOFLOGObjectLevelArgs(@"gsdb", @"Updating Snapshot=%@", snapshot); EOFLOGObjectLevelArgs(@"gsdb", @"row=%@", row); [_databaseContext recordSnapshot: row forGlobalID: gid]; isObjectNew = YES; //TODO } } else { EOFLOGObjectLevelArgs(@"gsdb", @"database class=%@", [database class]); NSAssert(database, @"No database-context database"); [database recordSnapshot: row forGlobalID: gid]; } EOFLOGObjectLevelArgs(@"gsdb", @"[self isRefreshingObjects]=%d", (int)[self isRefreshingObjects]); //From mirko if ([self isRefreshingObjects] == YES) { [[NSNotificationCenter defaultCenter] postNotificationName: EOObjectsChangedInStoreNotification object: _databaseContext userInfo: [NSDictionary dictionaryWithObject: [NSArray arrayWithObject:gid] forKey: EOUpdatedKey]]; //OK ? } if (!object) { EOClassDescription *entityClassDescripton = [_currentEntity classDescriptionForInstances]; object = [entityClassDescripton createInstanceWithEditingContext: _currentEditingContext globalID: gid zone: NULL]; EOFLOGObjectLevelArgs(@"gsdb", @"object=%@", object); NSAssert1(object, @"No Object. entityClassDescripton=%@", entityClassDescripton); EOEditingContext_recordObjectGlobalIDWithImpPtr(_currentEditingContext, NULL,object,gid); } else if (object && [EOFault isFault: object]) { EOAccessFaultHandler *handler = (EOAccessFaultHandler *) [EOFault handlerForFault: object]; EOKeyGlobalID *handlerGID = (EOKeyGlobalID *)[handler globalID]; isObjectNew = YES; //TODO [handlerGID isFinal]; //YES //TODO [EOFault clearFault: object]; /*mirko: [_databaseContext _removeBatchForGlobalID:gid fault:obj]; [EOFault clearFault:obj]; */ } if (isObjectNew) //TODO { [EOObserverCenter suppressObserverNotification]; NS_DURING { EOFLOGObjectLevelArgs(@"gsdb", @"Initialize %p", object); [_currentEditingContext initializeObject: object withGlobalID: gid editingContext: _currentEditingContext]; } NS_HANDLER { [EOObserverCenter enableObserverNotification]; [localException raise]; } NS_ENDHANDLER; [EOObserverCenter enableObserverNotification]; [object awakeFromFetchInEditingContext: _currentEditingContext]; } } } EOFLOGObjectFnStop(); return object; }; - (BOOL)isFetchInProgress { return [_adaptorChannel isFetchInProgress]; } - (void)cancelFetch { EOFLOGObjectFnStart(); [self _cancelInternalFetch]; //TODO VERIFY - NO ??!! [_adaptorChannel cancelFetch]; [_fetchProperties removeAllObjects]; [_fetchSpecifications removeAllObjects]; EOFLOGObjectFnStop(); } - (EODatabaseContext *)databaseContext { return _databaseContext; } - (EOAdaptorChannel *)adaptorChannel { return _adaptorChannel; } - (BOOL)isRefreshingObjects { return _isRefreshingObjects; } - (void)setIsRefreshingObjects: (BOOL)yn { _isRefreshingObjects = yn; } - (BOOL)isLocking { return _isLocking; } - (void)setIsLocking: (BOOL)isLocking { _isLocking = isLocking; } - (void)setDelegate: delegate { _delegate = delegate; _delegateRespondsTo.shouldSelectObjects = [delegate respondsToSelector:@selector(databaseContext:shouldSelectObjectsWithFetchSpecification:databaseChannel:)]; _delegateRespondsTo.didSelectObjects = [delegate respondsToSelector:@selector(databaseContext:didSelectObjectsWithFetchSpecification:databaseChannel:)]; _delegateRespondsTo.shouldUsePessimisticLock = [delegate respondsToSelector:@selector(databaseContext:shouldUsePessimisticLockWithFetchSpecification: databaseChannel:)]; _delegateRespondsTo.shouldUpdateSnapshot = [delegate respondsToSelector:@selector(databaseContext:shouldUpdateCurrentSnapshot:newSnapshot:globalID:databaseChannel:)]; } - delegate { return _delegate; } @end @implementation EODatabaseChannel (EODatabaseChannelPrivate) - (NSArray*) _propertiesToFetch { //OK NSArray *attributesToFetch=nil; EOFLOGObjectFnStart(); attributesToFetch = [_currentEntity _attributesToFetch]; NSAssert(_currentEntity, @"No current Entity"); EOFLOGObjectFnStop(); return attributesToFetch; } -(void)_setCurrentEntityAndRelationshipWithFetchSpecification: (EOFetchSpecification *)fetch { //OK NSString *entityName = [fetch entityName]; EODatabase *database = [_databaseContext database]; EOEntity *entity = [database entityNamed: entityName]; NSAssert1(entity, @"No Entity named %@", entityName); [self setCurrentEntity: entity]; } - (void) _buildNodeList:(id) param0 withParent:(id) param1 { //TODO [self notImplemented: _cmd]; } - (id) currentEditingContext { return _currentEditingContext; } - (void) _cancelInternalFetch { //OK EOFLOGObjectFnStart(); if ([_adaptorChannel isFetchInProgress]) { [_adaptorChannel cancelFetch]; } EOFLOGObjectFnStop(); } - (void) _closeChannel { //TODO [self notImplemented: _cmd]; } - (void) _openChannel { //TODO [self notImplemented: _cmd]; } - (void)_selectWithFetchSpecification: (EOFetchSpecification *)fetch editingContext: (EOEditingContext *)context { NSArray *propertiesToFetch = nil; EOUpdateStrategy updateStrategy = EOUpdateWithOptimisticLocking; BOOL fetchLocksObjects = NO; BOOL refreshesRefetchedObjects = NO; NSString *entityName = nil; EODatabase *database = nil; EOEntity *entity = nil; NSArray *primaryKeyAttributes = nil; NSDictionary *hints = nil; EOModel *model = nil; EOModelGroup *modelGroup = nil; EOQualifier *qualifier = nil; EOStoredProcedure *storedProcedure = nil; id customQueryExpressionHint = nil;//TODO EOSQLExpression *customQueryExpression = nil;//TODO NSString *storedProcedureName = nil; BOOL isDeep = NO; NSArray *subEntities = nil; NSDictionary *_hints = nil; EOFLOGObjectFnStart(); _hints = [fetch _hints]; customQueryExpressionHint = [_hints objectForKey: EOCustomQueryExpressionHintKey];//TODO use it if (customQueryExpressionHint) { EOAdaptorContext *adaptorContext = nil; EOAdaptor *adaptor = nil; Class expressionClass = Nil; EOFLOGObjectLevelArgs(@"gsdb", @"customQueryExpressionHint=%@", customQueryExpressionHint); adaptorContext = [_databaseContext adaptorContext]; EOFLOGObjectLevelArgs(@"gsdb", @"adaptorContext=%p", adaptorContext); adaptor = [adaptorContext adaptor]; EOFLOGObjectLevelArgs(@"gsdb", @"adaptor=%p", adaptor); EOFLOGObjectLevelArgs(@"gsdb", @"adaptor=%@", adaptor); EOFLOGObjectLevelArgs(@"gsdb", @"adaptor class=%@", [adaptor class]); //TODO VERIFY expressionClass = [adaptor expressionClass]; EOFLOGObjectLevelArgs(@"gsdb", @"expressionClass=%@", expressionClass); customQueryExpression = [expressionClass expressionForString: customQueryExpressionHint]; EOFLOGObjectLevelArgs(@"gsdb", @"customQueryExpression=%@", customQueryExpression); } [self setCurrentEditingContext: context]; //OK even if customQueryExpressionHintKey [self _setCurrentEntityAndRelationshipWithFetchSpecification: fetch]; isDeep = [fetch isDeep]; //ret 1 if (!customQueryExpressionHint) { subEntities = [entity subEntities]; EOFLOGObjectLevelArgs(@"gsdb", @"subEntities=%@", subEntities); //Strange { NSMutableArray *array = nil; array = [NSMutableArray arrayWithCapacity: 8]; if ([subEntities count] > 0 && isDeep) { //?? NSEnumerator *subEntitiesEnum = [subEntities objectEnumerator]; id subEntity = nil; while ((subEntity = [subEntitiesEnum nextObject])) { EOFetchSpecification *fetchSubEntity; fetchSubEntity = [fetch copy]; [fetchSubEntity setEntityName: [entity name]]; [array addObjectsFromArray: [context objectsWithFetchSpecification: fetchSubEntity]]; [fetchSubEntity release]; } } } } propertiesToFetch = [self _propertiesToFetch]; updateStrategy = [_databaseContext updateStrategy];//Ret 0 fetchLocksObjects = [fetch locksObjects]; refreshesRefetchedObjects = [fetch refreshesRefetchedObjects]; entityName = [fetch entityName]; database = [_databaseContext database]; entity = [database entityNamed:entityName]; primaryKeyAttributes = [entity primaryKeyAttributes]; hints = [fetch hints]; // ret {} storedProcedureName = [hints objectForKey: EOStoredProcedureNameHintKey];//TODO use it model = [entity model]; modelGroup = [model modelGroup]; //ret nil //TODO if model gr qualifier = [fetch qualifier]; // //Can be nil if (customQueryExpression) { [_adaptorChannel evaluateExpression: customQueryExpression]; NSAssert([propertiesToFetch count] > 0, @"No properties to fetch"); [_adaptorChannel setAttributesToFetch: propertiesToFetch]; } else { storedProcedure = [entity storedProcedureForOperation: @"EOFetchWithPrimaryKeyProcedure"]; if (storedProcedure) { NSEmitTODO(); //TODO [self notImplemented: _cmd]; } NSAssert([propertiesToFetch count] > 0, @"No properties to fetch"); EOFLOGObjectLevelArgs(@"gsdb", @"%@ -- %@ 0x%x: isFetchInProgress=%s", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, ([self isFetchInProgress] ? "YES" : "NO")); [_adaptorChannel selectAttributes: propertiesToFetch fetchSpecification: fetch lock: fetchLocksObjects entity: entity]; } EOFLOGObjectLevelArgs(@"gsdb", @"%@ -- %@ 0x%x: isFetchInProgress=%s", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, ([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 format:@"%@ -- %@ 0x%x: no transaction in progress", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self]; if(_delegateRespondsTo.shouldSelectObjects) { if(![_delegate databaseContext:_databaseContext shouldSelectObjectsWithFetchSpecification:fetch databaseChannel:self]) [NSException raise:EOGeneralDatabaseException format:@"%@ -- %@ 0x%x: delegate refuses to select objects", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self]; }; [_fetchSpecifications addObject:fetch]; // [self setCurrentEntity:[[_databaseContext database] // entityNamed:[fetch entityName]]];//done // [self setCurrentEditingContext:context];//done [self setIsLocking:([_databaseContext updateStrategy] == EOUpdateWithPessimisticLocking ? YES : [fetch locksObjects])]; [self setIsRefreshingObjects:[fetch refreshesRefetchedObjects]]; // attributesToFetch = [_currentEntity attributesToFetch];//done // EOFLOGObjectLevelArgs(@"gsdb",@"[_adaptorChannel class]: %@",[_adaptorChannel class]); // [_adaptorChannel selectAttributes:attributesToFetch // fetchSpecification:fetch // lock:_isLocking // entity:_currentEntity];//done [_fetchProperties addObjectsFromArray:[self _propertiesToFetch]]; if(_delegateRespondsTo.didSelectObjects) [_delegate databaseContext:_databaseContext didSelectObjectsWithFetchSpecification:fetch databaseChannel:self]; EOFLOGObjectFnStop(); } @end /* EODatabaseChannel */ gnustep-dl2-0.12.0/EOAccess/EODatabaseOperation.m0000644000175000017500000002012110645346232020403 0ustar ayersayers/** EOAdaptorOperation.m EOAdaptorOperation Class Copyright (C) 2000-2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 $Revision: 25326 $ $Date: 2007-07-12 08:39:22 +0200 (Don, 12. Jul 2007) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EODatabaseOperation.m 25326 2007-07-12 06:39:22Z ayers $") #ifdef GNUSTEP #include #include #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #include #include #endif #include #include #include #include #include "EOEntityPriv.h" @implementation EODatabaseOperation + (EODatabaseOperation *)databaseOperationWithGlobalID: (EOGlobalID *)globalID object: (id)object entity: (EOEntity *)entity { return [[[self alloc] initWithGlobalID: globalID object: object entity: entity] autorelease]; } - (id) initWithGlobalID: (EOGlobalID *)globalID object: (id)object entity: (EOEntity *)entity { if ((self = [super init])) { ASSIGN(_object, object); ASSIGN(_globalID, globalID); ASSIGN(_entity, entity); //_newRow = [NSMutableDictionary new];//still nil //_toManySnapshots = [NSMutableDictionary new];//TODO no: still nil } return self; } - (void)dealloc { DESTROY(_newRow); DESTROY(_globalID); DESTROY(_entity); DESTROY(_adaptorOps); DESTROY(_object); DESTROY(_dbSnapshot); DESTROY(_toManySnapshots); [super dealloc]; } - (NSDictionary *)dbSnapshot { EOFLOGObjectFnStart(); NSDebugMLLog(@"gsdb", @"dbOpe %@ snapshot %p=%@", self, _dbSnapshot, _dbSnapshot); EOFLOGObjectFnStop(); return _dbSnapshot; } - (void)setDBSnapshot: (NSDictionary *)dbSnapshot { EOFLOGObjectFnStart(); ASSIGN(_dbSnapshot, dbSnapshot); NSDebugMLLog(@"gsdb", @"dbOpe %@ snapshot %p=%@", self, _dbSnapshot, _dbSnapshot); if (dbSnapshot) [_newRow addEntriesFromDictionary: dbSnapshot]; NSDebugMLLog(@"gsdb", @"dbOpe %@", self); EOFLOGObjectFnStop(); } - (NSMutableDictionary *)newRow { return _newRow; } - (void)setNewRow: (NSMutableDictionary *)newRow { ASSIGN(_newRow, newRow); } - (EOGlobalID *)globalID { return _globalID; } - (id)object { return _object; } - (EOEntity *)entity { return _entity; } - (EODatabaseOperator)databaseOperator { return _databaseOperator; } - (void)setDatabaseOperator: (EODatabaseOperator)dbOpe { BOOL setOpe = YES; //Don't set Update if it's alreay insert if (dbOpe == EODatabaseUpdateOperator) { if (_databaseOperator==EODatabaseInsertOperator || _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; } - (NSDictionary *)rowDiffs { //OK NSMutableDictionary *row = nil; NSEnumerator *newRowEnum = nil; NSString *key = nil; EOFLOGObjectFnStart(); NSDebugMLLog(@"gsdb", @"self %p=%@", self, self); newRowEnum= [_newRow keyEnumerator]; while ((key = [newRowEnum nextObject])) { if (![_entity anyRelationshipNamed: key]) //Don't care about relationships { id value = [_newRow objectForKey: key]; if ([value isEqual: [_dbSnapshot objectForKey: key]] == NO) { if (!row) row = (NSMutableDictionary*)[NSMutableDictionary dictionary]; [row setObject: value forKey: key]; } } } NSDebugMLLog(@"gsdb", @"diff row %p=%@", row, row); EOFLOGObjectFnStop(); return row; } - (NSDictionary*)rowDiffsForAttributes: (NSArray*)attributes { //OK NSMutableDictionary *row = nil; EOAttribute *attr = nil; NSEnumerator *attrsEnum = nil; EOFLOGObjectFnStart(); NSDebugMLLog(@"gsdb", @"self %p=%@", self, self); attrsEnum = [attributes objectEnumerator]; while ((attr = [attrsEnum nextObject])) { NSString *name = [attr name]; NSString *snapname = [_entity snapshotKeyForAttributeName: name]; id value = [_newRow objectForKey: name]; if (value && [value isEqual: [_dbSnapshot objectForKey: snapname]] == NO) { if (!row) row = (NSMutableDictionary*)[NSMutableDictionary dictionary]; [row setObject: value forKey: name]; } } NSDebugMLLog(@"gsdb", @"diff row %p=%@", row, row); EOFLOGObjectFnStop(); return row; } - (NSDictionary *)primaryKeyDiffs { //OK NSDictionary *row = nil; if (_databaseOperator == EODatabaseUpdateOperator) { NSArray *pkAttributes = [_entity primaryKeyAttributes]; row = [self rowDiffsForAttributes: pkAttributes]; } return row; } - (NSArray *)adaptorOperations { return _adaptorOps; } - (void)addAdaptorOperation: (EOAdaptorOperation *)adaptorOperation { //OK if (!_adaptorOps) _adaptorOps = [NSMutableArray new]; if (!adaptorOperation) { //TODO raise exception } else [_adaptorOps addObject: adaptorOperation]; } - (void)removeAdaptorOperation: (EOAdaptorOperation *)adaptorOperation { [_adaptorOps removeObject: adaptorOperation]; } - (void)recordToManySnapshot: (NSArray *)gids relationshipName: (NSString *)name { //OK ?? if (_toManySnapshots) [_toManySnapshots setObject: gids forKey: name];//TODO VERIFY else { _toManySnapshots = [NSMutableDictionary dictionaryWithObject: gids forKey: name]; RETAIN(_toManySnapshots); } } - (NSDictionary *)toManySnapshots { return _toManySnapshots; } - (NSString *)description { //TODO revoir NSString *operatorString = nil; NSString *desc = nil; EOFLOGObjectFnStart(); switch (_databaseOperator) { case EODatabaseNothingOperator: operatorString = @"EODatabaseNothingOperator"; break; case EODatabaseInsertOperator: operatorString = @"EODatabaseInsertOperator"; break; case EODatabaseUpdateOperator: operatorString = @"EODatabaseUpdateOperator"; break; case EODatabaseDeleteOperator: operatorString = @"EODatabaseDeleteOperator"; break; default: operatorString = @"Unknwon"; break; } desc = [NSString stringWithFormat: @"<%s %p : operator: %@ entity: %@ globalID:%@\nnewRow %p: %@\nobject %p: %@\ndbSnapshot %p: %@>", object_get_class_name(self), (void*)self, operatorString, [_entity name], _globalID, _newRow, _newRow, _object, _object, _dbSnapshot, _dbSnapshot]; EOFLOGObjectFnStop(); return desc; } @end //Mirko @implementation EODatabaseOperation (private) - (void)_setGlobalID: (EOGlobalID *)globalID { ASSIGN(_globalID, globalID); } @end gnustep-dl2-0.12.0/EOAccess/EOModel.m0000644000175000017500000014250111022071506016052 0ustar ayersayers/** EOModel.m EOModel Class Copyright (C) 2000-2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Manuel Guesdon Date: February 2000 $Revision: 26594 $ $Date: 2008-06-06 01:14:14 +0200 (Fre, 06. Jun 2008) $ 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 3 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "config.h" RCS_ID("$Id: EOModel.m 26594 2008-06-05 23:14:14Z ratmice $") #ifdef GNUSTEP #include #include #include #include #include #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "EOEntityPriv.h" #include "EOPrivate.h" #include "EOAttributePriv.h" #define DEFAULT_MODEL_VERSION 2 NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification"; @interface EOModel (EOModelPrivate) + (NSString *) _formatModelPath: (NSString *)path checkFileSystem: (BOOL)chkFS; - (EOEntity *) _verifyBuiltEntityObject: (id)entity named: (NSString *)name; @end /* EOModel (EOModelPrivate) */ @implementation EOModel + (EOModel*) model { return AUTORELEASE([[self alloc] init]); } + (NSString*) findPathForModelNamed: (NSString *)modelName { NSString *modelPath = nil; NSString *tmpModelName = nil; NSString *tmpPath = nil; NSBundle *bundle = nil; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSAllLibrariesDirectory, NSAllDomainsMask, YES); tmpModelName = [modelName lastPathComponent]; EOFLOGClassLevelArgs(@"gsdb", @"modelName=%@ tmpModelName=%@", modelName, tmpModelName); tmpPath = [[modelName stringByStandardizingPath] stringByDeletingLastPathComponent]; EOFLOGClassLevelArgs(@"gsdb", @"modelName=%@ tmpPath=%@", modelName, tmpPath); bundle = [NSBundle mainBundle]; modelPath = [bundle pathForResource: modelName ofType: @"eomodel"]; EOFLOGClassLevelArgs(@"gsdb", @"modelName=%@ modelPath=%@", modelName, modelPath); if (!modelPath) { modelPath = [bundle pathForResource: modelName ofType: @"eomodeld"]; EOFLOGClassLevelArgs(@"gsdb", @"modelName=%@ modelPath=%@", modelName, modelPath); if (!modelPath) { if ([tmpPath length] == 0) { tmpPath = @"./"; tmpPath = [tmpPath stringByStandardizingPath]; } if ([[tmpModelName pathExtension] length] != 0) tmpModelName = [tmpModelName stringByDeletingPathExtension]; EOFLOGClassLevelArgs(@"gsdb", @"modelName=%@ tmpPath=%@ tmpModelName=%@", modelName, tmpPath, tmpModelName); bundle = [NSBundle bundleWithPath: tmpPath]; modelPath = [bundle pathForResource: tmpModelName ofType: @"eomodel"]; EOFLOGClassLevelArgs(@"gsdb", @"modelName=%@ modelPath=%@", modelName, modelPath); if (!modelPath) { modelPath = [bundle pathForResource: tmpModelName ofType: @"eomodeld"]; EOFLOGClassLevelArgs(@"gsdb", @"modelName=%@ modelPath=%@", modelName, modelPath); if (!modelPath) { int i, pathCount = [paths count]; for (i = 0; !modelPath && pathCount < i; i++) { EOFLOGClassLevelArgs(@"gsdb", @"Trying path:%@", [paths objectAtIndex:i]); bundle = [NSBundle bundleWithPath: [paths objectAtIndex:i]]; modelPath = [bundle pathForResource: modelName ofType: @"eomodel"]; EOFLOGClassLevelArgs(@"gsdb", @"modelName=%@ modelPath=%@", modelName, modelPath); if (!modelPath) { modelPath = [bundle pathForResource: modelName ofType: @"eomodeld"]; EOFLOGClassLevelArgs(@"gsdb", @"modelName=%@ modelPath=%@", modelName, modelPath); } } } } } } return modelPath; } - (id)init { EOFLOGObjectFnStart(); if ((self = [super init])) { // Turbocat _version = DEFAULT_MODEL_VERSION; _entitiesByName = [NSMutableDictionary new]; _entitiesByClass = NSCreateMapTableWithZone(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 8, [self zone]); _storedProcedures = [NSMutableArray new]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_classDescriptionNeeded:) name: EOClassDescriptionNeededNotification object: nil]; //No ? [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_classDescriptionNeeded:) name: EOClassDescriptionNeededForClassNotification object: nil]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_classDescriptionNeeded:) name: EOClassDescriptionNeededForEntityNameNotification object: nil]; [EOClassDescription invalidateClassDescriptionCache]; } EOFLOGObjectFnStop(); return self; } - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver: self]; [[self entities] makeObjectsPerformSelector:@selector(_setModel:) withObject:nil]; if (_entitiesByClass) { NSFreeMapTable(_entitiesByClass); _entitiesByClass = NULL; } DESTROY(_storedProcedures); DESTROY(_entitiesByName); DESTROY(_entities); DESTROY(_name); DESTROY(_path); DESTROY(_adaptorName); DESTROY(_connectionDictionary); DESTROY(_userInfo); DESTROY(_internalInfo); DESTROY(_docComment); [super dealloc]; } - (NSString*) path { return _path; } - (NSString*) name { return _name; } - (NSString*) adaptorName { return _adaptorName; } - (NSString*) adaptorClassName { return _adaptorClassName; } - (EOEntity*) entityNamed: (NSString *)name { EOEntity *entity = nil; NSAssert(name,@"No entity name"); entity = [_entitiesByName objectForKey: name]; if (entity != nil) { entity = [self _verifyBuiltEntityObject: entity named: name]; } return entity; } - (NSArray*) entities { //TODO revoir ? if (!_entities) { NSArray *entityNames = [self entityNames]; ASSIGN(_entities, [self resultsOfPerformingSelector: @selector(entityNamed:) withEachObjectInArray: entityNames]); } return _entities; } - (NSArray*) entityNames { return [[_entitiesByName allKeys] sortedArrayUsingSelector: @selector(compare:)]; } - (NSArray *)storedProcedureNames { /* We do not load procedures lazy so we can rely on the instance variable. */ return [_storedProcedures valueForKey: @"name"]; } - (EOStoredProcedure*)storedProcedureNamed: (NSString *)name { EOStoredProcedure *proc; NSString *procName; unsigned i,n; n = [_storedProcedures count]; for (i=0; i 0) { EOAdaptor *adaptor; adaptor = [EOAdaptor adaptorWithName: _adaptorName]; attributes = [adaptor prototypeAttributes]; } else attributes = [entity attributes]; EOFLOGObjectLevelArgs(@"gsdb", @"entity=%@ - attributes=%@", entity, attributes); if (attributes) { count = [attributes count]; for (i = 0; i < count; i++) { attribute = [attributes objectAtIndex: i]; if ([[attribute name] isEqualToString: attributeName]) break; } } EOFLOGObjectLevelArgs(@"gsdb", @"attribute=%@", attribute); EOFLOGObjectFnStop(); return attribute; } @end @implementation EOModel (EOModelFileAccess) + (EOModel*) modelWithContentsOfFile: (NSString *)path { return AUTORELEASE([[self alloc] initWithContentsOfFile: path]); } - (id) initWithContentsOfFile: (NSString *)path { NS_DURING { NSString *name = nil; NSString *modelPath = nil; NSString *indexPath = nil; NSString *fileContents = nil; NSDictionary *propList = nil; path = [path stringByStandardizingPath]; modelPath = [isa _formatModelPath: path checkFileSystem: YES]; NSAssert1(modelPath!=nil, @"Model does not exist at path %@", path ); name = [[modelPath lastPathComponent] stringByDeletingPathExtension]; [self setName: name]; if ([[modelPath pathExtension] isEqualToString: @"eomodeld"]) { indexPath = [modelPath stringByAppendingPathComponent: @"index.eomodeld"]; } else { indexPath = modelPath; } fileContents = [NSString stringWithContentsOfFile: indexPath]; NSAssert1(fileContents!=nil, @"File %@ could not be read.", indexPath); propList = [fileContents propertyList]; EOFLOGObjectLevelArgs(@"gsdb", @"propList=%@", propList); NSAssert1(propList!=nil, @"Model at path %@ is invalid", indexPath); self = [self initWithTableOfContentsPropertyList: propList path: modelPath]; NSAssert2(self!=nil,@"Failed to initialize with path %@ and plist %@", modelPath, propList); } NS_HANDLER { NSLog(@"exception in EOModel initWithContentsOfFile:"); NSLog(@"exception=%@", localException); [localException raise]; } NS_ENDHANDLER; return self; } /** *

Writes the receivers plist representation into an * .eomodeld file wrapper located at path.

*

Depending on the the path extension .eomodeld or .eomodel * the corresponding format will be used. * If the path has neither .eomodeld nor .eomodel path * extension, .eomodeld will be used.

*

If the file located at path already exists, a back is created * by appending a '~' character to file name. * If a backup file already exists, when trying to create a backup, * the old backup will be deleted.

*

If any of the file operations fail, an NSInvalidArgumentException * will be raised.

*

This method as the side effeect of setting the receivers path and * name. The this change can happen even if the write operation fails * with an exception.

*/ - (void)writeToFile: (NSString *)path { NSFileManager *mgr = [NSFileManager defaultManager]; NSMutableDictionary *pList; NSDictionary *entityPList; NSDictionary *stProcPList; NSEnumerator *entityEnum; NSEnumerator *stProcEnum; NSString *fileName; NSString *extension; BOOL writeSingleFile; [self loadAllModelObjects]; path = [path stringByStandardizingPath]; extension = [path pathExtension]; if ([extension isEqualToString: @"eomodeld"] == NO && [extension isEqualToString: @"eomodel"] == NO) { path = [path stringByAppendingPathExtension: @"eomodeld"]; extension = [path pathExtension]; } writeSingleFile = [extension isEqualToString: @"eomodel"] ? YES : NO; if ([mgr fileExistsAtPath: path]) { NSString *backupPath; backupPath = [path stringByAppendingString: @"~"]; if ([mgr fileExistsAtPath: backupPath]) { if ([mgr removeFileAtPath: backupPath handler: nil] == NO) { NSString *fmt; fmt = [NSString stringWithFormat: @"Could not remove %@", backupPath]; [NSException raise: NSInvalidArgumentException format: fmt]; } } if ([mgr movePath: path toPath: backupPath handler: nil] == NO) { NSString *fmt; fmt = [NSString stringWithFormat: @"Could not move %@ to %@", path, backupPath]; [NSException raise: NSInvalidArgumentException format: fmt]; } } [self _setPath: path]; pList = [NSMutableDictionary dictionaryWithCapacity: 10]; [self encodeIntoPropertyList: pList]; if (writeSingleFile == NO && [mgr createDirectoryAtPath: path attributes: nil] == NO) { NSString *fmt; fmt = [NSString stringWithFormat: @"Could not create directory: %@", path]; [NSException raise: NSInvalidArgumentException format: fmt]; } entityEnum = [[pList objectForKey: @"entities"] objectEnumerator]; while (writeSingleFile == NO && (entityPList = [entityEnum nextObject])) { NSString *fileName; fileName = [path stringByAppendingPathComponent: [NSString stringWithFormat: @"%@.plist", [entityPList objectForKey: @"name"]]]; if ([entityPList writeToFile: fileName atomically: YES] == NO) { NSString *fmt; fmt = [NSString stringWithFormat: @"Could not create file: %@", fileName]; [NSException raise: NSInvalidArgumentException format: fmt]; } } stProcEnum = [[pList objectForKey: @"storedProcedures"] objectEnumerator]; while (writeSingleFile == NO && (stProcPList = [stProcEnum nextObject])) { NSString *fileName; fileName = [stProcPList objectForKey: @"name"]; fileName = [fileName stringByAppendingPathExtension: @"storedProcedure"]; fileName = [path stringByAppendingPathComponent: fileName]; if ([stProcPList writeToFile: fileName atomically: YES] == NO) { NSString *fmt; fmt = [NSString stringWithFormat: @"Could not create file: %@", fileName]; [NSException raise: NSInvalidArgumentException format: fmt]; } } if (writeSingleFile == NO) { fileName = [path stringByAppendingPathComponent: @"index.eomodeld"]; [pList removeAllObjects]; [self encodeTableOfContentsIntoPropertyList: pList]; } else { fileName = path; } if ([pList writeToFile: fileName atomically: YES] == NO) { NSString *fmt; fmt = [NSString stringWithFormat: @"Could not create file: %@", fileName]; [NSException raise: NSInvalidArgumentException format: fmt]; } } @end @implementation EOModel (EOModelPropertyList) - (id)initWithTableOfContentsPropertyList: (NSDictionary *)tableOfContents path: (NSString *)path { //OK NS_DURING { if ((self = [self init])) { NSString *modelPath; NSString *versionString = nil; NSArray *entities = nil; int i, count = 0; EOFLOGObjectLevelArgs(@"gsdb", @"tableOfContents=%@", tableOfContents); /* The call to _setPath: also sets the name implicitly. */ modelPath = [isa _formatModelPath: path checkFileSystem: YES]; [self _setPath: modelPath]; EOFLOGObjectLevelArgs(@"gsdb", @"name=%@ path=%@", _name, _path); versionString = [tableOfContents objectForKey: @"EOModelVersion"]; if (versionString) _version = [versionString floatValue]; else _version = 0; // dayers: is this correct? ASSIGN(_connectionDictionary, [tableOfContents objectForKey: @"connectionDictionary"]); ASSIGN(_adaptorName, [tableOfContents objectForKey: @"adaptorName"]); ASSIGN(_userInfo, [tableOfContents objectForKey: @"userInfo"]); if (!_userInfo) { ASSIGN(_userInfo, [tableOfContents objectForKey:@"userDictionary"]); } ASSIGN(_internalInfo, [tableOfContents objectForKey: @"internalInfo"]); ASSIGN(_docComment,[tableOfContents objectForKey:@"docComment"]); //VERIFY if (_version >= 2) { NSMutableDictionary *markSP = [NSMutableDictionary dictionary]; NSArray *storedProcedures = [tableOfContents objectForKey: @"storedProcedures"]; count = [storedProcedures count]; for (i = 0; i < count; i++) { EOStoredProcedure *proc; NSDictionary *plist; NSString *fileName; NSString *procName; NSString *fullPath; procName = [storedProcedures objectAtIndex: i]; fileName = [procName stringByAppendingPathExtension: @"storedProcedure"]; fullPath = [_path stringByAppendingPathComponent: fileName]; plist = [NSDictionary dictionaryWithContentsOfFile: fullPath]; NSAssert2([procName isEqual: [plist objectForKey: @"name"]], @"Name mismatch: index.plist: %@" @" *.storedProcedure: %@", procName, [plist objectForKey: @"name"]); [markSP setObject: plist forKey: procName]; proc = [EOStoredProcedure storedProcedureWithPropertyList: plist owner: self]; [self addStoredProcedure: proc]; } count = [_storedProcedures count]; for (i = 0; i < count; i++) { EOStoredProcedure *proc; NSString *name; NSDictionary *plist; proc = [_storedProcedures objectAtIndex: i]; name = [proc name]; plist = [markSP objectForKey: name]; if (plist) { [proc awakeWithPropertyList: plist]; } } } entities = [tableOfContents objectForKey: @"entities"]; count = [entities count]; for (i=0; i= 2) { NSString *fileName = [NSString stringWithFormat: @"%@.plist", [plist objectForKey: @"name"]]; plist = [[NSString stringWithContentsOfFile: [_name stringByAppendingPathComponent: fileName]] propertyList]; } [markEntities setObject: plist forKey: [plist objectForKey: @"name"]]; entity = AUTORELEASE([[EOEntity alloc] initWithPropertyList: plist owner: self]); [self addEntity: entity]; } /* Do not access _entities until cache is triggered */ enumerator = [[self entities] objectEnumerator]; while ((entity = [enumerator nextObject])) { NS_DURING { [entity awakeWithPropertyList: [markEntities objectForKey: [entity name]]]; } NS_HANDLER { [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: exception in model '%@' during awakeWithPropertyList: of entity '%@': %@", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, [self name], [entity name], [localException reason]]; } NS_ENDHANDLER; } if (_version >= 2) { count = [propListSt count]; for (i = 0; i < count; i++) { EOStoredProcedure *st; NSDictionary *plist; NSString *fileName; fileName = [NSString stringWithFormat: @"%@.storedProcedure", [[propListSt objectAtIndex: i] objectForKey: @"name"]]; plist = [[NSString stringWithContentsOfFile: [_name stringByAppendingPathComponent: fileName]] propertyList]; [markSP setObject: plist forKey: [plist objectForKey: @"name"]]; st = [EOStoredProcedure storedProcedureWithPropertyList: plist owner: self]; [self addStoredProcedure: st]; } enumerator = [_storedProcedures objectEnumerator]; while ((sp = [enumerator nextObject])) [sp awakeWithPropertyList: [markSP objectForKey: [sp name]]]; } } } NS_HANDLER { NSLog(@"exception in EOModel initWithPropertyList:owner:"); NSLog(@"exception=%@", localException); [localException raise]; } NS_ENDHANDLER; return self; } - (void)awakeWithPropertyList: (NSDictionary *)propertyList { return; } - (void)encodeIntoPropertyList: (NSMutableDictionary *)propertyList { int i, count; [propertyList setObject: [[NSNumber numberWithFloat: DEFAULT_MODEL_VERSION] stringValue] forKey: @"EOModelVersion"]; if (_name) [propertyList setObject: _name forKey: @"name"]; if (_adaptorName) [propertyList setObject: _adaptorName forKey: @"adaptorName"]; if (_adaptorClassName) [propertyList setObject: _adaptorClassName forKey: @"adaptorClassName"]; if (_connectionDictionary) [propertyList setObject: _connectionDictionary forKey: @"connectionDictionary"]; if (_userInfo) [propertyList setObject: _userInfo forKey: @"userInfo"]; if (_internalInfo) [propertyList setObject: _internalInfo forKey: @"internalInfo"]; if (_docComment) [propertyList setObject: _docComment forKey: @"docComment"]; /* Do not access _entities until cache is triggered */ count = [[self entities] count]; if (count > 0) { NSMutableArray *entitiesArray = [NSMutableArray arrayWithCapacity: count]; [propertyList setObject: entitiesArray forKey: @"entities"]; for (i = 0; i < count; i++) { NSMutableDictionary *entityPList = [NSMutableDictionary dictionary]; EOEntity *entity = [_entities objectAtIndex: i]; [entity encodeIntoPropertyList: entityPList]; [entitiesArray addObject: entityPList]; } } count = [_storedProcedures count]; if (count > 0) { NSMutableArray *stArray = [NSMutableArray arrayWithCapacity: count]; [propertyList setObject: stArray forKey: @"storedProcedures"]; for (i = 0; i < count; i++) { NSMutableDictionary *stPList = [NSMutableDictionary dictionary]; EOStoredProcedure *proc = [_storedProcedures objectAtIndex: i]; [proc encodeIntoPropertyList: stPList]; [stArray addObject: stPList]; } } } @end @implementation EOModel (EOModelHidden) -(void) _classDescriptionNeeded: (NSNotification *)notification { //TODO NSString *notificationName = nil; EOFLOGObjectFnStart(); notificationName = [notification name]; EOFLOGObjectLevelArgs(@"gsdb", @"notificationName=%@", notificationName); if ([notificationName isEqualToString: EOClassDescriptionNeededForClassNotification]) { Class aClass = [notification object]; EOClassDescription *classDescription = nil; EOEntity *entity = nil; NSString *entityClassName = nil; EOFLOGObjectLevelArgs(@"gsdb", @"notification=%@ aClass=%@", notification, aClass); NSAssert(aClass, @"No class"); entity = [self _entityForClass: aClass]; if (!entity) { NSAssert1((!GSObjCIsKindOf(aClass, [EOGenericRecord class])), @"No entity for class %@", aClass); } else { Class entityClass=Nil; classDescription = [entity classDescriptionForInstances]; EOFLOGObjectLevelArgs(@"gsdb", @"classDescription=%@", classDescription); entityClassName = [entity className]; EOFLOGObjectLevelArgs(@"gsdb",@"entityClassName=%@",entityClassName); entityClass=NSClassFromString(entityClassName); NSAssert1(entityClass,@"No entity class named '%@'",entityClassName); [EOClassDescription registerClassDescription: classDescription forClass: entityClass]; } } else if ([notificationName isEqualToString: EOClassDescriptionNeededForEntityNameNotification]) { //OK EOClassDescription *classDescription; NSString *entityName = [notification object]; EOEntity *entity = nil; NSString *entityClassName = nil; Class entityClass = Nil; EOFLOGObjectLevelArgs(@"gsdb", @"notification=%@", notification); EOFLOGObjectLevelArgs(@"gsdb", @"entityName=%@", entityName); NSAssert(entityName, @"No entity name");//?? entity = [self entityNamed: entityName]; NSAssert1(entity, @"No entity named %@", entityName);//?? classDescription = [entity classDescriptionForInstances]; EOFLOGObjectLevelArgs(@"gsdb", @"classDescription=%@", classDescription); entityClassName = [entity className]; EOFLOGObjectLevelArgs(@"gsdb", @"entityClassName=%@", entityClassName); entityClass=NSClassFromString(entityClassName); NSAssert1(entityClass,@"No entity class named '%@'",entityClassName); [EOClassDescription registerClassDescription: classDescription forClass:entityClass];//?? } else if ([notificationName isEqualToString: EOClassDescriptionNeededNotification]) { //TODO } else { //TODO } EOFLOGObjectFnStop(); } - (void) _resetPrototypeCache { // TODO [self notImplemented: _cmd]; } - (BOOL) isPrototypesEntity: (id)param0 { // TODO [self notImplemented: _cmd]; return NO; } - (id) _instantiatedEntities { // TODO [self notImplemented: _cmd]; return nil; } - (void) _setPath: (NSString*)path { //OK [self loadAllModelObjects]; [self willChange]; ASSIGN(_path, path); [self setName: [[path lastPathComponent] stringByDeletingPathExtension]]; } - (EOEntity*) _entityForClass: (Class)aClass { NSString *className; EOEntity *entity; EOFLOGObjectFnStart(); NSAssert(aClass, @"No class"); NSAssert(_entitiesByClass, @"No _entitiesByClass"); className = NSStringFromClass(aClass); EOFLOGObjectLevelArgs(@"gsdb", @"className=%@", className); entity = NSMapGet(_entitiesByClass, className); EOFLOGObjectLevelArgs(@"gsdb", @"entity class=%@", [entity class]); if (entity) { entity = [self _verifyBuiltEntityObject: entity named: nil]; EOFLOGObjectLevelArgs(@"gsdb", @"entity=%@", entity); } else { EOFLOGObjectLevelArgs(@"gsdb", @"entity for class named=%@ not found", className); EOFLOGObjectLevelArgs(@"gsdb", @"entities class names=%@", NSAllMapTableKeys(_entitiesByClass)); EOFLOGObjectLevelArgs(@"gsdb", @"entities entities names=%@", NSAllMapTableValues(_entitiesByClass)); EOFLOGObjectLevelArgs(@"gsdb", @"entities map=%@", NSStringFromMapTable(_entitiesByClass)); } EOFLOGObjectFnStop(); return entity; } - (id) _childrenForEntityNamed: (id)param0 { // TODO [self notImplemented:_cmd]; return nil; } - (void) _registerChild: (id)param0 forParent: (id)param1 { // TODO [self notImplemented:_cmd]; return; } - (void) _setInheritanceLinks: (id)param0 { // TODO [self notImplemented: _cmd]; return; } - (void) _removeEntity: (EOEntity *)entity { //should be ok NSString *entityName = nil; NSString *entityClassName = nil; if ([entity isKindOfClass: [EOEntity class]]) { entityName = [entity name]; entityClassName = [entity className]; } else { entityName = [(NSDictionary *)entity objectForKey: @"name"]; entityClassName = [(NSDictionary *)entity objectForKey: @"className"]; } [_entitiesByName removeObjectForKey: entityName]; if (_entitiesByClass) NSMapRemove(_entitiesByClass, entityClassName); DESTROY(_entities); } - (EOEntity*) _addEntityWithPropertyList: (NSDictionary*)propertyList { //OK id children = nil; EOEntity *entity = nil; NSAssert(propertyList, @"no propertyList"); EOFLOGObjectLevelArgs(@"gsdb", @"propertyList=%@", propertyList); entity = AUTORELEASE([[EOEntity alloc] initWithPropertyList: propertyList owner: self]); NSAssert2([entity className], @"Entity %p named %@ has no class name", entity, [entity name]); entity = [self _addEntity: entity]; children = [self _childrenForEntityNamed: [entity name]]; if (children) { [self notImplemented: _cmd];//TODO //may be: self _registerChild:(id)param0 // forParent:entity... } [entity awakeWithPropertyList:propertyList]; [[NSNotificationCenter defaultCenter] postNotificationName: @"EOEntityLoadedNotification" object: entity]; return entity; } - (void) _addFakeEntityWithPropertyList: (NSDictionary*)propertyList { //OK NSString *entityName; NSString *className; NSAssert(propertyList, @"no propertyList"); entityName = [propertyList objectForKey: @"name"]; className = [propertyList objectForKey: @"className"]; NSAssert1(entityName, @"No entity name in %@", propertyList); NSAssert1(className, @"No class name in %@", propertyList); [self _setEntity: propertyList forEntityName: entityName className: className]; DESTROY(_entities); //To force rebuild } - (id) _addEntity: (EOEntity*)entity { //Seems OK NSString *entityClassName; NSAssert(entity, @"No entity to add"); EOFLOGObjectLevelArgs(@"gsdb", @"model _addEntity=%@", [entity name]); entityClassName = [entity className]; NSAssert2(entityClassName, @"Entity %p named %@ has no class name", entity, [entity name]); //May be returning a previous entity of that name if any ? [self _setEntity: entity forEntityName: [entity name] className: entityClassName]; [entity _setModel: self]; return entity; } //entity can be a EOEntity or an entity PList - (void) _setEntity: (id)entity forEntityName: (NSString*)entityName className: (NSString*)className { NSAssert(entityName, @"No entity name"); NSAssert(className, @"No class name"); NSAssert1([_entitiesByName objectForKey: entityName] == nil, @"Entity '%@' is already registered with this model", entityName); //Seems OK [_entitiesByName setObject: entity forKey: entityName]; NSAssert(_entitiesByClass, @"No entities by class"); if (NSMapGet(_entitiesByClass, className)) NSMapRemove(_entitiesByClass, className); NSMapInsertIfAbsent(_entitiesByClass, className, entity); } @end @implementation EOModel (EOModelEditing) - (void) setName: (NSString *)name { if (![name isEqualToString: _name]) { EOModelGroup *group; AUTORELEASE(RETAIN(self)); group = [self modelGroup]; if (group) { [group removeModel: self]; } [self willChange]; ASSIGNCOPY(_name, name); if (group) { [group addModel: self]; } } } - (void) setAdaptorName: (NSString *)adaptorName { [self willChange]; ASSIGNCOPY(_adaptorName, adaptorName); } - (void) setConnectionDictionary: (NSDictionary *)connectionDictionary { [self willChange]; ASSIGN(_connectionDictionary, connectionDictionary); } - (void) setUserInfo: (NSDictionary *)userInfo { [self willChange]; ASSIGN(_userInfo, userInfo); } - (void) setDocComment: (NSString *)docComment { [self willChange]; ASSIGNCOPY(_docComment, docComment); } - (void) addEntity: (EOEntity *)entity { NSString *entityName = [entity name]; // void *entitiesClass; // int count; NSString *className = nil; NSAssert1([self entityNamed: [entity name]] == nil, @"Entity '%@' is already registered with this model", entityName); NSAssert2([entity model]==nil, @"Entity '%@' is already owned by model '%@'.", [entity name], [[entity model] name]); [self willChange]; /* Do not access _entities until cache is triggered */ [(NSMutableArray *)[self entities] addObject: entity]; NSAssert(_entitiesByClass, @"No _entitiesByClass"); className = [entity className]; NSAssert1(className, @"No className in %@", entity); if (NSMapGet(_entitiesByClass, className)) NSMapRemove(_entitiesByClass, className); NSMapInsertIfAbsent(_entitiesByClass, className, entity); [_entitiesByName setObject: entity forKey: entityName]; [entity _setModel: self]; } - (void) removeEntity: (EOEntity *)entity { NSString *className = nil; /* as a special case this method can call _setModel: with nil */ [entity _setModel: nil]; [_entitiesByName removeObjectForKey: [entity name]]; NSAssert(_entitiesByClass, @"No _entitiesByClass"); className = [entity className]; NSAssert1(className, @"No className in %@", entity); [self willChange]; NSMapRemove(_entitiesByClass, className); /* Do not access _entities until cache is triggered */ [(NSMutableArray *)[self entities] removeObject: entity]; } - (void) removeEntityAndReferences: (EOEntity *)entity { [self removeEntity: entity]; // TODO; } - (void)addStoredProcedure: (EOStoredProcedure *)storedProcedure { if ([self storedProcedureNamed: [storedProcedure name]]) [NSException raise: NSInvalidArgumentException format: @"%@ -- %@ 0x%x: \"%@\" already registered as stored procedure name ", NSStringFromSelector(_cmd), NSStringFromClass([self class]), self, [storedProcedure name]]; NSAssert(_storedProcedures, @"Uninitialised _storedProcedures!"); [self willChange]; [(NSMutableArray *)_storedProcedures addObject: storedProcedure]; } - (void)removeStoredProcedure: (EOStoredProcedure *)storedProcedure { NSAssert(_storedProcedures, @"Uninitialised _storedProcedures!"); [self willChange]; [(NSMutableArray *)_storedProcedures removeObject: storedProcedure]; } - (void) setModelGroup: (EOModelGroup *)group { EOFLOGObjectFnStart(); //call group _addSubEntitiesCache: _group = group; EOFLOGObjectFnStop(); } - (void)loadAllModelObjects { NSArray *entityNames = [_entitiesByName allKeys]; unsigned i,n = [entityNames count]; for (i=0; i 0)) { listItems = [_name componentsSeparatedByString: @"_"]; newString = [newString stringByAppendingString: [(NSString *)[listItems objectAtIndex: 0] lowercaseString]]; anz = [listItems count]; for (i = 1; i < anz; i++) { newString = [newString stringByAppendingString: [(NSString *)[listItems objectAtIndex: i] capitalizedString]]; } // Exception abfangen NS_DURING { // Model Name [self setName: newString]; // Entites /* Do not access _entities until cache is triggered */ if ([self entities] && (count = [_entities count])) { for (i = 0; i < count; i++) [(EOEntity *)[_entities objectAtIndex:i] beautifyName]; } } NS_HANDLER NSLog(@"%@ in Class: EOEntity , Method: beautifyName >> error : %@", [localException name], [localException reason]); NS_ENDHANDLER; } EOFLOGObjectFnStopOrCond2(@"ModelingClasses", @"EOModel"); } @end @implementation EOModel (EOModelPrivate) /** * Returns a string that can be uses as a model path to load or save * the model. If chkFS is YES, then the path is searched. If path * does not include a path extension then first .eomodeld checked. If that * fails then .eomodel is searched. Call this method to format the path * provided before saving the model with chkFS NO. Call this method to * format the path provided before loading a model with chkFS YES. */ + (NSString *) _formatModelPath: (NSString *)path checkFileSystem: (BOOL)chkFS { NSFileManager *fileManager; NSString *lastPathComponent = nil; NSString *pathExtension = nil; NSString *searchPath = path; NSString *returnPath = path; lastPathComponent = [path lastPathComponent]; pathExtension = [lastPathComponent pathExtension]; if ([lastPathComponent isEqualToString: @"index.eomodeld"] == NO) { if ([pathExtension isEqualToString: @"eomodeld"] == NO) { searchPath = [searchPath stringByAppendingPathExtension: @"eomodeld"]; } searchPath = [searchPath stringByAppendingPathComponent: @"index.eomodeld"]; } searchPath = [searchPath stringByStandardizingPath]; if (chkFS==YES) { fileManager = [NSFileManager defaultManager]; if ([fileManager fileExistsAtPath: searchPath] == YES) { returnPath = searchPath; } else { searchPath = path; if ([pathExtension isEqualToString: @"eomodel"] == NO) { searchPath = [searchPath stringByAppendingPathComponent: @"eomodel"]; } searchPath = [searchPath stringByStandardizingPath]; if ([fileManager fileExistsAtPath: searchPath] == YES) { returnPath = searchPath; } } NSAssert1(returnPath!=nil,@"No valid Model found at path:%@", path); } else { returnPath = searchPath; } lastPathComponent = [returnPath lastPathComponent]; if ([lastPathComponent isEqualToString: @"index.eomodeld"] == YES) { returnPath = [returnPath stringByDeletingLastPathComponent]; } return returnPath; } - (EOEntity *) _verifyBuiltEntityObject: (id)entity named: (NSString*)name { if ([entity isKindOfClass: [EOEntity class]] == NO) { [EOObserverCenter suppressObserverNotification]; NS_DURING { NSString *basePath = nil; NSString *plistPathName = nil; NSDictionary *propList = nil; EOFLOGObjectLevelArgs(@"gsdb", @"name=%@", name); if (!name && [entity isKindOfClass: [NSDictionary class]]) name = [entity objectForKey: @"name"]; EOFLOGObjectLevelArgs(@"gsdb", @"name=%@", name); NSAssert1(name, @"No name for entity %@", entity); EOFLOGObjectLevelArgs(@"gsdb", @"[self path]=%@", [self path]); basePath = [self path]; AUTORELEASE(RETAIN(entity)); //so it won't be lost in _removeEntity EOFLOGObjectLevelArgs(@"gsdb", @"basePath =%@", basePath); if ([basePath hasSuffix: @"eomodel"]) { propList = entity; } else { plistPathName = [[basePath stringByAppendingPathComponent: name] stringByAppendingPathExtension: @"plist"]; EOFLOGObjectLevelArgs(@"gsdb", @"entity plistPathName =%@", plistPathName); propList = [NSDictionary dictionaryWithContentsOfFile: plistPathName]; EOFLOGObjectLevelArgs(@"gsdb", @"entity propList=%@", propList); if (!propList) { if ([[NSFileManager defaultManager] fileExistsAtPath: plistPathName]) { NSAssert1(NO, @"%@ is not a dictionary or is not readable.", plistPathName); } else { propList = entity; NSWarnLog(@"%@ doesn't exists. Using %@", plistPathName, propList); } } } [self _removeEntity: entity]; EOFLOGObjectLevelArgs(@"gsdb", @"entity propList=%@", propList); entity = [self _addEntityWithPropertyList: propList]; } NS_HANDLER { [EOObserverCenter enableObserverNotification]; [localException raise]; } NS_ENDHANDLER; [EOObserverCenter enableObserverNotification]; } return entity; } /* This method rebuilds the caches: _entitiesByName, _subEntitiesCache, _entitiesByClass from _entities. Insure this works for real entities and dictionaries which could be contained in _entities. Also note that className need not be unique. */ - (void)_updateCache { NSArray *names; EOEntity *entity; NSString *className; unsigned int i,c; DESTROY(_subEntitiesCache); NSResetMapTable(_entitiesByClass); names = [_entities valueForKey: @"name"]; DESTROY(_entitiesByName); _entitiesByName = [[NSMutableDictionary alloc] initWithObjects: _entities forKeys: names]; for (i = 0, c = [_entities count]; i < c; i++) { entity = [_entities objectAtIndex: i]; /* entity or dictionary */ className = [entity valueForKey: @"className"]; NSMapInsertIfAbsent(_entitiesByClass, className, entity); } } @end /* EOModel (EOModelPrivate) */ gnustep-dl2-0.12.0/EOModeler/0000755000175000017500000000000011147475626014616 5ustar ayersayersgnustep-dl2-0.12.0/EOModeler/EOModelerApp.h0000644000175000017500000000506111011132314017213 0ustar ayersayers#ifndef __EOModelerApp_H__ #define __EOModelerApp_H__ /* -*-objc-*- EOModelerApp.h Copyright (C) 2005 Free Software Foundation, Inc. Author: Matt Rice Date: Apr 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 Lesser General Public License as published by the Free Software Foundation; either version 3 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef NeXT_GUI_LIBRARY #include #else #include #endif #include @class EOModelerApp; @class EOModelerEditor; @class EOModelerDocument; @class NSMutableArray; @class NSMutableDictionary; @class EODisplayGroup; @class NSTableColumn; GDL2MODELER_EXPORT NSString *EOMSelectionChangedNotification; GDL2MODELER_EXPORT EOModelerApp *EOMApp; GDL2MODELER_EXPORT NSString *EOMPropertyPboardType; @protocol EOMColumnProvider - (void) initColumn:(NSTableColumn *)tableColumn class:(Class)objectClass name:(NSString *)columnName displayGroup:(EODisplayGroup *)dg document:(EOModelerDocument *)document; @end @interface EOModelerApp : NSApplication { NSMutableArray *_documents; NSMutableDictionary *_columnsByClass; EOModelerEditor *_currentEditor; } - (EOModelerDocument *)activeDocument; - (EOModelerEditor *)currentEditor; - (void)setCurrentEditor:(EOModelerEditor *)editor; - (NSArray *)documents; - (void) addDocument:(EOModelerDocument *)document; - (void) removeDocument:(EOModelerDocument *)document; - (NSArray *)columnNamesForClass:(Class)aClass; - (id ) providerForName:(NSString *)name class:(Class)objectClass; - (void) registerColumnName:(NSString *)columnNames forClass:(Class)objectClass provider:(id )provider; - (void) registerColumnNames:(NSArray *)columnNames forClass:(Class)objectClass provider:(id )provider; - (EOModelerDocument *) documentWithPath:(NSString *)path; - (EOModelerDocument *) loadDocumentAtPath:(NSString *)path; @end #endif // __EOModelerApp_H__ gnustep-dl2-0.12.0/EOModeler/EOMInspectorController.m0000644000175000017500000001422411011152430021321 0ustar ayersayers/** EOMInspectorController.m EOMInspectorController Class Copyright (C) 2005 Free Software Foundation, Inc. Author: Matt Rice Date: April 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 Lesser General Public License as published by the Free Software Foundation; either version 3 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA **/ #include #include #include #include #ifdef NeXT_GUI_LIBRARY #include #else #include #include #include #include #include #include #endif #ifdef NeXT_Foundation_LIBRARY #include #else #include #include #include #endif static EOMInspectorController *_sharedInspectorController; static NSMatrix *_iconBar; @interface EOMInspectorController(Private) - (void) _selectionChanged:(NSNotification *)notif; @end @implementation EOMInspectorController - (id) init { NSButtonCell *iconCell; NSSize scrollSize; if (_sharedInspectorController) [[NSException exceptionWithName: NSInternalInconsistencyException reason: @"EOMInspectorController is a singleton" userInfo:nil] raise]; self = [super init]; scrollSize = [NSScrollView frameSizeForContentSize:NSMakeSize(256, 64) hasHorizontalScroller:YES hasVerticalScroller:NO borderType:NSNoBorder]; window = [[NSPanel alloc] initWithContentRect:NSMakeRect(220, 536, 272, 388+scrollSize.height) styleMask:NSTitledWindowMask | NSClosableWindowMask backing:NSBackingStoreBuffered defer:YES]; [window setReleasedWhenClosed:NO]; scrollView = [[NSScrollView alloc] initWithFrame: NSMakeRect(0, 388, 272, scrollSize.height)]; scrollSize = [NSScrollView contentSizeForFrameSize:NSMakeSize(256,64) hasHorizontalScroller:YES hasVerticalScroller:NO borderType:NSNoBorder]; [scrollView setHasHorizontalScroller:YES]; [scrollView setHasVerticalScroller:NO]; _iconBar = [[NSMatrix alloc] initWithFrame:NSMakeRect(0, 0, 272, scrollSize.height)]; [_iconBar setAutosizesCells:NO]; [_iconBar setCellSize:NSMakeSize(64,64)]; [_iconBar setTarget:self]; [_iconBar setAction:@selector(_selectInspector:)]; iconCell = [[NSButtonCell alloc] initTextCell:@""]; [iconCell setButtonType:NSMomentaryPushInButton]; [iconCell setImagePosition:NSImageOnly]; [_iconBar setPrototype:iconCell]; [scrollView setDocumentView: _iconBar]; [[window contentView] addSubview: scrollView]; _sharedInspectorController = self; [[NSNotificationCenter defaultCenter] addObserver:_sharedInspectorController selector:@selector(_selectionChanged:) name:EOMSelectionChangedNotification object:nil]; return self; } - (void) _showInspector { [window makeKeyAndOrderFront:self]; [self _selectionChanged:nil]; } + (void) showInspector { [[self sharedInstance] _showInspector]; } + (EOMInspectorController *)sharedInstance { if (!_sharedInspectorController) return [[self alloc] init]; return _sharedInspectorController; } - (void) _selectionChanged:(NSNotification *)notif { NSArray *swvop = [[EOMApp currentEditor] selectionWithinViewedObject]; id inspector; if ([swvop count]) { /* inspectors is ordered in the lowest -displayOrder first. */ id selection = [swvop objectAtIndex:0]; NSArray *inspectors; int i, c; inspectors = [EOMInspector allInspectorsThatCanInspectObject: selection]; c = [inspectors count]; [_iconBar renewRows:1 columns:c]; [_iconBar setNeedsDisplay:YES]; if (c) { for (i = 0; i < c; i++) { NSCell *aCell = [_iconBar cellAtRow:0 column:i]; inspector = [inspectors objectAtIndex:i]; [aCell setImage:[inspector image]]; [aCell setRepresentedObject:inspector]; } [_iconBar setNeedsDisplay:YES]; /* if the current inspector can support the object, select it instead. Otherwise select the first inspector. */ if ([inspectors containsObject:lastInspector]) { inspector = lastInspector; [inspector prepareForDisplay]; } else { inspector = [inspectors objectAtIndex:0]; [inspector prepareForDisplay]; if ([lastInspector view] && lastInspector != inspector) [[lastInspector view] removeFromSuperview]; if ([inspector view] && lastInspector != inspector) [[window contentView] addSubview:[inspector view]]; [window setTitle:[inspector displayName]]; } [[inspector view] setNeedsDisplay:YES]; [inspector refresh]; lastInspector = inspector; } else { [[lastInspector view] removeFromSuperview]; lastInspector = nil; NSLog(@"no inspector"); } } else { [[lastInspector view] removeFromSuperview]; lastInspector = nil; NSLog(@"no selection"); } } - (void) _selectInspector:(id)sender { EOMInspector *inspector = [[sender selectedCell] representedObject]; [inspector prepareForDisplay]; if ([lastInspector view] && lastInspector != inspector) [[lastInspector view] removeFromSuperview]; if ([inspector view] && lastInspector != inspector) [[window contentView] addSubview:[inspector view]]; [[inspector view] setNeedsDisplay:YES]; [inspector refresh]; lastInspector = inspector; } @end gnustep-dl2-0.12.0/EOModeler/EODefines.h0000644000175000017500000000330010752273016016552 0ustar ayersayers/* -*-objc-*- EODefines.h Copyright (C) 2005 Free Software Foundation, Inc. Author: Matt Rice Date: Apr 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 Lesser General Public License as published by the Free Software Foundation; either version 3 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __EOModeler_EODefines_h__ #define __EOModeler_EODefines_h__ #ifdef __cplusplus extern "C" { #endif #ifdef GNUSTEP_WITH_DLL #if BUILD_libEOModeler_DLL # if defined(__MINGW32__) /* On Mingw, the compiler will export all symbols automatically, so * __declspec(dllexport) is not needed. */ # define GDL2MODELER_EXPORT extern # define GDL2MODELER_DECLARE # else # define GDL2MODELER_EXPORT __declspec(dllexport) # define GDL2MODELER_DECLARE __declspec(dllexport) # endif #else # define GDL2MODELER_EXPORT extern __declspec(dllimport) # define GDL2MODELER_DECLARE __declspec(dllimport) #endif #else /* GNUSTEP_WITH[OUT]_DLL */ # define GDL2MODELER_EXPORT extern # define GDL2MODELER_DECLARE #endif #ifdef __cplusplus } #endif #endif /* __EOMODELER_EODefines_h__ */ gnustep-dl2-0.12.0/EOModeler/EOModelerDocument.h0000644000175000017500000000444311011132314020254 0ustar ayersayers#ifndef __EOModelerDocument_H__ #define __EOModelerDocument_H__ /* -*-objc-*- EOModelerDocument.h Copyright (C) 2005 Free Software Foundation, Inc. Author: Matt Rice Date: Apr 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 Lesser General Public License as published by the Free Software Foundation; either version 3 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef NeXT_Foundation_LIBRARY #include #else #include #endif #include @class EOModel; @class NSMutableArray; @class NSDictionary; @class EOEditingContext; @class EOModelerEditor; @class EOAdaptor; @class NSAttributedString; @class NSString; GDL2MODELER_EXPORT NSString *EOMCheckConsistencyBeginNotification; GDL2MODELER_EXPORT NSString *EOMCheckConsistencyEndNotification; GDL2MODELER_EXPORT NSString *EOMCheckConsistencyForModelNotification; GDL2MODELER_EXPORT NSString *EOMConsistencyModelObjectKey; @interface EOModelerDocument : NSObject { EOModel *_model; NSMutableArray *_editors; NSDictionary *_userInfo; EOEditingContext *_editingContext; } + (void) setDefaultEditorClass: (Class)defaultEditorClass; - (id) initWithModel:(EOModel *)model; - (void) saveAs:(id)sender; - (NSString *)documentPath; - (EOModel *)model; - (EOAdaptor *)adaptor; - (EOModelerEditor *) addDefaultEditor; - (void) activate; - (void) appendConsistencyCheckErrorText:(NSAttributedString *)errorText; - (void) appendConsistencyCheckSuccessText:(NSAttributedString *)successText; /* actions */ - (void) addEntity:(id)sender; - (void) addRelationship:(id)sender; - (void) addAttribute:(id)sender; - (void) delete:(id)sender; @end #endif // __EOModelerDocument_H__ gnustep-dl2-0.12.0/EOModeler/GNUmakefile0000644000175000017500000000355411017542132016656 0ustar ayersayers# # EOModeler makefile for GNUstep Database Library. # # Copyright (C) 2001,2002,2003,2004,2005 Free Software Foundation, Inc. # # Written by: Mirko Viviani # # 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 3 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, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # include ../common.make include $(GNUSTEP_MAKEFILES)/common.make include ../Version # The library to be compiled NATIVE_LIBRARY_NAME=EOModeler EOModeler_NEEDS_GUI = yes # The C source files to be compiled EOModeler_C_FILES = # The Objective-C source files to be compiled EOModeler_OBJC_FILES = \ EOModelExtensions.m \ EOMInspector.m \ EOModelExtensions.m \ EOModelerDocument.m \ EOMInspectorController.m \ EOModelerApp.m \ EOModelerEditor.m EOModeler_HEADER_FILES_DIR = . EOModeler_HEADER_FILES_INSTALL_DIR = /EOModeler EOModeler_HEADER_FILES = \ EOModelExtensions.h \ EOMInspector.h \ EOModelExtensions.h \ EOModelerDocument.h \ EOMInspectorController.h \ EOModelerApp.h \ EOModelerEditor.h \ EODefines.h -include Makefile.preamble -include GNUmakefile.local include $(GNUSTEP_MAKEFILES)/native-library.make -include Makefile.postamble gnustep-dl2-0.12.0/EOModeler/EOModelerApp.m0000644000175000017500000001125111011132314017216 0ustar ayersayers/** EOModelerApp.m EOModelerApp Class Copyright (C) 2005 Free Software Foundation, Inc. Author: Matt Rice Date: April 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 Lesser General Public License as published by the Free Software Foundation; either version 3 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifdef NeXT_Foundation_LIBRARY #include #else #include #include #endif #include #include #include "EOModeler/EODefines.h" #include "EOModeler/EOModelerApp.h" #include "EOModeler/EOModelerDocument.h" #include EOModelerApp *EOMApp; NSString *EOMSelectionChangedNotification = @"EOModelerSelectionChanged"; NSString *EOMPropertyPboardType = @"EOModelProperty"; static EOModelerDocument *_activeDocument; @implementation EOModelerApp : NSApplication - (id) init { if ((self = [super init])) { EOMApp = (EOModelerApp*)NSApp; _documents = [[NSMutableArray alloc] init]; _columnsByClass = [[NSMutableDictionary alloc] init]; } return self; } - (NSArray *)allPasteboardTypes { return [NSArray arrayWithObject:EOMPropertyPboardType]; } - (EOModelerEditor *)currentEditor; { return _currentEditor; } - (void) setCurrentEditor:(EOModelerEditor *)newEditor { _currentEditor = newEditor; } - (void)addDocument:(EOModelerDocument *)document { [_documents addObject: document]; } - (void)removeDocument:(EOModelerDocument *)document { if (_activeDocument == document) _activeDocument = nil; [_documents removeObject: document]; } - (NSArray *)documents { return [NSArray arrayWithArray: _documents]; } - (EOModelerDocument *)activeDocument { //TODO return _activeDocument; } - (EOModelerDocument *)loadDocumentAtPath:(NSString *)path { EOModel *loadedModel = [[EOModel alloc] initWithContentsOfFile:path]; [[EOModelGroup defaultGroup] addModel:loadedModel]; EOModelerDocument *loadedDocument = [[EOModelerDocument alloc] initWithModel: loadedModel]; [self addDocument: loadedDocument]; RELEASE(loadedDocument); return loadedDocument; } - (EOModelerDocument *)documentWithPath:(NSString *)path { unsigned i = 0; for (i=0; i < [_documents count]; i++) { if ([[[_documents objectAtIndex:i] documentPath] isEqual: path]) return [_documents objectAtIndex:i]; } return nil; } - (void)registerColumnName:(NSString *)name forClass:(Class)class provider:(id )provider { NSMutableDictionary *classDict = [_columnsByClass objectForKey: class]; if (!classDict) { classDict = [[NSMutableDictionary alloc] init]; [_columnsByClass setObject:classDict forKey:class]; RELEASE(classDict); } [classDict setObject:provider forKey:name]; } - (void)registerColumnNames:(NSArray *)names forClass:(Class)class provider:(id )provider { unsigned i,count = [names count]; NSMutableDictionary *classDict = [_columnsByClass objectForKey: class]; if (!classDict) { classDict = [[NSMutableDictionary alloc] init]; [_columnsByClass setObject:classDict forKey:class]; RELEASE(classDict); } for (i = 0; i < count; i++) { [classDict setObject:provider forKey:[names objectAtIndex:i]]; } } - (NSArray *)columnNamesForClass:(Class)class { return [[_columnsByClass objectForKey:class] allKeys]; } - (id )providerForName:(NSString *)name class:(Class)class { return [[_columnsByClass objectForKey:class] objectForKey:name]; } + (EOModel *)modelWithPath:(NSString *)path { id _eom = [[EOModel alloc] initWithContentsOfFile:path]; [[EOModelGroup defaultGroup] addModel: _eom]; return _eom; } + (EOModel *)modelContainingFetchSpecification:(EOFetchSpecification *)fs { /* TODO */ return nil; } + (NSString *)nameForFetchSpecification:(EOFetchSpecification *)fs { /* TODO */ return nil; } -(void)_setActiveDocument:(EOModelerDocument*)ad { _activeDocument = ad; } @end gnustep-dl2-0.12.0/EOModeler/EOMInspector.m0000644000175000017500000001152511011132314017255 0ustar ayersayers/** EOMInspector.m EOMInspector Class Copyright (C) 2005 Free Software Foundation, Inc. Author: Matt Rice Date: April 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 Lesser General Public License as published by the Free Software Foundation; either version 3 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA **/ #include #ifdef NeXT_Foundation_LIBRARY #include #else #include #endif #include "EOModeler/EOMInspector.h" #include "EOModeler/EOMInspectorController.h" #include "EOModeler/EOModelerApp.h" #include "EOModeler/EOModelerEditor.h" #include #include static NSMapTable *_inspectorsByClass; @implementation EOMInspector - (id) init { self = [super init]; return self; } /* this method currently assumes that allRegisteredInspectors has been called *after* all bundles have been loaded. */ + (NSArray *) allRegisteredInspectors { if (!_inspectorsByClass) { NSArray *inspectorClasses = GSObjCAllSubclassesOfClass([self class]); int i,c; _inspectorsByClass = NSCreateMapTableWithZone(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, [inspectorClasses count], [self zone]); for (i = 0, c = [inspectorClasses count]; i < c; i++) { [[inspectorClasses objectAtIndex:i] sharedInspector]; } } return [NSAllMapTableValues(_inspectorsByClass) sortedArrayUsingSelector:@selector(_compareDisplayOrder:)]; } + (NSArray *) allInspectorsThatCanInspectObject:(id)selectedObject { int i,c; NSMutableArray *inspectors = [[NSMutableArray alloc] init]; NSArray *_allInspectors = [self allRegisteredInspectors]; for (i = 0, c = [_allInspectors count]; i < c; i++) { id gadget = [_allInspectors objectAtIndex:i]; if ([gadget canInspectObject:selectedObject]) { [inspectors addObject:gadget]; } } return inspectors; } + (EOMInspector *)sharedInspector { EOMInspector *_sharedInspector = NSMapGet(_inspectorsByClass, [self class]); if (!_sharedInspector) { id foo = [[self alloc] init]; NSMapInsert(_inspectorsByClass,[self class], foo); _sharedInspector = foo; } return _sharedInspector; } + (BOOL) usesControlActionForValidation { return YES; } + (NSArray *) selectionBeingValidated { return nil; // FIXME } - (NSString *) displayName { return [window title]; } - (NSImage *) image { if (!image) image = [NSImage imageNamed:NSStringFromClass([self class])]; return image; } - (NSImage *) hilightedImage { return [self image]; } - (float) displayOrder { return 10.0; } - (NSComparisonResult) _compareDisplayOrder:(EOMInspector *)inspector { float itsResult, myResult; myResult = [self displayOrder]; itsResult = [inspector displayOrder]; return (myResult < itsResult) ? NSOrderedAscending : (myResult == itsResult) ? NSOrderedSame : NSOrderedDescending; } - (BOOL) canInspectObject:(id)selectedObject { return NO; } - (void) load { if (![NSBundle loadNibNamed:NSStringFromClass([self class]) owner: self]) NSLog(@"failed to load: %@.gorm", NSStringFromClass([self class])); } - (void) unload { } - (void) prepareForDisplay { if (!view) { [self load]; } } /* returns the 'view' ivar if it exists otherwise the 'window' ivars content view */ - (NSView *) view { /* yes we leak this but these live throughout the applictions lifespan, * we'll only leak one because inspectors are singletons. * and theres no good way to release it in all cases. */ if (!view && window) view = RETAIN([window contentView]); return view; } - (void) refresh { return; } - (NSArray *) selectedObjects { NSArray *sel = [[EOMApp currentEditor] selectionWithinViewedObject]; if (![sel count]) sel = [NSArray arrayWithObject: [[[EOMApp currentEditor] viewedObjectPath] lastObject]]; return sel; } - (id) selectedObject { NSArray *selection = [[EOMApp currentEditor] selectionWithinViewedObject]; if ([selection count]) return [selection objectAtIndex:0]; else return [[[EOMApp currentEditor] viewedObjectPath] lastObject]; } - (BOOL) isAdvanced { return NO; } @end gnustep-dl2-0.12.0/EOModeler/Makefile.postamble0000644000175000017500000000344710645346232020243 0ustar ayersayers# # Makefile.postamble # # Copyright (C) 1997,2002,2005 Free Software Foundation, Inc. # # Written by: Scott Christley # # 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 3 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, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # # Makefile.postamble # # Project specific makefile rules # # Uncomment the targets you want. # The double colons (::) are important, do not make them single colons # otherwise the normal makefile rules will not be performed. # # Things to do before compiling before-all:: # Things to do after compiling # after-all:: # Things to do before installing # before-install:: # Things to do after installing # after-install:: # Things to do before uninstalling # before-uninstall:: # Things to do after uninstalling # after-uninstall:: # Things to do before cleaning # before-clean:: # Things to do after cleaning # after-clean:: # Things to do before distcleaning # before-distclean:: # Things to do after distcleaning # after-distclean:: # Things to do before checking # before-check:: # Things to do after checking # after-check: gnustep-dl2-0.12.0/EOModeler/Makefile.preamble0000644000175000017500000000462210765761345020051 0ustar ayersayers# # Makefile.preamble # # Copyright (C) 1997,2002,2003,2004,2005 Free Software Foundation, Inc. # # Written by: Scott Christley # # 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 3 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, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # # Makefile.preamble # # Project specific makefile variables, and additional # # Do not put any Makefile rules in this file, instead they should # be put into Makefile.postamble. # # # Flags dealing with compiling and linking # # Additional flags to pass to the preprocessor ADDITIONAL_CPPFLAGS = $(FND_DEFINE) $(RUNTIME_DEFINE) # Additional flags to pass to the Objective-C compiler ADDITIONAL_OBJCFLAGS = $(TEST_CFLAGS) # Additional flags to pass to the C compiler ADDITIONAL_CFLAGS = $(TEST_CFLAGS) # Additional include directories the compiler should search ADDITIONAL_INCLUDE_DIRS = -I../EOControl/$(GNUSTEP_TARGET_DIR) -I.. # Additional LDFLAGS to pass to the linker ADDITIONAL_LDFLAGS = $(TEST_LDFLAGS) # Additional library directories the linker should search ADDITIONAL_LIB_DIRS= # # Flags dealing with installing and uninstalling # # Additional directories to be created during installation ADDITIONAL_INSTALL_DIRS = # What are the libraries this library depends upon. This is needed for some # systems where building a shared library requires to pass to the linker # all the libraries the target library depends upon. ifneq ($(FOUNDATION_LIBRARY_NAME),) LIBRARIES_DEPEND_UPON = $(FND_LIBS) endif ifneq ($(FOUNDATION_LIB),gnu) LIBRARIES_DEPEND_UPON += -lgnustep-baseadd endif LIBRARIES_DEPEND_UPON += $(TEST_COVERAGE_LIBS) ADDITIONAL_NATIVE_LIB_DIRS += ../EOAccess ../EOControl ADDITIONAL_NATIVE_LIBS += EOControl EOAccess gnustep-dl2-0.12.0/EOModeler/EOModelerEditor.m0000644000175000017500000002645611011132314017741 0ustar ayersayers/** EOModelerEditor.m EOModelerEditor Classes Copyright (C) 2005 Free Software Foundation, Inc. Author: Matt Rice Date: April 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 Lesser General Public License as published by the Free Software Foundation; either version 3 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA **/ #include "EOModeler/EOModelerEditor.h" #include "EOModeler/EOModelerDocument.h" #include "EOModeler/EOModelerApp.h" #include #ifdef NeXT_GUI_LIBRARY #include #else #include #endif #ifdef NeXT_Foundation_LIBRARY #include #else #include #include #include #include #include #endif #include #include @implementation EOModelerEditor - (void) dealloc { [super dealloc]; } - (id)initWithDocument:(EOModelerDocument *)document { if ((self = [super init])) { _document = document; _selectionWithinViewedObject = [NSArray new]; } return self; } - (EOModelerDocument *)document { return _document; } /** Subclassses should implement, by default throws an exception */ - (void)setSelectionPath:(NSArray *)newSelection { [self subclassResponsibility: _cmd]; } /** Subclassses should implement, by default throws an exception */ - (NSArray *)selectionPath { [self subclassResponsibility: _cmd]; return nil; } /** Subclassses should implement, by default throws an exception */ - (void)activate { [self subclassResponsibility: _cmd]; } /** Subclassses should implement, by default throws an exception */ - (NSArray *)selectionWithinViewedObject { [self subclassResponsibility: _cmd]; return [NSArray array]; } /** Subclassses should implement, by default throws an exception */ - (void)setSelectionWithinViewedObject:(NSArray *)newSelection { [self subclassResponsibility: _cmd]; } /** Subclassses should implement, by default throws an exception */ - (void)setViewedObjectPath:(NSArray *)newPath { [self subclassResponsibility: _cmd]; } /** Subclassses should implement, by default throws an exception */ - (NSArray *)viewedObjectPath { [self subclassResponsibility: _cmd]; return nil; } - (void) debugSelectionPath { int i,j; NSArray *_selectionPath = [self selectionPath]; for (i = 0; i < [_selectionPath count]; i++) { id obj = [_selectionPath objectAtIndex:i]; if (![obj isKindOfClass:[NSArray class]]) NSLog(@"%i %@(%@)", i, [obj class], [obj name]); else { for (j = 0; j < [obj count]; j++) { id obj2 = [obj objectAtIndex:j]; NSLog(@"* %i %@(%@)", j, [obj2 class], [obj2 name]); } } } printf("\n\n"); } @end @implementation EOModelerCompoundEditor - (void) dealloc { RELEASE(_editors); RELEASE(_viewedObjectPath); RELEASE(_selectionWithinViewedObject); [super dealloc]; } - (id) initWithDocument:(id)doc { self = [super initWithDocument:doc]; _editors = [[NSMutableArray alloc] init]; _activeEditor = nil; _viewedObjectPath = [[NSArray alloc] initWithObjects:[doc model], nil]; return self; } - (void) selectionDidChange { [[NSNotificationCenter defaultCenter] postNotificationName:EOMSelectionChangedNotification object:_document]; } - (EOModelerEmbedibleEditor *)activeEditor { return _activeEditor; } - (void)activateEditorWithClass:(Class)embedibleEditorClass { int i, count = [_editors count]; for (i = 0; i < count; i++) { EOModelerEmbedibleEditor *anEditor = [_editors objectAtIndex:i]; if ([anEditor isKindOfClass: embedibleEditorClass]) { [anEditor activate]; _activeEditor = anEditor; } } } - (void)activateEmbeddedEditor:(EOModelerEmbedibleEditor *)editor { unsigned int index = [_editors indexOfObjectIdenticalTo: editor]; if (index == NSNotFound) { [_editors addObject: editor]; } [editor activate]; _activeEditor = editor; } - (EOModelerEmbedibleEditor *)embedibleEditorOfClass:(Class)editorClass { int i, count = [_editors count]; for (i = 0; i < count; i++) { EOModelerEmbedibleEditor *anEditor = [_editors objectAtIndex:i]; if ([anEditor isKindOfClass: editorClass]) { return anEditor; } } { EOModelerEmbedibleEditor *newEditor = [[editorClass alloc] initWithParentEditor:self]; [self registerEmbedibleEditor: newEditor]; RELEASE(newEditor); return newEditor; } } - (void)registerEmbedibleEditor:(EOModelerEmbedibleEditor *)editor { [_editors addObject:editor]; } /* getting the selection */ - (NSArray *)selectionPath { return [_viewedObjectPath arrayByAddingObject:_selectionWithinViewedObject]; } - (NSArray *) viewedObjectPath { return _viewedObjectPath; } - (NSArray *)selectionWithinViewedObject { return _selectionWithinViewedObject; } /**

Compound editors subclass this to send an EOMSelectionChangeNotification and manage the selection arrays.

*/ - (void)setSelectionPath:(NSArray *)newSelection { unsigned int indexOfLast = [newSelection indexOfObject:[newSelection lastObject]]; NSRange allButLastElement; /* int i,j; printf("%@\n",NSStringFromSelector(_cmd)); for (i = 0; i < [newSelection count]; i++) { id foo = [newSelection objectAtIndex:i]; if ([foo isKindOfClass:[NSArray class]]) { printf("\t"); for (j = 0; j < [foo count]; j++) printf("%@", [[foo objectAtIndex:j] class]); printf("\n"); } else printf("%@\n", [[newSelection objectAtIndex:i] class]); } */ if (indexOfLast == NSNotFound) { ASSIGN(_viewedObjectPath, [NSArray array]); ASSIGN(_selectionWithinViewedObject, [NSArray array]); } else { allButLastElement.location = 0; allButLastElement.length = indexOfLast; ASSIGN(_viewedObjectPath, [newSelection subarrayWithRange:allButLastElement]); ASSIGN(_selectionWithinViewedObject, [newSelection lastObject]); } [self selectionDidChange]; } /**

Compound editors subclass this to send an EOMSelectionChangeNotification and manage the selection arrays.

*/ - (void) setSelectionWithinViewedObject:(NSArray *) newSelection { /* int i,j; printf("%@\n",NSStringFromSelector(_cmd)); for (i = 0; i < [newSelection count]; i++) { id foo = [newSelection objectAtIndex:i]; if ([foo isKindOfClass:[NSArray class]]) { printf("\t"); for (j = 0; j < [foo count]; j++) printf("%@", [[foo objectAtIndex:j] class]); printf("\n"); } else printf("%@\n", [[newSelection objectAtIndex:i] class]); } */ ASSIGN(_selectionWithinViewedObject, newSelection); [self selectionDidChange]; } /**

Compound editors subclass this to send an EOMSelectionChangeNotification and manage the selection arrays.

*/ - (void) setViewedObjectPath:(NSArray *)newPath { /* int i,j; printf("%@\n",NSStringFromSelector(_cmd)); for (i = 0; i < [newPath count]; i++) { id foo = [newPath objectAtIndex:i]; if ([foo isKindOfClass:[NSArray class]]) { printf("\t"); for (j = 0; j < [foo count]; j++) printf("%@", [[foo objectAtIndex:j] class]); printf("\n"); } else printf("%@\n", [[newPath objectAtIndex:i] class]); } */ ASSIGN(_viewedObjectPath, newPath); [self selectionDidChange]; } - (void)setStoredProceduresSelected:(BOOL)selected { _storedProceduresSelected = selected; } - (BOOL)storedProceduresSelected { if ([[_viewedObjectPath lastObject] isKindOfClass: NSClassFromString(@"EOModel")]) { return _storedProceduresSelected; } return NO; } /* viewing the selection */ - (void)viewSelectedObject { if (![_selectionWithinViewedObject count]) return; { id object = [_selectionWithinViewedObject objectAtIndex:0]; [self setSelectionPath: [[_viewedObjectPath arrayByAddingObject: object] arrayByAddingObject:[NSArray array]]]; } } - (void) activate { [EOMApp setCurrentEditor:self]; } @end @implementation EOModelerEmbedibleEditor - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; [super dealloc]; } - (id) initWithParentEditor:(EOModelerCompoundEditor *)parentEditor { if ((self = [super initWithDocument: [parentEditor document]])) { _parentEditor = parentEditor; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(selectionDidChange:) name:EOMSelectionChangedNotification object:[self document]]; } return self; } - (EOModelerCompoundEditor *)parentEditor { return _parentEditor; } - (void)selectionDidChange:(NSNotification *)notification { if (self == [_parentEditor activeEditor]) { [self activate]; } } /** subclasses should return YES if they can edit the current selection (should return NO if there is no selection */ - (BOOL)canSupportCurrentSelection { return NO; } /* subclasses should implement */ - (NSArray *)friendEditorClasses { return nil; } /* subclasses should implement */ - (NSView *)mainView { return nil; } - (NSString *)pathViewPreferenceHint { [self subclassResponsibility: _cmd]; return nil; } - (void)print { [self subclassResponsibility: _cmd]; } /** Returns the selection path from the parent editor */ - (NSArray *)selectionPath { return [[self parentEditor] selectionPath]; } /** Returns the viewed object path from the parent editor */ - (NSArray *) viewedObjectPath { return [[self parentEditor] viewedObjectPath]; } /** Returns the selection within the viewed object from the parent editor */ - (NSArray *)selectionWithinViewedObject { return [[self parentEditor] selectionWithinViewedObject]; } /** Forwarded to the parent editor. * This method is not called by the parent editor. * to update the selection when its changed in the parent editor, * register for EOMSelectionDidChangeNotification. */ - (void)setSelectionPath:(NSArray *)newSelection { [[self parentEditor] setSelectionPath: newSelection]; } /** Forwarded to the parent editor. * This method is not called by the parent editor. * to update the selection when its changed in the parent editor, * register for EOMSelectionDidChangeNotification. */ - (void) setSelectionWithinViewedObject:(NSArray *) newSelection { [[self parentEditor] setSelectionWithinViewedObject: newSelection]; } /** Forwarded to the parent editor. * This method is not called by the parent editor. * to update the selection when its changed in the parent editor, * register for EOMSelectionDidChangeNotification. */ - (void) setViewedObjectPath:(NSArray *)newPath { [[self parentEditor] setViewedObjectPath: newPath]; } @end gnustep-dl2-0.12.0/EOModeler/EOModelerEditor.h0000644000175000017500000000523711011132314017726 0ustar ayersayers#ifndef __EOModelerEditor_H__ #define __EOModelerEditor_H__ /* -*-objc-*- EOModelerEditor.h Copyright (C) 2005 Free Software Foundation, Inc. Author: Matt Rice Date: Apr 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 Lesser General Public License as published by the Free Software Foundation; either version 3 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef NeXT_Foundation_LIBRARY #include #else #include #include #endif @class EOModelerDocument; @class EOModelerEmbedibleEditor; @class NSView; @class NSMutableArray; @class NSNotification; @interface EOModelerEditor : NSObject { EOModelerDocument *_document; NSMutableArray *_editors; EOModelerEmbedibleEditor *_activeEditor; NSArray *_viewedObjectPath; NSArray *_selectionWithinViewedObject; BOOL _storedProceduresSelected; } - (id) initWithDocument:(EOModelerDocument *)document; - (EOModelerDocument *)document; - (void) setSelectionWithinViewedObject:(NSArray *)selectionWithin; - (NSArray *) selectionWithinViewedObject; - (void) setSelectionPath:(NSArray *)selectionPath; - (NSArray *)selectionPath; - (void) setViewedObjectPath:(NSArray *)viewedObjectPath; - (NSArray *)viewedObjectPath; @end @interface EOModelerCompoundEditor : EOModelerEditor - (void) viewSelectedObject; - (void) registerEmbedibleEditor:(EOModelerEmbedibleEditor *)embedibleEditor; - (void) activateEmbeddedEditor:(EOModelerEmbedibleEditor *)embedibleEditor; - (void) activateEditorWithClass:(Class)editorClass; - (void) activate; - (EOModelerEmbedibleEditor *) activeEditor; - (EOModelerEmbedibleEditor *) embedibleEditorOfClass:(Class)eeClass; @end @interface EOModelerEmbedibleEditor : EOModelerEditor { EOModelerCompoundEditor *_parentEditor; } - (id)initWithParentEditor:(EOModelerCompoundEditor *)parentEditor; - (NSView *)mainView; - (BOOL) canSupportCurrentSelection; - (NSArray *)friendEditorClasses; - (EOModelerCompoundEditor *) parentEditor; - (void) selectionDidChange:(NSNotification *)notif; @end #endif // __EOModelerEditor_H__ gnustep-dl2-0.12.0/EOModeler/EOMInspector.h0000644000175000017500000000340111011132314017242 0ustar ayersayers#ifndef __EOMInspector_H__ #define __EOMInspector_H__ /* -*-objc-*- EOMInspector.h Copyright (C) 2005 Free Software Foundation, Inc. Author: Matt Rice Date: Apr 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 Lesser General Public License as published by the Free Software Foundation; either version 3 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef NeXT_GUI_LIBRARY #include #else #include #endif #ifdef NeXT_Foundation_LIBRARY #include #else #include #endif @class NSArray; @class NSWindow; @class NSView; @class NSImage; @interface EOMInspector : NSObject { IBOutlet NSImage *image; IBOutlet NSView *view; IBOutlet NSWindow *window; } + (NSArray *)allRegisteredInspectors; + (NSArray *)allInspectorsThatCanInspectObject:(id)anObject; + (EOMInspector *) sharedInspector; - (NSView *)view; - (BOOL) canInspectObject:(id)anObject; - (void) prepareForDisplay; - (void) refresh; - (id) selectedObject; - (NSString *)displayName; - (float) displayOrder; - (NSImage *)image; - (NSImage *)hilightedImage; @end #endif // __EOMInspector_H__ gnustep-dl2-0.12.0/EOModeler/EOModelExtensions.h0000644000175000017500000000430410645346232020324 0ustar ayersayers/* -*-objc-*- EOModelExtensions.h Copyright (C) 2001,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: June 2001 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 Lesser General Public License as published by the Free Software Foundation; either version 3 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __EOModelExtensions_h__ #define __EOModelExtensions_h__ #ifdef GNUSTEP #include #else #include #endif #include #include #include @interface EOEntity (EOModelExtensions) - (NSArray *)classAttributes; - (NSArray *)classScalarAttributes; - (NSArray *)classNonScalarAttributes; - (NSArray *)classToManyRelationships; - (NSArray *)classToOneRelationships; - (NSArray *)referencedClasses; - (NSString *)referenceClassName; - (NSString *)referenceJavaClassName; - (NSString *)parentClassName; - (NSString *)javaParentClassName; - (NSArray *)arrayWithParentClassNameIfNeeded; - (NSString *)classNameWithoutPackage; - (NSArray *)classPackage; @end @interface EOAttribute (EOModelExtensions) - (BOOL)isScalar; - (NSString *)cScalarTypeString; - (BOOL)isDeclaredBySuperClass; - (NSString *)javaValueClassName; @end @interface EORelationship (EOModelExtensions) - (BOOL)isDeclaredBySuperClass; @end @interface NSMutableAttributedString (_EOModelerErrorConstruction) + (NSMutableAttributedString *)mutableAttributedStringWithBoldSubstitutionsWithFormat: (NSString *)format, ...; @end #endif /* __EOModelExtensions_h__ */ gnustep-dl2-0.12.0/EOModeler/EOMInspectorController.h0000644000175000017500000000263511011132314021316 0ustar ayersayers#ifndef __EOMInspectorController_H__ #define __EOMInspectorController_H__ /* -*-objc-*- EOMInspectorController.h Copyright (C) 2005 Free Software Foundation, Inc. Author: Matt Rice Date: Apr 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 Lesser General Public License as published by the Free Software Foundation; either version 3 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef NeXT_Foundation_LIBRARY #include #else #include #endif @class NSWindow; @class NSScrollView; @class EOMInspector; @interface EOMInspectorController : NSObject { NSWindow *window; NSScrollView *scrollView; EOMInspector *lastInspector; } + (EOMInspectorController *)sharedInstance; + (void) showInspector; @end #endif // __EOMInspectorController_H__ gnustep-dl2-0.12.0/EOModeler/EOModelerDocument.m0000644000175000017500000004706711012240010020264 0ustar ayersayers/** EOModelerDocument.m EOModelerDocument Class Copyright (C) 2005 Free Software Foundation, Inc. Author: Matt Rice Date: April 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 Lesser General Public License as published by the Free Software Foundation; either version 3 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA **/ #include "EOModeler/EODefines.h" #include "EOModeler/EOModelerDocument.h" #include "EOModeler/EOModelerEditor.h" #include "EOModeler/EOModelerApp.h" #ifdef NeXT_GUI_LIBRARY #include #else #include #include #endif #include #include #include #include #include #include #include #include #ifdef NeXT_Foundation_LIBRARY #include #else #include #include #include #include #include #include #include #endif #include @interface ConsistencyResults : NSObject + (id) sharedConsistencyPanel; - (int) showConsistencyCheckResults:(id)sender cancelButton:(BOOL)useCancel showOnSuccess:(BOOL)flag; @end static Class _defaultEditorClass; static EOModelerEditor *_currentEditorForDocument; /* FIXME we cross the library->application boundry whenever working * with the ConsistencyResults class which is declared in DBModeler * theres a few ways this is crossed: * * enabling/disabling the cancel button * appending text * avoiding running the panel if all checks pass. * * this could possibly be done with private methods in this class * called from the receiver of an EOMCheckConsistencyEndNotification * on the notification -object (or something). */ /** Notification sent when beginning consistency checks. * The notifications object is the EOModelerDocument. * The receiver should call -appendConsistencyCheckErrorText: * on the notifications object for any consistency check failures */ NSString *EOMCheckConsistencyBeginNotification = @"EOMCheckConsistencyBeginNotification"; /** Notification sent when ending consistency checks. * The notifications object is the EOModelerDocument. * The receiver should call -appendConsistencyCheckSuccessText: * on the notifications object for any consistency checks that passed. */ NSString *EOMCheckConsistencyEndNotification = @"EOMCheckConsistencyEndNotification"; /** Notification sent when beginning EOModel consistency checks. * The notifications object is the EOModelerDocument. * The receiver should call -appendConsistencyCheckErrorText: * on the notifications object for any consistency check failures * the userInfo dictionary contains an EOModel instance for the * EOMConsistencyModelObjectKey key. */ NSString *EOMCheckConsistencyForModelNotification = @"EOMCheckConsistencyForModelNotification"; NSString *EOMConsistencyModelObjectKey = @"EOMConsistencyModelObjectKey"; @interface EOModelerApp (PrivateStuff) - (void) _setActiveDocument:(EOModelerDocument *)newDocument; @end @interface NSArray (EOMAdditions) - (id) firstSelectionOfClass:(Class)aClass; @end @implementation NSArray (EOMAdditions) - (id) firstSelectionOfClass:(Class)aClass { unsigned i, c; id obj = nil; for (i = 0, c = [self count]; i < c; i++) { obj = [self objectAtIndex:i]; if ([obj isKindOfClass:aClass]) { break; } if ([obj isKindOfClass:[NSArray class]]) { int j, d; for (j = 0, d = [obj count]; j < d; j++) { id obj2 = [obj objectAtIndex:j]; if ([obj2 isKindOfClass:aClass]) { obj = obj2; break; } } } } if (![obj isKindOfClass:aClass]) { return nil; } return obj; } @end @implementation EOModelerDocument - (BOOL) validateMenuItem:(NSMenuItem *)menuItem { NSArray *selection = [[EOMApp currentEditor] selectionPath]; if ([[menuItem title] isEqualToString:@"Add attribute"]) return ([selection firstSelectionOfClass:[EOEntity class]] != nil); else if ([[menuItem title] isEqualToString:@"Add relationship"]) return ([selection firstSelectionOfClass:[EOEntity class]] != nil); else if ([[menuItem title] isEqual:@"delete"]) return ([[selection lastObject] count]) ? YES : NO; // see -delete: //return ([[selection lastObject] count] || [selection count] > 2) ? YES : NO; return YES; } - (id)initWithModel:(EOModel*)model { if ((self = [super init])) { _model = RETAIN(model); [[EOModelGroup defaultGroup] addModel:model]; _userInfo = nil; _editors = [[NSMutableArray alloc] init]; _editingContext = [[EOEditingContext alloc] init]; [_editingContext insertObject:model]; } return self; } - (void) dealloc { [[_editingContext undoManager] removeAllActionsWithTarget:_editingContext]; [[EOModelGroup defaultGroup] removeModel:_model]; RELEASE(_model); RELEASE(_userInfo); RELEASE(_editors); RELEASE(_editingContext); [super dealloc]; } - (EOAdaptor *)adaptor { NS_DURING NS_VALUERETURN([EOAdaptor adaptorWithModel:_model], EOAdaptor *); NS_HANDLER return nil; NS_ENDHANDLER return nil; } - (EOModel *)model; { return _model; } - (EOEditingContext *)editingContext { return _editingContext; } - (BOOL) isDirty { return NO; /* FIXME*/ } - (BOOL) prepareToSave { if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DisableConsistencyCheckOnSave"] == NO) { NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center postNotificationName:EOMCheckConsistencyBeginNotification object:self]; [center postNotificationName:EOMCheckConsistencyForModelNotification object:self userInfo:[NSDictionary dictionaryWithObject:[self model] forKey:EOMConsistencyModelObjectKey]]; [center postNotificationName:EOMCheckConsistencyEndNotification object:self]; if ([[NSClassFromString(@"ConsistencyResults") sharedConsistencyPanel] showConsistencyCheckResults:self cancelButton:YES showOnSuccess:NO] == NSRunAbortedResponse) return NO; } return YES; } - (NSString *)documentPath { return [[[EOMApp activeDocument] model] path]; } - (BOOL)saveToPath:(NSString *)path { NSString *ext = [path pathExtension]; if (!([ext isEqual:@"eomodeld"] || [ext isEqual:@"eomodel"])) path = [path stringByAppendingPathExtension:@"eomodeld"]; NS_DURING [_model writeToFile: path]; NS_VALUERETURN(YES, BOOL); NS_HANDLER NSRunAlertPanel(@"Error", @"Save failed: %@", @"Ok", NULL, NULL, [localException reason]); return NO; NS_ENDHANDLER return NO; } - (BOOL)checkCloseDocument { /* FIXME */ return NO; } - (void)activate { [EOMApp _setActiveDocument: self]; [[_editors objectAtIndex:0] activate]; } /* Editors stuff */ - (NSArray *)editors { return [NSArray arrayWithArray:_editors]; } - (void)addEditor:(EOModelerEditor *)editor { /* check if we already have an editor object? */ [_editors addObject:editor]; } - (void) closeEditor:(EOModelerEditor *)editor { /* call checkCloseEditor */ } - (BOOL)checkCloseEditor:(EOModelerEditor *)editor { /* FIXME call consistency checker */ return NO; } - (EOModelerEditor *) addDefaultEditor { EOModelerEditor *defaultEditor; defaultEditor = [[_defaultEditorClass alloc] initWithDocument:self]; [self addEditor: defaultEditor]; _currentEditorForDocument = defaultEditor; RELEASE(defaultEditor); return defaultEditor; } - (void)addEntity:(id)sender { unsigned entityNumber; EOEntity *newEntity = [[EOEntity alloc] init]; NSArray *entities = [_model entities]; unsigned i,c; if (![_editors containsObject:[EOMApp currentEditor]]) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:@"current editor not in edited document" userInfo:nil] raise]; return; } c = [entities count]; entityNumber = c; /* look for the largest NNNN in entity named "EntityNNNN" * or the total number of entities in this model whichever is greater. */ for (i = 0; i < c; i++) { NSString *name = [[entities objectAtIndex:i] name]; if ([name hasPrefix:@"Entity"]) { NSRange range; unsigned tmp; name = [name substringFromIndex:6]; range = [name rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]]; if (!(range.location == NSNotFound) && !(range.length == 0)) continue; range = [name rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]]; if (!(range.location == NSNotFound) && !(range.length == 0)) { tmp = [name intValue]; entityNumber = (entityNumber < ++tmp) ? tmp : entityNumber; } } } [newEntity setName: entityNumber ? [NSString stringWithFormat: @"Entity%i", entityNumber] : @"Entity"]; [newEntity setClassName:@"EOGenericRecord"]; [_editingContext insertObject:newEntity]; [_model addEntity:AUTORELEASE(newEntity)]; [(EOModelerCompoundEditor *)[EOMApp currentEditor] setSelectionWithinViewedObject:[NSArray arrayWithObject:newEntity]]; } - (void)addAttribute:(id)sender { EOAttribute *attrb; EOModelerEditor *currEd = [EOMApp currentEditor]; unsigned int attributeNumber; EOEntity *entityObject; NSArray *attributes; int i,c; /* the currentEditor must be in this document */ if (![_editors containsObject:currEd]) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:@"current editor not in edited document" userInfo:nil] raise]; return; } entityObject = [[currEd selectionPath] firstSelectionOfClass:[EOEntity class]]; attributes = [entityObject attributes]; c = [attributes count]; attributeNumber = c; /* look for the largest NNNN in attribute named "AttributeNNNN" * or the total number of attributes in this entity whichever is greater. */ for (i = 0; i < c; i++) { NSString *name = [[attributes objectAtIndex:i] name]; if ([name hasPrefix:@"Attribute"]) { NSRange range; unsigned tmp; name = [name substringFromIndex:9]; range = [name rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]]; if (!(range.location == NSNotFound) && !(range.length == 0)) continue; range = [name rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]]; if (!(range.location == NSNotFound) && !(range.length == 0)) { tmp = [name intValue]; attributeNumber = (attributeNumber < ++tmp) ? tmp : attributeNumber; } } } attrb = [[EOAttribute alloc] init]; [attrb setName: attributeNumber ? [NSString stringWithFormat: @"Attribute%i", attributeNumber] : @"Attribute"]; [entityObject addAttribute:attrb]; [_editingContext insertObject:attrb]; if ([[[EOMApp currentEditor] selectionWithinViewedObject] count] && [[[[EOMApp currentEditor] selectionWithinViewedObject] objectAtIndex:0] isKindOfClass:[EOEntity class]]) [(EOModelerCompoundEditor *)[EOMApp currentEditor] viewSelectedObject]; [(EOModelerCompoundEditor *)[EOMApp currentEditor] setSelectionWithinViewedObject:[NSArray arrayWithObject:attrb]]; } - (void)addRelationship:(id)sender { EORelationship *newRel; EOEntity *srcEntity; EOModelerEditor *currentEditor = [EOMApp currentEditor]; NSArray *relationships; int relationshipNum, i, c; if (![_editors containsObject:currentEditor]) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:@"currentEditor not in edited document exception" userInfo:nil] raise]; return; } srcEntity = [[currentEditor selectionPath] firstSelectionOfClass:[EOEntity class]]; relationships = [srcEntity relationships]; c = [relationships count]; relationshipNum = c; /* look for the largest NNNN in relationships named "RelationshipNNNN" * or the total number of relationships in this attribute whichever is greater */ for (i = 0; i < c; i++) { NSString *name = [[relationships objectAtIndex:i] name]; if ([name hasPrefix:@"Relationship"]) { NSRange range; unsigned tmp; name = [name substringFromIndex:12]; range = [name rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]]; if (!(range.location == NSNotFound) && !(range.length == 0)) continue; range = [name rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]]; if (!(range.location == NSNotFound) && !(range.length == 0)) { tmp = [name intValue]; relationshipNum = (relationshipNum < ++tmp) ? tmp : relationshipNum; } } } newRel = [[EORelationship alloc] init]; [newRel setName: relationshipNum ? [NSString stringWithFormat:@"Relationship%i", relationshipNum] : @"Relationship"]; [srcEntity addRelationship:newRel]; [_editingContext insertObject:newRel]; if ([[[EOMApp currentEditor] selectionWithinViewedObject] count] && [[[[EOMApp currentEditor] selectionWithinViewedObject] objectAtIndex:0] isKindOfClass:[EOEntity class]]) [(EOModelerCompoundEditor *)[EOMApp currentEditor] viewSelectedObject]; [(EOModelerCompoundEditor *)[EOMApp currentEditor] setSelectionWithinViewedObject:[NSArray arrayWithObject:newRel]]; } - (void)delete:(id)sender { NSArray *objects = [[EOMApp currentEditor] selectionWithinViewedObject]; unsigned i,c = [objects count]; if (c == 0) { /* * if there is no selection delete the viewed object. */ /* this is commented out (until we have undo working?) to prevent accidental deletion of entities see also -validateMenuItem: id object; objects = [NSMutableArray arrayWithArray:[[EOMApp currentEditor] viewedObjectPath]]; object = [objects lastObject]; if ([object isKindOfClass:[EOAttribute class]]) { [[object entity] removeAttribute:object]; } else if ([object isKindOfClass:[EOEntity class]]) { [[object model] removeEntity:object]; } else if ([object isKindOfClass:[EORelationship class]]) { [[object entity] removeRelationship: object]; } [(NSMutableArray *)objects removeObjectAtIndex:[objects count] - 1]; [[EOMApp currentEditor] setViewedObjectPath: objects]; */ } else { for (i = 0, c = [objects count]; i < c; i++) { id object = [objects objectAtIndex:i]; if ([object isKindOfClass:[EOAttribute class]]) { NSArray *refs; refs = [[[object entity] model] referencesToProperty:object]; if (![refs count]) [[object entity] removeAttribute:object]; else { NSMutableString *str; unsigned i,c; str = [NSMutableString stringWithFormat:@"attribute is referenced by properties\n"]; for (i = 0, c = [refs count]; i < c; i++) { id prop = [refs objectAtIndex:i]; NSString *tmp; tmp=[NSString stringWithFormat:@"%@ in %@\n",[prop name], [[prop entity] name]]; [str appendString:tmp]; } NSRunAlertPanel(@"unable to remove attribute", str, @"ok", nil, nil); } } else if ([object isKindOfClass:[EOEntity class]]) { [[object model] removeEntity:object]; } else if ([object isKindOfClass:[EORelationship class]]) { [[object entity] removeRelationship: object]; } } [[EOMApp currentEditor] setSelectionWithinViewedObject:[NSArray array]]; } } - (void)addFetchSpecification:(id)sender { } - (void)addStoredProcedure:(id)sender { } - (void)addArgument:(id)sender { } - (BOOL)canFlattenSelectedAttribute; { return NO; // no idea } - (void)flattenAttribute:(id)sender { // likewise } - (void)save:(id)sender { NSString *path; path = [_model path]; if (!path) { [self saveAs:self]; } else { if ([self prepareToSave] == NO) return; [self saveToPath:path]; } } - (void)saveAs:(id)sender { NSString *path; id savePanel; int result; if ([self prepareToSave] == NO) return; savePanel = [NSSavePanel savePanel]; result = [savePanel runModal]; if (result == NSOKButton) { path = [savePanel filename]; [self saveToPath: path]; } } - (void)revertToSaved:(id)sender { } -(void)close:(id)sender { } - (void)undo:(id)sender { } - (void)redo:(id)sender { } /* consitency checking stuff */ - (void) appendConcistencyCheckErrorText: (NSAttributedString *)errorText { } - (void) appendConcistencyCheckSuccessText: (NSAttributedString *)successText { } + (void)setDefaultEditorClass:(Class)editorClass { _defaultEditorClass = editorClass; } + (Class)defaultEditorClass { return _defaultEditorClass; } - (void)setUserInfo:(NSDictionary*)dictionary { ASSIGN(_userInfo,dictionary); //just a guess } - (NSDictionary *)userInfo { return _userInfo; } - (void) windowDidBecomeKey:(NSNotification *)notif { [self activate]; } - (void) windowWillClose:(NSNotification *)notif { if ([_editors containsObject:[EOMApp currentEditor]]) { // Clear inspected object. [[EOMApp currentEditor] setSelectionPath:[NSArray array]]; // No longer current editor [EOMApp setCurrentEditor:nil]; } [EOMApp removeDocument:self]; } - (void) checkConsistency:(id)sender { NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center postNotificationName:EOMCheckConsistencyBeginNotification object:self]; [center postNotificationName:EOMCheckConsistencyForModelNotification object:self userInfo:[NSDictionary dictionaryWithObject:[self model] forKey:EOMConsistencyModelObjectKey]]; [center postNotificationName:EOMCheckConsistencyEndNotification object:self]; [[NSClassFromString(@"ConsistencyResults") sharedConsistencyPanel] showConsistencyCheckResults:self cancelButton:NO showOnSuccess:YES]; } - (void) appendConsistencyCheckErrorText:(NSAttributedString *)errorText { [[NSClassFromString(@"ConsistencyResults") sharedConsistencyPanel] appendConsistencyCheckErrorText:errorText]; } - (void) appendConsistencyCheckSuccessText:(NSAttributedString *)successText { [[NSClassFromString(@"ConsistencyResults") sharedConsistencyPanel] appendConsistencyCheckSuccessText:successText]; } @end gnustep-dl2-0.12.0/EOModeler/EOModelExtensions.m0000644000175000017500000001625711011132314020321 0ustar ayersayers/* EOModelExtensions.m Copyright (C) 2001,2002,2003,2004,2005 Free Software Foundation, Inc. Author: Mirko Viviani Date: January 2001 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 Lesser General Public License as published by the Free Software Foundation; either version 3 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #ifndef GNUSTEP #include #include #endif #ifdef NeXT_Foundation_LIBRARY #include #else #include #include #include #include #endif #ifdef NeXT_GUI_LIBRARY #include #else #include #include #endif #include #include "EOModeler/EOModelExtensions.h" @implementation EOEntity (EOModelExtensions) - (NSArray *)classAttributes { NSEnumerator *enumerator = [[self attributes] objectEnumerator]; EOAttribute *attr; NSMutableArray *array; EOFLOGObjectFnStartOrCond2(@"ModelingClasses",@"EOEntity"); array = [NSMutableArray arrayWithCapacity:10]; while((attr = [enumerator nextObject])) { [array addObject:attr]; } EOFLOGObjectFnStopOrCond2(@"ModelingClasses",@"EOEntity"); return array; } - (NSArray *)classScalarAttributes { NSEnumerator *enumerator = [[self classProperties] objectEnumerator]; EOAttribute *attr; NSMutableArray *array; EOFLOGObjectFnStartOrCond2(@"ModelingClasses",@"EOEntity"); array = [NSMutableArray arrayWithCapacity:10]; while((attr = [enumerator nextObject])) { if([attr isKindOfClass: [EOAttribute class]] && [attr isScalar] == YES) [array addObject:attr]; } EOFLOGObjectFnStopOrCond2(@"ModelingClasses",@"EOEntity"); return array; } - (NSArray *)classNonScalarAttributes { NSEnumerator *enumerator = [[self classProperties] objectEnumerator]; EOAttribute *attr; NSMutableArray *array; EOFLOGObjectFnStartOrCond2(@"ModelingClasses",@"EOEntity"); array = [NSMutableArray arrayWithCapacity:10]; while((attr = [enumerator nextObject])) { if([attr isKindOfClass: [EOAttribute class]] && [attr isScalar] == NO) [array addObject:attr]; } EOFLOGObjectFnStopOrCond2(@"ModelingClasses",@"EOEntity"); return array; } - (NSArray *)classToManyRelationships { NSEnumerator *enumerator = [[self classProperties] objectEnumerator]; EORelationship *relationship; NSMutableArray *array; EOFLOGObjectFnStartOrCond2(@"ModelingClasses",@"EOEntity"); array = [NSMutableArray arrayWithCapacity:10]; while((relationship = [enumerator nextObject])) { if([relationship isKindOfClass: [EORelationship class]] && [relationship isToMany] == YES) [array addObject:relationship]; } EOFLOGObjectFnStopOrCond2(@"ModelingClasses",@"EOEntity"); return array; } - (NSArray *)classToOneRelationships { NSEnumerator *enumerator = [[self classProperties] objectEnumerator]; EORelationship *relationship; NSMutableArray *array; EOFLOGObjectFnStartOrCond2(@"ModelingClasses",@"EOEntity"); array = [NSMutableArray arrayWithCapacity:10]; while((relationship = [enumerator nextObject])) { if([relationship isKindOfClass: [EORelationship class]] && [relationship isToMany] == NO) [array addObject:relationship]; } EOFLOGObjectFnStopOrCond2(@"ModelingClasses",@"EOEntity"); return array; } - (NSArray *)referencedClasses { NSEnumerator *enumerator = [[self relationships] objectEnumerator]; EORelationship *relationship; NSMutableArray *array; EOFLOGObjectFnStartOrCond2(@"ModelingClasses",@"EOEntity"); array = [NSMutableArray arrayWithCapacity:10]; while((relationship = [enumerator nextObject])) { [array addObject:[[relationship destinationEntity] className]]; } EOFLOGObjectFnStopOrCond2(@"ModelingClasses",@"EOEntity"); return array; } - (NSString *)referenceClassName { if([[self className] isEqual:@"EOGenericRecord"]) return @"id"; return [NSString stringWithFormat:@"%@ *", [self className]]; } - (NSString *)referenceJavaClassName { if([[self className] isEqual:@"EOGenericRecord"]) return @"CustomObject"; return [self className]; } - (NSString *)parentClassName { if([self parentEntity]) return [[self parentEntity] className]; return @"NSObject"; } - (NSString *)javaParentClassName { if([self parentEntity]) return [[self parentEntity] className]; return @"EOCustomObject"; } - (NSArray *)arrayWithParentClassNameIfNeeded { NSMutableArray *array; array = [NSMutableArray arrayWithCapacity:1]; if([self parentEntity]) [array addObject:[[self parentEntity] className]]; return array; } - (NSString *)classNameWithoutPackage { return [self className]; } - (NSArray *)classPackage { return [NSArray array]; } @end @implementation EOAttribute (EOModelExtensions) - (BOOL)isScalar { return NO; } - (NSString *)cScalarTypeString { return nil; } - (BOOL)isDeclaredBySuperClass { return NO; } - (NSString *)javaValueClassName { [self notImplemented:_cmd]; return nil; } @end @implementation EORelationship (EOModelExtensions) - (BOOL)isDeclaredBySuperClass { return NO; } @end @implementation NSMutableAttributedString (_EOModelerErrorConstruction) + (NSMutableAttributedString *)mutableAttributedStringWithBoldSubstitutionsWithFormat:(NSString *)format, ... { va_list ap; NSMutableAttributedString *s = [[NSMutableAttributedString alloc] init]; NSScanner *scanner = [NSScanner scannerWithString:format]; NSString *tmp; NSDictionary *boldAttributes; boldAttributes = [[NSDictionary alloc] initWithObjectsAndKeys: [NSFont boldSystemFontOfSize:[NSFont systemFontSize]], NSFontAttributeName, nil]; [scanner setCharactersToBeSkipped:nil]; if (format == nil) return nil; va_start(ap, format); [scanner scanUpToString:@"%@" intoString:&tmp]; [s appendAttributedString:AUTORELEASE([[NSAttributedString alloc] initWithString:tmp])]; while ([scanner scanString:@"%@" intoString:NULL]) { NSAttributedString *boldStr; boldStr = [[NSAttributedString alloc] initWithString:(NSString *)va_arg(ap, NSString *) attributes: boldAttributes]; [s appendAttributedString:AUTORELEASE(boldStr)]; if ([scanner scanUpToString:@"%@" intoString:&tmp]) [s appendAttributedString:AUTORELEASE([[NSAttributedString alloc] initWithString:tmp])]; } va_end(ap); RELEASE(boldAttributes); return AUTORELEASE(s); } @end gnustep-dl2-0.12.0/INSTALL0000644000175000017500000000243310645222462014024 0ustar ayersayersIntroduction ============ Make sure you have installed the GNUstep Makefile package (gnustep-make) and the GNUstep Base Library (gnustep-base) and you have sourced the makefile script: . $GNUSTEP_SYSTEM_ROOT/Library/Makefiles/GNUstep.sh If you want support for LoginPanels you also need the GNUstep GUI Library (gnustep-gui) and the GNUstep Backend Library (gnustep-back) installed. If your installing GDL2 on Cocoa, the GNUstep Base Library should be installed as a support library (gnustep-baseadd). GDL2 will use AppKit so you do not need gnustep-gui or gnustep-back. See the GNUstep-HOWTO in gnustep-make for more information. Quick installation instructions: ./configure make make install Configuration ============= Configuration is performed by running the `configure' program at a shell prompt. You may want to use some of the optional arguments to the `configure' program. Type `configure --help' for a list of these. Compilation =========== To compile this library, type make. After this is complete, type make install. Some additional options you can use with make are `debug=yes' to make a debugging version of the library and `shared=no' to make a static version of the library. See the gnustep-make package for more information on these options. gnustep-dl2-0.12.0/COPYING.LIB0000644000175000017500000001672710645346232014450 0ustar ayersayers GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. gnustep-dl2-0.12.0/DBModeler/0000755000175000017500000000000011147475624014576 5ustar ayersayersgnustep-dl2-0.12.0/DBModeler/DiagramView.m0000644000175000017500000003453111015532156017145 0ustar ayersayers/** DiagramView.m Author: Matt Rice Date: Oct 2006 This file is part of DBModeler. DBModeler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. DBModeler 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 General Public License for more details. You should have received a copy of the GNU General Public License along with DBModeler; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA **/ #include "DiagramView.h" #include "EntityView.h" #include "AttributeCell.h" #ifdef NeXT_Foundation_LIBRARY #include #else #include #endif #ifdef NeXT_GUI_LIBRARY #include #else #include #include #include #include #include #include #include #endif #include #include #include #include #include @implementation DiagramView - (id) initWithFrame:(NSRect)frameRect { self = [super initWithFrame:frameRect]; _shownEntities = [NSMutableDictionary new]; _relationships = [NSMutableArray new]; _subview_order = [NSMutableArray new]; _bgColor = RETAIN([NSColor colorWithCalibratedRed:0.881437 green:0.941223 blue:1.0 alpha:1.0]); [self registerForDraggedTypes:[NSArray arrayWithObject:NSColorPboardType]]; return self; } - (void) dealloc { RELEASE(_shownEntities); RELEASE(_relationships); RELEASE(_subview_order); RELEASE(_bgColor); [super dealloc]; } - (BOOL) prepareForDragOperation:(id )sender { return YES; } - (NSDragOperation) draggingEntered:(id )sender { return [sender draggingSourceOperationMask]; } - (BOOL) performDragOperation:(id )sender { NSPasteboard *pb = [sender draggingPasteboard]; NSColor *color = [NSColor colorFromPasteboard:pb]; ASSIGN(_bgColor, color); [self setNeedsDisplay:YES]; return YES; } - (BOOL) isFlipped { return YES; } - (void) setModel:(EOModel *)model { ASSIGN(_model, model); } - (void) showEntity:(NSString *)name { EntityView *ev; if (!(ev = [_shownEntities objectForKey:name])) { EOEntity *entity = [_model entityNamed:name]; NSArray *attribs = [entity attributes]; NSRect vis = [[self enclosingScrollView] documentVisibleRect]; NSRect evFrame; NSPoint toPoint; int i, c = [attribs count]; ev = [[EntityView alloc] initWithFrame:NSMakeRect(0,0,1,1)]; [ev setTitle:[entity name]]; [ev setNumberOfAttributes:c]; for (i = 0; i < c; i++) { EOAttribute *attrib = [attribs objectAtIndex:i]; AttributeCell *cell = [ev cellAtRow:i]; [cell setStringValue:[attrib name]]; [cell setLock:[[entity attributesUsedForLocking] containsObject:attrib]]; [cell setProp:[[entity classProperties] containsObject:attrib]]; [cell setKey:[[entity primaryKeyAttributes] containsObject:attrib]]; } [ev sizeToFit]; evFrame = [ev frame]; /* this "layout mechanism" is pure evil... */ toPoint.x = vis.origin.x + ((vis.size.width - evFrame.size.width) * rand()/(RAND_MAX + vis.origin.x)); toPoint.y = vis.origin.y + ((vis.size.height - evFrame.size.height) * rand()/(RAND_MAX + vis.origin.y)); [ev setFrameOrigin:toPoint]; [_shownEntities setObject:ev forKey:[entity name]]; [self addSubview:ev]; [_subview_order addObject:ev]; [self setupRelationships]; } else { EOEntity *entity = [_model entityNamed:name]; NSArray *attribs = [entity attributes]; int i, c = [attribs count]; [ev setTitle:[entity name]]; [ev setNumberOfAttributes:c]; for (i = 0; i < c; i++) { EOAttribute *attrib = [attribs objectAtIndex:i]; AttributeCell *cell = [ev cellAtRow:i]; [cell setStringValue:[attrib name]]; [cell setLock:[[entity attributesUsedForLocking] containsObject:attrib]]; [cell setProp:[[entity classProperties] containsObject:attrib]]; [cell setKey:[[entity primaryKeyAttributes] containsObject:attrib]]; } [ev sizeToFit]; [ev setNeedsDisplay:YES]; } } int sortSubviews(id view1, id view2, void *context) { DiagramView *self = context; unsigned idx1, idx2; idx1 = [self->_subview_order indexOfObject:view1]; idx2 = [self->_subview_order indexOfObject:view2]; return (idx1 < idx2) ? NSOrderedDescending : NSOrderedAscending; } - (void) orderViewFront:(NSView *)v { int idx = [_subview_order indexOfObject:v]; RETAIN(v); [_subview_order removeObjectAtIndex:idx]; [_subview_order insertObject:v atIndex:0]; RELEASE(v); [self sortSubviewsUsingFunction:(int (*)(id, id, void *))sortSubviews context:self]; [self setNeedsDisplay:YES]; } - (void) setupRelationships { int i,c; NSArray *stuff = [_shownEntities allKeys]; [_relationships removeAllObjects]; for (i = 0, c = [stuff count]; i < c; i++) { int j, d; NSString *entName = [stuff objectAtIndex:i]; EOEntity *ent = [_model entityNamed:entName]; NSArray *rels = [ent relationships]; for (j = 0, d = [rels count]; j < d; j++) { EORelationship *rel = [rels objectAtIndex:j]; EOEntity *dest = [rel destinationEntity]; id srcName = [ent name]; id destName = [dest name]; EntityView *from = [_shownEntities objectForKey:srcName]; EntityView *to = [_shownEntities objectForKey:destName]; NSArray *srcAttribs = [rel sourceAttributes]; NSArray *destAttribs = [rel destinationAttributes]; int k, e; for (k = 0, e = [srcAttribs count]; k < e; k++) { id sAttrib = [srcAttribs objectAtIndex:k]; id dAttrib = [destAttribs objectAtIndex:k]; int sIdx = [[ent attributes] indexOfObject:sAttrib]; int dIdx = [[dest attributes] indexOfObject:dAttrib]; NSRect fromRect = [from attributeRectAtRow:sIdx]; NSRect toRect = [to attributeRectAtRow:dIdx]; NSRect fromViewFrame = [from frame]; NSRect toViewFrame = [to frame]; NSPoint midPoint; NSPoint tmp; float arrowOffset; NSBezierPath *path = [NSBezierPath bezierPath]; BOOL fromRight; BOOL toRight; [path setLineWidth:2]; fromRect.origin.y += fromViewFrame.origin.y; toRect.origin.y += toViewFrame.origin.y; /* which side of the EntityView the arrow line will be connecting * to, for the source and destination entities */ fromRight = (fromViewFrame.origin.x - 40 < toViewFrame.origin.x + toViewFrame.size.width); toRight = (toViewFrame.origin.x - 40 < fromViewFrame.origin.x + fromViewFrame.size.width); if (fromRight) { fromRect.origin.x = fromViewFrame.origin.x + fromViewFrame.size.width + 5; } else { fromRect.origin.x = fromViewFrame.origin.x - 5; } if (toRight) { toRect.origin.x = toViewFrame.origin.x + toViewFrame.size.width; toRect.origin.x += 5; /* <- */ arrowOffset = -5.0; } else { toRect.origin.x = toViewFrame.origin.x; toRect.origin.x -= 5; /* -> */ arrowOffset = 5.0; } fromRect.origin.y = NSMidY(fromRect); toRect.origin.y = NSMidY(toRect); /* every line segment is drawn forwards and backwards so we dont * end up with lightning bolts when filling the arrow */ /* a recursive relationship... * Don't think they are particularly useful but... */ if (fromRect.origin.y == toRect.origin.y && fromRect.origin.x == toRect.origin.x) { [path moveToPoint:NSMakePoint(toRect.origin.x + 15, toRect.origin.y)]; [path lineToPoint:NSMakePoint(toRect.origin.x + 15, toRect.origin.y + 5)]; [path lineToPoint:NSMakePoint(toRect.origin.x + 15, toRect.origin.y)]; [path moveToPoint:NSMakePoint(toRect.origin.x + 15, toRect.origin.y + 5)]; [path lineToPoint:NSMakePoint(toRect.origin.x + 20, toRect.origin.y + 5)]; [path lineToPoint:NSMakePoint(toRect.origin.x + 15, toRect.origin.y + 5)]; [path moveToPoint:NSMakePoint(toRect.origin.x + 20, toRect.origin.y + 5)]; [path lineToPoint:NSMakePoint(toRect.origin.x + 20, toRect.origin.y)]; [path lineToPoint:NSMakePoint(toRect.origin.x + 20, toRect.origin.y + 5)]; } if ((fromRight || toRight) && !(fromRight && toRight)) { /* a line like... +----- * | * -----+ * (from the right side, to the left side or vice versa) */ [path moveToPoint:fromRect.origin]; midPoint.x = (fromRect.origin.x + toRect.origin.x) / 2; midPoint.y = fromRect.origin.y; [path lineToPoint:midPoint]; [path lineToPoint:fromRect.origin]; [path moveToPoint:midPoint]; tmp = midPoint; midPoint.x = (fromRect.origin.x + toRect.origin.x) / 2; midPoint.y = toRect.origin.y; [path lineToPoint:midPoint]; [path lineToPoint:tmp]; [path moveToPoint:midPoint]; [path lineToPoint:toRect.origin]; [path lineToPoint:midPoint]; } else if (fromRight && toRight) { /* need to --+ or -------+ <- joint end or start. * make a line | | * like... -------+ --+ <- joint start or end. * from the right side to the right side. */ NSPoint jointStart; NSPoint jointEnd; if (toRect.origin.x + toRect.size.width < fromRect.origin.x + fromRect.size.width) { jointStart = NSMakePoint(fromRect.origin.x + 20, fromRect.origin.y); jointEnd = NSMakePoint(fromRect.origin.x + 20, toRect.origin.y); } else { jointStart = NSMakePoint(toRect.origin.x + 20, fromRect.origin.y); jointEnd = NSMakePoint(toRect.origin.x + 20, toRect.origin.y); } [path moveToPoint:fromRect.origin]; [path lineToPoint:jointStart]; [path lineToPoint:fromRect.origin]; [path moveToPoint:jointStart]; [path lineToPoint:jointEnd]; [path lineToPoint:jointStart]; [path moveToPoint:jointEnd]; [path lineToPoint:toRect.origin]; [path lineToPoint:jointEnd]; } /* draw arrows.. */ if ([rel isToMany]) { [path moveToPoint:toRect.origin]; [path lineToPoint:NSMakePoint(toRect.origin.x - arrowOffset, toRect.origin.y + arrowOffset)]; [path lineToPoint:NSMakePoint(toRect.origin.x - arrowOffset, toRect.origin.y - arrowOffset)]; [path lineToPoint:toRect.origin]; toRect.origin.x -= arrowOffset; [path moveToPoint:toRect.origin]; [path lineToPoint:NSMakePoint(toRect.origin.x - arrowOffset, toRect.origin.y + arrowOffset)]; [path lineToPoint:NSMakePoint(toRect.origin.x - arrowOffset, toRect.origin.y - arrowOffset)]; [path lineToPoint:toRect.origin]; } else { [path moveToPoint:toRect.origin]; [path lineToPoint:NSMakePoint(toRect.origin.x - arrowOffset, toRect.origin.y + arrowOffset)]; [path lineToPoint:NSMakePoint(toRect.origin.x - arrowOffset, toRect.origin.y - arrowOffset)]; [path lineToPoint:toRect.origin]; } [path closePath]; [_relationships addObject:path]; } } } } - (void) mouseDown:(NSEvent *)ev { /* create new relationshp??*/ } - (BOOL) autoscroll:(NSEvent *)ev { NSPoint pt = [self convertPoint:[ev locationInWindow] fromView:nil]; NSRect r = _frame; BOOL flag; if (!NSPointInRect(pt, r)) { if (pt.x > r.size.width) r.size.width = pt.x; if (pt.y > r.size.height) r.size.height = pt.y; [self setFrameSize:r.size]; } flag = [super autoscroll:ev]; return flag; } - (void) drawRect:(NSRect)aRect { int i, c; [_bgColor set]; NSRectFill([self frame]); [self setupRelationships]; for (i = 0, c = [_relationships count]; i < c; i++) { [[NSColor blackColor] set]; NSBezierPath *path = [_relationships objectAtIndex:i]; [path stroke]; [path fill]; } } @end gnustep-dl2-0.12.0/DBModeler/ConsistencyChecker.m0000644000175000017500000003437011015532156020535 0ustar ayersayers/** ConsistencyChecker.m Author: Matt Rice Date: 2005, 2006 This file is part of DBModeler. DBModeler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. DBModeler 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 General Public License for more details. You should have received a copy of the GNU General Public License along with DBModeler; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA **/ #include "ConsistencyChecker.h" #include "Preferences.h" #include #include #include #include #include #include #include #ifdef NeXT_Foundation_LIBRARY #include #else #include #endif #define MY_PRETTY NSMutableAttributedString \ mutableAttributedStringWithBoldSubstitutionsWithFormat static NSMutableArray *successText; static EOModelerDocument *doc; @implementation ConsistencyChecker +(void) initialize { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(beginConsistencyCheck:) name:EOMCheckConsistencyBeginNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(endConsistencyCheck:) name:EOMCheckConsistencyEndNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(modelConsistencyCheck:) name:EOMCheckConsistencyForModelNotification object:nil]; successText = [[NSMutableArray alloc] initWithCapacity:8]; } + (void) beginConsistencyCheck:(NSNotification *)notif { } + (void) endConsistencyCheck:(NSNotification *)notif { unsigned i,c; doc = [notif object]; for (i = 0, c = [successText count]; i < c; i++) { [doc appendConsistencyCheckSuccessText:[successText objectAtIndex:i]]; } doc = nil; [successText removeAllObjects]; } /* helper functions */ static void pass(BOOL flag, NSAttributedString *as) { if (flag) { [successText addObject:as]; } else [doc appendConsistencyCheckErrorText: as]; } static BOOL isInvalid(NSString *str) { return (str == nil) || ([str length] == 0) ? YES : NO; } + (void) attributeDetailsCheckForModel:(EOModel *)model { NSArray *ents = [model entities]; unsigned i, c; BOOL flag = YES; for (i = 0, c = [ents count]; i < c; i++) { EOEntity *entity = [ents objectAtIndex:i]; NSArray *arr = [entity attributes]; unsigned j, d; for (j = 0, d = [arr count]; j < d; j++) { EOAttribute *attrib = [arr objectAtIndex:j]; NSString *className = [attrib valueClassName]; if ([[attrib className] isEqualToString:@"NSNumber"]) { if (isInvalid([attrib externalType])) { pass(NO,[MY_PRETTY: @"Fail: %@ of type 'NSNumber has no external type\n",[(EOAttribute *)attrib name]]); flag = NO; } } /* TODO check whether NSCalendarDate/NSData require valueFactory...*/ if ((!isInvalid(className)) && (![className isEqual:@"NSString"] && ![className isEqual:@"NSNumber"] && ![className isEqual:@"NSDecimalNumber"] && ![className isEqual:@"NSDate"] && ![className isEqual:@"NSData"]) && (isInvalid([attrib valueFactoryMethodName]))) { pass(NO,[MY_PRETTY: @"Fail: attribute '%@' of type '%@' requires a value factory method name\n",[(EOAttribute *)attrib name], className]); flag = NO; } } /* relationship primary key propagation */ arr = [entity relationships]; for (j = 0, d = [arr count]; j < d; j++) { EORelationship *rel = [arr objectAtIndex:j]; if ([rel propagatesPrimaryKey] == YES) { NSArray *attribs = [rel sourceAttributes]; NSArray *pkAttribs = [[rel entity] primaryKeyAttributes]; unsigned k, e; id pkey; BOOL ok = YES; for (k = 0, e = [pkAttribs count]; ok == YES && k < e; i++) { pkey = [pkAttribs objectAtIndex:k]; ok = [attribs containsObject:pkey]; } if (ok == NO) { pass(NO,[MY_PRETTY: @"Fail: relationship '%@' propagates primary key but its source attributes does not contain the source entity's primary key attributes\n",[(EORelationship *)rel name]]); flag = NO; } ok = YES; attribs = [rel destinationAttributes]; pkAttribs = [[rel destinationEntity] primaryKeyAttributes]; for (k = 0, e = [pkAttribs count]; ok == YES && k < e; i++) { pkey = [pkAttribs objectAtIndex:k]; ok = [attribs containsObject:pkey]; } if (ok == NO) { pass(NO, [MY_PRETTY: @"Fail: relationship '%@' propagates primary key but its destination attributes does not contain the destination entity's primary key attributes\n",[(EORelationship *)rel name]]); flag = NO; } } } } if (flag == YES) pass(YES, [MY_PRETTY: @"Success: attribute detail check\n"]); } + (void) entityStoredProcedureCheckForModel:(EOModel *)model { /* TODO */ } + (void) storedProcedureCheckForModel:(EOModel *)model { /* TODO */ } + (void) inheritanceCheckForModel:(EOModel *)model { BOOL flag = YES; NSArray *ents = [model entities]; unsigned i,c; for (i = 0, c = [ents count]; i < c; i++) { EOEntity *ent = [ents objectAtIndex:i]; NSArray *subEnts = [ent subEntities]; unsigned j, d; for (j = 0, d = [subEnts count]; j < d; j++) { EOEntity *subEnt = [subEnts objectAtIndex:j]; NSArray *arr = [ent attributes]; NSArray *subArr = [subEnt attributes]; unsigned k, e; for (k = 0, e = [arr count]; k < e; k++) { EOAttribute *attrib = [arr objectAtIndex:k]; if (![subArr containsObject:[(EOAttribute *)attrib name]]) { pass(NO, [MY_PRETTY: @"FAIL: sub entity '%@' missing parent's '%@' attribute",[(EOEntity *)subEnt name], [(EOAttribute *)attrib name]]); flag = NO; } } arr = [ent relationships]; for (k = 0, e = [arr count]; k < e; k++) { EORelationship *rel = [arr objectAtIndex:k]; EORelationship *subRel = [subEnt relationshipNamed:[(EORelationship *)rel name]]; if (!subRel || ![[rel definition] isEqual:[subRel definition]]) { pass(NO, [MY_PRETTY: @"FAIL: sub entity '%@' missing relationship '%@' or definitions do not match", [(EOEntity *)subEnt name], [(EORelationship *)rel name]]); flag = NO; } } arr = [ent primaryKeyAttributes]; subArr = [subEnt primaryKeyAttributes]; if (![arr isEqual:subArr]) { pass(NO, [MY_PRETTY: @"FAIL: sub entity '%@' and parent entities primary keys do not match", [(EOEntity *)subEnt name]]); flag = NO; } if ([[subEnt externalName] isEqual:[ent externalName]] && (![subEnt restrictingQualifier] || ![ent restrictingQualifier])) { pass(NO, [MY_PRETTY: @"FAIL: sub entity '%@' and parent entity in same table must contain a restricting qualifier", [(EOEntity *)subEnt name]]); flag = NO; } } } if (flag == YES) { pass(YES, [MY_PRETTY: @"Success: inheritance check"]); } } + (void) relationshipCheckForModel:(EOModel *)model { /* TODO */ NSArray *ents = [model entities]; unsigned i, c; BOOL flag = YES; for (i = 0, c = [ents count]; i < c; i++) { EOEntity *ent = [ents objectAtIndex:i]; NSArray *arr = [ent relationships]; unsigned j, d; for (j = 0, d = [arr count]; j < d; j++) { id rel = [arr objectAtIndex:j]; if (![[rel joins] count]) { pass(NO,[MY_PRETTY: @"Fail: relationship '%@' does not contain a join\n", [(EORelationship *)rel name]]); flag = NO; } if ([rel isToMany] == NO) { NSArray *pkAttribs = [[rel destinationEntity] primaryKeyAttributes]; NSArray *attribs = [rel destinationAttributes]; if (![pkAttribs isEqual:attribs]) { pass(NO, [MY_PRETTY: @"Fail: destination attributes of relationship '%@' are not the destination entity primary keys\n",[(EORelationship *)rel name]]); flag = NO; } } if ([rel propagatesPrimaryKey]) { NSArray *pkAttribs = [[rel entity] primaryKeyAttributes]; NSArray *attribs = [rel sourceAttributes]; unsigned k, e; BOOL ok = YES; for (k = 0, e = [pkAttribs count]; ok == YES && k < e; k++) { ok = [attribs containsObject: [pkAttribs objectAtIndex:k]]; } if (ok == NO) { pass(NO, [MY_PRETTY: @"Fail: relationship '%@' propagates primary keys but does not contain source entities primary key attributes\n", [(EORelationship *)rel name]]); flag = NO; } pkAttribs = [[rel destinationEntity] primaryKeyAttributes]; attribs = [rel destinationAttributes]; for (k = 0, e = [pkAttribs count]; ok == YES && k < e; k++) { ok = [attribs containsObject: [pkAttribs objectAtIndex:k]]; } if (ok == NO) { pass(NO, [MY_PRETTY: @"Fail: relationship '%@' propagates primary keys but does not contain destination entities primary key attributes\n", [(EORelationship *)rel name]]); flag = NO; } if ([[rel inverseRelationship] propagatesPrimaryKey]) { pass(NO,[MY_PRETTY: @"Fail: both relationship '%@' and inverse relationship '%@' should not propagate primary keys\n", [(EORelationship *)rel name], [(EORelationship *)[rel inverseRelationship] name]]); flag = NO; } } } } if (flag == YES) pass(YES, [MY_PRETTY: @"Success: relationship check\n"]); } + (void) primaryKeyCheckForModel:(EOModel *)model { NSArray *ents = [model entities]; unsigned i,c; BOOL flag = YES; for (i = 0, c = [ents count]; i < c; i++) { EOEntity *entity = [ents objectAtIndex:i]; NSArray *arr = [entity primaryKeyAttributes]; if (![arr count]) { pass(NO,[MY_PRETTY: @"Fail: Entity '%@' does not have a primary key.\n", [(EOEntity *)entity name]]); flag = NO; } } if (flag == YES) pass(YES, [MY_PRETTY:@"Success: primary key check\n"]); } + (void) externalNameCheckForModel:(EOModel *)model { NSArray *ents = [model entities]; NSArray *arr; unsigned i, c, j, d; BOOL flag = YES; for (i = 0,c = [ents count]; i < c; i++) { EOEntity *entity = [ents objectAtIndex:i]; NSString *extName = [entity externalName]; if (isInvalid(extName)) { pass(NO,[MY_PRETTY: @"Fail: Entity '%@' does not have an external name\n", [(EOEntity *)entity name]]); flag = NO; } arr = [entity attributes]; for (j = 0, d = [arr count]; j Date: Apr 2005 This file is part of DBModeler. DBModeler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. DBModeler 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 General Public License for more details. You should have received a copy of the GNU General Public License along with DBModeler; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA **/ #include "AdaptorsPanel.h" #include #include static NSArray *_adaptorNames; @implementation AdaptorsPanel - (void) dealloc { DESTROY(_window); DESTROY(_adaptorNames); /* released by window _label brws_adaptors btn_ok btn_cancel */ [super dealloc]; } - (id) init { if ((self = [super init])) { NSRect fr1, fr2; _adaptorNames = RETAIN([EOAdaptor availableAdaptorNames]); /* redo all these numbers so buttons and labels are on the right? */ _window = [[NSWindow alloc] initWithContentRect: NSMakeRect(200,200,200,300) styleMask: NSBorderlessWindowMask | NSTitledWindowMask backing: NSBackingStoreBuffered defer: YES]; [_window setTitle: @"Select adaptor"]; [_window setReleasedWhenClosed:NO]; brws_adaptors = [[NSBrowser alloc] initWithFrame: NSMakeRect(5,30,190,240)]; [brws_adaptors setDelegate: self]; [brws_adaptors addColumn]; [brws_adaptors setTitle: @"Available adaptors" ofColumn: 0]; [brws_adaptors setAllowsEmptySelection: NO]; [brws_adaptors setTarget:self]; [brws_adaptors setDoubleAction:@selector(ok:)]; btn_ok = [[NSButton alloc] initWithFrame: NSMakeRect(5,5,50,20)]; [btn_ok setTitle: @"ok"]; [btn_ok setTarget: self]; [btn_ok setAction: @selector(ok:)]; btn_cancel = [[NSButton alloc] initWithFrame: NSMakeRect(60,5,50,20)]; [btn_cancel setTitle: @"cancel"]; [btn_cancel setTarget: self]; [btn_cancel setAction: @selector(cancel:)]; [[_window contentView] addSubview: brws_adaptors]; [[_window contentView] addSubview: btn_ok]; [[_window contentView] addSubview: btn_cancel]; [_window setInitialFirstResponder:brws_adaptors]; [brws_adaptors setNextResponder:btn_ok]; [btn_ok setNextResponder:btn_cancel]; // hmm.. this seems to cause an infinate loop in the responder chain somehow // when in the modal loop. // [btn_cancel setNextResponder:brws_adaptors]; [btn_ok setKeyEquivalent:@"\r"]; [btn_ok setImage:[NSImage imageNamed:@"common_ret"]]; [btn_ok setAlternateImage:[NSImage imageNamed:@"common_retH"]]; [btn_ok setImagePosition:NSImageRight]; [btn_ok sizeToFit]; fr1 = [btn_ok frame]; fr2 = [btn_cancel frame]; fr1.size.width = fr2.size.width = fr1.size.width > fr2.size.width ? fr1.size.width : fr2.size.width; fr1.size.height = fr2.size.height = fr1.size.height > fr2.size.height ? fr1.size.height : fr2.size.height; fr2.origin.x = NSMaxX(fr1) + 8; [btn_ok setFrame:fr1]; [btn_cancel setFrame:fr2]; fr2 = [brws_adaptors frame]; fr2.origin.y = NSMaxY(fr1) + 8; [brws_adaptors setFrame:fr2]; RELEASE(_label); RELEASE(brws_adaptors); RELEASE(btn_ok); RELEASE(btn_cancel); } return self; } - (NSString *) runAdaptorsPanel { NSString *selection; if ([NSApp runModalForWindow:_window] == NSRunAbortedResponse) { selection = nil; [_window orderOut:self]; } else { selection = [[brws_adaptors selectedCell] stringValue]; [_window orderOut:self]; } return selection; } /* button actions */ - (void) ok: (id)sender { [NSApp stopModalWithCode:NSRunStoppedResponse]; } - (void) cancel: (id)sender { [NSApp stopModalWithCode:NSRunAbortedResponse]; } /* NSBrowser delegate stuff */ - (int) browser:(id)sender numberOfRowsInColumn:(int)column { return [_adaptorNames count]; } - (void)browser:(NSBrowser*)sender willDisplayCell:(NSBrowserCell*)cell atRow:(int)row column:(int)column { [cell setLeaf:YES]; [cell setTitle: [_adaptorNames objectAtIndex:row]]; } @end gnustep-dl2-0.12.0/DBModeler/NSView+Additions.h0000644000175000017500000000201511011131075020005 0ustar ayersayers/** NSView+Additions.h Author: Matt Rice Date: Oct 2006 This file is part of DBModeler. DBModeler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. DBModeler 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 General Public License for more details. You should have received a copy of the GNU General Public License along with DBModeler; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifdef NeXT_GUI_LIBRARY #include #else #include #endif @interface NSView (Additions) - (void) orderViewFront:(NSView *)v; @end gnustep-dl2-0.12.0/DBModeler/ModelerEntityEditor.h0000644000175000017500000000261311015532156020670 0ustar ayersayers#ifndef __ModelerEntityEditor_H_ #define __ModelerEntityEditor_H_ /* ModelerEntityEditor.h Author: Matt Rice Date: Apr 2005 This file is part of DBModeler. DBModeler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. DBModeler 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 General Public License for more details. You should have received a copy of the GNU General Public License along with DBModeler; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "ModelerTableEmbedibleEditor.h" #include @class NSBox; @class NSWindow; @class NSTableView; @class NSSplitView; @class EODisplayGroup; @class PlusMinusView; @interface ModelerEntityEditor : ModelerTableEmbedibleEditor { NSTableView *_topTable; NSTableView *_bottomTable; NSSplitView *_splitView; NSWindow *_window; NSBox *_box; EODisplayGroup *dg; } -(void)objectWillChange:(id)anObject; @end #endif // __ModelerEntityEditor_H_ gnustep-dl2-0.12.0/DBModeler/Inspectors/0000755000175000017500000000000011147475623016726 5ustar ayersayersgnustep-dl2-0.12.0/DBModeler/Inspectors/AdvancedEntityInspector.h0000644000175000017500000000266511011131075023655 0ustar ayersayers/* AdvancedEntityInspector.h Author: Matt Rice Date: 2005, 2006 This file is part of DBModeler. DBModeler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. DBModeler 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 General Public License for more details. You should have received a copy of the GNU General Public License along with DBModeler; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef NeXT_GUI_LIBRARY #include #else #include #endif #include @class NSButton; @class NSTableView; @interface AdvancedEntityInspector : EOMInspector { IBOutlet NSButton *abstract; IBOutlet NSButton *readOnly; IBOutlet NSButton *cachesObjects; IBOutlet NSButton *parent; IBOutlet NSTableView *entities; } - (IBAction) setAbstractAction:(id)sender; - (IBAction) setReadOnlyAction:(id)sender; - (IBAction) setCachesObjectsAction:(id)sender; - (IBAction) parentAction:(id)sender; - (IBAction) entityAction:(id)sender; @end gnustep-dl2-0.12.0/DBModeler/Inspectors/AttributeInspector.m0000644000175000017500000001615111015532156022727 0ustar ayersayers /* AttributesInspector.m Author: Matt Rice Date: 2005, 2006 This file is part of DBModeler. DBModeler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. DBModeler 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 General Public License for more details. You should have received a copy of the GNU General Public License along with DBModeler; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "AttributeInspector.h" #ifdef NeXT_Foundation_LIBRARY #include #else #include #endif #include #include #define NO_ZEROS(x, i) i ? [x setIntValue:i] : [x setStringValue:@""]; @implementation AttributeInspector - (void) awakeFromNib { RETAIN(_internalData); _flipDict = [[NSDictionary alloc] initWithObjectsAndKeys: _stringFlip, @"String", _customFlip, @"Custom", _dataFlip, @"Data", _dateFlip, @"Date", _decimalFlip, @"Decimal Number", _numberFlip, @"Number", nil]; _valueTypeDict = [[NSDictionary alloc] initWithObjectsAndKeys: @"i", @"int", @"d", @"double", @"f", @"float", @"c", @"char", @"s", @"short", @"I", @"unsigned int", @"C", @"unsigned char", @"S", @"unsigned short", @"l", @"long", @"L", @"unsigned long", @"u", @"long long", @"U", @"unsigned long long", @"char", @"c", @"unsigned char", @"C", @"short", @"s", @"unsigned short", @"S", @"int", @"i", @"unsigned int", @"I", @"long", @"l", @"unsigned long", @"L", @"long long", @"u", @"unsigned long long", @"U", @"float", @"f", @"double", @"d", nil]; _classTitleDict = [[NSDictionary alloc] initWithObjectsAndKeys: @"String", @"NSString", @"Data", @"NSData", @"Number", @"NSNumber", @"Date", @"NSCalendarDate", @"Decimal Number", @"NSDecimalNumber", @"NSString", @"String", @"NSData", @"Data", @"NSNumber", @"Number", @"NSDecimalNumber", @"Decimal Number", @"NSCalendarDate", @"Date", nil]; } - (NSString *) _titleForPopUp { NSString *vcn = [(EOAttribute *)[self selectedObject] valueClassName]; NSString *ret; ret = [_classTitleDict objectForKey:vcn]; if (!ret) return @"Custom"; return ret; } - (NSString *)_classNameForTitle:(NSString *)title { return [_classTitleDict objectForKey:title]; } - (NSBox *) _viewForTitle:(NSString *)title { return (NSBox *)[_flipDict objectForKey:title]; } - (float) displayOrder { return 0; } - (IBAction) setName:(id)sender; { [(EOAttribute *)[self selectedObject] setName:[sender stringValue]]; } - (IBAction) setExternalName:(id)sender; { [(EOAttribute *)[self selectedObject] setColumnName:[sender stringValue]]; } - (IBAction) setExternalType:(id)sender; { [(EOAttribute *)[self selectedObject] setExternalType:[sender stringValue]]; } - (IBAction) selectInternalDataType:(id)sender; { EOAttribute *obj = [self selectedObject]; NSString *title = [_flipSelect titleOfSelectedItem]; NSString *className = [self _classNameForTitle:title]; if (![[obj valueClassName] isEqual:className]) { [obj setValueClassName:className]; } if ([className isEqual:@"NSNumber"]) { if (![obj valueType]) { [obj setValueType:@"d"]; } } else { [obj setValueType:@""]; } [self refresh]; } - (void) refresh { EOAttribute *obj = [self selectedObject]; NSString *title = [self _titleForPopUp]; NSBox *flipTo = [self _viewForTitle:title]; [_nameField setStringValue:[obj name]]; [_extNameField setStringValue:[obj columnName]]; [_extTypeField setStringValue:[obj externalType]]; [_flipSelect selectItemWithTitle:title]; [flipTo setFrame: [_flipView frame]]; [_internalData replaceSubview:_flipView with:flipTo]; _flipView = flipTo; [self performSelector: NSSelectorFromString([@"update" stringByAppendingString:[title stringByReplacingString:@" " withString:@""]])]; } - (void) updateString { int tmp; tmp = [[self selectedObject] width]; NO_ZEROS(_string_width,tmp); } - (void) updateCustom { EOAttribute *obj = [self selectedObject]; int tmp; tmp = [obj width]; NO_ZEROS(_custom_width, tmp); [_custom_class setStringValue:[obj valueClassName]]; [_custom_factory setStringValue:[obj valueFactoryMethodName]]; [_custom_conversion setStringValue:[obj adaptorValueConversionMethodName]]; [_custom_arg selectItemAtIndex: [_custom_arg indexOfItemWithTag: [obj factoryMethodArgumentType]]]; } - (void) updateDecimalNumber { EOAttribute *obj = [self selectedObject]; int tmp; tmp = [obj width]; NO_ZEROS(_decimal_width, tmp); tmp = [obj precision]; NO_ZEROS(_decimal_precision, tmp); } - (void) updateNumber { EOAttribute *obj = [self selectedObject]; NSString *valType = [obj valueType]; NSString *valueTypeName; valueTypeName = [_valueTypeDict objectForKey: valType]; [_valueTypeSelect selectItemWithTitle:valueTypeName]; } - (void) updateDate { } - (void) updateData { int tmp; tmp = [[self selectedObject] width]; NO_ZEROS(_data_width, tmp); } - (BOOL) canInspectObject:(id)obj { return [obj isKindOfClass:[EOAttribute class]]; } - (IBAction) setValueType:(id)sender { EOAttribute *obj = [self selectedObject]; NSString *valueType; if (sender == _valueTypeSelect) { valueType = [_valueTypeDict objectForKey:[sender titleOfSelectedItem]]; } else if (sender == self) { valueType = @""; } [obj setValueType:valueType]; } - (IBAction) setTimeZone:(id)sender; { // fixme } - (IBAction) setWidth:(id)sender; { [(EOAttribute *)[self selectedObject] setWidth:[sender intValue]]; } - (IBAction) setPrecision:(id)sender; { [(EOAttribute *)[self selectedObject] setPrecision:[sender intValue]]; } - (IBAction) setClassName:(id)sender; { [(EOAttribute *)[self selectedObject] setValueClassName:[sender stringValue]]; } - (IBAction) setFactoryMethod:(id)sender; { [[self selectedObject] setValueFactoryMethodName:[sender stringValue]]; } - (IBAction) setConversionMethod:(id)sender; { [[self selectedObject] setAdaptorValueConversionMethodName:[sender stringValue]]; } - (IBAction) setInitArgument:(id)sender { [[self selectedObject] setFactoryMethodArgumentType:[[sender selectedItem] tag]]; } @end gnustep-dl2-0.12.0/DBModeler/Inspectors/AdvancedEntityInspector.m0000644000175000017500000000674611015532156023677 0ustar ayersayers/* AdvancedEntityInspector.m Author: Matt Rice Date: 2005, 2006 This file is part of DBModeler. DBModeler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. DBModeler 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 General Public License for more details. You should have received a copy of the GNU General Public License along with DBModeler; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "AdvancedEntityInspector.h" #include #include #include #ifdef NeXT_GUI_LIBRARY #include #else #include #include #endif #ifdef NeXT_Foundation_LIBRARY #include #else #include #endif @implementation AdvancedEntityInspector - (NSString *)displayName { return @"Adv Entity"; } - (BOOL) canInspectObject:(id)anObject { return [anObject isKindOfClass:[EOEntity class]]; } - (void) setReadOnlyAction:(id)sender { [(EOEntity *)[self selectedObject] setReadOnly:[readOnly state] == NSOnState ? YES : NO]; } - (void) setAbstractAction:(id)sender { [(EOEntity *)[self selectedObject] setIsAbstractEntity:[abstract state] == NSOnState ? YES : NO]; } - (void) setCachesObjectsAction:(id)sender { [(EOEntity *)[self selectedObject] setCachesObjects:[cachesObjects state] == NSOnState ? YES : NO]; } - (IBAction) parentAction:(id)sender; { EOEntity *selObj; EOEntity *selectedParent; int selectedRow; selectedRow = [entities selectedRow]; if (selectedRow == -1) return; selObj = [self selectedObject]; selectedParent = [[[selObj model] entities] objectAtIndex:[entities selectedRow]]; if ([selObj parentEntity] == selectedParent) { [selectedParent removeSubEntity:selObj]; } else { [[selObj parentEntity] removeSubEntity:selObj]; [selectedParent addSubEntity:selObj]; } } - (void) refresh { [abstract setState:[(EOEntity *)[self selectedObject] isAbstractEntity] ? NSOnState : NSOffState]; [readOnly setState:[(EOEntity *)[self selectedObject] isReadOnly] ? NSOnState : NSOffState]; [cachesObjects setState:[(EOEntity *)[self selectedObject] cachesObjects] ? NSOnState : NSOffState]; [entities reloadData]; [entities deselectAll:self]; [parent setEnabled:NO]; [parent setState:NSOnState]; } - (void) entityAction:(id)sender { EOEntity *selObj; EOEntity *selectedParent; int selectedRow = [sender selectedRow]; selObj = [self selectedObject]; if (selectedRow == -1) return; selectedParent = [[[selObj model] entities] objectAtIndex:selectedRow]; [parent setEnabled:YES]; [parent setState: ([selObj parentEntity] == selectedParent) ? NSOnState : NSOffState]; } - (int) numberOfRowsInTableView:(NSTableView *)tv { return [[[[self selectedObject] model] entities] count]; } - (id) tableView:(NSTableView *)tv objectValueForTableColumn:(NSTableColumn *)tc row:(int)row { return [[[[[self selectedObject] model] entities] objectAtIndex:row] name]; } @end gnustep-dl2-0.12.0/DBModeler/Inspectors/RelationshipInspector.h0000644000175000017500000000304011015532156023411 0ustar ayersayers /* RelationshipInspector.h Author: Matt Rice Date: Apr 2005 This file is part of DBModeler. DBModeler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. DBModeler 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 General Public License for more details. You should have received a copy of the GNU General Public License along with DBModeler; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #ifdef NeXT_GUI_LIBRARY #include #else #include #endif @class EOModel; @class EOEntity; @interface RelationshipInspector : EOMInspector { IBOutlet NSTextField *name_textField; IBOutlet NSPopUpButton *model_popup; IBOutlet NSMatrix *joinCardinality_matrix; IBOutlet NSPopUpButton *joinSemantic_popup; IBOutlet NSTableView *destEntity_tableView; IBOutlet NSTableView *srcAttrib_tableView; IBOutlet NSTableView *destAttrib_tableView; IBOutlet NSButton *connect_button; } - (IBAction) connectionChanged:(id)sender; - (IBAction) nameChanged:(id)sender; @end gnustep-dl2-0.12.0/DBModeler/Inspectors/RelationshipInspector.tiff0000644000175000017500000001050610477373673024141 0ustar ayersayersPNG  IHDR<4֯[sBIT|dtEXtSoftwarewww.inkscape.org<IDAThZyp]Wy}V햟dIŻ-qI !@J:tV2LۡP)]NK 4 -3PRIpljw[YoO{ᄏHrdY˳i3Ϻl!fX_WDK iYiz͂PC$D /'wyzom|v囫HaR__/HQtsL2" Dl.v3 Յ>$fu;xSSwUB-+ 6*iEhqҨT}D1"a@QaZ. q ӊy.f_;1w,X~fC,DŽt:~jhl?mz}9Xe|شDqHY XPbٸz%}O@v=m|H,N,Srٟ83ڽHnW|?@mj=jAyf%IQoky!h3/O 9Ɇ&g&$Xv;sFVif VHw7CMo+bLPBXigTwbd)̤L?@7k6/'+.Fzb]0&sد.33gjѓw;v@HFjBsc,}E#Q5ž'23ZN-Hwқƺ͓˒"HM 7W_٭DNS#B3f {-8Pw`_>2Bn(ԟ8c}!c}ݤ;xRCmvf;̷̸b m?J3:3{ 鱎\ϥwb;f>=MDܜ`R ט>˶ 3sl`f1, iT1Lɿw=%"3TCj_bG 5`&B3_#Ng_^K?Z+. 1 0 `T1f^V-tsjMc3sDMv?g dzqgq7޳rz"vT,X%46]B3YK)D?=>'̷Nr ;p'q@A>HQ 3s48jT|+O _ܛLer>īBB@°e ~8˳L`!<Lұ@'{g'!_m27+!`>~jć]༠B7Hٿfw{dy4m9?=~[c,ݮUy_fR:wo6*V߱h&03=Pw@Q +jZvmz{}H衰̥(_-H{dv3߲͡@2.PJQfeP&sJ`X+L-=gͮI3){\> #T\_on= J1]&Gz8=ufxj_;О#kZLV|#(,vLFXr=7қwn(v+ܡΔ:aI"D`9sO\fzffS hQRnfx0Ch&>zpJ>owJ+3JfN_= 9"j$D6uw}'ӣyjڙxEX"l#oTڗ\F3rݑnO]!й\"> makQ>pE+H۝َqRnCMPan;p?/>\[lM uB1¯9Slw˵vs@D_'"c^0=<]KiɈaۍʭOvx_Xfg'z{dgmZ l^\@F3, \ɟeN'0u1G$@@'3W-hjZm}EH%J0$Mvˉo/]T<םRgekO]>3͉_@`νen[^7ZQ:x+}OgT>CJKb)0AI$B!0ڙm~}s|"P%%Q;x֑Eu f[ Xv秘K[vXH@ Ū (Vw"94?e0;-qMIa%Xkͽ]&1;S,[;9y۠X,nL&x k*-lebȫK  7+*7`$$L#*UH(>*H 7)Xbw_> jt'W1]9`jQZנ';㮴-igcD@ Hp͚oJ+̜n{prY']sz.0<Xeu4'3A(ݪ֔X{y7c\YPwhqV Μ˂$bLJH";gd8oJPx[@gwfNCD ptۑQ(](iƊBQ =0 /*{nYfɡ!oig_u:bc]MG6-V @DN֓ 7\p_Q;HUZ5s1&qOx+C]yܲؿB.ٖZaR ][{fc̩G06PhxP KeA-D̾r:e*E)z[+wsz"`ݽ1jv=M%=bvLjԳOOaכ\5.i{-}5siyjSS$uF[lLn{;k֥-<Dx.h^Υ'F܁ox)sp${?" +EFzl y=z<3#j&=tO:]nGj7 ̍{e{G\'"M+k٭B]n3k6KK;>2huH)s&-OjW,{2+ٱIݬ2}qPh/U/5]Lϫȶ0vsM!)PtR?;S`eAD:AGfY )\ݑ`Val'eԂ5VzW#++{{ljH 5^\i5+tݑnf)s]Of.6a-`w;@C2ղ]o9a]I5V\euǯݛ] Li]$#ܜwn C+1*Q۔,vVϨ;jqf&wZ_d;t@xM3*o~fJcnn8z~ꕅ\w%twYI=NcvKcƔЌl`a൯)~jgu] 2Ӄvݷ8$H?TEuzy=mQ:dAB!bZ֊ow¾/^/-X&Ӭz|8~4Fje5{xY^RtE =*w\?ƈWzs_eUwjg*#J0.V +J%E l,̰@?i  jRIENDB`gnustep-dl2-0.12.0/DBModeler/Inspectors/AdvancedEntityInspector.gorm/0000755000175000017500000000000011147475623024462 5ustar ayersayersgnustep-dl2-0.12.0/DBModeler/Inspectors/AdvancedEntityInspector.gorm/objects.gorm0000644000175000017500000001314510507774114027001 0ustar ayersayersGNUstep archive00002c24:00000026:0000009d:00000001:01GSNibContainer1NSObject01 GSMutableSet1 NSMutableSet1NSSet&01GSWindowTemplate1GSClassSwapper01NSString&%NSPanel1 NSPanel1 NSWindow1 NSResponder% ? A C C&% C D^@01 NSView% ? A C C  C C&01 NSMutableArray1NSArray&01NSBox% A A  C| B  C| B&0 &0 % @ @ Cn B  Cn B&0 &0 1NSButton1 NSControl% BX BH B A  B A&0 &%0 1 NSButtonCell1 NSActionCell1NSCell0& % Read only01NSImage01NSMutableString&%common_SwitchOff01NSFont%&&&&&&&&%0&0&00&%common_SwitchOn&&&0% B A Bx A  Bx A&0 &%00&%Abstract&&&&&&&&%0&0&&&&0% A @ B A  B A&0 &%00&%Caches objects&&&&&&&&%0 &0!&&&&0"0#&%Options#&&&&&&&& @ @%%0$1 NSScrollView% A C7 C| CC  C| CC&0% &0&1 NSClipView% A A Ce C)  Ce C)&0' &0(1 NSTableView%  Ce C!  Ce C!&0) &%0*0+&&&&&&&&&0, &0-1 NSTableColumn0.&%column1 Ce A GP0/1NSTableHeaderCell1NSTextFieldCell00&% 01% 0&&&&&&&&0%021NSColor03&%NSNamedColorSpace04&%System05&%controlShadowColor063407&%windowFrameTextColor0809&%neuf9&&&&&&&&0%0:30;&%System0<&%textBackgroundColor0=3;0>& % textColor0?3;0@& % gridColor0A3;0B&%controlBackgroundColor0C1NSTableHeaderView%  Ce A  Ce A&0D &0E1 GSTableCornerView% @ @ A A  A A&0F &%% A @ @A0G1! NSScroller% @ A A C)  A C)&0H &%0I+&&&&&&&&&$2 _doScroll:v12@0:4@80J% A @ Ce A  Ce A&0K &C0L3;0M& % controlColorE&% A A A A GJ0N% C5 C B A  B A&0O &%0P0Q& % Set ParentQ&&&&&&&&%0R&0S& % Unset Parent&&&0T30U&%System0V&%windowBackgroundColor0W&%Window0X&%Inspector WindowX @@ B F@ F@%&   D D0Y &0Z &0[1"NSMutableDictionary1# NSDictionary& 0\& % ScrollView(0)$0]&%NSOwner0^&%AdvancedEntityInspector0_&%View(1) 0`& % TableView(0)(0a&%Box(0)0b& % Button(1)0c& % Button(3)N0d&%TableColumn(1)0e0f&%column2 BT A GP0g0h&% 1h&&&&&&&&0%0i30j&%System0k&%controlHighlightColor0l3j0m&%controlTextColor0n0o&%threeo&&&&&&&&0%:=0p&%View(0)0q& % InspectorWin0r& % Button(0) 0s& % Button(2)0t&%TableColumn(0)-0u &0v1$NSNibConnectorq0w&%NSOwner0x$pq0y$ra0z$ba0{$sa0|$ap0}$_a0~1%NSNibOutletConnectorwr0&%readOnly0%wb0&%abstract0%ws0& % cachesObjects0%wq0&%window01&NSNibControlConnectorrw0&%setReadOnlyAction:0&bw0&%setAbstractAction:0&sw0&%setCachesObjectsAction:0$\p0$`\0$t`0$d`0$cp0&cw0& % parentAction:0&`w0& % entityAction:0%w`0&%entities0%wc0&%parent0%`w0&%delegate0%`w0& % dataSource0"&gnustep-dl2-0.12.0/DBModeler/Inspectors/AdvancedEntityInspector.gorm/data.classes0000644000175000017500000000123510507774114026747 0ustar ayersayers{ "## Comment" = "Do NOT change this file, Gorm maintains it"; AdvancedEntityInspector = { Actions = ( "setAbstractAction:", "setReadOnlyAction:", "setCachesObjectsAction:", "entityAction:", "parentAction:" ); Outlets = ( abstract, readOnly, cachesObjects, entities, parent ); Super = EOMInspector; }; EOMInspector = { Actions = ( ); Outlets = ( window, view ); Super = NSObject; }; FirstResponder = { Actions = ( "entityAction:", "parentAction:", "setAbstractAction:", "setCachesObjectsAction:", "setReadOnlyAction:" ); Super = NSObject; }; }gnustep-dl2-0.12.0/DBModeler/Inspectors/AdvancedEntityInspector.gorm/data.info0000644000175000017500000000027010507736305026243 0ustar ayersayersGNUstep archive00002c24:00000003:00000003:00000000:01GormFilePrefsManager1NSObject%01NSString&%Latest Version0& % Typed Streamgnustep-dl2-0.12.0/DBModeler/Inspectors/RelationshipInspector.gorm/0000755000175000017500000000000011147475623024221 5ustar ayersayersgnustep-dl2-0.12.0/DBModeler/Inspectors/RelationshipInspector.gorm/objects.gorm0000644000175000017500000003362310240771767026550 0ustar ayersayersGNUstep archive00002af9:0000002a:00000182:00000001:01GSNibContainer1NSObject01NSMutableDictionary1 NSDictionary&"01NSString& % TableColumn01 NSTableColumn0&%column1 B A GP01NSTableHeaderCell1NSTextFieldCell1 NSActionCell1 NSCell0&% 01 NSFont% &&&&&&&&0%0 1 NSColor0 &%NSNamedColorSpace0 &%System0 &%controlShadowColor0 0&%System0&%windowFrameTextColor00&%cinq0 %&&&&&&&&0%0 0&%textBackgroundColor0 0& % textColor0&%Button01 NSButton1 NSControl1NSView1 NSResponder% C  B A  B A&01NSMutableArray1NSArray&%01 NSButtonCell0&%Connect&&&&&&&&%0&0& % Disconnect&&&0&% Box101NSBox% A0 A  C| C*  C| C*&0 &0!% @ @ Cn C  Cn C&0"&0#1 NSTextField% A B B A  B A&0$&%0%0&&%Source attribute0' % A&&&&&&&&0%0( 0)&%System0*&%textBackgroundColor0+ )0,& % textColor0-% C B B A  B A&0.&%0/00&%Destination attribute'&&&&&&&&0%01 02&%System03&%textBackgroundColor04 205& % textColor061 NSScrollView% B A B B  B B&07&081 NSClipView% A A B B  B B&09&0:1 NSTableView%  B C!  B C!&0;&%0< 0=&&&&&&&&&0>&0?0@&%column1 B A GP0A0B&% &&&&&&&&0% 0C 0D&%System0E&%windowFrameTextColor0F0G&%quatreG&&&&&&&&0%0H D0I&%textBackgroundColor0J D0K& % textColor0L D0M& % gridColor0N D0O&%controlBackgroundColor0P1NSTableHeaderView%  B A  B A&0Q&0R1GSTableCornerView% @ @ A A  A A&0S&%% A @ @@N0T1 NSScroller% @ A A B  A B&0U&%0V =&&&&&&&&&62 _doScroll:v12@0:4@80W% A @ B A  B A&0X&P0Y D0Z& % controlColorR8% A A A A TW0[% A B B  B B&0\&0]% A A B B  B B&0^&0_%  B C!  B C!&0`&%0a 0b&&&&&&&&&0c&0d0e&%column1 B A GP0f0g&% &&&&&&&&0% 0h 0i&%System0j&%windowFrameTextColor0kGG&&&&&&&&0%0l i0m&%textBackgroundColor0n i0o& % textColor0p i0q& % gridColor0r i0s&%controlBackgroundColor0t%  B A  B A&0u&0v% @ @ A A  A A&0w&%% A @ @@r0x% @ A A B  A B&0y&%0z b&&&&&&&&&[0{% A @ B A  B A&0|&t0} i0~& % controlColorv]% A A A A x{0 0&%Join&&&&&&&& @ @%%0& % TextField0% BD C B A  B A&0&%00&%Name'&&&&&&&&0%0 0&%System0&%textBackgroundColor0 0& % textColor0&%GSCustomClassMap0&0&% GormNSTableView1_0&% GormNSTableView2:0& % InspectorWin01NSWindow%  C C&% C[ D70%  C C  C C&0&0% C C B A  B A&0&%00&%Text&&&&&&&&0%0 0&%System0&%textBackgroundColor0 0& % textColor0% A C9 C} C*  C} C*&0&0% @k @h CnG C  CnG C&0&0% Be Bp B0 A  B0 A&0&%00&%Model0 % A@&&&&&&&&0%0 0&%System0&%textBackgroundColor0 0& % textColor0% B*e B B$ A  B$ A&0&%00&%Entity&&&&&&&&0%0 0&%System0&%textBackgroundColor0 0& % textColor01 NSPopUpButton% B2 Bp C A  C A&0&%01NSPopUpButtonCell1NSMenuItemCell0&&&&&&&&&01 NSMenu0&0&01! NSMenuItem0&%Item 10&&&%01"NSImage0& % common_Nibble%0!0&%Item 2&&%%0!0±&%Item 3&&%%%0ñ&0ı&&&&%%%%%0ű% B2  C B  C B&0Ʊ&0DZ% A A B B  B B&0ȱ&0ɱ%  B C!  B C!&0ʱ&%0˱ 0̱&&&&&&&&&0ͱ&0α 0ϱ& % gridColor0б 0ѱ&%controlBackgroundColor0ұ%  B A  B A&0ӱ&0Ա% @ @ A A  A A&0ձ&%% A @ @@0ֱ% A @ B A  B A&0ױ&0ر 0ٱ& % controlColor0ڱ% @ A A B  A B&0۱&%0ܱ ̐&&&&&&&&&Ų԰% A A A A 01#NSMatrix% A B BH  B BH&0ޱ&%0߱ 0&&&&&&&&&%% B A 0 0&%System0&%controlBackgroundColor0& % NSButtonCell00&%Radio0"01$NSMutableString&% common_RadioOff&&&&&&&&%0&0&0"0$&% common_RadioOn&&&%%0&00&%To one&&&&&&&&%0&&&&00&%To many&&&&&&&&%0&&&&0%  B A  B A&0&%00&&&&&&&&&0 0&0&0!0&%Inner0&&&%%0!0& % Full Outer&&%%P!P& % Left outer&&%%P!P& % Right outerP&&&%%%P&P&&&&%%%%%P P& % Destination&&&&&&&& @k @h%%P P &%windowBackgroundColorP &%WindowP &%Inspector Window  ? ? F@ F@%P & % ScrollViewP& %  TextField1P&%BoxP& %  TextField2P& %  TextField3P&%GormNSTableViewP& %  TextField4#P& %  TextField5-P& %  ScrollView1[P& %  ScrollView26P&%NSOwnerP&% RelationshipInspectorP& %  MenuItem1P&% GormNSPopUpButton1P& %  TableColumn1PP&%column2 BT A GPPP&% &&&&&&&&0%P P!&%controlHighlightColor P"P#&%three#&&&&&&&&0%P$& %  MenuItem2P%&%MenuItemP&& %  TableColumn2dP'&%MatrixP(& %  MenuItem3P)& %  TableColumn3P*P+&%column2 BT A GPP,P-&% &&&&&&&&0% hP.P/&%five/&&&&&&&&0%lnP0& %  MenuItem4P1& %  TableColumn4?P2& %  MenuItem5P3&%GormNSPopUpButtonP4& %  TableColumn5P5P6&%column2 BT A GPP7P8&% &&&&&&&&0% CP9//&&&&&&&&0%HJP:& %  MenuItem6P;&33P<1%NSNibConnectorP=&%NSOwnerP>%P?%3P@%PA% PB%PC%PD%PE%PF%'PG%PH%PI%PJ%PK%&PL%)PM%PN%PO%1PP%4PQ%PR%PS%PT%PU1&NSNibOutletConnector=PV&% windowPW&=3PX& %  model_popupPY&=PZ&% name_textFieldP[&=P\&% srcAttrib_tableViewP]&=P^&% destAttrib_tableViewP_&=P`&% destEntity_tableViewPa&=Pb$&% delegatePc&=Pd$& %  dataSourcePe&=dPf&=bPg&=dPh&=bPi%Pj1'NSNibControlConnector=Pk&% connectionChanged:Pl&=Pm$&% connect_buttonPn'=Po& %  nameChanged:Pp&='Pq&% joinCardinality_matrixPr&=Ps&% joinSemantic_popupPt%Pu&%MenuItemPv%Pw%$Px''=Py&% cardinalityChanged:Pz'=P{&% semanticChanged:P|%(P}%0P~%2P%:P1( GSMutableSet1) NSMutableSet1*NSSet&gnustep-dl2-0.12.0/DBModeler/Inspectors/RelationshipInspector.gorm/data.classes0000644000175000017500000000132510240771767026513 0ustar ayersayers{ "## Comment" = "Do NOT change this file, Gorm maintains it"; EOMInspector = { Actions = ( ); Outlets = ( view, window ); Super = NSObject; }; FirstResponder = { Actions = ( "cardinalityChanged:", "connectionChanged:", "nameChanged:", "semanticChanged:" ); Super = NSObject; }; RelationshipInspector = { Actions = ( "connectionChanged:", "cardinalityChanged:", "nameChanged:", "semanticChanged:" ); Outlets = ( name_textField, model_popup, destEntity_tableView, joinCardinality_matrix, joinSemantic_popup, srcAttrib_tableView, destAttrib_tableView, connect_button ); Super = EOMInspector; }; }gnustep-dl2-0.12.0/DBModeler/Inspectors/RelationshipInspector.gorm/data.info0000644000175000017500000000027010240771767026007 0ustar ayersayersGNUstep archive00002af9:00000003:00000003:00000000:01GormFilePrefsManager1NSObject% 01NSString&%Latest Version0& % Typed Streamgnustep-dl2-0.12.0/DBModeler/Inspectors/GNUmakefile0000644000175000017500000000304511017542132020764 0ustar ayersayers# # DBModeler/Inspectors makefile for GNUstep Database Library. # # Copyright (C) 2005,2006 Free Software Foundation, Inc. # # Author: Matt Rice # # 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 3 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, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # include ../../common.make include $(GNUSTEP_MAKEFILES)/common.make SUBPROJECT_NAME=Inspectors ADDITIONAL_INCLUDE_DIRS+=-I../../ Inspectors_NEEDS_GUI=yes Inspectors_HAS_RESOURCE_BUNDLE=yes Inspectors_RESOURCE_FILES+= \ RelationshipInspector.gorm \ RelationshipInspector.tiff Inspectors_OBJC_FILES+=RelationshipInspector.m Inspectors_RESOURCE_FILES+=AttributeInspector.gorm Inspectors_OBJC_FILES+=AttributeInspector.m Inspectors_RESOURCE_FILES+=AdvancedEntityInspector.gorm Inspectors_OBJC_FILES+=AdvancedEntityInspector.m include $(GNUSTEP_MAKEFILES)/subproject.make gnustep-dl2-0.12.0/DBModeler/Inspectors/AttributeInspector.h0000644000175000017500000000610011015532156022713 0ustar ayersayers /* AttributesInspector.h Author: Matt Rice Date: 2005, 2006 This file is part of DBModeler. DBModeler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. DBModeler 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 General Public License for more details. You should have received a copy of the GNU General Public License along with DBModeler; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #ifdef NeXT_GUI_LIBRARY #include #else #include #include #include #include #endif #ifdef NeXT_Foundation_LIBRARY #include #else #include #endif @interface AttributeInspector : EOMInspector { IBOutlet NSTextField *_extNameField; IBOutlet NSTextField *_extTypeField; IBOutlet NSPopUpButton *_valueTypeSelect; IBOutlet NSPopUpButton *_flipSelect;// select which valueClassName/flip IBOutlet NSBox *_flipView; // gets replaced with a *Flip... IBOutlet NSBox *_internalData; IBOutlet NSTextField *_nameField; NSDictionary *_flipDict; NSDictionary *_classTitleDict; NSDictionary *_valueTypeDict; IBOutlet NSBox *_customFlip; // default IBOutlet NSBox *_dataFlip; IBOutlet NSBox *_dateFlip; IBOutlet NSBox *_decimalFlip; IBOutlet NSBox *_numberFlip; IBOutlet NSBox *_stringFlip; NSTextField *_custom_width; NSTextField *_custom_class; NSTextField *_custom_factory; NSTextField *_custom_conversion; NSPopUpButton *_custom_arg; NSTextField *_string_width; NSTextField *_decimal_precision; NSTextField *_decimal_width; NSTextField *_data_width; NSButton *_date_tz; } /* generic */ - (IBAction) selectInternalDataType:(id)sender; - (IBAction) setName:(id)sender; - (IBAction) setExternalName:(id)sender; - (IBAction) setExternalType:(id)sender; /* dependent on value class name */ - (IBAction) setWidth:(id)sender; - (IBAction) setPrecision:(id)sender; - (IBAction) setClassName:(id)sender; - (IBAction) setFactoryMethod:(id)sender; - (IBAction) setConversionMethod:(id)sender; - (IBAction) setInitArgument:(id)sender; - (IBAction) setValueType:(id)sender; - (IBAction) setTimeZone:(id)sender; @end gnustep-dl2-0.12.0/DBModeler/Inspectors/RelationshipInspector.m0000644000175000017500000002521211015532156023423 0ustar ayersayers /* RelationshipInspector.m Author: Matt Rice Date: 2005, 2006 This file is part of DBModeler. DBModeler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. DBModeler 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 General Public License for more details. You should have received a copy of the GNU General Public License along with DBModeler; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "RelationshipInspector.h" #include #include #include #include #include #include #ifdef NeXT_Foundation_LIBRARY #include #else #include #endif @implementation RelationshipInspector - (NSString *) displayName { return @"Relationship inspector"; } - (EOEntity *)selectedEntity { int row = [destEntity_tableView selectedRow]; NSArray *entities = [[[EOMApp activeDocument] model] entities]; if (row == -1 || row == NSNotFound || row >= [entities count]) return nil; return [[[[EOMApp activeDocument] model] entities] objectAtIndex:row]; } - (EOAttribute *)selectedDestinationAttribute { int row = [destAttrib_tableView selectedRow]; NSArray *attribs = [[self selectedEntity] attributes]; if (row == -1 || row == NSNotFound || row >= [attribs count]) return nil; return [attribs objectAtIndex:[destAttrib_tableView selectedRow]]; } - (EOAttribute *)selectedSourceAttribute { int row = [srcAttrib_tableView selectedRow]; NSArray *attribs = [[[self selectedObject] entity] attributes]; if (row == -1 || row == NSNotFound || row >= [attribs count]) return nil; return [attribs objectAtIndex:[srcAttrib_tableView selectedRow]]; } - (int) indexOfSourceAttribute:(EOAttribute *)srcAttrib { id tmp; int row; if (srcAttrib == nil) return NSNotFound; tmp = [self selectedObject]; if (tmp == nil) return NSNotFound; tmp = [tmp entity]; if (tmp == nil) return NSNotFound; tmp = [(EOEntity *)tmp attributes]; if (tmp == nil) return NSNotFound; row = [tmp indexOfObject:srcAttrib]; return row; } - (int) indexOfDestinationAttribute:(EOAttribute *)destAttrib { id tmp; int row; if (destAttrib == nil) return NSNotFound; tmp = [self selectedObject]; if (tmp == nil) return NSNotFound; tmp = [tmp destinationEntity]; if (tmp == nil) return NSNotFound; tmp = [(EOEntity *)tmp attributes]; if (tmp == nil) return NSNotFound; row = [tmp indexOfObject:destAttrib]; return row; } - (EOJoin *) joinWithSource:(EOAttribute *)srcAttrib destination:(EOAttribute *)destAttrib { NSArray *joins; int i,c; if (!srcAttrib && !destAttrib) return nil; joins = [[self selectedObject] joins]; c = [joins count]; for (i = 0; i < c; i++) { BOOL flag; id join = [joins objectAtIndex:i]; /* if both arguments are non-nil, both must be equal, * if one argument is nil the non-nil argument must be equal */ flag = ((srcAttrib && destAttrib && [srcAttrib isEqual:[join sourceAttribute]] && [destAttrib isEqual:[join destinationAttribute]]) || (srcAttrib && (destAttrib == nil) && [srcAttrib isEqual:[join sourceAttribute]]) || (destAttrib && (srcAttrib == nil) && [destAttrib isEqual:[join destinationAttribute]])); if (flag) { return join; } } return nil; } - (EOJoin *) selectedJoin { EOJoin *join = [self joinWithSource:[self selectedSourceAttribute] destination:[self selectedDestinationAttribute]]; return join; } - (void) awakeFromNib { [destEntity_tableView setAllowsEmptySelection:NO]; [srcAttrib_tableView setAllowsEmptySelection:NO]; [destAttrib_tableView setAllowsEmptySelection:NO]; } - (float) displayOrder { return 0; } - (BOOL) canInspectObject:(id)anObject { return [anObject isKindOfClass:[EORelationship class]]; } - (void) updateConnectButton { [connect_button setEnabled:([self selectedDestinationAttribute] != nil)]; [connect_button setState: ([self selectedJoin] != nil) ? NSOnState : NSOffState]; } - (void) refresh { EOModel *activeModel = [[EOMApp activeDocument] model]; EOEntity *destEntity; EOAttribute *srcAttrib, *destAttrib; NSArray *joins; unsigned int row = 0; [name_textField setStringValue:[(EORelationship *)[self selectedObject] name]]; [srcAttrib_tableView reloadData]; [destAttrib_tableView reloadData]; [destEntity_tableView reloadData]; destEntity = [[self selectedObject] destinationEntity]; if (destEntity) { row = [[activeModel entities] indexOfObject:destEntity]; if (row == NSNotFound) row = 0; } else if ([destEntity_tableView numberOfRows]) row = 0; [destEntity_tableView selectRow:row byExtendingSelection:NO]; joins = [[self selectedObject] joins]; if ([joins count]) { EOJoin *join = [joins objectAtIndex:0]; srcAttrib = [join sourceAttribute]; destAttrib = [join destinationAttribute]; row = [self indexOfSourceAttribute:srcAttrib]; if (row != NSNotFound) [srcAttrib_tableView selectRow:row byExtendingSelection:NO]; row = [self indexOfDestinationAttribute:srcAttrib]; if (row != NSNotFound) [destAttrib_tableView selectRow:row byExtendingSelection:NO]; } else { if ([self numberOfRowsInTableView:srcAttrib_tableView]) { [srcAttrib_tableView selectRow:0 byExtendingSelection:NO]; } if ([self numberOfRowsInTableView:destAttrib_tableView]) { [destAttrib_tableView selectRow:0 byExtendingSelection:NO]; } } [self updateConnectButton]; [joinCardinality_matrix selectCellWithTag:[[self selectedObject] isToMany]]; [joinSemantic_popup selectItemAtIndex: [joinSemantic_popup indexOfItemWithTag: [[self selectedObject] joinSemantic]]]; } - (int) numberOfRowsInTableView:(NSTableView *)tv { EOModel *activeModel = [[EOMApp activeDocument] model]; if (tv == destEntity_tableView) { return [[activeModel entities] count]; } else if (tv == srcAttrib_tableView) return [[(EOEntity *)[[self selectedObject] entity] attributes] count]; else if (tv == destAttrib_tableView) { int selectedRow = [destEntity_tableView selectedRow]; if (selectedRow == -1 || selectedRow == NSNotFound) return 0; return [[(EOEntity *)[[activeModel entities] objectAtIndex:[destEntity_tableView selectedRow]] attributes] count]; } return 0; } - (id) tableView:(NSTableView *)tv objectValueForTableColumn:(NSTableColumn *)tc row:(int)rowIndex { EOModel *activeModel = [[EOMApp activeDocument] model]; if (tv == destEntity_tableView) { return [(EOEntity *)[[activeModel entities] objectAtIndex:rowIndex] name]; } else if (tv == srcAttrib_tableView) { return [(EOAttribute *)[[(EOEntity *)[[self selectedObject] entity] attributes] objectAtIndex:rowIndex] name]; } else if (tv == destAttrib_tableView) { int selectedRow = [destEntity_tableView selectedRow]; if (selectedRow == NSNotFound) [destEntity_tableView selectRow:0 byExtendingSelection:NO]; return [(EOAttribute *)[[(EOEntity *)[[activeModel entities] objectAtIndex:[destEntity_tableView selectedRow]] attributes] objectAtIndex:rowIndex] name]; } return nil; } - (void) tableViewSelectionDidChange:(NSNotification *)notif { NSTableView *tv = [notif object]; if (tv == destEntity_tableView) { [destAttrib_tableView reloadData]; } else if (tv == destAttrib_tableView) { EOJoin *join = [self joinWithSource:nil destination:[self selectedDestinationAttribute]]; int row = [self indexOfSourceAttribute:[join sourceAttribute]]; if (row != NSNotFound) [srcAttrib_tableView selectRow:row byExtendingSelection:NO]; } else if (tv == srcAttrib_tableView) { EOJoin *join = [self joinWithSource:[self selectedSourceAttribute] destination:nil]; int row = [self indexOfDestinationAttribute:[join destinationAttribute]]; if (row != NSNotFound) [destAttrib_tableView selectRow:row byExtendingSelection:NO]; } [self updateConnectButton]; } - (BOOL) tableView:(NSTableView *)tv shouldSelectRow:(int)rowIndex { if (tv == destEntity_tableView) { return [[self selectedObject] destinationEntity] == nil; } else { return YES; } } - (void) tableView:(NSTableView *)tv willDisplayCell:(NSCell *)cell forTableColumn:(id)tc row:(int)row { if (tv == destEntity_tableView) { NSColor *enabledText = [NSColor controlTextColor]; NSColor *disabledText = [NSColor disabledControlTextColor]; BOOL flag = ([[self selectedObject] destinationEntity] == nil); [(NSTextFieldCell *)cell setTextColor:(flag == YES) ? enabledText : disabledText]; } } - (void) connectionChanged:(id)sender { EOAttribute *srcAttrib; EOAttribute *destAttrib; EOJoin *join; EOEntity *destEnt = [[self selectedObject] destinationEntity]; destAttrib = [self selectedDestinationAttribute]; srcAttrib = [self selectedSourceAttribute]; if ([sender state] == NSOnState) { join = [[EOJoin alloc] initWithSourceAttribute:srcAttrib destinationAttribute:destAttrib]; [[self selectedObject] addJoin:join]; [join release]; } else { join = [self joinWithSource:srcAttrib destination:destAttrib]; [[self selectedObject] removeJoin:join]; } if (destEnt != [[self selectedObject] destinationEntity]) [destEntity_tableView reloadData]; } - (void) nameChanged:(id)sender { NSString *name = [name_textField stringValue]; [(EORelationship *)[self selectedObject] setName:name]; } - (void) semanticChanged:(id)sender { /* the tag in the nib must match the values in the EOJoinSemantic enum */ [[self selectedObject] setJoinSemantic: [[sender selectedItem] tag]]; } - (void) cardinalityChanged:(id)sender { /* the tag in the nib for to-one must be 0 to-many 1 */ [[self selectedObject] setToMany: [[sender selectedCell] tag]]; } @end gnustep-dl2-0.12.0/DBModeler/Inspectors/AttributeInspector.gorm/0000755000175000017500000000000011147475623023523 5ustar ayersayersgnustep-dl2-0.12.0/DBModeler/Inspectors/AttributeInspector.gorm/objects.gorm0000644000175000017500000005564110503044531026036 0ustar ayersayersGNUstep archive00002c24:00000023:000002ec:00000000:01GSNibContainer1NSObject01 GSMutableSet1 NSMutableSet1NSSet&01GSWindowTemplate1GSClassSwapper01NSString&%NSWindow1 NSWindow1 NSResponder% ? A C C€&% C+ D@01 NSView% ? A C C€  C C€&01 NSMutableArray1 NSArray&01 NSTextField1 NSControl% B C C A  C A&0 &%0 1NSTextFieldCell1 NSActionCell1NSCell0 &%Text0 1NSFont%&&&&&&&&0%0 1NSColor0 &%NSNamedColorSpace0&%System0&%textBackgroundColor0 0& % textColor0% B C B A  B A&0 &%00&%Name:0% A&&&&&&&&0%0 0&%System0&%textBackgroundColor0 0& % textColor01 NSPopUpButton1NSButton% A C B A  B A&0 &%01NSPopUpButtonCell1NSMenuItemCell1 NSButtonCell0& &&&&&&&&0 1NSMenu0!&0" &0#1 NSMenuItem0$&%Column0%&&&%0&1NSImage0'& % common_Nibble%0(0)&%Derived%&&%%%0*&0+&&&&# #%%%%%0,% B C C A  C A&0- &%0.0/&%Text &&&&&&&&0%00 01&%System02&%textBackgroundColor03 104& % textColor05% A C B A  B A&06 &%0708&%External Type:&&&&&&&&0%09 0:&%System0;&%textBackgroundColor0< :0=& % textColor0>% B C C A  C A&0? &%0@0A&%Text &&&&&&&&0%0B 0C&%System0D&%textBackgroundColor0E C0F& % textColor0G1NSBox% A B C| Cs  C| Cs&0H &0I % @ @ Cn CV  Cn CV&0J &0K% BL C@ C' A  C' A&0L &%0M0N& &&&&&&&&0O0P&0Q &0R0S&%Custom0T&&&%&%0U0V&%StringT&&%%0W0X&%Decimal NumberT&&%%0Y0Z&%Number0[&&&%%0\0]&%Date0^&&&%%0_0`&%Data0a&&&%%%0b&0c&&&&ROR%%%%%0d% @ Cn C5  Cn C5&0e &0f % @ @ C` C'  C` C'&0g &0h% B B B A  B A&0i &%0j0k&%_flip0l% A0k&&&&&&&&0%0m 0n&%System0o&%textBackgroundColor0p n0q& % textColor0r0s&%Title &&&&&&&& @ @%%0t0u&%Internal Data Type &&&&&&&& @ @%%0v 0w&%System0x&%windowBackgroundColor0y&%Window0z&%Inspector Windowz ? ? F@ F@%&  D D0{ % ? A DX D+&% CV D@0| % ? A DX D+  DX D+&0} &  0~% A C Cn C5  Cn C5&0 &0 % @ @ Cd C+  Cd C+&0 &  0% A C B A  B A&0 &%00&%External Width:&&&&&&&&0%0 0&%System0&%textBackgroundColor0 0& % textColor0% A B B A  B A&0 &%00&%Class:&&&&&&&&0%0 0&%System0&%textBackgroundColor0 0& % textColor0% B BL B A  B A&0 &%00& &&&&&&&&0%0 0&%System0&%textBackgroundColor0 0& % textColor0% A B B A  B A&0 &%00&%Factory method:&&&&&&&&0%0 0&%System0&%textBackgroundColor0 0& % textColor0% BL B A  B A&0 &%00&%Conversion method:&&&&&&&&0%0 0&%System0&%textBackgroundColor0 0& % textColor0% B A B A  B A&0 &%00& &&&&&&&&00&0 &00&%NSData0&&&%&%00&%NSString&&%%00&%Bytes&&%%%0&0&&&&%%%%%0% A A B A  B A&0 &%00±&%Init argument:&&&&&&&&0%0ñ 0ı&%System0ű&%textBackgroundColor0Ʊ 0DZ& % textColor0ȱ% B B B A  B A&0ɱ &%0ʱ0˱& &&&&&&&&0%0̱ 0ͱ&%System0α&%textBackgroundColor0ϱ 0б& % textColor0ѱ% B C B A  B A&0ұ &%0ӱ0Ա& &&&&&&&&0%0ձ 0ֱ&%System0ױ&%textBackgroundColor0ر 0ٱ& % textColor0ڱ% B B B A  B A&0۱ &%0ܱ0ݱ& &&&&&&&&0%0ޱ 0߱&%System0&%textBackgroundColor0 0& % textColor00&%Title &&&&&&&& @ @%%0% C} C Cn C5  Cn C5&0 &0 % @ @ Cd C+  Cd C+&0 &0% A C B A  B A&0 &%00&%External width&&&&&&&&0%0 0&%System0&%textBackgroundColor0 0& % textColor0% B C B A  B A&0 &%00& &&&&&&&&0%0 0&%System0&%textBackgroundColor0 0& % textColor0% A B B A  B A&0 &%00&%External precision&&&&&&&&0%0 P&%SystemP&%textBackgroundColorP P& % textColorP% B B B A  B A&P &%PP& &&&&&&&&0%P P &%SystemP &%textBackgroundColorP   P & % textColorP P&%Title &&&&&&&& @ @%%P% C Cn C5  Cn C5&P &P % @ @ Cd C+  Cd C+&P &P% A C B A  B A&P &%PP&%External width&&&&&&&&0%P P&%SystemP&%textBackgroundColorP P& % textColorP% B C B A  B A&P &%PP& &&&&&&&&0%P  P!&%SystemP"&%textBackgroundColorP# !P$& % textColorP%P&&%Title &&&&&&&& @ @%%P'% C C Cn C5  Cn C5&P( &P) % @ @ Cd C+  Cd C+&P* &P+% B C C A  C A&P, &%P-P.& &&&&&&&&P/P0&P1 &  P2P3&%intP4&&&%%P5P6&%doubleP7&&&%%P8P9&%floatP:&&&%%P;P<&%charP=&&&%%P>P?&%shortP@&&&%%PAPB& % unsigned intPC&&&%%PDPE& % unsigned charPF&&&%%PGPH&%unsigned shortPI&&&%%PJPK&%longPL&&&%%PMPN& % unsigned longPO&&&%%PPPQ& % long longPR&&&%%PSPT&%unsigned long long7&&%%%PU&PV&&&&/%%%%%PW% A C B A  B A&PX &%PYPZ& % Value type:Z&&&&&&&&0%P[ P\&%SystemP]&%textBackgroundColorP^ \P_& % textColorP`Pa&%Title &&&&&&&& @ @%%Pb% C D'@ B A  B A&Pc &%PdPe& % decimalFlipe&&&&&&&&0%Pf Pg&%SystemPh&%textBackgroundColorPi gPj& % textColorPk% BP D( B A  B A&Pl &%PmPn& % customFlipn&&&&&&&&0%Po Pp&%SystemPq&%textBackgroundColorPr pPs& % textColorPt% A C B A  B A&Pu &%PvPw&%dataFlipw&&&&&&&&0%Px Py&%SystemPz&%textBackgroundColorP{ yP|& % textColorP}% C{ C B A  B A&P~ &%PP&%dateFlip&&&&&&&&0%P P&%SystemP&%textBackgroundColorP P& % textColorP% D@ D' B A  B A&P &%PP&%number&&&&&&&&0%P P&%SystemP&%textBackgroundColorP P& % textColorP% C} C Cn C5  Cn C5&P &P % @ @ Cd C+  Cd C+&P &P% B B B A  B A&P &%PP& % Set timezone &&&&&&&&%P&P&&&&PP&%Title &&&&&&&& @ @%%P% A B` Cn C5  Cn C5&P &P % @ @ Cd C+  Cd C+&P &P% Ap C B A  B A&P &%PP&%External width&&&&&&&&0%P P&%SystemP&%textBackgroundColorP P& % textColorP% B C B A  B A&P &%PP& &&&&&&&&0%P P&%SystemP&%textBackgroundColorP P& % textColorPP&%Title &&&&&&&& @ @%%P% Bh C B A  B A&P &%PP& % stringFlip&&&&&&&&0%P P&%SystemP&%textBackgroundColorP P& % textColorP P&%SystemP&%windowBackgroundColorP&%WindowP&%WindowP&%Window @@ B F@ F@%&  D DP± &Pñ &P1NSMutableDictionary1 NSDictionary&ZPű&%Box(0)dPƱ& % MenuItem(26)SPDZ& % TextField(1)}Pȱ& % MenuItem(14)PɱPʱ&%intP˱&&&%%P̱&%PopUpButton(0)Pͱ& % MenuItem(3)PαPϱ&Pб&&&%%Pѱ&%BoxGPұ& % TextField(13)Pӱ&%View(2)PԱ&%Box(3)Pձ& % TextField(4)Pֱ& % TextFieldPױ& % MenuItem(17);Pر& % MenuItem(21)2Pٱ& % MenuItem(6)PڱP۱&%charPܱ&&&%%Pݱ& % TextField(16)hPޱ& % TextField(20)P߱&%View(5)P& % TextField(7)P& % MenuItem(24)MP& % MenuItem(12)PP& % unsigned charP&&&%%P& % MenuItem(9)PP& % long longP&&&%%P& % TextField(19)P& % TextField(23)P&%View(8)P& % MenuItem(1)P& % TextField(11)P&%View(0)fP& % MenuItem(27)8P&%Box(1)~P& % InspectorWinP& % TextField(2)bP& % MenuItem(15)PP&%shortP&&&%%P&%PopUpButton(1)+P& % MenuItem(4)PP&%unsigned long long&&%%P& % TextField(14)WP&%View(3)P&%MenuItem#P&%Box(4)P& % TextField(5)P& % MenuItem(18)DP& % MenuItem(22)AP& % MenuItem(10)PP&%unsigned shortP&&&%%P& % Button(0)P& % MenuItem(7)P P & % unsigned longP &&&%%P & % TextField(17)P &%View(6))P& % TextField(21)P&%Box(7)P& % TextField(8)P& % Window(0){P&%GormNSPopUpButtonP& % MenuItem(25)PP& % TextField(0)tP&%GormNSPopUpButton1KP& % MenuItem(13)PP& % unsigned intP&&&%%P& % TextField(24)P& % MenuItem(2)P& % MenuItem1(P&%NSOwnerP&%AttributeInspectorP& % TextField(12)kP & % MenuItem2RP!&%View(1)|P"& % MenuItem3UP#& % MenuItem4WP$& % MenuItem(28)5P%& % MenuItem5YP&&%Box(2)P'& % TextField(3)P(& % MenuItem(20)GP)& % MenuItem8\P*& % MenuItem9_P+& % MenuItem(5)P,P-&%double&&%%P.& % TextField(15)P/&%View(4)P0& % TextField1P1&%Box(5)'P2& % TextField2,P3& % TextField(6)P4& % TextField35P5& % MenuItem(19)>P6& % TextField4>P7& % MenuItem(23)JP8& % MenuItem(11)P9P:&%longP;&&&%%P<& % MenuItem(8)P=P>&%floatP?&&&%%P@& % TextField(18)PA& % TextField(22)PB& % MenuItem(0)PC& % TextField(10)PD& % TextField(9)PE &PF1 NSNibConnectorPG&%NSOwnerPH ֐PI 0PJ PK PL PM 2PN 4PO 6PP PQ  PR "PS #PT %PU )PV *PW ѐPX ŐPY ŐPZ GP[ !P\ !P] P^ 'ӐP_ ӐP` ӐPa 3ӐPb ӐPc ӐPd BPe 퐐Pf Pg ӐPh DӐPi CӐPj ӐPk1!NSNibOutletConnectorGPl& % _flipViewPm!GPn& % _flipSelectPo!G6Pp& % _extTypeFieldPq!G2Pr& % _extNameFieldPs!GPt& % _nameFieldPu!GPv& % _customFlipPw &!Px &Py !Pz /ԐP{ 1!P|  1P}!GP~& % _dataFlipP!G&P& % _decimalFlipP !P !P !P !P !P !P P !P P .!P!GP& % _stringFlipP!GP& % _dateFlipP!GP1"NSMutableString&%windowP!GP& % _internalDataP1#NSNibControlConnectorGP&%setName:P#2GP&%setExternalName:P#6GP&%setExternalType:P P#CGP& % setWidth:P#GP&%setInitArgument:P#DGP&%setFactoryMethod:P#GP& % setClassName:P#GP&%setConversionMethod:P!GP& % _custom_argP!GP&%_custom_conversionP!GDP&%_custom_factoryP!GP& % _custom_classP!GCP& % _custom_widthP AP  P @/P /P P P P P ߐP!G P"& % _string_widthP!GP& % _data_widthP!GP&%_date_tzP!GP&%_decimal_widthP!GP&%_decimal_precisionP# GP±"& % setWidth:Pñ#GPı#GPű#GPƱ"& % setPrecision:PDZ#GPȱ& % setTimeZone:Pɱ ͐Pʱ P˱ +P̱ ِPͱ Pα  Date: 2005, 2006 This file is part of DBModeler. DBModeler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. DBModeler 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 General Public License for more details. You should have received a copy of the GNU General Public License along with DBModeler; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef NeXT_Foundation_LIBRARY #include #else #include #endif @class NSObject; @interface Modeler : NSObject { } /* runs the adaptor panel and the adaptors login panel, and sets the active * documents connection dictionary. */ - (void) setAdaptor:(id)sender; @end #endif // __Modeler_H_ gnustep-dl2-0.12.0/DBModeler/ModelerEntityEditor.m0000644000175000017500000001676611015532156020713 0ustar ayersayers/** ModelerEntityEditor.m Author: Matt Rice Date: 2005, 2006 This file is part of DBModeler. DBModeler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. DBModeler 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 General Public License for more details. You should have received a copy of the GNU General Public License along with DBModeler; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA **/ #include "DefaultColumnProvider.h" #include "ModelerAttributeEditor.h" #include "ModelerEntityEditor.h" #include "KVDataSource.h" #include #include #include #include #include #include #include #ifdef NeXT_GUI_LIBRARY #include #else #include #include #include #include #include #include #include #include #include #endif #include #include @interface EOModelerDocument (asdf) -(void)_setDisplayGroup:(id)displayGroup; @end @interface ModelerEntityEditor (Private) - (void) _loadColumnsForClass:(Class) aClass; @end @implementation ModelerEntityEditor - (BOOL) canSupportCurrentSelection { id selection = [self selectionWithinViewedObject]; BOOL flag; if ([selection count] == 0) { flag = NO; return flag; } selection = [selection objectAtIndex:0]; flag = [selection isKindOfClass:[EOModel class]]; return flag; } - (NSArray *) friendEditorClasses { return [NSArray arrayWithObjects: [ModelerAttributeEditor class], nil]; } - (void) dealloc { [EOObserverCenter removeObserver:self forObject:[[self document] model]]; RELEASE(_splitView); RELEASE(dg); [super dealloc]; } - (id) initWithParentEditor: (EOModelerCompoundEditor *)parentEditor { if ((self = [super initWithParentEditor:parentEditor])) { EOClassDescription *classDescription = nil; KVDataSource *wds; NSScrollView *scrollView; NSPopUpButton *cornerView; NSMenuItem *mi = [[NSMenuItem alloc] initWithTitle:@"+" action:(SEL)nil keyEquivalent:@""]; _splitView = [[NSSplitView alloc] initWithFrame:NSMakeRect(0,0,10,10)]; scrollView = [[NSScrollView alloc] initWithFrame:NSMakeRect(0,0,10,10)]; [scrollView setHasHorizontalScroller:YES]; [scrollView setHasVerticalScroller:YES]; [scrollView setBorderType: NSBezelBorder]; _topTable = [[NSTableView alloc] initWithFrame:NSMakeRect(0,0,10,10)]; _bottomTable = [[NSTableView alloc] initWithFrame:NSMakeRect(0,0,10,10)]; #if OS_API_VERSION(GS_API_NONE, MAC_OS_X_VERSION_10_4) [_topTable setAutoresizesAllColumnsToFit:NO]; #else [_topTable setColumnAutoresizingStyle:NSTableViewLastColumnOnlyAutoresizingStyle]; #endif #if OS_API_VERSION(MAC_OS_X_VERSION_10_3, GS_API_LATEST) || GNU_GUI_LIBRARY [_topTable setUsesAlternatingRowBackgroundColors:YES]; [_topTable setGridStyleMask:NSTableViewSolidVerticalGridLineMask]; #endif [scrollView setDocumentView:_topTable]; RELEASE(_topTable); [_splitView addSubview:scrollView]; RELEASE(scrollView); scrollView = [[NSScrollView alloc] initWithFrame:NSMakeRect(0,0,10,10)]; [scrollView setHasHorizontalScroller:YES]; [scrollView setHasVerticalScroller:YES]; [scrollView setBorderType: NSBezelBorder]; #if OS_API_VERSION(GS_API_NONE, MAC_OS_X_VERSION_10_4) [_bottomTable setAutoresizesAllColumnsToFit:NO]; #else [_bottomTable setColumnAutoresizingStyle:NSTableViewLastColumnOnlyAutoresizingStyle]; #endif #if OS_API_VERSION(MAC_OS_X_VERSION_10_3, GS_API_LATEST) || GNU_GUI_LIBRARY [_bottomTable setUsesAlternatingRowBackgroundColors:YES]; [_bottomTable setGridStyleMask:NSTableViewSolidVerticalGridLineMask]; #endif [scrollView setDocumentView:_bottomTable]; RELEASE(_bottomTable); [_splitView addSubview:scrollView]; RELEASE(scrollView); [DefaultColumnProvider class]; // calls +initialize cornerView = [[NSPopUpButton alloc] initWithFrame:[[_topTable cornerView] bounds] pullsDown:YES]; [cornerView setPreferredEdge:NSMinYEdge]; [cornerView setTitle:@"+"]; [cornerView setBezelStyle:NSShadowlessSquareBezelStyle]; [[cornerView cell] setBezelStyle:NSShadowlessSquareBezelStyle]; [[cornerView cell] setArrowPosition:NSPopUpNoArrow]; //[mi setImage:[NSImage imageNamed:@"plus"]]; // [mi setOnStateImage:[NSImage imageNamed:@"plus"]]; // [mi setOffStateImage:[NSImage imageNamed:@"plus"]]; //[mi setState:NSOnState]; [[cornerView cell] setUsesItemFromMenu:NO]; [[cornerView cell] setShowsFirstResponder:NO]; [[cornerView cell] setShowsStateBy:NSContentsCellMask]; [[cornerView cell] setMenuItem:mi]; RELEASE(mi); [[cornerView cell] setImagePosition:NSNoImage]; [_topTable setCornerView:cornerView]; RELEASE(cornerView); [_topTable setAllowsMultipleSelection:YES]; classDescription = nil; wds = [[KVDataSource alloc] initWithClassDescription:classDescription editingContext:[[self document] editingContext]]; [wds setDataObject: [[self document] model]]; [wds setKey:@"entities"]; dg = [[EODisplayGroup alloc] init]; [EOObserverCenter addObserver:self forObject:[[self document] model]]; [dg setDataSource: wds]; RELEASE(wds); [dg setFetchesOnLoad:YES]; [dg setDelegate: self]; [self setupCornerView:cornerView tableView:_topTable displayGroup:dg forClass:[EOEntity class]]; [self addDefaultTableColumnsForTableView:_topTable displayGroup:dg]; } return self; } - (NSArray *)defaultColumnNamesForClass:(Class)aClass { NSArray *colNames = [super defaultColumnNamesForClass:aClass]; if (colNames == nil || [colNames count] == 0) { if (aClass == [EOEntity class]) return DefaultEntityColumns; else return nil; } return colNames; } - (void) activate { [dg fetch]; [dg selectObjectsIdenticalTo:[self selectionWithinViewedObject] selectFirstOnNoMatch:NO]; } - (NSView *)mainView { return _splitView; } - (void) objectWillChange:(id)anObject { [[NSRunLoop currentRunLoop] performSelector:@selector(needToFetch:) target:self argument:nil order:999 /* this number is probably arbitrary */ modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]]; } - (void) needToFetch:(id)sth { [dg fetch]; } @end @implementation ModelerEntityEditor (DisplayGroupDelegate) - (void) displayGroupDidChangeSelection:(EODisplayGroup *)displayGroup { [[self parentEditor] setSelectionWithinViewedObject: [displayGroup selectedObjects]]; } @end gnustep-dl2-0.12.0/DBModeler/DiagramView.h0000644000175000017500000000264411011131075017127 0ustar ayersayers/** DiagramView.h Author: Matt Rice Date: Oct 2006 This file is part of DBModeler. DBModeler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. DBModeler 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 General Public License for more details. You should have received a copy of the GNU General Public License along with DBModeler; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifndef __DIAGRAM_VIEW_H #ifdef NeXT_GUI_LIBRARY #include #else #include #endif @class NSColor; @class NSMutableDictionary; @class EOModel; @class NSArray; @class NSString; @interface DiagramView : NSView { EOModel *_model; NSMutableDictionary *_shownEntities; NSMutableArray *_relationships; NSColor *_bgColor; NSMutableArray *_subview_order; } - (void) setModel:(EOModel *)model; - (void) showEntity:(NSString *)name; - (void) setupRelationships; - (void) orderViewFront:(NSView *)view; @end #define __DIAGRAM_VIEW_H #endif gnustep-dl2-0.12.0/DBModeler/Resources/0000755000175000017500000000000011147475623016547 5ustar ayersayersgnustep-dl2-0.12.0/DBModeler/Resources/AllowsNull_Header.tiff0000644000175000017500000000253410502775651022767 0ustar ayersayersII* R @@LT(R/home/ratmice/clean/gnustep/gdl2/trunk/DBModeler/Resources/AllowsNull_Header.tiffAllowsNullHHgnustep-dl2-0.12.0/DBModeler/Resources/Info-gnustep.plist0000644000175000017500000000141410547475000022172 0ustar ayersayers{ ApplicationDescription = "GDL2 EOModel editor"; ApplicationIcon = DBModeler; ApplicationName = DBModeler; ApplicationRelease = "0.0.0 (Alpha)"; ApplicationURL = "http://mediawiki.gnustep.org/index.php/DBModeler"; Authors = ( "Matt Rice " ); Copyright = "Copyright \U00A9 2005, 2006 Free Software Foundation"; CopyrightDescription = "Released under the GNU GPL. See COPYING for details."; FullVersionID = 0.0.0; GSMainMarkupFile = ""; NSExecutable = DBModeler; NSIcon = DBModeler.tiff; NSRole = "Editor"; NSTypes = ( { NSUnixExtensions = ( "eomodeld", "eomodel" ); NSIcon = "EOModel.tiff"; } ); NSMainNibFile = ""; NSPrincipalClass = NSApplication; } gnustep-dl2-0.12.0/DBModeler/Resources/Preferences.gorm/0000755000175000017500000000000011147475623021753 5ustar ayersayersgnustep-dl2-0.12.0/DBModeler/Resources/Preferences.gorm/objects.gorm0000644000175000017500000001567410551154161024274 0ustar ayersayersGNUstep archive00002c88:00000027:000000bd:00000001:01GSNibContainer1NSObject01 GSMutableSet1 NSMutableSet1NSSet&01GSWindowTemplate1GSClassSwapper01NSString&%NSPanel1 NSPanel1 NSWindow1 NSResponder% ? A C C& % B D.@01 NSView% ? A C C  C C&01 NSMutableArray1NSArray&01NSButton1 NSControl% C B CK A  CK A&0 &%0 1 NSButtonCell1 NSActionCell1NSCell0 &%Check consistency on save0 1NSImage0 1NSMutableString&%common_SwitchOff0 1NSFont%&&&&&&&&%0&0&00&%common_SwitchOn&&&01 NSScrollView% A B Cq C&  Cq C&&0 &01 NSClipView% A A CZ C   CZ C &0 &01 NSTableView%  CZ C!  CZ C!&0 &%00& &&&&&&&&0 &01 NSTableColumn0&%column1 CZ A GP01NSTableHeaderCell1NSTextFieldCell0&%Bundles 0% &&&&&&&&0%0 1NSColor0!&%NSNamedColorSpace0"&%System0#&%controlShadowColor0$!"0%&%windowFrameTextColor0&0'&%huit '&&&&&&&&0%0(!0)&%System0*&%textBackgroundColor0+!)0,& % textColor0-!)0.& % gridColor0/!)00&%controlBackgroundColor011NSTableHeaderView%  CZ A  CZ A&02 &031GSTableCornerView% @ @ A A  A A&04 &%% A @ @@/051 NSScroller% @ A A C   A C &06 &%07 &&&&&&&&&2 _doScroll:v12@0:4@808% A @ CZ A  CZ A&09 &10:!)0;& % controlColor3% A A A A 580<% C B B` A  B` A&0= &%0>0?&%Remove &&&&&&&&%0@&0A&&&&0B% B B B` A  B` A&0C &%0D0E&%Add &&&&&&&&%0F&0G&&&&0H1!NSBox% C B CS C&  CS C&&0I &0J % @ @ CE C   CE C &0K &0L1"NSMatrix%  CE C   CE C &0M &%0N0O& &&&&&&&&%% CE A 0P!0Q&%System0R&%controlBackgroundColorP0S& % NSButtonCell0T0U&%Switch &&&&&&&&%0V&0W&&&&%%0X &0Y0Z&%Attribute Details &&&&&&&&%V0[&&&&0\0]& % External name &&&&&&&&%V0^&&&&0_0`& % Primary key &&&&&&&&%V0a&&&&0b0c& % Relationship &&&&&&&&%V0d&&&&0e0f&%Entity stored procedure &&&&&&&&%V0g&&&&0h0i&%Stored procedure &&&&&&&&%V0j&&&&0k0l& % Inheritance &&&&&&&&%V0m&&&&Y0n0o&%Consistency Checks o&&&&&&&& @ @%%0p!Q0q&%windowBackgroundColor0r&%Window0s&%Panels ? ? F@ F@%&   D D0t &0u &0v1#NSMutableDictionary1$ NSDictionary& 0w&%NSOwner0x&%DBModelerPrefs0y&%Button1B0z& % TableColumn10{0|&%column2 BT A GP0}0~&% &&&&&&&&0%0!Q0&%controlHighlightColor0!)0&%windowFrameTextColor00&%three &&&&&&&&0%(+0& % GormNSPanel0&%BoxH0& % ScrollView0&%Button2<0&%Button0&%ViewJ0&%MatrixL0& % TableColumn0&%GormNSTableView0 &01%NSNibConnector0&%NSOwner0%0%0%0%0%0%z0%0%y01&NSNibOutletConnector0& % dataSource0&0&%delegate0&0& % bundlesToLoad0&0&%consistencyCheckOnSave0&y0&%addBundleButton0&0&%removeBundleButton0&0& % prefsWindow01'NSNibControlConnector0&%switchButtonChanged:0&0& % check_matrix0%0%0'0&%checkOnSaveChanged:0'y0& % addBundle:0'0& % removeBundle:0&0&%initialFirstResponder0&y0& % nextKeyView0&y0&0&0&0#&gnustep-dl2-0.12.0/DBModeler/Resources/Preferences.gorm/data.classes0000644000175000017500000000103710477373673024253 0ustar ayersayers{ "## Comment" = "Do NOT change this file, Gorm maintains it"; DBModelerPrefs = { Actions = ( "switchButtonChanged:", "checkOnSaveChanged:", "addBundle:", "removeBundle:" ); Outlets = ( prefsWindow, consistencyCheckOnSave, bundlesToLoad, addBundleButton, check_matrix, removeBundleButton ); Super = NSObject; }; FirstResponder = { Actions = ( "addBundle:", "checkOnSaveChanged:", "removeBundle:", "switchButtonChanged:" ); Super = NSObject; }; }gnustep-dl2-0.12.0/DBModeler/Resources/Preferences.gorm/data.info0000644000175000017500000000027010551154161023525 0ustar ayersayersGNUstep archive00002c88:00000003:00000003:00000000:01GormFilePrefsManager1NSObject%01NSString&%Latest Version0& % Typed Streamgnustep-dl2-0.12.0/DBModeler/Resources/Locking_On.tiff0000644000175000017500000000212610477373673021453 0ustar ayersayersII*UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU P0@FN(/home/ratmice/livecvs/gnustep/dev-libs/gdl2/DBModeler/Resources/Locking_On.tiffCreated with The GIMPHHgnustep-dl2-0.12.0/DBModeler/Resources/ClassProperty_On.tiff0000644000175000017500000000213410477373673022676 0ustar ayersayersII*UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU V6@LT(/home/ratmice/livecvs/gnustep/dev-libs/gdl2/DBModeler/Resources/ClassProperty_On.tiffCreated with The GIMPHHgnustep-dl2-0.12.0/DBModeler/Resources/Key_Header.tiff0000644000175000017500000000254410477373673021435 0ustar ayersayersII* P>@T\(R/home/ratmice/livecvs/gnustep/dev-libs/gdl2/DBModeler/Resources/Key_Header.tiffCreated with The GIMPHHgnustep-dl2-0.12.0/DBModeler/Resources/Key_On.tiff0000644000175000017500000000212210500043326020561 0ustar ayersayersII*UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU L,@BJ(/home/ratmice/livecvs/gnustep/dev-libs/gdl2/DBModeler/Resources/Key_On.tiffCreated with The GIMPHHgnustep-dl2-0.12.0/DBModeler/Resources/Locking_Header.tiff0000644000175000017500000000255010500043326022240 0ustar ayersayersII* TB@X`(R/home/ratmice/livecvs/gnustep/dev-libs/gdl2/DBModeler/Resources/Locking_Header.tiffCreated with The GIMPHHgnustep-dl2-0.12.0/DBModeler/Resources/ClassProperty_Header.tiff0000644000175000017500000000255610477373673023522 0ustar ayersayersII* ZH@^f(R/home/ratmice/livecvs/gnustep/dev-libs/gdl2/DBModeler/Resources/ClassProperty_Header.tiffCreated with The GIMPHHgnustep-dl2-0.12.0/DBModeler/Resources/Locking_Diagram.tiff0000644000175000017500000000135610512515531022424 0ustar ayersayersII*   !@(R/home/ratmice/diagram2/lock.tiffCreated with The GIMPHHgnustep-dl2-0.12.0/DBModeler/Resources/Key_Diagram.tiff0000644000175000017500000000107410512515531021563 0ustar ayersayersII*   @,4(R/home/ratmice/diagram2/key.tiffCreated with The GIMPHHgnustep-dl2-0.12.0/DBModeler/Resources/ModelDrag.tiff0000644000175000017500000000357610502532735021262 0ustar ayersayersII*2xڭWilTUoyt*dkT*e1*!)*(?,QM DH-d ՈH)PCRPt{^;BqfZnf2sg|JŋH9 cD0JDaaYVzD/Uwze-Ƥ=kQR8a{B22>m ֕z4-&8tUZ^?k}꠽}C`28uOXBS_UR?5v$p>uіL4NIGw7p1ꬼxUO) ${ ɷ72i?|z}ޖO?/zU:iVB&8.$ny֒FBcЅN\MFn:J%dp6#&h9=u26qFч Jx~ >7i8;Owgc$}j*w^;zg &cZk2&3H"+u|w.x ZqB/S?sv]f ϥg\RRE>.E7nbP{a7eNv(X(ck蚳bTjQcd8{}Cc-NVV WmD1 vaeu []Xbj">u|imw45mafFU;oK5`*Dt:" U=URk-fspZsFrma-{L;HhpRk:rYF;}iP(+}m6%o VSSX qs~||\A64մqnҋOI6S 9Ü zIm.΄pz#)x9| FȆ\LIo720_9+!PbCdُȸd}zq2%ד}219pA1=岰?⵿PBabpB'S VM.؊(&1Aĉ.w#5Ǐ󚹥+Y$Mn[;|zWrWRfWAppI!Vp?97iH]Iή51yj.ІAY*mvV&xk_jOR|ZE9CA }ƪko*s+ykB=Qdc^h|n,%z,ṼjNTN̂^]:2g )& 6a$eĠhEJR~m{/ML*  $)4<(1:D=RModelDrag.tiffHHImageMagick 6.2.2 04/27/05 Q16 http://www.imagemagick.orggnustep-dl2-0.12.0/DBModeler/Resources/Menu-GNUstep.gsmarkup0000644000175000017500000000520511012240010022516 0ustar ayersayers gnustep-dl2-0.12.0/DBModeler/Resources/ClassProperty_Diagram.tiff0000644000175000017500000000112610512515531023643 0ustar ayersayersII*(  !0@ FN(R/home/ratmice/diagram2/prop.tiffCreated with The GIMPHHgnustep-dl2-0.12.0/DBModeler/Resources/ConsistencyResults.gsmarkup0000644000175000017500000000151011012262637024170 0ustar ayersayers