* EOAccess/EOAccessFault.m

remove empty init methods
  fix warnings
* EOAccess/EOAdaptor.[hm]
  add -expressionFactory
* EOAccess/EOAdaptorChannel.m
  clean -performAdaptorOperation:
* EOAccess/EOAdaptorOperation.m
  fix warnings
* EOAccess/EODatabase.[hm]
  add/handle _timestamp
* EOAccess/EODatabaseChannel.h
  remove delegate (moved to EODatabaseContext)
  add _currentEditingContextTimestamp
  add _refreshedGIDs
* EOAccess/EODatabaseChannel.m
  fix warnings
  remove delegate (moved to EODatabaseContext)
  add _currentEditingContextTimestamp
  add _refreshedGIDs
  rewrite -setEntity:
  rewrite -setCurrentEditingContext:
  rewrite -fetchObject
  rewrite -cancelFetch
  rewrite -_selectWithFetchSpecification:editingContext:
* EOAccess/EODatabaseContext.h
  add EODatabaseChannel delegate stuff
* EOAccess/EODatabaseContextPriv.h
  add EODatabaseChannel delegate stuff
* EOAccess/EODatabaseContext.m
  add EODatabaseChannel delegate stuff
  fix EOAdaptor..Operator / EODatabase..Operator mismatch
* EOAccess/EODatabaseOperation.m
  fix warnings
* EOAccess/EOEntity.[hm], EOAccess/EOEntityPriv.h
  fix warnings
  add singleTable... methods
* EOAccess/EOExpressionArray.m
  fix warnings
* EOAccess/EOSQLExpression.m
  rewrite -prepareInsertExpressionWithRow:
* EOAccess/EOSQLExpressionFactory.[hm]
  new class
* EOAccess/EOUtilities.[hm]
  remove duplicate methods
* EOAccess/GNUmakefile
  add EOSQLExpressionFactory.[hm]
* EOAdaptors/PostgreSQLAdaptor/PostgreSQLChannel.h
  remove duplicate _adaptorContext
* EOAdaptors/PostgreSQLAdaptor/PostgreSQLChannel.m
  remove duplicate _adaptorContext
  remove unused pgResultDictionary()
* EOControl/EOEditingContext.h
  handle fetchTimestamp
* EOControl/EOEditingContext.m
  handle fetchTimestamp
  rewrite -deleteObject:
  fix warnings
* EOControl/EOGenericRecord.m
  fix warnings
* EOControl/EOMutableKnownKeyDictionary.m
  fix warnings
* EOControl/EONSAddOns.[hm]
  remove duplicate method
* EOControl/EONull.m
  fix warnings


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@37938 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
mguesdon 2014-06-03 19:04:01 +00:00
parent 70ff29d9ec
commit c8cfc0fed3
33 changed files with 1320 additions and 887 deletions

View file

@ -1,3 +1,70 @@
2014-06-03 Manuel Guesdon <mguesdon@orange-concept.com>
* EOAccess/EOAccessFault.m
remove empty init methods
fix warnings
* EOAccess/EOAdaptor.[hm]
add -expressionFactory
* EOAccess/EOAdaptorChannel.m
clean -performAdaptorOperation:
* EOAccess/EOAdaptorOperation.m
fix warnings
* EOAccess/EODatabase.[hm]
add/handle _timestamp
* EOAccess/EODatabaseChannel.h
remove delegate (moved to EODatabaseContext)
add _currentEditingContextTimestamp
add _refreshedGIDs
* EOAccess/EODatabaseChannel.m
fix warnings
remove delegate (moved to EODatabaseContext)
add _currentEditingContextTimestamp
add _refreshedGIDs
rewrite -setEntity:
rewrite -setCurrentEditingContext:
rewrite -fetchObject
rewrite -cancelFetch
rewrite -_selectWithFetchSpecification:editingContext:
* EOAccess/EODatabaseContext.h
add EODatabaseChannel delegate stuff
* EOAccess/EODatabaseContextPriv.h
add EODatabaseChannel delegate stuff
* EOAccess/EODatabaseContext.m
add EODatabaseChannel delegate stuff
fix EOAdaptor..Operator / EODatabase..Operator mismatch
* EOAccess/EODatabaseOperation.m
fix warnings
* EOAccess/EOEntity.[hm], EOAccess/EOEntityPriv.h
fix warnings
add singleTable... methods
* EOAccess/EOExpressionArray.m
fix warnings
* EOAccess/EOSQLExpression.m
rewrite -prepareInsertExpressionWithRow:
* EOAccess/EOSQLExpressionFactory.[hm]
new class
* EOAccess/EOUtilities.[hm]
remove duplicate methods
* EOAccess/GNUmakefile
add EOSQLExpressionFactory.[hm]
* EOAdaptors/PostgreSQLAdaptor/PostgreSQLChannel.h
remove duplicate _adaptorContext
* EOAdaptors/PostgreSQLAdaptor/PostgreSQLChannel.m
remove duplicate _adaptorContext
remove unused pgResultDictionary()
* EOControl/EOEditingContext.h
handle fetchTimestamp
* EOControl/EOEditingContext.m
handle fetchTimestamp
rewrite -deleteObject:
fix warnings
* EOControl/EOGenericRecord.m
fix warnings
* EOControl/EOMutableKnownKeyDictionary.m
fix warnings
* EOControl/EONSAddOns.[hm]
remove duplicate method
* EOControl/EONull.m
fix warnings
2014-05-30 Sebastian Reitenbach <sebastia@l00-bugdead-prods.de>
* nearly every file
get rid of RCSID/RCS_ID

View file

@ -51,6 +51,7 @@
#include <EOControl/EOCheapArray.h>
#include <EOControl/EOKeyGlobalID.h>
#include <EOControl/EODebug.h>
#include <EOControl/EOEditingContext.h>
#include <EOAccess/EOAccessFault.h>
#include <EOAccess/EODatabaseContext.h>
@ -64,14 +65,6 @@ NSString *EOAccessFaultObjectNotAvailableException = @"EOAccessFaultObjectNotAva
@implementation EOAccessGenericFaultHandler
- (id)init
{
if ((self = [super init]))
{
}
return self;
}
- (void)linkAfter: (EOAccessGenericFaultHandler *)faultHandler
usingGeneration: (unsigned int)gen
{
@ -140,17 +133,6 @@ NSString *EOAccessFaultObjectNotAvailableException = @"EOAccessFaultObjectNotAva
@implementation EOAccessFaultHandler
- (id) init
{
if ((self = [super init]))
{
NSDebugFLog(@"INIT EOAccessFaultHandler %p. ThreadID=%@",
(void*)self, [NSThread currentThread]);
}
return self;
}
+ (EOAccessFaultHandler *)accessFaultHandlerWithGlobalID: (EOKeyGlobalID *)globalID
databaseContext: (EODatabaseContext *)dbcontext
editingContext: (EOEditingContext *)ec
@ -288,15 +270,6 @@ NSString *EOAccessFaultObjectNotAvailableException = @"EOAccessFaultObjectNotAva
editingContext: ec] autorelease];
}
- (id)init
{
if ((self = [super init]))
{
}
return self;
}
- (id)initWithSourceGlobalID: (EOKeyGlobalID *)sourceGID
relationshipName: (NSString *)relName
databaseContext: (EODatabaseContext *)dbcontext

View file

@ -50,6 +50,7 @@
@class EOAdaptorContext;
@class EOLoginPanel;
@class EOEntity;
@class EOSQLExpressionFactory;
GDL2ACCESS_EXPORT NSString *EOGeneralAdaptorException;
@ -136,6 +137,7 @@ GDL2ACCESS_EXPORT NSString *EOGeneralAdaptorException;
- (BOOL)isValidQualifierType: (NSString *)attribute
model: (EOModel *)model;
-(EOSQLExpressionFactory*)expressionFactory;
@end /* EOAdaptor */

View file

@ -94,7 +94,7 @@ NSString *EOAdministrativeConnectionDictionaryKey
if(!model)
[NSException raise: NSInvalidArgumentException
format: @"%@ -- %@ 0x%x: no model specified",
format: @"%@ -- %@ %p: no model specified",
NSStringFromSelector(_cmd),
NSStringFromClass([self class]),
self];
@ -104,7 +104,7 @@ NSString *EOAdministrativeConnectionDictionaryKey
if (!adaptorName)
[NSException raise: NSInvalidArgumentException
format: @"%@ -- %@ 0x%p: no adaptor name in model named %@",
format: @"%@ -- %@ %p: no adaptor name in model named %@",
NSStringFromSelector(_cmd),
NSStringFromClass([self class]),
self,
@ -765,6 +765,12 @@ NSString *EOAdministrativeConnectionDictionaryKey
return NO;
}
-(EOSQLExpressionFactory*)expressionFactory
{
[self subclassResponsibility: _cmd];
return nil;
}
@end /* EOAdaptor */

View file

@ -493,103 +493,71 @@ inRowDescribedByQualifier: (EOQualifier *)qualifier
@implementation EOAdaptorChannel (EOBatchProcessing)
//MG2014: OK
- (void)performAdaptorOperation: (EOAdaptorOperation *)adaptorOperation
{
EOAdaptorContext *adaptorContext = nil;
EOAdaptorContext *adaptorContext = [self adaptorContext];
EOEntity *entity = nil;
EOAdaptorOperator operator;
NSDictionary *changedValues=nil;
adaptorContext = [self adaptorContext];
//adaptorcontext transactionNestingLevel
//2fois
//...
if (![adaptorContext hasOpenTransaction])
[adaptorContext beginTransaction];
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%p: Operator %d is not defined",
NSStringFromSelector(_cmd),
NSStringFromClass([self class]),
self,
(int)operator];
break;
}
NS_HANDLER
switch(operator)
{
NSDebugMLog(@"EXCEPTION %@", localException);
[adaptorOperation setException: localException];
[localException raise];
case EOAdaptorLockOperator:
EOFLOGObjectLevel(@"gsdb", @"EOAdaptorLockOperator");
[self lockRowComparingAttributes: [adaptorOperation attributes]
entity: entity
qualifier: [adaptorOperation qualifier]
snapshot: [adaptorOperation changedValues]];
break;
case EOAdaptorInsertOperator:
EOFLOGObjectLevel(@"gsdb", @"EOAdaptorInsertOperator");
[self insertRow: [adaptorOperation changedValues]
forEntity: entity];
break;
case EOAdaptorUpdateOperator:
EOFLOGObjectLevel(@"gsdb", @"EOAdaptorUpdateOperator");
[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]];
[self returnValuesForLastStoredProcedureInvocation];
break;
case EOAdaptorUndefinedOperator:
EOFLOGObjectLevel(@"gsdb", @"EOAdaptorUndefinedOperator");
default:
[NSException raise: NSInvalidArgumentException
format: @"%@ -- %@ 0x%p: Operator %d is not defined",
NSStringFromSelector(_cmd),
NSStringFromClass([self class]),
self,
(int)operator];
break;
}
NS_ENDHANDLER;
//end
}
- (void)performAdaptorOperations: (NSArray *)adaptorOperations

View file

@ -49,9 +49,11 @@
#include <EOAccess/EODatabaseOperation.h>
#include <EOAccess/EOAttribute.h>
#include <EOAccess/EOEntity.h>
#include <EOAccess/EOStoredProcedure.h>
#include <EOControl/EOSortOrdering.h>
#include <EOControl/EODebug.h>
#include <EOControl/EOQualifier.h>
@implementation EOAdaptorOperation

View file

@ -64,6 +64,7 @@ GDL2ACCESS_EXPORT NSTimeInterval EODistantPastTimeInterval;
NSMutableDictionary *_entityCache;
EOAdaptor *_adaptor;
NSMutableDictionary *_toManySnapshots;
NSTimeInterval _timestamp;
}
+ (EODatabase *)databaseWithModel: (EOModel *)model;
@ -98,6 +99,7 @@ GDL2ACCESS_EXPORT NSTimeInterval EODistantPastTimeInterval;
- (void)invalidateResultCacheForEntityNamed: (NSString *)name;
- (void)invalidateResultCache;
- (void)handleDroppedConnection;
- (void)setTimestampToNow;
@end

View file

@ -110,18 +110,26 @@ static NSMutableArray *databaseInstances;
/*
* Initializing new instances
*/
-(id)init
{
if ((self=[super init]))
{
_timestamp = EODistantPastTimeInterval;
}
return self;
}
//OK
- initWithAdaptor: (EOAdaptor *)adaptor
{
if (!adaptor)
{
[self autorelease];
return nil;
}
if ((self = [super init]))
if ((self = [self init]))
{
[[NSNotificationCenter defaultCenter]
addObserver: self
@ -398,6 +406,11 @@ static NSMutableArray *databaseInstances;
EOFLOGObjectFnStopOrCond2(@"DatabaseLevel", @"EODatabase");
}
-(void)setTimestampToNow
{
_timestamp = [NSDate timeIntervalSinceReferenceDate];
}
@end
@ -480,26 +493,23 @@ static NSMutableArray *databaseInstances;
}
//MG2014: OK
- (NSDictionary *)snapshotForGlobalID: (EOGlobalID *)gid
{
return [self snapshotForGlobalID: gid
after: EODistantPastTimeInterval];
}
//MG2014: TODO: use ti
- (NSDictionary *)snapshotForGlobalID: (EOGlobalID *)gid
after: (NSTimeInterval)ti
{
//seems OK
NSDictionary *snapshot = nil;
NSAssert(gid, @"No gid");
snapshot = [_snapshots objectForKey: gid];
return snapshot;
}

View file

@ -48,22 +48,16 @@
@interface EODatabaseChannel : NSObject
{
EODatabaseContext *_databaseContext;
id _delegate;
EOAdaptorChannel *_adaptorChannel;
EOEntity *_currentEntity;
EOEditingContext *_currentEditingContext;
NSTimeInterval _currentEditingContextTimestamp;
NSMutableArray *_fetchProperties;
NSMutableArray *_fetchSpecifications;
NSMutableArray *_refreshedGIDs;
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;
BOOL _isFetchingSingleTableEntity;
}
+ (EODatabaseChannel *)databaseChannelWithDatabaseContext: (EODatabaseContext *)databaseContext;
@ -94,9 +88,6 @@
- (BOOL)isLocking;
- (void)setIsLocking: (BOOL)isLocking;
- (void)setDelegate: (id)delegate;
- (id)delegate;
@end
#endif /* __EODatabaseChannel_h__ */

View file

@ -65,6 +65,7 @@
#include <EOAccess/EODatabaseChannel.h>
#include <EOAccess/EODatabaseContext.h>
#include <EOAccess/EODatabaseContextPriv.h>
#include <EOAccess/EODatabase.h>
#include <EOAccess/EOAdaptor.h>
@ -74,8 +75,10 @@
#include <EOAccess/EOAttribute.h>
#include <EOAccess/EORelationship.h>
#include <EOAccess/EOModel.h>
#include <EOAccess/EOModelGroup.h>
#include <EOAccess/EOAccessFault.h>
#include <EOAccess/EOSQLExpression.h>
#include <EOAccess/EOSQLExpressionFactory.h>
#include <EOAccess/EOSQLQualifier.h>
#include "EOPrivate.h"
@ -152,85 +155,54 @@
DESTROY(_currentEditingContext);
DESTROY(_fetchProperties);
DESTROY(_fetchSpecifications);
DESTROY(_refreshedGIDs);
[super dealloc];
}
//MG2014: OK
- (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++)
if (entity != _currentEntity)
{
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
}
}
}
DESTROY(_fetchProperties);
ASSIGN(_currentEntity, entity);
[self setEntity: entity];
}
}
//MG2014: OK
- (void) setEntity: (EOEntity *)entity
{
NSArray *relationships = [entity relationships];
NSUInteger relCount = [relationships count];
if (relCount>0)
{
Class databaseContextClass=[[self databaseContext] class];
NSUInteger i=0;
for(i=0;i<relCount;i++)
{
EORelationship* relationship = [relationships objectAtIndex:i];
EOModel* model = [[relationship destinationEntity] model];
if ([[relationship entity]model] != model)
{
[databaseContextClass registeredDatabaseContextForModel:model
editingContext:[self currentEditingContext]];
}
}
}
}
//MG2014: OK
- (void)setCurrentEditingContext: (EOEditingContext*)context
{
if (context) {
EOCooperatingObjectStore *cooperatingObjectStore = [self databaseContext];
EOObjectStore *objectStore = [context rootObjectStore];
[(EOObjectStoreCoordinator*)objectStore
addCooperatingObjectStore: cooperatingObjectStore];
}
ASSIGN(_currentEditingContext, context);
ASSIGN(_currentEditingContext,context);
if(_currentEditingContext != nil)
{
_currentEditingContextTimestamp = [_currentEditingContext fetchTimestamp];
[(EOObjectStoreCoordinator*)[_currentEditingContext rootObjectStore]
addCooperatingObjectStore:[self databaseContext]];
}
}
- (void)selectObjectsWithFetchSpecification: (EOFetchSpecification *)fetchSpecification
@ -292,176 +264,223 @@
[self _selectWithFetchSpecification:fetchSpecification
editingContext:context];
[database setTimestampToNow];
}
//MG2014: OK
- (id)fetchObject
{
//seems OK
EODatabase *database=nil;
EODatabase* database=[_databaseContext database];
id object = nil;
database = [_databaseContext database];
if (![self isFetchInProgress])
{
[NSException raise: NSInvalidArgumentException
format: @"%@ -- %@ 0x%p: no fetch in progress",
NSStringFromSelector(_cmd),
NSStringFromClass([self class]),
self];
}
{
//Exception or just return nil ?
[NSException raise: NSInvalidArgumentException
format: @"%@ -- %@ 0x%p: 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];
row = [_adaptorChannel fetchRowWithZone: NULL];
if (!row)
{
//TODO
//VERIFY
/*
if no more obj:
if transactionNestingLevel
adaptorContext transactionDidCommit
*/
NSDictionary *row =nil;
EOEntity* entity = nil;
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(_currentEditingContext, @"No current editing context");
NSAssert(_adaptorChannel,@"No adaptor channel");
NSAssert(_currentEntity, @"Not current Entity");
[self _propertiesToFetch];
for (row = [_adaptorChannel fetchRowWithZone: NULL]; row == nil;)
{
if (_fetchSpecifications != nil)
{
[self _cancelInternalFetch];
[self _selectWithFetchSpecification:nil
editingContext:_currentEditingContext];
[self _propertiesToFetch];
row = [_adaptorChannel fetchRowWithZone: NULL];
}
else
{
_isLocking = NO;
return nil; // End
}
}
NSLog(@"MG-OXYMIUM-TMP %s:%d row=%@",__PRETTY_FUNCTION__,__LINE__,row);
gid = [_currentEntity globalIDForRow: row
isFinal: YES];//OK
object = [_currentEditingContext objectForGlobalID: gid]; //OK //nil
if (object)
isObjectNew = NO;
NSAssert(_databaseContext,@"No database context");
snapshot = [_databaseContext snapshotForGlobalID: gid]; //OK
if (snapshot)
{
//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 !
[_databaseContext recordSnapshot: row
forGlobalID: gid];
isObjectNew = YES; //TODO
}
}
if (_isFetchingSingleTableEntity)
{
entity = [_currentEntity _singleTableSubEntityForRow:row];
if (entity == nil)
{
[NSException raise: @"NSIllegalStateException"
format: @"%s Unable to determine subentity of '%@' for row: %@. Check that the attribute '%@' is marked as a class property in the EOModel and that the value satisfies some subentity's restricting qualifier.",
__PRETTY_FUNCTION__,
[_currentEntity name],
row,
[_currentEntity _singleTableSubEntityKey]];
}
}
else
{
NSAssert(database, @"No database-context database");
[database recordSnapshot: row
forGlobalID: gid];
}
//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];
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
{
if ((!object) || ([object isKindOfClass:[EOCustomObject class]] == NO)) {
[NSException raise: NSInternalInconsistencyException
format: @"%s:%d cannot initialize nil/non EOCustomObject object!", __FILE__, __LINE__];
}
[EOObserverCenter suppressObserverNotification];
NS_DURING
{
[_currentEditingContext initializeObject: object
withGlobalID: gid
editingContext: _currentEditingContext];
}
NS_HANDLER
{
[EOObserverCenter enableObserverNotification];
[localException raise];
}
NS_ENDHANDLER;
[EOObserverCenter enableObserverNotification];
if ((!object) || ([object isKindOfClass:[EOCustomObject class]] == NO)) {
[NSException raise: NSInternalInconsistencyException
format: @"%s:%d cannot initialize nil/non EOCustomObject object!", __FILE__, __LINE__];
}
[object awakeFromFetchInEditingContext: _currentEditingContext];
{
entity = _currentEntity;
}
EOKeyGlobalID* gid = (EOKeyGlobalID*)[entity _globalIDForRow:row
isFinal:YES];
if (gid == nil)
{
[NSException raise: @"NSIllegalStateException"
format: @"%s Cannot determine primary key for entity '%@' from row: %@",
__PRETTY_FUNCTION__,
[_currentEntity name],
row];
}
else
{
NSDictionary* dbxSnapshot = nil;
NSDictionary* snapshot = nil;
NSDictionary* newSnapshot = nil;
BOOL respondsTo_shouldUpdateCurrentSnapshot = [_databaseContext _respondsTo_shouldUpdateCurrentSnapshot];
object = [_currentEditingContext objectForGlobalID:gid];
NSLog(@"MG-OXYMIUM-TMP %s:%d gid=%@ object=%@",__PRETTY_FUNCTION__,__LINE__,gid,object);
}
snapshot = [database snapshotForGlobalID:gid
after: (respondsTo_shouldUpdateCurrentSnapshot ?
EODistantPastTimeInterval : _currentEditingContextTimestamp)];
NSLog(@"MG-OXYMIUM-TMP %s:%d gid=%@ snapshot=%@",__PRETTY_FUNCTION__,__LINE__,gid,snapshot);
if (snapshot != nil)
{
if (respondsTo_shouldUpdateCurrentSnapshot
&& (newSnapshot = [_databaseContext _shouldUpdateCurrentSnapshot:snapshot
newSnapshot:row
globalID: gid
databaseChannel:self])!=nil)
{
NSLog(@"MG-OXYMIUM-TMP %s:%d gid=%@ newSnapshot=%@",__PRETTY_FUNCTION__,__LINE__,gid,newSnapshot);
if (newSnapshot != snapshot)
{
snapshot = newSnapshot;
[database recordSnapshot:snapshot
forGlobalID:gid];
}
else
{
newSnapshot = nil;
}
}
else if ((_isLocking || _isRefreshingObjects)
&& ![_databaseContext isObjectLockedWithGlobalID:gid]
&& ![snapshot isEqual:row])
{
if(_isLocking && !_isRefreshingObjects)
{
[NSException raise: @"NSIllegalStateException"
format: @"%s attempt to lock object that has out of date snapshot: %@",
__PRETTY_FUNCTION__,
gid];
}
NSLog(@"MG-OXYMIUM-TMP %s:%d gid=%@ row=%@",__PRETTY_FUNCTION__,__LINE__,gid,row);
snapshot = newSnapshot = row;
[database recordSnapshot:snapshot
forGlobalID:gid];
}
dbxSnapshot = snapshot;
}
else
{
NSDictionary* aSnapshot = [database snapshotForGlobalID:gid];
NSLog(@"MG-OXYMIUM-TMP %s:%d gid=%@ aSnapshot=%@",__PRETTY_FUNCTION__,__LINE__,gid,aSnapshot);
[database recordSnapshot:row
forGlobalID:gid];
if (aSnapshot != nil
&& ![aSnapshot isEqualToDictionary:row])
newSnapshot = row;
dbxSnapshot = row;
}
if (_isLocking)
[_databaseContext registerLockedObjectWithGlobalID:gid];
if (newSnapshot != nil)
{
if (_refreshedGIDs == nil)
_refreshedGIDs = [NSMutableArray new];
[_refreshedGIDs addObject:gid];
}
if (object != nil
&& !_isFault(object))
{
return object; //End
}
else
{
if (object == nil
&& newSnapshot != nil)
{
object = [_currentEditingContext faultForGlobalID:gid
editingContext:_currentEditingContext];
return object; // End
}
else
{
if (object == nil)
{
EOClassDescription *entityClassDescripton = [entity classDescriptionForInstances];
object = [entityClassDescripton createInstanceWithEditingContext: _currentEditingContext
globalID: gid
zone: NULL];
[_currentEditingContext recordObject:object
globalID: gid];
}
else
{
EOAccessFaultHandler* handler =
(EOAccessFaultHandler *)[EOFault handlerForFault: object];
if ([(EOKeyGlobalID*)[handler globalID] isFinal])
{
[EOFault clearFault: object];
}
else
{
[EOFault clearFault: object];
[entity initObject:object
editingContext:_currentEditingContext
globalID:gid];
}
}
[EOObserverCenter suppressObserverNotification];
NS_DURING
{
ASSIGN(_databaseContext->_lastEntity,entity);
//TODO
/*
_databaseContext->_currentGlobalID = gid;
_databaseContext->_currentSnapshot = dbxSnapshot;
*/
[_currentEditingContext initializeObject:object
withGlobalID: gid
editingContext: _currentEditingContext];
//TODO
/*
_databaseContext->_currentGlobalID = nil;
*/
}
NS_HANDLER
{
[EOObserverCenter enableObserverNotification];
[localException raise];
}
NS_ENDHANDLER;
[EOObserverCenter enableObserverNotification];
[object awakeFromFetchInEditingContext:_currentEditingContext];
}
}
}
}
}
return object;
}
@ -470,18 +489,56 @@
return [_adaptorChannel isFetchInProgress];
}
//MG2014: Near OK (See TODO)
- (void)cancelFetch
{
[self _cancelInternalFetch];
if (_fetchSpecifications != nil)
DESTROY(_fetchSpecifications);
[self _cancelInternalFetch];
//TODO VERIFY - NO ??!!
[_adaptorChannel cancelFetch];
[_fetchProperties removeAllObjects];
[_fetchSpecifications removeAllObjects];
if (_refreshedGIDs != nil)
{
IMP oaiIMP=NULL;
EOEditingContext* editingContext = _currentEditingContext;
NSMutableArray* refreshedGIDs = _refreshedGIDs;
EODatabase* database = [_databaseContext database];
NSUInteger refreshedGIDsCount = [refreshedGIDs count];
NSUInteger i=0;
_refreshedGIDs = nil;
for(i=0; i<refreshedGIDsCount; i++)
[database incrementSnapshotCountForGlobalID:GDL2_ObjectAtIndexWithImpPtr(refreshedGIDs,&oaiIMP,i)];
[editingContext lock];
NS_DURING
{
[[NSNotificationCenter defaultCenter]
postNotificationName: @"EOObjectsChangedInStoreNotification"
object: _databaseContext
userInfo: [NSDictionary dictionaryWithObject:refreshedGIDs
forKey:@"updated"]];
for(i=0; i<refreshedGIDsCount; i++)
{
EOKeyGlobalID* gid = GDL2_ObjectAtIndexWithImpPtr(refreshedGIDs,&oaiIMP,i);
//TODO [[editingContext objectForGlobalID:gid] willRead];
[database decrementSnapshotCountForGlobalID:gid];
}
}
NS_HANDLER
{
[editingContext unlock];
DESTROY(refreshedGIDs);//was retained as _refreshedGIDs
[localException raise];
}
NS_ENDHANDLER;
[editingContext unlock];
DESTROY(refreshedGIDs);//was retained as _refreshedGIDs
}
}
- (EODatabaseContext *)databaseContext
@ -514,26 +571,6 @@
_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)
@ -573,233 +610,195 @@
return _currentEditingContext;
}
//MG2014: OK
- (void) _cancelInternalFetch
{
//OK
if ([_adaptorChannel isFetchInProgress])
{
[_adaptorChannel cancelFetch];
}
[_adaptorChannel cancelFetch];
}
//MG2014: OK
- (void) _closeChannel
{
//TODO
[self notImplemented: _cmd];
[_adaptorChannel closeChannel];
}
//MG2014: OK
- (void) _openChannel
{
//TODO
[self notImplemented: _cmd];
if (![_adaptorChannel isOpen])
[_adaptorChannel openChannel];
}
- (void)_selectWithFetchSpecification: (EOFetchSpecification *)fetch
editingContext: (EOEditingContext *)context
- (void)_selectWithFetchSpecification: (EOFetchSpecification *)fetchSpec
editingContext: (EOEditingContext *)editingContext
{
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;
EOSQLExpression* sqlExpression = nil;
_isFetchingSingleTableEntity = NO;
BOOL isDeep = NO;
NSArray *subEntities = nil;
NSDictionary *_hints = nil;
_hints = [fetch _hints];
customQueryExpressionHint = [_hints objectForKey: EOCustomQueryExpressionHintKey];//TODO use it
if (customQueryExpressionHint)
if (_fetchSpecifications != nil)
{
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]; //<EOAndQualifier> //Can be nil
if (customQueryExpression)
{
[_adaptorChannel evaluateExpression: customQueryExpression];
NSAssert([propertiesToFetch count] > 0, @"No properties to fetch");
[_adaptorChannel setAttributesToFetch: propertiesToFetch];
fetchSpec = [_fetchSpecifications lastObject];
[_fetchSpecifications removeLastObject];
[self setCurrentEntity:[[_databaseContext database]entityNamed:[fetchSpec entityName]]];
_isFetchingSingleTableEntity = [_currentEntity _isSingleTableEntity];
if ([_fetchSpecifications count] == 0)
DESTROY(_fetchSpecifications);
}
else
{
storedProcedure = [entity storedProcedureForOperation:
@"EOFetchWithPrimaryKeyProcedure"];
if (fetchSpec == nil)
{
[NSException raise: @"NSIllegalArgumentException"
format:@"%s invoked with nil fetchSpecification",
__PRETTY_FUNCTION__];
}
else
{
NSDictionary* hints = [fetchSpec hints];
id customQueryExpressionHint = [hints objectForKey:@"EOCustomQueryExpressionHintKey"];
if (customQueryExpressionHint != nil)
{
if ([customQueryExpressionHint isKindOfClass:[NSString class]])
{
sqlExpression = [[[[_databaseContext adaptorContext]adaptor]
expressionFactory]
expressionForString:customQueryExpressionHint];
}
else
sqlExpression = (EOSQLExpression*)customQueryExpressionHint;
}
[self setCurrentEditingContext:editingContext];
[self _setCurrentEntityAndRelationshipWithFetchSpecification:fetchSpec];
if (storedProcedure)
{
NSEmitTODO(); //TODO
[self notImplemented: _cmd];
if ([fetchSpec isDeep]
&& sqlExpression == nil)
{
_isFetchingSingleTableEntity = [_currentEntity _isSingleTableEntity];
if (!_isFetchingSingleTableEntity
&& [[_currentEntity subEntities]count]>0)
{
NSMutableArray* nodes = [NSMutableArray array];
NSUInteger nodesCount = 0;
[self _buildNodeList:nodes
withParent:_currentEntity];
nodesCount = [nodes count];
ASSIGN(_fetchSpecifications,([NSMutableArray arrayWithCapacity:nodesCount]));
if (nodesCount>0)
{
NSUInteger i=0;
for(i=0;i<nodesCount;i++)
{
EOFetchSpecification* aFetchSpec = AUTORELEASE([fetchSpec copy]);
[aFetchSpec setEntityName:[nodes objectAtIndex:i]];
[_fetchSpecifications addObject:aFetchSpec];
}
}
[self _selectWithFetchSpecification:nil
editingContext:editingContext];
return; //Finished !
}
}
}
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];
}
NSArray* propertiesToFetch = [self _propertiesToFetch];
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%p: no transaction in progress",
NSStringFromSelector(_cmd),
NSStringFromClass([self class]),
self];
if(_delegateRespondsTo.shouldSelectObjects)
if ([_databaseContext _performShouldSelectObjectsWithFetchSpecification:fetchSpec
databaseChannel:self])
{
if(![_delegate databaseContext:_databaseContext
shouldSelectObjectsWithFetchSpecification:fetch
databaseChannel:self])
[NSException raise:EOGeneralDatabaseException
format:@"%@ -- %@ 0x%p: 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];
_isLocking = [_databaseContext _usesPessimisticLockingWithFetchSpecification:fetchSpec
databaseChannel:self];
_isRefreshingObjects = [fetchSpec refreshesRefetchedObjects];
if(_isLocking
&& ![[_adaptorChannel adaptorContext] hasOpenTransaction])
{
[[_adaptorChannel adaptorContext] beginTransaction];
}
if ([[_currentEntity primaryKeyAttributes]count]==0)
{
[NSException raise: @"NSIllegalStateException"
format:@"%s attempt to select EOs from entity '%@' which has no primary key defined. All entities must have a primary key specified. You should run the EOModeler consistency checker on the model containing this entity and perform whatever actions are necessary to ensure that the model is in a consistent state.",
__PRETTY_FUNCTION__,
[_currentEntity name]];
}
else
{
NSDictionary* hints = [fetchSpec hints];
EOStoredProcedure* storedProcedure = nil;
NSString* storedProcedureName = [hints objectForKey:@"EOStoredProcedureNameHintKey"];
if (storedProcedureName != nil)
{
storedProcedure = [[[_currentEntity model]modelGroup]storedProcedureNamed:storedProcedureName];
}
if(storedProcedure != nil)
{
[_adaptorChannel executeStoredProcedure:storedProcedure
withValues:nil];
[_adaptorChannel setAttributesToFetch:propertiesToFetch];
}
else if(sqlExpression != nil)
{
[_adaptorChannel evaluateExpression:sqlExpression];
[_adaptorChannel setAttributesToFetch:propertiesToFetch];
}
else
{
EOQualifier* qualifier = [fetchSpec qualifier];
if (qualifier == nil
&& (storedProcedure = [_currentEntity storedProcedureForOperation:@"EOFetchAllProcedure"]) != nil)
{
[_adaptorChannel executeStoredProcedure:storedProcedure
withValues:nil];
[_adaptorChannel setAttributesToFetch:propertiesToFetch];
}
else
{
storedProcedure = [_currentEntity storedProcedureForOperation:@"EOFetchWithPrimaryKeyProcedure"];
if (qualifier != nil
&& storedProcedure != nil
&& [_currentEntity isQualifierForPrimaryKey:qualifier])
{
NSMutableDictionary* keyValues = nil;
if ([qualifier isKindOfClass:[EOKeyValueQualifier class]])
{
keyValues = [NSMutableDictionary dictionaryWithObject:[(EOKeyValueQualifier*)qualifier value]
forKey:[(EOKeyValueQualifier*)qualifier key]];
}
else
{
NSArray* qualifiers = [(EOAndQualifier*)qualifier qualifiers];
NSUInteger qualifiersCount = [qualifiers count];
NSUInteger i = 0;
keyValues = [NSMutableDictionary dictionaryWithCapacity:qualifiersCount];
for (i=0;i<qualifiersCount;i++)
{
EOKeyValueQualifier* kvQualifier = [qualifiers objectAtIndex:i];
[keyValues setObject:[kvQualifier value]
forKey:[kvQualifier key]];
}
}
[_adaptorChannel executeStoredProcedure:storedProcedure
withValues:keyValues];
[_adaptorChannel setAttributesToFetch:propertiesToFetch];
}
else
{
[_adaptorChannel selectAttributes: propertiesToFetch
fetchSpecification: fetchSpec
lock: _isLocking
entity: _currentEntity];
}
}
}
[_databaseContext _performDidSelectObjectsWithFetchSpecification:fetchSpec
databaseChannel:self];
}
}
}
@end /* EODatabaseChannel */

View file

@ -86,12 +86,14 @@ struct _EOTransactionScope;
NSMutableDictionary *_batchFaultBuffer;
NSMutableDictionary *_batchToManyFaultBuffer;
@public //accessed by EODatabaseChannel
EOEntity* _lastEntity;
/*TOADD
EOGlobalID *_currentGlobalID;
NSDictionary *_currentSnapshot;
objc_object *_currentBatch;
*/
@protected
NSMutableArray *_uniqueArrayStack; /* to-many snapshots */
NSHashTable *_nonPrimaryKeyGenerators;
@ -117,7 +119,11 @@ struct _EOTransactionScope;
unsigned int shouldFetchArrayFault:1;
unsigned int shouldHandleDatabaseException:1;
unsigned int databaseContextFailedToFetchObject:1;
unsigned int _reserved:19;
unsigned int shouldSelectObjects:1;
unsigned int shouldUsePessimisticLock:1;
unsigned int didSelectObjects:1;
unsigned int shouldUpdateCurrentSnapshot:1;
unsigned int _reserved:15;
} _delegateRespondsTo;
NSRecursiveLock *_lock; //TODO: not lock object !
@ -446,6 +452,10 @@ shouldRaiseExceptionForLockFailure: (NSException *)exception;
- (BOOL)databaseContext: (EODatabaseContext *)databaseContext
shouldFetchArrayFault: (id)fault;
- (BOOL)databaseContext: (EODatabaseContext *)databaseContext
shouldFetchObjectsWithFetchSpecification: (EOFetchSpecification*)fetchSpecification
databaseChannel:(EODatabaseChannel*)databaseChannel;
/**
* If the delegate returns NO, it is responsible for doing the right thing
* This is new in WO 4.5

View file

@ -449,7 +449,7 @@ static Class _contextClass = Nil;
for (i = 0 ; !busy && i < count; i++)
{
EODatabaseChannel *channel = GDL2_ObjectAtIndexWithImpPtr(_registeredChannels,&oaiIMP,i);
EODatabaseChannel *channel = GDL2_ObjectAtIndexWithImpPtr(_registeredChannels,&oaiIMP,i);
busy = [channel isFetchInProgress];
}
};
@ -476,9 +476,6 @@ static Class _contextClass = Nil;
[_registeredChannels count] + 1);
[_registeredChannels addObject:channel];
//Channels have same delegate as context
[channel setDelegate: _delegate];
}
- (void)unregisterChannel: (EODatabaseChannel *)channel
@ -602,42 +599,58 @@ May raise an exception if transaction has began or if you want pessimistic lock
/** 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:)];
_delegateRespondsTo.shouldHandleDatabaseException =
[delegate respondsToSelector: @selector(databaseContext:shouldHandleDatabaseException:)];
_delegateRespondsTo.databaseContextFailedToFetchObject =
[delegate respondsToSelector: @selector(databaseContext:failedToFetchObject:globalID:)];
_delegateRespondsTo.shouldSelectObjects =
[delegate respondsToSelector: @selector(databaseContext:shouldFetchObjectsWithFetchSpecification:databaseChannel:)];
while ((channel = GDL2_NextObjectWithImpPtr(channelsEnum,&enumNO)))
[channel setDelegate: delegate];
_delegateRespondsTo.didSelectObjects =
[delegate respondsToSelector:@selector(databaseContext:didSelectObjectsWithFetchSpecification:databaseChannel:)];
_delegateRespondsTo.shouldUsePessimisticLock =
[delegate respondsToSelector:@selector(databaseContext:shouldUsePessimisticLockWithFetchSpecification: databaseChannel:)];
_delegateRespondsTo.shouldUpdateCurrentSnapshot =
[delegate respondsToSelector:@selector(databaseContext:shouldUpdateCurrentSnapshot:newSnapshot:globalID:databaseChannel:)];
}
- (void)handleDroppedConnection
@ -2785,8 +2798,8 @@ Raises an exception is the adaptor is unable to perform the operations.
if ([gid isTemporary] || ([[dbOpe primaryKeyDiffs] count] > 0))
{
newGID = [entity globalIDForRow: newRow
isFinal: YES];
newGID = [entity _globalIDForRow: newRow
isFinal: YES];
if (!gidChangedUserInfo)
{
gidChangedUserInfo = [NSMutableDictionary dictionary];
@ -4436,7 +4449,7 @@ compareUsingEntityNames(id left, id right, void* vpSortOrders)
objsEnumNO=NULL;
while ((object = GDL2_NextObjectWithImpPtr(objsEnum,&objsEnumNO)))
{
IMP joinsEnumNO=NO;
IMP joinsEnumNO=NULL;
values
= AUTORELEASE([GDL2_alloc(NSMutableDictionary) initWithCapacity: 4]);
@ -5376,29 +5389,6 @@ compareUsingEntityNames(id left, id right, void* vpSortOrders)
return result;
}
-(id)_fetchSingleObjectForEntity:(EOEntity*)entity
globalID:(EOGlobalID*)gid
editingContext:(EOEditingContext*)context
{
id object=nil;
NSDictionary* pk = [entity primaryKeyForGlobalID:gid];
EOFetchSpecification* fetchSpec = [EOFetchSpecification fetchSpecificationWithEntityName:[entity name]
qualifier: [entity qualifierForPrimaryKey:pk]
sortOrderings: nil];
[fetchSpec setFetchLimit:1];
NSArray* objects = [self objectsWithFetchSpecification:fetchSpec
editingContext: context];
if ([objects count]==0)
{
[NSException raise: @"NSIllegalStateException"
format:@"The object with globalID %@ could not be found in the database. This could be result of a referential integrity problem with the database. An empty fault could not be created because the object's class could not be determined (e.g. the GID is temporary or it is for an abstract entity).",
gid];
}
else
object=[objects objectAtIndex:0];
return object;
}
-(id)_objectFaultWithSnapshot:(NSDictionary*) snapshot
relationship:(EORelationship*) relationship
@ -5696,21 +5686,23 @@ compareUsingEntityNames(id left, id right, void* vpSortOrders)
{
switch([dbOpe databaseOperator])
{
case EOAdaptorInsertOperator:
case EODatabaseNothingOperator:
break;
case EODatabaseInsertOperator:
[NSException raise: @"NSIllegalStateException"
format:@"cannot insert object: %@ that corresponds to read-only entity: %@ in databaseContext %@",
[dbOpe object],
[entity name],
self];
break;
case EOAdaptorDeleteOperator:
case EODatabaseDeleteOperator:
[NSException raise: @"NSIllegalStateException"
format:@"cannot insert delete: %@ that corresponds to read-only entity: %@ in databaseContext %@",
[dbOpe object],
[entity name],
self];
break;
case EOAdaptorUpdateOperator:
case EODatabaseUpdateOperator:
if (![[dbOpe dbSnapshot] isEqual:[dbOpe newRow]])
{
[NSException raise: @"NSIllegalStateException"
@ -5723,8 +5715,8 @@ compareUsingEntityNames(id left, id right, void* vpSortOrders)
break;
}
}
else if ([dbOpe databaseOperator] == EOAdaptorUpdateOperator
&& [entity hasNonUpdateableAttributes])
else if ([dbOpe databaseOperator] == EODatabaseUpdateOperator
&& [entity _hasNonUpdateableAttributes])
{
NSArray* dbSnapshotKeys = [entity dbSnapshotKeys];
NSDictionary* dbSnapshot = [dbOpe dbSnapshot];
@ -6185,4 +6177,98 @@ If the object has been just inserted, the dictionary is empty.
return [self notImplemented: _cmd]; //TODO
}
-(id)_fetchSingleObjectForEntity:(EOEntity*)entity
globalID:(EOGlobalID*)gid
editingContext:(EOEditingContext*)context
{
id object=nil;
NSDictionary* pk = [entity primaryKeyForGlobalID:gid];
EOFetchSpecification* fetchSpec = [EOFetchSpecification fetchSpecificationWithEntityName:[entity name]
qualifier: [entity qualifierForPrimaryKey:pk]
sortOrderings: nil];
[fetchSpec setFetchLimit:1];
NSArray* objects = [self objectsWithFetchSpecification:fetchSpec
editingContext: context];
if ([objects count]==0)
{
[NSException raise: @"NSIllegalStateException"
format:@"The object with globalID %@ could not be found in the database. This could be result of a referential integrity problem with the database. An empty fault could not be created because the object's class could not be determined (e.g. the GID is temporary or it is for an abstract entity).",
gid];
}
else
object=[objects objectAtIndex:0];
return object;
}
@end
@implementation EODatabaseContext (EODatabaseContextDelegate)
-(BOOL)_performShouldSelectObjectsWithFetchSpecification:(EOFetchSpecification*)fetchSpecification
databaseChannel:(EODatabaseChannel*)databaseChannel
{
BOOL doIt=YES;
if (_delegate!=nil
&& _delegateRespondsTo.shouldSelectObjects)
{
doIt=[_delegate databaseContext: self
shouldFetchObjectsWithFetchSpecification: fetchSpecification
databaseChannel: databaseChannel];
}
return doIt;
}
-(BOOL)_respondsTo_shouldUpdateCurrentSnapshot
{
return _delegateRespondsTo.shouldUpdateCurrentSnapshot;
}
-(NSDictionary*)_shouldUpdateCurrentSnapshot:(NSDictionary*)currentSnapshot
newSnapshot:(NSDictionary*)newSnapshot
globalID:(EOKeyGlobalID*)globalID
databaseChannel:(EODatabaseChannel*)databaseChannel
{
NSDictionary* r=nil;
if (_delegate!=nil
&& _delegateRespondsTo.shouldUpdateCurrentSnapshot)
{
r=[_delegate databaseContext: self
shouldUpdateCurrentSnapshot: currentSnapshot
newSnapshot: newSnapshot
globalID: globalID
databaseChannel: databaseChannel];
}
return r;
}
-(BOOL) _usesPessimisticLockingWithFetchSpecification:(EOFetchSpecification*)fetchSpec
databaseChannel:(EODatabaseChannel*)databaseChannel
{
BOOL yn=NO;
if (_delegate!=nil
&& _delegateRespondsTo.shouldUsePessimisticLock)
{
yn=[_delegate databaseContext: self
shouldUsePessimisticLockWithFetchSpecification: fetchSpec
databaseChannel: databaseChannel];
}
else if ([self updateStrategy] == EOUpdateWithPessimisticLocking)
yn=YES;
else if (fetchSpec != nil)
yn=[fetchSpec locksObjects];
return yn;
}
-(void)_performDidSelectObjectsWithFetchSpecification:(EOFetchSpecification*)fetchSpec
databaseChannel:(EODatabaseChannel*)databaseChannel
{
if (_delegate!=nil
&& _delegateRespondsTo.didSelectObjects)
{
[_delegate databaseContext:self
didSelectObjectsWithFetchSpecification:fetchSpec
databaseChannel:databaseChannel];
}
}
@end

View file

@ -71,7 +71,25 @@
- (BOOL)_shouldGeneratePrimaryKeyForEntityName: (NSString *)entityName;
- (EOEntity*) _entityForObject:(EOCustomObject*) eo;
- (void)_buildPrimaryKeyGeneratorListForEditingContext: (EOEditingContext *)context;
- (id)_fetchSingleObjectForEntity:(EOEntity*)entity
globalID:(EOGlobalID*)gid
editingContext:(EOEditingContext*)context;
@end
@interface EODatabaseContext (EODatabaseContextDelegate)
-(BOOL) _respondsTo_shouldUpdateCurrentSnapshot;
-(BOOL)_performShouldSelectObjectsWithFetchSpecification:(EOFetchSpecification*)fetchSpec
databaseChannel:(EODatabaseChannel*)databaseChannel;
-(NSDictionary*)_shouldUpdateCurrentSnapshot:(NSDictionary*)currentSnapshot
newSnapshot:(NSDictionary*)newSnapshot
globalID:(EOKeyGlobalID*)gid
databaseChannel:(EODatabaseChannel*)databaseChannel;
-(BOOL) _usesPessimisticLockingWithFetchSpecification:(EOFetchSpecification*)fetchSpec
databaseChannel:(EODatabaseChannel*)databaseChannel;
-(void)_performDidSelectObjectsWithFetchSpecification:(EOFetchSpecification*)fetchSpec
databaseChannel:(EODatabaseChannel*)databaseChannel;
@end
#endif /* __EODatabaseContextPriv_h__ */

View file

@ -52,6 +52,7 @@
#include <EOControl/EODebug.h>
#include <EOControl/EOPrivate.h>
#include <EOControl/EOGlobalID.h>
#include <EOAccess/EODatabaseOperation.h>
#include <EOAccess/EOAttribute.h>

View file

@ -98,12 +98,15 @@
NSMutableArray *_primaryKeyAttributes;
NSMutableArray *_classProperties; // EOAttribute/EORelationship
NSMutableArray *_attributesUsedForLocking;
NSMutableArray *_attributesToFetch;
NSMutableArray *_attributesToSave;
NSArray *_attributesToFetch;
NSArray *_attributesToSave;
NSMutableArray *_propertiesToFault;
NSArray* _dbSnapshotKeys;
NSMutableArray *_subEntities;
NSMutableDictionary* _singleTableSubEntityDictionary;
NSString* _singleTableSubEntityKey;
EOQualifier* _singleTableRestrictingQualifier;
EOEntity *_parent;
struct {
@ -118,8 +121,10 @@
unsigned int updating:1;
unsigned int cachesObjects:1;
unsigned int isSingleTableEntity:1;
unsigned int nonUpdateableAttributesInitialized:1;
unsigned int nonUpdateableAttributes:1;
unsigned int extraRefCount:22;
unsigned int extraRefCount:20;
} _flags;
}
@ -182,7 +187,7 @@
- (unsigned int)maxNumberOfInstancesToBatchFetch;
- (EOGlobalID *)globalIDForRow: (NSDictionary *)row;
- (NSDictionary *)primaryKeyForGlobalID: (EOKeyGlobalID *)gid;
- (NSDictionary *)primaryKeyForGlobalID: (EOGlobalID *)gid;
@end
@interface EOEntity (EOEntityEditing)

View file

@ -208,7 +208,7 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat
if ([array count] > 0)
{
ASSIGN(_attributes, array);
ASSIGN(_attributes, (NSMutableArray*)array);
_flags.attributesIsLazy = YES;
}
@ -217,7 +217,7 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat
array);
if ([array count] > 0)
{
ASSIGN(_attributesUsedForLocking, array);
ASSIGN(_attributesUsedForLocking, (NSMutableArray*)array);
_flags.attributesUsedForLockingIsLazy = YES;
}
@ -229,7 +229,7 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat
if ([array count] > 0)
{
ASSIGN(_primaryKeyAttributes, array);
ASSIGN(_primaryKeyAttributes, (NSMutableArray*)array);
_flags.primaryKeyAttributesIsLazy = YES;
}
@ -243,7 +243,7 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat
if ([array count] > 0)
{
ASSIGN(_classProperties, array);
ASSIGN(_classProperties, (NSMutableArray*)array);
_flags.classPropertiesIsLazy = YES;
}
@ -253,7 +253,7 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat
if ([array count] > 0)
{
ASSIGN(_relationships, array);
ASSIGN(_relationships, (NSMutableArray*)array);
_flags.relationshipsIsLazy = YES;
}
@ -634,6 +634,9 @@ static void performSelectorOnArrayWithEachObjectOfClass(NSArray *arr, SEL select
DESTROY(_storedProcedures); // never initialized?
DESTROY(_snapshotToAdaptorRowSubsetMapping);
DESTROY(_subEntities);
DESTROY(_singleTableSubEntityDictionary);
DESTROY(_singleTableSubEntityKey);
DESTROY(_singleTableRestrictingQualifier);
DESTROY(_userInfo);
[super dealloc];
@ -1480,7 +1483,7 @@ static void performSelectorOnArrayWithEachObjectOfClass(NSArray *arr, SEL select
- (EOGlobalID *)globalIDForRow: (NSDictionary *)row
{
EOGlobalID *gid = [self globalIDForRow: row
EOGlobalID *gid = [self _globalIDForRow: row
isFinal: NO];
NSAssert(gid, @"No gid");
@ -1498,7 +1501,7 @@ createInstanceWithEditingContext:globalID:zone:
return gid;
}
- (NSDictionary *)primaryKeyForGlobalID: (EOKeyGlobalID *)gid
- (NSDictionary *)primaryKeyForGlobalID: (EOGlobalID *)gid
{
//OK
NSMutableDictionary *dictionaryForPrimaryKey = nil;
@ -1511,7 +1514,7 @@ createInstanceWithEditingContext:globalID:zone:
if (count > 0)
{
int i;
id *gidkeyValues = [gid keyValues];
id *gidkeyValues = [(EOKeyGlobalID*)gid keyValues];
if (gidkeyValues)
{
@ -1655,6 +1658,7 @@ createInstanceWithEditingContext:globalID:zone:
[_attributes addObject: attribute];
[self _setIsEdited]; //To clean caches
[attribute setParent: self];
[self _clearAttributesCaches];
}
/**
@ -1684,6 +1688,7 @@ createInstanceWithEditingContext:globalID:zone:
[_attributes removeObject: attribute];
[self _setIsEdited];//To clean caches
[self _clearAttributesCaches];
}
}
@ -2347,8 +2352,8 @@ createInstanceWithEditingContext:globalID:zone:
[self _setIsEdited];
}
- (id) globalIDForRow: (NSDictionary*)row
isFinal: (BOOL)isFinal
- (EOGlobalID*) _globalIDForRow: (NSDictionary*)row
isFinal: (BOOL)isFinal
{
EOKeyGlobalID *globalID = nil;
NSArray *primaryKeyAttributeNames = nil;
@ -3530,14 +3535,14 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
if (componentsCount>0)
{
EOEntity *entity = self;
int i=0;
NSUInteger i=0;
for(i=0;i<componentsCount;i++)
{
EORelationship* relationship = [entity relationshipNamed: [components objectAtIndex:i]];
NSArray* sourceAttributes = [relationship sourceAttributes];
NSArray* destinationAttributes = [relationship destinationAttributes];
int index = [sourceAttributes indexOfObjectIdenticalTo:resultAttribute];
if(i == NSNotFound)
NSUInteger index = [sourceAttributes indexOfObjectIdenticalTo:resultAttribute];
if(index == NSNotFound)
{
[NSException raise: @"NSIllegalStateException"
format: @"%@ entity '%@' is unable to map attribute along relationship path '%@'",
@ -3595,7 +3600,7 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
if(i>0)
{
NSArray* sourceAttributes = [relationship sourceAttributes];
if(![destinationAttributes containsIdenticalObjectsWithArray:sourceAttributes]);
if(![destinationAttributes containsIdenticalObjectsWithArray:sourceAttributes])
{
has=NO;
break;
@ -4255,6 +4260,35 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
}
}
-(void)_clearAttributesCaches
{
_flags.nonUpdateableAttributesInitialized = NO;
}
//MG2014: OK
-(BOOL)_hasNonUpdateableAttributes
{
if(!_flags.nonUpdateableAttributesInitialized)
{
NSArray* attributes = [self attributes];
NSUInteger attributesCount=[attributes count];
_flags.nonUpdateableAttributes=NO;
if (attributesCount>0)
{
NSUInteger i=0;
for(i=0;i<attributesCount;i++)
{
if ([[attributes objectAtIndex:i] _isNonUpdateable])
{
_flags.nonUpdateableAttributes=YES;
break;
}
}
}
_flags.nonUpdateableAttributesInitialized = YES;
}
return _flags.nonUpdateableAttributes;
}
@end
@implementation EOEntity (EOEntityPrivateSingleEntity)
@ -4262,6 +4296,113 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
{
return _flags.isSingleTableEntity;
}
- (EOQualifier*) _singleTableRestrictingQualifier
{
if (_singleTableRestrictingQualifier == nil)
{
NSArray* subEntities = [self subEntities];
NSUInteger subEntitiesCount=[subEntities count];
NSUInteger i=0;
NSMutableArray* qualifiers = [NSMutableArray array];
if (_restrictingQualifier != nil)
[qualifiers addObject:_restrictingQualifier];
for(i=0;i<subEntitiesCount;i++)
{
EOQualifier* qualifier = [[subEntities objectAtIndex:i] _singleTableRestrictingQualifier];
if (qualifier != nil)
[qualifiers addObject:qualifier];
}
if ([qualifiers count]>0)
_singleTableRestrictingQualifier = [EOOrQualifier qualifierWithQualifierArray:qualifiers];
}
return _singleTableRestrictingQualifier;
}
//MG2014: OK
-(NSString*)_singleTableSubEntityKey
{
if (_singleTableSubEntityKey == nil
&& _restrictingQualifier != nil
&& [_restrictingQualifier isKindOfClass:[EOKeyValueQualifier class]]
&& sel_isEqual([(EOKeyValueQualifier*)_restrictingQualifier selector],EOQualifierOperatorEqual))
{
ASSIGN(_singleTableSubEntityKey,([(EOKeyValueQualifier*)_restrictingQualifier key]));
}
return _singleTableSubEntityKey;
}
//MG2014: OK ??
-(id)_subEntityKeyValue
{
id value=nil;
if (_restrictingQualifier != nil)
{
value = [(EOKeyValueQualifier*)_restrictingQualifier value];
if (value == nil)
value=GDL2_EONull;
}
return value;
}
//MG2014: OK
-(void)_generateSingleTableSubEntityDictionary:(NSMutableDictionary*)d
{
NSArray* subEntities = [self subEntities];
NSUInteger subEntitiesCount=[subEntities count];
if (subEntitiesCount>0)
{
NSUInteger i=0;
for(i = 0; i<subEntitiesCount; i++)
{
[[subEntities objectAtIndex:i] _generateSingleTableSubEntityDictionary:d];
}
}
id value = [self _subEntityKeyValue];
if (value != nil)
{
[d setObject:self
forKey:value];
}
ASSIGN(_singleTableSubEntityDictionary,d);
}
//MG2014: OK
-(NSDictionary*)_singleTableSubEntityDictionary
{
if (_flags.isSingleTableEntity)
{
if (_singleTableSubEntityDictionary == nil)
{
NSMutableDictionary* d = [NSMutableDictionary dictionary];
[self _generateSingleTableSubEntityDictionary:d];
}
return _singleTableSubEntityDictionary;
}
else
return nil;
}
//MG2014: OK
-(EOEntity*) _singleTableSubEntityForRow:(NSDictionary*)row
{
NSDictionary* d = [self _singleTableSubEntityDictionary];
if (d != nil)
{
NSString* key = [self _singleTableSubEntityKey];
if (key != nil)
{
id value = [row objectForKey:key];
if (value != nil)
return [d objectForKey:value];
}
}
return nil;
}
@end
@implementation EOEntity (Deprecated)

View file

@ -87,8 +87,8 @@
- (NSArray *)_classPropertyAttributes;
- (Class)classForObjectWithGlobalID: (EOKeyGlobalID *)globalID;
- (id)globalIDForRow: (NSDictionary *)row
isFinal: (BOOL)isFinal;
- (EOGlobalID*)_globalIDForRow: (NSDictionary *)row
isFinal: (BOOL)isFinal;
- (BOOL) _hasAttributeNamed:(NSString *)name;
@end
@ -115,6 +115,8 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path;
- (id)_parsePropertyName: (NSString *)propertyName;
+(void) _assertNoPropagateKeyCycleWithEntities:(NSMutableArray*)entities
relationships:(NSMutableArray*)relationships;
-(void)_clearAttributesCaches;
-(BOOL)_hasNonUpdateableAttributes;
//- (id)_newStringWithBuffer: (unsigned short *)param0
// length: (unsigned int *)param1;
@end
@ -133,6 +135,12 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path;
@interface EOEntity (EOEntityPrivateSingleEntity)
- (BOOL) _isSingleTableEntity;
- (EOQualifier*) _singleTableRestrictingQualifier;
- (NSString*)_singleTableSubEntityKey;
- (id)_subEntityKeyValue;
- (void)_generateSingleTableSubEntityDictionary:(NSMutableDictionary*)d;
- (NSDictionary*)_singleTableSubEntityDictionary;
- (EOEntity*) _singleTableSubEntityForRow:(NSDictionary*)row;
@end
#endif

View file

@ -64,6 +64,7 @@
#include <EOAccess/EOEntity.h>
#include <EOAccess/EOExpressionArray.h>
#include <EOAccess/EORelationship.h>
#include <EOAccess/EOSQLExpression.h>
#include "EOPrivate.h"
@ -339,7 +340,7 @@ static SEL eqSel;
return [[self objectAtIndex:0] isKindOfClass:GDL2_EORelationshipClass];
}
- (NSString *)valueWithSQLExpressionElement:(EOSQLExpression*)element
- (NSString *)valueWithSQLExpressionElement:(id)element
forSQLExpression:(EOSQLExpression*)sqlExpression
{
NSString* value=nil;
@ -364,7 +365,7 @@ static SEL eqSel;
if (count>0)
{
if (sqlExpression != nil
&& [[self firstObject] isKindOfClass:GDL2_EORelationshipClass])
&& [[self objectAtIndex:0] isKindOfClass:GDL2_EORelationshipClass])
{
value = [sqlExpression sqlStringForAttributePath:self];
}

View file

@ -66,6 +66,7 @@
#include <EOAccess/EOModel.h>
#include <EOAccess/EOEntity.h>
#include <EOAccess/EOEntityPriv.h>
#include <EOAccess/EOAttribute.h>
#include <EOAccess/EORelationship.h>
#include <EOAccess/EOAdaptor.h>
@ -464,64 +465,38 @@ NSString *EOBindVariableColumnKey = @"EOBindVariableColumnKey";
return entitiesString;
}
//MG2014: OK
- (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
NSEnumerator* rowEnum = [row keyEnumerator];
NSString *attributeName = nil;
while ((attributeName = [rowEnum nextObject]))
{
rowEnum = [row keyEnumerator];
while ((attributeName = [rowEnum nextObject]))
EOAttribute *attribute = [_entity anyAttributeNamed: attributeName];
if (attribute==nil)
{
[NSException raise: @"NSIllegalStateException"
format: @"%s: row argument contains key '%@' which does not have corresponding attribute on entity '%@'",
__PRETTY_FUNCTION__,
attributeName,
[_entity name]];
}
else
{
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];
tableList = [self tableListWithRootEntity: [self _rootEntityForExpression]];
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");
ASSIGN(_statement, [self assembleInsertStatementWithRow: row
tableList: tableList
columnList: _listString
valueList: _valueListString]);
}
- (void)prepareUpdateExpressionWithRow: (NSDictionary *)row

View file

@ -0,0 +1,62 @@
/* -*-objc-*-
EOSQLExpressionFactory.h
Copyright (C) 2014 Free Software Foundation, Inc.
Author: Manuel Guesdon <mguesdon@orange-concept.com>
Date: Jun 2014
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 __EOSQLExpressionFactory_h__
#define __EOSQLExpressionFactory_h__
@interface EOSQLExpressionFactory: NSObject
{
EOAdaptor* _adaptor;
Class _expressionClass;
}
+(EOSQLExpressionFactory*)sqlExpressionFactoryWithAdaptor:(EOAdaptor*)adaptor;
-(id)initWithAdaptor:(EOAdaptor*)adaptor;
-(EOAdaptor*)adaptor;
-(Class)expressionClass;
-(EOSQLExpression*)createExpressionWithEntity:(EOEntity*)entity;
-(EOSQLExpression*)expressionForString:(NSString*)string;
-(EOSQLExpression*)expressionForEntity:(EOEntity*)entity;
-(EOSQLExpression*)insertStatementForRow:(NSDictionary*)row
withEntity:(EOEntity*)entity;
-(EOSQLExpression*) updateStatementForRow:(NSDictionary*)row
qualifier:(EOQualifier*)qualifier
withEntity:(EOEntity*)entity;
-(EOSQLExpression*)deleteStatementWithQualifier:(EOQualifier*)qualifier
entity:(EOEntity*)entity;
-(EOSQLExpression*)selectStatementForAttributes:(NSArray*)attributes
lock:(BOOL)lock
fetchSpecification:(EOFetchSpecification*)fetchSpec
entity:(EOEntity*)entity;
@end
#endif // __EOSQLExpressionFactory_h__

View file

@ -0,0 +1,229 @@
/* EOSQLExpressionFactory.m
Copyright (C) 2014 Free Software Foundation, Inc.
Author: Manuel Guesdon <mguesdon@orange-concept.com>
Date: Jun 2014
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"
#include <string.h>
#ifdef GNUSTEP
#include <Foundation/NSDebug.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSEnumerator.h>
#include <Foundation/NSException.h>
#include <Foundation/NSNotification.h>
#include <Foundation/NSSet.h>
#include <Foundation/NSString.h>
#include <Foundation/NSUserDefaults.h>
#else
#include <Foundation/Foundation.h>
#endif
#ifndef GNUSTEP
#include <GNUstepBase/GNUstep.h>
#include <GNUstepBase/GSObjCRuntime.h>
#include <GNUstepBase/NSDebug+GNUstepBase.h>
#include <GNUstepBase/NSObject+GNUstepBase.h>
#endif
#include <EOAccess/EOModel.h>
#include <EOAccess/EOEntity.h>
#include <EOAccess/EOAdaptor.h>
#include <EOAccess/EOSQLExpression.h>
#include <EOAccess/EOSQLExpressionFactory.h>
/*
#include <EOControl/EOFetchSpecification.h>
#include <EOControl/EOQualifier.h>
#include <EOControl/EOSortOrdering.h>
#include <EOControl/EODebug.h>
#include <EOControl/EONull.h>
#include <EOAccess/EOModel.h>
#include <EOAccess/EOEntity.h>
#include <EOAccess/EOEntityPriv.h>
#include <EOAccess/EOAttribute.h>
#include <EOAccess/EORelationship.h>
#include <EOAccess/EOAdaptor.h>
#include <EOAccess/EOAdaptorContext.h>
#include <EOAccess/EOAdaptorChannel.h>
#include <EOAccess/EOJoin.h>
#include <EOAccess/EOSQLExpression.h>
#include <EOAccess/EOSQLQualifier.h>
#include <EOAccess/EOExpressionArray.h>
#include "EOPrivate.h"
#include "EOEntityPriv.h"
#include "EOAttributePriv.h"
#include "EOSQLExpressionPriv.h"
*/
@implementation EOSQLExpressionFactory
+(EOSQLExpressionFactory*)sqlExpressionFactoryWithAdaptor:(EOAdaptor*)adaptor
{
return AUTORELEASE([[self alloc]initWithAdaptor:adaptor]);
}
-(id)initWithAdaptor:(EOAdaptor*)adaptor
{
if ((self=[self init]))
{
ASSIGN(_adaptor,adaptor);
ASSIGN(_expressionClass,[adaptor expressionClass]);
}
return self;
}
-(void)dealloc
{
DESTROY(_adaptor);
DESTROY(_expressionClass);
[super dealloc];
}
-(EOAdaptor*)adaptor
{
return _adaptor;
}
-(Class)expressionClass;
{
return _expressionClass;
}
-(EOSQLExpression*)createExpressionWithEntity:(EOEntity*)entity
{
return [_expressionClass sqlExpressionWithEntity:entity];
}
-(EOSQLExpression*)expressionForString:(NSString*)string
{
EOSQLExpression* sqlExpression = [self createExpressionWithEntity:nil];
[sqlExpression setStatement:string];
return sqlExpression;
}
-(EOSQLExpression*)expressionForEntity:(EOEntity*)entity
{
return [self createExpressionWithEntity:nil];
}
-(EOSQLExpression*)insertStatementForRow:(NSDictionary*)row
withEntity:(EOEntity*)entity
{
EOSQLExpression* sqlExpression = nil;
if (entity == nil)
{
[NSException raise: @"NSIllegalArgumentException"
format:@"%s entity must not be nil",
__PRETTY_FUNCTION__];
}
else
{
sqlExpression = [self createExpressionWithEntity:entity];
[sqlExpression setUseAliases:NO];
[sqlExpression prepareInsertExpressionWithRow:row];
}
return sqlExpression;
}
-(EOSQLExpression*) updateStatementForRow:(NSDictionary*)row
qualifier:(EOQualifier*)qualifier
withEntity:(EOEntity*)entity
{
EOSQLExpression* sqlExpression = nil;
if ([row count] == 0)
{
[NSException raise: @"NSIllegalArgumentException"
format:@"%s nothing to update",
__PRETTY_FUNCTION__];
}
else if (entity == nil)
{
[NSException raise: @"NSIllegalArgumentException"
format:@"%s entity must not be nil",
__PRETTY_FUNCTION__];
}
else if(qualifier == nil)
{
[NSException raise: @"NSIllegalArgumentException"
format:@"%s qualifier must not be nil",
__PRETTY_FUNCTION__];
}
else
{
sqlExpression = [self createExpressionWithEntity:entity];
[sqlExpression setUseAliases:NO];
[sqlExpression prepareUpdateExpressionWithRow:row
qualifier:qualifier];
}
return sqlExpression;
}
-(EOSQLExpression*)deleteStatementWithQualifier:(EOQualifier*)qualifier
entity:(EOEntity*)entity
{
EOSQLExpression* sqlExpression = [self createExpressionWithEntity:entity];
[sqlExpression setUseAliases:NO];
[sqlExpression prepareDeleteExpressionForQualifier:qualifier];
return sqlExpression;
}
-(EOSQLExpression*)selectStatementForAttributes:(NSArray*)attributes
lock:(BOOL)lock
fetchSpecification:(EOFetchSpecification*)fetchSpec
entity:(EOEntity*)entity
{
EOSQLExpression* sqlExpression = nil;
if ([attributes count] == 0)
{
[NSException raise: @"NSIllegalArgumentException"
format:@"%s nothing to select",
__PRETTY_FUNCTION__];
}
else if (fetchSpec == nil)
{
[NSException raise: @"NSIllegalArgumentException"
format:@"%s fetchSpecification must not be nil",
__PRETTY_FUNCTION__];
}
else if(entity == nil)
{
[NSException raise: @"NSIllegalArgumentException"
format:@"%s entity must not be nil",
__PRETTY_FUNCTION__];
}
else
{
sqlExpression = [self createExpressionWithEntity:entity];
[sqlExpression setUseAliases:YES];
[sqlExpression prepareSelectExpressionWithAttributes: attributes
lock: lock
fetchSpecification: fetchSpec];
}
return sqlExpression;
}
@end

View file

@ -113,13 +113,4 @@ connectionDictionaryOverrides: (NSDictionary *)overrides;
@end
@interface EOFetchSpecification (EOAccess)
+ (EOFetchSpecification *)fetchSpecificationNamed: (NSString *)name
entityNamed: (NSString *)entityName;
@end
#endif

View file

@ -1070,27 +1070,3 @@ connectionDictionaryOverrides: (NSDictionary *)overrides
@end
@implementation EOFetchSpecification (EOAccess)
+ (EOFetchSpecification *)fetchSpecificationNamed: (NSString *)name
entityNamed: (NSString *)entityName
{
EOFetchSpecification *newEOFetchSpecification = nil;
EOModelGroup *anModelGroup;
anModelGroup = [EOModelGroup defaultGroup];
if (anModelGroup)
newEOFetchSpecification = [anModelGroup fetchSpecificationNamed: name
entityNamed: entityName];
return newEOFetchSpecification;
}
@end

View file

@ -55,6 +55,7 @@ EODatabaseOperation.m \
EOSchemaGeneration.m \
EOSchemaSynchronization.m \
EOSQLExpression.m \
EOSQLExpressionFactory.m \
EOSQLQualifier.m \
EODatabase.m \
EODatabaseChannel.m \
@ -80,6 +81,7 @@ EOAdaptorContext.h \
EOAdaptorChannel.h \
EODatabaseOperation.h \
EOSQLExpression.h \
EOSQLExpressionFactory.h \
EOSQLQualifier.h \
EODatabase.h \
EODatabaseChannel.h \

View file

@ -50,7 +50,6 @@
@interface PostgreSQLChannel : EOAdaptorChannel
{
PostgreSQLContext *_adaptorContext;
PGconn *_pgConn;
PGresult *_pgResult;
NSArray *_attributes;

View file

@ -90,96 +90,6 @@ static BOOL attrRespondsToValueTypeChar = NO;
#define EOAdaptorDebugLog(format, args...) \
do { if ([self isDebugEnabled]) { NSLog(format , ## args); } } while (0)
#warning Check this. Is this unused code? -- dw
static NSDictionary *
pgResultDictionary(PGresult *pgResult)
{
int nfields, ntuples;
int i, j;
NSMutableArray *fields;
NSMutableArray *tuples;
ExecStatusType statusType;
nfields = PQnfields(pgResult);
ntuples = PQntuples(pgResult);
fields = [NSMutableArray arrayWithCapacity: nfields];
tuples = [NSMutableArray arrayWithCapacity: ntuples];
for (i = 1; i <= nfields; i++)
{
NSString *fname;
NSNumber *fnumber;
NSNumber *ftype;
NSNumber *fsize;
NSNumber *fmod;
NSDictionary *dict;
char *cfname;
cfname = PQfname(pgResult, i);
fname = [NSString stringWithCString: cfname];
fnumber = [NSNumber numberWithInt: PQfnumber(pgResult, cfname)];
ftype = [NSNumber numberWithUnsignedInt: PQftype(pgResult, i)];
fsize = [NSNumber numberWithInt: PQfsize(pgResult, i)];
fmod = [NSNumber numberWithInt: PQfmod(pgResult, i)];
dict = [NSDictionary dictionaryWithObjectsAndKeys:
fname, @"PQfname",
fnumber, @"PQfnumber",
ftype, @"PQftype",
fsize, @"PQfsize",
fmod, @"PQfmod",
nil];
[fields addObject: dict];
}
for (i = 1; i <= ntuples; i++)
{
NSMutableDictionary *tuple;
tuple = [NSMutableDictionary dictionaryWithCapacity: nfields];
for (j = 1; j <= nfields; j++)
{
NSString *tupleInfo;
NSString *tupleKey;
tupleKey = [NSString stringWithCString: PQfname(pgResult, j)];
if (PQgetisnull(pgResult, i, j))
{
tupleInfo = @"NULL";
}
else
{
NSString *fmt;
fmt = [NSString stringWithFormat: @"%%%ds", PQgetlength(pgResult, i, j)];
tupleInfo = [NSString stringWithFormat: fmt, PQgetvalue(pgResult, i, j)];
}
[tuple setObject: tupleInfo forKey: tupleKey];
}
[tuples addObject: tuple];
}
statusType = PQresultStatus(pgResult);
return [NSDictionary dictionaryWithObjectsAndKeys:
[NSString stringWithFormat:@"%d", statusType], @"PQresultStatus",
[NSString stringWithFormat:@"%s", PQresStatus(statusType)], @"PQresStatus",
[NSString stringWithFormat:@"%s", PQresultErrorMessage(pgResult)], @"PQresultErrorMessage",
[NSString stringWithFormat:@"%d", ntuples], @"PQntuples",
[NSString stringWithFormat:@"%d", nfields], @"PQnfields",
[NSString stringWithFormat:@"%d", PQbinaryTuples(pgResult)], @"PQbinaryTuples",
[NSString stringWithFormat:@"%s", PQcmdStatus(pgResult)], @"PQcmdStatus",
[NSString stringWithFormat:@"%s", PQoidStatus(pgResult)], @"PQoidStatus",
[NSString stringWithFormat:@"%d", PQoidValue(pgResult)], @"PQoidValue",
[NSString stringWithFormat:@"%s", PQcmdTuples(pgResult)], @"PQcmdTuples",
tuples, @"tuples",
fields, @"fields",
nil];
}
/*
* read up to the specified number of characters, terminating at a non-digit
* except for leading whitespace characters.
@ -592,9 +502,7 @@ newValueForBytesLengthAttribute (const void *bytes,
{
EOAttribute *attr = nil;
ASSIGN(_adaptorContext, adaptorContext);//TODO NO
//verify
//verify
_oidToTypeName = [[NSMutableDictionary alloc] initWithCapacity: 101];
attr = [[EOAttribute alloc] init];
@ -616,7 +524,6 @@ newValueForBytesLengthAttribute (const void *bytes,
if ([self isOpen])
[self closeChannel];
DESTROY(_adaptorContext);
DESTROY(_sqlExpression);
DESTROY(_oidToTypeName);
DESTROY(_pkAttributeArray);
@ -1103,7 +1010,7 @@ newValueForBytesLengthAttribute (const void *bytes,
if (([self _evaluateExpression: expression
withAttributes: nil] == 0))
{
NSDebugMLLog(@"gsdb", @"_evaluateExpression:withAttributes: return NO", "");
NSDebugMLLog(@"gsdb", @"_evaluateExpression:withAttributes: return %@", @"NO");
[self _cancelResults];
}
else
@ -1211,7 +1118,7 @@ each key
if ([nrow count] > 0)
{
sqlexpr = [[[_adaptorContext adaptor] expressionClass]
sqlexpr = [[[_context adaptor] expressionClass]
insertStatementForRow: nrow
entity: entity];
@ -1240,7 +1147,7 @@ each key
}
}
[_adaptorContext autoCommitTransaction];
[(PostgreSQLContext*)_context autoCommitTransaction];
}
@ -1276,9 +1183,9 @@ each key
adaptorContext = (PostgreSQLContext *)[self adaptorContext];
[self _cancelResults];
[_adaptorContext autoBeginTransaction: NO];
[(PostgreSQLContext*)_context autoBeginTransaction: NO];
sqlexpr = [[[_adaptorContext adaptor] expressionClass]
sqlexpr = [[[_context adaptor] expressionClass]
deleteStatementWithQualifier: qualifier
entity: entity];
@ -1350,7 +1257,7 @@ each key
[self _cancelResults];
[_adaptorContext autoBeginTransaction: NO];
[(PostgreSQLContext*)_context autoBeginTransaction: NO];
ASSIGN(_attributes, attributes);
// NSDebugMLLog(@"gsdb",@"00 attributes=%@",_attributes);
@ -1358,7 +1265,7 @@ each key
NSAssert([attributes count] > 0, @"No Attributes");
sqlExpr = [[[_adaptorContext adaptor] expressionClass]
sqlExpr = [[[_context adaptor] expressionClass]
selectStatementForAttributes: attributes
lock: flag
fetchSpecification: fetchSpecification
@ -1377,7 +1284,7 @@ each key
}
}
[_adaptorContext autoCommitTransaction];
[(PostgreSQLContext*)_context autoCommitTransaction];
if (_delegateRespondsTo.didSelectAttributes)
[_delegate adaptorChannel: self
@ -1476,7 +1383,7 @@ each key
NSDictionary *dbRow = nil;
sqlExpr = [[[_adaptorContext adaptor] expressionClass]
sqlExpr = [[[_context adaptor] expressionClass]
selectStatementForAttributes: invAttributes
lock: NO
fetchSpecification:
@ -1523,7 +1430,7 @@ each key
if ([mrow count] > 0)
{
sqlExpr = [[[_adaptorContext adaptor] expressionClass]
sqlExpr = [[[_context adaptor] expressionClass]
updateStatementForRow: mrow
qualifier: qualifier
entity: entity];
@ -2327,7 +2234,7 @@ each key
}
sqlFormat=[NSString stringWithFormat: @"SELECT nextval('%@')",
[[[self adaptorContext]adaptor] primaryKeySequenceNameFormat]];
[(PostgreSQLAdaptor*)[[self adaptorContext]adaptor] primaryKeySequenceNameFormat]];
sqlString = [NSString stringWithFormat: sqlFormat,
[entity primaryKeyRootName]];
@ -2364,7 +2271,7 @@ each key
NSAssert(pkValue, @"no pk value");
[_adaptorContext autoCommitTransaction];
[(PostgreSQLContext*)_context autoCommitTransaction];
pk = [NSDictionary dictionaryWithObject: pkValue
forKey: [primAttribute name]];

View file

@ -104,7 +104,7 @@
int _lockCount;
id _notificationQueue;
NSAutoreleasePool * _lockPool;
NSTimeInterval fetchTimestamp;
NSTimeInterval _fetchTimestamp;
}
+ (void)setDefaultFetchTimestampLag: (NSTimeInterval)lag;
@ -251,6 +251,9 @@ modified state of the object.**/
- (void)clearOriginalSnapshotForObject: (id)object;
- (NSTimeInterval)fetchTimestamp;
- (void)setFetchTimestamp:(NSTimeInterval)ts;
@end
/* To be used with NSRunLoop's performSelector:target:argument:order:modes: */

View file

@ -2413,56 +2413,49 @@ _mergeValueForKey(id obj, id value,
}
// parameters[0]=object
// parameters[1]=gid
-(void)_undoDelete:(NSArray*)parameters
{
NSAssert1([parameters count]==2,@"Bad parameters count: %d",[parameters count]);
[self _insertObject:[parameters objectAtIndex:0]
withGlobalID:[parameters objectAtIndex:1]];
}
- (void)deleteObject: (id)object
{
EOFLOGObjectLevelArgs(@"EOEditingContext", @"Unprocessed: %@",
[self unprocessedDescription]);
EOFLOGObjectLevelArgs(@"EOEditingContext", @"Objects: %@",
[self objectsDescription]);
if (_sharedContext != nil
&& [_sharedContext globalIDForObject:object] != nil)
{
[_sharedContext deleteObject:object];
}
if (!NSHashGet(_unprocessedDeletes, object)
&& !NSHashGet(_deletedObjects, object))
{
NSMethodSignature *undoMethodSignature = nil;
NSUndoManager *undoManager;
//EOGlobalID *gid = [self globalIDForObject: object];
EOGlobalID* gid = [self globalIDForObject:object];
[self _registerClearStateWithUndoManager];
undoManager = (NSUndoManager*)[self undoManager];
[undoManager prepareWithInvocationTarget: self];
undoMethodSignature = [undoManager methodSignatureForSelector:
@selector(_insertObject:withGlobalID:)];
/*
//TODO
if base class of undoManager ret nil, undomanager call editingcont methodSignatureForSelector: _insertObject:withGlobalID:
undoManager forwardInvocation:
<NSInvocation selector: _insertObject:withGlobalID: signature: NMethodSignature: types=v@:@@ nargs=4 sizeOfParams=16 returnValueLength=0; >
_NSUndoInvocation avec selector:_insertObject:withGlobalID:
target self (editing context)
[undoManager _registerUndoObject:arget: EOEditingContext -- selector:_insertObject:withGlobalID:
_invocation=NSInvocation * object: Description:<NSInvocation selector: _insertObject:withGlobalID: signature: NSMethodSignature: types=v@:@@ nargs=4 sizeOfParams=16 returnValueLength=0; >
next=_NSUndoObject * object:0x0 Description:*nil*
previous=_NSUndoObject * object:0x0 Description:*nil*
_target=id object: Description:<EOEditingContext>
[self _prepareEventGrouping];
*/
NSHashInsert(_unprocessedDeletes, object);
[self _enqueueEndOfEventNotification];
[object willChange];
if (_undoManager != nil)
{
[_undoManager registerUndoWithTarget:self
selector:@selector(_undoDelete:)
object:[NSArray arrayWithObjects:object,gid, nil]];
//TODO _updatedObjectsCache = _deletedObjectsCache = null;
NSHashInsert(_unprocessedDeletes, object);
[self _enqueueEndOfEventNotification];
};
}
EOFLOGObjectLevelArgs(@"EOEditingContext", @"Unprocessed: %@",
[self unprocessedDescription]);
EOFLOGObjectLevelArgs(@"EOEditingContext", @"Objects: %@",
[self objectsDescription]);
}
- (void)lockObject: (id)object
@ -2545,7 +2538,7 @@ _mergeValueForKey(id obj, id value,
{
EOGlobalID *gid=nil;
IMP objectForGlobalIDIMP=NULL;
IMP enumNO=NO;
IMP enumNO=NULL;
enumerator = [[_snapshotsByGID allKeys] objectEnumerator];
@ -2870,7 +2863,7 @@ _mergeValueForKey(id obj, id value,
- (void)objectWillChange: (id)object
{
//TODO
//
EOFLOGObjectLevelArgs(@"EOEditingContext",
@ -3779,6 +3772,28 @@ modified state of the object.**/
[self _sendOrEnqueueNotification: notification
selector: @selector(_defaultEditingContextNowInitialized:)];
}
-(NSTimeInterval)fetchTimestamp
{
if (_flags.lockUsingParent)
return [(EOEditingContext*)_objectStore fetchTimestamp];
else
return _fetchTimestamp;
}
-(void)setFetchTimestamp:(NSTimeInterval)ts
{
if (_flags.lockUsingParent)
{
[NSException raise: @"NSIllegalStateException"
format: @"Can not %s for a nested editing context",
__PRETTY_FUNCTION__];
}
else
_fetchTimestamp = ts;
}
@end

View file

@ -143,7 +143,7 @@ static NSRecursiveLock *allGenericRecordsLock = nil;
// Ayers: Review
// We use entity dictionaryForProperties to avoid creation
//of new EOMKKDInitializer
ASSIGN(_dictionary,[classDescription dictionaryForInstanceProperties]);
ASSIGN(_dictionary,((EOMutableKnownKeyDictionary*)[classDescription dictionaryForInstanceProperties]));
EOFLOGObjectLevelArgs(@"EOGenericRecord", @"Record %p: dictionary=%@",
self, _dictionary);
};
@ -1164,17 +1164,13 @@ You can override this to exclude properties manually handled by derived object *
+ (NSString *)eoFormatSizeDictionary: (NSDictionary *)dict
{
NSMutableString *dscr = [NSMutableString string];
NSMutableDictionary *processed;
NSMutableDictionary *summaryNb;
NSMutableDictionary *summarySize;
NSString *key;
NSMutableDictionary *summaryNb = nil;
NSMutableDictionary *summarySize = nil;
NSString *key = nil;
unsigned totalSize = 0;
unsigned totalNb = 0;
NSEnumerator *enumK;
processed = [dict objectForKey: @"processed"];
summaryNb = [dict objectForKey: @"summaryNb"];
summarySize = [dict objectForKey: @"summarySize"];
enumK = [[[summaryNb allKeys] sortedArrayUsingSelector:
@ -1204,8 +1200,6 @@ You can override this to exclude properties manually handled by derived object *
(int)(totalNb!=0 ? (totalSize / totalNb) : 0),
(int)(totalNb!=0 ? (totalSize / totalNb / 1024) : 0)];
return dscr;
}

View file

@ -751,14 +751,11 @@
// This is the designated initializer
- (id) initWithObjects: (const id[])objects
forKeys: (const id[])keys
forKeys: (const id <NSCopying>[])keys
count: (NSUInteger)count
{
//OK
EOMKKDInitializer *initializer = nil;
if (count > 0)
{
NSAssert(keys, @"No keys array");

View file

@ -115,7 +115,6 @@ returnsRemovedValues:(NSArray**)removedValues
-(unsigned short)unsignedShortValue;
-(long)longValue;
-(unsigned long)unsignedLongValue;
-(long long)longLongValue;
-(unsigned long long)unsignedLongLongValue;
@end

View file

@ -712,12 +712,6 @@ returnsRemovedValues:(NSArray**)removedValues
return (unsigned long)v;
};
-(long long)longLongValue
{
long long v=atoll([self lossyCString]);
return v;
};
-(unsigned long long)unsignedLongLongValue
{
return strtoull([self lossyCString],NULL,10);

View file

@ -90,12 +90,12 @@
+ (id) allocWithZone: (NSZone *)zone
{
return [NSNull null];
return (EONull*)[NSNull null];
}
+ null
{
return [NSNull null];
return (EONull*)[NSNull null];
}
@end