|
|
Sample Programs from NeXSTEP 3.3
/* Evaluator.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.
*
*
*
*/
#import <foundation/NSString.h>
#import <foundation/NSUtilities.h>
#import "ScrollViewExtras.h"
#import "Evaluator.h"
#import "EOFDelegateAdaptorCategory.h"
#define FAILURE NXLocalizedString("Failure:", NULL, \
"Message given to user when an operation has failed.")
#define CANNOT_CONNECT NXLocalizedString("Cannot connect to database", NULL, \
"Message given to user to explain what fails. ")
#define OK NXLocalizedString("OK", NULL, "Okay to continue ")
@implementation Evaluator
- initWithModelFile:(NSString *)filePath
{
char path[MAXPATHLEN];
BOOL result=NO;
[super init];
// open the model file and connect to the database
model = [[[EOModel alloc]
initWithContentsOfFile: filePath] autorelease];
if (!model)
return nil;
adaptor = [EOAdaptor adaptorWithModel:model];
if (!adaptor)
return nil;
context = [adaptor createAdaptorContext];
if (!context)
return nil;
channel = [context createAdaptorChannel];
if (!channel)
return nil;
if (![channel isOpen])
result = [channel openChannel];
if (result)
[resultsView sprintf:"Connection successful\n"];
else
[resultsView sprintf:"Connection failed\n"];
[[NXBundle mainBundle] getPath:path forResource:"SQLWindow" ofType:"nib"];
[NXApp loadNibFile:path owner:self withNames:NO];
[(Window *)[resultsView window] setDelegate:self];
[[resultsView window] setTitleAsFilename:[filePath cString]];
[[queryView docView] selectAll:self];
[[resultsView window] makeKeyAndOrderFront:self];
/*----------------------------------------------------------------------
* set up the channel delegate to SybaseDelegate for Sybase model files
* use EOFDelegateCategory for Oracle model files
*--------------------------------------------------------------------*/
if ([[adaptor name] isEqualToString:@"Sybase"]) {
sybaseDelegate = [[SybaseDelegate alloc] init];
[channel setDelegate:sybaseDelegate];
}
else {
sybaseDelegate = nil;
[channel setDelegate:[[EOFDelegateAdaptorCategory alloc] init]];
}
return self;
}
- free
{
[model release];
[adaptor release];
[context release];
[channel release];
if (sybaseDelegate)
[sybaseDelegate release];
return [super free];
}
- evaluate:sender
{
BOOL result = NO;
int charCount;
char *buffer = NULL;
NSDictionary *row;
/*----------------------------------------------------------------------
* get the SQL statement
*--------------------------------------------------------------------*/
if ((charCount = [[queryView docView] textLength]) > 0) {
buffer = malloc((charCount+1) * sizeof(char));
[[queryView docView] getSubstring:buffer start:0 length:charCount];
buffer[charCount] = 0;
while (charCount > 0 && buffer[--charCount] == '\n')
buffer[charCount] = 0;
[resultsView sprintf:"%s\n", buffer];
}
else {
[resultsView sprintf:"Can't execute an empty string!\n"];
return self;
}
/*----------------------------------------------------------------------
* evaluate the SQL statement
*--------------------------------------------------------------------*/
[context beginTransaction];
result = [channel evaluateExpression:
[[NSString alloc] initWithCString:(const char *)buffer]];
if (result){
[resultsView sprintf:"SQL successfully evaluated\n"];
while ([channel isFetchInProgress] == YES) {
// get the array of attributes from the result set
attributes = [channel describeResults];
// since the EO Framework attributes are stored as Attribute1,
// Attribute2, etc., build a dictionary to do conversion.
[self buildColumnNamesDictionary:attributes];
// The NSDictionary contains all the data for one row
while ((row = [channel fetchAttributes: attributes withZone:
[adaptor zone]]) != nil)
// read data back
[self readDataFromDict:row ];
}
[context commitTransaction];
}
else {
// do clean-up if SQL statement cannot be evaluated.
[resultsView sprintf:"SQL evaluation failed\n"];
if ([channel isFetchInProgress] == YES)
[channel cancelFetch];
[context rollbackTransaction];
}
free(buffer);
return self;
}
/* Build a dictionary where the Keys are Attribute1, Attribute2, etc.,
* while the values are the actual column names as specified in the
* database.
*/
- buildColumnNamesDictionary:(NSArray *) attributesArray
{
NSEnumerator *enumerator;
EOAttribute *attribute;
NSMutableArray *keys = [NSMutableArray array];
NSMutableArray *values = [NSMutableArray array];
enumerator = [attributesArray objectEnumerator];
while ((attribute = [enumerator nextObject]) != nil) {
[keys addObject:[attribute name]];
[values addObject:[attribute columnName]];
}
columnNamesDict = [NSDictionary dictionaryWithObjects:values
forKeys: keys];
return self;
}
/* Cycle through the key and value pairs of the dictionary
* and print them to result view
*
*/
- readDataFromDict:(NSDictionary *) dictionary
{
NSEnumerator *keyEnumerator;
NSString * key;
NSString * newKey;
id value;
char buffer[1024];
SybaseRowType rowType=0;
keyEnumerator = [dictionary keyEnumerator];
if (sybaseDelegate)
rowType = [sybaseDelegate currentRowType];
//print the full dictionary for Sybase regular rows or if the Oracle adaptor is used
if ( ((sybaseDelegate) && (rowType == SybaseRegularRow ))
|| (sybaseDelegate == nil) )
{
while ((key = [keyEnumerator nextObject]) != nil) {
newKey = [columnNamesDict objectForKey:[key description]];
value = [dictionary objectForKey:key];
sprintf(buffer, "%s: \t %s\n", [[newKey description] cString],
[[(NSObject *)value description] cString]);
[resultsView sprintf:buffer];
}
}
else {
// This must be one special sybase row
switch (rowType) {
case SybaseComputeRow:
case SybaseReturnStatusRow:
// print one row of data only
key = [keyEnumerator nextObject];
value = [dictionary objectForKey:key];
sprintf(buffer, "Row type: %s \t %s\n", (rowType == SybaseComputeRow) ?
"SybaseComputeRow": "SybaseReturnStatusRow",
[[(NSObject *)value description] cString]);
[resultsView sprintf:buffer];
sprintf(buffer, "************************************\n");
[resultsView sprintf:buffer];
break;
case SybaseReturnParameterRow:
// Exercise for the reader: How to format this row
[resultsView sprintf:"SybaseReturnParameterRow: No data printed\n"];
break;
case SybaseRegularRow:
default:
break;
}
}
return self;
}
- clear:sender
{
[resultsView clear:sender];
[[queryView docView] selectText:self];
return self;
}
- close:sender
{
// close the adaptor channel and disconnect from the database
[channel closeChannel];
// close the main window
[[NXApp mainWindow] performClose:sender];
return self;
}
/*--------------------------------------------------------------------------
* Announcing Trace Info
*------------------------------------------------------------------------*/
- (void) logString:(NSString *) aString
{
[resultsView sprintf: "%s", [aString cString]];
}
- (void) announce:sender selector:(SEL)selector
{
return [self announce:sender selector:selector with:nil];
}
- (void) announce:sender selector:(SEL)selector with:array
{
NSMutableString *string;
string = [NSMutableString stringWithFormat:@"BEGIN> {Sender = %s%s",
[[(NSObject *)[sender class] description] cString], "}" ];
[string appendFormat:@" \n\t{Delegate Method = %s} ", sel_getName(selector)];
if (array)
{
id object;
id verboseString = [NSMutableString stringWithCapacity:0];
id enumerator = [array objectEnumerator];
while ((object = [enumerator nextObject]) != nil)
[verboseString
appendFormat:@"\n\t{Argument = %s} \n\t{Argument Description = %s} ",
[[(NSObject *)[object class] description] cString],
[[(NSObject *) object description] cString]];
[string appendString:verboseString];
}
[string appendFormat:@"\n"];
[resultsView sprintf: "%s", [string cString]];
}
/* Window Delegate method -- constrain window resizing */
- windowWillResize:sender toSize:(NXSize *)frameSize
{
if ( frameSize->height < 230 ) frameSize->height= 230;
return self;
}
@end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.