/*
 * src/test/examples/testlibpqpipeline2.c
 *
 *
 * testlibpqpipeline.c
 *		this test program tests query pipelining.  It shows how to issue multiple
 *      pipelined queries, and identify from which query a result originated.  It 
 *      also demonstrates how failure of one query does not impact subsequent queries
 *      when they are not part of the same transaction.
 *
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

#include "libpq-fe.h"

static void checkResult(PGconn *conn, PGresult *result, PGquery *query, int expectedResultStatus)
{
	if (PQresultStatus(result) != expectedResultStatus)
	{
		printf( "Got unexpected result status '%s', expected '%s'\nQuery:%s\n", 
			PQresStatus(PQresultStatus(result)), PQresStatus(expectedResultStatus),
			PQgetQueryCommand(query));
		PQclear(result);
		PQclear(PQexec(conn,"DROP TABLE test"));
		PQfinish(conn);
		exit(1);
	}
	PQclear(result);
}

int
main(int argc, char **argv)
{
	PGconn * conn;
	PGquery * query1;
	PGquery * query2;
	PGquery * query3;
	PGquery * curQuery;
	PGresult * result;
	
	conn = NULL;
	query1 = query2 = query3 = curQuery = NULL;
	result = NULL;
	
	/* make a connection to the database */
	conn = PQsetdb(NULL, NULL, NULL, NULL, NULL);

	/* check to see that the backend connection was successfully made */
	if (PQstatus(conn) != CONNECTION_OK)
	{
		fprintf(stderr, "Connection to database failed: %s",
				PQerrorMessage(conn));
		exit(1);
	}

	checkResult(conn,PQexec(conn,"DROP TABLE IF EXISTS test"),NULL,PGRES_COMMAND_OK);
	checkResult(conn,PQexec(conn,"CREATE TABLE test ( id SERIAL PRIMARY KEY )"),NULL,PGRES_COMMAND_OK);
	
	PQsendQuery(conn, "INSERT INTO test(id) VALUES (DEFAULT),(DEFAULT) RETURNING id");
	query1 = PQgetLastQuery(conn);
	
	/* Duplicate primary key error */
	PQsendQuery(conn, "UPDATE test SET id=2 WHERE id=1");
	query2 = PQgetLastQuery(conn);
	
	PQsendQuery(conn, "SELECT * FROM test");
	query3 = PQgetLastQuery(conn);
	
	while( 1 )
	{
		if( PQconsumeInput(conn) == 0 ) {
			printf( "PQconsumeInput ERROR: %s\n", PQerrorMessage(conn) );
			return 1;
		}
		
		if (PQisBusy(conn))
			continue;
		
		curQuery = PQgetFirstQuery(conn);
		result = PQgetResult(conn);
		
		/* Finished processing results? */
		if (result == NULL)
			break;
		
		if (curQuery == query1)
			checkResult(conn,result,curQuery,PGRES_TUPLES_OK);
		if (curQuery == query2)
			checkResult(conn,result,curQuery,PGRES_FATAL_ERROR);
		if (curQuery == query3)
			checkResult(conn,result,curQuery,PGRES_TUPLES_OK);
	}

	PQexec(conn,"DROP TABLE test");
	
	return 0;
} 