Annotation of Examples/EnterpriseObjects/SHLExamples/Querying/QueryController.m, revision 1.1.1.1

1.1       root        1: /*--------------------------------------------------------------------------
                      2:  *
                      3:  *     You may freely copy, distribute, and reuse the code in this example.
                      4:  *     SHL Systemhouse disclaims any warranty of any kind, expressed or  
                      5:  *     implied, as to its fitness for any particular use.
                      6:  *
                      7:  *
                      8:  *     QueryController
                      9:  *
                     10:  *     Inherits From:          NSObject
                     11:  *
                     12:  *     Conforms To:            None.
                     13:  *
                     14:  *     Declared In:            QueryController.h
                     15:  *
                     16:  *
                     17:  *------------------------------------------------------------------------*/
                     18: #import "QueryController.h"
                     19: #import "EOQualifierContentsCategory.h"
                     20: 
                     21: 
                     22: 
                     23: 
                     24: @implementation QueryController
                     25: 
                     26: 
                     27: /*--------------------------------------------------------------------------
                     28:  *     Model file reading and preparation for query building
                     29:  *------------------------------------------------------------------------*/
                     30: - _setUpForModelFile: (NSString *)aFilepath
                     31: {
                     32:        id model = [[EOModel allocWithZone: NULL]
                     33:                                initWithContentsOfFile: aFilepath];
                     34: 
                     35:        /*----------------------------------------------------------------------
                     36:         *      create adaptor with specifics contained in the model (server, etc.)
                     37:         *--------------------------------------------------------------------*/
                     38:        if (adaptor) [adaptor autorelease];
                     39:        adaptor = [[EOAdaptor adaptorWithModel: model] retain];
                     40:        [model autorelease];
                     41: 
                     42:        /*----------------------------------------------------------------------
                     43:         *      set up database pieces to allow transactions, qualifiers, etc.
                     44:         *--------------------------------------------------------------------*/
                     45:        if (database) [database autorelease];
                     46:        database = [[EODatabase allocWithZone: [self zone]]
                     47:                                        initWithAdaptor: adaptor];
                     48: 
                     49:        if (dbContext) [dbContext autorelease];
                     50:        dbContext = [[EODatabaseContext alloc] initWithDatabase: database];
                     51:        
                     52:        if (dbChannel) [dbChannel autorelease];
                     53:        dbChannel = [[EODatabaseChannel alloc] initWithDatabaseContext: dbContext];
                     54: 
                     55:        /*----------------------------------------------------------------------
                     56:         *      open the channel and turn on debug to see SQL in console
                     57:         *--------------------------------------------------------------------*/
                     58:        if (! [dbChannel openChannel]) {
                     59:                NSLog(@"database channel could not be opened.");
                     60:        }
                     61:        [[dbChannel adaptorChannel] setDebugEnabled:YES];
                     62: 
                     63:        entity = nil;
                     64: 
                     65:        [self clearQualifier:nil];
                     66:        [[qualifierBrowser matrixInColumn:0] renewRows:0 cols:0];
                     67:        [[qualifierBrowser matrixInColumn:0] sizeToCells];
                     68:        [qualifierBrowser display];
                     69:        return self;
                     70: }
                     71: 
                     72: 
                     73: /*--------------------------------------------------------------------------
                     74:  *     IconWell delegate method
                     75:  *------------------------------------------------------------------------*/
                     76: - dragSource:dragSource didDropOnIconWell:sender
                     77: {
                     78:        [modelPath setStringValue: (const char *)[sender path]];
                     79:        [self _setUpForModelFile: [NSString stringWithCString:
                     80:                (char *)[sender path]]];
                     81: 
                     82:        [[browser loadColumnZero] display];
                     83:        [window makeKeyAndOrderFront: self];
                     84: 
                     85:        return self;
                     86: }
                     87: 
                     88: 
                     89: /*--------------------------------------------------------------------------
                     90:  *     Application delegation
                     91:  *------------------------------------------------------------------------*/
                     92: - appDidInit: sender
                     93: {
                     94:        qualifier = nil;
                     95:        dataSource = nil;
                     96:        controller = nil;
                     97:        dbContext = nil;
                     98:        dbChannel = nil;
                     99: 
                    100:        [qualifierOperation setEmptySelectionEnabled:YES];
                    101:        [qualifierOperation selectCellAt:-1:-1];
                    102:        [window makeKeyAndOrderFront: self];
                    103:        return self;
                    104: }
                    105: 
                    106: 
                    107: /*--------------------------------------------------------------------------
                    108:  *     Query Actions
                    109:  *------------------------------------------------------------------------*/
                    110: - performQuery:sender
                    111: {
                    112:        id                      selection = [[NSMutableArray allocWithZone:NULL] init];
                    113:        id                      selectedCells = [[List alloc] init];
                    114:        int                     countSelected, iterator;
                    115:        const char      *cString;
                    116:        
                    117:        /*----------------------------------------------------------------------
                    118:         *      get attribute names to be selected and browsed
                    119:         *--------------------------------------------------------------------*/
                    120:        [[browser matrixInColumn:1] getSelectedCells:selectedCells];
                    121:        countSelected = [selectedCells count];
                    122: 
                    123:        if (countSelected == 0) {
                    124:                [selectedCells free];
                    125:                selectedCells = [[browser matrixInColumn:1] cellList];
                    126:                countSelected = [selectedCells count];
                    127:        }
                    128:        
                    129:        /*----------------------------------------------------------------------
                    130:         *      transfer info from a NS3.2 list to a NS3.3NSArray
                    131:         *--------------------------------------------------------------------*/
                    132:        for (iterator = 0; iterator < countSelected; iterator++) {
                    133:                cString = [(Cell *)[selectedCells objectAt: iterator] stringValue];
                    134:                [(NSMutableArray *)selection addObject:
                    135:                                [NSString stringWithCString: cString]];
                    136:        }
                    137: 
                    138:        /*----------------------------------------------------------------------
                    139:         *      assure current entity
                    140:         *--------------------------------------------------------------------*/
                    141:        cString = [(Cell *)[[browser matrixInColumn:0] selectedCell] stringValue];
                    142:        entity = [[adaptor model] entityNamed:
                    143:                                [NSString stringWithCString: cString]];
                    144: 
                    145:        /*----------------------------------------------------------------------
                    146:         *      if qualifier is not defined, create an unqualified fetch.
                    147:         *--------------------------------------------------------------------*/
                    148:        if (qualifier == nil)
                    149:                qualifier = [entity qualifier];
                    150: 
                    151:        /*----------------------------------------------------------------------
                    152:         *      call method to handle fetch and reporting thru NXTableView
                    153:         *--------------------------------------------------------------------*/
                    154:        [self fetchAndDisplay:selection inEntity:entity
                    155:                                withQualifier:qualifier];
                    156: 
                    157:     return self;
                    158: }
                    159: 
                    160: 
                    161: - (void) fetchAndDisplay:(NSArray *)attributes inEntity:(EOEntity *)anEntity
                    162:        withQualifier:(EOQualifier *)aQualifier
                    163: {
                    164:        unsigned int    count, iterator;
                    165: 
                    166:        [resultWindow disableDisplay];
                    167: 
                    168:        /*----------------------------------------------------------------------
                    169:         *      if not the first query, we need to change dataSources.  The entity
                    170:         *      may be different from the previous query.
                    171:         *--------------------------------------------------------------------*/
                    172:        if (dataSource) [dataSource autorelease];
                    173: 
                    174:        dataSource = [[EODatabaseDataSource allocWithZone:[self zone]]
                    175:                                        initWithDatabaseChannel:dbChannel
                    176:                                        entityNamed:[anEntity name]];
                    177:        /*----------------------------------------------------------------------
                    178:         *      get a new controller with the new dataSource
                    179:         *--------------------------------------------------------------------*/
                    180:        controller = [[EOController allocWithZone: [self zone]]
                    181:                        initWithDataSource: dataSource];
                    182: 
                    183:        /*----------------------------------------------------------------------
                    184:         *      delete all current columns in the table view
                    185:         *--------------------------------------------------------------------*/
                    186:        count = [resultTable columnCount];
                    187:        for (iterator = count; iterator > 0; iterator--)
                    188:                [resultTable removeColumnAt: iterator-1];
                    189:        [(NXTableView *)resultTable setDataSource:nil];
                    190: 
                    191:        /*----------------------------------------------------------------------
                    192:         *      iterate through the desired select attributes and build columns for
                    193:         *      each in the tableView.
                    194:         *--------------------------------------------------------------------*/
                    195:        count = [attributes count];
                    196:        for (iterator = 0; iterator < count; iterator ++) {
                    197:                id      association;
                    198:                id      attribute = [anEntity attributeNamed:
                    199:                        [attributes objectAtIndex:iterator]];
                    200: 
                    201:                [resultTable addColumn:attribute withTitle:
                    202:                        [[(EOAttribute *)attribute name] cString]];
                    203: 
                    204:        /*----------------------------------------------------------------------
                    205:         *      create a new association for each of these attribute/column pairs
                    206:         *--------------------------------------------------------------------*/
                    207:                association = [[EOColumnAssociation allocWithZone: [self zone]]
                    208:                        initWithController:controller key: [(EOAttribute *)attribute name]
                    209:                        destination:[resultTable columnAt:iterator]];
                    210: 
                    211:                [association setTableView:resultTable];
                    212:                [controller addAssociation: association];
                    213:                [association autorelease];
                    214:        }
                    215: 
                    216:        /*----------------------------------------------------------------------
                    217:         *      set the qualifier for the fetch.
                    218:         *--------------------------------------------------------------------*/
                    219:        [dataSource setQualifier: aQualifier];
                    220: 
                    221:        /*----------------------------------------------------------------------
                    222:         *      Start a transaction, do the fetch, rollback the transaction (a fetch
                    223:         *      doesn't need to commit anything) have the values filled to the
                    224:         *      tableView via the columnAssociations.
                    225:         *--------------------------------------------------------------------*/
                    226:        [dbContext beginTransaction];
                    227: 
                    228:        if (! [controller fetch])
                    229:                NSLog(@"controller fetch failed.");
                    230: 
                    231:        [dbContext rollbackTransaction];
                    232: 
                    233:        /*----------------------------------------------------------------------
                    234:         *      Redisplay everything...
                    235:         *--------------------------------------------------------------------*/
                    236:        [resultWindow reenableDisplay];
                    237:        [controller redisplay];
                    238:        [resultWindow makeKeyAndOrderFront:self];
                    239:        return;
                    240: }
                    241:        
                    242:        
                    243: - (int) browser:aBrowser fillMatrix:aMatrix inColumn:(int)aColumn
                    244: {
                    245:        int                     iterator = 0, entryCount = 0;
                    246:        id                      contents = nil;
                    247:        id                      enumerator, current;
                    248: 
                    249:        /*----------------------------------------------------------------------
                    250:         *      Fill qualifier browser with the attributes of the selected entity;
                    251:         *      this is the same list as in the second column of the first browser.
                    252:         *--------------------------------------------------------------------*/
                    253:        if (aBrowser == qualifierBrowser) {
                    254:                id selectedEntity;
                    255: 
                    256:                iterator = 0;
                    257:                if ([browser selectedColumn] < 0) 
                    258:                        return 0;
                    259: 
                    260:                selectedEntity = [NSString stringWithCString: 
                    261:                        [(Cell *)[[browser matrixInColumn:0] selectedCell]
                    262:                         stringValue]];
                    263:                contents = [[[adaptor model] entityNamed: selectedEntity] attributes];
                    264:                entity = nil;
                    265: 
                    266:                entryCount = [contents count];
                    267:                [aMatrix renewRows: entryCount cols: 1];
                    268: 
                    269:                enumerator = [contents objectEnumerator];
                    270:                while ((current = [enumerator nextObject]) != nil) {
                    271: 
                    272:                        [[[aMatrix cellAt: iterator++ : 0] 
                    273:                                setStringValue: [[(EOAttribute *)current name] cString]]
                    274:                                setLeaf:  YES];
                    275:                }
                    276:                return entryCount;
                    277:        }
                    278: 
                    279:        /*----------------------------------------------------------------------
                    280:         *      The main entity attribute browser with two columns.  One selects the
                    281:         *      entity for the query the other the attributes to be selected.  Note
                    282:         *      that since we're using the EODatabaseAdaptor (instead of the
                    283:         *      EOChannelAdaptor, we actually select the entire object, but only these
                    284:         *      fields will be associated with the tableView.
                    285:         *
                    286:         *      Reset query qualifiers for new entity
                    287:         *--------------------------------------------------------------------*/
                    288:        [qualifier autorelease];
                    289:        [qualifierText setStringValue: ""];
                    290:        [queryText setStringValue: ""];
                    291: 
                    292:        if (aColumn == 0) 
                    293:                contents = [[adaptor model] entities];
                    294: 
                    295:        else if (aColumn == 1) {
                    296:                id selectedEntity;
                    297: 
                    298:                selectedEntity = [NSString stringWithCString: 
                    299:                        [(Cell *)[[aBrowser matrixInColumn:0] selectedCell] stringValue]];
                    300:                contents = [[[adaptor model] entityNamed: selectedEntity] attributes];
                    301:                entity = nil;
                    302:        }
                    303: 
                    304:        entryCount = [contents count];
                    305:        [aMatrix renewRows: entryCount cols: 1];
                    306: 
                    307:        enumerator = [contents objectEnumerator];
                    308:        while ((current = [enumerator nextObject]) != nil) {
                    309: 
                    310:                [[[aMatrix cellAt: iterator : 0] 
                    311:                        setStringValue: [[(EOEntity *)current name] cString]]
                    312:                        setLeaf:  aColumn == 1 ];
                    313:                iterator++;
                    314:        }
                    315: 
                    316:        if (aColumn ==  1)
                    317:                [[qualifierBrowser loadColumnZero] display];
                    318: 
                    319:        return entryCount;
                    320: }
                    321: 
                    322: 
                    323: - selectOperation:sender
                    324: {
                    325:        int selectedOp;
                    326:        id      opString = nil;
                    327:        int     selection;
                    328: 
                    329:        selectedOp = [[qualifierOperation selectedCell] tag];
                    330: 
                    331:        if (selectedOp == 0) opString = @"<";
                    332:        else if (selectedOp == 1) opString = @"<=";
                    333:        else if (selectedOp == 2) opString = @">";
                    334:        else if (selectedOp == 3) opString = @">=";
                    335:        else if (selectedOp == 4) opString = @"=";
                    336:        else if (selectedOp == 5) opString = @"<>";
                    337:        
                    338:        
                    339:        [qualifierText setStringValue: 
                    340:                [[NSString stringWithFormat:@"%s%s ",
                    341:                [(TextField *)qualifierText stringValue],
                    342:                        [opString cString]] cString]];
                    343: 
                    344:        selection = strlen([(TextField *)qualifierText stringValue]);
                    345:        [qualifierText selectText:nil];
                    346: 
                    347: 
                    348:        return self;
                    349: }
                    350: 
                    351: 
                    352: - selectAttribute:sender
                    353: {
                    354:        id                      selectedCell;
                    355:        EOAttribute     *newAttribute;
                    356: 
                    357:        if (entity == nil) {
                    358:                const char      *entityName;
                    359: 
                    360:                entityName = [(Cell *)[[browser matrixInColumn: 0]
                    361:                                                                selectedCell] stringValue];
                    362:                entity = [[adaptor model] entityNamed:
                    363:                                [NSString stringWithCString: entityName]];
                    364:        }
                    365: 
                    366:        if ((selectedCell = [qualifierBrowser selectedCell])) {
                    367:                id      newString;
                    368: 
                    369:                newAttribute = [entity attributeNamed:
                    370:                        [NSString stringWithCString:[(Cell *)selectedCell stringValue]]];
                    371: 
                    372:        /*----------------------------------------------------------------------
                    373:         *      Get the name internal to the database; if it is a column, get the
                    374:         *      column name, otherwise, it is a complex value (a flattened attribute)
                    375:         *      so get the description.
                    376:         *--------------------------------------------------------------------*/
                    377:                newString = [NSString stringWithFormat: @"%s%s ",
                    378:                        [(TextField *)qualifierText stringValue],       
                    379:                        [newAttribute columnName] ?     
                    380:                                [(NSString *)[newAttribute columnName] cString] :
                    381:                                [(NSString *)[newAttribute definition] cString]];
                    382: 
                    383:                [qualifierText setStringValue: [newString cString]];
                    384:                [qualifierText selectText: nil];
                    385: 
                    386:        }
                    387: 
                    388:        return self;
                    389: }
                    390: 
                    391: 
                    392: - replaceQualifier: sender
                    393: {
                    394:        if (qualifier) [qualifier autorelease];
                    395: 
                    396:        if (entity == nil) {
                    397:                const char      *entityName;
                    398: 
                    399:                entityName = [(Cell *)[[browser matrixInColumn: 0]
                    400:                                                                selectedCell] stringValue];
                    401:                if (! entityName) {
                    402:                        NXRunAlertPanel("Query Builder",
                    403:                                "A model file must be present before a query is possible.",
                    404:                                NULL, NULL, NULL);
                    405:                        return nil;
                    406:                }
                    407: 
                    408:                entity = [[adaptor model] entityNamed:
                    409:                                [NSString stringWithCString: entityName]];
                    410:        }
                    411: 
                    412:        qualifier = [[EOQualifier allocWithZone:[self zone]]
                    413:                initWithEntity:entity
                    414:                qualifierFormat: [NSString stringWithCString:
                    415:                        [(TextField *)qualifierText stringValue]]];
                    416:        
                    417:        if ([negator state]) [qualifier negate];
                    418: 
                    419:        [negator setState: 0];
                    420:        [queryText setStringValue:[[qualifier contents] cString]];
                    421:        [qualifierText setStringValue:""];
                    422:        [qualifierText selectText: nil];
                    423:        [qualifierOperation selectCellAt:-1:-1];
                    424: 
                    425: 
                    426:        return self;
                    427: }
                    428: 
                    429: 
                    430: - appendAND: sender
                    431: {
                    432:        id newQualifier;
                    433: 
                    434:        if (entity == nil) {
                    435:                const char      *entityName;
                    436: 
                    437:                entityName = [(Cell *)[[browser matrixInColumn: 0]
                    438:                                                                selectedCell] stringValue];
                    439:                if (! entityName) {
                    440:                        NXRunAlertPanel("Query Builder",
                    441:                                "A model file must be present before a query is possible.",
                    442:                                NULL, NULL, NULL);
                    443:                        return nil;
                    444:                }
                    445: 
                    446:                entity = [[adaptor model] entityNamed:
                    447:                                [NSString stringWithCString: entityName]];
                    448:        }
                    449: 
                    450: 
                    451:        newQualifier = [[EOQualifier allocWithZone:[self zone]]
                    452:                initWithEntity:entity
                    453:                qualifierFormat: [NSString stringWithCString:
                    454:                        [(TextField *)qualifierText stringValue]]];
                    455: 
                    456:        /*----------------------------------------------------------------------
                    457:         *      If the qualifier is to be negated...
                    458:         *--------------------------------------------------------------------*/
                    459:        if ([negator state]) [newQualifier negate];
                    460: 
                    461:        /*----------------------------------------------------------------------
                    462:         *      AND the new qualifier with the previous one
                    463:         *--------------------------------------------------------------------*/
                    464:        [qualifier      conjoinWithQualifier: newQualifier];
                    465: 
                    466:        [newQualifier autorelease];
                    467: 
                    468:        [negator setState: 0];
                    469:        [queryText setStringValue:[[qualifier contents] cString]];
                    470:        [qualifierText setStringValue:""];
                    471:        [qualifierText selectText: nil];
                    472:        [qualifierOperation selectCellAt:-1:-1];
                    473: 
                    474: 
                    475:        return self;
                    476: }
                    477: 
                    478: 
                    479: - appendOR: sender
                    480: {
                    481:        id newQualifier;
                    482: 
                    483:        if (entity == nil) {
                    484:                const char      *entityName;
                    485: 
                    486:                entityName = [(Cell *)[[browser matrixInColumn: 0]
                    487:                                                                selectedCell] stringValue];
                    488:                if (! entityName) {
                    489:                        NXRunAlertPanel("Query Builder",
                    490:                                "A model file must be present before a query is possible.",
                    491:                                NULL, NULL, NULL);
                    492:                        return nil;
                    493:                }
                    494: 
                    495:                entity = [[adaptor model] entityNamed:
                    496:                                [NSString stringWithCString: entityName]];
                    497:        }
                    498: 
                    499: 
                    500:        newQualifier = [[EOQualifier allocWithZone:[self zone]]
                    501:                initWithEntity:entity
                    502:                qualifierFormat: [NSString stringWithCString:
                    503:                        [(TextField *)qualifierText stringValue]]];
                    504: 
                    505:        /*----------------------------------------------------------------------
                    506:         *      If the qualifier is to be negated...
                    507:         *--------------------------------------------------------------------*/
                    508:        if ([negator state]) [newQualifier negate];
                    509: 
                    510:        /*----------------------------------------------------------------------
                    511:         *      OR the new qualifier with the previous one.
                    512:         *--------------------------------------------------------------------*/
                    513:        [qualifier      disjoinWithQualifier: newQualifier];
                    514: 
                    515:        [newQualifier autorelease];
                    516: 
                    517:        [negator setState: 0];
                    518:        [queryText setStringValue:[[qualifier contents] cString]];
                    519:        [qualifierText setStringValue:""];
                    520:        [qualifierText selectText: nil];
                    521:        [qualifierOperation selectCellAt:-1:-1];
                    522: 
                    523: 
                    524:        return self;
                    525: }
                    526: 
                    527: 
                    528: - clearQualifier: sender
                    529: {
                    530:        [qualifier autorelease];
                    531:        qualifier = nil;
                    532:        [negator setState: 0];
                    533:        [queryText setStringValue:""];
                    534:        [qualifierText setStringValue:""];
                    535:        [qualifierText selectText:nil];
                    536:        [qualifierOperation selectCellAt:-1:-1];
                    537: 
                    538:        return self;
                    539: }
                    540: 
                    541: 
                    542: @end

unix.superglobalmegacorp.com

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