File:  [NeXTSTEP 3.3 examples] / Examples / DatabaseKit / PubsDemo / Controller.m
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:49:00 2018 UTC (8 years, 1 month ago) by root
Branches: NeXT, MAIN
CVS tags: NeXTSTEP33, HEAD
Sample Programs from NeXSTEP 3.3

/* 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 <libc.h>
#import "Controller.h"

/* Define localized strings */
#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.")
#define EMPTY_STRING NXLocalizedString("Cannot accept empty string", NULL, "Notify user that empty string input is not valid.")
#define INSERT_FAILED NXLocalizedString("Insert operation failed", NULL, "Notify user that insert operation has failed.")

static char newAuthorID[100];

@implementation Controller

/* Extract the actual database and recordlist from the DBModule UI Object
 */ 
-appDidInit:sender
{
		/* Notify the user if the database can't be found */
	if (![DBDatabase findDatabaseNamed:"SybaseDemo" connect:YES]) {
		NXRunAlertPanel(NULL,INSTALL_MODEL, "OK", NULL, NULL);
		return self;
	}	
  	dbDatabase = [dbModule database];
	dbFetchGroup = [dbModule rootFetchGroup];
	dbRecordList = [dbFetchGroup recordList];
	recordOrder = DB_AscendingOrder;
	dbQualifier = nil;
	
			/* Initialize the retrieval order to be ascending order
			 */
	sortProp = [[dbModule entity] propertyNamed:"lastName"];
			
	[dbRecordList addRetrieveOrder:recordOrder for:sortProp];
		
			/* Assign the controller object to be the delegate of dbFetchGroup.
			 * See also the method fetchGroup:didInsertRecordAt:
			 */
	[dbFetchGroup setDelegate:self];
	
			/* Assign the record list of the root fetchgroup to be the delegate
			 * of DBBinder. This is a convenient way to make sure that the proper
			 * qualifier will be used at fetch time.
			 * See also the method binderWillSelect:
			 */
	[[dbFetchGroup recordList] setBinderDelegate:self];
	
			/* Create a DBValue instance to be used later for accessing data
			 * inside a record list.
			 */
	aValue = [[DBValue alloc] init];
	
	[theWindow makeKeyAndOrderFront:nil];
	return self;
}

/* Change the retrieval order for the record list. To be set before pressing
 * SELECT.
 */
-changeRetrieveOrder:sender
{
	recordOrder = [sender selectedTag];
	return self;
}

/* Build the DBQualifier before a SELECT operation. Note that you should give
 * the external names as defined in dbModel for properties.
 */
- buildSelectQualifier:sender
{
	const char * state;
	id stateProperty;
	
	state = [qualifierField stringValue];
	if (!strcmp(state,"")) {
		dbQualifier = nil;
		return nil;
	}
	else {
	stateProperty = [[dbModule entity] propertyNamed:"state"];
	dbQualifier = [[DBQualifier allocFromZone:[self zone] ] 
		initForEntity:[dbModule entity]
		fromDescription:"%@ LIKE %s", stateProperty, state];
	}
	return self;
}

/* This method is called when the SELECT button is pressed.
 * NOTE: If the qualifier form has a NULL string, the source is set to nil,
 * which means that ALL records will be fetched. 
 */
- select:sender
{
	id	source;

	[self buildSelectQualifier:nil];	
	if (!dbQualifier)
		source = nil;
	else
		source = [dbModule entity];
		
	[dbFetchGroup fetchContentsOf:source usingQualifier:dbQualifier];
	
		/* Update the display */
	[self display];
	return self;
}

/* This method is called when the INSERT button is pressed. Check for blank
 * record fields before the actual INSERT.
 */
- insert:sender
{
	if ([self checkInputRecord:sender]==nil)
		NXRunAlertPanel(NULL,INSERT_FAILED, "OK", NULL, NULL);
	else
		[dbModule insertNewRecord:sender];
	[self display];
	return self;
}
	
/* Try to highlight the newly added row based on the token "newAuthorID".
 * This method is called everytime the SELECT button is pressed.
 * If there is no match, the first row is highlighted by default.
 */
- display
{
	int rowCount, i, row;
	id socSecProperty;
	const char *keyValue;
	
	row = 0;
		/* Search for a match only if the ID has meaningful data */
	if ( strlen(newAuthorID) > 0 ) {
		rowCount = [dbTableView rowCount];
		socSecProperty = [[dbModule entity] propertyNamed:"authorID"];
		for (i= 0; i < rowCount; i++) {
			[dbRecordList getValue:aValue forProperty:socSecProperty at:i];
			keyValue = (const char *)[aValue stringValue];
			if (!strcmp(keyValue, newAuthorID)) {
				row = i;
				break; }
		}
	}
	[dbFetchGroup setCurrentRecord:row];
	[dbTableView display];
	return self;
}



/* DBFetchGroup delegate methods */

/*
 * This method is called at each SELECT operation.
 */
- fetchGroupWillFetch:fetchGroup
{
	[dbRecordList addRetrieveOrder:recordOrder for:sortProp];
	return self;
}

/*
 * This method is called at each INSERT operation.
 */

- fetchGroup:fetchGroup didInsertRecordAt:(int)index
{
		/* Fill in the record fields before inserting the new record */
	[self fillNewRecordAt:index];
	return self;
}


/* 
 * This delegate method is called at each SAVE operation.
 */
- fetchGroupDidSave:fetchGroup
{
	[self clearData];
	return self;
}

/* 
 * This binder delegate method is called at each SELECT operation so that 
 * the proper qualifier is used.
 */
 
- (BOOL)binderWillSelect:aBinder
{
  [aBinder setQualifier:dbQualifier];
  return YES;
}

/* checkInputRecord
 * Check if any input field is empty.
 */
- checkInputRecord:sender
{
	int	i;
	const char *inputStr;
		
	for ( i = 0; i < 9; i++ ) {
 		inputStr = (const char *)[formMatrix stringValueAt:i];
			/* If the string is empty, abort the operation */
		if  ( inputStr == NULL){
			NXRunAlertPanel (NULL,EMPTY_STRING,NULL, NULL, NULL);
			return nil;
			}
	}
 		return self;
}

/* fillNewRecordAt:(int) index
 * Method used for INSERT operation 
 * Get the user input from the form cells. 
 */
- fillNewRecordAt:(int)index
{
	const char *inputString;
	int	contractNum;
		
			/* set last name */		
	inputString = (const char *)[formMatrix stringValueAt:0];
	[aValue setStringValue:inputString];
	[dbRecordList setValue:aValue 
				forProperty:[[dbModule entity] propertyNamed:"lastName"]
				at:index];	
				
		/* set first name */
	inputString = (const char *)[formMatrix stringValueAt:1];
	[aValue setStringValue:(const char *)inputString];
	[dbRecordList setValue: aValue
				forProperty: [[dbModule entity] propertyNamed:"firstName"]
				at:index];
				
		/* get the ssn or author id */
 	inputString = (const char *)[formMatrix stringValueAt:2];
	[aValue setStringValue:inputString];
	[dbRecordList setValue:aValue 
				forProperty:[[dbModule entity] propertyNamed:"authorID"]
				at:index];
	strcpy( newAuthorID, inputString);
			
			/* set address */
	inputString = (const char *)[formMatrix stringValueAt:3];
	[aValue setStringValue: inputString];
	[dbRecordList setValue: aValue
				forProperty:[[dbModule entity] propertyNamed:"address"]
				at:index];

			/* set city name */
	inputString = (const char *)[formMatrix stringValueAt:4];
	[aValue setStringValue: inputString];
	[dbRecordList setValue: aValue
			forProperty:[[dbModule entity] propertyNamed:"city"]
			at:index];

			/* set state */
	inputString = (const char *)[formMatrix stringValueAt:5];
	[aValue setStringValue: inputString];
	[dbRecordList setValue: aValue
			forProperty:[[dbModule entity] propertyNamed:"state"]
			at:index];

			/* set zip code */
	inputString = (const char *)[formMatrix stringValueAt:6];
	[aValue setStringValue: inputString];
	[dbRecordList setValue: aValue
			forProperty:[[dbModule entity] propertyNamed:"zipCode"]
			at:index ];
	
			/* set phone number */
	inputString = (const char *)[formMatrix stringValueAt:7];
	[aValue setStringValue: inputString];
	[dbRecordList setValue:aValue
				forProperty:[[dbModule entity] propertyNamed:"phone"]
				at:index];
	
			/* set contract number */
	contractNum = [formMatrix intValueAt:8];
	[aValue setIntValue:contractNum];
	[dbRecordList setValue: aValue
				forProperty:[[dbModule entity] propertyNamed:"contract"]
				at:index];

	return self;
}


/* Clear the form cells after each SAVE operation to avoid creating
 * duplicate records.
 */
- clearData
{
	int i;
	
	for (i = 0; i < 9; i++)
		[formMatrix setStringValue:""at:i];
	return self;
}

@end


unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.