--- /dev/null
+.\" This is -*-nroff-*-
+.\" XXX standard disclaimer belongs here....
+.\" $Header: /cvsroot/pgsql/src/interfaces/libpgeasy/Attic/libpgeasy.3,v 1.1 1999/10/12 14:06:49 momjian Exp $
+.TH PGEASY INTRO 08/08/98 PostgreSQL PostgreSQL
+.SH DESCRIPTION
+Pgeasy allows you to cleanly interface to the libpq library,
+more like a 4gl SQL interface.
+.PP
+It consists of set of simplified C functions that encapsulate the
+functionality of libpq.
+The functions are:
+
+.nf
+PGresult *doquery(char *query);
+PGconn *connectdb();
+void disconnectdb();
+
+int fetch(void *param,...);
+int fetchwithnulls(void *param,...);
+void reset_fetch();
+
+void on_error_continue();
+void on_error_stop();
+
+PGresult *get_result();
+void set_result(PGresult *newres);
+void unset_result(PGresult *oldres);
+.fi
+.PP
+Many functions return a structure or value, so you can do more work
+with the result if required.
+.PP
+You basically connect to the database with
+.BR connectdb ,
+issue your query with
+.BR doquery ,
+fetch the results with
+.BR fetch ,
+and finish with
+.BR disconnectdb .
+.PP
+For
+.IR select
+queries,
+.BR fetch
+allows you to pass pointers as parameters, and on return the variables
+are filled with data from the binary cursor you opened. These binary
+cursors can not be used if you are running the
+.BR pgeasy
+client on a system with a different architecture than the database
+server. If you pass a NULL pointer parameter, the column is skipped.
+.BR fetchwithnulls
+allows you to retieve the
+.IR null
+status of the field by passing an
+.IR int*
+after each result pointer, which returns true or false if the field is null.
+You can always use libpq functions on the PGresult pointer returned by
+.BR doquery .
+.BR reset_fetch
+starts the fetch back at the beginning.
+.PP
+.BR get_result ,
+.BR set_result ,
+and
+.BR unset_result
+allow you to handle multiple result sets at the same time.
+.PP
+There are a variety of demonstration programs in the
+.BR pgeasy
+source directory.
--- /dev/null
+/*
+ * pgeasy.c
+ *
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include <libpq-fe.h>
+#include "halt.h"
+#include "libpgeasy.h"
+
+#define NUL '\0'
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/* GLOBAL VARIABLES */
+static PGconn *conn;
+static PGresult *res = NULL;
+
+#define ON_ERROR_STOP 0
+#define ON_ERROR_CONTINUE 1
+
+static int on_error_state = ON_ERROR_STOP;
+
+static in_result_block = FALSE;
+static was_get_unset_result = FALSE;
+
+/* LOCAL VARIABLES */
+static int tuple;
+
+/*
+**
+** connectdb - returns PGconn structure
+**
+*/
+PGconn *
+connectdb(char *dbName,
+ char *pghost,
+ char *pgport,
+ char *pgoptions,
+ char *pgtty)
+{
+ /* make a connection to the database */
+ conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
+ if (PQstatus(conn) == CONNECTION_BAD)
+ halt("Connection to database '%s' failed.\n%s\n", dbName,
+ PQerrorMessage(conn));
+ return conn;
+}
+
+/*
+**
+** disconnectdb
+**
+*/
+void
+disconnectdb()
+{
+ PQfinish(conn);
+}
+
+/*
+**
+** doquery - returns PGresult structure
+**
+*/
+PGresult *
+doquery(char *query)
+{
+ if (res != NULL && in_result_block == FALSE && was_get_unset_result == FALSE)
+ PQclear(res);
+
+ was_get_unset_result = FALSE;
+ res = PQexec(conn, query);
+
+ if (on_error_state == ON_ERROR_STOP &&
+ (res == NULL ||
+ PQresultStatus(res) == PGRES_BAD_RESPONSE ||
+ PQresultStatus(res) == PGRES_NONFATAL_ERROR ||
+ PQresultStatus(res) == PGRES_FATAL_ERROR))
+ {
+ if (res != NULL)
+ fprintf(stderr, "query error: %s\n", PQcmdStatus(res));
+ else
+ fprintf(stderr, "connection error: %s\n", PQerrorMessage(conn));
+ PQfinish(conn);
+ halt("failed request: %s\n", query);
+ }
+ tuple = 0;
+ return res;
+}
+
+/*
+**
+** fetch - returns tuple number (starts at 0), or the value END_OF_TUPLES
+** NULL pointers are skipped
+**
+*/
+int
+fetch(void *param,...)
+{
+ va_list ap;
+ int arg,
+ num_fields;
+
+ num_fields = PQnfields(res);
+
+ if (tuple >= PQntuples(res))
+ return END_OF_TUPLES;
+
+ va_start(ap, param);
+ for (arg = 0; arg < num_fields; arg++)
+ {
+ if (param != NULL)
+ {
+ if (PQfsize(res, arg) == -1)
+ {
+ memcpy(param, PQgetvalue(res, tuple, arg), PQgetlength(res, tuple, arg));
+ ((char *) param)[PQgetlength(res, tuple, arg)] = NUL;
+ }
+ else
+ memcpy(param, PQgetvalue(res, tuple, arg), PQfsize(res, arg));
+ }
+ param = va_arg(ap, char *);
+ }
+ va_end(ap);
+ return tuple++;
+}
+
+/*
+**
+** fetchwithnulls - returns tuple number (starts at 0),
+** or the value END_OF_TUPLES
+** Returns TRUE or FALSE into null indicator variables
+** NULL pointers are skipped
+*/
+int
+fetchwithnulls(void *param,...)
+{
+ va_list ap;
+ int arg,
+ num_fields;
+
+ num_fields = PQnfields(res);
+
+ if (tuple >= PQntuples(res))
+ return END_OF_TUPLES;
+
+ va_start(ap, param);
+ for (arg = 0; arg < num_fields; arg++)
+ {
+ if (param != NULL)
+ {
+ if (PQfsize(res, arg) == -1)
+ {
+ memcpy(param, PQgetvalue(res, tuple, arg), PQgetlength(res, tuple, arg));
+ ((char *) param)[PQgetlength(res, tuple, arg)] = NUL;
+ }
+ else
+ memcpy(param, PQgetvalue(res, tuple, arg), PQfsize(res, arg));
+ }
+ param = va_arg(ap, char *);
+ if (PQgetisnull(res, tuple, arg) != 0)
+ *(int *) param = 1;
+ else
+ *(int *) param = 0;
+ param = va_arg(ap, char *);
+ }
+ va_end(ap);
+ return tuple++;
+}
+
+/*
+**
+** on_error_stop
+**
+*/
+void
+on_error_stop()
+{
+ on_error_state = ON_ERROR_STOP;
+}
+
+/*
+**
+** on_error_continue
+**
+*/
+void
+on_error_continue()
+{
+ on_error_state = ON_ERROR_CONTINUE;
+}
+
+
+/*
+**
+** get_result
+**
+*/
+PGresult *
+get_result()
+{
+ char *cmdstatus = PQcmdStatus(res);
+
+ was_get_unset_result = TRUE;
+
+ /* we have to store the fetch location somewhere */
+ cmdstatus[0] = NUL;
+ memcpy(&cmdstatus[1], &tuple, sizeof(tuple));
+
+ return res;
+}
+
+/*
+**
+** set_result
+**
+*/
+void
+set_result(PGresult *newres)
+{
+
+ char *cmdstatus = PQcmdStatus(res);
+
+ if (newres == NULL)
+ halt("set_result called with null result pointer\n");
+
+ if (res != NULL && was_get_unset_result == FALSE)
+ if (in_result_block == FALSE)
+ PQclear(res);
+ else
+ {
+ cmdstatus[0] = NUL;
+ memcpy(&cmdstatus[1], &tuple, sizeof(tuple));
+ }
+
+ in_result_block = TRUE;
+ was_get_unset_result = FALSE;
+
+ cmdstatus = PQcmdStatus(newres);
+ memcpy(&tuple, &cmdstatus[1], sizeof(tuple));
+
+ res = newres;
+}
+
+
+/*
+**
+** unset_result
+**
+*/
+void
+unset_result(PGresult *oldres)
+{
+ char *cmdstatus = PQcmdStatus(oldres);
+
+ if (oldres == NULL)
+ halt("unset_result called with null result pointer\n");
+
+ if (in_result_block == FALSE)
+ halt("Unset of result without being set.\n");
+
+ was_get_unset_result = TRUE;
+ cmdstatus[0] = NUL;
+ memcpy(&cmdstatus[1], &tuple, sizeof(tuple));
+ in_result_block = FALSE;
+}
+
+/*
+**
+** reset_fetch
+**
+*/
+void
+reset_fetch()
+{
+ tuple = 0;
+}