* EOAccess/EOEntity.m/.h:

o added _instanceDictionaryInitializer.
	    Permit to have a restricted dictionary initializer
	    (i.e. propertyDictionaryInitializer minus instance
	     object ivars).
	  o added NSObject
	    +_instanceDictionaryInitializerExcludedPropertyNames
	  o more information in log/exception in _parseRelationshipPath
	  o added -_instanceDictionaryInitializer
	  o added - _dictionaryForInstanceProperties
	  o added -_classForInstances
	* EOAccess/EOModel.m:
	  o added asserts
	  o clean warnings
	* EOAccess/EORelationship.m:
	  o asserts
	  o fix in -isReciprocalToRelationship:


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@18224 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
David Ayers 2003-11-28 22:47:32 +00:00
parent ff38b6fc00
commit 5f1314ddfc
5 changed files with 232 additions and 38 deletions

View file

@ -12,7 +12,7 @@
o added missing number types
o introducing new number types:
('u' for long long / int8 and 'U' for unsigned long long)
* EOControl/EONSAddOns.h/m
* EOControl/EONSAddOns.m/.h
o added number accessors for NSString
o added NSObject
-performSelector:withObject:withObject:withObject:
@ -22,6 +22,23 @@
with more than one attribute for PK)
* EOAccess/EODatabaseContextPriv.h
o added -_primaryKeyForObject:raiseException:
* EOAccess/EOEntity.m/.h:
o added _instanceDictionaryInitializer.
Permit to have a restricted dictionary initializer
(i.e. propertyDictionaryInitializer minus instance
object ivars).
o added NSObject
+_instanceDictionaryInitializerExcludedPropertyNames
o more information in log/exception in _parseRelationshipPath
o added -_instanceDictionaryInitializer
o added - _dictionaryForInstanceProperties
o added -_classForInstances
* EOAccess/EOModel.m:
o added asserts
o clean warnings
* EOAccess/EORelationship.m:
o asserts
o fix in -isReciprocalToRelationship:
2003-10-24 David Ayers <d.ayers@inode.at>

View file

@ -85,6 +85,7 @@
EOMKKDInitializer* _snapshotDictionaryInitializer;
EOMKKDInitializer* _primaryKeyDictionaryInitializer;
EOMKKDInitializer* _propertyDictionaryInitializer;
EOMKKDInitializer* _instanceDictionaryInitializer;
EOMKKDSubsetMapping* _snapshotToAdaptorRowSubsetMapping;
Class _classForInstances;
@ -158,6 +159,8 @@
/* Accessing the enterprise object class */
- (NSString*)className;
-(Class)_classForInstances;
/* Accessing attributes */
- (EOAttribute *)attributeNamed: (NSString *)attributeName;
- (EOAttribute *)anyAttributeNamed: (NSString *)relationshipName;
@ -335,6 +338,7 @@ GDL2ACCESS_EXPORT NSString *EONextPrimaryKeyProcedureOperation;
- (EOMKKDSubsetMapping*) _snapshotToAdaptorRowSubsetMapping;
- (EOMutableKnownKeyDictionary*) _dictionaryForPrimaryKey;
- (EOMutableKnownKeyDictionary*) _dictionaryForProperties;
- (EOMutableKnownKeyDictionary*) _dictionaryForInstanceProperties;
- (NSArray*) _relationshipsToFaultForRow: (NSDictionary*)row;
- (NSArray*) _classPropertyAttributes;
- (NSArray*) _attributesToSave;
@ -343,6 +347,7 @@ GDL2ACCESS_EXPORT NSString *EONextPrimaryKeyProcedureOperation;
- (EOMKKDInitializer*) _snapshotDictionaryInitializer;
- (EOMKKDInitializer*) _primaryKeyDictionaryInitializer;
- (EOMKKDInitializer*) _propertyDictionaryInitializer;
- (EOMKKDInitializer*) _instanceDictionaryInitializer;
- (void) _setModel: (EOModel*)model;
- (void) _setIsEdited;
- (NSArray*) _classPropertyAttributes;
@ -363,6 +368,10 @@ GDL2ACCESS_EXPORT NSString *EONextPrimaryKeyProcedureOperation;
/** returns entity **/
- (EOEntity *)entity;
/** 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)
@ -376,4 +385,10 @@ GDL2ACCESS_EXPORT NSString *EONextPrimaryKeyProcedureOperation;
@end
@interface NSObject (EOEntity)
/** should returns an array of property names to exclude from entity
instanceDictionaryInitializer **/
+ (NSArray *)_instanceDictionaryInitializerExcludedPropertyNames;
@end
#endif /* __EOEntity_h__ */

View file

@ -532,6 +532,7 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat
DESTROY(_snapshotDictionaryInitializer);
DESTROY(_primaryKeyDictionaryInitializer);
DESTROY(_propertyDictionaryInitializer);
DESTROY(_instanceDictionaryInitializer);
DESTROY(_snapshotToAdaptorRowSubsetMapping);
DESTROY(_classForInstances);
@ -931,6 +932,36 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat
return _className;
}
-(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;
}
- (NSArray *)attributesUsedForLocking
{
//OK
@ -3067,6 +3098,38 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat
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;
EOFLOGObjectFnStart();
instanceDictionaryInitializer = [self _instanceDictionaryInitializer];
EOFLOGObjectLevelArgs(@"EOEntity", @"instanceDictionaryInitializer=%@",
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];
};
EOFLOGObjectLevelArgs(@"EOEntity", @"dictionaryForProperties=%@",
dictionaryForProperties);
EOFLOGObjectFnStop();
return dictionaryForProperties;
}
- (NSArray*) _relationshipsToFaultForRow: (NSDictionary*)row
{
NSMutableArray *rels = [NSMutableArray array];
@ -3391,6 +3454,55 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat
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;
}
- (void) _setModel: (EOModel *)model
{
EOFLOGObjectFnStart();
@ -3481,6 +3593,11 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat
(_propertyDictionaryInitializer ? "Not NIL" : "NIL"));
AUTORELEASE_SETNIL(_propertyDictionaryInitializer);
EOFLOGObjectLevelArgs(@"EOEntity",@"_instanceDictionaryInitializer: %p %s",
_instanceDictionaryInitializer,
(_instanceDictionaryInitializer ? "Not NIL" : "NIL"));
AUTORELEASE_SETNIL(_instanceDictionaryInitializer);
//TODO call _flushCache on each attr
NSAssert4(!_attributesToFetch
|| [_attributesToFetch isKindOfClass: [NSArray class]],
@ -3549,32 +3666,17 @@ createInstanceWithEditingContext:globalID:zone:
*/
return gid;
}
-(Class)classForObjectWithGlobalID: (EOKeyGlobalID*)globalID
{
//near OK
Class classForInstances = _classForInstances;
EOFLOGObjectFnStart();
//TODO:use globalID ??
if (!_classForInstances)
if (!classForInstances)
{
NSString *className;
Class objectClass;
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);
}
classForInstances = [self _classForInstances];
}
EOFLOGObjectFnStop();
@ -3736,10 +3838,11 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString*)path
- (NSDictionary *)_keyMapForRelationshipPath: (NSString *)path
{
//Ayers: Review
//NearOK
NSMutableArray *sourceKeys = [NSMutableArray array];
NSMutableArray *destinationKeys = [NSMutableArray array];
NSArray *attributesToFetch = [self _attributesToFetch]; //Use It !!
//NSArray *attributesToFetch = [self _attributesToFetch]; //Use It !!
EORelationship *relationship = [self anyRelationshipNamed: path]; //?? iterate on path ? //TODO
NSEmitTODO(); //TODO
@ -3833,12 +3936,18 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString*)path
objectToken = [NSString stringWithCString:start
length: (unsigned)(s - start)];
EOFLOGObjectLevelArgs(@"EOEntity", @"objectToken: '%@'",
objectToken);
expr = [self _parsePropertyName: objectToken];
EOFLOGObjectLevelArgs(@"EOEntity", @"expr: '%@'",
expr);
if (expr)
objectToken = expr;
EOFLOGObjectLevelArgs(@"EOEntity", @"addObject:%@",
EOFLOGObjectLevelArgs(@"EOEntity", @"addObject I Token: '%@'",
objectToken);
[expressionArray addObject: objectToken];
@ -3873,7 +3982,7 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString*)path
objectToken = [NSString stringWithCString: start
length: (unsigned)(s - start)];
EOFLOGObjectLevelArgs(@"EOEntity", @"addObject:%@",
EOFLOGObjectLevelArgs(@"EOEntity", @"addObject O Token: '%@'",
objectToken);
[expressionArray addObject: objectToken];
@ -3917,7 +4026,6 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString*)path
- (EOExpressionArray*) _parseRelationshipPath: (NSString*)path
{
//Near OK quotationPlace.quotationPlaceLabels
EOEntity *entity = self;
EOExpressionArray *expressionArray = nil;
NSArray *components = nil;
@ -3981,22 +4089,23 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString*)path
}
else
{
NSDebugMLog(@"self %p name=%@: relationship \"%@\" used in \"%@\" doesn't exist in entity %@",
NSDebugMLog(@"self %p name=%@: relationship \"%@\" used in \"%@\" doesn't exist in entity \"%@\"",
self,
[self name],
path,
part,
entity);
path,
[entity name]);
//EOF don't throw exception. But we do !
[NSException raise: NSInvalidArgumentException
format: @"%@ -- %@ 0x%x: relationship \"%@\" used in \"%@\" doesn't exist in entity %@",
format: @"%@ -- %@ 0x%x: entity name=%@: relationship \"%@\" used in \"%@\" doesn't exist in entity \"%@\"",
NSStringFromSelector(_cmd),
NSStringFromClass([self class]),
self,
path,
[self name],
part,
entity];
path,
[entity name]];
}
}
EOFLOGObjectLevelArgs(@"EOEntity", @"self=%p expressionArray=%@",
@ -4426,10 +4535,11 @@ if someone has an example of EOF creating an object here without propagatesPrima
- (NSString *)inverseForRelationshipKey: (NSString *)relationshipKey
{
//Ayers: Review
//Near OK
NSString *inverseName = nil;
EORelationship *relationship = [_entity relationshipNamed: relationshipKey];
EOEntity *parentEntity = [_entity parentEntity];
//EOEntity *parentEntity = [_entity parentEntity];
//TODO what if parentEntity
EORelationship *inverseRelationship = [relationship inverseRelationship];
@ -4518,4 +4628,33 @@ if someone has an example of EOF creating an object here without propagatesPrima
return exception;
}
/** 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 NSObject (EOEntity)
/** should returns a set of property names to exclude from entity
instanceDictionaryInitializer **/
+ (NSArray *)_instanceDictionaryInitializerExcludedPropertyNames
{
// default implementation returns nil
return nil;
};
@end

View file

@ -661,7 +661,6 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
{
if ((self = [self init]))
{
NSString *name;
NSString *versionString = nil;
NSArray *entities = nil;
int i, count = 0;
@ -1039,6 +1038,7 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
}
else
{
Class entityClass=Nil;
classDescription = [entity classDescriptionForInstances];
EOFLOGObjectLevelArgs(@"gsdb", @"classDescription=%@",
classDescription);
@ -1046,8 +1046,11 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
entityClassName = [entity className];
EOFLOGObjectLevelArgs(@"gsdb",@"entityClassName=%@",entityClassName);
entityClass=NSClassFromString(entityClassName);
NSAssert1(entityClass,@"No entity class named '%@'",entityClassName);
[EOClassDescription registerClassDescription: classDescription
forClass: NSClassFromString(entityClassName)];
forClass: entityClass];
/* classDescription = [[EOClassDescription new] autorelease];
EOFLOGObjectLevelArgs(@"gsdb",
@ -1064,8 +1067,9 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
//OK
EOClassDescription *classDescription;
NSString *entityName = [notification object];
EOEntity *entity;
NSString *entityClassName;
EOEntity *entity = nil;
NSString *entityClassName = nil;
Class entityClass = Nil;
EOFLOGObjectLevelArgs(@"gsdb", @"notification=%@", notification);
EOFLOGObjectLevelArgs(@"gsdb", @"entityName=%@", entityName);
@ -1081,8 +1085,11 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
entityClassName = [entity className];
EOFLOGObjectLevelArgs(@"gsdb", @"entityClassName=%@", entityClassName);
entityClass=NSClassFromString(entityClassName);
NSAssert1(entityClass,@"No entity class named '%@'",entityClassName);
[EOClassDescription registerClassDescription: classDescription
forClass: NSClassFromString(entityClassName)];//??
forClass:entityClass];//??
}
else if ([notificationName
isEqualToString: EOClassDescriptionNeededNotification])
@ -1464,9 +1471,10 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
- (void) loadAllModelObjects
{
NSArray *storedProcedures = [self storedProcedures];
//Ayers: Review
//NSArray *storedProcedures = [self storedProcedures];
//TODO something if storedProcedures ?
NSArray *entities = [self entities];
//NSArray *entities = [self entities];
//TODO something if entities ?
[self willChange];

View file

@ -366,6 +366,10 @@ RCS_ID("$Id$")
_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"];
@ -832,6 +836,7 @@ to know what to-many mean :-) **/
- (BOOL)isReciprocalToRelationship: (EORelationship *)relationship
{
//Should be OK
//Ayers: Review
BOOL isReciprocal = NO;
EOEntity *entity;
EOEntity *relationshipDestinationEntity = nil;
@ -890,8 +895,18 @@ to know what to-many mean :-) **/
}
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