#ifndef WSCODBCDATABASE_H
#define WSCODBCDATABASE_H

#ifdef MSW
#include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sql.h>
#include <sqlext.h>

#include <WScom.h>
#include <WSCvariant.h>


#define CODBC_ACCESS_MODE_READ		0
#define CODBC_ACCESS_MODE_EDIT		1
#define CODBC_ACCESS_MODE_ADDNEW	2

struct _Col {
	SQLCHAR			colName[32];
	SQLSMALLINT		colNameLen;
	SQLSMALLINT		colType;
	SQLUINTEGER		colSize;
	SQLSMALLINT		colScale;
	SQLINTEGER		buffLen;
	SQLINTEGER		len;
	void*			buff;
};

class WSCdbDrvDatabase;
class WSCdbDrvRecord;
class WSCodbcRecord;
class WSCvodbc;

class WSCodbcDatabase
{
public:
	WSDLEX32 WSCodbcDatabase();
	WSDLEX32 virtual ~WSCodbcDatabase();
	
	WSDLEX32 virtual long    open(char* dsn, char* uid, char* pwd);
	WSDLEX32 virtual long    close();
	WSDLEX32 virtual long    beginTran();
	WSDLEX32 virtual long    commitTran();
	WSDLEX32 virtual long    abortTran();
	WSDLEX32 virtual long    sqlExecute(const char* stmt);
	WSDLEX32 virtual WSCbool isOpen();
	WSDLEX32 virtual void    getErrorMsg(char* szState, char* szMsg);
	WSDLEX32 virtual void    getErrorMsg(char* szMsg,long size);
	WSDLEX32 virtual void    setEncode(long code);
	WSDLEX32 virtual long    getEncode();

private:
	void getError(SQLHANDLE	hstmt);

public:
	WSCbool		_open;
	SQLHANDLE	_henv;
	SQLHANDLE	_hdbc;
	SQLCHAR		_szSqlState[6];
	SQLCHAR		_szErrorMsg[SQL_MAX_MESSAGE_LENGTH + 1];
	long		_encoding;
};

class WSCodbcRecord
{
public:
	WSDLEX32 WSCodbcRecord(WSCodbcDatabase* pDatabase);
	WSDLEX32 WSCodbcRecord(WSCvodbc* obj);
	WSDLEX32 virtual ~WSCodbcRecord();
	WSDLEX32 virtual long    open(const char* stmt);
	WSDLEX32 virtual long    open(const char* stmt, short eCousor, short eAccess = SQL_CONCUR_LOCK);
	WSDLEX32 virtual long    close();
	WSDLEX32 virtual WSCbool isEOF();
	WSDLEX32 virtual WSCbool isOpen();
	WSDLEX32 virtual long    getColValue(long index, WSCvariant* var);
	WSDLEX32 virtual long    getColValue(const char* name, WSCvariant* var);
	WSDLEX32 virtual long    getColStringValue(long index, char* var);
	WSDLEX32 virtual long    getColStringValue(const char* name, char* var);
	WSDLEX32 virtual long    setColValue(long index, WSCvariant var);
	WSDLEX32 virtual long    setColValue(const char* name, WSCvariant var);
	WSDLEX32 virtual long    edit();
	WSDLEX32 virtual long    update();
	WSDLEX32 virtual long    addnew();
	WSDLEX32 virtual long    deleterow();
	WSDLEX32 virtual long    moveNext();
	WSDLEX32 virtual long    movePrevious();
	WSDLEX32 virtual long    moveFirst();
	WSDLEX32 virtual long    moveLast();
	WSDLEX32 virtual long    getColName(long index, char* name);
	WSDLEX32 virtual long    getColIndex(const char* name);
	WSDLEX32 virtual long    getColType(long index);
	WSDLEX32 virtual long    getColType(const char* name);
	WSDLEX32 virtual long    getColLength(long index);
	WSDLEX32 virtual long    getColLength(const char* name);
	WSDLEX32 virtual long    getRowCount();
	WSDLEX32 virtual long    getColCount();
	WSDLEX32 virtual void    getErrorMsg(char* szState, char* szMsg);
	WSDLEX32 virtual WSCstring getErrorMessage();
	WSDLEX32 virtual long    isNull(long index);
	WSDLEX32 virtual long    isNull(const char* name);

private:
	void Cleanup(WSCodbcDatabase* pDatabase);
	long BindCols();
	void ReleaseCols();
	void getValue(int index, WSCvariant* var);
	void setValue(int index, WSCvariant* var);
	void getError(SQLHANDLE	hstmt);
	long getColTypeConv(long index);

public:
	WSCodbcDatabase*	_pDB;
	SQLHANDLE		_hstmt;
	WSCbool			_open;
	WSCbool			_eof;
	short			_Cols;
	_Col*			_fd;
	short			_access_mode;
	SQLCHAR			_szSqlState[6];
	SQLCHAR			_szErrorMsg[SQL_MAX_MESSAGE_LENGTH + 1];
	SQLINTEGER		_access;
	SQLINTEGER		_Cursor;
};

#endif		// WSCODBCDATABASE_H
