Annotation of Examples/EnterpriseObjects/SHLExamples/Querying/QueryController.m, revision 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.