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

/*
 * NAME
 * Public:
 *	pg_error()	- store an error
 *	pg_error_get()	- get an error
 *
 * Private:
 *	pg_error_zero() - initialize error variables
 *
 * SYNOPSIS
 *	#include "gdi_postgres.h"
 *
 *	dbStatus
 *	pg_error (conn, channo, pg_buffer, errtext)
 *	dbConn	*conn;
 *	int	channo;
 *	char	*pg_buffer;
 *	char	*errtext;
 *
 *	dbStatus
 *	pg_error_get (conn, errtext, maxtext)
 *	dbConn	*conn;
 *	char	*errtext;
 *	int	maxtext;
 *
 * BUGS
 *	PQerrormsg does not always get set.
 *
 * DIAGNOSTICS
 *	GDI_ERROR_STATUS gets set to GDI_SUCCESS or GDI_FAILURE.
 *	GDI_ERROR_STATUS (GDI_SUCCESS or GDI_FAILURE) is returned to the 
 *	calling application.
 *
 * FILES
 *	pg_error.c (this file)
 *
 * AUTHOR
 *	Jean T. Anderson, SAIC Open Systems Division
 */

#ifndef	lint
static char SccsId[] = "@(#)pg_error.c	16.2 8/7/93 Copyright (c) 1992-1993 Science Applications International Corporation";
#endif

#include "gdi_postgres.h" 

extern	char PQerrormsg[error_msg_length]; /* from libpq.h, here for clarity */
extern	dbConn null_conn;

Proto (static void, pg_error_zero, ( dbConn *conn ));

/*
 * pg_error ()
 *
 * Store postgres error
 *
 * Public
 */

dbStatus
pg_error (conn, channo, pg_buffer, errtext)
dbConn		*conn;		/* (i) dbConn			*/
int		channo;		/* (i) channel number		*/
char		*pg_buffer;	/* (i) Postgres results buffer	*/
char		*errtext;	/* (i) custom error text	*/
{
	char		*routine = "pg_error";
	char		pg_type, error_buffer[GDI_ERROR_SIZE+1];
	int		pg_bufsize;
	dbStatus	status;

	if ((conn == NULL) || (conn->vendor_conn == NULL))
	{
		sprintf(error_buffer, "%s: Database not connected", routine);
		gdi_error_app (conn, GDI_NOCONNECT, error_buffer);
		return (GDI_FAILURE);
	}

	pg_error_zero(conn);

	pg_bufsize=strlen(pg_buffer);

	if( conn->debug == GDI_DEBUG_VERBOSE)
	{
		fprintf(stderr, "%16s: %-14s: results buff size=%d, ",
			routine, errtext, pg_bufsize);
		if(pg_bufsize)
			fprintf(stderr, "contents=<%s>\n", pg_buffer);
	}

	if(pg_bufsize==0)
	{
                sprintf(error_buffer, 
			"%16s: Warning: Empty postgres results buffer",
			routine);
		gdi_error_app (conn, GDI_WARNING, error_buffer);
		return(GDI_WARNING);
	}

		/* Get the status type */
	PG_ERROR_TYPE(conn) = pg_type = pg_buffer[0];

	switch (pg_type)
	{
		case 'A':	/* asynchronous handling? I'm not sure */
		case 'B':	/* ready for 'copy' output */
		case 'C':	/* query 'C'ompleted   (tcop/dest.c)*/
		case 'D':	/* ready for 'copy' input */
		case 'I':	/* the last query finished (tcop/dest.c)*/
		case 'P':	/* Results are in the Portal buffer */
		   status=GDI_SUCCESS;
		   break;
		case 'E':	/* An error occurred */
		case 'R':	/* Something 'R'eally bad happened */
		default:
		   status=GDI_FAILURE;
		   break;
	}

	if(status == GDI_FAILURE)
	{
		/* We plan on parsing PQerrormsg and putting a 
		 * more "user friendly" message in GDI_ERROR_MSG.
		 * Until then, copy PQerrormsg into GDI_ERROR_MSG.
		 */
		/* errtext comes in from the calling routine */
		(void) pg_strncpy (GDI_ERROR_MSG (conn), errtext, 
			GDI_ERROR_SIZE, strlen(errtext));

		strncat (GDI_ERROR_MSG (conn), ": ", GDI_ERROR_SIZE);
		strncat (GDI_ERROR_MSG (conn), PQerrormsg, GDI_ERROR_SIZE);
		GDI_ERROR_MSG (conn) [GDI_ERROR_SIZE] = '\0';

/* Store PQerrormsg in PG_ERROR_MSG once we have implemented the
 * user-friendly message in GDI_ERROR_MSG.
 *		(void) pg_strncpy (PG_ERROR_MSG  (conn), PQerrormsg, 
 *			PG_ERROR_SIZE, strlen(PQerrormsg));
 */
		GDI_ERROR_CODE(conn) = GDI_FAILURE;
		GDI_ERROR_STATUS(conn) = GDI_FAILURE;
	}

	return (GDI_ERROR_STATUS(conn));
}


dbStatus
pg_error_get (conn, errtext, maxtext)
dbConn	*conn;
char	*errtext;
int	maxtext;
{
	char	*routine="pg_error_get";
	char	msgbuf[GDI_ERROR_SIZE+1];

	if ((conn == NULL) || (conn->vendor_conn == NULL))
	{
		sprintf(msgbuf, "%s: Database not connected.", routine);
		gdi_error_app (conn, GDI_NOCONNECT,  msgbuf);
		return (GDI_FAILURE);
	}

	sprintf(msgbuf, "%c: %s", PG_ERROR_TYPE(conn), PG_ERROR_MSG(conn));
	(void) pg_strncpy (errtext, msgbuf, maxtext, strlen(msgbuf));
	return (GDI_SUCCESS);
}

/*
 * Zero out (initialize) dbConn error information
 *
 * Private
 */
static void
pg_error_zero(conn)
dbConn  *conn;
{
        GDI_ERROR_STATUS(conn) = GDI_SUCCESS;
        GDI_ERROR_SEVERITY(conn) = GDI_NOERROR;
        GDI_ERROR_CODE(conn) = GDI_NOERROR;
        GDI_ERROR_MSG (conn) [0] = '\0';
	PG_ERROR_MSG(conn)[0] = '\0';
        return;
}
