#include <stdio.h>
#include <stdlib.h>
#include "libpq-fe.h"
#include "post.h"

/* add_PGresult(PGresult)
 * 		Creates a linked list of PGresult's so that they can be freed when
 *		they are no longer needed.
 */
void add_PGresult(PGresult* new_PGresult) {
	static PGresult_ll_type *end;
	PGresult_ll_type *PGresult_ll;

	PGresult_ll=malloc(sizeof(void*)*2);
	
	if (!PGresult_ll_start)
		/* set start point of ll if not already set */
		PGresult_ll_start=end=PGresult_ll;

	if ( end != PGresult_ll ) 
		  /* this is not the first element of ll, so set the old
           * end of ll to point to the new end of ll */
		end->next=PGresult_ll;

	/* set data for ll */
	PGresult_ll->next=NULL;
	PGresult_ll->result=new_PGresult;

	/* update end to point to new end of ll */
	end = PGresult_ll;
}

 /* closedb() 
  *		Closes database connection and frees memory associated with it 
  */
void closedb() {
	PGresult_ll_type *foo;

	while ( PGresult_ll_start ) {
		PQclear(PGresult_ll_start->result);
		foo = PGresult_ll_start;
		PGresult_ll_start=PGresult_ll_start->next;	
		free(foo);
	}
		
	PQfinish(conn);	
}


/* initdb () 
 *	makes a connection to the database
 ****/
PGconn* initdb() {
	if ( !conn ) {
		conn = PQconnectdb(CONNECTION_STRING);
		atexit(closedb);
	}
	if ( PQstatus(conn) == CONNECTION_BAD ) {
		printf("Could not connect to Database, DB returned %s\n",
				PQerrorMessage(conn));
		exit(EXIT_FAILURE);
	}
	return(conn);
} 

/* exec (string)
 * executes string, terminates on error
 * initiates connection to database if not already connected
 *
 * NOTE: using 'exec' as a function name is in general bad, and this
 *       is no exception.
 ***/ 
PGresult* exec(const char *string) {
	PGresult *foo;
	if ( !conn ) 
		initdb();
	foo=PQexec(conn, string);
	if (!foo) {
		printf("Fatal Error: %s\n",
			    PQerrorMessage(conn));	
		exit(EXIT_FAILURE);
	}
	if ((PQresultStatus(foo) != PGRES_TUPLES_OK) && 
	    (PQresultStatus(foo) != PGRES_COMMAND_OK) )
		printf("%s returns\n %s\n",string, PQerrorMessage(conn));	

	add_PGresult(foo);
	return(foo);
}


