mirror of
https://github.com/gnustep/libs-gdl2.git
synced 2025-04-22 12:55:44 +00:00
* EOAccess/EODatabase.m
* EOAccess/EODatabase.h add _doesReleaseUnreferencedSnapshots add dummy for incrementSnapshotCountForGlobalID add dummy for decrementSnapshotCountForGlobalID add disableSnapshotRefcounting * EOAccess/EODatabaseContext.m retain EOAdaptorChannel created by adaptor This is documented in WO 4.5. Otherwise it gets closed after the request's autorelease pool is drained. I tested this on OSX with the BookStore example. added some dummies for future implementation refactor objectsWithFetchSpecification: editingContext: refactor commitChanges * EOAccess/EODatabaseChannel.m reformat * EOAdaptors/PostgreSQLAdaptor/PostgreSQLExpression.m add include * EOControl/EOGenericRecord.m add [self willChange] in setValue:forUndefinedKey: this will make saving changes possible for EOGenericRecord otherwise it was just showing them in memory git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@30675 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
5c4b24e769
commit
7671304816
7 changed files with 535 additions and 1064 deletions
25
ChangeLog
25
ChangeLog
|
@ -1,3 +1,28 @@
|
|||
2010-06-11 David Wetzel <dave@turbocat.de>
|
||||
* EOAccess/EODatabase.m
|
||||
* EOAccess/EODatabase.h
|
||||
add _doesReleaseUnreferencedSnapshots
|
||||
add dummy for incrementSnapshotCountForGlobalID
|
||||
add dummy for decrementSnapshotCountForGlobalID
|
||||
add disableSnapshotRefcounting
|
||||
* EOAccess/EODatabaseContext.m
|
||||
retain EOAdaptorChannel created by adaptor
|
||||
This is documented in WO 4.5.
|
||||
Otherwise it gets closed after the request's
|
||||
autorelease pool is drained.
|
||||
I tested this on OSX with the BookStore example.
|
||||
added some dummies for future implementation
|
||||
refactor objectsWithFetchSpecification: editingContext:
|
||||
refactor commitChanges
|
||||
* EOAccess/EODatabaseChannel.m
|
||||
reformat
|
||||
* EOAdaptors/PostgreSQLAdaptor/PostgreSQLExpression.m
|
||||
add include
|
||||
* EOControl/EOGenericRecord.m
|
||||
add [self willChange] in setValue:forUndefinedKey:
|
||||
this will make saving changes possible for EOGenericRecord
|
||||
otherwise it was just showing them in memory
|
||||
|
||||
2010-06-10 David Wetzel <dave@turbocat.de>
|
||||
* EOControl/EOGenericRecord.h
|
||||
* EOControl/EOGenericRecord.m
|
||||
|
|
|
@ -72,6 +72,10 @@ GDL2ACCESS_EXPORT NSTimeInterval EODistantPastTimeInterval;
|
|||
|
||||
- (id)initWithModel: (EOModel *)model;
|
||||
|
||||
- (void)incrementSnapshotCountForGlobalID:(EOGlobalID *)globalId;
|
||||
- (void)decrementSnapshotCountForGlobalID:(EOGlobalID *)globalId;
|
||||
+ (void)disableSnapshotRefcounting;
|
||||
|
||||
- (NSArray *)registeredContexts;
|
||||
|
||||
- (void)registerContext: (EODatabaseContext *)context;
|
||||
|
|
|
@ -75,6 +75,7 @@ RCS_ID("$Id$")
|
|||
|
||||
NSString *EOGeneralDatabaseException = @"EOGeneralDatabaseException";
|
||||
NSTimeInterval EODistantPastTimeInterval = -603979776.0;
|
||||
static BOOL _doesReleaseUnreferencedSnapshots = YES;
|
||||
|
||||
@implementation EODatabase
|
||||
|
||||
|
@ -173,6 +174,29 @@ static NSMutableArray *databaseInstances;
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)incrementSnapshotCountForGlobalID:(EOGlobalID *)globalId
|
||||
{
|
||||
if (!_doesReleaseUnreferencedSnapshots)
|
||||
{
|
||||
return;
|
||||
}
|
||||
GSOnceFLog(@"TODO: %s", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
- (void)decrementSnapshotCountForGlobalID:(EOGlobalID *)globalId
|
||||
{
|
||||
if (!_doesReleaseUnreferencedSnapshots)
|
||||
{
|
||||
return;
|
||||
}
|
||||
GSOnceFLog(@"TODO: %s", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
+ (void)disableSnapshotRefcounting
|
||||
{
|
||||
_doesReleaseUnreferencedSnapshots = NO;
|
||||
}
|
||||
|
||||
- (NSArray *)registeredContexts
|
||||
{
|
||||
NSMutableArray *array = [NSMutableArray array];
|
||||
|
|
|
@ -224,13 +224,14 @@ RCS_ID("$Id$")
|
|||
|
||||
- (void)setCurrentEditingContext: (EOEditingContext*)context
|
||||
{
|
||||
//OK
|
||||
EOCooperatingObjectStore *cooperatingObjectStore = [self databaseContext];
|
||||
EOObjectStore *objectStore = [context rootObjectStore];
|
||||
|
||||
[(EOObjectStoreCoordinator*)objectStore
|
||||
addCooperatingObjectStore: cooperatingObjectStore];
|
||||
|
||||
if (context) {
|
||||
EOCooperatingObjectStore *cooperatingObjectStore = [self databaseContext];
|
||||
EOObjectStore *objectStore = [context rootObjectStore];
|
||||
|
||||
[(EOObjectStoreCoordinator*)objectStore
|
||||
addCooperatingObjectStore: cooperatingObjectStore];
|
||||
}
|
||||
|
||||
ASSIGN(_currentEditingContext, context);
|
||||
}
|
||||
|
||||
|
@ -302,189 +303,189 @@ RCS_ID("$Id$")
|
|||
EODatabase *database=nil;
|
||||
id object = nil;
|
||||
|
||||
|
||||
|
||||
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];
|
||||
}
|
||||
{
|
||||
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)
|
||||
{
|
||||
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];
|
||||
}
|
||||
}
|
||||
//TODO
|
||||
//VERIFY
|
||||
/*
|
||||
if no more obj:
|
||||
if transactionNestingLevel
|
||||
adaptorContext transactionDidCommit
|
||||
*/
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return object;
|
||||
};
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -51,6 +51,7 @@ RCS_ID("$Id$")
|
|||
#ifndef GNUSTEP
|
||||
#include <GNUstepBase/GNUstep.h>
|
||||
#include <GNUstepBase/NSDebug+GNUstepBase.h>
|
||||
#include <GNUstepBase/NSObject+GNUstepBase.h>
|
||||
#endif
|
||||
|
||||
#include <EOControl/EONull.h>
|
||||
|
|
|
@ -772,6 +772,7 @@ inline BOOL infoForInstanceVariableWithImpPtr(id object,GDL2IMP_BOOL* impPtr,
|
|||
|
||||
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
|
||||
{
|
||||
[self willChange];
|
||||
[_dictionary setObject:value
|
||||
forKey:key];
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue