//
//  MCPPostgresConnection.h
//  MCPostgresPersistence
//
//  Created by Michael Clark on 26/08/08.
//  Copyright 2008 Marketcircle Inc.. All rights reserved.
//

#import <Foundation/Foundation.h>

#import <SystemConfiguration/SystemConfiguration.h>
#import <IOKit/pwr_mgt/IOPMLib.h>
#import <IOKit/IOMessage.h>

#import <MCFoundation/MCPDatabaseConnection.h>

@class MCPGDatabase;
@class MCPConnectionInfo;
@class MCPModel;

@interface MCPPostgresConnection : MCPDatabaseConnection {
	MCPGDatabase*      dbAdaptor;
	
	id                 connectionDelegate;
		
	NSMutableArray*    _deletedObjects;
	
	NSNumber*             pkeyOffset;
	
	NSMutableDictionary*  tableColumnTranslations;
	NSMutableDictionary*  tableColumnAttributeTranslations;
	NSMutableDictionary*  entityLockIndexLookUp;
	
    // For power notifs
    io_connect_t          ioPort;
    IONotificationPortRef ioNotify;
    io_object_t           ioItr;
	// Used for Network change notifications
	SCDynamicStoreRef dynamicStoreRef;
	CFRunLoopSourceRef runLoopSourceRef;

}

- (id)initWithPGDatabase: (MCPGDatabase*)aDatabase model: (MCPModel*)aModel;

- (BOOL)connectWithConnectionInfo: (MCPConnectionInfo*)anInfo error: (NSError**)error;

- (void)reconnect;
- (MCPGDatabase *)databaseAdaptor;
- (BOOL)checkConnection;
- (void)releaseConnection; // Closes and then releases the database adaptor

- (BOOL)databaseConnectionEstablished: (BOOL)wasRecovery error: (NSError**)error;
  // Gets called when the connection to the database is established, either on first connect or recovery connect
  // Subclassers can override this method to perform connection based setup - should always call super FIRST
  // If part of the logic produces an error the method should return NO and supply an appropriate NSError


// Uses underlying PG calls to escape the given string.  
// It converts the NSString to a cstring using UTF8, escapes, then creates a new autoreleased NSString using UTF8 encoding
// If the PG call returns an error and exception is thrown.
- (NSString*)escapeStringForSQLInclusion: (NSString*)in_str;

// Method allows bindings to be passed in to go along with the whereClause - methods using a qualifier use this method
- (NSArray *)rawRowsForEntityNamed:(NSString *)aName
				 desiredAttributes:(NSArray*)attributes
				   withRawSQLWhere:(id)whereClause
					   sqlBindings:(NSDictionary*)bindings
							  from:(NSString *)from
						   groupBy:(NSString *)groupBy
							 order:(NSString *)orderClause
						fetchLimit:(long)fetchLimit
							 batch:(int)batchNumber
				   distinctResults:(BOOL)distinct
					  tableAliases:(MCPTableAliases *)tableAliases;



- (NSException *)executeStringSQL:(NSString *)sql;

- (NSException *)deleteOwnedRelationship:(MCPRelationship *)rel ofObject:(id)obj;
- (NSException *)nullifyToManyRelationship:(MCPRelationship *)rel ofObject:(id)obj;
- (NSString *)whereClauseForRelationship:(MCPRelationship *)relation ofObject:(id)obj; 

- (void)executeBatchedDatabaseCommands:(NSArray *)commands;

- (NSNumber *)pkeyOffset;
- (void)setPkeyOffset:(NSNumber *)aPkeyOffset;

- (id)connectionDelegate;
- (void)setConnectionDelegate:(id)aConnectionDelegate;

@end



@interface NSObject(MCPPostgresConnectionDelegate)

- (void)connectionFatallyLostDatabaseConnection: (MCPPostgresConnection*)connection;

- (void)connectionWillBeginRecovery: (MCPPostgresConnection*)connection;
- (void)connectionRecovered: (MCPPostgresConnection*)connection;
- (void)connectionFailedRecovery: (MCPPostgresConnection*)connection withError: (NSError*)error;

@end

