Annotation of Examples/EnterpriseObjects/ManyToMany/Projects_sybase/Projects.m, revision 1.1.1.1

1.1       root        1: #import "UniqueKey.h"
                      2: #import "Projects.h"
                      3: 
                      4: 
                      5: static BOOL _Debug = YES;
                      6: 
                      7: @implementation Projects
                      8: 
                      9: /******************************************************************************
                     10: * Create two instances of the UniqueKey object to grab blocks of <count> keys for
                     11: * our use during inserts.  The count is set low so you can see the SQL reserve
                     12: * blocks of keys.  Up the count to something larger for it to be of use.
                     13: *
                     14: * The login information (connection dictionary) in the model has been blanked out,
                     15: * since you may elect to have the tables in some database other than PEOPLE, so we
                     16: * elect to run a login panel.  Once the login is complete we can get the
                     17: * connection dictionary from the adaptor and use that information to allow
                     18: * UniqueKey to login and create its separate connection for key reservation.
                     19: *
                     20: * Note the content views of the employee and project boxes and paste in the
                     21: * default content.
                     22: ******************************************************************************/
                     23: - appDidInit:sender
                     24: {
                     25:     EOAdaptor *eoAdaptor;
                     26: 
                     27:     dbChannel = [[(id)[employeeController dataSource] databaseChannel] retain];
                     28:     dbContext = [[dbChannel databaseContext] retain];
                     29:     
                     30:     if(_Debug) [[dbChannel adaptorChannel] setDelegate:self];
                     31:     
                     32:     projectEntity    = [[(id)[projectController dataSource] entity] retain];
                     33:     employeeEntity   = [[(id)[employeeController dataSource] entity] retain];
                     34:     empProjectEntity = [[(id)[projectEntity relationshipNamed:@"toEmpProjects"] destinationEntity] retain];
                     35:        empProjectDDS   = [[EODatabaseDataSource alloc] initWithDatabaseChannel: dbChannel
                     36:                                                entityNamed: [empProjectEntity name]]; 
                     37:     eoAdaptor = [[[dbChannel adaptorChannel] adaptorContext] adaptor];
                     38:     if(![eoAdaptor runLoginPanelAndValidateConnectionDictionary]) [NXApp terminate:self];
                     39:     [UniqueKey setConnectionDictionary:[eoAdaptor connectionDictionary]];
                     40:     
                     41:     projectUniqueKey  = [[[UniqueKey alloc] initWithEntity:projectEntity  count:5] retain];
                     42:     employeeUniqueKey = [[[UniqueKey alloc] initWithEntity:employeeEntity count:5] retain];
                     43:     if(!projectUniqueKey || !employeeUniqueKey) [NXApp terminate:self];
                     44: 
                     45:     [self setFetchOrderFor:projectController                with:@"ProjectName" order:EOAscendingOrder];
                     46:     [self setFetchOrderFor:addProjectsForEmployeeController with:@"ProjectName" order:EOAscendingOrder];
                     47:     [self setFetchOrderFor:employeeController               with:@"LastName"    order:EOAscendingOrder];
                     48:     [self setFetchOrderFor:addEmployeesOnProjectController  with:@"LastName"    order:EOAscendingOrder];
                     49:     
                     50:     [addProjectsForEmployeeController setSelectsFirstObjectAfterFetch:NO];
                     51:     [addEmployeesOnProjectController  setSelectsFirstObjectAfterFetch:NO];
                     52: 
                     53:     inspectorWindow=[swapBox window];
                     54:     [self projectInspector:nil];               // swap in the project content view
                     55:     [[inspectorWindow center] makeKeyAndOrderFront:nil];
                     56:     return self;
                     57: }
                     58: 
                     59: 
                     60: /******************************************************************************
                     61: * Set a controller's data source to fetch sorted by a given attribute name
                     62: * and order.
                     63: ******************************************************************************/
                     64: - setFetchOrderFor:(EOController*)controller with:(NSString*)attributeName order:(EOOrdering)order
                     65: {
                     66:     id         dataSource = [controller dataSource];
                     67:     id         attribute  = [[dataSource entity] attributeNamed:attributeName];
                     68:     NSArray    *orderArray;
                     69:     
                     70:     orderArray = [NSArray arrayWithObject:
                     71:        [EOAttributeOrdering attributeOrderingWithAttribute:attribute ordering:order]];
                     72:     [dataSource setFetchOrder:orderArray];
                     73:     return self;
                     74: }
                     75: 
                     76: 
                     77: /******************************************************************************
                     78: * Accept the users selection for either the Employee or Project inspector.  Swap
                     79: * in the appropriate content view.  
                     80: ******************************************************************************/
                     81: - employeeInspector:sender
                     82: {
                     83:     [inspectorWindow disableFlushWindow];
                     84:     [swapBox setContentView:[employeeBox contentView]];
                     85:     [employeeController fetch];
                     86:     [swapBox display];
                     87:     [[inspectorWindow reenableFlushWindow] flushWindowIfNeeded];
                     88:     return self;
                     89: }
                     90: 
                     91: - projectInspector:sender
                     92: {
                     93:     [inspectorWindow disableFlushWindow];
                     94:     [swapBox setContentView:[projectBox contentView]];
                     95:     [projectController fetch];
                     96:     [swapBox display];
                     97:     [[inspectorWindow reenableFlushWindow] flushWindowIfNeeded];
                     98:     return self;
                     99: }
                    100: 
                    101: 
                    102: /******************************************************************************
                    103: * Utility to create an intermediate table empProject EOGenericRecord.
                    104: ******************************************************************************/
                    105: - createEmpProject:(NSNumber*)empId:(NSNumber*)projectId
                    106: {
                    107:     EOGenericRecord *empProject = [empProjectDDS createObject];
                    108:     
                    109:     [empProject setObject:projectId forKey:@"ProjectId"];
                    110:     [empProject setObject:empId forKey:@"EmpId"];
                    111:     return empProject;
                    112: }
                    113: 
                    114: 
                    115: /******************************************************************************
                    116: * Bring up the add employee selection panel and start a modal session.  Construct 
                    117: * and 'otherEmployees' qualifier to select employees that do not already appear
                    118: * in the EmployeesOnProject detail view.
                    119: ******************************************************************************/
                    120: - addEmployeesOnProject:sender
                    121: {
                    122:     EOGenericRecord    *project   = [(id)[employeesOnProjectController dataSource] masterObject];
                    123:     NSNumber           *projectId = [project objectForKey:@"ProjectId"];
                    124:     EOQualifier                *otherEmployees;
                    125:     NSString           *qualifierString;
                    126:     
                    127:     qualifierString = [NSString stringWithFormat:
                    128:        @"EmpId not in (SELECT z1.EMP_ID FROM EMPLOYEE z1, EMP_PROJECT z2 "
                    129:        @"WHERE z1.EMP_ID = z2.EMP_ID AND z2.PROJECT_ID = %@)",projectId];
                    130:        
                    131:     otherEmployees = [[[EOQualifier alloc]
                    132:        initWithEntity:employeeEntity qualifierFormat:qualifierString] autorelease];
                    133:        
                    134:     [(id)[addEmployeesOnProjectController dataSource] setQualifier:otherEmployees];
                    135:     [addEmployeesOnProjectController clearSelection];
                    136:     [addEmployeesOnProjectController fetch];
                    137:     [[addEmployeesPanel center] makeKeyAndOrderFront:nil];
                    138:     [NXApp runModalFor:addEmployeesPanel];
                    139:     [addEmployeesPanel orderOut:self];
                    140:     [projectController fetch];
                    141:     return self;
                    142: }
                    143: 
                    144: - addEmployeesOnProjectOK:sender
                    145: {
                    146:        NSArray                 *eArray;
                    147:        NSEnumerator    *eEnumerator;
                    148:        EOGenericRecord *project;
                    149:        NSNumber                *projectId;
                    150:        EOGenericRecord *employee;
                    151:     EOGenericRecord    *empProject;
                    152: 
                    153:     eArray             = [addEmployeesOnProjectController selectedObjects];
                    154:     eEnumerator        = [eArray objectEnumerator];
                    155:     project    = [(id)[employeesOnProjectController dataSource] masterObject];
                    156:     projectId  = [project objectForKey:@"ProjectId"];
                    157:     [dbContext beginTransaction];
                    158:     while((employee = [eEnumerator nextObject]) != nil) {
                    159:        empProject = [self createEmpProject:[employee objectForKey:@"EmpId"]:projectId];        
                    160:        [dbChannel insertObject:empProject];
                    161:     }
                    162:     [dbContext commitTransaction];
                    163:     [NXApp stopModal];
                    164:     return self;
                    165: }
                    166: 
                    167: 
                    168: /******************************************************************************
                    169: * Bring up the add project selection panel and start a modal session.  Construct 
                    170: * and 'otherProjects' qualifier to select project that do not already appear
                    171: * in the ProjectsForEmployee detail view.  We use an imbedded select here with
                    172: * '.' chars in the qualifier string.  These names will not be converted, since they
                    173: * contain '.' chars, so we have the ability to write qualifiers that
                    174: * reference external names it we like.
                    175: ******************************************************************************/
                    176: - addProjectsForEmployee:sender
                    177: {
                    178:     EOGenericRecord    *employee  = [(id)[projectsForEmployeeController dataSource] masterObject];
                    179:     NSNumber           *empId     = [employee objectForKey:@"EmpId"];
                    180:     EOQualifier                *otherProjects;
                    181:     NSString           *qualifierString;
                    182:     
                    183:     qualifierString = [NSString stringWithFormat:
                    184:        @"ProjectId not in (SELECT z1.PROJECT_ID FROM PROJECT z1, EMP_PROJECT z2 "
                    185:        @"WHERE z1.PROJECT_ID = z2.PROJECT_ID AND z2.EMP_ID = %@)",empId];
                    186: 
                    187:     otherProjects = [[[EOQualifier alloc]
                    188:        initWithEntity:projectEntity qualifierFormat:qualifierString] autorelease];
                    189: 
                    190:     [(id)[addProjectsForEmployeeController dataSource] setQualifier:otherProjects];
                    191:     [addProjectsForEmployeeController clearSelection];
                    192:     [addProjectsForEmployeeController fetch];
                    193:     [[addProjectsPanel center] makeKeyAndOrderFront:nil];
                    194:     [NXApp runModalFor:addProjectsPanel];
                    195:     [addProjectsPanel orderOut:self];
                    196:     [employeeController fetch];
                    197:     return self;
                    198: }
                    199: 
                    200: - addProjectsForEmployeeOK:sender
                    201: {
                    202:     NSArray                    *pArray;
                    203:     NSEnumerator       *pEnumerator;
                    204:     EOGenericRecord    *employee;
                    205:     NSNumber           *empId;
                    206:     EOGenericRecord    *project;
                    207:     EOGenericRecord    *empProject;
                    208: 
                    209:        pArray          = [addProjectsForEmployeeController selectedObjects];
                    210:     pEnumerator        = [pArray objectEnumerator];
                    211:     employee   = [(id)[projectsForEmployeeController dataSource] masterObject];
                    212:     empId              = [employee objectForKey:@"EmpId"];
                    213: 
                    214:     [dbContext beginTransaction];
                    215:     while((project = [pEnumerator nextObject]) != nil) {
                    216:        empProject = [self createEmpProject:empId:[project objectForKey:@"ProjectId"]];
                    217:        [dbChannel insertObject:empProject];
                    218:     }
                    219:     [dbContext commitTransaction];
                    220:     [NXApp stopModal];
                    221:     return self;
                    222: }
                    223: 
                    224: 
                    225: /******************************************************************************
                    226: * Delete the intermediate table entries for the selected employee.  To do this we
                    227: * get the selected master object and ask it for the enumerator of empProject
                    228: * objects.  Since each empProject object can be asked objectForKey:@"Employee", we
                    229: * see if that empProject object has a corresponding employee in the selected employee
                    230: * array (eArray).  We choose to use the method indexOfObjectIdenticalTo: to do the
                    231: * check since it uses pointer equality.  This works because object uniquing is
                    232: * enabled by default.
                    233: ******************************************************************************/
                    234: - removeSelectedEmployeesOnProject:sender
                    235: {
                    236:     NSArray            *eArray;
                    237:     EOGenericRecord    *project;
                    238:     NSEnumerator       *epEnumerator;
                    239:     EOGenericRecord    *empProject;
                    240: 
                    241:        eArray                  = [employeesOnProjectController selectedObjects];
                    242:     project                    = [(id)[employeesOnProjectController dataSource] masterObject];
                    243:     epEnumerator       = [[project objectForKey:@"toEmpProjects"] objectEnumerator];
                    244: 
                    245:     [dbContext beginTransaction];
                    246:     while((empProject=[epEnumerator nextObject]) != nil)
                    247:        if([eArray indexOfObjectIdenticalTo:[empProject objectForKey:@"toEmployee"]]!=NSNotFound)
                    248:                [dbChannel deleteObject:empProject];
                    249:     [dbContext commitTransaction];
                    250:     [projectController fetch];
                    251:     return self;
                    252: }
                    253: 
                    254: 
                    255: /******************************************************************************
                    256: * Delete the intermediate table entries for the selected project.  To do this we
                    257: * get the selected master object and ask it for the enumerator of empProject
                    258: * objects.  Since each empProject object can be asked objectForKey:@"Project", we
                    259: * see if that empProject object has a corresponding project in the selected project
                    260: * array (pArray).  We choose to use the method indexOfObjectIdenticalTo: to do the
                    261: * check since it uses pointer equality.  This works because object uniquing is
                    262: * enabled by default.
                    263: ******************************************************************************/
                    264: - removeSelectedProjectsForEmployee:sender
                    265: {
                    266:     NSArray            *pArray;
                    267:     EOGenericRecord    *employee;
                    268:     NSEnumerator       *epEnumerator;
                    269:     EOGenericRecord    *empProject;
                    270:     
                    271:        pArray                  = [projectsForEmployeeController selectedObjects];
                    272:     employee           = [(id)[projectsForEmployeeController dataSource] masterObject];
                    273:     epEnumerator       = [[employee objectForKey:@"toEmpProjects"] objectEnumerator];
                    274: 
                    275:     [dbContext beginTransaction];
                    276:     while((empProject=[epEnumerator nextObject]) != nil)
                    277:        if([pArray indexOfObjectIdenticalTo:[empProject objectForKey:@"toProject"]]!=NSNotFound)
                    278:                [dbChannel deleteObject:empProject];
                    279:     [dbContext commitTransaction];
                    280:     [employeeController fetch];
                    281:     return self;
                    282: }
                    283: 
                    284: 
                    285: /******************************************************************************
                    286: * Generate unique keys for the new object.  Use the instance of UniqueKey
                    287: * to dole out a key from its internal buffer.  The UniqueKey object has its
                    288: * own channel to the DB which it uses to allocate blocks of keys.
                    289: ******************************************************************************/
                    290: - (BOOL)controller:(EOController *)controller willInsertObject:object atIndex: (unsigned)newIndex
                    291: {
                    292:     if(controller==employeeController) {
                    293:        NSArray *emptyArray1 = [[[NSArray alloc] init] autorelease];
                    294:        NSArray *emptyArray2 = [[[NSArray alloc] init] autorelease];
                    295:        NSNumber *empId      = [NSNumber numberWithInt:[employeeUniqueKey nextKey]];
                    296:        
                    297:         [object setObject:empId forKey:@"EmpId"];
                    298:        [object setObject:@"<FirstName>" forKey:@"FirstName"];
                    299:        [object setObject:@"<LastName>" forKey:@"LastName"];
                    300:        [object setObject:@"<Phone>" forKey:@"Phone"];
                    301:        [object setObject:emptyArray1 forKey:@"toEmpProjects"];
                    302:        [object setObject:emptyArray2 forKey:@"toProjects"];
                    303:        return YES;
                    304:     }
                    305:     if(controller==projectController) {
                    306:        NSArray *emptyArray1 = [[[NSArray alloc] init] autorelease];
                    307:        NSArray *emptyArray2 = [[[NSArray alloc] init] autorelease];
                    308:        NSNumber *projectId  = [NSNumber numberWithInt:[projectUniqueKey nextKey]];
                    309:        
                    310:         [object setObject:projectId forKey:@"ProjectId"];
                    311:        [object setObject:@"<ProjectName>" forKey:@"ProjectName"];
                    312:        [object setObject:emptyArray1 forKey:@"toEmpProjects"];
                    313:        [object setObject:emptyArray2 forKey:@"toEmployees"];
                    314:        return YES;
                    315:     }
                    316:     return NO;
                    317: }
                    318: 
                    319: 
                    320: /******************************************************************************
                    321: * When a project or employee is deleted, make sure we delete the entry in the
                    322: * empProject intermediate table.  Both the project and employee entities have
                    323: * a toEmpProjects relationship which we can use to delete the intermediate
                    324: * table records.
                    325: ******************************************************************************/
                    326: - (BOOL)controller:controller willDeleteObject:object
                    327: {
                    328:     NSArray            *epArray;
                    329:     NSEnumerator       *epEnumerator;
                    330:     EOGenericRecord    *empProject;
                    331:        
                    332:     // The employee and project entities have a toEmpProjects
                    333:     // relationship to the intermediate table
                    334:     if(controller==projectController ||
                    335:        controller==employeeController) {
                    336:        [dbContext beginTransaction];
                    337:        epArray=[object objectForKey:@"toEmpProjects"];
                    338:        epEnumerator=[epArray objectEnumerator];
                    339:        while((empProject = [epEnumerator nextObject]) != nil)
                    340:                [dbChannel deleteObject:empProject];
                    341:        [dbContext commitTransaction];
                    342:     }
                    343:     return YES;
                    344: }
                    345: 
                    346: 
                    347: /******************************************************************************
                    348: * Echo SQL when debug is enabled.
                    349: ******************************************************************************/
                    350: - (EODelegateResponse)adaptorChannel:channel willEvaluateExpression:(NSMutableString *)expression
                    351: {
                    352:     NSLog(expression);
                    353:     return EODelegateApproves;
                    354: }
                    355: 
                    356: - (void)dealloc
                    357: {
                    358:        [dbContext  release];
                    359:        [dbChannel  release];
                    360:        [projectEntity  release];
                    361:        [employeeEntity release];
                    362:        [empProjectEntity  release];
                    363:        [projectUniqueKey  release];
                    364:        [employeeUniqueKey  release];
                    365:        [super dealloc];
                    366:    
                    367: }
                    368: 
                    369: @end

unix.superglobalmegacorp.com

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