home *** CD-ROM | disk | FTP | other *** search
Wrap
/* TableViewController.m: * You may freely copy, distribute, and reuse the code in this example. * NeXT disclaims any warranty of any kind, expressed or implied, as to its * fitness for any particular use. * * Written by: Mai Nguyen, NeXT Developer Support * * */ #import "TableViewController.h" #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.") /* Comment this line out if you want to run an Oracle version */ #define SYBASE_DEMO 1 @implementation TableViewController /* * Miscellaneous initialization tasks: connect to database, initialize * tableview, set up dbModule. */ -appDidInit:sender { NXRect viewFrame; #ifdef SYBASE_DEMO /* Notify the user if the database can't be found */ if (!(dbDatabase = [DBDatabase findDatabaseNamed:"SybaseDemo" connect:YES])) { NXRunAlertPanel(NULL,INSTALL_MODEL, "OK", NULL, NULL); return self; } #else /* Notify the user if the database can't be found */ if (!(dbDatabase = [DBDatabase findDatabaseNamed:"OracleDemo" connect:YES])) { NXRunAlertPanel(NULL,INSTALL_MODEL, "OK", NULL, NULL); return self; } #endif [dbDatabase setDelegate:self]; /* Install the tableview into the custom view */ [[dbTableView getFrame:&viewFrame] free]; dbTableView = [[DBTableView alloc] initFrame:&viewFrame]; [[window contentView] addSubview:dbTableView]; [dbTableView setHorizScrollerRequired:YES]; [dbTableView setVertScrollerRequired:YES]; [dbTableView setDelegate: self]; #ifdef SYBASE_DEMO rootEntity = [dbDatabase entityNamed:"Author"]; #else rootEntity = [dbDatabase entityNamed:"Order"]; #endif /* Must initialize your dbModule */ dbModule = [[DBModule alloc] initDatabase:dbDatabase entity:rootEntity]; dbFetchGroup = [dbModule rootFetchGroup]; [dbFetchGroup setDelegate:self]; #ifdef SYBASE_DEMO dbQualifier = [[DBQualifier alloc] initForEntity:[dbModule entity] fromDescription:"state = %s", "CA"]; #else dbQualifier = [[DBQualifier alloc] initForEntity:[dbModule entity] fromDescription:"customer.state = %s", "CA"]; #endif [window disableFlushWindow]; [self initTableView]; [[window reenableFlushWindow] flushWindow]; return self; } - showAll:sender { [dbFetchGroup fetchContentsOf:[dbModule entity] usingQualifier:dbQualifier]; [dbTableView display]; return self; } /* In order to replicate the Interface Builder functionality, one has to * add an expression to the fetchgroup for each attribute and subattribute. */ - addTableColumn:(const char *)label { id newExpression; /* allocate a new expression, add it to the FetchGroup and add it */ /* to the TableView */ newExpression = [[DBExpression alloc] initForEntity:[dbModule entity] fromDescription:label]; [dbFetchGroup addExpression:newExpression]; [dbTableView addColumn:newExpression withTitle:label]; return self; } /* Get all the attributes and subattributes from the defined table and * initialize the tableview accordingly. */ - initTableView { int i, j, propCount, subpropCount; id prop, subprop, subpropList; char buffer[100]; id <DBEntities, DBTypes> theEntity; propList = [[List alloc] init]; [rootEntity getProperties: propList]; propCount = [propList count]; for (i = 0; i < propCount; i++) { prop = [propList objectAt:i]; theEntity = (id<DBTypes>)[prop propertyType]; if(! [theEntity isEntity]) { /* add top-level attribute */ [self addTableColumn:[prop name]]; /* defined above */ } else if ([prop isSingular]) { /* add all sub-attributes but skip sub-relationships. Note that getting sub-attributes only work for to-one relationship */ subpropList = [[List alloc] init]; [theEntity getProperties:subpropList]; subpropCount = [subpropList count]; for (j = 0; j < subpropCount; j++) { subprop = [subpropList objectAt:j]; if (![[subprop propertyType] isEntity]) { sprintf(buffer, "%s.%s", [prop name], [subprop name]); [self addTableColumn:buffer]; /* defined above */ } } [subpropList free]; /* to prevent a memory leak */ } } /* Making this association will make the fetchgroup * become the tableview data source. */ [dbFetchGroup makeAssociationFrom:nil to:dbTableView]; /* * free property list which is no longer needed */ [propList free]; [window makeKeyAndOrderFront:self]; return self; } /* Set the sort order before the actual fetch */ - fetchGroupWillFetch: sender { if( sortProp == nil) { sortProp = [[dbTableView columnAt: 0] identifier]; } [[sender recordList] addRetrieveOrder: DB_AscendingOrder for: sortProp]; return self; } /* Find the new sort property every time the tableView column gets moved */ - tableView:sender movedColumnFrom:(unsigned int) old to:(unsigned int) new { sortProp = [[sender columnAt: new] identifier]; return [dbModule fetchAllRecords: self]; } - free { if (dbQualifier) [dbQualifier free]; if (dbTableView) [dbTableView free]; return [super free]; } /* DBDatabase delegate methods to log SQL queries - Useful for debugging */ - (BOOL)db:aDb willEvaluateString:(const char*)aString usingBinder:aBinder { fprintf(stderr, "SQL query:%s\n", aString); return YES; } @end