home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer) / NeXT_Developer-3.3.iso / NextDeveloper / Examples / DatabaseKit / PubsDemo / Controller.m < prev    next >
Encoding:
Text File  |  1993-07-14  |  8.0 KB  |  314 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. #import <appkit/appkit.h>     
  11. #import    <dbkit/dbkit.h>
  12. #import <libc.h>
  13. #import "Controller.h"
  14.  
  15. /* Define localized strings */
  16. #define INSTALL_MODEL NXLocalizedString("Please install SybaseDemo.dbmodela into your project directory and restart.", NULL, "Notify user that SybaseDemo.dbmodela must be installed in his project directory.")
  17. #define EMPTY_STRING NXLocalizedString("Cannot accept empty string", NULL, "Notify user that empty string input is not valid.")
  18. #define INSERT_FAILED NXLocalizedString("Insert operation failed", NULL, "Notify user that insert operation has failed.")
  19.  
  20. static char newAuthorID[100];
  21.  
  22. @implementation Controller
  23.  
  24. /* Extract the actual database and recordlist from the DBModule UI Object
  25.  */ 
  26. -appDidInit:sender
  27. {
  28.         /* Notify the user if the database can't be found */
  29.     if (![DBDatabase findDatabaseNamed:"SybaseDemo" connect:YES]) {
  30.         NXRunAlertPanel(NULL,INSTALL_MODEL, "OK", NULL, NULL);
  31.         return self;
  32.     }    
  33.       dbDatabase = [dbModule database];
  34.     dbFetchGroup = [dbModule rootFetchGroup];
  35.     dbRecordList = [dbFetchGroup recordList];
  36.     recordOrder = DB_AscendingOrder;
  37.     dbQualifier = nil;
  38.     
  39.             /* Initialize the retrieval order to be ascending order
  40.              */
  41.     sortProp = [[dbModule entity] propertyNamed:"lastName"];
  42.             
  43.     [dbRecordList addRetrieveOrder:recordOrder for:sortProp];
  44.         
  45.             /* Assign the controller object to be the delegate of dbFetchGroup.
  46.              * See also the method fetchGroup:didInsertRecordAt:
  47.              */
  48.     [dbFetchGroup setDelegate:self];
  49.     
  50.             /* Assign the record list of the root fetchgroup to be the delegate
  51.              * of DBBinder. This is a convenient way to make sure that the proper
  52.              * qualifier will be used at fetch time.
  53.              * See also the method binderWillSelect:
  54.              */
  55.     [[dbFetchGroup recordList] setBinderDelegate:self];
  56.     
  57.             /* Create a DBValue instance to be used later for accessing data
  58.              * inside a record list.
  59.              */
  60.     aValue = [[DBValue alloc] init];
  61.     
  62.     [theWindow makeKeyAndOrderFront:nil];
  63.     return self;
  64. }
  65.  
  66. /* Change the retrieval order for the record list. To be set before pressing
  67.  * SELECT.
  68.  */
  69. -changeRetrieveOrder:sender
  70. {
  71.     recordOrder = [sender selectedTag];
  72.     return self;
  73. }
  74.  
  75. /* Build the DBQualifier before a SELECT operation. Note that you should give
  76.  * the external names as defined in dbModel for properties.
  77.  */
  78. - buildSelectQualifier:sender
  79. {
  80.     const char * state;
  81.     id stateProperty;
  82.     
  83.     state = [qualifierField stringValue];
  84.     if (!strcmp(state,"")) {
  85.         dbQualifier = nil;
  86.         return nil;
  87.     }
  88.     else {
  89.     stateProperty = [[dbModule entity] propertyNamed:"state"];
  90.     dbQualifier = [[DBQualifier allocFromZone:[self zone] ] 
  91.         initForEntity:[dbModule entity]
  92.         fromDescription:"%@ LIKE %s", stateProperty, state];
  93.     }
  94.     return self;
  95. }
  96.  
  97. /* This method is called when the SELECT button is pressed.
  98.  * NOTE: If the qualifier form has a NULL string, the source is set to nil,
  99.  * which means that ALL records will be fetched. 
  100.  */
  101. - select:sender
  102. {
  103.     id    source;
  104.  
  105.     [self buildSelectQualifier:nil];    
  106.     if (!dbQualifier)
  107.         source = nil;
  108.     else
  109.         source = [dbModule entity];
  110.         
  111.     [dbFetchGroup fetchContentsOf:source usingQualifier:dbQualifier];
  112.     
  113.         /* Update the display */
  114.     [self display];
  115.     return self;
  116. }
  117.  
  118. /* This method is called when the INSERT button is pressed. Check for blank
  119.  * record fields before the actual INSERT.
  120.  */
  121. - insert:sender
  122. {
  123.     if ([self checkInputRecord:sender]==nil)
  124.         NXRunAlertPanel(NULL,INSERT_FAILED, "OK", NULL, NULL);
  125.     else
  126.         [dbModule insertNewRecord:sender];
  127.     [self display];
  128.     return self;
  129. }
  130.     
  131. /* Try to highlight the newly added row based on the token "newAuthorID".
  132.  * This method is called everytime the SELECT button is pressed.
  133.  * If there is no match, the first row is highlighted by default.
  134.  */
  135. - display
  136. {
  137.     int rowCount, i, row;
  138.     id socSecProperty;
  139.     const char *keyValue;
  140.     
  141.     row = 0;
  142.         /* Search for a match only if the ID has meaningful data */
  143.     if ( strlen(newAuthorID) > 0 ) {
  144.         rowCount = [dbTableView rowCount];
  145.         socSecProperty = [[dbModule entity] propertyNamed:"authorID"];
  146.         for (i= 0; i < rowCount; i++) {
  147.             [dbRecordList getValue:aValue forProperty:socSecProperty at:i];
  148.             keyValue = (const char *)[aValue stringValue];
  149.             if (!strcmp(keyValue, newAuthorID)) {
  150.                 row = i;
  151.                 break; }
  152.         }
  153.     }
  154.     [dbFetchGroup setCurrentRecord:row];
  155.     [dbTableView display];
  156.     return self;
  157. }
  158.  
  159.  
  160.  
  161. /* DBFetchGroup delegate methods */
  162.  
  163. /*
  164.  * This method is called at each SELECT operation.
  165.  */
  166. - fetchGroupWillFetch:fetchGroup
  167. {
  168.     [dbRecordList addRetrieveOrder:recordOrder for:sortProp];
  169.     return self;
  170. }
  171.  
  172. /*
  173.  * This method is called at each INSERT operation.
  174.  */
  175.  
  176. - fetchGroup:fetchGroup didInsertRecordAt:(int)index
  177. {
  178.         /* Fill in the record fields before inserting the new record */
  179.     [self fillNewRecordAt:index];
  180.     return self;
  181. }
  182.  
  183.  
  184. /* 
  185.  * This delegate method is called at each SAVE operation.
  186.  */
  187. - fetchGroupDidSave:fetchGroup
  188. {
  189.     [self clearData];
  190.     return self;
  191. }
  192.  
  193. /* 
  194.  * This binder delegate method is called at each SELECT operation so that 
  195.  * the proper qualifier is used.
  196.  */
  197.  
  198. - (BOOL)binderWillSelect:aBinder
  199. {
  200.   [aBinder setQualifier:dbQualifier];
  201.   return YES;
  202. }
  203.  
  204. /* checkInputRecord
  205.  * Check if any input field is empty.
  206.  */
  207. - checkInputRecord:sender
  208. {
  209.     int    i;
  210.     const char *inputStr;
  211.         
  212.     for ( i = 0; i < 9; i++ ) {
  213.          inputStr = (const char *)[formMatrix stringValueAt:i];
  214.             /* If the string is empty, abort the operation */
  215.         if  ( inputStr == NULL){
  216.             NXRunAlertPanel (NULL,EMPTY_STRING,NULL, NULL, NULL);
  217.             return nil;
  218.             }
  219.     }
  220.          return self;
  221. }
  222.  
  223. /* fillNewRecordAt:(int) index
  224.  * Method used for INSERT operation 
  225.  * Get the user input from the form cells. 
  226.  */
  227. - fillNewRecordAt:(int)index
  228. {
  229.     const char *inputString;
  230.     int    contractNum;
  231.         
  232.             /* set last name */        
  233.     inputString = (const char *)[formMatrix stringValueAt:0];
  234.     [aValue setStringValue:inputString];
  235.     [dbRecordList setValue:aValue 
  236.                 forProperty:[[dbModule entity] propertyNamed:"lastName"]
  237.                 at:index];    
  238.                 
  239.         /* set first name */
  240.     inputString = (const char *)[formMatrix stringValueAt:1];
  241.     [aValue setStringValue:(const char *)inputString];
  242.     [dbRecordList setValue: aValue
  243.                 forProperty: [[dbModule entity] propertyNamed:"firstName"]
  244.                 at:index];
  245.                 
  246.         /* get the ssn or author id */
  247.      inputString = (const char *)[formMatrix stringValueAt:2];
  248.     [aValue setStringValue:inputString];
  249.     [dbRecordList setValue:aValue 
  250.                 forProperty:[[dbModule entity] propertyNamed:"authorID"]
  251.                 at:index];
  252.     strcpy( newAuthorID, inputString);
  253.             
  254.             /* set address */
  255.     inputString = (const char *)[formMatrix stringValueAt:3];
  256.     [aValue setStringValue: inputString];
  257.     [dbRecordList setValue: aValue
  258.                 forProperty:[[dbModule entity] propertyNamed:"address"]
  259.                 at:index];
  260.  
  261.             /* set city name */
  262.     inputString = (const char *)[formMatrix stringValueAt:4];
  263.     [aValue setStringValue: inputString];
  264.     [dbRecordList setValue: aValue
  265.             forProperty:[[dbModule entity] propertyNamed:"city"]
  266.             at:index];
  267.  
  268.             /* set state */
  269.     inputString = (const char *)[formMatrix stringValueAt:5];
  270.     [aValue setStringValue: inputString];
  271.     [dbRecordList setValue: aValue
  272.             forProperty:[[dbModule entity] propertyNamed:"state"]
  273.             at:index];
  274.  
  275.             /* set zip code */
  276.     inputString = (const char *)[formMatrix stringValueAt:6];
  277.     [aValue setStringValue: inputString];
  278.     [dbRecordList setValue: aValue
  279.             forProperty:[[dbModule entity] propertyNamed:"zipCode"]
  280.             at:index ];
  281.     
  282.             /* set phone number */
  283.     inputString = (const char *)[formMatrix stringValueAt:7];
  284.     [aValue setStringValue: inputString];
  285.     [dbRecordList setValue:aValue
  286.                 forProperty:[[dbModule entity] propertyNamed:"phone"]
  287.                 at:index];
  288.     
  289.             /* set contract number */
  290.     contractNum = [formMatrix intValueAt:8];
  291.     [aValue setIntValue:contractNum];
  292.     [dbRecordList setValue: aValue
  293.                 forProperty:[[dbModule entity] propertyNamed:"contract"]
  294.                 at:index];
  295.  
  296.     return self;
  297. }
  298.  
  299.  
  300. /* Clear the form cells after each SAVE operation to avoid creating
  301.  * duplicate records.
  302.  */
  303. - clearData
  304. {
  305.     int i;
  306.     
  307.     for (i = 0; i < 9; i++)
  308.         [formMatrix setStringValue:""at:i];
  309.     return self;
  310. }
  311.  
  312. @end
  313.  
  314.