home *** CD-ROM | disk | FTP | other *** search
- /* Controller.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 <appkit/appkit.h>
- #import <dbkit/dbkit.h>
- #import <objc/List.h>
- #import <objc/NXBundle.h>
- #import <sys/param.h>
- #import <libc.h>
-
- #import "Controller.h"
- #import "AddressView.h"
-
-
- #define FAILURE NXLocalizedString("Failure:", NULL, "Message given to user when connection to database can't be made")
- #define CANNOT_CONNECT NXLocalizedString("Couldn't connect to database", NULL, "Message given to user to explain what fails. ")
- #define CANNOT_ADD NXLocalizedString("Add operation failed", NULL, "Message given to user that add operation has failed")
- #define CANNOT_UPDATE NXLocalizedString("Update operation failed",NULL,"Message given to user that update operation has failed")
- #define CANNOT_DELETE NXLocalizedString("Delete operation failed",NULL,"Message given to user that delete operation has failed")
-
- @implementation Controller
-
- - appDidInit:sender
- {
- /* Try to connect to the database specified using the Sybase Adaptor
- * and the default login sa, NULL password, SYBASE server, and
- * pubs database.
- */
- database = [[DBDatabase alloc]init];
- [database connectUsingAdaptor:"SybaseAdaptor"
- andString:"sa@SYBASE/pubs"];
-
- if ( ![database isConnected] ) {
- NXRunAlertPanel(FAILURE, CANNOT_CONNECT, "OK", NULL, NULL);
- return self;
- }
- /* Once successfully connected, build the data to be displayed in the
- * matrix
- */
- [self initRecordList];
- [addressView loadCellsFrom:self];
-
- /* Assign the controller to become the database delegate */
- [database setDelegate:self];
-
- cellMatrix = [addressView cellMatrix];
-
- /* Select a cell as a start */
- [[cellMatrix selectCellAt:0 :0] sendAction];
- /* Bring the main application window up front */
- [theWindow makeKeyAndOrderFront:nil];
-
- return self;
- }
-
- /* Set up the DBRecordList object. Create a list of properties which contains
- * all properties needed for display or updating.
- */
- - initRecordList
- {
- id firstName, lastName, phone;
- id state, city, address, zipCode, contract;
- List *keyList;
-
- if (recordList)
- [recordList free];
- if (propertyList)
- [propertyList free];
-
- /* get the author table from the database */
- authorEntity = [database entityNamed:"authors"];
-
- /* get the properties */
- lastName = [authorEntity propertyNamed:"au_lname"];
- firstName = [authorEntity propertyNamed:"au_fname"];
- authId = [authorEntity propertyNamed:"au_id"];
-
- phone = [authorEntity propertyNamed:"phone"];
- address = [authorEntity propertyNamed:"address"];
- city = [authorEntity propertyNamed:"city"];
- state = [authorEntity propertyNamed:"state"];
- zipCode = [authorEntity propertyNamed:"zip"];
- contract = [authorEntity propertyNamed:"contract"];
-
- /* Set up the property list
- * Note that certain properties need to be defined in order
- * for an Insert or Update operation to work. This depends
- * on how your data dictionary has been defined. Here pubs
- * is being used as the model.
- */
- propertyList = [[List alloc] init];
- [propertyList addObject:authId];
- [propertyList addObject:lastName];
- [propertyList addObject:firstName];
- [propertyList addObject:phone];
- [propertyList addObject:address];
- [propertyList addObject:city];
- [propertyList addObject:state];
- [propertyList addObject:zipCode];
- [propertyList addObject:contract];
-
- recordList = [[DBRecordList alloc] init];
-
-
- /* A unique key is needed if you want to update or insert new
- * data via the record list into the database. If no key is defined,
- * the data retrieved via the record list is read-only.
- * This is needed here, since we do not use a dbmodel to define
- * the key.
- */
- keyList = (List *)[[List alloc] init];
- [keyList addObject:authId];
- [recordList setKeyProperties:keyList];
- [keyList free];
-
- /* You must set the properties FIRST before setting the retrieve order */
- [recordList setProperties:propertyList ofSource:authorEntity];
-
- [recordList addRetrieveOrder:DB_AscendingOrder for:lastName];
- [recordList addRetrieveOrder:DB_AscendingOrder for:firstName];
- [recordList fetchUsingQualifier:nil];
- recordCount = [recordList count];
-
- return self;
- }
-
- /* This method is called when selecting "Insert"
- */
- - addRecords:sender
- {
-
- int row;
-
- if (recordCount > 0) {
-
- if ( ![addressView addRecordFrom:sender at:(recordCount-1)]) {
- NXRunAlertPanel(NULL, CANNOT_ADD, NULL, NULL, NULL);
- return self;
- }
-
- [self initRecordList];
- [addressView loadCellsFrom:self];
- /* Find the row of the newly inserted record */
- row = [addressView getNewRow];
- [cellMatrix scrollCellToVisible:row :0];
- [[cellMatrix selectCellAt:row:0] sendAction];
- }
- else
- fprintf(stderr, "empty record list - NOP\n");
- return self;
- }
-
- /* This method gets called when selecting "Update"
- */
- - updateRecords:sender
- {
- int row;
-
- row = [cellMatrix selectedRow];
- if ( ![addressView updateRecordFrom:sender at:row]) {
- NXRunAlertPanel(NULL, CANNOT_UPDATE, NULL, NULL, NULL);
- return self;
- }
- /* Redisplay the records */
- [self initRecordList];
- [addressView loadCellsFrom:self];
- /* find the row of the updated record */
- row = [addressView getNewRow];
- [cellMatrix scrollCellToVisible:row :0];
- [[cellMatrix selectCellAt:row:0] sendAction];
-
- return self;
- }
-
-
- - deleteRecords:sender
- {
-
- int row;
-
- row = [cellMatrix selectedRow];
- if (recordCount > 0) {
-
- if (![addressView deleteSelectedRecord:sender]) {
- NXRunAlertPanel(NULL, CANNOT_DELETE, NULL, NULL, NULL);
- return self;
- }
-
- [self initRecordList];
- [addressView loadCellsFrom:self];
- [cellMatrix scrollCellToVisible:row :0];
- [[cellMatrix selectCellAt:row:0] sendAction];
- }
- else
- fprintf(stderr, "empty record list - NOP\n");
-
- return self;
- }
- - getRecordList
- {
- return recordList;
- }
-
- - getPropertyList
- {
- return propertyList;
- }
-
- - (int)getRecordCount
- {
- return recordCount;
- }
-
- - showSQLPanel:sender
- {
- [SQLPanel makeKeyAndOrderFront:nil];
- return self;
- }
-
- - showInfoPanel:sender
- {
- if (!infoPanel) {
- infoPanel = [NXApp loadNibSection:"InfoPanel.nib" owner:NXApp
- withNames:NO];
- }
- [infoPanel orderFront:nil];
- return self;
- }
-
- - appWillTerminate:sender
- {
- /* deallocate what has been allocated */
- if (recordList)
- [recordList free];
- if (propertyList)
- [propertyList free];
- return self;
- }
-
- /* DBDatabase delegate methods to log error messages and SQL queries */
-
- - (BOOL)db:aDb willEvaluateString:(const unsigned char*)aString
- usingBinder:aBinder
- {
- [textObj appendToText:"SQL Query:\n"];
- [textObj appendToText:aString];
- [textObj appendToText:"\n"];
- return YES;
- }
-
- @end
-
- @implementation Text(printResults)
-
- - appendToText:(const char *)newText
- {
- int currentLength = [self textLength];
-
- [self setSel:currentLength :currentLength];
- [self replaceSel:newText];
- [self scrollSelToVisible];
- return self;
- }
-
- @end
-