#include <stdio.h>
#include <string.h>
#include <time.h>
#include <libpq-fe.h>

#ifndef INSERTPERTRANSACTION
#define INSERTPERTRANSACTION 400
#endif

void exit_nicely(PGconn *conn)
{
	PQfinish(conn);
	exit(1);
}

int main(int argc, char **argv)
{
	char query[2048];
	char *pghost,
         *pgport,
         *pguser,
         *pgpass,
         *pgoptions,
         *pgtty;
	char *dbName;
  	int  nFields;
	int i;
 
     /* FILE *debug; */
 
	PGconn     *conn;
	PGresult   *res;

	pghost = NULL;
	pgport = NULL;
	pgoptions = NULL;
	pgtty = NULL;
	pguser = "postgres";
	pgpass = NULL;
	dbName = "pgtest";


	conn = PQsetdbLogin(pghost, pgport, pgoptions, pgtty, dbName,
						pguser, pgpass);
 
	/*
	* check to see that the backend connection was successfully made
  	*/
	if (PQstatus(conn) == CONNECTION_BAD)
	{
		fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
		fprintf(stderr, "%s", PQerrorMessage(conn));
		exit_nicely(conn);
	}


	/* Do 200000 inserts for this instance */
	for (i = 0; i < 200000; i++)
	{
#ifdef TRANSACTION
		/* First insert in transaction block begins, BEGIN TRANSACTION */
		if (!(i % INSERTPERTRANSACTION)) {
			/* start a transaction block */
			res = PQexec(conn, "BEGIN");
			if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
			{
				fprintf(stderr, "BEGIN command failed\n");
				PQclear(res);
				exit_nicely(conn);
			}
 
			/*
			* should PQclear PGresult whenever it is no longer needed to avoid
			* memory leaks
			*/
			PQclear(res);
		}
#endif

		snprintf(query, 2048,
			"INSERT INTO LOGS (CTIME, STIME, ITIME, AGENTID, SUBAGENTID, "
			"OWNERID, HOSTID, APPNAME, LOGBODY) VALUES "
			"('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s', '%s');",
			(int) time(NULL),         /* simulate CTIME epoch */
			(int) time(NULL) + 23,    /* simulate STIME epoch */
			(int) time(NULL) + 45,    /* simulate ITIME epoch */
			(int) time(NULL) % 5,     /* simulate 5 different AGENTID */
			(int) time(NULL) % 15,    /* simulate 5 different SUBAGENTID */
			(int) time(NULL) % 200,   /* simulate 200 different OWNERID */
			(int) time(NULL) % 10,    /* simulate 10 different HOSTID */
			argv[0],
			"The dummy log for testing PostgreSQL 7.3.4 "
			"speed under heavy conditions."
			);

		/* start a transaction block */
		res = PQexec(conn, query);
		if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
		{
			fprintf(stderr, "INSERT command failed\n");
			fprintf(stderr, "Backend Says:%s\n", PQresultErrorMessage(res));
			PQclear(res);
			exit_nicely(conn);
		}

		/*
		* should PQclear PGresult whenever it is no longer needed to avoid
		* memory leaks
		*/
		PQclear(res);

#ifdef TRANSACTION
		/* The last insert in this transaction, it is time to COMMIT */
		if ((i % INSERTPERTRANSACTION) == (INSERTPERTRANSACTION - 1)) {
			/* start a transaction block */
			res = PQexec(conn, "COMMIT");
			if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
			{
				fprintf(stderr, "COMMIT command failed\n");
				PQclear(res);
				exit_nicely(conn);
			}
 
			/*
			* should PQclear PGresult whenever it is no longer needed to avoid
			* memory leaks
			*/
			PQclear(res);
		}
#endif

		if (!(i%1000)) { /* display time information for each 1000 inserts */
			fprintf(stderr, "%8d\t %d\n", i, (int) time(NULL));
		}

	}

#ifdef TRANSACTION
	/* Do truncated commit */
	if ((i % INSERTPERTRANSACTION) != 0) {
		printf("COMMIT TRANSACTION\n");
		/* start a transaction block */
		res = PQexec(conn, "COMMIT");
		if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
		{
			fprintf(stderr, "COMMIT command failed\n");
			PQclear(res);
			exit_nicely(conn);
		}

		/*
		* should PQclear PGresult whenever it is no longer needed to avoid
		* memory leaks
		*/
		PQclear(res);
	}
#endif

	exit_nicely(conn);

}
