mirror of
https://github.com/gnustep/libs-gdl2.git
synced 2025-04-22 04:40:44 +00:00
* 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:
parent
70ff29d9ec
commit
c8cfc0fed3
33 changed files with 1320 additions and 887 deletions
67
ChangeLog
67
ChangeLog
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
|
||||
#include <EOControl/EODebug.h>
|
||||
#include <EOControl/EOPrivate.h>
|
||||
#include <EOControl/EOGlobalID.h>
|
||||
|
||||
#include <EOAccess/EODatabaseOperation.h>
|
||||
#include <EOAccess/EOAttribute.h>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
62
EOAccess/EOSQLExpressionFactory.h
Normal file
62
EOAccess/EOSQLExpressionFactory.h
Normal 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__
|
229
EOAccess/EOSQLExpressionFactory.m
Normal file
229
EOAccess/EOSQLExpressionFactory.m
Normal 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
|
|
@ -113,13 +113,4 @@ connectionDictionaryOverrides: (NSDictionary *)overrides;
|
|||
|
||||
@end
|
||||
|
||||
|
||||
@interface EOFetchSpecification (EOAccess)
|
||||
|
||||
+ (EOFetchSpecification *)fetchSpecificationNamed: (NSString *)name
|
||||
entityNamed: (NSString *)entityName;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
|
||||
@interface PostgreSQLChannel : EOAdaptorChannel
|
||||
{
|
||||
PostgreSQLContext *_adaptorContext;
|
||||
PGconn *_pgConn;
|
||||
PGresult *_pgResult;
|
||||
NSArray *_attributes;
|
||||
|
|
|
@ -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]];
|
||||
|
|
|
@ -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: */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -115,7 +115,6 @@ returnsRemovedValues:(NSArray**)removedValues
|
|||
-(unsigned short)unsignedShortValue;
|
||||
-(long)longValue;
|
||||
-(unsigned long)unsignedLongValue;
|
||||
-(long long)longLongValue;
|
||||
-(unsigned long long)unsignedLongLongValue;
|
||||
@end
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -90,12 +90,12 @@
|
|||
|
||||
+ (id) allocWithZone: (NSZone *)zone
|
||||
{
|
||||
return [NSNull null];
|
||||
return (EONull*)[NSNull null];
|
||||
}
|
||||
|
||||
+ null
|
||||
{
|
||||
return [NSNull null];
|
||||
return (EONull*)[NSNull null];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in a new issue