#ifndef WSCDBMYSQL_H
#define WSCDBMYSQL_H

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

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

struct _MysqlCol {
	WSCuchar	colName[32];
	short		colType;
	int			buffLen;
	void*		buff;
};

#define MYSQL_ACCESS_MODE_READ			0
#define MYSQL_ACCESS_MODE_EDIT			1
#define MYSQL_ACCESS_MODE_ADDNEW		2
#define MYSQL_MAX_MESSAGE_LENGTH		255
#define MYSQL_TRAN_FUNCTION				1
#define MYSQL_TRAN_RECORD_FUNCTION		2


class WSCdbDrvDatabase;
class WSCdbDrvRecord;
class WSCdbMysqlRecord;

class WSCdbMysqlDatabase : public  WSCdbDrvDatabase
{
public:
	WSCdbMysqlDatabase();
	virtual ~WSCdbMysqlDatabase();
	
	virtual long     open(char* host, char* uid, char* pwd, char* dbname, char* port = NULL);
	virtual long     close();
	virtual long     beginTran();
	virtual long     commitTran();
	virtual long     abortTran();
	virtual long     sqlExecute(const char* stmt);
	virtual WSCbool  isOpen();
	virtual void     getErrorMsg(char* szState, char* szMsg);
	virtual void     getErrorMsg(char* szMsg,long size);
	virtual void    setEncode(long code);
	virtual long    getEncode();

	        int      getProcessId();
	        WSCulong getCursor();
	        short    getbeginTranmode();
	        void     setbeginTranmode(short begin);
	        char*    getDbName();
private:
	void getError();
	void getServerEncoding();
	char* decode(const char* buf);

public:
	WSCbool		_open;
	short		_begin;
	MYSQL*		_hconn;
	WSCuchar	_szSqlState[6];
	WSCuchar	_szErrorMsg[MYSQL_MAX_MESSAGE_LENGTH + 1];
	char		_dbName[80];
	long		_encoding;
};

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

private:
	void  Cleanup(WSCdbMysqlDatabase* pDatabase);
	long  BindCols();
	void  ReleaseCols();
	void  getValue(int index, WSCvariant* var);
	void  setValue(int index, WSCvariant* var);
	void  getError();
	char* makeINSERT();
	char* makeUPDATE();
	char* makeDELETE();
	void  getTableName(char* p, char* tbl, int size);
	long  setRowPos(WSCulong pos);
	int   getBufflen(int type);
	char* getSqlString(int i);
	void  encode(char* buf, char* str);
	char* decode(char* buf);
	char* getSelectSQL(const char* p, long rowiduse);
	long  getColTypeConv(long index);

public:
	WSCdbMysqlDatabase*	_pDB;
	MYSQL_RES*			_res_stmt;
	WSCbool				_open;
	short				_Cols;
	_MysqlCol*			_fd;
	short				_access_mode;
	WSCuchar			_szSqlState[6];
	WSCuchar			_szErrorMsg[MYSQL_MAX_MESSAGE_LENGTH + 1];
	int					_access;
	int					_Cursor;
	WSCulong			_RowCount;
	WSCulong			_FetchRowPos;
	long				_encoding;
	char				_tableName[80];
	long				_rowiduse;
};

#endif		// WSCDBMYSQL_H
