|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.