Annotation of Examples/DatabaseKit/PubsDemo/Controller.m, revision 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.