Author: mguesdon
Date: Thu May 22 20:31:05 2014
New Revision: 37905

URL: http://svn.gna.org/viewcvs/gnustep?rev=37905&view=rev
Log:
* 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

Modified:
    libs/gdl2/trunk/ChangeLog
    libs/gdl2/trunk/EOAccess/EOAttribute.h
    libs/gdl2/trunk/EOAccess/EOAttribute.m
    libs/gdl2/trunk/EOAccess/EOAttributePriv.h
    libs/gdl2/trunk/EOAccess/EODatabaseContext.m

Modified: libs/gdl2/trunk/ChangeLog
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/gdl2/trunk/ChangeLog?rev=37905&r1=37904&r2=37905&view=diff
==============================================================================
--- libs/gdl2/trunk/ChangeLog   (original)
+++ libs/gdl2/trunk/ChangeLog   Thu May 22 20:31:05 2014
@@ -1,3 +1,19 @@
+2014-05-22  Manuel Guesdon <[email protected]>
+       * 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 <[email protected]>
        * EOAdaptors/PostgreSQLAdaptor/PostgreSQLChannel.m:
          fix newValueForDateTypeLengthAttribute

Modified: libs/gdl2/trunk/EOAccess/EOAttribute.h
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/gdl2/trunk/EOAccess/EOAttribute.h?rev=37905&r1=37904&r2=37905&view=diff
==============================================================================
--- libs/gdl2/trunk/EOAccess/EOAttribute.h      (original)
+++ libs/gdl2/trunk/EOAccess/EOAttribute.h      Thu May 22 20:31:05 2014
@@ -96,7 +96,9 @@
     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;

Modified: libs/gdl2/trunk/EOAccess/EOAttribute.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/gdl2/trunk/EOAccess/EOAttribute.m?rev=37905&r1=37904&r2=37905&view=diff
==============================================================================
--- libs/gdl2/trunk/EOAccess/EOAttribute.m      (original)
+++ libs/gdl2/trunk/EOAccess/EOAttribute.m      Thu May 22 20:31:05 2014
@@ -1035,6 +1035,7 @@
       [self willChange];
       _flags.isReadOnly = yn;
       [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_readOnly];
+      _flags.isNonUpdateableInitialized = NO;
     }
 }
 
@@ -2211,6 +2212,25 @@
   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
 

Modified: libs/gdl2/trunk/EOAccess/EOAttributePriv.h
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/gdl2/trunk/EOAccess/EOAttributePriv.h?rev=37905&r1=37904&r2=37905&view=diff
==============================================================================
--- libs/gdl2/trunk/EOAccess/EOAttributePriv.h  (original)
+++ libs/gdl2/trunk/EOAccess/EOAttributePriv.h  Thu May 22 20:31:05 2014
@@ -65,6 +65,9 @@
 - (void)_setValuesFromTargetAttribute;
 -(void)_setSourceToDestinationKeyMap:(NSDictionary*)map;
 -(NSDictionary*) _sourceToDestinationKeyMap;
+
+-(BOOL)_isNonUpdateable;
+-(BOOL)_isPrimaryKeyClassProperty;
 @end
 
 @interface EOAttribute (EOAttributePrivate2)

Modified: libs/gdl2/trunk/EOAccess/EODatabaseContext.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/gdl2/trunk/EOAccess/EODatabaseContext.m?rev=37905&r1=37904&r2=37905&view=diff
==============================================================================
--- libs/gdl2/trunk/EOAccess/EODatabaseContext.m        (original)
+++ libs/gdl2/trunk/EOAccess/EODatabaseContext.m        Thu May 22 20:31:05 2014
@@ -712,13 +712,7 @@
        editingContext: (EOEditingContext *)context
            isComplete: (BOOL)isComplete
 {
-  //OK
   EOAccessFaultHandler *handler;
-
-
-
-
-
 
   NSAssert(globalID, @"No globalID");
   NSAssert1([globalID isKindOfClass: [EOKeyGlobalID class]],
@@ -747,7 +741,6 @@
 
   [self _addBatchForGlobalID: (EOKeyGlobalID*)globalID
         fault: object];
-
 
   //TODO: use isComplete
 }
@@ -5496,19 +5489,68 @@
   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
   
@@ -5521,143 +5563,54 @@
              @"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];
-      
-      
-      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<count; h++)
-           {
-           join = [joins objectAtIndex:h];
-           
-           value = [snapshot objectForKey:[[join sourceAttribute]
-           name]];
-           if (value == null)
-           realValue = nil;
-           else
-           realValue = value;
-           
-           [[prop validateValue:&realValue] raise];
-           
-           [row setObject:value
-                      forKey:[[join destinationAttribute]
-           name]];
-           }
-           
-           if (realValue || [prop isMandatory] == YES)
-           {
-           faultGID = [[(EORelationship *)prop destinationEntity]
-           globalIDForRow:row];
-           
-           fault = [context objectForGlobalID:faultGID];
-           
-           if (fault == nil)
-           fault = [context faultForGlobalID:faultGID
-           editingContext:context];
-           }
-           else
-           fault = nil;
-           
-           */
-        }
-      }
-      
-      [object takeStoredValue:relObject
-                       forKey:relName];
-    }
-  };
-  
-  
+    {
+      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];
+         
+         if ([relationship isToMany])
+           {
+             EOGlobalID *gid = [entity globalIDForRow: row];
+             
+             relObject = [self arrayFaultWithSourceGlobalID: gid
+                               relationshipName: relName
+                               editingContext: context];
+           }
+         else
+           {
+             relObject=[self _objectFaultWithSnapshot: row
+                             relationship: relationship
+                             editingContext: context];
+           }
+         
+         [object takeStoredValue:relObject
+                 forKey:relName];
+       }
+    }
 }
 
 - (void)forgetAllLocks
@@ -5745,11 +5698,19 @@
 - (EODatabaseChannel*) _obtainOpenChannel
 {
   EODatabaseChannel *channel = [self availableChannel];
-
-  if (![self _openChannelWithLoginPanel: channel])
-    {
-      NSEmitTODO();
-      [self notImplemented: _cmd];//TODO
+  if (channel==nil)
+    {
+      [NSException raise: @"NSIllegalStateException"
+                  format:@"%s: no database channel is available",
+                  __PRETTY_FUNCTION__];
+
+    }
+  else if (![self _openChannelWithLoginPanel: channel])
+    {
+      [NSException raise: @"NSIllegalStateException"
+                  format:@"%s: failed to open database channel",
+                  __PRETTY_FUNCTION__];
+
     }
 
   return channel;
@@ -5757,21 +5718,69 @@
 
 - (BOOL) _openChannelWithLoginPanel: (EODatabaseChannel*)databaseChannel
 {
-  // veridy: LoginPanel ???
+  BOOL result=NO;
   EOAdaptorChannel *adaptorChannel = [databaseChannel adaptorChannel];
 
-  if (![adaptorChannel isOpen]) //??
-    {
-      [adaptorChannel openChannel];
-    }
-
-  return [adaptorChannel isOpen];
+  if ([adaptorChannel isOpen])
+    result=YES;
+  else
+    {
+      NSException* exception=nil;
+      NS_DURING
+       {
+         [adaptorChannel openChannel];
+        }
+      NS_HANDLER
+       {
+         if (![[localException name] 
isEqualToString:EOGeneralAdaptorException])
+           [localException raise];
+         else
+           NSLog(@"%@",localException);
+       }
+      NS_ENDHANDLER;
+
+      if ([adaptorChannel isOpen])
+       result=YES;
+      else
+       [exception raise];
+    }
+  return result;
 }
 
 - (void) _forceDisconnect
-{ // TODO
-  NSEmitTODO();
-  [self notImplemented: _cmd];
+{ 
+  EOAdaptorContext* adaptorContext = [self adaptorContext];
+  NSArray* channels = [adaptorContext channels];
+  NSArray* registeredChannels = [self registeredChannels];
+
+  int i = 0;
+  int c=[channels count];
+  for(i=0;i<c;i++)
+    {
+      NS_DURING
+       {
+         [[channels objectAtIndex:i] closeChannel];
+       }
+      NS_HANDLER
+       {
+         NSLog(@"%@",localException);
+       }
+      NS_ENDHANDLER;
+    }
+
+  c=[registeredChannels count];
+  for(i=0;i<c;i++)
+    {
+      NS_DURING
+       {
+         [self unregisterChannel:[registeredChannels objectAtIndex:i]];
+       }
+      NS_HANDLER
+       {
+         NSLog(@"%@",localException);
+       }
+      NS_ENDHANDLER;
+    }
 }
 
 @end
@@ -5795,25 +5804,63 @@
 
 - (void) _verifyNoChangesToReadonlyEntity: (EODatabaseOperation*)dbOpe
 {
-  //TODO
-  EOEntity *entity = nil;
-
-
-
-  entity = [dbOpe entity];
-
-
-
+  EOEntity* entity = [dbOpe entity];
   if ([entity isReadOnly])
     {
-      //?? exception I presume
-    }
-  else
-    {
-      [dbOpe databaseOperator]; //SoWhat
-    }
-
-
+      switch([dbOpe databaseOperator])
+       {
+       case EOAdaptorInsertOperator:
+         [NSException raise: @"NSIllegalStateException"
+                      format:@"cannot insert object: %@ that corresponds to 
read-only entity: %@ in databaseContext %@",
+                      [dbOpe object],
+                      [entity name],
+                      self];
+         break;
+       case EOAdaptorDeleteOperator:
+         [NSException raise: @"NSIllegalStateException"
+                      format:@"cannot insert delete: %@ that corresponds to 
read-only entity: %@ in databaseContext %@",
+                      [dbOpe object],
+                      [entity name],
+                      self];
+         break;
+       case EOAdaptorUpdateOperator:
+         if (![[dbOpe dbSnapshot] isEqual:[dbOpe newRow]])
+           {
+             [NSException raise: @"NSIllegalStateException"
+                          format:@"cannot update '%@' keys on object %@ that 
corresponds to read-only entity: %@ in databaseContext %@",
+                          [[dbOpe rowDiffsForAttributes:[entity attributes]] 
allKeys],
+                          [dbOpe object],
+                          [entity name],
+                          self];
+           }
+         break;
+       }
+    }
+  else if ([dbOpe databaseOperator] == EOAdaptorUpdateOperator
+          && [entity hasNonUpdateableAttributes])
+    {
+      NSArray* dbSnapshotKeys = [entity dbSnapshotKeys];
+      NSDictionary* dbSnapshot = [dbOpe dbSnapshot];
+      NSMutableDictionary* newRow = [dbOpe newRow];
+      int i=0;
+      int c=[dbSnapshotKeys count];
+      for(i=0;i<c;i++)
+       {
+         NSString* key = [dbSnapshotKeys objectAtIndex:i];
+         EOAttribute* attribute = [entity attributeNamed:key];
+         if ([attribute _isNonUpdateable]
+             && ![[dbSnapshot objectForKey:key] isEqual:[newRow 
objectForKey:key]])
+           {
+             [NSException raise: @"NSIllegalStateException"
+                          format:@"cannot update %@ '%@' on object: %@ that 
corresponds to read-onlywof entity: %@ in databaseContext %@",
+                          ([attribute isReadOnly] ? @"read-only key" : 
@"primary-key"),
+                          key,
+                          [dbOpe object],
+                          [entity name],
+                          self];
+           }
+       }
+    }
 }
 
 - (void) _cleanUpAfterSave


_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs

Reply via email to