home *** CD-ROM | disk | FTP | other *** search
Wrap
/* Controller.m: * You may freely copy, distribute, and reuse the code in this example. * NeXT disclaims any warranty of any kind, expressed or implied, as to its * fitness for any particular use. * * Written by Mai Nguyen, NeXT Developer Support * */ #import <appkit/appkit.h> #import <dbkit/dbkit.h> #import <libc.h> #import "Controller.h" /* Define localized strings */ #define INSTALL_MODEL NXLocalizedString("Please install SybaseDemo.dbmodela into your project directory and restart.", NULL, "Notify user that SybaseDemo.dbmodela must be installed in his project directory.") #define EMPTY_STRING NXLocalizedString("Cannot accept empty string", NULL, "Notify user that empty string input is not valid.") #define INSERT_FAILED NXLocalizedString("Insert operation failed", NULL, "Notify user that insert operation has failed.") static char newAuthorID[100]; @implementation Controller /* Extract the actual database and recordlist from the DBModule UI Object */ -appDidInit:sender { /* Notify the user if the database can't be found */ if (![DBDatabase findDatabaseNamed:"SybaseDemo" connect:YES]) { NXRunAlertPanel(NULL,INSTALL_MODEL, "OK", NULL, NULL); return self; } dbDatabase = [dbModule database]; dbFetchGroup = [dbModule rootFetchGroup]; dbRecordList = [dbFetchGroup recordList]; recordOrder = DB_AscendingOrder; dbQualifier = nil; /* Initialize the retrieval order to be ascending order */ sortProp = [[dbModule entity] propertyNamed:"lastName"]; [dbRecordList addRetrieveOrder:recordOrder for:sortProp]; /* Assign the controller object to be the delegate of dbFetchGroup. * See also the method fetchGroup:didInsertRecordAt: */ [dbFetchGroup setDelegate:self]; /* Assign the record list of the root fetchgroup to be the delegate * of DBBinder. This is a convenient way to make sure that the proper * qualifier will be used at fetch time. * See also the method binderWillSelect: */ [[dbFetchGroup recordList] setBinderDelegate:self]; /* Create a DBValue instance to be used later for accessing data * inside a record list. */ aValue = [[DBValue alloc] init]; [theWindow makeKeyAndOrderFront:nil]; return self; } /* Change the retrieval order for the record list. To be set before pressing * SELECT. */ -changeRetrieveOrder:sender { recordOrder = [sender selectedTag]; return self; } /* Build the DBQualifier before a SELECT operation. Note that you should give * the external names as defined in dbModel for properties. */ - buildSelectQualifier:sender { const char * state; id stateProperty; state = [qualifierField stringValue]; if (!strcmp(state,"")) { dbQualifier = nil; return nil; } else { stateProperty = [[dbModule entity] propertyNamed:"state"]; dbQualifier = [[DBQualifier allocFromZone:[self zone] ] initForEntity:[dbModule entity] fromDescription:"%@ LIKE %s", stateProperty, state]; } return self; } /* This method is called when the SELECT button is pressed. * NOTE: If the qualifier form has a NULL string, the source is set to nil, * which means that ALL records will be fetched. */ - select:sender { id source; [self buildSelectQualifier:nil]; if (!dbQualifier) source = nil; else source = [dbModule entity]; [dbFetchGroup fetchContentsOf:source usingQualifier:dbQualifier]; /* Update the display */ [self display]; return self; } /* This method is called when the INSERT button is pressed. Check for blank * record fields before the actual INSERT. */ - insert:sender { if ([self checkInputRecord:sender]==nil) NXRunAlertPanel(NULL,INSERT_FAILED, "OK", NULL, NULL); else [dbModule insertNewRecord:sender]; [self display]; return self; } /* Try to highlight the newly added row based on the token "newAuthorID". * This method is called everytime the SELECT button is pressed. * If there is no match, the first row is highlighted by default. */ - display { int rowCount, i, row; id socSecProperty; const char *keyValue; row = 0; /* Search for a match only if the ID has meaningful data */ if ( strlen(newAuthorID) > 0 ) { rowCount = [dbTableView rowCount]; socSecProperty = [[dbModule entity] propertyNamed:"authorID"]; for (i= 0; i < rowCount; i++) { [dbRecordList getValue:aValue forProperty:socSecProperty at:i]; keyValue = (const char *)[aValue stringValue]; if (!strcmp(keyValue, newAuthorID)) { row = i; break; } } } [dbFetchGroup setCurrentRecord:row]; [dbTableView display]; return self; } /* DBFetchGroup delegate methods */ /* * This method is called at each SELECT operation. */ - fetchGroupWillFetch:fetchGroup { [dbRecordList addRetrieveOrder:recordOrder for:sortProp]; return self; } /* * This method is called at each INSERT operation. */ - fetchGroup:fetchGroup didInsertRecordAt:(int)index { /* Fill in the record fields before inserting the new record */ [self fillNewRecordAt:index]; return self; } /* * This delegate method is called at each SAVE operation. */ - fetchGroupDidSave:fetchGroup { [self clearData]; return self; } /* * This binder delegate method is called at each SELECT operation so that * the proper qualifier is used. */ - (BOOL)binderWillSelect:aBinder { [aBinder setQualifier:dbQualifier]; return YES; } /* checkInputRecord * Check if any input field is empty. */ - checkInputRecord:sender { int i; const char *inputStr; for ( i = 0; i < 9; i++ ) { inputStr = (const char *)[formMatrix stringValueAt:i]; /* If the string is empty, abort the operation */ if ( inputStr == NULL){ NXRunAlertPanel (NULL,EMPTY_STRING,NULL, NULL, NULL); return nil; } } return self; } /* fillNewRecordAt:(int) index * Method used for INSERT operation * Get the user input from the form cells. */ - fillNewRecordAt:(int)index { const char *inputString; int contractNum; /* set last name */ inputString = (const char *)[formMatrix stringValueAt:0]; [aValue setStringValue:inputString]; [dbRecordList setValue:aValue forProperty:[[dbModule entity] propertyNamed:"lastName"] at:index]; /* set first name */ inputString = (const char *)[formMatrix stringValueAt:1]; [aValue setStringValue:(const char *)inputString]; [dbRecordList setValue: aValue forProperty: [[dbModule entity] propertyNamed:"firstName"] at:index]; /* get the ssn or author id */ inputString = (const char *)[formMatrix stringValueAt:2]; [aValue setStringValue:inputString]; [dbRecordList setValue:aValue forProperty:[[dbModule entity] propertyNamed:"authorID"] at:index]; strcpy( newAuthorID, inputString); /* set address */ inputString = (const char *)[formMatrix stringValueAt:3]; [aValue setStringValue: inputString]; [dbRecordList setValue: aValue forProperty:[[dbModule entity] propertyNamed:"address"] at:index]; /* set city name */ inputString = (const char *)[formMatrix stringValueAt:4]; [aValue setStringValue: inputString]; [dbRecordList setValue: aValue forProperty:[[dbModule entity] propertyNamed:"city"] at:index]; /* set state */ inputString = (const char *)[formMatrix stringValueAt:5]; [aValue setStringValue: inputString]; [dbRecordList setValue: aValue forProperty:[[dbModule entity] propertyNamed:"state"] at:index]; /* set zip code */ inputString = (const char *)[formMatrix stringValueAt:6]; [aValue setStringValue: inputString]; [dbRecordList setValue: aValue forProperty:[[dbModule entity] propertyNamed:"zipCode"] at:index ]; /* set phone number */ inputString = (const char *)[formMatrix stringValueAt:7]; [aValue setStringValue: inputString]; [dbRecordList setValue:aValue forProperty:[[dbModule entity] propertyNamed:"phone"] at:index]; /* set contract number */ contractNum = [formMatrix intValueAt:8]; [aValue setIntValue:contractNum]; [dbRecordList setValue: aValue forProperty:[[dbModule entity] propertyNamed:"contract"] at:index]; return self; } /* Clear the form cells after each SAVE operation to avoid creating * duplicate records. */ - clearData { int i; for (i = 0; i < 9; i++) [formMatrix setStringValue:""at:i]; return self; } @end