#ifndef DBFSQL_H
#define DBFSQL_H

/* Errors (e:subCode) */
#define ER_NOLIB		1000
#define ER_CONNECT		1001
#define ER_NOCONNECT	1002
#define ER_NOSQL		1003
#define ER_NOSTATEMENT	1004
#define ER_BADSTATEMENT	1005
#define ER_BADSELECT	1006
#define ER_NOROWSET		1007
#define ER_NOFIELD		1008
#define ER_TYPEMISMATCH	1009
#define ER_RDBMSERROR	1010

#define MAXFIELDNAME	20		// (without terminating zero)

#ifndef min
#define min(a,b) (a)<(b)?(a):(b)
#endif
#ifndef max
#define max(a,b) (a)<(b)?(a):(b)
#endif

struct tagSQLVTBL;

typedef struct
{
	unsigned char cmp[128];
	unsigned char upper[128];
	unsigned char lower[128];
	unsigned char read[128];
	unsigned char write[128];
}
SQLLocale;

typedef struct tagSQLFIELD {
	char name[MAXFIELDNAME+1];
	int type;
	int len;
	int dec;
	unsigned int ops;
	int buflen;
	int unsign;
	int notnull;
	int binary;
} SQLFIELD;

typedef struct tagSQLSTMT {
	struct tagSQLSTMT* next;
	int stmt_item;
	struct tagSQLCONN* conn;
} SQLSTMT;

typedef struct tagSQLROWSET {
	int rowset_item;
	struct tagSQLCONN* conn;
	struct tagSQLROWSET* next;
	int recno;
	int lastrec;
	int bof;
	int eof;
	int nfields;
	SQLFIELD* fields;
	int id;
} SQLROWSET;

typedef struct tagSQLCONN {
	struct tagSQLVTBL* vtbl;
	struct tagSQLSTMT* stmts;
	struct tagSQLROWSET* rowsets;
	SQLLocale* loc;
} SQLCONN;

typedef struct tagSQLVTBL {
	void (*destroyconn)(SQLCONN* conn);
	int (*prepare)(ClipMachine* mp,SQLCONN* conn,char* sql);
	int (*command)(ClipMachine* mp,SQLSTMT* stmt,ClipVar* ap);
	SQLROWSET* (*createrowset)(ClipMachine* mp,SQLSTMT* stmt,ClipVar* ap,const char* idname);
	char* (*testparser)(ClipMachine* mp,char* sql,ClipVar* ap);
	char* (*getvalue)(SQLROWSET* rowset,int fieldno,int* len);
	void (*setvalue)(SQLROWSET* rowset,int fieldno,char* value,int len);
	void (*append)(SQLROWSET* rowset);
	void (*delete_)(SQLROWSET* rowset);
	void (*newid)(ClipMachine* mp,SQLSTMT* stmt);
} SQLVTBL;

SQLLocale * SQL_get_locale(ClipMachine * mp, const char* sqlcs);

#endif
