remove hacks, adapt to EOCustomObject

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@30192 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Dave Wetzel 2010-04-19 07:15:37 +00:00
parent 0a68de0f7c
commit d763dcfadd
8 changed files with 1198 additions and 1450 deletions

View file

@ -1,3 +1,14 @@
2010-04-19 David Wetzel <dave@turbocat.de>
* EOInterface/EOAssociation.m: remove hacks
* EOControl/EOEditingContext.m: remove hacks, adapt to EOCustomObject
* EOControl/EOCustomObject.h/m: added code here
* EOControl/EOClassDescription.h/m: adapt to EOCustomObject
* EOControl/EOPrivate.h: adapt to EOCustomObject
* EOControl/EOClassDescription.m:adapt to EOCustomObject
* EOAccess/EODatabaseContext.m rewrote qualifierForLockingAttributes:primaryKeyAttributes:entity:snapshot:
2010-04-17 David Wetzel <dave@turbocat.de>
* EOCustomObject.h/m new class like in EOF3. Use this as your EO's superclass or
use EOGenericRecords

View file

@ -35,6 +35,8 @@
#include <Foundation/Foundation.h>
#endif
#import <Foundation/NSClassDescription.h>
#include <EOControl/EODefines.h>
@class NSDictionary;
@ -53,7 +55,7 @@ typedef enum
} EODeleteRule;
@interface EOClassDescription : NSObject
@interface EOClassDescription : NSClassDescription
+ (void)registerClassDescription: (EOClassDescription *)description
forClass: (Class)aClass;
@ -118,42 +120,6 @@ fromFetchInEditingContext: (EOEditingContext *)editingContext;
@end
@interface NSObject (EOInitialization)
- (id)initWithEditingContext: (EOEditingContext *)editingContext
classDescription: (EOClassDescription *)classDescription
globalID: (EOGlobalID *)globalID;
@end
@interface NSObject (EOClassDescriptionPrimitives)
- (EOClassDescription *)classDescription;
- (NSString *)entityName;
- (NSArray *)attributeKeys;
- (NSArray *)toOneRelationshipKeys;
- (NSArray *)toManyRelationshipKeys;
- (NSString *)inverseForRelationshipKey: (NSString *)relationshipKey;
- (EODeleteRule)deleteRuleForRelationshipKey: (NSString *)relationshipKey;
- (BOOL)ownsDestinationObjectsForRelationshipKey: (NSString *)relationshipKey;
- (EOClassDescription *)classDescriptionForDestinationKey: (NSString *)detailKey;
- (NSString *)userPresentableDescription;
- (NSException *)validateValue: (id *)valueP forKey: (NSString *)key;
- (id)validateTakeValue:(id)value forKeyPath:(NSString *)path;
- (NSException *)validateForSave;
- (NSException *)validateForDelete;
- (void)awakeFromInsertionInEditingContext: (EOEditingContext *)editingContext;
- (void)awakeFromFetchInEditingContext: (EOEditingContext *)editingContext;
@end
GDL2CONTROL_EXPORT NSString *EOClassDescriptionNeededNotification;
GDL2CONTROL_EXPORT NSString *EOClassDescriptionNeededForClassNotification;
GDL2CONTROL_EXPORT NSString *EOClassDescriptionNeededForEntityNameNotification;
@ -165,42 +131,6 @@ GDL2CONTROL_EXPORT NSString *EOClassDescriptionNeededForEntityNameNotification;
@end
@interface NSObject (EOClassDescriptionExtras)
- (NSDictionary *)snapshot;
- (void)updateFromSnapshot: (NSDictionary *)snapshot;
- (BOOL)isToManyKey: (NSString *)key;
- (NSException *)validateForInsert;
- (NSException *)validateForUpdate;
- (NSArray *)allPropertyKeys;
- (void)clearProperties;
- (void)propagateDeleteWithEditingContext: (EOEditingContext *)editingContext;
- (NSString *)eoShallowDescription;
- (NSString *)eoDescription;
@end
@interface NSObject (EOKeyRelationshipManipulation)
- (void)addObject: (id)object toPropertyWithKey: (NSString *)key;
- (void)removeObject: (id)object fromPropertyWithKey: (NSString *)key;
- (void)addObject: (id)object
toBothSidesOfRelationshipWithKey: (NSString *)key;
- (void)removeObject: (id)object
fromBothSidesOfRelationshipWithKey: (NSString *)key;
@end
/*
* Validation exceptions (with name EOValidationException)
*/
@ -225,14 +155,4 @@ GDL2CONTROL_EXPORT NSString *EOValidatedPropertyUserInfoKey;
@end
@interface NSObject (_EOValueMerging)
- (void)mergeValue: (id)value forKey: (id)key;
- (void)mergeChangesFromDictionary: (NSDictionary *)changes;
- (NSDictionary *)changesFromSnapshot: (NSDictionary *)snapshot;
- (void)reapplyChangesFromSnapshot: (NSDictionary *)changes;
@end
#endif

File diff suppressed because it is too large Load diff

View file

@ -29,16 +29,96 @@
#ifdef GNUSTEP
#include <Foundation/NSObject.h>
#include <Foundation/NSKeyValueCoding.h>
#else
#include <Foundation/Foundation.h>
#endif
#include <EOControl/EOClassDescription.h>
@class EOEditingContext;
@interface EOCustomObject : NSObject
{
}
- (id)initWithEditingContext: (EOEditingContext *)editingContext
classDescription: (EOClassDescription *)classDescription
globalID: (EOGlobalID *)globalID;
// -----------------------------------------------
// those used to be EOClassDescriptionPrimitives
- (EOClassDescription *)classDescription;
- (NSString *)entityName;
- (NSArray *)attributeKeys;
- (NSArray *)toOneRelationshipKeys;
- (NSArray *)toManyRelationshipKeys;
- (NSString *)inverseForRelationshipKey: (NSString *)relationshipKey;
- (EODeleteRule)deleteRuleForRelationshipKey: (NSString *)relationshipKey;
- (BOOL)ownsDestinationObjectsForRelationshipKey: (NSString *)relationshipKey;
- (EOClassDescription *)classDescriptionForDestinationKey: (NSString *)detailKey;
- (NSString *)userPresentableDescription;
- (NSException *)validateValue: (id *)valueP forKey: (NSString *)key;
- (id)validateTakeValue:(id)value forKeyPath:(NSString *)path;
- (NSException *)validateForSave;
- (NSException *)validateForDelete;
- (void)awakeFromInsertionInEditingContext: (EOEditingContext *)editingContext;
- (void)awakeFromFetchInEditingContext: (EOEditingContext *)editingContext;
// -----------------------------------------------
// those used to be EOKeyRelationshipManipulation
- (void)addObject: (id)object toPropertyWithKey: (NSString *)key;
- (void)removeObject: (id)object fromPropertyWithKey: (NSString *)key;
- (void)addObject: (id)object toBothSidesOfRelationshipWithKey: (NSString *)key;
- (void)removeObject: (id)object fromBothSidesOfRelationshipWithKey: (NSString *)key;
// -----------------------------------------------
// those used to be NSObject (_EOValueMerging)
- (void)mergeValue: (id)value forKey: (id)key;
- (void)mergeChangesFromDictionary: (NSDictionary *)changes;
- (NSDictionary *)changesFromSnapshot: (NSDictionary *)snapshot;
- (void)reapplyChangesFromSnapshot: (NSDictionary *)changes;
// -----------------------------------------------
// those used to be NSObject (EOClassDescriptionExtras)
- (NSDictionary *)snapshot;
- (void)updateFromSnapshot: (NSDictionary *)snapshot;
- (BOOL)isToManyKey: (NSString *)key;
- (NSException *)validateForInsert;
- (NSException *)validateForUpdate;
- (NSArray *)allPropertyKeys;
- (void)clearProperties;
- (void)propagateDeleteWithEditingContext: (EOEditingContext *)editingContext;
- (NSString *)eoShallowDescription;
- (NSString *)eoDescription;
@end
#endif // __EOCustomObject_h__

File diff suppressed because it is too large Load diff

View file

@ -55,7 +55,7 @@ RCS_ID("$Id$")
#include "EONSAddOns.h"
#include "EODeprecated.h"
#include "EODebug.h"
#include "EOCustomObject.h"
#include "EOPrivate.h"
@class EOEntityClassDescription;
@ -171,8 +171,8 @@ static Class EOAssociationClass = nil;
static EOObjectStore *defaultParentStore = nil;
static NSTimeInterval defaultFetchLag = 3600.0;
static NSHashTable *ecDeallocHT = 0;
static NSHashTable *assocDeallocHT = 0;
//static NSHashTable *ecDeallocHT = 0;
//static NSHashTable *assocDeallocHT = 0;
/* Notifications */
NSString *EOObjectsChangedInEditingContextNotification
@ -265,9 +265,15 @@ _mergeValueForKey(id obj, id value,
}
}
+ (void)objectDeallocated:(id)object
+ (void)_objectDeallocated:(id)object
{
[[object editingContext] forgetObject: object];
if (EOAssociationClass != nil)
{
[EOAssociationClass objectDeallocated: object]; // rename to _objectDeallocated: ? -- dw
}
}
+ (NSTimeInterval)defaultFetchTimestampLag
@ -1407,71 +1413,59 @@ _mergeValueForKey(id obj, id value,
withGlobalID: (EOGlobalID *)gid
{
EOGlobalID *gidBis = nil;
EOFLOGObjectFnStart();
EOFLOGObjectLevelArgs(@"EOEditingContext", @"Object %p=%@", object, object);
EOFLOGObjectLevelArgs(@"EOEditingContext", @"gid=%@",gid);
EOFLOGObjectLevelArgs(@"EOEditingContext", @"Unprocessed: %@",
[self unprocessedDescription]);
EOFLOGObjectLevelArgs(@"EOEditingContext", @"Objects: %@",
[self objectsDescription]);
NSAssert(object, @"No Object");
NSAssert([object isKindOfClass:[EOCustomObject class]] , @"Sorry, only subclasses of EOCustomObject supported in this version.");
//GSWDisplayGroup -insertAtIndex+EODataSource createObject call insert ! So object is inserted twice
if (_insertedObjects && NSHashGet(_insertedObjects, object))
{
// NSLog(@"Already inserted object [_insertedObjects] %p=%@",object,object);
EOFLOGObjectLevelArgs(@"EOEditingContext",
@"Already inserted gid=%@ object [_insertedObjects] %p=%@",
gid, object, object);
}
{
// NSLog(@"Already inserted object [_insertedObjects] %p=%@",object,object);
EOFLOGObjectLevelArgs(@"EOEditingContext",
@"Already inserted gid=%@ object [_insertedObjects] %p=%@",
gid, object, object);
}
else if (_unprocessedInserts && NSHashGet(_unprocessedInserts, object))
{
// NSLog(@"Already inserted object [_unprocessedInserts] %p=%@",object,object);
EOFLOGObjectLevelArgs(@"EOEditingContext",
@"Already inserted gid=%@ object [_unprocessedInserts] %p=%@",
gid, object, object);
}
{
// NSLog(@"Already inserted object [_unprocessedInserts] %p=%@",object,object);
EOFLOGObjectLevelArgs(@"EOEditingContext",
@"Already inserted gid=%@ object [_unprocessedInserts] %p=%@",
gid, object, object);
}
if ([gid isTemporary])
{
[self _registerClearStateWithUndoManager];
[_undoManager registerUndoWithTarget: self
selector: @selector(deleteObject:)
object: object];
gidBis = EOEditingContext_globalIDForObjectWithImpPtr(self,NULL,object);
/* Record object for GID mappings. */
if (gidBis)
{
[self _registerClearStateWithUndoManager];
[_undoManager registerUndoWithTarget: self
selector: @selector(deleteObject:)
object: object];
gidBis = EOEditingContext_globalIDForObjectWithImpPtr(self,NULL,object);
/* Record object for GID mappings. */
if (gidBis)
{
EOFLOGObjectLevelArgs(@"EOEditingContext",
@"Already recored gid=%@ previous gid=%@ object %p=%@",
gid, gidBis, object, object);
}
else
{
NSAssert(gid, @"No gid");
EOEditingContext_recordObjectGlobalIDWithImpPtr(self,NULL,object,gid);
}
/* Do the actual insert into the editing context,
independent of whether this object has ever been
previously tracked by the GID mappings. */
NSHashInsert(_unprocessedInserts, object);
[self _enqueueEndOfEventNotification];
EOFLOGObjectLevelArgs(@"EOEditingContext",
@"Already recored gid=%@ previous gid=%@ object %p=%@",
gid, gidBis, object, object);
}
EOFLOGObjectLevelArgs(@"EOEditingContext", @"Unprocessed: %@",
[self unprocessedDescription]);
EOFLOGObjectLevelArgs(@"EOEditingContext", @"Objects: %@",
[self objectsDescription]);
EOFLOGObjectFnStop();
else
{
NSAssert(gid, @"No gid");
EOEditingContext_recordObjectGlobalIDWithImpPtr(self,NULL,object,gid);
}
/* Do the actual insert into the editing context,
independent of whether this object has ever been
previously tracked by the GID mappings. */
NSHashInsert(_unprocessedInserts, object);
[self _enqueueEndOfEventNotification];
}
}
- (void)_processEndOfEventNotification: (NSNotification*)notification
@ -2841,15 +2835,11 @@ _mergeValueForKey(id obj, id value,
{
EOObjectStore *rootObjectStore;
EOFLOGObjectFnStart();
if ([_objectStore isKindOfClass: [EOEditingContext class]] == YES)
rootObjectStore = [(EOEditingContext *)_objectStore rootObjectStore];
else
rootObjectStore=_objectStore;
EOFLOGObjectFnStop();
return rootObjectStore;
}
@ -2964,12 +2954,12 @@ _mergeValueForKey(id obj, id value,
NSAssert(globalID, @"No GlobalID");
/* Global hash table for faster dealloc. */
if (!ecDeallocHT)
{
ecDeallocHT
= NSCreateHashTable(NSNonOwnedPointerHashCallBacks, 64);
}
NSHashInsert(ecDeallocHT, object);
// if (!ecDeallocHT)
// {
// ecDeallocHT
// = NSCreateHashTable(NSNonOwnedPointerHashCallBacks, 64);
// }
// NSHashInsert(ecDeallocHT, object);
EOFLOGObjectLevel(@"EOEditingContext", @"insertInto _globalIDsByObject");
NSMapInsert(_globalIDsByObject, object, globalID);
@ -3008,7 +2998,7 @@ _mergeValueForKey(id obj, id value,
EOFLOGObjectFnStart();
/* Global hash table for faster dealloc. */
NSHashRemove(ecDeallocHT, object);
//NSHashRemove(ecDeallocHT, object);
gid = EOEditingContext_globalIDForObjectWithImpPtr(self,NULL,object);
@ -4030,42 +4020,3 @@ static BOOL usesContextRelativeEncoding = NO;
[self notImplemented: _cmd]; //TODO
}
@end
@implementation NSObject (DeallocHack)
/*
* This is a real hack that shows that the design of this
* library did not take the reference counting mechanisms
* of OpenStep to heart. I'm sorry kids, but this seems
* how it has to be done to remain compatible. Any hints
* on how to speed this up are appreciated. But understand
* that we don't know the classes which need to call this
* and there could be deep hierarchy.
*/
- (void) dealloc
{
if (ecDeallocHT && NSHashGet(ecDeallocHT, self))
{
[GDL2_EOEditingContextClass objectDeallocated: self];
}
if (assocDeallocHT && NSHashGet(assocDeallocHT, self))
{
[EOAssociationClass objectDeallocated: self];
NSHashRemove(assocDeallocHT,self);
}
[EOObserverCenter _forgetObject:self];
/* We cannot if (0) [super dealloc]; as NSObject does not have superclass. */
NSDeallocateObject (self);
}
- (void) registerAssociationForDeallocHack:(id)object
{
if (!assocDeallocHT)
{
assocDeallocHT = NSCreateHashTable(NSNonOwnedPointerHashCallBacks, 64);
}
NSHashInsert(assocDeallocHT, object);
}
@end

View file

@ -30,13 +30,13 @@
#include <Foundation/NSArray.h>
#include <Foundation/NSHashTable.h>
#include <EOControl/EOObserver.h>
#include <EOControl/EOEditingContext.h>
#include "EODefines.h"
@class NSNumber;
@class EONull;
@class EOMutableKnownKeyDictionary;
@class EOMKKDInitializer;
@class EOEditingContext;
@class EOGlobalID;
typedef unsigned int (*GDL2IMP_UINT)(id, SEL, ...);
@ -378,8 +378,8 @@ GDL2CONTROL_EXPORT BOOL GDL2_isLegalDBName(NSString *name);
// ==== Memory Management Utilities ====
@interface NSObject (DeallocHack)
- (void) registerAssociationForDeallocHack:(id)object;
@interface EOEditingContext (EOMemoryManagement)
+ (void)_objectDeallocated:(id)object;
@end
@interface EOObserverCenter(EOPrivate)

View file

@ -212,43 +212,43 @@ static NSMapTable *_objectToAssociations;
- (void)establishConnection
{
if (_isConnected == NO)
{
NSMapEnumerator displayGroupEnum;
EODisplayGroup *displayGroup;
void *unusedKey;
GDL2NonRetainingMutableArray *associations;
displayGroupEnum = NSEnumerateMapTable(_displayGroupMap);
while (NSNextMapEnumeratorPair(&displayGroupEnum,
&unusedKey, (void*)&displayGroup))
{
NSMapEnumerator displayGroupEnum;
EODisplayGroup *displayGroup;
void *unusedKey;
GDL2NonRetainingMutableArray *associations;
displayGroupEnum = NSEnumerateMapTable(_displayGroupMap);
while (NSNextMapEnumeratorPair(&displayGroupEnum,
&unusedKey, (void*)&displayGroup))
{
[displayGroup retain];
[EOObserverCenter addObserver:self forObject:displayGroup];
}
NSEndMapTableEnumeration (&displayGroupEnum);
/* registerAssociationForDeallocHack is implemented in
EOControl/EOEditingContext.m this causes +objectDeallocated:
to be called when '_object' is deallocated, which will break the
connection which releases the association instance. */
[self retain];
[self registerAssociationForDeallocHack:_object];
associations = (id)NSMapGet(_objectToAssociations, _object);
if (!associations)
{
associations = [[GDL2NonRetainingMutableArray alloc] initWithCapacity:32];
[associations addObject:self];
NSMapInsert(_objectToAssociations, _object, associations);
}
else
{
[associations addObject:self];
}
_isConnected = YES;
[displayGroup retain];
[EOObserverCenter addObserver:self forObject:displayGroup];
}
NSEndMapTableEnumeration (&displayGroupEnum);
/* registerAssociationForDeallocHack is implemented in
EOControl/EOEditingContext.m this causes +objectDeallocated:
to be called when '_object' is deallocated, which will break the
connection which releases the association instance. */
[self retain];
// [self registerAssociationForDeallocHack:_object];
associations = (id)NSMapGet(_objectToAssociations, _object);
if (!associations)
{
associations = [[GDL2NonRetainingMutableArray alloc] initWithCapacity:32];
[associations addObject:self];
NSMapInsert(_objectToAssociations, _object, associations);
}
else
{
[associations addObject:self];
}
_isConnected = YES;
}
}
- (void)breakConnection