Annotation of Examples/DatabaseKit/AddressBook/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: 
                     11: #import <appkit/appkit.h>
                     12: #import <dbkit/dbkit.h>
                     13: #import <objc/List.h>
                     14: #import <objc/NXBundle.h>
                     15: #import <sys/param.h>
                     16: #import <libc.h>
                     17: 
                     18: #import "Controller.h"
                     19: #import "AddressView.h"
                     20: 
                     21: 
                     22: #define FAILURE NXLocalizedString("Failure:", NULL, "Message given to user when connection to database can't be made")
                     23: #define CANNOT_CONNECT NXLocalizedString("Couldn't connect to database", NULL, "Message given to user to explain what fails. ")
                     24: #define CANNOT_ADD NXLocalizedString("Add operation failed", NULL, "Message given to user that add operation has failed")
                     25: #define CANNOT_UPDATE NXLocalizedString("Update operation failed",NULL,"Message given to user that update operation has failed")
                     26: #define CANNOT_DELETE NXLocalizedString("Delete operation failed",NULL,"Message given to user that delete operation has failed")
                     27: 
                     28: @implementation Controller
                     29: 
                     30: - appDidInit:sender
                     31: {
                     32:                /* Try to connect to the database specified using the Sybase Adaptor
                     33:                 * and the default login sa, NULL password, SYBASE server, and
                     34:                 * pubs database.
                     35:                 */
                     36:        database = [[DBDatabase alloc]init];       
                     37:        [database connectUsingAdaptor:"SybaseAdaptor"
                     38:                                                                 andString:"sa@SYBASE/pubs"];
                     39: 
                     40:        if ( ![database isConnected] ) {
                     41:                        NXRunAlertPanel(FAILURE, CANNOT_CONNECT, "OK", NULL, NULL);
                     42:                        return self;
                     43:                        }
                     44:                /* Once successfully connected, build the data to be displayed in the
                     45:                 * matrix
                     46:                 */
                     47:        [self initRecordList];
                     48:     [addressView loadCellsFrom:self];
                     49: 
                     50:                /* Assign the controller to become the database delegate */
                     51:        [database setDelegate:self];
                     52: 
                     53:        cellMatrix = [addressView cellMatrix];
                     54:        
                     55:                /* Select a cell as a start */
                     56:     [[cellMatrix selectCellAt:0 :0] sendAction];
                     57:        /* Bring the main application window up front */
                     58:        [theWindow makeKeyAndOrderFront:nil];
                     59:                                
                     60:        return self;
                     61: }
                     62: 
                     63: /* Set up the DBRecordList object. Create a list of properties which contains
                     64:  * all properties needed for display or updating.
                     65:  */
                     66: - initRecordList
                     67: {
                     68:        id firstName, lastName, phone;
                     69:        id state, city, address, zipCode, contract;
                     70:        List    *keyList;
                     71:        
                     72:        if (recordList)
                     73:                [recordList free];
                     74:        if (propertyList)
                     75:                [propertyList free];
                     76: 
                     77:                        /* get the author table from the database */    
                     78:        authorEntity = [database entityNamed:"authors"];
                     79:        
                     80:                        /* get the properties  */
                     81:        lastName = [authorEntity propertyNamed:"au_lname"];
                     82:        firstName = [authorEntity propertyNamed:"au_fname"];
                     83:        authId = [authorEntity propertyNamed:"au_id"];
                     84:        
                     85:        phone = [authorEntity propertyNamed:"phone"];
                     86:        address = [authorEntity propertyNamed:"address"];
                     87:        city = [authorEntity propertyNamed:"city"];
                     88:        state = [authorEntity propertyNamed:"state"];
                     89:        zipCode = [authorEntity propertyNamed:"zip"];     
                     90:        contract = [authorEntity propertyNamed:"contract"];
                     91:        
                     92:                /* Set up the property list 
                     93:                 * Note that certain properties need to be defined in order
                     94:                 * for an Insert or Update operation to work. This depends
                     95:                 * on how your data dictionary has been defined. Here pubs
                     96:                 * is being used as the model.
                     97:                 */
                     98:        propertyList = [[List alloc] init];
                     99:        [propertyList addObject:authId];
                    100:        [propertyList addObject:lastName];
                    101:        [propertyList addObject:firstName];
                    102:        [propertyList addObject:phone];
                    103:        [propertyList addObject:address];
                    104:        [propertyList addObject:city];
                    105:        [propertyList addObject:state];
                    106:        [propertyList addObject:zipCode];
                    107:        [propertyList addObject:contract];
                    108: 
                    109:        recordList = [[DBRecordList alloc] init];
                    110:        
                    111:        
                    112:                /* A unique key is needed if you want to update or insert new
                    113:                 * data via the record list into the database. If no key is defined,
                    114:                 * the data retrieved via the  record list is read-only.
                    115:                 * This is needed here, since we do not use a dbmodel to define
                    116:                 * the key.
                    117:                 */
                    118:        keyList = (List *)[[List alloc] init];
                    119:        [keyList addObject:authId];
                    120:        [recordList setKeyProperties:keyList];
                    121:        [keyList free];
                    122:        
                    123:        /* You must set the properties FIRST before setting the retrieve order */
                    124:        [recordList setProperties:propertyList ofSource:authorEntity];
                    125:        
                    126:        [recordList addRetrieveOrder:DB_AscendingOrder for:lastName];
                    127:        [recordList addRetrieveOrder:DB_AscendingOrder for:firstName];                                  
                    128:        [recordList fetchUsingQualifier:nil];                                                           
                    129:        recordCount = [recordList count];
                    130:        
                    131:        return self;
                    132: }
                    133:        
                    134: /* This method is called when selecting "Insert"
                    135:  */
                    136: - addRecords:sender
                    137: {      
                    138:        
                    139:        int row;
                    140: 
                    141:        if (recordCount > 0) {
                    142:        
                    143:                if ( ![addressView addRecordFrom:sender at:(recordCount-1)]) {
                    144:                        NXRunAlertPanel(NULL, CANNOT_ADD, NULL, NULL, NULL);
                    145:                        return self;
                    146:                }
                    147:                
                    148:        [self initRecordList];
                    149:        [addressView loadCellsFrom:self];
                    150:                /* Find the row of the newly inserted record */
                    151:        row = [addressView getNewRow];
                    152:        [cellMatrix scrollCellToVisible:row :0];
                    153:        [[cellMatrix selectCellAt:row:0] sendAction];
                    154:        }
                    155:        else
                    156:                fprintf(stderr, "empty record list - NOP\n");
                    157:        return self;
                    158: }
                    159: 
                    160: /* This method gets called when selecting "Update"
                    161:  */
                    162: - updateRecords:sender
                    163: {
                    164:        int row;
                    165:        
                    166:        row = [cellMatrix selectedRow];
                    167:        if ( ![addressView updateRecordFrom:sender at:row]) {
                    168:                NXRunAlertPanel(NULL, CANNOT_UPDATE, NULL, NULL, NULL);
                    169:                return self;
                    170:        }
                    171:                /* Redisplay the records */
                    172:        [self initRecordList];
                    173:        [addressView loadCellsFrom:self];
                    174:                /* find the row of the updated record */
                    175:        row = [addressView getNewRow];
                    176:        [cellMatrix scrollCellToVisible:row :0];
                    177:        [[cellMatrix selectCellAt:row:0] sendAction];
                    178: 
                    179:        return self;
                    180: }
                    181: 
                    182: 
                    183: - deleteRecords:sender
                    184: {      
                    185:        
                    186:        int row;
                    187:        
                    188:        row = [cellMatrix selectedRow];
                    189:        if (recordCount > 0) {
                    190:        
                    191:        if (![addressView deleteSelectedRecord:sender]) {
                    192:                        NXRunAlertPanel(NULL, CANNOT_DELETE, NULL, NULL, NULL);
                    193:                        return self;
                    194:                }
                    195: 
                    196:        [self initRecordList];
                    197:        [addressView loadCellsFrom:self];
                    198:        [cellMatrix scrollCellToVisible:row :0];
                    199:        [[cellMatrix selectCellAt:row:0] sendAction];
                    200:        }
                    201:        else
                    202:                fprintf(stderr, "empty record list - NOP\n");
                    203:        
                    204:        return self;
                    205: }      
                    206: - getRecordList
                    207: {
                    208:        return recordList;
                    209: }
                    210: 
                    211: - getPropertyList
                    212: {
                    213:        return propertyList;
                    214: }
                    215: 
                    216: - (int)getRecordCount
                    217: {
                    218:        return recordCount;
                    219: }
                    220: 
                    221: - showSQLPanel:sender
                    222: {
                    223:        [SQLPanel makeKeyAndOrderFront:nil];
                    224:        return self;
                    225: }
                    226: 
                    227: - showInfoPanel:sender
                    228: {
                    229:        if (!infoPanel) {
                    230:                infoPanel = [NXApp loadNibSection:"InfoPanel.nib" owner:NXApp
                    231:                                                                                                                 withNames:NO]; 
                    232:                }
                    233:     [infoPanel orderFront:nil];
                    234:        return self;
                    235: }
                    236: 
                    237: - appWillTerminate:sender
                    238: {
                    239:        /* deallocate what has been allocated */
                    240:        if (recordList)
                    241:                [recordList free];
                    242:        if (propertyList)
                    243:                [propertyList free];
                    244:        return self;
                    245: }
                    246: 
                    247: /* DBDatabase delegate methods to log error messages and SQL queries */
                    248: 
                    249: - (BOOL)db:aDb willEvaluateString:(const unsigned char*)aString
                    250:         usingBinder:aBinder
                    251: {
                    252:        [textObj appendToText:"SQL Query:\n"];
                    253:        [textObj appendToText:aString];
                    254:        [textObj appendToText:"\n"];
                    255:        return YES;
                    256: }
                    257: 
                    258: @end
                    259: 
                    260: @implementation Text(printResults)
                    261: 
                    262: - appendToText:(const char *)newText
                    263: {
                    264:        int currentLength = [self textLength];
                    265: 
                    266:        [self setSel:currentLength :currentLength];
                    267:        [self replaceSel:newText];
                    268:        [self scrollSelToVisible];
                    269:        return self;
                    270: }
                    271: 
                    272: @end

unix.superglobalmegacorp.com

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