/*  *********************************************************
	*           PVX PLUS PROPRIETARY & SENSITIVE            *
	* ----------------------------------------------------- *
	*  The information contained herein is the exclusive    *
	*  property of PVX Plus Technologies Ltd (Ontario).     *
	*  This material shall not be reproduced, or its        *
	*  contents disclosed to others in whole or in part.    *
	* ----------------------------------------------------- *
	*   Copyright (c) 2011                                  *
	*            PVX Plus Technologies (Ontario, Canada)    *
	********************************************************* */

#if !defined(_PVKIO_DEF)
#define _PVKIO_DEF

/*#define __DEBUG__ */ /* DEBUG switch - enables extended log */
#ifdef __DEBUG__
#ifndef PXPSQLSVR
#	define PVX_NET_STAT
#endif
#endif

#include "sybex.h"
#include "pvxshare.h"	/* contains the MAX_ defines */

#if defined(WIN32) || defined(_WIN32)
#	define PVK_WINDOWS
#elif defined(_UNIX_)
#	define PVK_UNIX
#endif

#define PVX_DEF_PORT                20222

typedef void* PV_HANDLE;
typedef PV_HANDLE HPVKENV;
typedef PV_HANDLE PVKFH; 

#define	PVXIND 1 
#define PVXKEY 2 
#define PVXKY2 3 
#define SBBIND 4 
#define SBBKEY 5
#define PVXVUE 6

/* Structures for creating files and getting
 *	the data dictonary information
 */

#define nMaxRecords nMaxRecordsLow
#define nCurRecords nCurRecordsLow
#define nAllocRecords nAllocRecordsLow

typedef struct tag_PV_FILEINFO
{	
	UINT32			nMaxRecordsLow;
	UINT32			nMaxRecordsHigh;
	UINT32			nCurRecordsLow;
	UINT32			nCurRecordsHigh;
	UINT32			nAllocRecordsLow;
	UINT32			nAllocRecordsHigh;
	UINT32			nCreateTime;
	UINT32			fOptions;
	INT32			nType;
	INT32			nRecsz;
	INT32			nNumIndexes;
	INT32			nBufsz;
	INT32			nNumSegments;
	unsigned char	fSizeFlag;
	unsigned char	cSep;
} PV_FILEINFO, *LPPV_FILEINFO;

typedef struct tag_PV_INDEXINFO
{	INT32			nKeySize;
	INT32			nNumSeg;
	INT32			fIdxOpts;
	unsigned char	cNullByte;
	char			szIdxName[25];
} PV_INDEXINFO, *LPPV_INDEXINFO;

typedef struct tag_PV_SEGINFO
{	unsigned char	nSegSize;
 	unsigned char	cNullByte;
 	INT32			nFieldno;
 	INT32			nFieldofs;
	INT32			fSegOpts;
} PV_SEGINFO, *LPPV_SEGINFO;

typedef struct tag_PV_TABLEINFO
{	
	char			szName[MAX_TABLE_NAME_LENGTH + 1];
	char			szDescription[MAX_DDF_DESCRIPTION + 1];
	char			szPhysical[MAX_DDF_PHYSICAL + 1];
	char			szIniFile[MAX_INI_FILE_NAME_LENGTH+1];	/* Alternate INI file */
	char			szIOProgram[MAX_DDF_IOPROG + 1];
	char			szGroup[MAX_DDF_GROUP + 1];
	char			szSecurity[MAX_DDF_SECURITY + 1];
	char			*szExtension;
	char			*szNotes;
	char            szFileFlags[33];
	UINT32			nExtensionSize;
	UINT32			nNotesSize;
	UINT32			fOptions;
	unsigned char	cSep;
	unsigned char	cSorted;
	int				iColumnCnt;			/* Number of columns */
	/* MAS90 specific */
	int				iVarFldNo;			/* Variant field (M90) */
	int				iVarFldOfs;			/* Variant offset (M90) */
	int				iVarFldLen;			/* Variant length (M90) */
	char			cM90FileRef[8];		/* MAS90 File reference */
	char			cM90Module[2];		/* MAS90 Module code */
	intptr_t		fhM90Dict;			/* Handle to Mas90 Dictionary */
	char			cSecurity;			/* MAS90 Security (M90) */
	INT32			cbSY0CMP;			/* Dummy SY0CMP record size */
	unsigned char	szSY0CMP[2048];		/* SY0CMP record data */
	BOOL			bSY0CMP;			/* Sy0cmp record flag (M90) */
	INT32			iSortRequired;		/* SORTTABLE option in the INI */
} PV_TABLEINFO, *LPPV_TABLEINFO;

/* fOptions */
#define PVCOL_OPT_HIDE			0x00000001
#define PVCOL_OPT_RECTYPE_DEF	0x00000002
#define PVCOL_OPT_RECTYPE_CHK	0x00000004
#define PVCOL_OPT_NOSHOW		0x00000008
#define	PVCOL_RIGHT_JUSTIFY     0x00000010
#define	PVCOL_CENTER_JUSTIFY	0x00000020	   

typedef struct tag_PV_COLINFO
{	
	char			szName[MAX_DDF_COLUMN_NAME + 1];
	char			szFormat[MAX_COLUMN_FORMAT_LENGTH + 1];
	char			szClass[MAX_CLASS_LENGTH + 1];
	char			szDescription[MAX_DDF_DESCRIPTION + 1];
	char			szOccurs[MAX_COLUMN_OCCURS_LENGTH + 1];
	char			szDefault[MAX_COLUMN_DEFAULT_LENGTH + 1];
	char			szSecurity[MAX_DDF_SECURITY + 1];
	char			szTag[MAX_COLUMN_TAG_LENGTH + 1];
	char			szValidation[MAX_COLUMN_VALIDATE_LENGTH + 1];
	char            szMustBe[MAX_COLUMN_MUSTBE_LENGTH + 1];
	char            szRecTypeVal[MAX_COLUMN_RECTYPE_LENGTH + 1];
	char            szSameAs[MAX_COLUMN_SAMEAS_LENGTH + 1];
	char			*szExtension;
	char			*szNotes;
	UINT32			nExtensionSize;
	UINT32			nNotesSize;
	UINT32			fOptions;
	char			cMustBe;
	INT32		    nFieldno;
	INT32		    nFieldofs;
	INT32           nType; 
	INT32           nFormat; 
	INT32		    nPrecision;
	INT32		    nScale;
	INT32		    nOutputType;
	INT32           nFill;
	INT32           nDelim;
} PV_COLINFO, *LPPV_COLINFO;

/* PVKRST structure for storing restrict conditions */
struct PVKRST
{	
	INT32		fld;		/* Field number */
	INT32		ofs;		/* Field offset */
	INT32		len;		/* Field length */
	INT32		fOperator;  /* Oprator type */
	INT32		rst_dec;    /* decimal */
	INT32		cbValue;	/* Length of value string */
	INT32		rst_bfrsz;	/* Current Buffer Size for rgbValue */
	char 		*rgbValue;	/* Value string */
	double      dbl_rst;
};

struct PVKRSTS
{	
	char			szMaxKey[MAX_KEY_LENGTH];
	int				iMaxKey;
	struct PVKRST	pRS[MAX_RESTRICTIONS];/* Restrict info */
};


/* Read option flags */
#define	READ_BOOKMARK	0x0001
#define	READ_RESTRICT	0x0002
#define	READ_BULKMODE	0x0004
#define	READ_CACHE_OK	0x0008

#define WSF_INPUT       0x0200 

/* Flags for use with PVKExtWrite */
#define INSERT_OK			0x0001		/* Write Insert flag */
#define UPDATE_OK			0x0002		/* Write Update flag */

/* file options used by PV_FILEINFO */
#define PVOPT_VAR_RSZ		0x0001		/* Key file variable length records */
#define PVOPT_NULL_KEY		0x0002		/* Strip nulls from keys */
#define PVOPT_SEP			0x0004		/* Sepaator byte in file header */
#define PVOPT_NOSEP			0x0008		/* No Seperator - delimited by length */
#define PVOPT_JOURNALIZE	0x0010		/* Journalize file */
#define	PVOPT_COMPRESS		0x0020		/* Data records are compressed */
#define PVOPT_PASSWORD		0x0040		/* File is password protected */
#define PVOPT_ENCRYPT		0x0080		/* Encrypt record data blocks and key blocks */
#define PVOPT_EXTENDED		0x0100		/* Extended record support */
#define PVOPT_READPASS		0x0200		/* Password is not required for READ only access to the file */
#define PVOPT_ZLIB_CMP		0x0400		/* ZLib compression for data records */

/* Key segment options */
#define KSEGOPT_UNIQUE		0x0001		/* Unique key */
#define KSEGOPT_UPPER		0x0002		/* Convert key seg to upper case */
#define KSEGOPT_LOWER		0x0004		/* Convert key seg to lower case */
#define KSEGOPT_TABLE		0x0008		/* Convert key using translate table */
#define KSEGOPT_SWAP		0x0010		/* Swap the byte order of the key */
#define KSEGOPT_DUPKEY0		0x0020		/* Non-unique primary key */
#define KSEGOPT_NULLSEG		0x0040		/* Don't add key if any segment is null */
#define KSEGOPT_DESCENDING	0x0080		/* Used by Infinity only and new key parser */

#define KSEGOPT_NULLKEY		0x0100		/* Null key all segments */
#define KSEGOPT_AUTOINC		0x0200		/* Auto-increment key */
#define KSEGOPT_ZSTRING		0x0400		/* Ignore data after 0x00 for keys */

#define KSEGOPT_TYPE		0x3800		/* Type field -- 3 bits -- Offset by 11 bits */

#define KSEGTYP_ASCII_ZERO	0x0800		/* Auto-increment key - in ASCII format - Zero filled */
#define KSEGTYP_ASCII_SPACE	0x1000		/* Auto-increment key - in ASCII format - Space filled */
#define KSEGTYP_OPT_3		0x1800		/* Type:3 */
#define KSEGTYP_SIGNED_INT	0x2000		/* Signed INT key - stored with sign bit flipped */
#define KSEGTYP_OPT_5		0x2800		/* Type:5 */
#define KSEGTYP_OPT_6		0x3000		/* Type:6 */
#define KSEGTYP_BINNUM		0x3800		/* Type:7 - Numeric with scale */

#define KSegType(a)			((a) & KSEGOPT_TYPE)
#define IsKSegAutoInc(a)	(ON(a, KSEGOPT_AUTOINC) || (KSegType(a) == KSEGTYP_ASCII_ZERO) || (KSegType(a) == KSEGTYP_ASCII_SPACE))

#define KEYOPT_UNIQUE		0x0001		/* Key must be unique */
#define KEYOPT_NOCHANGE		0x0002		/* Key never changes */
#define KEYOPT_NULLKEY		0x0004		/* All key segments are NULLs */

#define WSF_LOCK        0x0400          /* Open and lock */

/*	Function Proto-types
 */
PVKFH APIDEF PVK_open (char *path); /* Open file - returns fh */
int APIDEF PVK_close (PVKFH lpdata); /* Closes file */
int APIDEF PVK_dict (PVKFH lpdata, int dctidx, char *dctbfr, int dctbsz); /* Returns dictionary record */
int APIDEF PVK_dict_add (PVKFH lpdata, int dctidx, byte *dctbfr, size_t dctbsz);
int APIDEF PVK_read (PVKFH lpdata, char *dtabfr, long dtabsz, int fc);
										/* Reads record
											fc= PVKRD_CUR 	-- Returns current
												PVKRD_NEXT	-- Returns next
												PVKRD_PRIOR	-- Returns prior */
int APIDEF PVK_ExtReadDirect (PVKFH lpdata, char *dtabfr, int dtabsz, int fc, long nRecOfs, long lAddr);
int APIDEF PVK_write (PVKFH lpdata, char *dtabfr, int dtabsz, char *keybfr, int keysz);
int APIDEF PVK_insert (PVKFH lpdata, char *dtabfr, int dtabsz, char *keybfr, int keysz);
int APIDEF PVK_update (PVKFH lpdata, char *dtabfr, int dtabsz, char *keybfr, int keysz);
										/*	Pvk_write ... Writes/rewrites record
											Pvk_insert .. Only adds new record
											Pvk_update .. Only updates existing record
											keybfr/keysz indicate external key
											if no external key then keysz MUST be set to zero */
int APIDEF PVK_ExtWrite (PVKFH lpdata, char *dtabfr, int dtabsz, char *keybfr, int keysz, int options, long nRecOfs);
int APIDEF PVK_remove (PVKFH lpdata, char *keybfr, int keysz);	/* Remove record given the primary key */
int APIDEF PVK_seek (PVKFH lpdata, char *keybfr, int keysz, int keynum);	/* Positions via key - Changes key number if keyno NE 0 */
int APIDEF PVK_GetKey (PVKFH lpdata, char *keybfr, int keysz, int keynum);	/* Get the current key value - returns length */
int APIDEF PVK_setpos (PVKFH lpdata, long addr);	/* Returns to logical position in file */
long APIDEF PVK_getpos (PVKFH lpdata);			/* Returns logical position in file */
int APIDEF PVK_keyadjust (PVKFH lpdata, char *keyBfr, int keysz, int keynum);

/* PVK_UnlockRecord
 *
 *	Call to remove record locks without having to read file
 *		Called with record address to unlock or
 *		PVK_UNLOCK_CURRENT	to unlock current record
 *		PVK_UNLOCK_ALL		to unlock all records
 */
#define PVK_UNLOCK_CURRENT	0				/* Option to unlock current record */
#define PVK_UNLOCK_ALL		-1				/* Option to unlock all records */

int APIDEF PVK_UnlockRecord (PVKFH lpdata, long lAddr);
int APIDEF PVK_IsRecordLocked (PVKFH lpdata, long lAddr);
char * APIDEF PVK_strerr (PVKFH lpdata);	/* Return error message text */
int APIDEF PVK_geterrno (PVKFH lpdata);
int APIDEF PVK_SetPswd (PVKFH lpdata, char *Pswd, int szPswd, int Perms);	/* Set password on file */
int APIDEF PVK_read_ODBC (PVKFH lpdata, char *dtabfr, long dtabsz, int fc, char *cur_key, byte *key_len, char *max_key, byte max_key_sz);
int APIDEF PVK_read_FIRST (PVKFH lpdata, char *dtabfr, long dtabsz, int fc, char *cur_key, byte *key_len, long *lAddr, char *max_key, byte max_key_sz, byte *restr, int npsz);
int APIDEF PVK_RestrictedRead (PVKFH lpdata, char *dtabfr, long dtabsz, int fc, char *cur_key, byte *key_len, long *lAddr, char *max_key, byte max_key_sz, int fRead);
int	APIDEF PVK_PutRestrictInfo (PVKFH lpdata, int idx, struct PVKRST *rst);
int APIDEF PVK_PutMaxKeyInfo (PVKFH lpdata, char *szMaxKey, int iMaxKey);
void APIDEF PVK_setPrefix (HPVKENV hEnv, char *prefix);	/* Set prefix */
void APIDEF PVK_setWDir (HPVKENV hEnv, char *directory);	/* Set working directory */

/* New functions, ODBC Server uses it */
void APIDEF PVK_ExtUnlock (PVKFH lpdata, int forceit);

/* *** Environment (thread safe) functions ***
** *** The following functions use the Environment pointer thus
** *** environmental values are thread safe
** *** All functions that pass files handles are thread safe
** *** Since the file handle contains the environment handle active
** *** however this is a static environment (thus only one environment)
*/
HPVKENV APIDEF PVK_AllocEnv (void);				/* Allocate Environment */
void APIDEF PVK_DeAllocEnv (HPVKENV hEnv);		/* Free the Environment */
PVKFH APIDEF PVK_openEx (char *path, char *pswd, int pswd_sz, INT16 opt);
PVKFH APIDEF PVK_OpenExt (HPVKENV hEnv, char *path, char *pswd, int pswd_sz, INT16 opt, INT32 *open_err);
int APIDEF PVK_RegisterKey (HPVKENV hEnv, char *text, long key);          /* Register */
BOOL APIDEF PVK_RawReadMode (PVKFH lpdata, BOOL flag);
intptr_t APIDEF PVGetEnvMode (HPVKENV hEnv, int iFlag);
intptr_t APIDEF PVSetEnvMode (HPVKENV hEnv, int iFlag, intptr_t iValue);
int APIDEF PVAddIndex (HPVKENV env, char *path, PV_INDEXINFO *key, int keysno, PV_SEGINFO *seg);
int APIDEF PVDropIndex (PVKFH lpdata, int keyno);
void APIDEF PV_SocketClosed (SOCKET socket);

#define PV_BURST_MODE	1
#define PV_DIRTY_READ	2
#define PV_LOCK_MODE	3
#define PV_READ_ONLY	4
#define	PV_MAX_MB		5
#define	PV_WORKING_DIR	6
#define	PV_PREFIX		7
#define	PV_VIEW_DLL		8
#define	PV_SQL_HANDLE	9
#define	PV_VERSION      10
#define	PV_RMT_VERSION  11
#define	PV_HOST         12
#define	PV_PORT         13
#define	PV_CONNECT      14
#define	PV_SVR_ACTIVATED  15
#define	PV_COMPANY      16
#define	PV_USER			17
#define	PV_PASSWORD     18
#define	PV_SESSIONID    19
#define	PV_DBG_NETSTAT  20
#define	PV_DBG_TEXT     21
#define	PV_CACHE_SIZE	22
#define	PV_COMPRESS		23
#define PV_INI_DIR		24
#define PV_CATALOG		25
#define PV_SSL			26

#define PVK_DONT_CHECK_LOCK		1		/* Don't check and never lock read records */
#define PVK_CHECK_LOCK			2		/* Check for EXTRACTED records */
#define PVK_CHECK_LOCK_NOWAIT	4		/* Check for EXTRACTED records and exit immediately if locked */
#define PVK_HDR_LOCK_NOWAIT		8		/* Don't wait for a locked header */

/* Transaction logic */
int APIDEF PVK_BeginTX (HPVKENV hEnv);
int APIDEF PVK_CommitTX (HPVKENV hEnv);
int APIDEF PVK_RollbackTX (HPVKENV hEnv);

/* Create and index calls */
int APIDEF PVCreateFile (
				HPVKENV			hEnv,		/* Environment */
				char			*szPath,	/* Path to file to create */
				PV_FILEINFO		*lpFileInfo,	/* File information structure */
				PV_INDEXINFO	*lpIndexInfo,	/* Index Information - primary key only */
				PV_SEGINFO		*lpSegInfo	/* Array of segment descriptors */
);


int APIDEF PVDescribeFile (PVKFH lpdata, PV_FILEINFO *fi);
PV_HANDLE APIDEF PVRequestHandle (HPVKENV env, int *nError);
int APIDEF PVFreeHandle (PV_HANDLE hRequest);
int APIDEF PVDescribeIndex (PVKFH lpdata, int nStartIndex, int *nIndexCount, int *nSegCount, PV_INDEXINFO *key, PV_SEGINFO *seg);

#define PV_TABLES_AND_VIEWS 0
#define PV_TABLES_ONLY 1
#define PV_VIEWS_ONLY 2

int APIDEF PVGetTables (PV_HANDLE hRequest, char *szCatalog, size_t nCatalogSize, char *szSchema, size_t nSchemaSize, char *szTable, size_t nTableSize, int nTableType, int *nTableCount, int *nError);
int APIDEF PVGetColumns (PV_HANDLE hRequest, char *szCatalog, char *szSchema, char *szTable, char *szFile, int *nColsCount);
int APIDEF PVFetchTable (PV_HANDLE hRequest, char *table, int	len, int tabs, PV_TABLEINFO *tableInfo);
int APIDEF PVFetchColumn (PV_HANDLE hRequest, int cols, PV_COLINFO *colInfo);

/* security functions */
BOOL APIDEF PVLogon (HPVKENV hEnv, char *szUser, char *szCompany, char *szPswd, char *szSID, int *fSilent, char *szDirectory, char *pClientBuffer, int *nClientBufferSize, int *nError, char *szErrMsg);
BOOL APIDEF PVLogoff (HPVKENV hEnv, char *szUser, char *szCompany, char *szPswd, char *szSID, int *fSilent, int *nError, char *szErrMsg);

/* Internal use only functions - used by the PxPlus SQL Server so Ids can be passed to the client instead of pointers  */
HPVKENV APIDEF GetLocalEnvironmentById (unsigned int envId);		/* Lookup an Environment from an Id */
PVKFH APIDEF GetLocalFileById (unsigned int fileId);				/* Lookup a file handle from an Id */
PV_HANDLE APIDEF GetLocalSQLSessionById (unsigned int sqlSessionId);	/* Lookup a SQL session from an Id */

/* Internal use only functions - used by the PxPlus SQL Server to build HTTP response  */
int APIDEF GetNumConnections();
int APIDEF GetNumOpenFiles();

/* check return status from PVK_open with INVALID_PVKFH */
#define INVALID_PVKFH ((PVKFH)(-1))

#define PVKRD_CUR			1
#define PVKRD_NEXT			2
#define PVKRD_PRIOR			3

#define PVKRD_LOCK			0x1000		/* OR into function to Lock record */
#define PVKRD_UNLOCK		0x2000		/* OR into function to UnLock all records */


#define PVK_BURST_ON		1
#define PVK_BURST_OFF		0
#define PVK_DIRTY_ON		1
#define PVK_DIRTY_OFF		0
#define PVK_COMPRESS_ON		1
#define PVK_COMPRESS_OFF	0

#define PVK_READONLY_ON		1			/* Switch to Read-only mode during open if read-write access fails */
#define PVK_READONLY_OFF	0

#define PVKSEEK_RAW_READ	-1000

/* Error codes */
#define	PV_ERROR			-1
#define	PV_TRUNCATED		-2

#define ERR_INSIDE_PVK_RPT_ERROR (-1)	/* FP(Errno) set to this value inside Pvk_Rpt_error */
#define ERR_OK					0		/* no error */ 
#define ERR_CANT_OPEN			1
#define ERR_BAD_FH				2
#define ERR_NOSUCH_KEY			3
#define ERR_EOF					4
#define ERR_BAD_TYPE			5
#define ERR_KEYNO				6
#define ERR_KEY_LENGTH			7
#define ERR_NO_MEMORY			8
#define ERR_KIO_OFS				9
#define ERR_KIO_FAILED			10
#define ERR_KIO_WRONG			11
#define ERR_KSZ_WRONG			12
#define ERR_RSZ_WRONG			13
#define ERR_SEEK_FAILED			14
#define ERR_READ_FAILED			15
#define ERR_READ_SHORT			16
#define ERR_BAD_FUNCTION		17
#define ERR_INDEXED_FILE		18
#define ERR_WRITE_FAILED		19
#define ERR_KIO_BADADR			20
#define ERR_KIO_DELCHN			21
#define ERR_KIO_NOEOF			22
#define ERR_BUSY				23			/* File or Data busy */
#define ERR_FILE_FULL			24
#define ERR_NOT_REGISTERED		25
#define ERR_DOM					26			/* Duplicate key not allowed - if missing Rpt ERR_NO_SUCH_KEY */
#define ERR_KIO_RSIZE			27			/* Keyed file error (Record length invalid) */
#define ERR_KIO_BADSEG			28			/* Invalid segment number */
#define ERR_IND_HEADER			29			/* Unable to access Indexed file header */
#define ERR_KIO_DECOMPFAIL		30			/* Decompress of record failed */
#define ERR_PSWD_WRONG			31			/* Wrong password supplied */
#define ERR_BAD_OFFSET			32			/* Bad Read Offset */
#define ERR_NO_SUCH_FILE		33			/* File does not exist (or already exists) */
#define ERR_RESTRICT_FAILED		34
#define ERR_ACCESS_VLTN			35			/* Access violation, attempt to write to ReadOnly file */
#define ERR_TX_BEGIN			36			/* Begin transaction without finishing previous */
#define ERR_TX_ROLLBACK			37			/* Rollback/Commit without proper Begin transaction */
#define ERR_FILE_BUSY			38			/* File is busy */
#define ERR_MISSING_INFO		39			/* Not enough information was passed in */
#define ERR_OBJ_VER_WRONG		40
#define ERR_BAD_BUFFER			41			/* Incorrect buffer returned from page_get */
#define ERR_SYS_NOFH			42			/* os error: No more file handles 
												available (too many open files)*/ 
#define ERR_NET_FAILED			43			/* network error  */
#define ERR_VERSION				44
#define ERR_SECURITY_FAILED		45			/* Logon failed */
#define ERR_PVK_NOTSUPPORTED	46			/* Feature is not supported */
#define ERR_NO_BIGFILES			47			/* Files > 2GB not supported */
#define ERR_CATALOG				48			/* Invalid catalog */
#endif /* _PVKIO_DEF */
