mirror of
https://github.com/gnustep/libs-gdl2.git
synced 2025-02-21 18:40:51 +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
|
@ -277,9 +277,8 @@ 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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -1322,6 +1328,152 @@ 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
|
||||||
|
@ -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,22 +1552,21 @@ userInfo = {
|
||||||
*/
|
*/
|
||||||
rawRowKeyPaths = [fetchSpecification rawRowKeyPaths];//OK
|
rawRowKeyPaths = [fetchSpecification rawRowKeyPaths];//OK
|
||||||
if (rawRowKeyPaths)
|
if (rawRowKeyPaths)
|
||||||
#if 0
|
|
||||||
{
|
{
|
||||||
NSEmitTODO();
|
NSArray * rawRows = [self _fetchRawRowKeyPaths:rawRowKeyPaths
|
||||||
[self notImplemented: _cmd]; //TODO
|
fetchSpecification:fetchSpecification
|
||||||
}
|
entity:entity
|
||||||
#else
|
editingContext:context];
|
||||||
|
return rawRows;
|
||||||
|
} else {
|
||||||
// (stephane@sente.ch) Adapted implementation of non raw rows
|
// (stephane@sente.ch) Adapted implementation of non raw rows
|
||||||
{
|
|
||||||
//cachesObject
|
//cachesObject
|
||||||
//fetchspe isDeep ret 1
|
//fetchspe isDeep ret 1
|
||||||
channel = [self _obtainOpenChannel];
|
|
||||||
|
|
||||||
if (!channel)
|
if (!channel)
|
||||||
{
|
{
|
||||||
NSEmitTODO();
|
channel = [self _obtainOpenChannel];
|
||||||
[self notImplemented: _cmd];//TODO
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1424,17 +1576,17 @@ userInfo = {
|
||||||
([channel isFetchInProgress] ? "YES" : "NO"));
|
([channel isFetchInProgress] ? "YES" : "NO"));
|
||||||
|
|
||||||
//mirko:
|
//mirko:
|
||||||
#if 0
|
//#if 0
|
||||||
if (_flags.beganTransaction == NO
|
// if (_flags.beganTransaction == NO
|
||||||
&& _updateStrategy == EOUpdateWithPessimisticLocking)
|
// && _updateStrategy == EOUpdateWithPessimisticLocking)
|
||||||
{
|
// {
|
||||||
[_adaptorContext beginTransaction];
|
// [_adaptorContext beginTransaction];
|
||||||
|
//
|
||||||
NSDebugMLLog(@"EODatabaseContext",
|
// NSDebugMLLog(@"EODatabaseContext",
|
||||||
@"BEGAN TRANSACTION FLAG==>YES");
|
// @"BEGAN TRANSACTION FLAG==>YES");
|
||||||
_flags.beganTransaction = YES;
|
// _flags.beganTransaction = YES;
|
||||||
}
|
// }
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
if ([entity isAbstractEntity] == NO) //Mirko ???
|
if ([entity isAbstractEntity] == NO) //Mirko ???
|
||||||
// (stephane@sente) Should we test deepInheritanceFetch?
|
// (stephane@sente) Should we test deepInheritanceFetch?
|
||||||
|
@ -1577,13 +1729,9 @@ userInfo = {
|
||||||
NS_ENDHANDLER;
|
NS_ENDHANDLER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NSDebugMLLog(@"EODatabaseContext",
|
|
||||||
@"step 2 channel is busy=%d",
|
|
||||||
(int)[channel isFetchInProgress]);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
else if ([entity cachesObjects] == YES)//OK
|
if ([entity cachesObjects] == YES)//OK
|
||||||
{
|
{
|
||||||
///TODO MG!!!
|
///TODO MG!!!
|
||||||
NSMutableArray *cache;
|
NSMutableArray *cache;
|
||||||
|
|
|
@ -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,6 +99,11 @@ 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)
|
||||||
|
@ -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