Patch added

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@15130 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-Macdonald 2002-11-27 06:44:53 +00:00
parent 4aaf233a85
commit feae00e114
3 changed files with 281 additions and 270 deletions

View file

@ -1,3 +1,10 @@
2002-11-27 Richard Frith-Macdonald <rfm@gnu.org>
* EOAccess/EOModel.h:
* EOAccess/EOModel.m: Appplied David Ayers patch for programmatic
model manipulation. Fixed typo. Use NSFileManager rather than
mkdir(). Tidied some use of autorelease for memory efficiency etc.
2002-11-26 Manuel Guesdon <mguesdon@orange-concept.com>
* EOAccess/EOEntity.m:

View file

@ -115,7 +115,7 @@
- (id) initWithTableOfContentsPropertyList: (NSDictionary *)tableOfContents
path: (NSString *)path;
- (void)encodeTableOfContentsInfoPropertyList: (NSMutableDictionary *)propertyList;
- (void)encodeTableOfContentsIntoPropertyList: (NSMutableDictionary *)propertyList;
- (void)encodeIntoPropertyList: (NSMutableDictionary *)propertyList;
- (void)awakeWithPropertyList: (NSDictionary *)propertyList;
@ -177,13 +177,4 @@
extern NSString *EOEntityLoadedNotification;
@interface EOModel (EOModelPrivate)
- (void)setCreateMutableObjects: (BOOL)flag;
- (BOOL)createsMutableObjects;
- (EOEntity *)_verifyBuiltEntityObject: (id)entity
named: (NSString *)name;
@end /* EOModel (EOModelPrivate) */
#endif /* __EOModel_h__ */

View file

@ -34,41 +34,51 @@
static char rcsId[] = "$Id$";
#import <Foundation/Foundation.h>
#include <Foundation/Foundation.h>
#import <Foundation/NSBundle.h>
#import <Foundation/NSValue.h>
#import <Foundation/NSUtilities.h>
#import <Foundation/NSObjCRuntime.h>
#include <Foundation/NSBundle.h>
#include <Foundation/NSValue.h>
#include <Foundation/NSUtilities.h>
#include <Foundation/NSObjCRuntime.h>
#include <Foundation/NSException.h>
#include <Foundation/NSFileManager.h>
#include <Foundation/NSValue.h>
#import <Foundation/NSException.h>
#include <EOAccess/EOModel.h>
#include <EOAccess/EOEntity.h>
#include <EOAccess/EOEntityPriv.h>
#include <EOAccess/EOStoredProcedure.h>
#include <EOAccess/EOModelGroup.h>
#include <EOAccess/EOAccessFault.h>
#import <EOAccess/EOModel.h>
#import <EOAccess/EOEntity.h>
#import <EOAccess/EOEntityPriv.h>
#import <EOAccess/EOStoredProcedure.h>
#import <EOAccess/EOModelGroup.h>
#import <EOAccess/EOAccessFault.h>
#import <EOControl/EOGenericRecord.h>
#import <EOControl/EOFault.h>
#import <EOControl/EOKeyGlobalID.h>
#import <EOControl/EOClassDescription.h>
#import <EOControl/EOObserver.h>
#import <EOControl/EONSAddOns.h>
#import <EOControl/EODebug.h>
#include <sys/stat.h>
#include <EOControl/EOGenericRecord.h>
#include <EOControl/EOFault.h>
#include <EOControl/EOKeyGlobalID.h>
#include <EOControl/EOClassDescription.h>
#include <EOControl/EOObserver.h>
#include <EOControl/EONSAddOns.h>
#include <EOControl/EODebug.h>
NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
@interface EOModel (EOModelPrivate)
+ (NSString *) _formatModelPath: (NSString *)path checkFileSystem: (BOOL)chkFS;
- (void) setCreateMutableObjects: (BOOL)flag;
- (BOOL) createsMutableObjects;
- (EOEntity *) _verifyBuiltEntityObject: (id)entity
named: (NSString *)name;
@end /* EOModel (EOModelPrivate) */
@implementation EOModel
+ (EOModel*) model
{
return [[[self alloc] init] autorelease];
return AUTORELEASE([[self alloc] init]);
}
+ (NSString*) findPathForModelNamed: (NSString *)modelName
@ -173,6 +183,7 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
if ((self = [super init]))
{
// Turbocat
_version = 2;
_flags.createsMutableObjects = YES;
_entitiesByName = [GCMutableDictionary new];
@ -270,48 +281,6 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
return YES;
}
/*Mirko:
- (void)_registerClassDescForClass:(NSNotification *)notification
{
EOEntityClassDescription *classDesc = nil;
Class aClass = [notification object];
int i;
if (_entitiesByClass == NULL)
return;
for (i = 0; ((Class *)_entitiesByClass)[i]; i = i + 2)
{
if(aClass == ((Class *)_entitiesByClass)[i])
{
classDesc = [EOEntityClassDescription entityClassDescriptionWithEntity: ((EOEntity **)_entitiesByClass)[i+1]];
[EOClassDescription registerClassDescription:classDesc
forClass:aClass];
return;
}
}
}
- (void)_registerClassDescForEntityName:(NSNotification *)notification
{
EOEntityClassDescription *classDesc;
NSString *entityName = [notification object];
EOEntity *entity;
entity = [self entityNamed:entityName];
if (entity)
{
classDesc = [EOEntityClassDescription entityClassDescriptionWithEntity: entity];
[EOClassDescription registerClassDescription: classDesc
forClass: NSClassFromString([entity className])];
}
}
*/
- (NSString*) path
{
return _path;
@ -425,7 +394,7 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
return _storedProcedures;
}
- (EOEntity *)entityForObject: object
- (EOEntity*) entityForObject: (id)object
{
EOEntity *entity = nil;
NSString *entityName = nil;
@ -461,6 +430,30 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
return _userInfo;
}
- (NSString*) description
{
NSMutableDictionary *descdict;
id obj;
descdict = [[NSMutableDictionary alloc] initWithCapacity: 6];
obj = [self name];
if (obj) [descdict setObject: obj forKey: @"name"];
obj = [self adaptorName];
if (obj) [descdict setObject: obj forKey: @"adaptorName"];
obj = [self connectionDictionary];
if (obj) [descdict setObject: obj forKey: @"connectionDictionary"];
obj = [self userInfo];
if (obj) [descdict setObject: obj forKey: @"userInfo"];
obj = [self entities];
if (obj) [descdict setObject: obj forKey: @"entities"];
obj = [self storedProcedures];
if (obj) [descdict setObject: obj forKey: @"storedProcedures"];
obj = [descdict description];
RELEASE(descdict);
return obj;
}
- (NSString*) docComment
{
return _docComment;
@ -483,76 +476,51 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
+ (EOModel*) modelWithContentsOfFile: (NSString *)path
{
return [[[self alloc] initWithContentsOfFile: path] autorelease];
return AUTORELEASE([[self alloc] initWithContentsOfFile: path]);
}
- (id) initWithContentsOfFile: (NSString *)path
{
NS_DURING
{
NSDictionary *propList = nil;
NSString *completePath = [[self class] findPathForModelNamed: path];
NSString *name = nil;
NSString *modelPath = nil;
NSString *indexPath = nil;
NSString *fileContents = nil;
NSDictionary *propList = nil;
NSDebugMLLog(@"gsdb", @"path=%@", path);
NSDebugMLLog(@"gsdb", @"completePath=%@", completePath);
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 ([[completePath pathExtension] isEqualToString: @"eomodeld"])
indexPath = [completePath stringByAppendingPathComponent:
@"index.eomodeld"];
if ([[modelPath pathExtension] isEqualToString: @"eomodeld"])
{
indexPath =
[modelPath stringByAppendingPathComponent: @"index.eomodeld"];
}
else
indexPath = completePath;
{
indexPath = modelPath;
}
NSDebugMLLog(@"gsdb", @"path=%@ completePath=%@ indexPath=%@",
path, completePath, indexPath);
propList = [[NSString stringWithContentsOfFile: indexPath] propertyList];
fileContents = [NSString stringWithContentsOfFile: indexPath];
propList = [fileContents propertyList];
NSDebugMLLog(@"gsdb", @"propList=%@", propList);
NSAssert1(propList!=nil, @"Model at path %@ is invalid", indexPath);
if (!propList)
{
NSLog(@"Loading model (path=%@ \n index path=%@) failed",
path,
indexPath);
//Try loading directly from path
if ([[path pathExtension] isEqualToString: @"eomodeld"])
indexPath = [path stringByAppendingPathComponent:
@"index.eomodeld"];
else
indexPath = path;
NSDebugMLLog(@"gsdb", @"path=%@ completePath=%@ indexPath=%@",
path, completePath, indexPath);
propList = [[NSString stringWithContentsOfFile: indexPath] propertyList];
NSDebugMLLog(@"gsdb", @"propList=%@", propList);
}
//TODO test it
NSAssert2(propList, @"Loading model (path=%@ \n index path=%@) failed",
path,
indexPath);
//what to do if it fail ?
if ((self = [self initWithTableOfContentsPropertyList: propList
path: path]))
{
}
else
{
NSEmitTODO();
return [self notImplemented: _cmd]; //TODO
}
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=ExceptionByAddingUserInfoObjectFrameInfo(localException,
@"In EOModel initWithContentsOfFile:");*/
NSLog(@"exception=%@", localException);
[localException raise];
}
NS_ENDHANDLER;
@ -562,7 +530,9 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
- (void) writeToFile: (NSString *)path
{
NSFileManager *mgr = [NSFileManager defaultManager];
NSMutableDictionary *pList;
NSDictionary *attributes;
NSDictionary *entityPList;
NSEnumerator *entityEnum;
@ -574,19 +544,20 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
[self encodeIntoPropertyList: pList];
mkdir([path cString], S_IRWXU | S_IRWXG | S_IRWXO);
attributes = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithUnsignedLong: 0777], NSFilePosixPermissions,
nil];
[mgr createDirectoryAtPath: path attributes: attributes];
entityEnum = [[pList objectForKey: @"entities"] objectEnumerator];
while ((entityPList = [entityEnum nextObject]))
{
NSString *fileName;
NSArray *entityArray;
fileName = [path stringByAppendingPathComponent:
[NSString stringWithFormat: @"%@.plist",
[entityPList objectForKey: @"name"]]];
entityArray = [NSArray arrayWithObject: entityPList];
[entityArray writeToFile: fileName atomically: YES];
[entityPList writeToFile: fileName atomically: YES];
}
{
@ -595,7 +566,7 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
fileName = [path stringByAppendingPathComponent: @"index.eomodeld"];
[pList removeAllObjects];
[self encodeTableOfContentsInfoPropertyList: pList];
[self encodeTableOfContentsIntoPropertyList: pList];
[pList writeToFile: fileName atomically: YES];
}
}
@ -612,21 +583,22 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
{
if ((self = [self init]))
{
NSString *name;
NSString *versionString = nil;
NSArray *entities = nil;
int i, count = 0;
[self _setPath: path];
_name = [[EOModel findPathForModelNamed: _path] retain];
NSDebugMLLog(@"gsdb", @"tableOfContents=%@", tableOfContents);
NSAssert1(_name, @"No name for model (path=%@)", path);
[self setName: _name];//??
/* The call to _setPath: also sets the name implicitly. */
[self _setPath: [isa _formatModelPath: path checkFileSystem: YES]];
NSDebugMLLog(@"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"]);
@ -695,9 +667,6 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
{
NSLog(@"exception in EOModel initWithTableOfContentsPropertyList:path:");
NSLog(@"exception=%@", localException);
/* localException=ExceptionByAddingUserInfoObjectFrameInfo(localException,
@"In EOModel initWithTableOfContentsPropertyList:path:");*/
NSLog(@"exception=%@", localException);
[localException raise];
}
NS_ENDHANDLER;
@ -705,12 +674,14 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
return self;
}
- (void)encodeTableOfContentsInfoPropertyList: (NSMutableDictionary *)propertyList
- (void) encodeTableOfContentsIntoPropertyList:
(NSMutableDictionary *)propertyList
{
int i, count;
NSMutableArray *entitiesArray;
[propertyList setObject: [[NSNumber numberWithFloat: [isa version]] stringValue]
[propertyList setObject:
[[NSNumber numberWithFloat: [isa version]] stringValue]
forKey: @"EOModelVersion"];
if (_adaptorName)
@ -881,10 +852,6 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
{
NSLog(@"exception in EOModel initWithPropertyList:owner:");
NSLog(@"exception=%@", localException);
/* localException=ExceptionByAddingUserInfoObjectFrameInfo(localException,
@"In EOModel initWithPropertyList:owner:");
*/
NSLog(@"exception=%@", localException);
[localException raise];
}
NS_ENDHANDLER;
@ -1064,14 +1031,13 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
return nil;
}
- (void) _setPath: (NSString*)path
{
//OK
[self loadAllModelObjects];
[self willChange];
ASSIGN(_path,path);
[self setName: [path stringByDeletingPathExtension]];//VERIFY
[self setName: [[path lastPathComponents] stringByDeletingPathExtension]];
}
- (EOEntity*) _entityForClass: (Class)aClass
@ -1313,20 +1279,13 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
[(GCMutableArray *)_entities addObject: entity];
else
{
_entities = [[[_entities autorelease] mutableCopy] autorelease];
[(GCMutableArray *)_entities addObject: entity];
_entities = [_entities copy];
id e = [[GCMutableArray alloc] initWithArray: _entities];
[e addObject: entity];
ASSIGNCOPY(_entities, e);
RELEASE(e);
}
/*
count = [_entities count];
entitiesClass = calloc(count, sizeof(id));
memcpy(entitiesClass, _entitiesByClass, sizeof(Class)*(count-1));
((Class *)entitiesClass)[count-1] = [entity class];
free(_entitiesByClass);
_entitiesByClass = entitiesClass;
*/
NSAssert(_entitiesByClass, @"No _entitiesByClass");
className = [entity className];
@ -1344,28 +1303,11 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
- (void) removeEntity: (EOEntity *)entity
{
// unsigned int entityIndex = [_entities indexOfObject:entity];
NSString *className = nil;
// void *entitiesClass=NULL;
// int count;
[entity setModel: nil];
[_entitiesByName removeObjectForKey: [entity name]];
/* count = [_entities count]-1;
if(count)
{
entitiesClass = calloc(count, sizeof(id));
if(entityIndex)
memcpy(entitiesClass, _entitiesByClass, sizeof(id)*entityIndex);
if(count > entityIndex)
memcpy(&((int *)entitiesClass)[entityIndex],
&((int *)_entitiesByClass)[entityIndex+1],
sizeof(id)*(count-entityIndex));
}
free(_entitiesByClass);
_entitiesByClass = entitiesClass;
*/
NSAssert(_entitiesByClass, @"No _entitiesByClass");
className = [entity className];
@ -1376,9 +1318,11 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
[(GCMutableArray *)_entities removeObject: entity];
else
{
_entities = [[_entities autorelease] mutableCopy];
[(GCMutableArray *)_entities removeObject: entity];
_entities = [[_entities autorelease] copy];
id e = [[GCMutableArray alloc] initWithArray: _entities];
[e removeObject: entity];
ASSIGNCOPY(_entities, e);
RELEASE(e);
}
}
@ -1517,6 +1461,75 @@ letter of each embedded word other than the first, which is upper case. Thus,
@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;
}
- (void) setCreateMutableObjects: (BOOL)flag
{
@ -1539,7 +1552,7 @@ letter of each embedded word other than the first, which is upper case. Thus,
- (EOEntity *) _verifyBuiltEntityObject: (id)entity
named: (NSString*)name
{
if (![entity isKindOfClass: [EOEntity class]])
if ([entity isKindOfClass: [EOEntity class]] == NO)
{
[EOObserverCenter suppressObserverNotification];
@ -1558,7 +1571,7 @@ letter of each embedded word other than the first, which is upper case. Thus,
NSAssert1(name, @"No name for entity %@", entity);
NSDebugMLLog(@"gsdb", @"[self path]=%@", [self path]);
basePath = [[self class] findPathForModelNamed: [self path]];
basePath = [self path];
[[entity retain] autorelease]; //so it won't be lost in _removeEntity
NSDebugMLLog(@"gsdb", @"basePath =%@", basePath);