#import "MiniSQLAdaptorContext.h"
#import "MiniSQLAdaptorChannel.h"
#import "MiniSQLAdaptor.h"

#import <eoaccess/eoaccess.h>

@implementation MiniSQLAdaptorContext
- initWithAdaptor:(MiniSQLAdaptor *)anAdaptor
{
    [super init];
    
    adaptor = [anAdaptor retain];
    
    return self;
}


- (void) dealloc
{
    [adaptor release];
    [super   dealloc];
}


- (EOAdaptor *)adaptor;
// Returns the EOAdaptor that handles the connection within which the
// adaptor context works.
{
    return adaptor;
}


- (EOAdaptorChannel *) createAdaptorChannel
// Returns a new EOAdaptorChannel.  Returns nil if a new channel cannot 
// be created.  EOAdaptorContexts by default have no channels at all.  The 
// newly created channel retains its context. 
{
// only return one...
    if (channel) {
	return nil;
    } else {
	channel = [[[MiniSQLAdaptorChannel allocWithZone:[self zone]]
			initWithAdaptor:adaptor
			andContext:self]
			autorelease];

	return channel;
    }
}


- (BOOL)beginTransaction
// Attempts to begin a new transaction, nested within the current one if 
// nested transaction are supported, returning YES if successful and NO 
// if not. 
{
#ifdef REAL_TP_SUPPORT
    NSString           *string;
#endif

 // notify the delegate if possible...
    if (_delegateRespondsTo.willBegin) {
	EODelegateResponse  response;

	response = [_delegate adaptorContextWillBegin:self];

	if (response == EODelegateOverrides) {
	    return YES;
	}
	if (response != EODelegateApproves) {
	    return NO;
	}
    }

 // perform a sanity check...
    if ([channel isFetchInProgress]) {
	[adaptor reportError:@"Illegal attempt to begin a transaction while a fetch is in progress."];
	return NO;
    }

    transaction += 1;


#ifdef REAL_TP_SUPPORT
 // process transactions...
    if (transaction == 1) {
	string = @"BEGIN TRANSACTION";
    } else {
	string = [NSString stringWithFormat:@"SAVE TRANSACTION T_%d", transaction];
    }

    if (![channel evaluateExpression:string]) {
	transaction -= 1;
	return NO;
    }
#endif

    if (_delegateRespondsTo.didBegin)
	[_delegate adaptorContextDidBegin:self];

    return YES;
}


- (BOOL)commitTransaction
// Attempts to commit the last transaction begun, returning YES if
// successful and NO if not.
{
    BOOL                result;

    if (_delegateRespondsTo.willCommit) {
	EODelegateResponse  response;

	response = [_delegate adaptorContextWillCommit:self];

	if (response == EODelegateOverrides) {
	    return YES;
	}
	if (response != EODelegateApproves) {
	    return NO;
	}
    }

    if ([channel isFetchInProgress]) {
	[adaptor reportError:@"Illegal attempt to commit a transaction while a fetch is in progress."];
	return NO;
    }
    if (![self transactionNestingLevel]) {
	[adaptor reportError:@"Illegal attempt to commit a transaction when there are none in progress."];
	return NO;
    }

    if (transaction > 0) {
	result = YES;
#ifdef REAL_TP_SUPPORT
    // process transactions... 
	if (transaction == 1)
	    result = [channel evaluateExpression:@"COMMIT TRANSACTION"];

	if (result == YES) {
#endif
	    transaction -= 1;

	    if (_delegateRespondsTo.didCommit)
		[_delegate adaptorContextDidCommit:self];

	    return YES;
#ifdef REAL_TP_SUPPORT
	}
#endif
    }
    return NO;
}

- (BOOL)rollbackTransaction
// Attempts to roll back the last transaction begun, returning YES if
// successful and NO if not.
{
    if (_delegateRespondsTo.willRollback) {
	EODelegateResponse  response;

	response = [_delegate adaptorContextWillRollback:self];

	if (response == EODelegateOverrides) {
	    return YES;
	}
	if (response != EODelegateApproves) {
	    return NO;
	}
    }

    if (![self transactionNestingLevel]) {
    	[adaptor reportError:@"Illegal attempt to rollback a transaction when there are none in progress."];
	return NO;
    }

    if (transaction > 0) {
#ifdef REAL_TP_SUPPORT
	if (transaction == 1) {
	    string = @"ROLLBACK TRANSACTION";
	} else {
	    string = [NSString stringWithFormat:
		@"ROLLBACK TRANSACTION T_%d", transaction];
	}
	if ([channel evaluateExpression:string]) {
#endif
	    transaction -= 1;
	    if (_delegateRespondsTo.didRollback) {
		[_delegate adaptorContextDidRollback:self];
	    }
	    return YES;
#ifdef REAL_TP_SUPPORT
	}
#endif 
    }

    return NO;
}

- (BOOL)canNestTransactions
// Returns YES if the database server can nest transactions, NO
// otherwise.
{
    return YES;
}

- (unsigned)nestedTransactions
// Returns the number of transactions in progress. If transactions
// can nest, this number may be greater than one.
{
    return transaction;
}

- (unsigned int)transactionNestingLevel
// A cover for -nestedTransactions.
{
    return [self nestedTransactions];
}

- (void)transactionDidBegin
{
    transaction += 1;
}

- (void)transactionDidCommit
{
    if (transaction != 0) {
	transaction -= 1;
    }
}

- (void)transactionDidRollback
{
    if (transaction != 0) {
	transaction -= 1;
    }
}

- (BOOL)hasBusyChannels
// Returns YES if the receiver has channels that have outstanding
// operations (that is, have a fetch in progress), NO otherwise.
{
    return [channel isFetchInProgress] ? YES : NO; 
}

@end
