Annotation of Examples/EnterpriseObjects/MasteringDetails/EOFExtensions.subproj/ResetRelationships.m, revision 1.1.1.1

1.1       root        1: /* ResetRelationships.m created by cfeder on Thu 15-Dec-1994 */
                      2: 
                      3: #import "ResetRelationships.h"
                      4: #import "ValueForKey.h"
                      5: #import "RelationshipKeySetter.h"
                      6: 
                      7: @implementation EODatabaseChannel (setForeignKey)
                      8: - objectForPrimaryKey:(NSDictionary *)key entity:(EOEntity *)entity
                      9:     // returns existing object instance if there is one, or a fault otherwise
                     10: {
                     11:     EODatabaseContext *context = [self databaseContext];
                     12:     id object = [context objectForPrimaryKey:key entity:entity];
                     13:     if (!object) {
                     14:         object = [EOFault objectFaultWithPrimaryKey:key
                     15:             entity:entity databaseChannel:self zone:[self zone]];
                     16:     }
                     17:     return object;
                     18: }
                     19: 
                     20: - fetchObjectDescribedByQualifier:(EOQualifier *)qualifier
                     21:     // raises if not to-one.
                     22: {
                     23:     BOOL success, autoTransaction = NO;
                     24:     EODatabaseContext *context = [self databaseContext];
                     25:     NSZone *zone = [self zone];
                     26:     id object;
                     27: 
                     28:     if (![context transactionNestingLevel]) {
                     29:         [context beginTransaction];
                     30:         autoTransaction = YES;
                     31:     }
                     32: 
                     33:     success = [self selectObjectsDescribedByQualifier:qualifier
                     34:         fetchOrder:nil];
                     35:     object = [self fetchWithZone:zone];
                     36:     if (!success || !object || [self fetchWithZone:zone]) {
                     37:         [self cancelFetch];
                     38:         [NSException raise:NSInternalInconsistencyException format:@"%s: error fetching object", sel_getName(_cmd)];
                     39:     }
                     40: 
                     41:     if (autoTransaction) [context commitTransaction];
                     42:     return object;
                     43: }
                     44: 
                     45: - destinationObjectForRelationship:relationship sourceObject:sourceObject
                     46:     // look up an exising fault, or create a new one
                     47: {
                     48:     id object;
                     49:     // EODatabase *database = [[self databaseContext] database];
                     50: 
                     51:     if ([relationship isToMany]) {
                     52:         // EOF doesn't unique faults, so we just have to construct a new one
                     53:         EOQualifier *qual = [EOQualifier qualifierForObject:sourceObject relationship:relationship];
                     54:         object = [EOFault arrayFaultWithQualifier:qual
                     55:             fetchOrder:nil databaseChannel:self zone:[self zone]];
                     56:     } else {
                     57:         // see if this is already in the uniquing table
                     58:         if ([relationship isFlattened]) {
                     59:             EOQualifier *qual = [EOQualifier qualifierForObject:sourceObject relationship:relationship];
                     60: 
                     61:             // should fetch object from channel with qualifier
                     62:             object = [self fetchObjectDescribedByQualifier:qual];
                     63:         } else {
                     64:             // for to-ones, the primary key is always the destination of the
                     65:             // relationship
                     66:             NSDictionary *pk = [relationship destinationValuesFromSourceObject:sourceObject];
                     67:             object = [self objectForPrimaryKey:pk entity:[relationship destinationEntity]];
                     68:         }
                     69:     }
                     70:     return object;
                     71: }
                     72: 
                     73: - (void)updateRelationshipsInObject:object forModifiedAttributes:(NSArray *)attributes
                     74:    // After the values in object corresponding to the EOAttributes
                     75:    // in the "attributes" array have been update (perhaps with 
                     76:    // takeValuesFromDictionary) this method can be called to update any
                     77:    // corresponding relationship properties.  So, if a foreign dept_id
                     78:    // attribute way modified in a employee object, this would attempt to
                     79:    // reset the "toDepartment" property to point at the corresponding
                     80:    // department object.
                     81: {
                     82:     // We should apply some caching here to make this fast.  I.e. map directly
                     83:     // from attribute to list of class property relationships that this participates in.
                     84:     // For now we'll just be simple and slow.
                     85:     NSMutableArray *affectedRelationships = [NSMutableArray array];
                     86:     EOModel *model = [[[[self databaseContext] database] adaptor] model];
                     87:     EOEntity *entity = [model entityForObject:object];
                     88:     NSArray *classProperties = [entity classProperties];
                     89:     NSArray *relationships = [entity relationships];
                     90:     int i,count = [relationships count];
                     91: 
                     92:     for(i=0; i<count; i++) {
                     93:         EORelationship *relationship = [relationships objectAtIndex:i];
                     94: 
                     95:         if ([classProperties indexOfObjectIdenticalTo:relationship] != NSNotFound) {
                     96:             NSArray *joins = [relationship joins];
                     97:             int j, jcount = [joins count];
                     98: 
                     99:             for (j = 0; j < jcount; j++) {
                    100:                 EOJoin *join = [joins objectAtIndex:j];
                    101:                 if ([attributes indexOfObjectIdenticalTo:[join sourceAttribute]] != NSNotFound) {
                    102:                     [affectedRelationships addObject:relationship];
                    103:                     break;
                    104:                 }
                    105:             }
                    106:         }
                    107:     }
                    108: 
                    109:     // We now have a list of affected relationships that we need to retarget
                    110:     {
                    111:         count = [affectedRelationships count];
                    112:         for(i=0; i<count; i++) {
                    113:             EORelationship *relationship = [relationships objectAtIndex:i];
                    114:             id dest = [self destinationObjectForRelationship:relationship sourceObject:object];
                    115:             [object takeValue:dest forKey:[relationship name]];
                    116:         }
                    117:     }
                    118: }
                    119: @end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.