/*
 ******************************************************************************
 *  Copyright 1984-1993 United States Data Corporation. All Rights Reserved.
 ******************************************************************************
 *                                - NOTICE -
 *
 *  The information contained herein is confidential information of United
 *  States Data Corporation, a Delaware corporation, and is protected by
 *  United States copyright and trade secret law and international treaties.
 *  This information is not to be disclosed, used or copied by or transferred
 *  to any individual, corporation, company or other person without the
 *  express written permission of United States Data Corporation.
 ******************************************************************************
 *
 * Module:	HDT_DBC.H
 *
 *	Header file for database cursor API.
 *
 * History:
 *		bjc 04/29/93	Created. 
 */


#ifndef _DBC_INCLUDED
#define _DBC_INCLUDED

#include <hdt_base.h>		/* Base Definitions for the API */
#include <hdt_sqls.h>

/*
 ************************************************************************
 *                              Constants                               *       
 ************************************************************************
 */

/* 
 * States of the cursor 
 */

#define DBC_CLOSED	0	/* cursor is closed */
#define DBC_PREPED	1	/* cursor is prepared */
#define DBC_EXECED	2	/* cursor is being executed */
#define DBC_FETCHED	3	/* cursor is being fetched */

/* 
 * Cursor operation types
 */

#define DBC_READER		0x0001	/* query is a read-only operation */
#define DBC_WRITER		0x0002	/* query is a write operation */

/*
 *   OR-wise flags for cursor
 */

#define DBC_HADT_CURSOR		0x0001L	/* reserved for HADTLIB cursors */
#define DBC_FREE_PARAMS_DA	0x0002L	/* free params hs_da structure */
#define DBC_FREE_SELECT_DA	0x0004L	/* free select hs_da structure */
#define DBC_FREE_PARAMS_DATA	0x0008L	/* free params data for hs_da */
#define DBC_FREE_SELECT_DATA	0x0010L	/* free select data for hs_da */
#define DBC_FREE_QMEMBER	0x0020L	/* free cursor's query member */
#define DBC_FREE_QINSTANCE	0x0040L	/* free cursor's query instance */
#define DBC_FREE_UDATA		0x0080L	/* free cursor's UDATA */

/* 
 *  Return codes from dbc_fetch_one() 
 */

#define DBC_FETCH_ERR	(-1)	/* error occured during fetch */
#define DBC_FETCH_OK	0	/* fetch of next row successful */
#define DBC_FETCH_END	1	/* no more data to fetch */
#define DBC_FETCH_HALT	2	/* Fetch handler requested fetch to stop */

/* 
 *  Return codes from DBC_REC2DA functions
 */

#define	DBC_FETCH_CONTINUE	0
#define DBC_FETCH_STOP		1


/*
 ************************************************************************
 *                           Global Variables                           * 
 ************************************************************************
 */

/*
 *	Reserved HADTLIB query group value.  All cursors created by 
 *	the HADTLIB (except dynamic SQL which has its own group) should set 
 *	their 'qgroup' equal to this value in order to prevent conflicts 
 *	with user specified group values.
 */

extern void	*Dbc_hadt_qgroup;

/*
 ************************************************************************
 *                           Types & Structures                         * 
 ************************************************************************
 */

/*
 *  Query identification components
 */

typedef int (*DBC_CMP_QMEMBER) (void*, void*); 	/* QID comp func., returns */
						/* 0 for same, !0 for diff */
typedef void (*DBC_DSTR_QMEMBER) (void*);	/* QID member free function */

typedef int (*DBC_CMP_QINST) (void*, void*);	/* INST comp func., returns */
						/* 0 for same, !0 for diff */
typedef void (*DBC_DSTR_QINST) (void*);		/* Instance free function */

/*
 *  User-associated cursor data de-allocation routine
 */

typedef void (*DBC_DSTR_UDATA) (void*);  	/* UDATA free function */

/* 
 *  DBC - DataBase Cursor structure
 *
 *  A database cursor structure denotes one open SQL statement between the
 *  task and an historian.  Several open statements can be chained off
 *  a single task-historian database session (see structure DBS).
 */

typedef struct _dbc
{
	/*
	 *  Cursor session data
	 */

	void		*dbs;			/* cursor's session */
	struct _dbc	*next;			/* next cursor in session */

	SQLS		*sqls;			/* SQL statement */
	HSD_STMTID	*hs_stmt;		/* historian rec for cursor */	
	HS_DA		*select; 		/* output data for select */
	HS_DA		*params; 		/* input data for params */
	u32		flags;			/* flags that tune cursor */
	int		rw_mode; 		/* read or write statement */
	int		status;	 		/* cursor state */

	/*
	 *  The  'r_tot' and ' r_remain' members are used by the 
	 *  dbc_fetch_first() and dbc_fetch_next() functions for 
	 *  seamless, buffered fetching.
	 */

	int		r_tot;			/* tot rows fetched in buf */
	int		r_remain;		/* rows remaining in buffer */

	/*
	 *  Cursor idenfication/de-allocation members
	 */

	void		*qgroup;		/* query ID group */
	void		*qmember;		/* query ID member/variant */
	void		*qinstance;		/* query ID instance */
	DBC_CMP_QMEMBER	qmember_cmp;		/* QID mem comparsion func */
	DBC_DSTR_QMEMBER qmember_destroy;	/* QID member free func */
	DBC_CMP_QINST	qinst_cmp;		/* Q instance cmp func */
	DBC_DSTR_QINST	qinst_destroy;		/* Q instance free function */

	void		*udata;			/* user assigned data */
	DBC_DSTR_UDATA	udata_destroy;		/* UDATA free function */

} DBC;


/*
 *  User provided function to move data from a user-record to a HS_DA.
 *  The DBC_REC2DA function should return one of the following:
 *
 *	DBE_GOOD 
 *	DBE_ERROR
 */

typedef int (*DBC_REC2DA) (HS_DA*, short, void*);

/*
 *  Data transfer prototype for functions passed into dbs_fetch_one().
 *
 *  Type description for functions that transfer data from an HS_DA
 *  into a target structure.  When a fetch is performed, its resulting
 *  data is placed into a generic HS_DA.  These functions copies the
 *  this data from the generic HS_DA into structures specialized for 
 *  that data.
 *
 *  Function dbs_fetch_one() ENFORCES that the DBS_DA2REC function 
 *  return one of the following:
 *
 *	DBC_FETCH_CONT
 *	DBC_FETCH_STOP
 */

typedef int (*DBC_DA2REC) (void*, HS_DA*, short);


/*
 ************************************************************************
 *                              Macros                                  *       
 ************************************************************************
 */

/*
 *	Macros to obtain read-only members of a DBC.  These values
 *	should not be altered unless you understand the implications.
 */

#define dbc_get_dbs(p)		((DBS*) (p)->dbs)
#define dbc_set_dbs(p, q)	((p)->dbs = (void*) q)

#define dbc_get_sqls(p)		((p)->sqls)
#define dbc_get_sql_stmt(p)	(sqls_get_sql_stmt((p)->sqls))
#define dbc_get_select(p)	((p)->select)
#define dbc_get_params(p)	((p)->params)
#define dbc_get_rw_mode(p)	((p)->rw_mode)

/*
 *	Macros to modify members of a DBC which only the session to
 *	which it attached should alter. 
 */

#define dbc_get_hs_stmt(p)	((p)->hs_stmt)
#define dbc_set_hs_stmt(p, s)	((p)->hs_stmt = s)

#define dbc_get_status(p)	((p)->status)
#define dbc_set_status(p,s)	((p)->status = s)

#define dbc_get_r_tot(p)	((p)->r_tot)
#define dbc_set_r_tot(p,s)	((p)->r_tot = s)
#define dbc_get_r_remain(p)	((p)->r_remain)
#define dbc_set_r_remain(p,s)	((p)->r_remain = s)

/*
 *  Macros used to manipulate cursor identification members of DBC
 */

#define dbc_get_qgroup(p)		((p)->qgroup)
#define dbc_set_qgroup(p, qg)		((p)->qgroup = qg)

#define dbc_get_qmember(p)		((p)->qmember)
#define dbc_set_qmember(p, qm)		((p)->qmember = qm)

#define dbc_get_qinstance(p)		((p)->qinstance)
#define dbc_set_qinstance(p, qi)	((p)->qinstance = qi)

#define dbc_get_qmember_cmp(p)		((p)->qmember_cmp)
#define dbc_set_qmember_cmp(p, s)	((p)->qmember_cmp = s)

#define dbc_get_qmember_destroy(p)	((p)->qmember_destroy)
#define dbc_set_qmember_destroy(p, s)	((p)->qmember_destroy = s)

#define dbc_get_qinstance_cmp(p)	((p)->qinst_cmp)
#define dbc_set_qinstance_cmp(p, s)	((p)->qinst_cmp = s)

#define dbc_get_qinstance_destroy(p)	((p)->qinst_destroy)
#define dbc_set_qinstance_destroy(p, s)	((p)->qinst_destroy = s)

#define dbc_get_udata(p)		((p)->udata)
#define dbc_set_udata(p, s)		((p)->udata = s)

#define dbc_get_udata_destroy(p)	((p)->udata_destroy)
#define dbc_set_udata_destroy(p, s)	((p)->udata_destroy = s)

#define dbc_get_flags(p)		((p)->flags)
#define dbc_set_flags(p, flg)		((p)->flags = flg)


/*
 ************************************************************************
 *                         Function Prototypes                          * 
 ************************************************************************
 */
#ifdef __cplusplus
extern "C" {
#endif

extern DBC*	dbc_create(char *sql_stmt, HS_DA *select, HS_DA *params, 
		           u32 flags, int rw_mode);

extern int	dbc_identify(DBC *dbc, void *qgroup, 
		             void *qmember, void *qinstance);

extern int	dbc_prepare_cursor(DBC *dbc);
extern int	dbc_exec_cursor(DBC *dbc, int sync);
extern int	dbc_fetch_cursor(DBC *dbc, int rows_req, int *rows_fetched);
extern int	dbc_fetch_onerow(DBC *dbc, DBC_DA2REC da2rec, void *rec);
extern int	dbc_commit_cursor(DBC *dbc, int sync);
extern int	dbc_close_cursor(DBC *dbc, int sync);

extern void	dbc_destroy(DBC *dbc);


#ifdef __cplusplus
}
#endif

#endif


