/* See the copyright notice (COPYRIGHT) in this directory. */

/*
 * NAME    
 *	gdi_postgres.h
 *
 * SYNOPSIS
 *      Contains defines and function prototypes for GDI interface to Postgres.
 *
 * AUTHOR
 *	J. T. Anderson, SAIC Open Systems Division
 *
 * SccsId:  @(#)gdi_postgres.h	16.2 8/3/93
 */

#ifndef _GDI_POSTGRES_H_
#define _GDI_POSTGRES_H_

/* POSTGRES includes are at bottom of file because definitions conflict */

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include "libgendb.h"
#include "pg_types.h"
#include "proto.h"
#include "utilities.h"

#undef PALLOC_DEBUG

#undef palloc

#define PG_ALLOC_FAIL -1

#define PG_NOT_IMPLEMENTED "not implemented in POSTGRES yet"
#define PG_NA_S "function not applicable to POSTGRES database"

	/* =====================
	 * POSTGRES OBJECT SIZES
	 * =====================
	 */
#define PG_ERROR_LOG_SIZE	256
#define PG_SMALLERROR_SIZE	320	/* define a smaller error size */
#define PG_ERRORMSG_SIZE 	4096	/* error_msg_length in libpq.h */
#define PG_ERROR_SIZE		PG_ERRORMSG_SIZE

#define	PG_DBNAME_SIZE	        16	/* page 3 in the 4.1 User Manual */
#define PG_CLASS_SIZE	        16	/* from system catalogs */
#define	PG_OBJ_NAME_SIZE        PG_CLASS_SIZE
#define PG_NODE_SIZE		30
#define PG_TYPE_SIZE		40
#define PG_SHORT_COMMAND_SIZE	30
#define PG_COMMAND_SIZE	       256
#define PG_DATE_MASK_SIZE      30	/* Wed Jun 2 13:07:47 1993 PDT */
#define PG_DEFAULT_SEVERITY	GDI_WARNING

#define PG_GMT_TIME		1
#define PG_LOCAL_TIME		0
#define PG_NULL			-1	/* used by null indicator arrays */
#define PG_NOT_NULL		0

#define PG_ALL_PORTALS		0	/* synchronous (user) + asynch */
#define PG_ASYNCH_PORTALS	1
#define PG_MAX_PORTALS		10 	/* MAXPORTALS in libpq.h */
#define PG_PORTAL_NAME_SIZE     16 	/* portal_name_length in libpq.h */

	/* =====================
	 * POSTGRES ERROR CODES
	 * =====================
	 */
#define PG_LOCK_TIMEOUT		1100
#define PG_DUP_VERSION		1101

	/* =====================
	 * POSTGRES QUERY CODES
	 * =====================
	 */
#define PG_ABORT		1	/* abort a transaction */
#define PG_ADDATTR		2	/* add attribute to a class */
#define PG_APPEND		3	/* append an instance to a class */
#define PG_ATTACHAS		4	/* NOT IMPLEMENTED in 4.1 */
#define PG_BEGIN		5	/* begin a transaction */
#define PG_CHANGE_ACL		6	/* change access control list */
#define PG_CLOSE		7	/* close a portal */
#define PG_CLUSTER		8	/* NO EFFECT in 4.1 */
#define PG_COPY			9	/* copy data into or from a class */
#define PG_CREATE		10	/* create a class */
#define PG_CREATE_VERSION	11	/* snapshots NOT IMPLEMENTED in 4.1 */
#define PG_DEFINE_AGGREGATE	12
#define PG_DEFINE_FUNCTION	13
#define PG_DEFINE_INDEX		14
#define PG_DEFINE_OPERATOR	15
#define PG_DEFINE_RULE		16
#define PG_DEFINE_TYPE		17
#define PG_DEFINE_VIEW		18
#define PG_DELETE		19	/* delete instances from a class */
#define PG_DESTROY		20	/* destroy a class */
#define PG_EXTEND		21	/* extend a partial index */
#define PG_END			22	/* end (commit) a transaction */
#define PG_FETCH		23	/* fetch from a portal */
#define PG_LISTEN		24
#define PG_LOAD			25	/* load an object file */
#define PG_MERGE		26	/* NOT IMPLEMENTED in 4.1 */
#define PG_MOVE			27	/* move the pointer in a portal */
#define PG_NOTIFY		28	/* NOT IMPLEMENTED in 4.1 */
#define PG_PURGE		29	/* discard historical data */
#define PG_REMOVE_AGGREGATE	30	
#define PG_REMOVE_FUNCTION	31
#define PG_REMOVE_INDEX		32
#define PG_REMOVE_OPERATOR	33
#define PG_REMOVE_RULE		34
#define PG_REMOVE_TYPE		35
#define PG_REMOVE_VIEW		36	/* I can't find this command anywhere */
#define PG_RENAME		37	/* change class or attribute name */
#define PG_REPLACE		38	/* do an update */
#define PG_RETRIEVE		39
#define PG_RETRIEVE_INTO	40
#define PG_VACUUM		41
#define PG_UNKNOWN_QUERY	100

typedef struct pg_class
{
     char               name [PG_CLASS_SIZE + 1];
     struct pg_class   *next_t;
} PG_TMP_CLASS;

	/* Portal management is a bit artificial since a real portal is
	 * created only when results come back from a query.
	 */
typedef struct portal_def
{
	char	pg_pname[PG_PORTAL_NAME_SIZE+1];	/* Portal Name */
	int	pg_pcode;				/* Channel number */
	char	pg_fname[PG_SHORT_COMMAND_SIZE+1];	/* Query func name */
	int	pg_fcode;				/* Query func code */
} PRTDEF;

        /* vendor conn for Postgres */
typedef struct
{
	PRTDEF		**channel;		/* channels */
	int		num_channels;		/* num of allocated channels */
	int		session_id;		/* Postgres session id    */
	PG_TMP_CLASS	*temp_tables;		/* list of temporary tables  */
	char		err_log[PG_ERROR_LOG_SIZE+1];	/* log location */
	char		err_type;		/* single character code     */
	char		err_text [PG_ERROR_SIZE + 1]; 
	char		date_mask[PG_DATE_MASK_SIZE+1];
	int		tr_state;
} dbConnPostgres;

#define PG_SESSION_ID(conn)   (((dbConnPostgres *) (conn)->vendor_conn)->session_id)
#define PG_TEMP_TABLES(conn)  (((dbConnPostgres *) (conn)->vendor_conn)->temp_tables)
#define PG_ERROR_LOG(conn)    (((dbConnPostgres *) (conn)->vendor_conn)->err_log)
#define PG_ERROR_TYPE(conn)   (((dbConnPostgres *) (conn)->vendor_conn)->err_type)
#define PG_ERROR_MSG(conn)    (((dbConnPostgres *) (conn)->vendor_conn)->err_text)
#define PG_TRAN(conn)    (((dbConnPostgres *) (conn)->vendor_conn)->tr_state)

/* channel management */
#define PG_CHANNELS(conn)     (((dbConnPostgres *) (conn)->vendor_conn)->channel)
#define PG_CHAN(conn, n)      (((dbConnPostgres *) (conn)->vendor_conn)->channel[n])
#define PG_NUM_CHANNELS(conn) (((dbConnPostgres *) (conn)->vendor_conn)->num_channels)
#define PG_PORT_NUM(conn, n)  (((dbConnPostgres *) (conn)->vendor_conn)->channel[n]->pg_pcode)
#define PG_PORT_NAME(conn, n) (((dbConnPostgres *) (conn)->vendor_conn)->channel[n]->pg_pname)
#define PG_QUERY_CODE(conn,n) (((dbConnPostgres *) (conn)->vendor_conn)->channel[n]->pg_fcode)
#define PG_QUERY_NAME(conn,n) (((dbConnPostgres *) (conn)->vendor_conn)->channel[n]->pg_fname)

/* ============================================================================
 *                    Postgres interface function prototypes
 * ============================================================================
 */

/*
 * Function prototypes for database connect management
 */

Proto	(dbFuncs *, pg_link, ());

Proto	(dbStatus,	pg_open, 
	(
		dbConn	*conn, 		/* (i) database connector */
		char	*account,	/* (i) GDI_NA for POSTGRES */
		char	*password,	/* (i) GDI_NA for POSTGRES */
		char	*database,	/* (i) database name */
		char	*server,	/* (i) GDI_NA for POSTGRES */
		char	*appname	/* (i) NA for POSTGRES */
	  ));


Proto	(dbStatus,	pg_close, 
	 (
	  dbConn *conn 		/* (i) database connector */
	  ));

Proto	(dbStatus,	pg_dead, 
	 (
	  dbConn *conn 		/* (i) database connector */
	  ));

Proto (dbStatus, pg_print_conn,
	(
	dbConn  *conn		/* (i) database connector       */
	));


Proto   (dbStatus,   pg_submit,
	(
	dbConn	*conn,		/* (i) database connector   */
	char	*command,	/* (i) command              */
	int	maxrecs,	/* (i) maximum records      */
	dbConstr *constr,	/* (i) database constructor */
	dbObj	**results 	/* (o) results              */
));

Proto   (dbStatus,   pg_parse,
	(
	dbConn	*d,		/* (i) database connector   */
	char	*query,		/* (i) database query       */
	char	*pq,		/* (i/o) postquel command   */
	int	pq_len		/* (i) size of pq	*/
));

Proto   (dbStatus,   pg_query,
	(
	dbConn	*d,		/* (i) database connector */
	int	chan,		/* (i) query channel */
	char	*q_in,		/* (i) original query       */
	char	*q_out,		/* (o) final query       */
	int	q_len,		/* (i) size of q_out */
	char	*portal		/* (i/o) portal query will be executed on */
));

Proto   (dbStatus,   pg_fetch,
	(
	dbConn	*conn,		/* (i) database connector   */
	int	channo,		/* (i) database channel     */
	dbObj	*dbobj,		/* (o) dbObj results        */
	int	maxrec,		/* (i) max records the user wants */
	char	*pname		/* (i) portal data was retrieved on */
));

/*
 * Function prototypes for channel management
 */

Proto	(dbStatus,	pg_open_channel, 
	 (
	  dbConn *conn, 	/* (i) database connector */
	  int    *channo	/* (o) new channel number */
	  ));

Proto	(dbStatus,	pg_close_channel, 
	 (
	  dbConn *conn, 	/* (i) database connector */
	  int    channo		/* (i) channel number     */
	  ));

Proto	(dbStatus,	pg_channel_is_open,
	 (
	  dbConn *conn, 	/* (i) database connector */
	  int    channo		/* (i) channel number     */
	  ));

Proto	(dbStatus,	pg_portal_open,
	 (
	  dbConn *conn, 	/* (i) database connector */
	  int    channo,	/* (i) channel number     */
	  int	rule_type	/* (i) PG_ALL_PORTALS or PG_ASYNCH_PORTALS */
	  ));

Proto	(dbStatus,	pg_flush,
	 (
	  dbConn *conn, 	/* (i) database connector */
	  int    channo		/* (i) channel number     */
	  ));

/*
 *  Data type management 
 */

Proto (dbStatus, pg_build_dbtype,
	(
	dbConn	*dbconn,	/* (i) database connector              */
	char	*cname,		/* (i) column name		       */
	pgType	*dbtype,	/* (i/o) POSTGRES internal type        */
	char	*dbtype_s,	/* (o) POSTGRES type string            */
	int	slen,		/* (i) POSTGRES size of dbtype_s       */
	int	*max_arrlen	/* (o) elements in array if not scalar */
	));

Proto (dbStatus, pg_derive_ctype,
       (
	int	coerce_option,	/* (i) constructor coerce option */
	pgType	dbtype,		/* (i) POSTGRES internal type    */
	dbCtype	*ctype,		/* (o) C type                    */
	int	*max_strlen	/* (o) C string length           */
	));

Proto (dbStatus, pg_derive_etype,
       (
	dbCtype	ctype,		/* (i) C type                    */
	int	length,		/* (i) C string length  	 */
	int	*elength	/* (o) external length for malloc */
	));

Proto (dbStatus, pg_gdi_funcs,
	 (
	  dbConn *conn 		/* (i) database connector */
	  ));

Proto (dbStatus,      pg_get_elem, ( dbConn *conn, char *att_name, int *att_val ));
Proto (char *,   pg_get_type, ( dbConn *conn, int oid ));
Proto (int, pg_get_relid, 
	( dbConn *conn, char *class_name, int *class_oid));

Proto (dbStatus,	pg_builtin_dbtype_s, 
	(
		dbConn	*dbconn,
		pgType	*dbtype,
		char	*dbtype_s));


/*
 * error handling
 */
Proto	(dbStatus,	pg_error, 
	 (
		dbConn	*conn,		/* (i) database connector */
		int	channo,		/* (i) channel number      */
		char	*pg_buffer,	/* (i) postgres error buffer */
		char	*errtext	/* (i) custom error text  */
	  ));

Proto	(dbStatus,	pg_error_get, 
	 (
		dbConn	*conn,		/* (i) database connector */
		char	*errtext,	/* (i) custom error text  */
		int	maxtext		/* (i) length of errtext */
	  ));
/*
 * Function prototypes for transaction management
 */

Proto (dbStatus, pg_begin_tran,
	(
 		dbConn		*conn,		/* (i) database connector */
		int		channo,		/* (i) NA POSTGRES        */
		char		*tran_name	/* (i) NA POSTGRES        */
	));

Proto (dbStatus, pg_commit,
	(
 		dbConn		*conn,		/* (i) database connector */
		int		channo		/* (i) NA POSTGRES        */
	));

Proto (dbStatus, pg_rollback,
	(
 		dbConn		*conn,		/* (i) database connector */
		int		channo		/* (i) NA POSTGRES        */
	));

	/* pg_savepoint has no effect in POSTGRES, here for GDI compatibility */
Proto (dbStatus, pg_savepoint,
	(
	dbConn		*conn,		/* (i) database connector */
	int		channo,		/* (i) NA POSTGRES        */
	char		*sname		/* (i) NA POSTGRES	  */
	));

/*
 * Function prototypes for specialized database and utility functions
 */

Proto	(dbStatus,	pg_set_date_mask,
	 (
	  dbConn *conn,		/* (i) database connector */
	  char   *new_mask	/* (i) table name         */
	  ));

Proto	(dbStatus,	pg_get_date_mask,
	 (
	  dbConn *conn,		/* (i) database connector */
	  char   *new_mask,	/* (i) table name         */
          int    holder_size
	  ));

Proto	(dbStatus,	pg_create_table,
	 (
	  dbConn *conn,		/* (i) database connector */
	  char   *tablename,	/* (i) table name         */
	  dbObj  *tabledef      /* (i) table definition   */
	  ));

Proto	(dbStatus,	pg_temp_name,
	 (
	dbConn	*conn,
	char	*name,
	char	*new_name
	  ));

Proto	(dbStatus,	pg_add_table,
	(
	dbConn	*conn,
	char	*name
	));

Proto	(dbStatus,	pg_drop_tables,
	(
	dbConn	*conn
	));

Proto	(dbStatus,	pg_insert,
	 (
	  dbConn *conn,		/* (i) database connector */
	  char   *tablename,	/* (i) table name         */
	  dbObj  *datain        /* (i) input data         */
	  ));

Proto (dbStatus, pg_get_counter,
       (
	dbConn *conn,		/* (i) database connector */
	char   *table_name,	/* (i) table name         */
	char   *ctr_name,	/* (i) counter name       */
	int    n_keys,		/* (i) number of keys     */
	int    *key_value	/* (o) key value          */
	));

Proto (dbStatus, pg_describe_object,
       (
        dbConn   *conn,         /* (i) database connector  */
        char     *object_name,  /* (i) object name         */
        dbConstr *constr,       /* (i) results constructor */
        dbObj    **results      /* (o) results             */
        ));

Proto (dbStatus, pg_what_is_object,
       (
        dbConn   *conn,         /* (i) database connector  */
        char     *object_name,  /* (i) object name         */
        dbConstr *constr,       /* (i) results constructor */
        dbObj    **results      /* (o) results             */
        ));

Proto (dbStatus, pg_describe_query,
       (
        dbConn   *conn,         /* (i) database connector */
        char     *query,        /* (i) query              */
        dbObj    **results      /* (o) results            */
        ));

Proto (dbStatus, pg_trace,
	(
 		dbConn		*conn,		/* (i) database connector */
		int		mode,		/* (i) TRUE/FALSE         */
		char		*filename	/* (i) Sybase only        */
	));


Proto (dbStatus, pg_abort,
	(
 		dbConn		*conn		/* (i) database connector */
	));

Proto ( char *, pg_strncpy,
	(
		char	*to,		/* (i/o) destination string */
		char	*from,		/* (i) source string */
		int	to_len,		/* (i) destination length */
		int	from_len	/* (i) source length */
	));

Proto (int, pg_count, (dbConn *conn, char *query, char *portal));

Proto (int, pg_get_count, ( dbConn *conn, char *query));

/* Including libpq-fe.h also includes:
 *	tmp/libpq.h
 *	tmp/simplelists.h
 *	tmp/c.h
 *	utils/exc.h
 */
#include "tmp/libpq-fe.h"

Proto (void,	pg_PQpnames, (char [MAXPORTALS][PortalNameLength], int));
Proto (dbStatus,	pg_get_attr,
	(
		PortalBuffer	*portalbuf,	/* (i) portal buffer */
		int		tupno,		/* (i) tuple number */
		int		attno,		/* (i) attribute number */
		char		**result,	/* (o) data value */
		int		*length		/* (o) size of result */
	));

Proto	(char *, GetAttributeByName,
	 (
		TUPLE	tuple,
		char	*attname,
		char	*isnull
	));

Proto	(char *, PQexec, (char *query));
Proto	(void ,  PQsetdb, (char *dbname));
Proto	(void ,  PQreset, ());
Proto	(char *, PQgetvalue, (PortalBuffer *portal, int tuple_index, int field_number));

#endif
