Update pgeasy for missing files.
authorBruce Momjian <bruce@momjian.us>
Tue, 12 Oct 1999 14:06:49 +0000 (14:06 +0000)
committerBruce Momjian <bruce@momjian.us>
Tue, 12 Oct 1999 14:06:49 +0000 (14:06 +0000)
src/interfaces/libpgeasy/libpgeasy.3 [new file with mode: 0644]
src/interfaces/libpgeasy/libpgeasy.c [new file with mode: 0644]
src/interfaces/libpgeasy/libpgeasy.h [new file with mode: 0644]

diff --git a/src/interfaces/libpgeasy/libpgeasy.3 b/src/interfaces/libpgeasy/libpgeasy.3
new file mode 100644 (file)
index 0000000..e90da0e
--- /dev/null
@@ -0,0 +1,71 @@
+.\" 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.
diff --git a/src/interfaces/libpgeasy/libpgeasy.c b/src/interfaces/libpgeasy/libpgeasy.c
new file mode 100644 (file)
index 0000000..b067466
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * 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;
+}
diff --git a/src/interfaces/libpgeasy/libpgeasy.h b/src/interfaces/libpgeasy/libpgeasy.h
new file mode 100644 (file)
index 0000000..43fbeab
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * pglib.h
+ *
+*/
+
+PGresult   *doquery(char *query);
+PGconn    *connectdb(char *dbName,
+               char *pghost,
+               char *pgport,
+               char *pgoptions,
+               char *pgtty);
+void       disconnectdb(void);
+int            fetch(void *param,...);
+int            fetchwithnulls(void *param,...);
+void       on_error_continue(void);
+void       on_error_stop(void);
+PGresult   *get_result(void);
+void       set_result(PGresult *newres);
+void       unset_result(PGresult *oldres);
+void       reset_fetch(void);
+
+#define END_OF_TUPLES  (-1)