#include <WSCdb.h>
#include <WSCodbcDatabase.h>
#include <WSCvodbc.h>
#include <WSClocaleSet.h>
#include "udebug.h"

//#define VC_TEST		// VC++ test use

WSCodbcDatabase::WSCodbcDatabase()
{
	TRACE_U(("WSCodbcDatabase::WSCodbcDatabase start"));
	
	_open = False;
	_henv = SQL_NULL_HANDLE;
	_hdbc = SQL_NULL_HANDLE;
	_encoding = -1;
	TRACE_U(("WSCodbcDatabase::WSCodbcDatabase end"));
}
WSCodbcDatabase::~WSCodbcDatabase()
{
	TRACE_U(("WSCodbcDatabase::~WSCodbcDatabase"));

	close();
	
	TRACE_U(("WSCodbcDatabase::~WSCodbcDatabase end"));
}
long WSCodbcDatabase::open(char* dsn, char* uid, char* pwd)
{
	TRACE_U(("WSCodbcDatabase::open start"));

	SQLRETURN	sqlrc = SQL_SUCCESS;
// update 2002/06/05
	if(isOpen()) {
		close();
	}
	_open = False;
	
	sqlrc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &_henv);
	if(sqlrc != SQL_SUCCESS) {
		TRACE_U(("WSCodbcDatabase::open SQLAllocHandle(SQL_HANDLE_ENV) Error"));
		getError(NULL);
		return WS_ERR;
	}
	sqlrc = SQLSetEnvAttr(_henv, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);
	if (sqlrc != SQL_SUCCESS && sqlrc != SQL_SUCCESS_WITH_INFO) {
		TRACE_U(("WSCodbcDatabase::open SQLSetEnvAttr(SQL_ATTR_ODBC_VERSION) Error"));
		getError(NULL);
		return WS_ERR;
	}
	sqlrc = SQLAllocHandle(SQL_HANDLE_DBC, _henv, &_hdbc);
	if(sqlrc != SQL_SUCCESS) {
		TRACE_U(("WSCodbcDatabase::open SQLAllocHandle(SQL_HANDLE_DBC) Error"));
		getError(NULL);
		return WS_ERR;
	}
	sqlrc = SQLSetConnectAttr(_hdbc, SQL_ATTR_AUTOCOMMIT, (void *)SQL_AUTOCOMMIT_ON, SQL_NTS);
	if (sqlrc != SQL_SUCCESS) {
		TRACE_U(("WSCodbcDatabase::open SQLSetConnectAttr(SQL_ATTR_AUTOCOMMIT) Error"));
		getError(NULL);
		return WS_ERR;
	}
	sqlrc = SQLConnect(_hdbc, (SQLCHAR*)dsn, SQL_NTS, (SQLCHAR*)uid, SQL_NTS, (SQLCHAR*)pwd, SQL_NTS);
	if (sqlrc != SQL_SUCCESS && sqlrc != SQL_SUCCESS_WITH_INFO) {
		TRACE_U(("WSCodbcDatabase::open SQLConnect() Error"));
		getError(NULL);
		return WS_ERR;
	}
	_open = True;
	
	TRACE_U(("WSCodbcDatabase::open end"));
	return WS_NO_ERR;
}
long WSCodbcDatabase::close()
{
	TRACE_U(("WSCodbcDatabase::close start"));
	SQLRETURN	sqlrc = SQL_SUCCESS;
	if(_hdbc) {
		TRACE_U(("WSCodbcDatabase::close SQLDisconnect()"));
		sqlrc = SQLDisconnect(_hdbc);
		TRACE_U(("WSCodbcDatabase::close SQLFreeHandle(SQL_HANDLE_DBC)"));
		sqlrc = SQLFreeHandle(SQL_HANDLE_DBC, _hdbc);
		_hdbc = NULL;
	}
	if(_henv) {
		TRACE_U(("WSCodbcDatabase::close SQLFreeHandle(SQL_HANDLE_ENV)"));
		sqlrc = SQLFreeHandle(SQL_HANDLE_ENV, _henv);
		_henv = NULL;
	}
	_open = False;
	_encoding = -1;
	TRACE_U(("WSCodbcDatabase::close end"));
	return WS_NO_ERR;
}
long WSCodbcDatabase::beginTran()
{
	TRACE_U(("WSCodbcDatabase::beginTran start"));
	SQLRETURN	sqlrc = SQL_SUCCESS;
	sqlrc = SQLSetConnectAttr(_hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, SQL_NTS);
	if (sqlrc != SQL_SUCCESS) {
		TRACE_U(("WSCodbcDatabase::beginTran SQLSetConnectAttr(SQL_ATTR_AUTOCOMMIT) Error"));
		getError(NULL);
		return WS_ERR;
	}
	TRACE_U(("WSCodbcDatabase::beginTran end"));
	return WS_NO_ERR;
}
long WSCodbcDatabase::commitTran()
{
	TRACE_U(("WSCodbcDatabase::commitTran start"));
	SQLRETURN	sqlrc = SQL_SUCCESS;
	sqlrc = SQLEndTran(SQL_HANDLE_DBC, _hdbc, SQL_COMMIT);
	if (sqlrc != SQL_SUCCESS) {
		TRACE_U(("WSCodbcDatabase::commitTran SQLEndTran()"));
		getError(NULL);
		return WS_ERR;
	}
	TRACE_U(("WSCodbcDatabase::commitTran end"));
	return WS_NO_ERR;
}
long WSCodbcDatabase::abortTran()
{
	TRACE_U(("WSCodbcDatabase::abortTran start"));
	SQLRETURN	sqlrc = SQL_SUCCESS;
	sqlrc = SQLEndTran(SQL_HANDLE_DBC, _hdbc, SQL_ROLLBACK);
	if (sqlrc != SQL_SUCCESS) {
		TRACE_U(("WSCodbcDatabase::abortTran SQLEndTran()"));
		getError(NULL);
		return WS_ERR;
	}
	TRACE_U(("WSCodbcDatabase::abortTran end"));
	return WS_NO_ERR;
}
long WSCodbcDatabase::sqlExecute(const char* stmt)
{
	TRACE_U(("WSCodbcDatabase::sqlExecute start"));

	SQLRETURN	sqlrc = SQL_SUCCESS;
	SQLHANDLE	hstmt;
// update 2002/06/05
	if(!isOpen()) {
		TRACE_U(("WSCodbcDatabase::sqlExecute not open error"));
		return WS_ERR;
	}
	sqlrc = SQLAllocHandle(SQL_HANDLE_STMT, _hdbc, &hstmt);
	if (sqlrc != SQL_SUCCESS) {
		TRACE_U(("WSCodbcDatabase::sqlExecute SQLAllocHandle() Error"));
		getError(NULL);
		return WS_ERR;
	}
    sqlrc = SQLExecDirect(hstmt, (SQLCHAR*)stmt, SQL_NTS);
//	SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
//	if (sqlrc != SQL_SUCCESS) {
// update 2002/06/05
	if (sqlrc < SQL_SUCCESS) {
		TRACE_U(("WSCodbcDatabase::sqlExecute SQLExecDirect() Error"));
		getError(hstmt);
		SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
		return WS_ERR;
	}
	SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
	TRACE_U(("WSCodbcDatabase::sqlExecute end"));
	return WS_NO_ERR;
}
WSCbool WSCodbcDatabase::isOpen()
{
	return _open;
}
void WSCodbcDatabase::getError(SQLHANDLE hstmt)
{
	TRACE_U(("WSCodbcDatabase::getError start"));

	SQLINTEGER	fNativeError;
	SQLSMALLINT	cbErrorMsgMax = sizeof(_szErrorMsg);
	SQLSMALLINT	cbErrorMsg = sizeof(_szErrorMsg);

	SQLError(_henv, 
			 _hdbc, 
			 hstmt, 
			 _szSqlState, 
			 &fNativeError, 
			 _szErrorMsg, 
			 cbErrorMsgMax, 
			 &cbErrorMsg);

	TRACE_U(("WSCodbcDatabase::getError State:%s messgae:%s", _szSqlState, _szErrorMsg));
	TRACE_U(("WSCodbcDatabase::getError end"));
}

void WSCodbcDatabase::getErrorMsg(char* szState, char* szMsg)
{
	TRACE_U(("WSCodbcDatabase::getErrorMsg start"));
	
	strcpy(szState, (char*)_szSqlState);
	strcpy(szMsg, (char*)_szErrorMsg);
	
	TRACE_U(("WSCodbcDatabase::getErrorMsg end"));
}

void WSCodbcDatabase::getErrorMsg(char* szMsg,long size)
{
	TRACE_U(("WSCodbcDatabase::getErrorMsg start"));
	
      char szStat[6];
      char szErrorMsg[SQL_MAX_MESSAGE_LENGTH + 1];
      char buf[SQL_MAX_MESSAGE_LENGTH + 1+32];
      getErrorMsg(szStat,szErrorMsg);
      sprintf(buf,"status:%s message:%s",szStat,szErrorMsg);
      strncpy(szMsg,buf,size);
// update 2002/06/05
      szMsg[size] = '\0';
      
	TRACE_U(("WSCodbcDatabase::getErrorMsg end"));
}
void WSCodbcDatabase::setEncode(long code)
{
	_encoding = code;
}
long WSCodbcDatabase::getEncode()
{
	return _encoding;
}



/////
WSCodbcRecord::WSCodbcRecord(WSCodbcDatabase* pDatabase)
{
	TRACE_U(("WSCodbcRecord::WSCodbcRecord start"));

// update 2002/06/06
#if 0
	_pDB = pDatabase;
	_hstmt = NULL;
	_open = False;
	_eof = True;
	_Cols = 0;
	_fd = NULL;
	_access_mode = CODBC_ACCESS_MODE_READ;
	memset(_szSqlState, '\0', sizeof(_szSqlState));
	memset(_szErrorMsg, '\0', sizeof(_szErrorMsg));
#endif

	Cleanup(pDatabase);

	TRACE_U(("WSCodbcRecord::WSCodbcRecord end"));
}
WSCodbcRecord::WSCodbcRecord(WSCvodbc* pDatabase)
{
	TRACE_U(("WSCodbcRecord::WSCodbcRecord start"));
	
// update 2002/06/06
#if 0
	_pDB = pDatabase->getODBCDatabase();
	_hstmt = NULL;
	_open = False;
	_eof = True;
	_Cols = 0;
	_fd = NULL;
	_access_mode = CODBC_ACCESS_MODE_READ;
	_access = ReadWrite;
	memset(_szSqlState, '\0', sizeof(_szSqlState));
	memset(_szErrorMsg, '\0', sizeof(_szErrorMsg));
#endif

	Cleanup(pDatabase->getODBCDatabase());

	TRACE_U(("WSCodbcRecord::WSCodbcRecord end"));
}
void WSCodbcRecord::Cleanup(WSCodbcDatabase* pDatabase)
{
	_pDB = pDatabase;
	_hstmt = NULL;
	_open = False;
	_eof = True;
	_Cols = 0;
	_fd = NULL;
	_access_mode = CODBC_ACCESS_MODE_READ;
	_Cursor = SQL_CURSOR_STATIC;
	_access = SQL_CONCUR_LOCK;
	memset(_szSqlState, '\0', sizeof(_szSqlState));
	memset(_szErrorMsg, '\0', sizeof(_szErrorMsg));
}
WSCodbcRecord::~WSCodbcRecord()
{
	TRACE_U(("WSCodbcRecord::~WSCodbcRecord start"));

	close();

// update 2002/06/05
	_pDB = NULL;

	TRACE_U(("WSCodbcRecord::~WSCodbcRecord end"));
}
long WSCodbcRecord::open(const char* stmt)
{
	return open(stmt, SQL_CURSOR_STATIC, SQL_CONCUR_LOCK);
}
long WSCodbcRecord::open(const char* stmt, short eCousor, short eAccess)
{
	TRACE_U(("WSCodbcRecord::open start"));

	SQLRETURN	sqlrc = SQL_SUCCESS;
// update 2002/06/05
	if(_pDB == NULL) {
		TRACE_U(("WSCodbcRecord::open WSCodbcDatabase not open error"));
		return WS_ERR;
	}
	if(_pDB->_hdbc == NULL) {
		TRACE_U(("WSCodbcRecord::open WSCodbcDatabase hdbc not open error"));
		return WS_ERR;
	}
	if(_hstmt) {
//		TRACE_U(("WSCodbcRecord::open SQLFreeHandle(SQL_HANDLE_STMT)"));
//		SQLFreeHandle(SQL_HANDLE_STMT, _hstmt);
		close();
	}
	_open = False;
	sqlrc = SQLAllocHandle(SQL_HANDLE_STMT, _pDB->_hdbc, &_hstmt);
	if (sqlrc != SQL_SUCCESS) {
		TRACE_U(("WSCodbcRecord::open SQLAllocHandle(SQL_HANDLE_STMT) Error"));
		getError(_hstmt);
		return WS_ERR;
	}
// update 2002/06/05
//	sqlrc = SQLSetStmtAttr(_hstmt, SQL_CURSOR_TYPE, (void*)SQL_CURSOR_STATIC, SQL_NTS);
	_Cursor = eCousor;
	sqlrc = SQLSetStmtAttr(_hstmt, SQL_ATTR_CURSOR_TYPE, (void*)_Cursor, SQL_NTS);

	_access = eAccess;
	if(_Cursor == SQL_CURSOR_KEYSET_DRIVEN || _access == SQL_CONCUR_READ_ONLY) {
		sqlrc = SQLSetStmtAttr(_hstmt, SQL_ATTR_CONCURRENCY, (void*)_access , SQL_NTS);
		if (sqlrc != SQL_SUCCESS) {
			TRACE_U(("WSCodbcRecord::open SQLSetStmtAttr(SQL_ATTR_CONCURRENCY) Error"));
			getError(_hstmt);
			return WS_ERR;
		}
	}
//

    sqlrc = SQLExecDirect(_hstmt, (SQLCHAR*)stmt, SQL_NTS);
	if (sqlrc != SQL_SUCCESS) {
		TRACE_U(("WSCodbcRecord::open SQLExecDirect() Error"));
		getError(_hstmt);
		return WS_ERR;
	}

	if(BindCols() != WS_NO_ERR) {
		return WS_ERR;
	}

	_open = True;
	_eof = False;

	moveNext();

	TRACE_U(("WSCodbcRecord::open end"));
	return WS_NO_ERR;
}
long WSCodbcRecord::close()
{
	TRACE_U(("WSCodbcRecord::close start"));

	if(_hstmt) {
		TRACE_U(("WSCodbcRecord::close SQLFreeHandle(SQL_HANDLE_STMT)"));
		SQLFreeHandle(SQL_HANDLE_STMT, _hstmt);
		_hstmt = NULL;
	}
	ReleaseCols();
// update 2002/06/05
//	_pDB = NULL;
	_open = False;
	_eof = True;

	TRACE_U(("WSCodbcRecord::close end"));
	return WS_NO_ERR;
}
WSCbool WSCodbcRecord::isEOF()
{
	return _eof;
}
WSCbool WSCodbcRecord::isOpen()
{
	return _open;
}
long WSCodbcRecord::getColValue(long index, WSCvariant* var)
{
	if(index < 0 || index >= _Cols) {
		return WS_ERR;
	}
	getValue(index, var);
	return WS_NO_ERR;
}
long WSCodbcRecord::getColValue(const char* name, WSCvariant* var)
{
	return getColValue(getColIndex(name), var);
}
long WSCodbcRecord::getColStringValue(long index, char* var)
{
	if(index < 0 || index >= _Cols) {
		return WS_ERR;
	}
	strcpy(var, (char*)_fd[index].buff);
	
	return WS_NO_ERR;
}
long WSCodbcRecord::getColStringValue(const char* name, char* var)
{
	return getColStringValue(getColIndex(name), var);
}
long WSCodbcRecord::setColValue(long index, WSCvariant var)
{
	if(index < 0 || index >= _Cols) {
		return WS_ERR;
	}
	if(_access_mode == CODBC_ACCESS_MODE_READ) {
		return WS_ERR;
	}
	setValue(index, &var);
	return WS_NO_ERR;
}
long WSCodbcRecord::setColValue(const char* name, WSCvariant var)
{
	return setColValue(getColIndex(name), var);
}
long WSCodbcRecord::edit()
{
// update 2002/06/06
//	if(isEOF()) {
	if(isEOF() || _access == SQL_CONCUR_READ_ONLY || _Cursor != SQL_CURSOR_KEYSET_DRIVEN) {
		return WS_ERR;
	}
	_access_mode = CODBC_ACCESS_MODE_EDIT;

	return WS_NO_ERR;
}
long WSCodbcRecord::addnew()
{
// update 2002/06/06
//	if(isEOF()) {
	if(isOpen() || _access == SQL_CONCUR_READ_ONLY || _Cursor != SQL_CURSOR_KEYSET_DRIVEN) {
		return WS_ERR;
	}
	for(int i = 0; i < _Cols; i++) {
		memset(_fd[i].buff, '\0', _fd[i].buffLen);
	}
	_access_mode = CODBC_ACCESS_MODE_ADDNEW;
	return WS_NO_ERR;
}
long WSCodbcRecord::update()
{
	SQLSMALLINT	Operation;
	SQLRETURN	sqlrc = SQL_SUCCESS;

	if(_access_mode == CODBC_ACCESS_MODE_READ) {
		return WS_ERR;
	}
	if(_access_mode == CODBC_ACCESS_MODE_ADDNEW) {
		Operation = SQL_ADD;
	} else {
		Operation = SQL_UPDATE;
	}
	_access_mode = CODBC_ACCESS_MODE_READ;
	sqlrc = SQLSetPos(_hstmt, 1, Operation, SQL_LOCK_NO_CHANGE);
	if (sqlrc != SQL_SUCCESS) {
		TRACE_U(("WSCodbcRecord::update SQLSetPos() Error"));
		getError(_hstmt);
		return WS_ERR;
	}
	return WS_NO_ERR;
}
long WSCodbcRecord::deleterow()
{
	SQLRETURN	sqlrc = SQL_SUCCESS;

// update 2002/06/06
//	if(_access_mode == CODBC_ACCESS_MODE_READ) {
	if(isEOF() || _access == SQL_CONCUR_READ_ONLY || _Cursor != SQL_CURSOR_KEYSET_DRIVEN) {
		return WS_ERR;
	}
	_access_mode = CODBC_ACCESS_MODE_READ;
	sqlrc = SQLSetPos(_hstmt, 1, SQL_DELETE, SQL_LOCK_NO_CHANGE); 
	if (sqlrc != SQL_SUCCESS) {
		TRACE_U(("WSCodbcRecord::deleterow SQLSetPos() Error"));
		getError(_hstmt);
		return WS_ERR;
	}
	return WS_NO_ERR;
}
long WSCodbcRecord::moveNext()
{
	SQLRETURN	sqlrc = SQL_SUCCESS;
	if(_eof) {
		return WS_ERR;
	}
	_access_mode = CODBC_ACCESS_MODE_READ;
// update 2002/06/05
//    sqlrc = SQLFetch(_hstmt);
	sqlrc = SQLFetchScroll(_hstmt, SQL_FETCH_NEXT , 0);
	if(sqlrc == SQL_NO_DATA_FOUND) {
		_eof = True;
	}
	return WS_NO_ERR;
}
long WSCodbcRecord::movePrevious()
{
	SQLRETURN	sqlrc = SQL_SUCCESS;
	_access_mode = CODBC_ACCESS_MODE_READ;
	sqlrc = SQLFetchScroll(_hstmt, SQL_FETCH_PRIOR, 1);
	if(sqlrc == SQL_ROW_SUCCESS) {
		_eof = False;
	}
	return WS_NO_ERR;
}
long WSCodbcRecord::moveFirst()
{
	SQLRETURN	sqlrc = SQL_SUCCESS;
	_access_mode = CODBC_ACCESS_MODE_READ;
	sqlrc = SQLFetchScroll(_hstmt, SQL_FETCH_FIRST, 1);
	if(sqlrc == SQL_ROW_SUCCESS) {
		_eof = False;
	}
	return WS_NO_ERR;
}
long WSCodbcRecord::moveLast()
{
	SQLRETURN	sqlrc = SQL_SUCCESS;
	if(_eof) {
		return WS_ERR;
	}
	_access_mode = CODBC_ACCESS_MODE_READ;
	sqlrc = SQLFetchScroll(_hstmt, SQL_FETCH_LAST, 1);
	return WS_NO_ERR;
}
long WSCodbcRecord::getColName(long index, char* name)
{
	if(!isOpen()) {
		return -1;
	}
	if(index < 0 || index >= _Cols) {
		return WS_ERR;
	}
	strcpy(name, (char*)_fd[index].colName);
	return WS_NO_ERR;
}
long WSCodbcRecord::getColIndex(const char* name)
{
	if(!isOpen()) {
		return -1;
	}
	for(int i = 0; i < _Cols; i++) {
		if(WSGFstricmp((char*)_fd[i].colName, (char*)name) == 0) {
			return i;
		}
	}
	return -1;
}
long WSCodbcRecord::getColType(long index)
{
	if(!isOpen()) {
		return -1;
	}
	if(index < 0 || index >= _Cols) {
		return -1;
	}
//	return _fd[index].colType;
	return getColTypeConv(index);
}
long WSCodbcRecord::getColType(const char* name)
{
	return getColType(getColIndex(name));
}
long WSCodbcRecord::getColLength(long index)
{
	if(!isOpen()) {
		return -1;
	}
	if(index < 0 || index >= _Cols) {
		return -1;
	}
	return _fd[index].buffLen - 1;
}
long WSCodbcRecord::getColLength(const char* name)
{
	return getColType(getColIndex(name));
}

long WSCodbcRecord::getRowCount()
{
	SQLRETURN	sqlrc = SQL_SUCCESS;
	long nCount = -1;

    sqlrc = SQLRowCount(_hstmt, (SQLINTEGER*)&nCount);

	return nCount;
}
long WSCodbcRecord::getColCount()
{
	return _Cols;
}
long WSCodbcRecord::BindCols()
{
	TRACE_U(("WSCodbcRecord::BindCols start"));

	SQLRETURN	sqlrc = SQL_SUCCESS;
	SQLINTEGER	colDataDisplaySize;
	int i;

    sqlrc = SQLNumResultCols(_hstmt, &_Cols);
	if (sqlrc != SQL_SUCCESS || _Cols < 1) {
		TRACE_U(("WSCodbcRecord::BindCols SQLNumResultCols() Error"));
		getError(_hstmt);
		return WS_ERR;
	}
	_fd = new _Col[_Cols];
	memset(_fd, '\0', sizeof(_Col) * _Cols);

    for(i = 0; i < _Cols; i++ ) {
		sqlrc = SQLDescribeCol(_hstmt,
                               (SQLSMALLINT)(i+1),
							   _fd[i].colName,
							   sizeof(_fd[i].colName),
							   &_fd[i].colNameLen,
							   &_fd[i].colType,
							   &_fd[i].colSize,
							   &_fd[i].colScale,
							   NULL);
	 	if (sqlrc != SQL_SUCCESS) {
			TRACE_U(("WSCodbcRecord::BindCols SQLDescribeCol() Error"));
			getError(_hstmt);
			return WS_ERR;
		}
        sqlrc = SQLColAttribute(_hstmt,
								(SQLSMALLINT)(i+1),
								SQL_DESC_DISPLAY_SIZE,
								NULL,
								0,
								NULL,
								&colDataDisplaySize);
	 	if (sqlrc != SQL_SUCCESS) {
			TRACE_U(("WSCodbcRecord::BindCols SQLColAttribute() Error"));
			getError(_hstmt);
			return WS_ERR;
		}
        _fd[i].buffLen = colDataDisplaySize + 1;
		if(_fd[i].buffLen < 1) {
// update 2002/06/05
//			_fd[i].buffLen = 4097;
			_fd[i].buffLen = 32767;
		}
        _fd[i].buff = new char[_fd[i].buffLen];

        sqlrc = SQLBindCol(_hstmt,
						   (SQLSMALLINT)(i+1),
						   SQL_C_CHAR,
						   _fd[i].buff,
						   _fd[i].buffLen,
						   &_fd[i].len);
	 	if (sqlrc != SQL_SUCCESS) {
			TRACE_U(("WSCodbcRecord::BindCols SQLBindCol() Error"));
			getError(_hstmt);
			return WS_ERR;
		}
    }
	TRACE_U(("WSCodbcRecord::BindCols start"));
	return WS_NO_ERR;
}
void WSCodbcRecord::ReleaseCols()
{
	TRACE_U(("WSCodbcRecord::ReleaseCols start"));
	
	if(_fd == NULL) {
		return;
	}
    for(int i = 0; i < _Cols; i++ ) {
        delete[] (char*)(_fd[i].buff);
    }
    delete[] _fd;

	_fd = NULL;

	TRACE_U(("WSCodbcRecord::ReleaseCols end"));
}

void WSCodbcRecord::getValue(int index, WSCvariant* var)
{
	TRACE_U(("WSCodbcRecord::getValue start"));

	TRACE_U(("WSCodbcRecord::getValue _fd[index].colType:%d", _fd[index].colType));
	if(_fd[index].colType == SQL_CHAR) {
		// unsigned char
		*var = (char*)_fd[index].buff;
	} else
	if(_fd[index].colType == SQL_NUMERIC) {
		*var = (char*)_fd[index].buff;
	} else
	if(_fd[index].colType == SQL_DECIMAL) {
		*var = (char*)_fd[index].buff;
	}
	if(_fd[index].colType == SQL_INTEGER) {
		// long int
		*var = (long)atol((char*)_fd[index].buff);
	} else
	if(_fd[index].colType == SQL_SMALLINT) {
		// short int
		*var = (short)atoi((char*)_fd[index].buff);
	} else
	if(_fd[index].colType == SQL_FLOAT) {
		// float
// update 2002/06/05
//		*var = (float)atof((char*)_fd[index].buff);
		*var = (double)atof((char*)_fd[index].buff);
	} else
	if(_fd[index].colType == SQL_REAL) {
		// REAL
// update 2002/06/05
//		*var = (char*)_fd[index].buff;
		*var = (float)atof((char*)_fd[index].buff);
	} else
	if(_fd[index].colType == SQL_DOUBLE) {
		// float
		*var = (double)atof((char*)_fd[index].buff);
	} else
	if(_fd[index].colType == SQL_TYPE_DATE) {
		*var = (char*)_fd[index].buff;
	} else
	if(_fd[index].colType == SQL_TYPE_TIME) {
		*var = (char*)_fd[index].buff;
	} else
	if(_fd[index].colType == SQL_TYPE_TIMESTAMP) {
		*var = (char*)_fd[index].buff;
	} else {
		*var = (char*)_fd[index].buff;
	}
	TRACE_U(("WSCodbcRecord::getValue end"));
}
void WSCodbcRecord::setValue(int index, WSCvariant* var)
{
	TRACE_U(("WSCodbcRecord::setValue start"));

	TRACE_U(("WSCodbcRecord::setValue _fd[index].colType:%d", _fd[index].colType));
	int len = (int)strlen((char*)var);

	if(_fd[index].colType == SQL_CHAR) {
		// unsigned char
//		memcpy(_fd[index].buff, (char*)var, _fd[index].buffLen-1);
		strncpy((char*)_fd[index].buff, (char*)var, _fd[index].buffLen-1);
		((char*)_fd[index].buff)[(len < _fd[index].buffLen ? len : _fd[index].buffLen-1)] = '\0';
	} else
	if(_fd[index].colType == SQL_NUMERIC) {
//		memcpy(_fd[index].buff, (char*)var, _fd[index].buffLen-1);
		strncpy((char*)_fd[index].buff, (char*)var, _fd[index].buffLen-1);
		((char*)_fd[index].buff)[(len < _fd[index].buffLen ? len : _fd[index].buffLen-1)] = '\0';
	} else
	if(_fd[index].colType == SQL_DECIMAL) {
//		memcpy(_fd[index].buff, (char*)var, _fd[index].buffLen-1);
		strncpy((char*)_fd[index].buff, (char*)var, _fd[index].buffLen-1);
		((char*)_fd[index].buff)[(len < _fd[index].buffLen ? len : _fd[index].buffLen-1)] = '\0';
	}
	if(_fd[index].colType == SQL_INTEGER) {
		// long int
		sprintf((char*)_fd[index].buff, "%d", var->getLong());
	} else
	if(_fd[index].colType == SQL_SMALLINT) {
		// short int
		sprintf((char*)_fd[index].buff, "%d", var->getShort());
	} else
	if(_fd[index].colType == SQL_FLOAT) {
		// float
		sprintf((char*)_fd[index].buff, "%f", var->getDouble());
	} else
	if(_fd[index].colType == SQL_REAL) {
		// REAL
		sprintf((char*)_fd[index].buff, "%f", var->getFloat());
	} else
	if(_fd[index].colType == SQL_DOUBLE) {
		// float
		sprintf((char*)_fd[index].buff, "%f", var->getDouble());
	} else
	if(_fd[index].colType == SQL_TYPE_DATE) {
//		memcpy(_fd[index].buff, (char*)var, _fd[index].buffLen-1);
		strncpy((char*)_fd[index].buff, (char*)var, _fd[index].buffLen-1);
		((char*)_fd[index].buff)[(len < _fd[index].buffLen ? len : _fd[index].buffLen-1)] = '\0';
	} else
	if(_fd[index].colType == SQL_TYPE_TIME) {
//		memcpy(_fd[index].buff, (char*)var, _fd[index].buffLen-1);
		strncpy((char*)_fd[index].buff, (char*)var, _fd[index].buffLen-1);
		((char*)_fd[index].buff)[(len < _fd[index].buffLen ? len : _fd[index].buffLen-1)] = '\0';
	} else
	if(_fd[index].colType == SQL_TYPE_TIMESTAMP) {
//		memcpy(_fd[index].buff, (char*)var, _fd[index].buffLen-1);
		strncpy((char*)_fd[index].buff, (char*)var, _fd[index].buffLen-1);
		((char*)_fd[index].buff)[(len < _fd[index].buffLen ? len : _fd[index].buffLen-1)] = '\0';
	} else {
//		memcpy(_fd[index].buff, (char*)var, _fd[index].buffLen-1);
		strncpy((char*)_fd[index].buff, (char*)var, _fd[index].buffLen-1);
		((char*)_fd[index].buff)[(len < _fd[index].buffLen ? len : _fd[index].buffLen-1)] = '\0';
	}
	_fd[index].len = _fd[index].buffLen - 1;

	TRACE_U(("WSCodbcRecord::setValue end"));
}

void WSCodbcRecord::getError(SQLHANDLE hstmt)
{
	TRACE_U(("WSCodbcRecord::getError start"));

	SQLINTEGER	fNativeError;
	SQLSMALLINT	cbErrorMsgMax = sizeof(_szErrorMsg);
	SQLSMALLINT	cbErrorMsg = sizeof(_szErrorMsg);

	SQLError(_pDB->_henv, 
			 _pDB->_hdbc, 
			 hstmt, 
			 _szSqlState, 
			 &fNativeError, 
			 _szErrorMsg, 
			 cbErrorMsgMax, 
			 &cbErrorMsg);

	TRACE_U(("WSCodbcRecord::getError State:%s messgae:%s", _szSqlState, _szErrorMsg));
	TRACE_U(("WSCodbcRecord::getError end"));
}

void WSCodbcRecord::getErrorMsg(char* szState, char* szMsg)
{
	TRACE_U(("WSCodbcRecord::getErrorMsg start"));

	strcpy(szState, (char*)_szSqlState);
	strcpy(szMsg, (char*)_szErrorMsg);

	TRACE_U(("WSCodbcRecord::getErrorMsg start"));
}
long WSCodbcRecord::getColTypeConv(long index)
{
	if(_fd[index].colType == SQL_CHAR) {
		return WSCDB_FIELD_TYPE_CHAR;
	} else
	if(_fd[index].colType == SQL_NUMERIC) {
		return WSCDB_FIELD_TYPE_NUMERIC;
	} else
	if(_fd[index].colType == SQL_DECIMAL) {
		return WSCDB_FIELD_TYPE_DECIMAL;
	}
	if(_fd[index].colType == SQL_INTEGER) {
		return WSCDB_FIELD_TYPE_INTEGER;
	} else
	if(_fd[index].colType == SQL_SMALLINT) {
		return WSCDB_FIELD_TYPE_SMALLINT;
	} else
	if(_fd[index].colType == SQL_FLOAT) {
		return WSCDB_FIELD_TYPE_FLOAT;
	} else
	if(_fd[index].colType == SQL_REAL) {
		return WSCDB_FIELD_TYPE_REAL;
	} else
	if(_fd[index].colType == SQL_DOUBLE) {
		return WSCDB_FIELD_TYPE_DOUBLE;
	} else
	if(_fd[index].colType == SQL_TYPE_DATE) {
		return WSCDB_FIELD_TYPE_DATE;
	} else
	if(_fd[index].colType == SQL_TYPE_TIME) {
		return WSCDB_FIELD_TYPE_TIME;
	} else
	if(_fd[index].colType == SQL_TYPE_TIMESTAMP) {
	} else {
		return WSCDB_FIELD_TYPE_TIMESTAMP;
	}

	return WSCDB_FIELD_TYPE_NONE;
}
WSCstring WSCodbcRecord::getErrorMessage(){
  WSCstring ret;
  char stat[10];
  char buf[SQL_MAX_MESSAGE_LENGTH+1];
  getErrorMsg(stat,buf);
  char buf2[SQL_MAX_MESSAGE_LENGTH+1+32];
  sprintf(buf2,"state: %s ,message: %s",stat,buf);
  ret.setString(buf2);
  return ret;
}
