mirror of
https://github.com/gnustep/libs-gdl2.git
synced 2025-02-21 02:20:55 +00:00
* EOAccess/EOAttribute.m
added attributeWithParent: definition: convenience method * EOAccess/EOAdaptorContext.m _channelDidInit: setDelegate * EOAccess/EODatabaseContext.m availableChannel: call registerChannel new method _fetchRawRowKeyPaths:fetchSpecification:entity:editingContext: * EOAccess/EODatabaseChannel.m raise NSInvalidArgumentException in init. initWithDatabaseContext: more checks * EOAdaptors/PostgreSQLAdaptor/PostgreSQLContext.m beginTransaction: more checks, raise NSInternalInconsistencyException git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@30494 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
fb061e0a13
commit
021d9c6759
6 changed files with 389 additions and 217 deletions
|
@ -113,11 +113,11 @@ NSString *EOAdaptorContextRollbackTransactionNotification = @"EOAdaptorContextRo
|
||||||
- (BOOL)hasOpenChannels
|
- (BOOL)hasOpenChannels
|
||||||
{
|
{
|
||||||
int i, count = [_channels count];
|
int i, count = [_channels count];
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
if ([[[_channels objectAtIndex: i] nonretainedObjectValue] isOpen])
|
if ([[[_channels objectAtIndex: i] nonretainedObjectValue] isOpen])
|
||||||
return YES;
|
return YES;
|
||||||
|
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,23 +277,22 @@ NSString *EOAdaptorContextRollbackTransactionNotification = @"EOAdaptorContextRo
|
||||||
{
|
{
|
||||||
[_channels addObject: [NSValue valueWithNonretainedObject: channel]];
|
[_channels addObject: [NSValue valueWithNonretainedObject: channel]];
|
||||||
|
|
||||||
[channel setDebugEnabled: [self isDebugEnabled]];
|
[channel setDebugEnabled: [self isDebugEnabled]]; // not done on reference -- dw
|
||||||
//call self delegate
|
[channel setDelegate:_delegate];
|
||||||
//call channel setDelegate: returned ?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_channelWillDealloc:channel
|
- (void)_channelWillDealloc:channel
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = [_channels count] - 1; i >= 0; i--)
|
for (i = [_channels count] - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if ([[_channels objectAtIndex: i] nonretainedObjectValue] == channel)
|
||||||
{
|
{
|
||||||
if ([[_channels objectAtIndex: i] nonretainedObjectValue] == channel)
|
[_channels removeObjectAtIndex: i];
|
||||||
{
|
break;
|
||||||
[_channels removeObjectAtIndex: i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -116,6 +116,11 @@ typedef enum {
|
||||||
+ (id)attributeWithPropertyList: (NSDictionary *)propertyList
|
+ (id)attributeWithPropertyList: (NSDictionary *)propertyList
|
||||||
owner: (id)owner;
|
owner: (id)owner;
|
||||||
|
|
||||||
|
/** returns an autoreleased attribute **/
|
||||||
|
|
||||||
|
+ (id) attributeWithParent:(EOEntity *) parent
|
||||||
|
definition:(NSString*) def;
|
||||||
|
|
||||||
/* Accessing the entity */
|
/* Accessing the entity */
|
||||||
- (NSString *)name;
|
- (NSString *)name;
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,20 @@ RCS_ID("$Id$")
|
||||||
owner: owner] autorelease];
|
owner: owner] autorelease];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (id) attributeWithParent:(EOEntity *) parent
|
||||||
|
definition:(NSString*) def
|
||||||
|
{
|
||||||
|
EOAttribute * attr = [[[self alloc] init] autorelease];
|
||||||
|
|
||||||
|
if (attr) {
|
||||||
|
[attr setName: def];
|
||||||
|
[attr setParent: parent];
|
||||||
|
[attr setDefinition: def];
|
||||||
|
}
|
||||||
|
|
||||||
|
return attr;
|
||||||
|
}
|
||||||
|
|
||||||
- (id) initWithPropertyList: (NSDictionary *)propertyList
|
- (id) initWithPropertyList: (NSDictionary *)propertyList
|
||||||
owner: (id)owner
|
owner: (id)owner
|
||||||
{
|
{
|
||||||
|
|
|
@ -112,20 +112,30 @@ RCS_ID("$Id$")
|
||||||
return [[[self alloc] initWithDatabaseContext: databaseContext] autorelease];
|
return [[[self alloc] initWithDatabaseContext: databaseContext] autorelease];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (id) init
|
||||||
|
{
|
||||||
|
[NSException raise: NSInvalidArgumentException
|
||||||
|
format: @"Use initWithDatabaseContext to init an instance of class %@",
|
||||||
|
NSStringFromClass([self class])];
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
- (id) initWithDatabaseContext:(EODatabaseContext *)databaseContext
|
- (id) initWithDatabaseContext:(EODatabaseContext *)databaseContext
|
||||||
{
|
{
|
||||||
if ((self = [super init]))
|
if ((self = [super init]))
|
||||||
{
|
{
|
||||||
ASSIGN(_databaseContext, databaseContext);
|
ASSIGN(_adaptorChannel, [[databaseContext adaptorContext]
|
||||||
ASSIGN(_adaptorChannel, [[_databaseContext adaptorContext]
|
|
||||||
createAdaptorChannel]);
|
createAdaptorChannel]);
|
||||||
//TODO NO<<<<
|
|
||||||
[_adaptorChannel openChannel];
|
|
||||||
|
|
||||||
_fetchProperties = [NSMutableArray new];
|
if (!_adaptorChannel)
|
||||||
_fetchSpecifications = [NSMutableArray new];
|
{
|
||||||
//NO>>>>>>>
|
[NSException raise: NSInternalInconsistencyException
|
||||||
[_databaseContext registerChannel: self];//should be in caller
|
format: @"EODatabaseChannel is unable to obtain new channel from %@",
|
||||||
|
[databaseContext adaptorContext]];
|
||||||
|
} else {
|
||||||
|
ASSIGN(_databaseContext, databaseContext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|
|
@ -537,8 +537,14 @@ static Class _contextClass = Nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!channel)
|
if ((!channel) && ([_registeredChannels count] < 1)) {
|
||||||
channel = [EODatabaseChannel databaseChannelWithDatabaseContext: self];
|
channel = [EODatabaseChannel databaseChannelWithDatabaseContext: self];
|
||||||
|
if (channel)
|
||||||
|
{
|
||||||
|
[self registerChannel:channel];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
@ -1260,8 +1266,8 @@ userInfo = {
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_fetchRelationship: (EORelationship *)relationship
|
- (void)_fetchRelationship: (EORelationship *)relationship
|
||||||
withObjects: (NSArray *)objsArray
|
withObjects: (NSArray *)objsArray
|
||||||
editingContext: (EOEditingContext *)context
|
editingContext: (EOEditingContext *)context
|
||||||
{
|
{
|
||||||
NSMutableArray *qualArray = nil;
|
NSMutableArray *qualArray = nil;
|
||||||
NSEnumerator *objEnum = nil;
|
NSEnumerator *objEnum = nil;
|
||||||
|
@ -1322,8 +1328,154 @@ userInfo = {
|
||||||
EOFLOGObjectFnStop();
|
EOFLOGObjectFnStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSArray*) _fetchRawRowKeyPaths:(NSArray *) rawRowKeyPaths
|
||||||
|
fetchSpecification: (EOFetchSpecification*) fetchSpecification
|
||||||
|
entity: (EOEntity *) entity
|
||||||
|
editingContext: (EOEditingContext *) context
|
||||||
|
{
|
||||||
|
EOAdaptorChannel * adaptorChannel = [[self availableChannel] adaptorChannel];
|
||||||
|
NSMutableArray * results = [NSMutableArray array];
|
||||||
|
NSUInteger fetchLimit = 0;
|
||||||
|
NSUInteger rowsFetched = 0;
|
||||||
|
NSUInteger keyCount = [rawRowKeyPaths count];
|
||||||
|
id messageHandler = nil; // used to prompt the user after the fetch limit is reached.
|
||||||
|
NSString * hintKey = nil;
|
||||||
|
BOOL continueFetch = NO;
|
||||||
|
NSUInteger k;
|
||||||
|
|
||||||
|
NSArray * attributesToFetch;
|
||||||
|
if (keyCount == 0)
|
||||||
|
{
|
||||||
|
attributesToFetch = [entity attributesToFetch];
|
||||||
|
} else {
|
||||||
|
// Populate an array with the attributes we need
|
||||||
|
attributesToFetch = [NSMutableArray arrayWithCapacity:keyCount];
|
||||||
|
BOOL hasNonFlattenedAttributes = NO;
|
||||||
|
|
||||||
|
for (k = 0; k < keyCount; k++)
|
||||||
|
{
|
||||||
|
NSString * keyName = [rawRowKeyPaths objectAtIndex:k];
|
||||||
|
EOAttribute * attr = [entity attributeNamed:keyName];
|
||||||
|
if (!attr)
|
||||||
|
{
|
||||||
|
attr = [EOAttribute attributeWithParent:entity
|
||||||
|
definition:keyName];
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if ((!hasNonFlattenedAttributes) && (![attr isFlattened]))
|
||||||
|
{
|
||||||
|
hasNonFlattenedAttributes = YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[attributesToFetch addObject:attr];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasNonFlattenedAttributes)
|
||||||
|
{
|
||||||
|
// check if lastObject is enouth.
|
||||||
|
// the reference however does only checks the lastObject.
|
||||||
|
|
||||||
|
EOAttribute * attr = [attributesToFetch lastObject];
|
||||||
|
EORelationship * relationship;
|
||||||
|
|
||||||
|
if ([attr isFlattened])
|
||||||
|
{
|
||||||
|
relationship = [[attr _definitionArray] objectAtIndex:0];
|
||||||
|
} else {
|
||||||
|
NSString * s1 = [rawRowKeyPaths lastObject];
|
||||||
|
NSString * relName = [[s1 componentsSeparatedByString:@"."] objectAtIndex:0];
|
||||||
|
relationship = [entity relationshipNamed:relName];
|
||||||
|
|
||||||
|
if ([relationship isFlattened])
|
||||||
|
{
|
||||||
|
relationship = [[relationship _definitionArray] objectAtIndex:0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EOJoin * join = [[relationship joins] lastObject];
|
||||||
|
EOAttribute * attr2 = [join sourceAttribute];
|
||||||
|
|
||||||
|
[attributesToFetch addObject:attr2];
|
||||||
|
}
|
||||||
|
// our channel does not support this.
|
||||||
|
//[adaptorChannel _setRawDictionaryInitializerForAttributes:attributesToFetch];
|
||||||
|
}
|
||||||
|
if ((hintKey = [[fetchSpecification hints] objectForKey:@"EOCustomQueryExpressionHintKey"]))
|
||||||
|
{
|
||||||
|
if ([hintKey isKindOfClass:[NSString class]])
|
||||||
|
{
|
||||||
|
hintKey = [[[_adaptorContext adaptor] expressionClass] expressionForString:hintKey];
|
||||||
|
} else {
|
||||||
|
NSLog(@"%s - %@ is not an NSString but a %@",__PRETTY_FUNCTION__, hintKey, NSStringFromClass([hintKey class]));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
EOQualifier * qualifier = [[fetchSpecification qualifier] schemaBasedQualifierWithRootEntity:entity];
|
||||||
|
|
||||||
|
if (qualifier != [fetchSpecification qualifier])
|
||||||
|
{
|
||||||
|
[fetchSpecification setQualifier:qualifier];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (![adaptorChannel isOpen])
|
||||||
|
{
|
||||||
|
[adaptorChannel openChannel];
|
||||||
|
}
|
||||||
|
if (hintKey)
|
||||||
|
{
|
||||||
|
[adaptorChannel evaluateExpression:hintKey];
|
||||||
|
[adaptorChannel setAttributesToFetch:attributesToFetch];
|
||||||
|
} else {
|
||||||
|
[adaptorChannel selectAttributes:attributesToFetch
|
||||||
|
fetchSpecification:fetchSpecification
|
||||||
|
lock:NO
|
||||||
|
entity:entity];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0 is no fetch limit
|
||||||
|
fetchLimit = [fetchSpecification fetchLimit];
|
||||||
|
// TODO: check if we need to check for protocol EOMessageHandlers
|
||||||
|
if (([fetchSpecification promptsAfterFetchLimit]) && ([context messageHandler]))
|
||||||
|
{
|
||||||
|
messageHandler = [context messageHandler];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
do {
|
||||||
|
do {
|
||||||
|
NSMutableDictionary * dict = [adaptorChannel fetchRowWithZone:NULL];
|
||||||
|
if (!dict) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
[results addObject:dict];
|
||||||
|
rowsFetched++;
|
||||||
|
} while ((fetchLimit == 0) || (rowsFetched < fetchLimit));
|
||||||
|
|
||||||
|
if (!messageHandler) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
continueFetch = [messageHandler editingContext:context
|
||||||
|
shouldContinueFetchingWithCurrentObjectCount:rowsFetched
|
||||||
|
originalLimit:fetchLimit
|
||||||
|
objectStore:self];
|
||||||
|
|
||||||
|
} while (continueFetch);
|
||||||
|
|
||||||
|
[adaptorChannel cancelFetch];
|
||||||
|
|
||||||
|
if (_delegate)
|
||||||
|
{
|
||||||
|
|
||||||
|
[_delegate databaseContext: self
|
||||||
|
didFetchObjects: results
|
||||||
|
fetchSpecification: fetchSpecification
|
||||||
|
editingContext: context];
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
- (NSArray *)objectsWithFetchSpecification: (EOFetchSpecification *)fetchSpecification
|
- (NSArray *)objectsWithFetchSpecification: (EOFetchSpecification *)fetchSpecification
|
||||||
editingContext: (EOEditingContext *)context
|
editingContext: (EOEditingContext *)context
|
||||||
{ // TODO
|
{ // TODO
|
||||||
EODatabaseChannel *channel = nil;
|
EODatabaseChannel *channel = nil;
|
||||||
NSMutableArray *array = nil;
|
NSMutableArray *array = nil;
|
||||||
|
@ -1348,6 +1500,7 @@ userInfo = {
|
||||||
NSDebugMLLog(@"EODatabaseContext", @"fetchSpecification=%@", fetchSpecification);
|
NSDebugMLLog(@"EODatabaseContext", @"fetchSpecification=%@", fetchSpecification);
|
||||||
|
|
||||||
#warning fix this method! -- dw
|
#warning fix this method! -- dw
|
||||||
|
channel = [self _obtainOpenChannel];
|
||||||
|
|
||||||
if (_flags.beganTransaction == NO)
|
if (_flags.beganTransaction == NO)
|
||||||
{
|
{
|
||||||
|
@ -1399,192 +1552,187 @@ userInfo = {
|
||||||
*/
|
*/
|
||||||
rawRowKeyPaths = [fetchSpecification rawRowKeyPaths];//OK
|
rawRowKeyPaths = [fetchSpecification rawRowKeyPaths];//OK
|
||||||
if (rawRowKeyPaths)
|
if (rawRowKeyPaths)
|
||||||
#if 0
|
|
||||||
{
|
|
||||||
NSEmitTODO();
|
|
||||||
[self notImplemented: _cmd]; //TODO
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// (stephane@sente.ch) Adapted implementation of non raw rows
|
|
||||||
{
|
{
|
||||||
//cachesObject
|
NSArray * rawRows = [self _fetchRawRowKeyPaths:rawRowKeyPaths
|
||||||
//fetchspe isDeep ret 1
|
fetchSpecification:fetchSpecification
|
||||||
channel = [self _obtainOpenChannel];
|
entity:entity
|
||||||
|
editingContext:context];
|
||||||
if (!channel)
|
return rawRows;
|
||||||
{
|
} else {
|
||||||
NSEmitTODO();
|
// (stephane@sente.ch) Adapted implementation of non raw rows
|
||||||
[self notImplemented: _cmd];//TODO
|
|
||||||
}
|
//cachesObject
|
||||||
else
|
//fetchspe isDeep ret 1
|
||||||
{
|
|
||||||
NSDebugMLLog(@"EODatabaseContext",
|
if (!channel)
|
||||||
@"channel class %@ [channel isFetchInProgress]=%s",
|
|
||||||
[channel class],
|
|
||||||
([channel isFetchInProgress] ? "YES" : "NO"));
|
|
||||||
|
|
||||||
//mirko:
|
|
||||||
#if 0
|
|
||||||
if (_flags.beganTransaction == NO
|
|
||||||
&& _updateStrategy == EOUpdateWithPessimisticLocking)
|
|
||||||
{
|
|
||||||
[_adaptorContext beginTransaction];
|
|
||||||
|
|
||||||
NSDebugMLLog(@"EODatabaseContext",
|
|
||||||
@"BEGAN TRANSACTION FLAG==>YES");
|
|
||||||
_flags.beganTransaction = YES;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ([entity isAbstractEntity] == NO) //Mirko ???
|
|
||||||
// (stephane@sente) Should we test deepInheritanceFetch?
|
|
||||||
{
|
|
||||||
int autoreleaseSteps = 20;
|
|
||||||
int autoreleaseStep = autoreleaseSteps;
|
|
||||||
BOOL promptsAfterFetchLimit = NO;
|
|
||||||
NSAutoreleasePool *arp = nil;//To avoid too much memory use when fetching a lot of objects
|
|
||||||
int limit = 0;
|
|
||||||
|
|
||||||
[channel selectObjectsWithFetchSpecification: fetchSpecification
|
|
||||||
editingContext: context];//OK
|
|
||||||
|
|
||||||
NSDebugMLLog(@"EODatabaseContext",
|
|
||||||
@"[channel isFetchInProgress]=%s",
|
|
||||||
([channel isFetchInProgress] ? "YES" : "NO"));
|
|
||||||
|
|
||||||
limit = [fetchSpecification fetchLimit];//OK
|
|
||||||
promptsAfterFetchLimit = [fetchSpecification promptsAfterFetchLimit];
|
|
||||||
|
|
||||||
NSDebugMLLog(@"EODatabaseContext", @"Will Fetch");
|
|
||||||
|
|
||||||
NS_DURING
|
|
||||||
{
|
|
||||||
IMP channelFetchObjectIMP=
|
|
||||||
[channel methodForSelector:@selector(fetchObject)];
|
|
||||||
|
|
||||||
IMP arrayAddObjectIMP=
|
|
||||||
[array methodForSelector:@selector(addObject:)];
|
|
||||||
|
|
||||||
GDL2IMP_UINT arrayIndexOfObjectIdenticalToIMP=
|
|
||||||
(GDL2IMP_UINT)[array methodForSelector:@selector(indexOfObjectIdenticalTo:)];
|
|
||||||
|
|
||||||
arp = GDL2_NSAutoreleasePool_new();
|
|
||||||
NSDebugMLLog(@"EODatabaseContext",
|
|
||||||
@"[channel isFetchInProgress]=%s",
|
|
||||||
([channel isFetchInProgress] ? "YES" : "NO"));
|
|
||||||
|
|
||||||
while ((obj = (*channelFetchObjectIMP)(channel,@selector(fetchObject))))
|
|
||||||
{
|
|
||||||
NSDebugMLLog(@"EODatabaseContext",
|
|
||||||
@"fetched an object");
|
|
||||||
NSDebugMLLog(@"EODatabaseContext",
|
|
||||||
@"FETCH OBJECT object=%@\n", obj);
|
|
||||||
NSDebugMLLog(@"EODatabaseContext",
|
|
||||||
@"%d usesDistinct: %s", num,
|
|
||||||
(usesDistinct ? "YES" : "NO"));
|
|
||||||
NSDebugMLLog(@"EODatabaseContext",
|
|
||||||
@"object=%@\n\n", obj);
|
|
||||||
|
|
||||||
if (usesDistinct == YES
|
|
||||||
&& num > 0
|
|
||||||
&& GDL2_IndexOfObjectIdenticalToWithImp(array,arrayIndexOfObjectIdenticalToIMP,obj)!=NSNotFound)
|
|
||||||
// (stephane@sente) I thought that DISTINCT was done on server-side?!?
|
|
||||||
{
|
|
||||||
obj = nil;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NSDebugMLLog(@"EODatabaseContext", @"AFTER FETCH");
|
|
||||||
GDL2_AddObjectWithImp(array,arrayAddObjectIMP,obj);
|
|
||||||
NSDebugMLLog(@"EODatabaseContext", @"array count=%d",
|
|
||||||
[array count]);
|
|
||||||
num++;
|
|
||||||
|
|
||||||
if (limit > 0 && num >= limit)
|
|
||||||
{
|
|
||||||
if ([[context messageHandler]
|
|
||||||
editingContext: context
|
|
||||||
shouldContinueFetchingWithCurrentObjectCount: num
|
|
||||||
originalLimit: limit
|
|
||||||
objectStore: self] == YES)
|
|
||||||
limit = 0;//??
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DESTROY(arp);
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
if (autoreleaseStep <= 0)
|
|
||||||
{
|
|
||||||
DESTROY(arp);
|
|
||||||
autoreleaseStep = autoreleaseSteps;
|
|
||||||
arp = GDL2_NSAutoreleasePool_new();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
autoreleaseStep--;
|
|
||||||
|
|
||||||
NSDebugMLLog(@"EODatabaseContext",
|
|
||||||
@"WILL FETCH NEXT OBJECT");
|
|
||||||
NSDebugMLLog(@"EODatabaseContext",
|
|
||||||
@"[channel isFetchInProgress]=%s",
|
|
||||||
([channel isFetchInProgress]
|
|
||||||
? "YES" : "NO"));
|
|
||||||
}
|
|
||||||
|
|
||||||
NSDebugMLLog(@"EODatabaseContext",
|
|
||||||
@"finished fetch");
|
|
||||||
NSDebugMLLog(@"EODatabaseContext",
|
|
||||||
@"array=%@", array);
|
|
||||||
NSDebugMLLog(@"EODatabaseContext",
|
|
||||||
@"step 0 channel is busy=%d",
|
|
||||||
(int)[channel isFetchInProgress]);
|
|
||||||
|
|
||||||
[channel cancelFetch]; //OK
|
|
||||||
|
|
||||||
NSDebugMLLog(@"EODatabaseContext",
|
|
||||||
@"step 1 channel is busy=%d",
|
|
||||||
(int)[channel isFetchInProgress]);
|
|
||||||
NSDebugMLLog(@"EODatabaseContext", @"array=%@", array);
|
|
||||||
|
|
||||||
//TODO
|
|
||||||
/*
|
|
||||||
handle exceptio in fetchObject
|
|
||||||
channel fetchObject
|
|
||||||
|
|
||||||
if eception:
|
|
||||||
if ([editcontext handleError:localException])
|
|
||||||
{
|
|
||||||
//TODO
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//TODO
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
DESTROY(arp);
|
|
||||||
}
|
|
||||||
NS_HANDLER
|
|
||||||
{
|
|
||||||
NSDebugMLLog(@"EODatabaseContext", @"AN EXCEPTION: %@",
|
|
||||||
localException);
|
|
||||||
|
|
||||||
RETAIN(localException);
|
|
||||||
DESTROY(arp);
|
|
||||||
AUTORELEASE(localException);
|
|
||||||
[localException raise];
|
|
||||||
}
|
|
||||||
NS_ENDHANDLER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NSDebugMLLog(@"EODatabaseContext",
|
|
||||||
@"step 2 channel is busy=%d",
|
|
||||||
(int)[channel isFetchInProgress]);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
else if ([entity cachesObjects] == YES)//OK
|
|
||||||
{
|
{
|
||||||
|
channel = [self _obtainOpenChannel];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSDebugMLLog(@"EODatabaseContext",
|
||||||
|
@"channel class %@ [channel isFetchInProgress]=%s",
|
||||||
|
[channel class],
|
||||||
|
([channel isFetchInProgress] ? "YES" : "NO"));
|
||||||
|
|
||||||
|
//mirko:
|
||||||
|
//#if 0
|
||||||
|
// if (_flags.beganTransaction == NO
|
||||||
|
// && _updateStrategy == EOUpdateWithPessimisticLocking)
|
||||||
|
// {
|
||||||
|
// [_adaptorContext beginTransaction];
|
||||||
|
//
|
||||||
|
// NSDebugMLLog(@"EODatabaseContext",
|
||||||
|
// @"BEGAN TRANSACTION FLAG==>YES");
|
||||||
|
// _flags.beganTransaction = YES;
|
||||||
|
// }
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
if ([entity isAbstractEntity] == NO) //Mirko ???
|
||||||
|
// (stephane@sente) Should we test deepInheritanceFetch?
|
||||||
|
{
|
||||||
|
int autoreleaseSteps = 20;
|
||||||
|
int autoreleaseStep = autoreleaseSteps;
|
||||||
|
BOOL promptsAfterFetchLimit = NO;
|
||||||
|
NSAutoreleasePool *arp = nil;//To avoid too much memory use when fetching a lot of objects
|
||||||
|
int limit = 0;
|
||||||
|
|
||||||
|
[channel selectObjectsWithFetchSpecification: fetchSpecification
|
||||||
|
editingContext: context];//OK
|
||||||
|
|
||||||
|
NSDebugMLLog(@"EODatabaseContext",
|
||||||
|
@"[channel isFetchInProgress]=%s",
|
||||||
|
([channel isFetchInProgress] ? "YES" : "NO"));
|
||||||
|
|
||||||
|
limit = [fetchSpecification fetchLimit];//OK
|
||||||
|
promptsAfterFetchLimit = [fetchSpecification promptsAfterFetchLimit];
|
||||||
|
|
||||||
|
NSDebugMLLog(@"EODatabaseContext", @"Will Fetch");
|
||||||
|
|
||||||
|
NS_DURING
|
||||||
|
{
|
||||||
|
IMP channelFetchObjectIMP=
|
||||||
|
[channel methodForSelector:@selector(fetchObject)];
|
||||||
|
|
||||||
|
IMP arrayAddObjectIMP=
|
||||||
|
[array methodForSelector:@selector(addObject:)];
|
||||||
|
|
||||||
|
GDL2IMP_UINT arrayIndexOfObjectIdenticalToIMP=
|
||||||
|
(GDL2IMP_UINT)[array methodForSelector:@selector(indexOfObjectIdenticalTo:)];
|
||||||
|
|
||||||
|
arp = GDL2_NSAutoreleasePool_new();
|
||||||
|
NSDebugMLLog(@"EODatabaseContext",
|
||||||
|
@"[channel isFetchInProgress]=%s",
|
||||||
|
([channel isFetchInProgress] ? "YES" : "NO"));
|
||||||
|
|
||||||
|
while ((obj = (*channelFetchObjectIMP)(channel,@selector(fetchObject))))
|
||||||
|
{
|
||||||
|
NSDebugMLLog(@"EODatabaseContext",
|
||||||
|
@"fetched an object");
|
||||||
|
NSDebugMLLog(@"EODatabaseContext",
|
||||||
|
@"FETCH OBJECT object=%@\n", obj);
|
||||||
|
NSDebugMLLog(@"EODatabaseContext",
|
||||||
|
@"%d usesDistinct: %s", num,
|
||||||
|
(usesDistinct ? "YES" : "NO"));
|
||||||
|
NSDebugMLLog(@"EODatabaseContext",
|
||||||
|
@"object=%@\n\n", obj);
|
||||||
|
|
||||||
|
if (usesDistinct == YES
|
||||||
|
&& num > 0
|
||||||
|
&& GDL2_IndexOfObjectIdenticalToWithImp(array,arrayIndexOfObjectIdenticalToIMP,obj)!=NSNotFound)
|
||||||
|
// (stephane@sente) I thought that DISTINCT was done on server-side?!?
|
||||||
|
{
|
||||||
|
obj = nil;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSDebugMLLog(@"EODatabaseContext", @"AFTER FETCH");
|
||||||
|
GDL2_AddObjectWithImp(array,arrayAddObjectIMP,obj);
|
||||||
|
NSDebugMLLog(@"EODatabaseContext", @"array count=%d",
|
||||||
|
[array count]);
|
||||||
|
num++;
|
||||||
|
|
||||||
|
if (limit > 0 && num >= limit)
|
||||||
|
{
|
||||||
|
if ([[context messageHandler]
|
||||||
|
editingContext: context
|
||||||
|
shouldContinueFetchingWithCurrentObjectCount: num
|
||||||
|
originalLimit: limit
|
||||||
|
objectStore: self] == YES)
|
||||||
|
limit = 0;//??
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DESTROY(arp);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if (autoreleaseStep <= 0)
|
||||||
|
{
|
||||||
|
DESTROY(arp);
|
||||||
|
autoreleaseStep = autoreleaseSteps;
|
||||||
|
arp = GDL2_NSAutoreleasePool_new();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
autoreleaseStep--;
|
||||||
|
|
||||||
|
NSDebugMLLog(@"EODatabaseContext",
|
||||||
|
@"WILL FETCH NEXT OBJECT");
|
||||||
|
NSDebugMLLog(@"EODatabaseContext",
|
||||||
|
@"[channel isFetchInProgress]=%s",
|
||||||
|
([channel isFetchInProgress]
|
||||||
|
? "YES" : "NO"));
|
||||||
|
}
|
||||||
|
|
||||||
|
NSDebugMLLog(@"EODatabaseContext",
|
||||||
|
@"finished fetch");
|
||||||
|
NSDebugMLLog(@"EODatabaseContext",
|
||||||
|
@"array=%@", array);
|
||||||
|
NSDebugMLLog(@"EODatabaseContext",
|
||||||
|
@"step 0 channel is busy=%d",
|
||||||
|
(int)[channel isFetchInProgress]);
|
||||||
|
|
||||||
|
[channel cancelFetch]; //OK
|
||||||
|
|
||||||
|
NSDebugMLLog(@"EODatabaseContext",
|
||||||
|
@"step 1 channel is busy=%d",
|
||||||
|
(int)[channel isFetchInProgress]);
|
||||||
|
NSDebugMLLog(@"EODatabaseContext", @"array=%@", array);
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
/*
|
||||||
|
handle exceptio in fetchObject
|
||||||
|
channel fetchObject
|
||||||
|
|
||||||
|
if eception:
|
||||||
|
if ([editcontext handleError:localException])
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
DESTROY(arp);
|
||||||
|
}
|
||||||
|
NS_HANDLER
|
||||||
|
{
|
||||||
|
NSDebugMLLog(@"EODatabaseContext", @"AN EXCEPTION: %@",
|
||||||
|
localException);
|
||||||
|
|
||||||
|
RETAIN(localException);
|
||||||
|
DESTROY(arp);
|
||||||
|
AUTORELEASE(localException);
|
||||||
|
[localException raise];
|
||||||
|
}
|
||||||
|
NS_ENDHANDLER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([entity cachesObjects] == YES)//OK
|
||||||
|
{
|
||||||
///TODO MG!!!
|
///TODO MG!!!
|
||||||
NSMutableArray *cache;
|
NSMutableArray *cache;
|
||||||
EOQualifier *qualifier;
|
EOQualifier *qualifier;
|
||||||
|
|
|
@ -82,8 +82,6 @@ RCS_ID("$Id$")
|
||||||
{
|
{
|
||||||
PostgreSQLChannel *channel = nil;
|
PostgreSQLChannel *channel = nil;
|
||||||
|
|
||||||
EOFLOGObjectFnStart();
|
|
||||||
|
|
||||||
if ([self transactionNestingLevel])
|
if ([self transactionNestingLevel])
|
||||||
[NSException raise: NSInternalInconsistencyException
|
[NSException raise: NSInternalInconsistencyException
|
||||||
format: @"%@ -- %@ 0x%x: attempted to begin a transaction within a transaction",
|
format: @"%@ -- %@ 0x%x: attempted to begin a transaction within a transaction",
|
||||||
|
@ -101,8 +99,13 @@ RCS_ID("$Id$")
|
||||||
self];
|
self];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((!_channels) || ([_channels count] < 1)) {
|
||||||
|
[NSException raise:NSInternalInconsistencyException
|
||||||
|
format:@"%s: No open channel found. CreateAdaptorChannel first!",
|
||||||
|
__PRETTY_FUNCTION__];
|
||||||
|
}
|
||||||
channel = [[_channels objectAtIndex: 0] nonretainedObjectValue];
|
channel = [[_channels objectAtIndex: 0] nonretainedObjectValue];
|
||||||
|
|
||||||
if ([channel isOpen] == NO)
|
if ([channel isOpen] == NO)
|
||||||
[NSException raise: PostgreSQLException
|
[NSException raise: PostgreSQLException
|
||||||
format: @"cannot execute SQL expression. Channel is not opened."];
|
format: @"cannot execute SQL expression. Channel is not opened."];
|
||||||
|
@ -117,13 +120,6 @@ RCS_ID("$Id$")
|
||||||
|
|
||||||
if (_delegateRespondsTo.didBegin)
|
if (_delegateRespondsTo.didBegin)
|
||||||
[_delegate adaptorContextDidBegin: self];
|
[_delegate adaptorContextDidBegin: self];
|
||||||
|
|
||||||
NSDebugMLLog(@"gsdb", @"_flags.didBegin=%s",
|
|
||||||
(_flags.didBegin ? "YES" : "NO"));
|
|
||||||
NSDebugMLLog(@"gsdb", @"_flags.didAutoBegin=%s",
|
|
||||||
(_flags.didAutoBegin ? "YES" : "NO"));
|
|
||||||
|
|
||||||
EOFLOGObjectFnStop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)commitTransaction
|
- (void)commitTransaction
|
||||||
|
|
Loading…
Reference in a new issue