Annotation of Examples/DatabaseKit/PubsDemo/Controller.m, revision 1.1.1.1

1.1       root        1: /* Controller.m:
                      2:  * You may freely copy, distribute, and reuse the code in this example.
                      3:  * NeXT disclaims any warranty of any kind, expressed or  implied, as to its
                      4:  * fitness for any particular use.
                      5:  *
                      6:  * Written by Mai Nguyen, NeXT Developer Support
                      7:  *
                      8:  */
                      9: 
                     10: #import <appkit/appkit.h>      
                     11: #import        <dbkit/dbkit.h>
                     12: #import <libc.h>
                     13: #import "Controller.h"
                     14: 
                     15: /* Define localized strings */
                     16: #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.")
                     17: #define EMPTY_STRING NXLocalizedString("Cannot accept empty string", NULL, "Notify user that empty string input is not valid.")
                     18: #define INSERT_FAILED NXLocalizedString("Insert operation failed", NULL, "Notify user that insert operation has failed.")
                     19: 
                     20: static char newAuthorID[100];
                     21: 
                     22: @implementation Controller
                     23: 
                     24: /* Extract the actual database and recordlist from the DBModule UI Object
                     25:  */ 
                     26: -appDidInit:sender
                     27: {
                     28:                /* Notify the user if the database can't be found */
                     29:        if (![DBDatabase findDatabaseNamed:"SybaseDemo" connect:YES]) {
                     30:                NXRunAlertPanel(NULL,INSTALL_MODEL, "OK", NULL, NULL);
                     31:                return self;
                     32:        }       
                     33:        dbDatabase = [dbModule database];
                     34:        dbFetchGroup = [dbModule rootFetchGroup];
                     35:        dbRecordList = [dbFetchGroup recordList];
                     36:        recordOrder = DB_AscendingOrder;
                     37:        dbQualifier = nil;
                     38:        
                     39:                        /* Initialize the retrieval order to be ascending order
                     40:                         */
                     41:        sortProp = [[dbModule entity] propertyNamed:"lastName"];
                     42:                        
                     43:        [dbRecordList addRetrieveOrder:recordOrder for:sortProp];
                     44:                
                     45:                        /* Assign the controller object to be the delegate of dbFetchGroup.
                     46:                         * See also the method fetchGroup:didInsertRecordAt:
                     47:                         */
                     48:        [dbFetchGroup setDelegate:self];
                     49:        
                     50:                        /* Assign the record list of the root fetchgroup to be the delegate
                     51:                         * of DBBinder. This is a convenient way to make sure that the proper
                     52:                         * qualifier will be used at fetch time.
                     53:                         * See also the method binderWillSelect:
                     54:                         */
                     55:        [[dbFetchGroup recordList] setBinderDelegate:self];
                     56:        
                     57:                        /* Create a DBValue instance to be used later for accessing data
                     58:                         * inside a record list.
                     59:                         */
                     60:        aValue = [[DBValue alloc] init];
                     61:        
                     62:        [theWindow makeKeyAndOrderFront:nil];
                     63:        return self;
                     64: }
                     65: 
                     66: /* Change the retrieval order for the record list. To be set before pressing
                     67:  * SELECT.
                     68:  */
                     69: -changeRetrieveOrder:sender
                     70: {
                     71:        recordOrder = [sender selectedTag];
                     72:        return self;
                     73: }
                     74: 
                     75: /* Build the DBQualifier before a SELECT operation. Note that you should give
                     76:  * the external names as defined in dbModel for properties.
                     77:  */
                     78: - buildSelectQualifier:sender
                     79: {
                     80:        const char * state;
                     81:        id stateProperty;
                     82:        
                     83:        state = [qualifierField stringValue];
                     84:        if (!strcmp(state,"")) {
                     85:                dbQualifier = nil;
                     86:                return nil;
                     87:        }
                     88:        else {
                     89:        stateProperty = [[dbModule entity] propertyNamed:"state"];
                     90:        dbQualifier = [[DBQualifier allocFromZone:[self zone] ] 
                     91:                initForEntity:[dbModule entity]
                     92:                fromDescription:"%@ LIKE %s", stateProperty, state];
                     93:        }
                     94:        return self;
                     95: }
                     96: 
                     97: /* This method is called when the SELECT button is pressed.
                     98:  * NOTE: If the qualifier form has a NULL string, the source is set to nil,
                     99:  * which means that ALL records will be fetched. 
                    100:  */
                    101: - select:sender
                    102: {
                    103:        id      source;
                    104: 
                    105:        [self buildSelectQualifier:nil];        
                    106:        if (!dbQualifier)
                    107:                source = nil;
                    108:        else
                    109:                source = [dbModule entity];
                    110:                
                    111:        [dbFetchGroup fetchContentsOf:source usingQualifier:dbQualifier];
                    112:        
                    113:                /* Update the display */
                    114:        [self display];
                    115:        return self;
                    116: }
                    117: 
                    118: /* This method is called when the INSERT button is pressed. Check for blank
                    119:  * record fields before the actual INSERT.
                    120:  */
                    121: - insert:sender
                    122: {
                    123:        if ([self checkInputRecord:sender]==nil)
                    124:                NXRunAlertPanel(NULL,INSERT_FAILED, "OK", NULL, NULL);
                    125:        else
                    126:                [dbModule insertNewRecord:sender];
                    127:        [self display];
                    128:        return self;
                    129: }
                    130:        
                    131: /* Try to highlight the newly added row based on the token "newAuthorID".
                    132:  * This method is called everytime the SELECT button is pressed.
                    133:  * If there is no match, the first row is highlighted by default.
                    134:  */
                    135: - display
                    136: {
                    137:        int rowCount, i, row;
                    138:        id socSecProperty;
                    139:        const char *keyValue;
                    140:        
                    141:        row = 0;
                    142:                /* Search for a match only if the ID has meaningful data */
                    143:        if ( strlen(newAuthorID) > 0 ) {
                    144:                rowCount = [dbTableView rowCount];
                    145:                socSecProperty = [[dbModule entity] propertyNamed:"authorID"];
                    146:                for (i= 0; i < rowCount; i++) {
                    147:                        [dbRecordList getValue:aValue forProperty:socSecProperty at:i];
                    148:                        keyValue = (const char *)[aValue stringValue];
                    149:                        if (!strcmp(keyValue, newAuthorID)) {
                    150:                                row = i;
                    151:                                break; }
                    152:                }
                    153:        }
                    154:        [dbFetchGroup setCurrentRecord:row];
                    155:        [dbTableView display];
                    156:        return self;
                    157: }
                    158: 
                    159: 
                    160: 
                    161: /* DBFetchGroup delegate methods */
                    162: 
                    163: /*
                    164:  * This method is called at each SELECT operation.
                    165:  */
                    166: - fetchGroupWillFetch:fetchGroup
                    167: {
                    168:        [dbRecordList addRetrieveOrder:recordOrder for:sortProp];
                    169:        return self;
                    170: }
                    171: 
                    172: /*
                    173:  * This method is called at each INSERT operation.
                    174:  */
                    175: 
                    176: - fetchGroup:fetchGroup didInsertRecordAt:(int)index
                    177: {
                    178:                /* Fill in the record fields before inserting the new record */
                    179:        [self fillNewRecordAt:index];
                    180:        return self;
                    181: }
                    182: 
                    183: 
                    184: /* 
                    185:  * This delegate method is called at each SAVE operation.
                    186:  */
                    187: - fetchGroupDidSave:fetchGroup
                    188: {
                    189:        [self clearData];
                    190:        return self;
                    191: }
                    192: 
                    193: /* 
                    194:  * This binder delegate method is called at each SELECT operation so that 
                    195:  * the proper qualifier is used.
                    196:  */
                    197:  
                    198: - (BOOL)binderWillSelect:aBinder
                    199: {
                    200:   [aBinder setQualifier:dbQualifier];
                    201:   return YES;
                    202: }
                    203: 
                    204: /* checkInputRecord
                    205:  * Check if any input field is empty.
                    206:  */
                    207: - checkInputRecord:sender
                    208: {
                    209:        int     i;
                    210:        const char *inputStr;
                    211:                
                    212:        for ( i = 0; i < 9; i++ ) {
                    213:                inputStr = (const char *)[formMatrix stringValueAt:i];
                    214:                        /* If the string is empty, abort the operation */
                    215:                if  ( inputStr == NULL){
                    216:                        NXRunAlertPanel (NULL,EMPTY_STRING,NULL, NULL, NULL);
                    217:                        return nil;
                    218:                        }
                    219:        }
                    220:                return self;
                    221: }
                    222: 
                    223: /* fillNewRecordAt:(int) index
                    224:  * Method used for INSERT operation 
                    225:  * Get the user input from the form cells. 
                    226:  */
                    227: - fillNewRecordAt:(int)index
                    228: {
                    229:        const char *inputString;
                    230:        int     contractNum;
                    231:                
                    232:                        /* set last name */             
                    233:        inputString = (const char *)[formMatrix stringValueAt:0];
                    234:        [aValue setStringValue:inputString];
                    235:        [dbRecordList setValue:aValue 
                    236:                                forProperty:[[dbModule entity] propertyNamed:"lastName"]
                    237:                                at:index];      
                    238:                                
                    239:                /* set first name */
                    240:        inputString = (const char *)[formMatrix stringValueAt:1];
                    241:        [aValue setStringValue:(const char *)inputString];
                    242:        [dbRecordList setValue: aValue
                    243:                                forProperty: [[dbModule entity] propertyNamed:"firstName"]
                    244:                                at:index];
                    245:                                
                    246:                /* get the ssn or author id */
                    247:        inputString = (const char *)[formMatrix stringValueAt:2];
                    248:        [aValue setStringValue:inputString];
                    249:        [dbRecordList setValue:aValue 
                    250:                                forProperty:[[dbModule entity] propertyNamed:"authorID"]
                    251:                                at:index];
                    252:        strcpy( newAuthorID, inputString);
                    253:                        
                    254:                        /* set address */
                    255:        inputString = (const char *)[formMatrix stringValueAt:3];
                    256:        [aValue setStringValue: inputString];
                    257:        [dbRecordList setValue: aValue
                    258:                                forProperty:[[dbModule entity] propertyNamed:"address"]
                    259:                                at:index];
                    260: 
                    261:                        /* set city name */
                    262:        inputString = (const char *)[formMatrix stringValueAt:4];
                    263:        [aValue setStringValue: inputString];
                    264:        [dbRecordList setValue: aValue
                    265:                        forProperty:[[dbModule entity] propertyNamed:"city"]
                    266:                        at:index];
                    267: 
                    268:                        /* set state */
                    269:        inputString = (const char *)[formMatrix stringValueAt:5];
                    270:        [aValue setStringValue: inputString];
                    271:        [dbRecordList setValue: aValue
                    272:                        forProperty:[[dbModule entity] propertyNamed:"state"]
                    273:                        at:index];
                    274: 
                    275:                        /* set zip code */
                    276:        inputString = (const char *)[formMatrix stringValueAt:6];
                    277:        [aValue setStringValue: inputString];
                    278:        [dbRecordList setValue: aValue
                    279:                        forProperty:[[dbModule entity] propertyNamed:"zipCode"]
                    280:                        at:index ];
                    281:        
                    282:                        /* set phone number */
                    283:        inputString = (const char *)[formMatrix stringValueAt:7];
                    284:        [aValue setStringValue: inputString];
                    285:        [dbRecordList setValue:aValue
                    286:                                forProperty:[[dbModule entity] propertyNamed:"phone"]
                    287:                                at:index];
                    288:        
                    289:                        /* set contract number */
                    290:        contractNum = [formMatrix intValueAt:8];
                    291:        [aValue setIntValue:contractNum];
                    292:        [dbRecordList setValue: aValue
                    293:                                forProperty:[[dbModule entity] propertyNamed:"contract"]
                    294:                                at:index];
                    295: 
                    296:        return self;
                    297: }
                    298: 
                    299: 
                    300: /* Clear the form cells after each SAVE operation to avoid creating
                    301:  * duplicate records.
                    302:  */
                    303: - clearData
                    304: {
                    305:        int i;
                    306:        
                    307:        for (i = 0; i < 9; i++)
                    308:                [formMatrix setStringValue:""at:i];
                    309:        return self;
                    310: }
                    311: 
                    312: @end
                    313: 

unix.superglobalmegacorp.com

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