/* 
   test-fault.m

   Copyright (C) 1996 Free Software Foundation, Inc.

   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
   Date: 1996

   This file is part of the GNUstep Database Library.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with this library; see the file COPYING.LIB.
   If not, write to the Free Software Foundation,
   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include <Foundation/NSArray.h>
#include <Foundation/NSException.h>
#include <Foundation/NSObjCRuntime.h>

#include <extensions/objc-runtime.h>

#include <eoaccess/EOEntity.h>
#include <eoaccess/EOGenericRecord.h>

@class EOGenericRecord;

#include "test-fault.h"

static BOOL throwOnFault = NO;

@interface EOFaultResolver(Testing)
@end

@implementation EOFaultResolver(Testing)

- (BOOL)beforeFault
{
    if (throwOnFault)
	[NSException raise:@"UnexpectedFaultException" format:@""];
    return YES;
}

@end

@implementation TestFault

+ (void)setThrowOnFault:(BOOL)yn
{
    throwOnFault = yn;
}

- initWithFault:aFault
{
    fault = aFault;
    return self;
}

- faultInstance
{
    return fault;
}

+ fault_objectFaultWithPrimaryKey:(NSDictionary*)key
    entity:(EOEntity*)entity 
    databaseChannel:(EODatabaseChannel*)channel
    zone:(NSZone*)zone;
{
    return [[self alloc] initWithFault:
	[EOFault objectFaultWithPrimaryKey:key
	    entity:entity 
	    databaseChannel:channel
	    zone:zone]];
}

+ (NSArray*)fault_arrayFaultWithQualifier:(EOQualifier*)qualifier 
    fetchOrder:(NSArray*)fetchOrder 
    databaseChannel:(EODatabaseChannel*)channel
    zone:(NSZone*)zone;
{
    return [[self alloc] initWithFault:
	[EOFault arrayFaultWithQualifier:qualifier
	    fetchOrder:fetchOrder 
	    databaseChannel:channel
	    zone:zone]];
}

// Inquire about a fault

+ (BOOL)fault_isFault:aFault
{return [EOFault isFault:aFault];}

+ (void)fault_clearFault:aFault
{[EOFault clearFault:aFault];}

+ (Class)fault_targetClassForFault:aFault
{return [EOFault targetClassForFault:aFault];}

+ (NSDictionary*)fault_primaryKeyForFault:aFault
{return [EOFault primaryKeyForFault:aFault];}

+ (EOEntity*)fault_entityForFault:aFault
{return [EOFault entityForFault:aFault];}

+ (EOQualifier*)fault_qualifierForFault:aFault
{return [EOFault qualifierForFault:aFault];}

+ (NSArray*)fault_fetchOrderForFault:aFault
{return [EOFault fetchOrderForFault:aFault];}

+ (EODatabaseChannel*)fault_databaseChannelForFault:aFault
{return [EOFault databaseChannelForFault:aFault];}

// Non-Faulting Instance methods

+ fault_superclass
{return [EOFault superclass];}

+ (Class)fault_class
{return [EOFault class];}

+ (BOOL)fault_isKindOfClass:(Class)aClass
{return [EOFault isKindOfClass:aClass];}

+ (BOOL)fault_isMemberOfClass:(Class)aClass
{return [EOFault isMemberOfClass:aClass];}

+ (BOOL)fault_conformsToProtocol:(Protocol*)aProtocol
{return [EOFault conformsToProtocol:aProtocol];}

+ (BOOL)fault_respondsToSelector:(SEL)aSelector
{return [EOFault respondsToSelector:aSelector];}

+ fault_self
{return [EOFault self];}

+ (void)fault_dealloc
{[EOFault dealloc];}

+ fault_retain
{return [EOFault retain];}

+ (void)fault_release
{[EOFault release];}

+ fault_autorelease
{return [EOFault autorelease];}

+ (unsigned)fault_retainCount
{return [EOFault retainCount];}

+ (NSZone*)fault_zone
{return [EOFault zone];}

+ (BOOL)fault_isProxy
{return [EOFault isProxy];}

+ (NSString*)fault_description
{return [EOFault description];}

- fault_superclass
{return [fault superclass];}

- (Class)fault_class
{return [fault class];}

- (BOOL)fault_isKindOfClass:(Class)aClass
{return [fault isKindOfClass:aClass];}

- (BOOL)fault_isMemberOfClass:(Class)aClass
{return [fault isMemberOfClass:aClass];}

- (BOOL)fault_conformsToProtocol:(Protocol*)aProtocol
{return [fault conformsToProtocol:aProtocol];}

- (BOOL)fault_respondsToSelector:(SEL)aSelector
{return [fault respondsToSelector:aSelector];}

- fault_self
{return [fault self];}

- (void)fault_dealloc
{[fault dealloc];}

- fault_retain
{return [fault retain];}

- (void)fault_release
{[fault release];}

- fault_autorelease
{return [fault autorelease];}

- (unsigned)fault_retainCount
{return [fault retainCount];}

- (NSZone*)fault_zone
{return [fault zone];}

- (BOOL)fault_isProxy
{return [fault isProxy];}

- (NSString*)fault_description 
{return [fault description];}

@end /* test-fault */

@implementation TestFaultChannel

- init
{
    level = 0;
    fetching = NO;
    return self;
}

- databaseContext
{return self;}

- (BOOL)beginTransaction
{level++; return YES;}

- (BOOL)commitTransaction
{level--; return YES;}

- (void)rollbackTransaction;
{level--;}

- (int)transactionNestingLevel
{return level;}

- (BOOL)isFetchInProgress
{return fetching;}

- (BOOL)selectObjectsDescribedByQualifier:(EOQualifier*)qualifier
  fetchOrder:(NSArray*)fetchOrder
{
    index = 0;
    return YES;
}

- fetchWithZone:(NSZone*)zone
{
    id anObj;
    
    if (objects && index < [objects count]) {
	anObj = [objects objectAtIndex:index++];
	[EOFault clearFault:anObj];
	return anObj;
    }
    else
	return nil;
}

- (void)cancelFetch
{
    fetching = NO;
}

- setObjectsToFetch:(NSArray*)array
{
    [array retain];
    [objects release];
    objects = array;
    index = 0;
    return self;
}

- allocateObjectForRow:(NSDictionary*)row entity:(EOEntity*)entity 
  zone:(NSZone*)zone
{
    const char* class_name;
    Class class;
    
    class_name = [[entity className] cString];
    if (class_name)
	class = objc_get_class(class_name);
    else
	class = NULL;

    if (!class)
	class = [EOGenericRecord class];

    if (class == [EOGenericRecord class])
	class = [EOGenericRecord class];

    return [class allocWithZone:zone];
}

@end
