home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 (1993) / nebula.bin / SourceCode / DBkit / TableViewExample / TableViewController.m < prev    next >
Encoding:
Text File  |  1992-09-18  |  4.2 KB  |  150 lines

  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 OracleDemo.dbmodel into your ~/Library/Databases directory and restart.", NULL, "Notify user that OracleDemo.dbmodel must be installed in his local Databases directory.")
  13.  
  14. @implementation TableViewController
  15. /*
  16. * Miscellaneous initialization tasks: connect to database, initialize
  17. * tableview, set up dbModule. 
  18. */ 
  19. -appDidInit:sender
  20. {
  21.     id entityList = [[List alloc] init];
  22.     NXRect viewFrame;
  23.     
  24.     /* Notify the user if the database can't be found */
  25.     if (!(dbDatabase = [DBDatabase findDatabaseNamed:"OracleDemo" 
  26.                     connect:YES])) {
  27.         NXRunAlertPanel(NULL,INSTALL_MODEL, "OK", NULL, NULL);
  28.         return self;
  29.     }
  30.     [dbDatabase setDelegate:self];
  31.     
  32.         /* Install the tableview into the custom view */
  33.     [[dbTableView getFrame:&viewFrame] free];
  34.     dbTableView = [[DBTableView alloc] initFrame:&viewFrame];
  35.     [[window contentView] addSubview:dbTableView];
  36.     [dbTableView setHorizScrollerRequired:YES];
  37.     [dbTableView setVertScrollerRequired:YES];
  38.     rootEntity = [dbDatabase entityNamed:"Order"];
  39.     
  40.         /* Must initialize your dbModule */
  41.       dbModule = [[DBModule alloc] initDatabase:dbDatabase 
  42.                             entity:rootEntity];                    
  43.     dbFetchGroup = [dbModule rootFetchGroup];
  44.     dbQualifier = [[DBQualifier alloc] initForEntity:[dbModule entity]
  45.                 fromDescription:"customer.state = %s", "CA"];    
  46.     [window disableFlushWindow];
  47.     [self initTableView];
  48.     [[window reenableFlushWindow] flushWindow];
  49.     
  50.     return self;
  51. }
  52. - showAll:sender
  53. {
  54.     [dbFetchGroup fetchContentsOf:[dbModule entity]
  55.                                             usingQualifier:dbQualifier];
  56.     [dbTableView display];
  57.  
  58.     return self;
  59. }
  60.  
  61. /* In order to replicate the Interface Builder functionality, one has to
  62.  * add an expression to the fetchgroup for each attribute and subattribute.
  63.  */
  64.  
  65. - addTableColumn:(const char *)label
  66. {
  67.     id newExpression;
  68.  
  69.     /* allocate a new expression, add it to the FetchGroup and add it */
  70.     /* to the TableView */
  71.     newExpression = [[DBExpression alloc] initForEntity:[dbModule entity]
  72.                 fromDescription:label];
  73.     [dbFetchGroup addExpression:newExpression];
  74.     [dbTableView  addColumn:newExpression withTitle:label];
  75.     return self;
  76. }
  77.  
  78.  
  79. /* Get all the attributes and subattributes from the defined table (named
  80.  * "Order" in our demo model) and initialize the tableview accordingly.
  81.  */
  82. - initTableView
  83. {
  84.     int i, j, propCount, subpropCount;
  85.     id prop, subprop, subpropList;
  86.     char buffer[100];
  87.  
  88.       propList = [[List alloc] init];
  89.     [rootEntity getProperties: propList];
  90.     propCount = [propList count];
  91.  
  92.     for (i = 0; i < propCount; i++) {
  93.         prop = [propList objectAt:i];
  94.  
  95.         if(! [[prop propertyType] isEntity]) {
  96.  
  97.             /* add top-level attribute */
  98.             [self addTableColumn:[prop name]];   /* defined above */
  99.         } else if ([prop isSingular]) {
  100.  
  101.             /* add all sub-attributes but skip sub-relationships.
  102.                Note that getting sub-attributes only work for
  103.                to-one relationship
  104.              */
  105.             subpropList  = [[List alloc] init];
  106.             [[prop propertyType] getProperties:subpropList];
  107.             subpropCount = [subpropList count];
  108.             for (j = 0; j < subpropCount; j++) {
  109.                 subprop = [subpropList objectAt:j];
  110.                 if (![[subprop propertyType] isEntity]) {
  111.                 sprintf(buffer, "%s.%s", [prop name], [subprop name]);
  112.                 [self addTableColumn:buffer];   /* defined above */
  113.                 }
  114.             }
  115.             [subpropList free];        /* to prevent a memory leak */
  116.         }
  117.     }
  118.     
  119.         /* Making this association will make the fetchgroup
  120.          * become the tableview data source.
  121.          */
  122.     [dbFetchGroup makeAssociationFrom:nil to:dbTableView];
  123.         /*
  124.          * free property list which is no longer needed
  125.          */
  126.     [propList free];
  127.     [window makeKeyAndOrderFront:self];
  128.     return self;
  129. }
  130.  
  131.  
  132. - free
  133. {
  134.     if (dbQualifier)
  135.         [dbQualifier free];
  136.     if (dbTableView)
  137.         [dbTableView free];
  138.     return [super free];
  139. }
  140.  
  141. /* DBDatabase delegate methods to log SQL queries  - Useful for debugging */
  142.  
  143. - (BOOL)db:aDb willEvaluateString:(const char*)aString usingBinder:aBinder
  144. {
  145.     fprintf(stderr, "SQL query:%s\n", aString);
  146.     return YES;
  147. }
  148.  
  149. @end
  150.