Annotation of Examples/DatabaseKit/TableView/TableViewController.m, revision 1.1.1.1

1.1       root        1: /* TableViewController.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 "TableViewController.h"
                     11: 
                     12: #define INSTALL_MODEL NXLocalizedString("Please install SybaseDemo.dbmodela or OracleDemo.dbmodela in your project.", NULL, "Notify user that the ascii model files must be installed in his project directory.")
                     13: 
                     14: /* Comment this line out if you want to run an Oracle version */
                     15: #define        SYBASE_DEMO      1
                     16: 
                     17: @implementation TableViewController
                     18: /*
                     19: * Miscellaneous initialization tasks: connect to database, initialize
                     20: * tableview, set up dbModule. 
                     21: */ 
                     22: -appDidInit:sender
                     23: {
                     24:        NXRect viewFrame;
                     25:        
                     26: #ifdef SYBASE_DEMO     
                     27:        /* Notify the user if the database can't be found */
                     28:        if (!(dbDatabase = [DBDatabase findDatabaseNamed:"SybaseDemo" 
                     29:                                        connect:YES])) {
                     30:                NXRunAlertPanel(NULL,INSTALL_MODEL, "OK", NULL, NULL);
                     31:                return self;
                     32:        }
                     33: #else
                     34:        /* Notify the user if the database can't be found */
                     35:        if (!(dbDatabase = [DBDatabase findDatabaseNamed:"OracleDemo" 
                     36:                                        connect:YES])) {
                     37:                NXRunAlertPanel(NULL,INSTALL_MODEL, "OK", NULL, NULL);
                     38:                return self;
                     39:        }
                     40: #endif
                     41: 
                     42:        [dbDatabase setDelegate:self];
                     43:        
                     44:                /* Install the tableview into the custom view */
                     45:        [[dbTableView getFrame:&viewFrame] free];
                     46:        dbTableView = [[DBTableView alloc] initFrame:&viewFrame];
                     47:        [[window contentView] addSubview:dbTableView];
                     48:        [dbTableView setHorizScrollerRequired:YES];
                     49:        [dbTableView setVertScrollerRequired:YES];
                     50:        [dbTableView setDelegate: self];
                     51: 
                     52: #ifdef SYBASE_DEMO
                     53:        rootEntity = [dbDatabase entityNamed:"Author"];
                     54: #else
                     55:        rootEntity = [dbDatabase entityNamed:"Order"];
                     56: #endif
                     57:                /* Must initialize your dbModule */
                     58:        dbModule = [[DBModule alloc] initDatabase:dbDatabase 
                     59:                                                        entity:rootEntity];                                     
                     60:        dbFetchGroup = [dbModule rootFetchGroup];
                     61:        [dbFetchGroup setDelegate:self];
                     62: #ifdef SYBASE_DEMO
                     63:        dbQualifier = [[DBQualifier alloc] initForEntity:[dbModule entity]
                     64:                                fromDescription:"state = %s", "CA"];
                     65: #else
                     66:        dbQualifier = [[DBQualifier alloc] initForEntity:[dbModule entity]
                     67:                                fromDescription:"customer.state = %s", "CA"];
                     68: #endif         
                     69:        [window disableFlushWindow];
                     70:        [self initTableView];
                     71:        [[window reenableFlushWindow] flushWindow];
                     72:        
                     73:        return self;
                     74: }
                     75: - showAll:sender
                     76: {
                     77:        [dbFetchGroup fetchContentsOf:[dbModule entity]
                     78:                                                                                        usingQualifier:dbQualifier];
                     79:        [dbTableView display];
                     80: 
                     81:        return self;
                     82: }
                     83: 
                     84: /* In order to replicate the Interface Builder functionality, one has to
                     85:  * add an expression to the fetchgroup for each attribute and subattribute.
                     86:  */
                     87: 
                     88: - addTableColumn:(const char *)label
                     89: {
                     90:     id newExpression;
                     91: 
                     92:     /* allocate a new expression, add it to the FetchGroup and add it */
                     93:        /* to the TableView */
                     94:        newExpression = [[DBExpression alloc] initForEntity:[dbModule entity]
                     95:                                fromDescription:label];
                     96:        [dbFetchGroup addExpression:newExpression];
                     97:        [dbTableView  addColumn:newExpression withTitle:label];
                     98:     return self;
                     99: }
                    100: 
                    101: 
                    102: /* Get all the attributes and subattributes from the defined table and
                    103:  *     initialize the tableview accordingly.
                    104:  */
                    105: - initTableView
                    106: {
                    107:        int i, j, propCount, subpropCount;
                    108:        id prop, subprop, subpropList;
                    109:        char buffer[100];
                    110:        id <DBEntities, DBTypes> theEntity;
                    111: 
                    112:        propList = [[List alloc] init];
                    113:        [rootEntity getProperties: propList];
                    114:     propCount = [propList count];
                    115: 
                    116:     for (i = 0; i < propCount; i++) {
                    117:            prop = [propList objectAt:i];
                    118:                theEntity = (id<DBTypes>)[prop propertyType];
                    119:            if(! [theEntity isEntity]) {
                    120: 
                    121:                        /* add top-level attribute */
                    122:                        [self addTableColumn:[prop name]];   /* defined above */
                    123:                } else if ([prop isSingular]) {
                    124: 
                    125:                        /* add all sub-attributes but skip sub-relationships.
                    126:                           Note that getting sub-attributes only work for
                    127:                           to-one relationship
                    128:                         */
                    129:                        subpropList  = [[List alloc] init];
                    130:                        
                    131:                        [theEntity getProperties:subpropList];
                    132:                        subpropCount = [subpropList count];
                    133:                        for (j = 0; j < subpropCount; j++) {
                    134:                                subprop = [subpropList objectAt:j];
                    135:                                if (![[subprop propertyType] isEntity]) {
                    136:                                sprintf(buffer, "%s.%s", [prop name], [subprop name]);
                    137:                                [self addTableColumn:buffer];   /* defined above */
                    138:                                }
                    139:                        }
                    140:                        [subpropList free];             /* to prevent a memory leak */
                    141:                }
                    142:        }
                    143:        
                    144:                /* Making this association will make the fetchgroup
                    145:                 * become the tableview data source.
                    146:                 */
                    147:        [dbFetchGroup makeAssociationFrom:nil to:dbTableView];
                    148:                /*
                    149:                 * free property list which is no longer needed
                    150:                 */
                    151:        [propList free];
                    152:        [window makeKeyAndOrderFront:self];
                    153:     return self;
                    154: }
                    155: 
                    156: 
                    157: /* Set the sort order before the actual fetch */
                    158: - fetchGroupWillFetch: sender
                    159: {
                    160:     if( sortProp == nil) {
                    161:        sortProp = [[dbTableView columnAt: 0] identifier];
                    162:     }
                    163:     [[sender recordList]
                    164:        addRetrieveOrder: DB_AscendingOrder
                    165:            for: sortProp];
                    166:     return self;
                    167: }
                    168: 
                    169: /* Find the new sort property every time the tableView column gets moved */
                    170: - tableView:sender movedColumnFrom:(unsigned int) old to:(unsigned int) new
                    171: {
                    172:     sortProp = [[sender columnAt: new] identifier];
                    173:     return [dbModule fetchAllRecords: self];
                    174: }
                    175: 
                    176: 
                    177: 
                    178: 
                    179: - free
                    180: {
                    181:        if (dbQualifier)
                    182:                [dbQualifier free];
                    183:        if (dbTableView)
                    184:                [dbTableView free];
                    185:        return [super free];
                    186: }
                    187: 
                    188: /* DBDatabase delegate methods to log SQL queries  - Useful for debugging */
                    189: 
                    190: - (BOOL)db:aDb willEvaluateString:(const char*)aString usingBinder:aBinder
                    191: {
                    192:        fprintf(stderr, "SQL query:%s\n", aString);
                    193:        return YES;
                    194: }
                    195: 
                    196: @end

unix.superglobalmegacorp.com

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