/*
**	msql_priv.h	- Private (internal) definitions
**
**
** Copyright (c) 1993-95  David J. Hughes
** Copyright (c) 1995  Hughes Technologies Pty Ltd
**
** Permission to use, copy, and distribute for non-commercial purposes,
** is hereby granted without fee, providing that the above copyright
** notice appear in all copies and that both the copyright notice and this
** permission notice appear in supporting documentation.
**
** This software is provided "as is" without any expressed or implied warranty.
**
** ID = "msql_priv.h,v 1.3 1994/08/19 08:03:14 bambi Exp"
*/


#ifndef MSQL_PRIV_H
#define MSQL_PRIV_H

#include "version.h"

#ifdef	BERK_DB
#  include <db/db.h>
#else
#  include "avl_tree.h"
#endif


/***************************************************************************
*	Configuration parameters 
*/



#define MAX_FIELDS	75		/* Max fields per query */
#define NAME_LEN	35		/* Field/table name length */
#define	PKT_LEN		(32*1024)	/* Max size of client/server packet */
#define	CACHE_SIZE	6		/* Size of table cache */
#define	OFB_SIZE	(128-sizeof(u_int))/* Size of overflow buffers */
#define NUM_INDEX	5		/* Max indices per table */
#define MAX_INDEX_WIDTH	10		/* Max fields per index */

#define CACHE_FDS	(CACHE_SIZE * (NUM_INDEX + 2))

/***************************************************************************
** Internal structures
*/

/*
** Identifier format.  Multi-part to enable stuff like "emp.name"
*/
typedef struct ident_s {
	char	seg1[NAME_LEN + 1],
		seg2[NAME_LEN + 1];
} ident_t;


/* 
** Field value storage union 
*/
typedef struct val_s {
	union val_u {			
		int	intVal;
		u_char	*charVal;
		double	realVal;
		ident_t	*identVal;
	} val;
	int	type,
		nullVal,
		dataLen;
} val_t;


typedef struct tname_s {
	char	name[NAME_LEN + 1],
		cname[NAME_LEN + 1];
	int	done;
	struct	tname_s *next;
} tname_t;



/* 
** Internal field list element
*/
typedef struct field_ps {		
	char	table[NAME_LEN + 1],
		name[NAME_LEN + 1],
		funct[NAME_LEN + 1];
	val_t 	*value;
	int	type,
		sysvar,
		length,
		dataLength,
		offset,
		null,
		flags,
		fieldID;
	u_int	overflow;
	void	*entry;
	struct	field_ps *next;
} field_t;


#define	IDX_AVL		1

/*
** Index definition
*/
typedef struct mindex_s {
	char	table[NAME_LEN + 1],
		name[NAME_LEN + 1],
		unique,
		*buf;
	int	fields[MAX_INDEX_WIDTH + 1],
		length,
		fieldCount,
		idxType;
#ifdef BERK_DB
	DB	*file;
#else
	avltree	*tree;
#endif
	struct	mindex_s *next;
} mindex_t;



/* 
** Where clause list element 
*/
typedef struct cond_s {			
	char	table[NAME_LEN + 1],
		name[NAME_LEN + 1];
	int     clist[MAX_FIELDS];	/* only used in the head */
	val_t 	*value;
	int	op,
		bool,
		type,
		length,
		sysvar,
		fieldID;
	struct	cond_s *next,
		*subCond;
} cond_t;


typedef	struct cstk_s {
	cond_t	*head,
		*tail;
	struct	cstk_s *next;
} cstk_t;




typedef struct tlist_s {
	char	name[NAME_LEN + 1];
	struct	tlist_s *next;
} tlist_t;


/* 
** Order clause list element 
*/
typedef struct order_s {		
	char	table[NAME_LEN + 1],
		name[NAME_LEN + 1];
	int	dir,
		type,
		length;
	void	*entry;
	struct	order_s *next;
} order_t;



typedef	struct	hdr_s {
	char	active;
	int	timestamp;
} hdr_t;



typedef struct row_s {
	int	rowID;
	hdr_t	*header;
	u_char	*data,
		*buf;
} row_t;



typedef struct seq_s {
	int	step;
	u_int	value;
} seq_t;


typedef struct sblk_s {
	char	version;
	u_int	freeList;
	u_int	numRows;
	u_int	activeRows;
	seq_t	sequence;
} sblk_t;


/* 
** Table cache entry struct 
*/
typedef struct cache_s {		
	char	db[NAME_LEN + 1],
		cname[NAME_LEN + 1],
		table[NAME_LEN + 1],
		resInfo[4 * (NAME_LEN+1)]; /* used for debugging info */
	row_t	row;
	int	age,
		dataFD,
		overflowFD,
		rowLen,
		result;
	field_t	*def;
	mindex_t *indices;
	int	remapData,
		remapOverflow;
	caddr_t	dataMap,
		overflowMap;
	off_t	size,
		overflowSize;
	sblk_t	*sblk;
} cache_t;




typedef struct cinfo_s {
	char    *db,
		*host,
		*user;
	int     access;
	u_int	connectTime,
		lastQuery,
		numQueries;
	struct  sockaddr_in local, remote;
} cinfo_t;




typedef struct cand_s {
	int	type;		/* Lookup type - SEQ, IDX_ABS, IDX_RANGE */
	u_int	nextPos,	/* Seq search next pos */
		lastPos;	/* Last key based location */
	int	index,		/* Which index to use */
		single,		/* Is it a single field index? */
		ident,		/* Is it an IDENT based lookup? */
		length,		/* Length of buffer space */
		rowID;		/* Row ID for position lookups */
	u_char	*rangeMin,	/* IDX_RANGE start value */
		*rangeMax;	/* IDX_RANGE stop value */
	char	*buf,		/* Index value buffer */
		idx_name[NAME_LEN + 1];
#ifdef BERK_DB
	DB      *file;		/* Btree */
#else
	avltree	*tree;
	avl_cur	cursor;
#endif
} cand_t;



#define	HEADER_SIZE	sizeof(hdr_t)
#define	SBLK_SIZE	sizeof(sblk_t)
#define VC_HEAD_SIZE	(sizeof(int)+sizeof(u_int))

#define	CAND_SEQ	1
#define CAND_IDX_ABS	2
#define CAND_IDX_RANGE	3
#define CAND_ROWID	4
#define CAND_SYS_SEQ	5


/***************************************************************************
*	External variables  (var's defined in msql_proc.c)
*/

#ifndef MSQL_ADT


extern	int	command,
		notnullflag,
		keyflag,
		msqlSelectLimit;
extern	char	*arrayLen;
extern	cond_t	*condHead;
extern	field_t	*fieldHead;
extern	order_t	*orderHead;
extern	tlist_t	*tableHead;

#endif





/***************************************************************************
*	YACC stack type
*/
#ifdef YYSTYPE
#  undef YYSTYPE
#endif
typedef char	* C_PTR;
#define YYSTYPE C_PTR




/***************************************************************************
*	Macros and other constants
*/


#define	EQ_OP		1
#define	LT_OP		2
#define	GT_OP		3
#define	NE_OP		4
#define	LE_OP		5
#define GE_OP		6
#define LIKE_OP		7
#define NOT_LIKE_OP	8
#define RLIKE_OP	9
#define CLIKE_OP	10
#define NOT_RLIKE_OP	11
#define NOT_CLIKE_OP	12

#define	NO_BOOL		0
#define	AND_BOOL	1
#define	OR_BOOL		2


#define	MEM_ALIGN	4
#define NO_POS          0xFFFFFFFF

#define QUIT		1
#define	INIT_DB		2
#define QUERY		3
#define DB_LIST		4
#define TABLE_LIST	5
#define FIELD_LIST	6
#define	CREATE_DB	7
#define DROP_DB		8
#define RELOAD_ACL	9
#define SHUTDOWN	10
#define INDEX_LIST	11
#define	SERVER_STATS	12

#define NO_REMAP	0
#define DATA_REMAP	1
#define KEY_REMAP	2
#define STACK_REMAP	4
#define FULL_REMAP	0xffff

#define DEST_CLIENT	1
#define DEST_TABLE	2

#define	NO_ACCESS	0
#define	READ_ACCESS	1
#define	WRITE_ACCESS	2
#define RW_ACCESS	READ_ACCESS | WRITE_ACCESS

#define	IGNORE_IDENT	1
#define KEEP_IDENT	0

#define MALLOC_BLK      1
#define MMAP_BLK        2
 

int writePkt();
int readPkt();


#ifndef _MSQL_SERVER_SOURCE

extern	char	*msqlHomeDir;

#endif



/*
** Inline definitions
*/

/* inlined, unaligned, 4-byte copy */
#define bcopy4(s,d) \
      ((((unsigned char *)d)[0] = ((unsigned char *)s)[0]), \
       (((unsigned char *)d)[1] = ((unsigned char *)s)[1]), \
       (((unsigned char *)d)[2] = ((unsigned char *)s)[2]), \
       (((unsigned char *)d)[3] = ((unsigned char *)s)[3]))
/* inlined, unaligned, 8-byte copy */
#define bcopy8(s,d) \
      ((((unsigned char *)d)[0] = ((unsigned char *)s)[0]), \
       (((unsigned char *)d)[1] = ((unsigned char *)s)[1]), \
       (((unsigned char *)d)[2] = ((unsigned char *)s)[2]), \
       (((unsigned char *)d)[3] = ((unsigned char *)s)[3]), \
       (((unsigned char *)d)[4] = ((unsigned char *)s)[4]), \
       (((unsigned char *)d)[5] = ((unsigned char *)s)[5]), \
       (((unsigned char *)d)[6] = ((unsigned char *)s)[6]), \
       (((unsigned char *)d)[7] = ((unsigned char *)s)[7]))



#ifdef _MSQL_SERVER_SOURCE
#define mmap(a,l,p,fl,fd,o) MMap(a,(size_t)l,p,fl,fd,o,__FILE__,__LINE__)
#define munmap(a,l)         MUnmap(a,(size_t)l,__FILE__,__LINE__)
#define malloc(s)           Malloc(s,__FILE__,__LINE__)
#define strdup(s)           Strdup(s,__FILE__,__LINE__)
#define fastMalloc(s)       FastMalloc(s,__FILE__,__LINE__)
#define free(a)             Free((char *)a,__FILE__,__LINE__)
#define safeFree(x)         {if(x) { (void)free(x); x = NULL; } }
#endif


/*
** Prototypes
*/

#undef __ANSI_PROTO
#if defined(__STDC__) || defined(__cplusplus)
#  define __ANSI_PROTO(x)       x
#else
#  define __ANSI_PROTO(x)       ()
#endif


/* index.c prototypes */
int 	insertIndices __ANSI_PROTO((cache_t *,field_t *,u_int));
int 	deleteIndices __ANSI_PROTO((cache_t *,field_t *,u_int));
int 	checkIndices __ANSI_PROTO((cache_t *,field_t *));
void 	freeCandidate __ANSI_PROTO((cand_t *));
void	closeIndices __ANSI_PROTO((cache_t *));
void	zeroIndices __ANSI_PROTO((cache_t *));
void 	setCandidateValues __ANSI_PROTO((cache_t*, cand_t*, field_t *));
void 	resetCandidate __ANSI_PROTO((cand_t *));
u_int 	getCandidate __ANSI_PROTO((cache_t *, cand_t *));
cand_t	*msqlSetupCandidate __ANSI_PROTO((cache_t *, cond_t *,field_t *, int));
mindex_t *loadIndices __ANSI_PROTO((char *, char *));



/* types.c prototypes */
u_char	*readVarChar __ANSI_PROTO((cache_t *, u_char *, int));
u_int 	writeVarChar __ANSI_PROTO((cache_t *, u_char *, int));
int	matchRow __ANSI_PROTO((cache_t *,row_t *,cond_t *));
int 	compareRows __ANSI_PROTO((cache_t*,row_t*,row_t*,order_t*,int*));
int 	checkDupRow __ANSI_PROTO((cache_t*,u_char*,u_char*));


/* table.c prototypes */
int	openTable __ANSI_PROTO((char *,char *));
int	openOverflow __ANSI_PROTO((char *,char *));
int	writeFreeList __ANSI_PROTO((cache_t *,u_int, u_int));
int	pushBlankPos __ANSI_PROTO((cache_t *,char *,char *, u_int));
int	initTable __ANSI_PROTO((cache_t *,int));
int	rowWrite __ANSI_PROTO((cache_t *,row_t *,u_int));
int	rowRead __ANSI_PROTO((cache_t *,row_t *,u_int));
int	deleteRow __ANSI_PROTO((cache_t *,u_int));
int	fillRow __ANSI_PROTO((cache_t *,row_t *,field_t *,int *));
int	updateValues __ANSI_PROTO((cache_t*,row_t *,field_t *,int *));
void 	cleanTmpDir ();
void 	freeTableDef __ANSI_PROTO((field_t *));
void 	freeTmpTable __ANSI_PROTO((cache_t *));
void 	extractValues __ANSI_PROTO((cache_t *, row_t *,field_t *,int *));
u_int	readFreeList __ANSI_PROTO((cache_t *,u_int));
u_int	popBlankPos __ANSI_PROTO((cache_t *,char *,char *));
row_t	*dupRow __ANSI_PROTO((cache_t *, row_t *, row_t *));
field_t	*expandFieldWildCards __ANSI_PROTO((cache_t *, field_t *));
cache_t	*loadTableDef __ANSI_PROTO((char *, char *, char *));
cache_t	*createTmpTable __ANSI_PROTO((cache_t *, cache_t *, field_t *));


/* net.c prototypes */
void	initNet();

/* msqldb.c prototypes */
int	msqlSetupFields __ANSI_PROTO((cache_t *,int *,field_t *));
int	msqlSetupConds __ANSI_PROTO((cache_t *,cond_t *));
int	msqlSetupOrder __ANSI_PROTO((cache_t *,int *,order_t *));
int	msqlInit __ANSI_PROTO((char *));
int	msqlServerCreateTable __ANSI_PROTO((char *,field_t *,char *));
int	msqlServerCreateIndex __ANSI_PROTO((mindex_t *,field_t *,char *));
int	msqlServerDropTable __ANSI_PROTO((char *, char *));
int	msqlServerDropIndex __ANSI_PROTO((mindex_t *, char *));
int	msqlServerDelete __ANSI_PROTO((char *,cond_t *,char *));
int	msqlServerInsert __ANSI_PROTO((char *,field_t *,char *));
int	msqlServerUpdate __ANSI_PROTO((char *,field_t *,cond_t *,char *));
void 	msqlServerListDBs __ANSI_PROTO((int));
void	msqlServerListTables __ANSI_PROTO((int,char *));
void 	msqlServerListFields __ANSI_PROTO((int, char *, char *));
void 	msqlServerListIndex __ANSI_PROTO((int, char *, char *, char *));
void 	msqlBackendInit();
void 	msqlBackendClean();
void 	msqlDropCache();
void 	msqlQualifyFields __ANSI_PROTO((char *, field_t *));
void	msqlQualifyConds __ANSI_PROTO((char *, cond_t*));
void	msqlQualifyOrder __ANSI_PROTO((char *, order_t*));
void	msqlServerCreateDB __ANSI_PROTO((int, char *));
void	msqlServerDropDB __ANSI_PROTO((int, char *));
void 	initBackend();
void 	formatPacket __ANSI_PROTO((char*,field_t *));
void 	freeRow __ANSI_PROTO((row_t *));


/* select.c prototypes */
int	msqlServerSelect __ANSI_PROTO((tname_t*,field_t*,cond_t*,order_t*,char *));

/* sysvar.c prototypes */
void 	getSysVar __ANSI_PROTO((cache_t *,row_t *,field_t *));
int 	compareSysVar __ANSI_PROTO((cache_t *,row_t *,cond_t *));
int 	checkSysVar __ANSI_PROTO((cache_t *,field_t *));
int 	checkSysVarCond __ANSI_PROTO((cond_t *));

/* msql_proc.c prototypes */
int 	msqlAddField __ANSI_PROTO((ident_t*,int,char *,int,int));
void 	msqlProcessQuery ();
void 	msqlPushCond ();
void 	msqlAddSubCond __ANSI_PROTO((int));
void 	msqlParseQuery __ANSI_PROTO((char *,int));
void 	msqlFreeValue __ANSI_PROTO((val_t *));
void 	msqlSetDB __ANSI_PROTO((char *));
void 	msqlSetSelectLimit __ANSI_PROTO((val_t *));
void 	msqlAddFieldValue __ANSI_PROTO((val_t *));
void 	msqlAddCond __ANSI_PROTO((ident_t*,int,val_t*,int));
void 	msqlAddOrder __ANSI_PROTO((ident_t*,int));
void 	msqlAddTable __ANSI_PROTO((char*,char*));
void 	msqlAddIndex __ANSI_PROTO((char*, char*, int, int));
void 	msqlClean();
val_t 	*nullValue();
val_t 	*fillValue __ANSI_PROTO((char *,int,int));
val_t 	*msqlCreateValue __ANSI_PROTO((u_char *,int,int));
ident_t *msqlCreateIdent __ANSI_PROTO((char*,char*));



/* acl.c prototypes */
int 	msqlLoadAcl __ANSI_PROTO((int));
int 	msqlCheckAccess __ANSI_PROTO((char *,cinfo_t *));
void 	msqlServerReloadAcls __ANSI_PROTO((int));
void 	msqlSetPerms __ANSI_PROTO((int));
int 	msqlCheckPerms __ANSI_PROTO((int));
int 	msqlCheckLocal __ANSI_PROTO((cinfo_t *));

/* memory.c prototypes */
void 	checkBlocks __ANSI_PROTO((int));
caddr_t MMap __ANSI_PROTO((caddr_t,size_t,int,int,int,off_t,char *,int));
int 	MUnmap __ANSI_PROTO((caddr_t,size_t,char *,int));
char 	*FastMalloc __ANSI_PROTO((int,char *,int));
char 	*Malloc __ANSI_PROTO((int,char *,int));
char 	*Strdup __ANSI_PROTO((char *,char *,int));
void 	Free __ANSI_PROTO((char *, char *,int));

/* Parser & Scanner prototypes */
int	yyparse();
void 	msqlInitScanner __ANSI_PROTO((u_char *));

/* Misc prototypes */
char 	*msql_tmpnam __ANSI_PROTO((char *));

#endif /* MSQL_PRIV_H */
