home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.0 / NeXTSTEP3.0.iso / NextDeveloper / Examples / DatabaseKit / AddressBook / Controller.m < prev    next >
Text File  |  1992-07-09  |  7KB  |  247 lines

  1. /* Controller.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.  
  11. #import <appkit/appkit.h>
  12. #import <dbkit/dbkit.h>
  13. #import <objc/List.h>
  14. #import <objc/NXBundle.h>
  15. #import <sys/param.h>
  16. #import <libc.h>
  17.  
  18. #import "Controller.h"
  19. #import "AddressView.h"
  20. #import "Appender.h"
  21.  
  22.  
  23. #define FAILURE NXLocalizedString("Failure:", NULL, "Message given to user when connection to database can't be made")
  24. #define CANNOT_CONNECT NXLocalizedString("Couldn't connect to database", NULL, "Message given to user to explain what fails. ")
  25. #define CANNOT_ADD NXLocalizedString("Add operation failed", NULL, "Message given to user that add operation has failed")
  26. #define CANNOT_UPDATE NXLocalizedString("Update operation failed",NULL,"Message given to user that update operation has failed")
  27. #define CANNOT_DELETE NXLocalizedString("Delete operation failed",NULL,"Message given to user that delete operation has failed")
  28.  
  29. @implementation Controller
  30.  
  31. - appDidInit:sender
  32. {
  33.         /* Try to connect to the database specified using the Sybase Adaptor
  34.          * and the default login sa, NULL password, SYBASE server, and
  35.          * pubs database.
  36.          */
  37.        database = [[DBDatabase alloc]init];       
  38.     [database connectUsingAdaptor:"SybaseAdaptor"
  39.                                  andString:"sa@SYBASE/pubs"];
  40.  
  41.     if ( ![database isConnected] ) {
  42.             NXRunAlertPanel(FAILURE, CANNOT_CONNECT, "OK", NULL, NULL);
  43.             return self;
  44.             }
  45.         /* Once successfully connected, build the data to be displayed in the
  46.          * matrix
  47.          */
  48.     [self initRecordList];
  49.     [addressView loadCellsFrom:self];
  50.  
  51.         /* Assign the controller to become the database delegate */
  52.     [database setDelegate:self];
  53.  
  54.        cellMatrix = [addressView cellMatrix];
  55.     
  56.          /* Select a cell as a start */
  57.     [[cellMatrix selectCellAt:0 :0] sendAction];
  58.         /* Bring the main application window up front */
  59.     [theWindow makeKeyAndOrderFront:nil];
  60.                 
  61.        return self;
  62. }
  63.  
  64. /* Set up the DBRecordList object. Create a list of properties which contains
  65.  * all properties needed for display or updating.
  66.  */
  67. - initRecordList
  68. {
  69.     id firstName, lastName, phone;UD state, city, address, zipCode, contract;
  70.     List    *keyList;
  71.     
  72.             /* get the author table from the database */    
  73.     authorEntity = [database entityNamed:"authors"];
  74.     
  75.             /* get the properties  */
  76.     lastName = [authorEntity propertyNamed:"au_lname"];
  77.     firstName = [authorEntity propertyNamed:"au_fname"];
  78.     authId = [authorEntity propertyNamed:"au_id"];
  79.     
  80.      phone = [authorEntity propertyNamed:"phone"];
  81.     address = [authorEntity propertyNamed:"address"];
  82.     city = [authorEntity propertyNamed:"city"];
  83.     state = [authorEntity propertyNamed:"state"];
  84.     zipCode = [authorEntity propertyNamed:"zip"];      
  85.     contract = [authorEntity propertyNamed:"contract"];
  86.     
  87.           /* Set up the property list 
  88.          * Note that certain properties need to be defined in order
  89.          * for an Insert or Update operation to work. This depends
  90.          * on how your data dictionary has been defined. Here pubs
  91.          * is being used as the model.
  92.          */
  93.     propertyList = [[List alloc] init];
  94.     [propertyList addObject:authId];
  95.       [propertyList addObject:lastName];
  96.     [propertyList addObject:firstName];
  97.       [propertyList addObject:phone];
  98.     [propertyList addObject:address];
  99.     [propertyList addObject:city];
  100.     [propertyList addObject:state];
  101.     [propertyList addObject:zipCode];
  102.       [propertyList addObject:contract];
  103.  
  104.        recordList = [[DBRecordList alloc] init];
  105.     
  106.         /* A unique key is needed if you want to update or insert new
  107.          * data via the record list into the database. If no key is defined,
  108.          * the data retrieved via the  record list is read-only.
  109.          */
  110.     keyList = (List *)[[List alloc] init];
  111.     [keyList addObject:authId];
  112.     [recordList setKeyProperties:keyList];
  113.     [keyList free];
  114.  
  115.     [recordList addRetrieveOrder:DB_AscendingOrder for:lastName];
  116.     [recordList addRetrieveOrder:DB_AscendingOrder for:firstName];                    
  117.     [recordList setProperties:propertyList ofSource:authorEntity];
  118.     [recordList fetchUsingQualifier:nil];
  119.                                              
  120.        recordCount = [recordList count];
  121.     
  122.        return self;
  123. }
  124.     
  125. /* This method is called when selecting "Insert"
  126.  */
  127. - addRecords:sender
  128. {    
  129.     
  130.     int row;
  131.  
  132.     if (recordCount > 0) {
  133.     
  134.         if ( ![addressView addRecordFrom:sender at:(recordCount-1)]) {
  135.             NXRunAlertPanel(NULL, CANNOT_ADD, NULL, NULL, NULL);
  136.             return self;
  137.         }
  138.         
  139.     [self initRecordList];
  140.      [addressView loadCellsFrom:self];
  141.         /* Find the row of the newly inserted record */
  142.     row = [addressView getNewRow];
  143.        [cellUDix scrollCellToVisible:row :0];
  144.       [[cellMatrix selectCellAt:row:0] sendAction];
  145.       }
  146.       else
  147.           fprintf(stderr, "empty record list - NOP\n");
  148.       return self;
  149. }
  150.  
  151. /* This method gets called when selecting "Update"
  152.  */
  153. - updateRecords:sender
  154. {
  155.     int row;
  156.     
  157.     row = [cellMatrix selectedRow];
  158.     if ( ![addressView updateRecordFrom:sender at:row]) {
  159.         NXRunAlertPanel(NULL, CANNOT_UPDATE, NULL, NULL, NULL);
  160.         return self;
  161.     }
  162.         /* Redisplay the records */
  163.     [self initRecordList];
  164.      [addressView loadCellsFrom:self];
  165.         /* find the row of the updated record */
  166.     row = [addressView getNewRow];
  167.        [cellMatrix scrollCellToVisible:row :0];
  168.       [[cellMatrix selectCellAt:row:0] sendAction];
  169.  
  170.     return self;
  171. }
  172.  
  173.  
  174. - deleteRecords:sender
  175. {    
  176.     
  177.     int row;
  178.     
  179.     row = [cellMatrix selectedRow];
  180.     if (recordCount > 0) {
  181.     
  182.     if (![addressView deleteSelectedRecord:sender]) {
  183.             NXRunAlertPanel(NULL, CANNOT_DELETE, NULL, NULL, NULL);
  184.             return self;
  185.         }
  186.  
  187.     [self initRecordList];
  188.      [addressView loadCellsFrom:self];
  189.        [cellMatrix scrollCellToVisible:row :0];
  190.       [[cellMatrix selectCellAt:row:0] sendAction];
  191.       }
  192.       else
  193.           fprintf(stderr, "empty record list - NOP\n");
  194.     
  195.     return self;
  196. }    
  197. - getRecordList
  198. {
  199.     return recordList;
  200. }
  201.  
  202. - getPropertyList
  203. {
  204.     return propertyList;
  205. }
  206.  
  207. - (int)getRecordCount
  208. {
  209.     return recordCount;
  210. }
  211.  
  212. - showSQLPanel:sender
  213. {
  214.     [SQLPanel makeKeyAndOrderFront:nil];
  215.     return self;
  216. }
  217.  
  218. /* The use of NXBundle here ensures that the proper panel is loaded in case
  219.  * it's being localized.
  220. */
  221. - showInfoPanel:sender
  222. {
  223.     char path[MAXPATHLEN+1];
  224.  
  225.     if (!infoPanel) {
  226.          if ([[NXBundle mainBundle] 
  227.                 getPath:path forResource:"InfoPanel" ofType:"nib"]) {
  228.         infoPanel = [NXApp loadNibFile:path owner:NXApp withNames:NO 
  229.                                                     fromZone:[NXApp zone]];
  230.         }
  231.     }
  232.     [infoPanel orderFront:nil];
  233.     return self;
  234. }
  235.  
  236. /* DBDatabase delegate methods to log error messages and SQL queries */
  237.  
  238. - (BOOL)db:aDb willEvaluateString:(const char*)aString usingBinder:aBinder
  239. {
  240.     [appender appendToText:"SQL Query:\n"];
  241.     [appender appendToText:aString];
  242.     [appender appendToText:"\n"];
  243.     return YES;
  244. }
  245.  
  246. @end
  247.