Annotation of Examples/EnterpriseObjects/MasteringDetails/EOFExtensions.subproj/RelationshipKeySetter.m, revision 1.1.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.