//
//  PersistentObjectContext.h
//  MCSQLite
//
//  Created by Mark Onyschuk on 4/6/08.
//  Copyright 2008 Marketcircle, Inc. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "sqlite3.h"

#import "MCSQLiteDefines.h"


enum {
	MCSQLiteSynchronousModeOff=0,
	MCSQLiteSynchronousModeNormal=1,
	MCSQLiteSynchronousModeFull=2
};

typedef NSUInteger MCSQLiteSynchronousMode;


@interface MCSQLiteContext : NSObject {
	sqlite3 *db;
	NSString *path;
	
	BOOL logSQL;
	int busyTimeout;
	NSUInteger transactionLevel;
    
    BOOL resetsConnectionAfterRunloop;
}

#pragma mark -
#pragma mark Initialization
+ (MCSQLiteContext *)contextWithPath:(NSString *)aPath createIfNotFound:(BOOL)create;
- (id)initWithPath:(NSString *)aPath createIfNotFound:(BOOL)create;

#pragma mark -
#pragma mark Accessors
- (sqlite3 *)db;
- (void)setDb:(sqlite3 *)aDb;

- (NSString *)path;
- (void)setPath:(NSString *)aPath;

- (BOOL)logSQL;
- (void)setLogSQL:(BOOL)flag;

- (int)busyTimeout;
- (void)setBusyTimeout:(int)timeout;

- (NSUInteger)transactionLevel;
- (void)setTransactionLevel:(NSUInteger)aTransactionLevel;

- (MCSQLiteSynchronousMode)synchronousMode;
- (void)setSynchronousMode:(MCSQLiteSynchronousMode)aMode;

/*!
 If you are in WAL mode, you cannot change the journal mode if other connections are open.
 Once set, WAL mode is persistent.
 */
- (NSString *)journalMode;
- (BOOL)setJournalMode:(NSString *)aJournalMode;

/*!
 If you are operating in WAL journal mode, then a checkpoint is attempted
 */
- (BOOL)checkpoint;

- (BOOL)resetsConnectionAfterRunloop;
- (void)setResetsConnectionAfterRunloop:(BOOL)flag;

/*!
 Note: You cannot change the cache size once in WAL mode
 */
- (BOOL)setCacheSize:(NSInteger)pages;

#pragma mark -
#pragma mark Low Level Database Operations
- (NSNumber *)lastRowID;

- (int)lastErrorCode;
- (NSString *)lastErrorMessage;

- (BOOL)executeSQL:(NSString *)sql;

- (BOOL)resultWithQuery:(NSString*)sql, ...;
- (BOOL)resultWithQuery:(NSString *)sql arguments:(NSArray *)anArray; 
- (BOOL)resultWithQuery:(NSString *)sql bindings:(id)aKVCConformingObject;

- (id)resultSetWithQuery:(NSString*)sql, ...;
- (id)resultSetWithQuery:(NSString *)sql arguments:(NSArray *)anArray; 
- (id)resultSetWithQuery:(NSString *)sql bindings:(id)aKVCConformingObject;

- (void)begin;
- (void)beginImmediate;
- (void)beginExclusive;

- (void)commit;
- (void)rollback;

- (void)vacuum;

- (BOOL)close;
- (BOOL)closeAndReopen;
- (BOOL)closeAndReopen:(BOOL)force;

- (void)setNeedsReset;

#pragma mark -
#pragma mark Cleanup
- (void)finalize;
- (void)dealloc;

#pragma mark -
#pragma mark Conveniences
- (BOOL)doesTableExistNamed: (NSString*)aTableName;


// These call use the concept of making a table in the database to mark operations that can leave the database invalid.
//  The unmark call removes the table and the is call checks for its existence
- (BOOL)markAsOperationInProgress;
- (BOOL)unmarkAsOperationInProgress;
- (BOOL)isOperationInProgress;


@end

@interface MCSQLiteContext (ObjectInterface)
- (BOOL)insertInto:(NSString *)aTable values:(NSDictionary *)anObject;
- (BOOL)replaceInto:(NSString *)aTable values:(NSDictionary *)anObject;
- (BOOL)deleteFrom:(NSString *)aTable rowsMatchingValues:(NSDictionary *)anObject;
- (BOOL)deleteFrom:(NSString *)aTable where:(NSString *)aWhereClause arguments:(NSArray *)arguments;
- (BOOL)update:(NSString *)aTable values:(NSDictionary *)anObject where:(NSString *)aWhereClause arguments:(NSArray *)arguments;

- (NSDictionary *)getSingleRowFrom:(NSString *)aTable where:(NSString *)aWhereClause arguments:(NSArray *)argument;
@end


@interface MCSQLiteContext (Deprecated)
- (BOOL)hadError MCDeprecatedMethod;
	// replace [myContext hadError] with [myContext lastErrorCode] != SQLITE_OK

- (id)executeQuery:(NSString *)sql, ... MCDeprecatedMethod;
- (id)executeQuery:(NSString *)sql arguments:(NSArray *)anArray MCDeprecatedMethod;
	// use resultSetWithQuery:...

- (BOOL)executeUpdate:(NSString *)sql, ... MCDeprecatedMethod;
- (BOOL)executeUpdate:(NSString *)sql arguments:(NSArray *)anArray	MCDeprecatedMethod;
	// use resultWithQuery:...

@end

