#include <config.h>
#include <stdio.h>

#include <Foundation/NSString.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSData.h>
#include <Foundation/NSDate.h>
#include <Foundation/NSValue.h>
#include <Foundation/NSUtilities.h>
#include <Foundation/NSProcessInfo.h>
#include <Foundation/NSAutoreleasePool.h>

#include <eoaccess/EOModel.h>
#include <eoaccess/EOEntity.h>
#include <eoaccess/EOQualifier.h>
#include <eoaccess/EOAdaptor.h>
#include <eoaccess/EOAdaptorContext.h>
#include <eoaccess/EOAdaptorChannel.h>

#include <eoadaptors/Sybase/SybaseAdaptor.h>

@interface MyObject : NSObject
@end

@implementation MyObject
- (BOOL)adaptor:(EOAdaptor*)adaptor willReportError:(NSString*)error
{
    NSLog (@"Sybase error: %@", error);
    return YES;
}
@end

void main(int argc, char** argv, char** env)
{
    NSString* filename = @"models/test-sybdb.eomodel";
    EOModel* model;
    id adaptor;
    id adaptorContext;
    id adaptorChannel;
    id qualifier;
    id row = [[NSMutableDictionary new] autorelease];
    id table_entity;
    char* data1 = "binary $i";
    char* data2 = "varbinary $i";
    char* image = "image $i";
    id delegate = [MyObject new];
    NSArray* attrs;
    int i, j, n = 50;

#if LIB_FOUNDATION_LIBRARY
    [NSProcessInfo initializeWithArguments:argv count:argc environment:env];
#endif

    [SybaseAdaptor setLogsMessages:NO];
    model = [[[EOModel alloc] initWithContentsOfFile:filename]
			autorelease];
    adaptor = [EOAdaptor adaptorWithModel:model];
    table_entity = [model entityNamed:@"Table1"];

    [adaptor setDelegate:delegate];
    adaptorContext = [adaptor createAdaptorContext];
    adaptorChannel = [adaptorContext createAdaptorChannel];
    [adaptorChannel setDebugEnabled:NO];
    [adaptorChannel openChannel];

    [adaptorContext beginTransaction];
    [adaptorChannel evaluateExpression:@"delete TABLE1"];
    [adaptorContext commitTransaction];

    [adaptorContext beginTransaction];
    for (i = 0; i < n; i++) {
	id pool = [NSAutoreleasePool new];

	[row setObject:[NSNumber numberWithChar:i] forKey:@"Tinyint"];
	[row setObject:[NSNumber numberWithShort:i] forKey:@"Smallint"];
	[row setObject:[NSNumber numberWithInt:i] forKey:@"Int"];
	[row setObject:[NSNumber numberWithDouble:i] forKey:@"Float"];
	[row setObject:[NSNumber numberWithDouble:i] forKey:@"Money"];
	[row setObject:[NSCalendarDate date] forKey:@"Datetime"];
	[row setObject:@"text $i" forKey:@"Text"];
	[row setObject:[NSData dataWithBytes:image length:strlen(image)]
	     forKey:@"Image"];
	[row setObject:@"char $i" forKey:@"Char"];
	[row setObject:@"varchar $i" forKey:@"Varchar"];
	[row setObject:[NSData dataWithBytes:data1 length:strlen(data1)]
	     forKey:@"Binary"];
	[row setObject:[NSData dataWithBytes:data2 length:strlen(data2)]
	     forKey:@"Varbinary"];
//	[row setObject:[NSNumber numberWithChar:i % 2] forKey:@"Bit"];
	if (![adaptorChannel insertRow:row forEntity:table_entity])
	    printf ("insertRow:forEntity: failed\n");

	[pool release];
    }
    [adaptorContext commitTransaction];

    attrs = [NSArray arrayWithObjects:
		    [table_entity attributeNamed:@"Tinyint"],
		    [table_entity attributeNamed:@"Smallint"],
		    [table_entity attributeNamed:@"Int"],
		    [table_entity attributeNamed:@"Float"],
		    [table_entity attributeNamed:@"Money"],
		    [table_entity attributeNamed:@"Datetime"],
		    [table_entity attributeNamed:@"Text"],
		    [table_entity attributeNamed:@"Image"],
		    [table_entity attributeNamed:@"Char"],
		    [table_entity attributeNamed:@"Varchar"],
		    [table_entity attributeNamed:@"Binary"],
		    [table_entity attributeNamed:@"Varbinary"],
//		    [table_entity attributeNamed:@"Bit"],
		    nil];
    [adaptorContext beginTransaction];
    if (![adaptorChannel selectAttributes:attrs
			describedByQualifier:nil fetchOrder:nil lock:NO])
	printf ("selectAttributes:describedByQualifier:fetchOrder:lock: failed\n");

    while ((row = [adaptorChannel fetchAttributes:attrs withZone:NULL]))
	;
//	puts ([[row description] cString]);

    [adaptorContext commitTransaction];

    [adaptorContext beginTransaction];

    for (i = n - 1, j = n; i >= 0; i--, j++) {
	id pool = [NSAutoreleasePool new];

	row = [NSMutableDictionary dictionaryWithCapacity:3];
	[row setObject:[NSNumber numberWithChar:i % 128] forKey:@"Tinyint"];
	[row setObject:[NSNumber numberWithShort:i] forKey:@"Smallint"];
	[row setObject:[NSNumber numberWithInt:i] forKey:@"Int"];
	qualifier = [EOQualifier qualifierForPrimaryKey:row
				 entity:table_entity];
	[row setObject:[NSNumber numberWithChar:j] forKey:@"Tinyint"];
	[row setObject:[NSNumber numberWithShort:j] forKey:@"Smallint"];
	[row setObject:[NSNumber numberWithInt:j] forKey:@"Int"];
	[row setObject:[NSNumber numberWithDouble:j] forKey:@"Float"];
	[row setObject:[NSNumber numberWithDouble:j] forKey:@"Money"];
	[row setObject:[NSCalendarDate date] forKey:@"Datetime"];
	[row setObject:@"text $j" forKey:@"Text"];
	[row setObject:[NSData dataWithBytes:image length:strlen(image)]
	     forKey:@"Image"];
	[row setObject:@"char $j" forKey:@"Char"];
	[row setObject:@"varchar $j" forKey:@"Varchar"];
	[row setObject:[NSData dataWithBytes:data1 length:strlen(data1)]
	     forKey:@"Binary"];
	[row setObject:[NSData dataWithBytes:data2 length:strlen(data2)]
	     forKey:@"Varbinary"];

	if (![adaptorChannel updateRow:row describedByQualifier:qualifier])
	    printf ("updateRow:describedByQualifier: failed");

	[pool release];
    }

    [adaptorContext commitTransaction];

}
