Annotation of Examples/EnterpriseObjects/MasteringDetails/EOFExtensions.subproj/RelationshipKeySetter.m, revision 1.1

1.1     ! root        1: /* RelationshipKeySetter.m created by cfeder on Tue 08-Nov-1994 */
        !             2: 
        !             3: #import "RelationshipKeySetter.h"
        !             4: #import "ValueForKey.h"
        !             5: #import <objc/objc-runtime.h>
        !             6: 
        !             7: @implementation EOEntity (attrsNamed)
        !             8: - attributesNamed:(NSArray *)names
        !             9: {
        !            10:     int i, count = [names count];
        !            11:     NSMutableArray *result = [NSMutableArray arrayWithCapacity:count];
        !            12:     for(i=0; i<count; i++) {
        !            13:         EOAttribute *attr = [self attributeNamed:[names objectAtIndex:i]];
        !            14:         if (attr)
        !            15:             [result addObject:attr];
        !            16:     }
        !            17:     return result;
        !            18: }
        !            19: 
        !            20: - createObject
        !            21: {
        !            22:     id eo = nil;
        !            23:     const char *className  = [self className];
        !            24:     Class eoClass = objc_lookUpClass (className);
        !            25: 
        !            26:     if (!eoClass) eoClass = [EOGenericRecord class];
        !            27: 
        !            28:     if (eoClass) {
        !            29:         eo = [eoClass allocWithZone:[self zone]];
        !            30:         if ([eo respondsToSelector:@selector(initWithPrimaryKey:entity:)])
        !            31:             eo = [eo initWithPrimaryKey:nil entity:self];
        !            32:         else
        !            33:             [eo init];
        !            34:     }
        !            35:     return [eo autorelease];
        !            36: }
        !            37: @end
        !            38: 
        !            39: 
        !            40: @implementation EORelationship (setPropsInDestObject)
        !            41: - (NSArray *)sourceKeys
        !            42: {
        !            43:     EORelationship *sourceRelationship = [self isFlattened]
        !            44:         ? [[self componentRelationships] objectAtIndex:0] : self;
        !            45:     NSArray *joins = [sourceRelationship joins];
        !            46:     int i, count = [joins count];
        !            47:     NSMutableArray *results = [NSMutableArray arrayWithCapacity:count];
        !            48: 
        !            49:     for (i = 0; i < count; i++) {
        !            50:         EOJoin *join = [joins objectAtIndex:i];
        !            51:         [results addObject:[[join sourceAttribute] name]];
        !            52:     }
        !            53:     return results;
        !            54: }
        !            55: 
        !            56: - (void)setJoinPropertiesInDestinationObject:destination fromSourceObject:source
        !            57: {
        !            58:     NSArray *joins = [self joins];
        !            59:     int i, count = [joins count];
        !            60: 
        !            61:     for (i = 0; i < count; i++) {
        !            62:         EOJoin *join = [joins objectAtIndex:i];
        !            63:         id val = [(NSObject *)source valueForKey:[[join sourceAttribute] name]];
        !            64:         if (!val) val = [EONull null];
        !            65:         [destination takeValue:val forKey:[[join destinationAttribute] name]];
        !            66:     }
        !            67: }
        !            68: 
        !            69: - (void)setJoinPropertiesInSourceObject:source fromDestinationObject:destination
        !            70: {
        !            71: 
        !            72:     NSArray *joins = [self joins];
        !            73:     int i, count = [joins count];
        !            74: 
        !            75:     for (i = 0; i < count; i++) {
        !            76:         EOJoin *join = [joins objectAtIndex:i];
        !            77:         id val = [(NSObject*)destination valueForKey:[[join destinationAttribute] name]];
        !            78:         if (!val) val = [EONull null];
        !            79:         [source takeValue:val forKey:[[join sourceAttribute] name]];
        !            80:     }
        !            81: }
        !            82: 
        !            83: - (NSDictionary *)destinationValuesFromSourceObject:sourceObject
        !            84: {
        !            85:     NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
        !            86:     [self setJoinPropertiesInDestinationObject:dictionary fromSourceObject:sourceObject];
        !            87:     return dictionary;
        !            88: }
        !            89: 
        !            90: - (BOOL)hasJoinsOnPrimaryKeyOfSourceEntity
        !            91: {
        !            92:     // FIX ME!
        !            93:     // this is not quite right for multi-attribute keys (the ordering may
        !            94:     // cause a false mismatch)
        !            95:     return [[self sourceKeys] isEqual:[[self entity] primaryKeyAttributeNames]];
        !            96: }
        !            97: 
        !            98: - (void)updateMasterObject:master withNewDestinationObject:destination
        !            99:     // For to-one relationships!
        !           100: {
        !           101:     // Decide which way to propagate the attributes based on which side of the
        !           102:     // relationship hooks to a primary key.
        !           103:     if ([self hasJoinsOnPrimaryKeyOfSourceEntity])
        !           104:         [self setJoinPropertiesInDestinationObject:destination fromSourceObject:master];
        !           105:     else
        !           106:         [self setJoinPropertiesInSourceObject:destination fromDestinationObject:master];
        !           107: }
        !           108: 
        !           109: - linkObjectForSourceObject:master destinationObject:destination
        !           110:     // created an intermediate object for many-to-many relationship through
        !           111:     // an intermediate table.  Initializes keys of intermediate object using
        !           112:     // keys from source and destination object
        !           113: {
        !           114:     NSArray *relationships = [self componentRelationships];
        !           115:     EORelationship *sourceToLink = [relationships objectAtIndex:0];
        !           116:     EORelationship *linkToDestination = [relationships objectAtIndex:1];
        !           117:     EOEntity *linkEntity = [sourceToLink destinationEntity];
        !           118:     id link = [linkEntity createObject];
        !           119:     [sourceToLink setJoinPropertiesInDestinationObject:link fromSourceObject:master];
        !           120:     [linkToDestination setJoinPropertiesInSourceObject:link fromDestinationObject:destination];
        !           121:     return link;
        !           122: }
        !           123: 
        !           124: - updateKeysForSourceObject:source destinationObject:destination
        !           125:     // Sets keys on source or destination to maintain consistency for
        !           126:     // the source to now map to destination for this relationship.
        !           127:     // Does not actually assign destination to ivar in source (just messes
        !           128:     // with the keys).
        !           129:     // Returns the modified object (source or destination). In the case of
        !           130:     // a many to many returns a newly created link object.
        !           131:     // The caller is reposible for inserting or updating the returned
        !           132:     // object in the database.
        !           133: {
        !           134:     id modifiedObject = nil;
        !           135:     
        !           136:     if ([self isToMany]) {
        !           137:         // figure out what values we need to snarf from our parents
        !           138:         if ([self isFlattened]) {
        !           139:             // Many to many   create link obj          Delete link   none     to-many
        !           140:             // I'm assuming there's only one link object...
        !           141:             modifiedObject = [self linkObjectForSourceObject:source destinationObject:destination];
        !           142:         } else {
        !           143:             // PK -> FK       D->FK := M->PK           none          none     to-many
        !           144:             [self setJoinPropertiesInDestinationObject:destination fromSourceObject:source];
        !           145:             modifiedObject = destination;
        !           146:         }
        !           147:     } else {
        !           148:         if ([self hasJoinsOnPrimaryKeyOfSourceEntity]) {
        !           149:             // PK -> PK       D->PK := M->PK           None          none     to-one
        !           150:             [self setJoinPropertiesInDestinationObject:destination fromSourceObject:source];
        !           151:             modifiedObject = destination;
        !           152:         } else {
        !           153:             // FK -> PK       M->FK := D->PK           M->FK=NULL    none     to-one
        !           154:             // We need to update the master with a new foreign key.
        !           155:             // send it to the dataSource as well...
        !           156:             [self setJoinPropertiesInSourceObject:source fromDestinationObject:destination];
        !           157:             modifiedObject = source;
        !           158:         }
        !           159:     }
        !           160:     return modifiedObject;
        !           161: }
        !           162: 
        !           163: 
        !           164: - updateKeysForDeleteOfDestinationObject:destination fromSourceObject:source
        !           165:     // Sets keys on source or destination to maintain consistency for
        !           166:     // a delete of the destination from the source.  Returns the object
        !           167:     // modified, or a synthesized link object that must be deleted to
        !           168:     // affect the delete.  The caller is responsible for updating the
        !           169:     // source object, or deleting the destination or link in the database.
        !           170:     //
        !           171:     // This does not actually update destination to ivar in source (just messes
        !           172:     // with the keys).
        !           173: {
        !           174:     id modifiedObject = nil;
        !           175: 
        !           176:     if ([self isToMany]) {
        !           177:         // figure out what values we need to snarf from our parents
        !           178:         if ([self isFlattened]) {
        !           179:             // Many to many   create link obj          Delete link            to-many
        !           180:             // I'm assuming there's only one link object...
        !           181:             modifiedObject = [self linkObjectForSourceObject:source destinationObject:destination];
        !           182:         } else {
        !           183:             // PK -> FK       D->FK := M->PK           Delete D               to-many
        !           184:             // Nil out foreign key in destination
        !           185:             [self setJoinPropertiesInDestinationObject:destination fromSourceObject:nil];
        !           186:             modifiedObject = destination;
        !           187:         }
        !           188:     } else {
        !           189:         if ([self hasJoinsOnPrimaryKeyOfSourceEntity]) {
        !           190:             // PK -> PK       D->PK := M->PK           delete D               to-one
        !           191:             // no use nilling out destinations primary key.  Row must be deleted
        !           192:             modifiedObject = destination;
        !           193:         } else {
        !           194:             // FK -> PK       M->FK := D->PK           M->FK=NULL             to-one
        !           195:             // nil out foreign key in source
        !           196:             [self setJoinPropertiesInSourceObject:source fromDestinationObject:nil];
        !           197:             modifiedObject = source;
        !           198:         }
        !           199:     }
        !           200:     return modifiedObject;
        !           201: }
        !           202: 
        !           203: @end
        !           204: 
        !           205: 

unix.superglobalmegacorp.com

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