From 879c15cae4df3df06ce6209a5edb3033f255af00 Mon Sep 17 00:00:00 2001 From: Manuel Guesdon Date: Thu, 22 May 2014 18:31:05 +0000 Subject: [PATCH] * EOAccess/EODatabaseContext.m implement _objectFaultWithSnapshot:relationship:editingContext: fix -initializeObject:row:entity:editingContext: finish implementation of -_obtainOpenChannel implement -_forceDisconnect fix -_openChannelWithLoginPanel: implement -_verifyNoChangesToReadonlyEntity: * EOAccess/EOAttributePriv.h add -_isNonUpdateable add -_isPrimaryKeyClassProperty add _flags.isNonUpdateable add _flags.isNonUpdateableInitialized * EOAccess/EOAttribute.m add -_isNonUpdateable add -_isPrimaryKeyClassProperty git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@37905 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 16 ++ EOAccess/EOAttribute.h | 4 +- EOAccess/EOAttribute.m | 20 ++ EOAccess/EOAttributePriv.h | 3 + EOAccess/EODatabaseContext.m | 381 ++++++++++++++++++++--------------- 5 files changed, 256 insertions(+), 168 deletions(-) diff --git a/ChangeLog b/ChangeLog index 792371d..2102ef2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2014-05-22 Manuel Guesdon + * EOAccess/EODatabaseContext.m + implement _objectFaultWithSnapshot:relationship:editingContext: + fix -initializeObject:row:entity:editingContext: + finish implementation of -_obtainOpenChannel + implement -_forceDisconnect + fix -_openChannelWithLoginPanel: + implement -_verifyNoChangesToReadonlyEntity: + * EOAccess/EOAttributePriv.h + add -_isNonUpdateable + add -_isPrimaryKeyClassProperty + add _flags.isNonUpdateable + add _flags.isNonUpdateableInitialized + * EOAccess/EOAttribute.m + add -_isNonUpdateable + add -_isPrimaryKeyClassProperty 2014-05-22 Manuel Guesdon * EOAdaptors/PostgreSQLAdaptor/PostgreSQLChannel.m: fix newValueForDateTypeLengthAttribute diff --git a/EOAccess/EOAttribute.h b/EOAccess/EOAttribute.h index dce9054..67bbf18 100644 --- a/EOAccess/EOAttribute.h +++ b/EOAccess/EOAttribute.h @@ -96,7 +96,9 @@ typedef enum { unsigned int isParentAnEOEntity:1; unsigned int protoOverride:EOATTRIBUTE_PROTO_OVERRIDE_BITS_COUNT; unsigned int isAttributeValueInitialized:1; - unsigned int unused : 10; + unsigned int isNonUpdateable; + unsigned int isNonUpdateableInitialized; + unsigned int unused : 8; } _flags; unsigned int extraRefCount; diff --git a/EOAccess/EOAttribute.m b/EOAccess/EOAttribute.m index a654ee9..f984ee7 100644 --- a/EOAccess/EOAttribute.m +++ b/EOAccess/EOAttribute.m @@ -1035,6 +1035,7 @@ static NSArray* staticPrototypeKeys=nil; [self willChange]; _flags.isReadOnly = yn; [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_readOnly]; + _flags.isNonUpdateableInitialized = NO; } } @@ -2211,6 +2212,25 @@ More details: return _sourceToDestinationKeyMap; } +-(BOOL)_isNonUpdateable +{ + if (!_flags.isNonUpdateableInitialized) + { + _flags.isNonUpdateable = ([self isReadOnly] || [self _isPrimaryKeyClassProperty]); + _flags.isNonUpdateableInitialized = YES; + } + return _flags.isNonUpdateable; +} + +-(BOOL)_isPrimaryKeyClassProperty +{ + NSArray* pkAttrs = [_parent primaryKeyAttributes]; + if ([pkAttrs containsObject:self] + && [[_parent classProperties]containsObject:self]) + return YES; + else + return NO; +} @end diff --git a/EOAccess/EOAttributePriv.h b/EOAccess/EOAttributePriv.h index ba0416c..9177e36 100644 --- a/EOAccess/EOAttributePriv.h +++ b/EOAccess/EOAttributePriv.h @@ -65,6 +65,9 @@ typedef enum _EOAttributeProtoOverrideBits - (void)_setValuesFromTargetAttribute; -(void)_setSourceToDestinationKeyMap:(NSDictionary*)map; -(NSDictionary*) _sourceToDestinationKeyMap; + +-(BOOL)_isNonUpdateable; +-(BOOL)_isPrimaryKeyClassProperty; @end @interface EOAttribute (EOAttributePrivate2) diff --git a/EOAccess/EODatabaseContext.m b/EOAccess/EODatabaseContext.m index 5c2e3b8..60dd85d 100644 --- a/EOAccess/EODatabaseContext.m +++ b/EOAccess/EODatabaseContext.m @@ -712,14 +712,8 @@ May raise an exception if transaction has began or if you want pessimistic lock editingContext: (EOEditingContext *)context isComplete: (BOOL)isComplete { - //OK EOAccessFaultHandler *handler; - - - - - NSAssert(globalID, @"No globalID"); NSAssert1([globalID isKindOfClass: [EOKeyGlobalID class]], @"globalID is not a EOKeyGlobalID but a %@", @@ -748,7 +742,6 @@ May raise an exception if transaction has began or if you want pessimistic lock [self _addBatchForGlobalID: (EOKeyGlobalID*)globalID fault: object]; - //TODO: use isComplete } @@ -5496,20 +5489,69 @@ 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 + editingContext:(EOEditingContext*)context +{ + id objectFault=nil; + EOMutableKnownKeyDictionary *foreignKeyForSourceRow = + [relationship _foreignKeyForSourceRow: snapshot]; + + if ([foreignKeyForSourceRow containsObjectsNotIdenticalTo: GDL2_EONull]) + { + EOEntity *destinationEntity = [relationship destinationEntity]; + EOGlobalID *relRowGid = [destinationEntity + globalIDForRow: foreignKeyForSourceRow]; + + if ([[destinationEntity subEntities]count] > 0) + { + objectFault=[self _fetchSingleObjectForEntity:destinationEntity + globalID:relRowGid + editingContext:context]; + } + else + { + objectFault=[context faultForGlobalID: relRowGid + editingContext: context]; + } + } + return objectFault; +} + - (void)initializeObject: (id)object row: (NSDictionary*)row entity: (EOEntity*)entity editingContext: (EOEditingContext*)context { - //really near ok NSArray *relationships = nil; - NSArray *classPropertyAttributeNames = nil; - NSUInteger count = 0; + NSArray *classPropertyAttributeNames = [entity classPropertyAttributeNames]; + NSUInteger count = [classPropertyAttributeNames count]; IMP rowObjectForKeyIMP=NULL; - classPropertyAttributeNames = [entity classPropertyAttributeNames]; - count = [classPropertyAttributeNames count]; - //row is usuallly a EOMutableKnownKeyDictionary so will use EOMKKD_objectForKeyWithImpPtr if (count>0) @@ -5521,143 +5563,54 @@ compareUsingEntityNames(id left, id right, void* vpSortOrders) @"Object is a fault. call -methodForSelector: on it is a bad idea"); for (i = 0; i < count; i++) - { - id key = GDL2_ObjectAtIndexWithImp(classPropertyAttributeNames,oaiIMP,i); - id value = nil; - - - value = EOMKKD_objectForKeyWithImpPtr(row,&rowObjectForKeyIMP,key); - - if (value == GDL2_EONull) - value = nil; - - [object takeStoredValue:value - forKey:key]; - } + { + id key = GDL2_ObjectAtIndexWithImp(classPropertyAttributeNames,oaiIMP,i); + id value = EOMKKD_objectForKeyWithImpPtr(row,&rowObjectForKeyIMP,key); + + if (value == GDL2_EONull) + value = nil; + + [object takeStoredValue:value + forKey:key]; + } }; - relationships = [entity _relationshipsToFaultForRow: row]; - - - + relationships = [entity _relationshipsToFaultForRow: row]; count = [relationships count]; if (count>0) - { - NSUInteger i=0; - IMP oaiIMP=[relationships methodForSelector:@selector(objectAtIndex:)]; - - NSAssert(!_isFault(object), - @"Object is a fault. call -methodForSelector: on it is a bad idea"); - - - for (i = 0; i < count; i++) { - id relObject = nil; - EORelationship *relationship = GDL2_ObjectAtIndexWithImp(relationships,oaiIMP,i); - NSString *relName = [relationship name]; + NSUInteger i=0; + IMP oaiIMP=[relationships methodForSelector:@selector(objectAtIndex:)]; + NSAssert(!_isFault(object), + @"Object is a fault. call -methodForSelector: on it is a bad idea"); - if ([relationship isToMany]) - { - EOGlobalID *gid = [entity globalIDForRow: row]; - - relObject = [self arrayFaultWithSourceGlobalID: gid - relationshipName: relName - editingContext: context]; - } - else if ([relationship isFlattened]) - { - // to one flattened relationship like aRelationship.anotherRelationship... - - // I don't know how to handle this case.... May be we shouldn't treat this as real property ?? - NSEmitTODO(); - relObject = nil; - } - else - { - EOMutableKnownKeyDictionary *foreignKeyForSourceRow = nil; - - foreignKeyForSourceRow = [relationship _foreignKeyForSourceRow: row]; - - if (![foreignKeyForSourceRow - containsObjectsNotIdenticalTo: GDL2_EONull]) - { - NSEmitTODO();//TODO: what to do if rel is mandatory ? - relObject = nil; - } - else - { - EOEntity *destinationEntity = [relationship destinationEntity]; - EOGlobalID *relRowGid = [destinationEntity - globalIDForRow: foreignKeyForSourceRow]; - - - - if ([(EOKeyGlobalID*)relRowGid areKeysAllNulls]) - NSWarnLog(@"All key of relRowGid %p (%@) are nulls", - relRowGid, - relRowGid); - - relObject = [context faultForGlobalID: relRowGid - editingContext: context]; - - NSDebugMLLog(@"EODatabaseContext", @"relObject=%p (%@)", - relObject, [relObject class]); - //end - /* - NSArray *joins = [(EORelationship *)prop joins]; - EOJoin *join; - NSMutableDictionary *row; - EOGlobalID *faultGID; - int h, count; - id value, realValue = nil; - - row = [NSMutableDictionary dictionaryWithCapacity:4]; - - count = [joins count]; - for (h=0; h