From ad869fcb88ac46d164cce0abc88a0b01cb7bcefc Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Mon, 11 Oct 1999 18:03:04 +0000 Subject: pgeasy update. --- src/interfaces/libpgeasy/Makefile.in | 89 ++++++++ src/interfaces/libpgeasy/README | 10 + src/interfaces/libpgeasy/examples/Makefile | 27 +++ src/interfaces/libpgeasy/examples/pginsert.c | 101 +++++++++ src/interfaces/libpgeasy/examples/pgnulltest.c | 142 ++++++++++++ src/interfaces/libpgeasy/examples/pgwordcount.c | 70 ++++++ src/interfaces/libpgeasy/halt.c | 60 +++++ src/interfaces/libpgeasy/halt.h | 6 + src/interfaces/libpgeasy/pgeasy.3 | 71 ++++++ src/interfaces/libpgeasy/pgeasy.c | 287 ++++++++++++++++++++++++ src/interfaces/libpgeasy/pgeasy.h | 18 ++ src/interfaces/pgeasy/Makefile.in | 89 -------- src/interfaces/pgeasy/README | 10 - src/interfaces/pgeasy/examples/Makefile | 27 --- src/interfaces/pgeasy/examples/pginsert.c | 101 --------- src/interfaces/pgeasy/examples/pgnulltest.c | 142 ------------ src/interfaces/pgeasy/examples/pgwordcount.c | 70 ------ src/interfaces/pgeasy/halt.c | 60 ----- src/interfaces/pgeasy/halt.h | 6 - src/interfaces/pgeasy/pgeasy.3 | 71 ------ src/interfaces/pgeasy/pgeasy.c | 287 ------------------------ src/interfaces/pgeasy/pgeasy.h | 18 -- 22 files changed, 881 insertions(+), 881 deletions(-) create mode 100644 src/interfaces/libpgeasy/Makefile.in create mode 100644 src/interfaces/libpgeasy/README create mode 100644 src/interfaces/libpgeasy/examples/Makefile create mode 100644 src/interfaces/libpgeasy/examples/pginsert.c create mode 100644 src/interfaces/libpgeasy/examples/pgnulltest.c create mode 100644 src/interfaces/libpgeasy/examples/pgwordcount.c create mode 100644 src/interfaces/libpgeasy/halt.c create mode 100644 src/interfaces/libpgeasy/halt.h create mode 100644 src/interfaces/libpgeasy/pgeasy.3 create mode 100644 src/interfaces/libpgeasy/pgeasy.c create mode 100644 src/interfaces/libpgeasy/pgeasy.h delete mode 100644 src/interfaces/pgeasy/Makefile.in delete mode 100644 src/interfaces/pgeasy/README delete mode 100644 src/interfaces/pgeasy/examples/Makefile delete mode 100644 src/interfaces/pgeasy/examples/pginsert.c delete mode 100644 src/interfaces/pgeasy/examples/pgnulltest.c delete mode 100644 src/interfaces/pgeasy/examples/pgwordcount.c delete mode 100644 src/interfaces/pgeasy/halt.c delete mode 100644 src/interfaces/pgeasy/halt.h delete mode 100644 src/interfaces/pgeasy/pgeasy.3 delete mode 100644 src/interfaces/pgeasy/pgeasy.c delete mode 100644 src/interfaces/pgeasy/pgeasy.h diff --git a/src/interfaces/libpgeasy/Makefile.in b/src/interfaces/libpgeasy/Makefile.in new file mode 100644 index 00000000000..4117a8eac9f --- /dev/null +++ b/src/interfaces/libpgeasy/Makefile.in @@ -0,0 +1,89 @@ +#------------------------------------------------------------------------- +# +# Makefile +# Makefile for pgeasy library +# +# IDENTIFICATION +# $Header: /cvsroot/pgsql/src/interfaces/libpgeasy/Attic/Makefile.in,v 1.1 1999/10/11 18:03:00 momjian Exp $ +# +#------------------------------------------------------------------------- + +NAME= pgeasy +SO_MAJOR_VERSION= 2 +SO_MINOR_VERSION= 0 + +SRCDIR= @top_srcdir@ +include $(SRCDIR)/Makefile.global + +ifdef KRBVERS +CFLAGS+= $(KRBFLAGS) +endif + +OBJS= pgeasy.o halt.o + +SHLIB_LINK+= -L../libpq -lpq + +SHLIB_LINK+= -L../libpq -lpq + +# If crypt is a separate library, rather than part of libc, it may need +# to be referenced separately to keep (broken) linkers happy. (This is +# braindead; users of libpq should not need to know what it depends on.) +SHLIB_LINK+= $(findstring -lcrypt,$(LIBS)) + +# Shared library stuff, also default 'all' target +include $(SRCDIR)/Makefile.shlib + + +.PHONY: install install-headers + +install: install-headers install-lib $(install-shlib-dep) + +install-headers: pgeasy.h + @if [ ! -d $(HEADERDIR) ]; then mkdir $(HEADERDIR); fi + $(INSTALL) $(INSTLOPTS) pgeasy.h $(HEADERDIR)/pgeasy.h + +.PHONY: clean + +clean: clean-shlib + rm -f lib$(NAME).a $(OBJS) + +depend dep: + $(CC) -MM $(CFLAGS) *.c >depend + +ifeq (depend,$(wildcard depend)) +include depend +endif + + + +PGEASY = pgeasy.o halt.o +TARGET = libpgeasy.a pginsert pgwordcount pgnulltest +CFLAGS = -g -Wall -I. -I../../src/interfaces/libpq -I/usr/local/pgsql/include +LDFLAGS = -L/usr/local/pgsql/lib -lpq + +all : $(TARGET) + +libpgeasy.a: pgeasy.o halt.o + ar r libpgeasy.a pgeasy.o halt.o + +pgeasy.o: pgeasy.c + gcc -c $(CFLAGS) pgeasy.c + +halt.o: halt.c + gcc -c $(CFLAGS) halt.c + +pginsert: $(PGEASY) pginsert.c + gcc -o $@ $(CFLAGS) $@.c $(PGEASY) $(LDFLAGS) + +pgwordcount: $(PGEASY) pgwordcount.c + gcc -o $@ $(CFLAGS) $@.c $(PGEASY) $(LDFLAGS) + +pgnulltest: $(PGEASY) pgnulltest.c + gcc -o $@ $(CFLAGS) $@.c $(PGEASY) $(LDFLAGS) + +clean: + rm -f *.o $(TARGET) log core + +install: + install -s -o bin -g bin $(TARGET) /usr/local/pgsql/bin + diff --git a/src/interfaces/libpgeasy/README b/src/interfaces/libpgeasy/README new file mode 100644 index 00000000000..b8e26d40a10 --- /dev/null +++ b/src/interfaces/libpgeasy/README @@ -0,0 +1,10 @@ + + + Pgeasy 2.0 + (Formerly contrib/pginterface) + +Attached is a copy of the Postgres support routines I wrote to allow me +to more cleanly interface to the libpg library, more like a 4gl SQL +interface. + +Bruce Momjian (root@candle.pha.pa.us) diff --git a/src/interfaces/libpgeasy/examples/Makefile b/src/interfaces/libpgeasy/examples/Makefile new file mode 100644 index 00000000000..db88f1b9ebc --- /dev/null +++ b/src/interfaces/libpgeasy/examples/Makefile @@ -0,0 +1,27 @@ +#------------------------------------------------------------------------- +# +# Makefile +# Makefile for pgeasy examples +# +# IDENTIFICATION +# $Header: /cvsroot/pgsql/src/interfaces/libpgeasy/examples/Attic/Makefile,v 1.1 1999/10/11 18:03:01 momjian Exp $ +# +#------------------------------------------------------------------------- + +TARGET = pginsert pgwordcount pgnulltest +LDFLAGS = -lpgeasy + +all : $(TARGET) + +pginsert: + gcc -o $@ $(CFLAGS) $@.c $(PGEASY) $(LDFLAGS) + +pgwordcount: + gcc -o $@ $(CFLAGS) $@.c $(PGEASY) $(LDFLAGS) + +pgnulltest: + gcc -o $@ $(CFLAGS) $@.c $(PGEASY) $(LDFLAGS) + +clean: + rm -f *.o $(TARGET) log core + diff --git a/src/interfaces/libpgeasy/examples/pginsert.c b/src/interfaces/libpgeasy/examples/pginsert.c new file mode 100644 index 00000000000..7cb2cf5b268 --- /dev/null +++ b/src/interfaces/libpgeasy/examples/pginsert.c @@ -0,0 +1,101 @@ +/* + * insert.c + * +*/ + +#include +#include +#include +#include "halt.h" +#include "pgeasy.h" + +int +main(int argc, char **argv) +{ + char query[4000]; + int row = 1; + int aint; + float afloat; + double adouble; + char achar[11], + achar16[17], + abpchar[11], + avarchar[51], + atext[51]; + time_t aabstime; + + if (argc != 2) + halt("Usage: %s database\n", argv[0]); + + connectdb(argv[1], NULL, NULL, NULL, NULL); + + on_error_continue(); + doquery("DROP TABLE testfetch"); + on_error_stop(); + + doquery("\ + CREATE TABLE testfetch( \ + aint int4, \ + afloat float4, \ + adouble float8, \ + achar char, \ + achar16 char16, \ + abpchar char(10), \ + avarchar varchar(50), \ + atext text, \ + aabstime abstime) \ + "); + + while (1) + { + sprintf(query, "INSERT INTO testfetch VALUES ( \ + %d, \ + 2322.12, \ + '923121.0323'::float8, \ + 'A', \ + 'Betty', \ + 'Charley', \ + 'Doug', \ + 'Ernie', \ + 'now' )", row); + doquery(query); + + doquery("BEGIN WORK"); + doquery("DECLARE c_testfetch BINARY CURSOR FOR \ + SELECT * FROM testfetch"); + + doquery("FETCH ALL IN c_testfetch"); + + while (fetch( + &aint, + &afloat, + &adouble, + achar, + achar16, + abpchar, + avarchar, + atext, + &aabstime) != END_OF_TUPLES) + printf("int %d\nfloat %f\ndouble %f\nchar %s\nchar16 %s\n\ +bpchar %s\nvarchar %s\ntext %s\nabstime %s", + aint, + afloat, + adouble, + achar, + achar16, + abpchar, + avarchar, + atext, + ctime(&aabstime)); + + + doquery("CLOSE c_testfetch"); + doquery("COMMIT WORK"); + printf("--- %-d rows inserted so far\n", row); + + row++; + } + + disconnectdb(); + return 0; +} diff --git a/src/interfaces/libpgeasy/examples/pgnulltest.c b/src/interfaces/libpgeasy/examples/pgnulltest.c new file mode 100644 index 00000000000..4651d77bac8 --- /dev/null +++ b/src/interfaces/libpgeasy/examples/pgnulltest.c @@ -0,0 +1,142 @@ +/* + * pgnulltest.c + * +*/ + +#define TEST_NON_NULLS + +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + char query[4000]; + int row = 1; + int aint; + float afloat; + double adouble; + char achar[11], + achar16[17], + abpchar[11], + avarchar[51], + atext[51]; + time_t aabstime; + int aint_null, + afloat_null, + adouble_null, + achar_null, + achar16_null, + abpchar_null, + avarchar_null, + atext_null, + aabstime_null; + + if (argc != 2) + halt("Usage: %s database\n", argv[0]); + + connectdb(argv[1], NULL, NULL, NULL, NULL); + + on_error_continue(); + doquery("DROP TABLE testfetch"); + on_error_stop(); + + doquery("\ + CREATE TABLE testfetch( \ + aint int4, \ + afloat float4, \ + adouble float8, \ + achar char, \ + achar16 char16, \ + abpchar char(10), \ + avarchar varchar(50), \ + atext text, \ + aabstime abstime) \ + "); + +#ifdef TEST_NON_NULLS + sprintf(query, "INSERT INTO testfetch VALUES ( \ + 0, \ + 0, \ + 0, \ + '', \ + '', \ + '', \ + '', \ + '', \ + '');"); +#else + sprintf(query, "INSERT INTO testfetch VALUES ( \ + NULL, \ + NULL, \ + NULL, \ + NULL, \ + NULL, \ + NULL, \ + NULL, \ + NULL, \ + NULL);"); +#endif + doquery(query); + + doquery("BEGIN WORK"); + doquery("DECLARE c_testfetch BINARY CURSOR FOR \ + SELECT * FROM testfetch"); + + doquery("FETCH ALL IN c_testfetch"); + + if (fetchwithnulls( + &aint, + &aint_null, + &afloat, + &afloat_null, + &adouble, + &adouble_null, + achar, + &achar_null, + achar16, + &achar16_null, + abpchar, + &abpchar_null, + avarchar, + &avarchar_null, + atext, + &atext_null, + &aabstime, + &aabstime_null) != END_OF_TUPLES) + printf("int %d\nfloat %f\ndouble %f\nchar %s\nchar16 %s\n\ +bpchar %s\nvarchar %s\ntext %s\nabstime %s\n", + aint, + afloat, + adouble, + achar, + achar16, + abpchar, + avarchar, + atext, + ctime(&aabstime)); + printf("NULL:\nint %d\nfloat %d\ndouble %d\nchar %d\nchar16 %d\n\ +bpchar %d\nvarchar %d\ntext %d\nabstime %d\n", + aint_null, + afloat_null, + adouble_null, + achar_null, + achar16_null, + abpchar_null, + avarchar_null, + atext_null, + aabstime_null); + + + doquery("CLOSE c_testfetch"); + doquery("COMMIT WORK"); + printf("--- %-d rows inserted so far\n", row); + + row++; + + disconnectdb(); + return 0; +} diff --git a/src/interfaces/libpgeasy/examples/pgwordcount.c b/src/interfaces/libpgeasy/examples/pgwordcount.c new file mode 100644 index 00000000000..4715f88f438 --- /dev/null +++ b/src/interfaces/libpgeasy/examples/pgwordcount.c @@ -0,0 +1,70 @@ +/* + * wordcount.c + * +*/ + +#include +#include "halt.h" +#include +#include "pgeasy.h" + +int +main(int argc, char **argv) +{ + char query[4000]; + int row = 0; + int count; + char line[4000]; + + if (argc != 2) + halt("Usage: %s database\n", argv[0]); + + connectdb(argv[1], NULL, NULL, NULL, NULL); + on_error_continue(); + doquery("DROP TABLE words"); + on_error_stop(); + + doquery("\ + CREATE TABLE words( \ + matches int4, \ + word text ) \ + "); + doquery("\ + CREATE INDEX i_words_1 ON words USING btree ( \ + word text_ops )\ + "); + + while (1) + { + if (scanf("%s", line) != 1) + break; + doquery("BEGIN WORK"); + sprintf(query, "\ + DECLARE c_words BINARY CURSOR FOR \ + SELECT count(*) \ + FROM words \ + WHERE word = '%s'", line); + doquery(query); + doquery("FETCH ALL IN c_words"); + + while (fetch(&count) == END_OF_TUPLES) + count = 0; + doquery("CLOSE c_words"); + doquery("COMMIT WORK"); + + if (count == 0) + sprintf(query, "\ + INSERT INTO words \ + VALUES (1, '%s')", line); + else + sprintf(query, "\ + UPDATE words \ + SET matches = matches + 1 \ + WHERE word = '%s'", line); + doquery(query); + row++; + } + + disconnectdb(); + return 0; +} diff --git a/src/interfaces/libpgeasy/halt.c b/src/interfaces/libpgeasy/halt.c new file mode 100644 index 00000000000..f56385898f8 --- /dev/null +++ b/src/interfaces/libpgeasy/halt.c @@ -0,0 +1,60 @@ +/* +** +** halt.c +** +** This is used to print out error messages and exit +*/ + +#include +#include +#include +#include +#include +#include + + +/*------------------------------------------------------------------------- +** +** halt - print error message, and call clean up routine or exit +** +**------------------------------------------------------------------------*/ + +/*VARARGS*/ +void +halt(va_alist) +va_dcl +{ + va_list arg_ptr; + char *format, + *pstr; + void (*sig_func) (); + + va_start(arg_ptr); + format = va_arg(arg_ptr, char *); + if (strncmp(format, "PERROR", 6) != 0) + vfprintf(stderr, format, arg_ptr); + else + { + for (pstr = format + 6; *pstr == ' ' || *pstr == ':'; pstr++) + ; + vfprintf(stderr, pstr, arg_ptr); + perror(""); + } + va_end(arg_ptr); + fflush(stderr); + + /* call one clean up function if defined */ + if ((sig_func = signal(SIGTERM, SIG_DFL)) !=SIG_DFL && + sig_func !=SIG_IGN) + (*sig_func) (0); + else if ((sig_func = signal(SIGHUP, SIG_DFL)) !=SIG_DFL && + sig_func !=SIG_IGN) + (*sig_func) (0); + else if ((sig_func = signal(SIGINT, SIG_DFL)) !=SIG_DFL && + sig_func !=SIG_IGN) + (*sig_func) (0); + else if ((sig_func = signal(SIGQUIT, SIG_DFL)) !=SIG_DFL && + sig_func !=SIG_IGN) + (*sig_func) (0); + exit(1); +} diff --git a/src/interfaces/libpgeasy/halt.h b/src/interfaces/libpgeasy/halt.h new file mode 100644 index 00000000000..8d83ede83a9 --- /dev/null +++ b/src/interfaces/libpgeasy/halt.h @@ -0,0 +1,6 @@ +/* +** halt.h +** +*/ + +void halt(); diff --git a/src/interfaces/libpgeasy/pgeasy.3 b/src/interfaces/libpgeasy/pgeasy.3 new file mode 100644 index 00000000000..34b6e9f1b66 --- /dev/null +++ b/src/interfaces/libpgeasy/pgeasy.3 @@ -0,0 +1,71 @@ +.\" This is -*-nroff-*- +.\" XXX standard disclaimer belongs here.... +.\" $Header: /cvsroot/pgsql/src/interfaces/libpgeasy/Attic/pgeasy.3,v 1.1 1999/10/11 18:03:00 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/pgeasy.c b/src/interfaces/libpgeasy/pgeasy.c new file mode 100644 index 00000000000..f3d6aae01e6 --- /dev/null +++ b/src/interfaces/libpgeasy/pgeasy.c @@ -0,0 +1,287 @@ +/* + * pgeasy.c + * +*/ + +#include +#include +#include + +#include +#include "halt.h" +#include "pgeasy.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/pgeasy.h b/src/interfaces/libpgeasy/pgeasy.h new file mode 100644 index 00000000000..11253acebc6 --- /dev/null +++ b/src/interfaces/libpgeasy/pgeasy.h @@ -0,0 +1,18 @@ +/* + * pglib.h + * +*/ + +PGresult *doquery(char *query); +PGconn *connectdb(); +void disconnectdb(); +int fetch(void *param,...); +int fetchwithnulls(void *param,...); +void on_error_continue(); +void on_error_stop(); +PGresult *get_result(); +void set_result(PGresult *newres); +void unset_result(PGresult *oldres); +void reset_fetch(); + +#define END_OF_TUPLES (-1) diff --git a/src/interfaces/pgeasy/Makefile.in b/src/interfaces/pgeasy/Makefile.in deleted file mode 100644 index f535e46e390..00000000000 --- a/src/interfaces/pgeasy/Makefile.in +++ /dev/null @@ -1,89 +0,0 @@ -#------------------------------------------------------------------------- -# -# Makefile -# Makefile for pgeasy library -# -# IDENTIFICATION -# $Header: /cvsroot/pgsql/src/interfaces/pgeasy/Attic/Makefile.in,v 1.1 1999/10/11 17:47:01 momjian Exp $ -# -#------------------------------------------------------------------------- - -NAME= pgeasy -SO_MAJOR_VERSION= 2 -SO_MINOR_VERSION= 0 - -SRCDIR= @top_srcdir@ -include $(SRCDIR)/Makefile.global - -ifdef KRBVERS -CFLAGS+= $(KRBFLAGS) -endif - -OBJS= pgeasy.o halt.o - -SHLIB_LINK+= -L../libpq -lpq - -SHLIB_LINK+= -L../libpq -lpq - -# If crypt is a separate library, rather than part of libc, it may need -# to be referenced separately to keep (broken) linkers happy. (This is -# braindead; users of libpq should not need to know what it depends on.) -SHLIB_LINK+= $(findstring -lcrypt,$(LIBS)) - -# Shared library stuff, also default 'all' target -include $(SRCDIR)/Makefile.shlib - - -.PHONY: install install-headers - -install: install-headers install-lib $(install-shlib-dep) - -install-headers: pgeasy.h - @if [ ! -d $(HEADERDIR) ]; then mkdir $(HEADERDIR); fi - $(INSTALL) $(INSTLOPTS) pgeasy.h $(HEADERDIR)/pgeasy.h - -.PHONY: clean - -clean: clean-shlib - rm -f lib$(NAME).a $(OBJS) - -depend dep: - $(CC) -MM $(CFLAGS) *.c >depend - -ifeq (depend,$(wildcard depend)) -include depend -endif - - - -PGEASY = pgeasy.o halt.o -TARGET = libpgeasy.a pginsert pgwordcount pgnulltest -CFLAGS = -g -Wall -I. -I../../src/interfaces/libpq -I/usr/local/pgsql/include -LDFLAGS = -L/usr/local/pgsql/lib -lpq - -all : $(TARGET) - -libpgeasy.a: pgeasy.o halt.o - ar r libpgeasy.a pgeasy.o halt.o - -pgeasy.o: pgeasy.c - gcc -c $(CFLAGS) pgeasy.c - -halt.o: halt.c - gcc -c $(CFLAGS) halt.c - -pginsert: $(PGEASY) pginsert.c - gcc -o $@ $(CFLAGS) $@.c $(PGEASY) $(LDFLAGS) - -pgwordcount: $(PGEASY) pgwordcount.c - gcc -o $@ $(CFLAGS) $@.c $(PGEASY) $(LDFLAGS) - -pgnulltest: $(PGEASY) pgnulltest.c - gcc -o $@ $(CFLAGS) $@.c $(PGEASY) $(LDFLAGS) - -clean: - rm -f *.o $(TARGET) log core - -install: - install -s -o bin -g bin $(TARGET) /usr/local/pgsql/bin - diff --git a/src/interfaces/pgeasy/README b/src/interfaces/pgeasy/README deleted file mode 100644 index b8e26d40a10..00000000000 --- a/src/interfaces/pgeasy/README +++ /dev/null @@ -1,10 +0,0 @@ - - - Pgeasy 2.0 - (Formerly contrib/pginterface) - -Attached is a copy of the Postgres support routines I wrote to allow me -to more cleanly interface to the libpg library, more like a 4gl SQL -interface. - -Bruce Momjian (root@candle.pha.pa.us) diff --git a/src/interfaces/pgeasy/examples/Makefile b/src/interfaces/pgeasy/examples/Makefile deleted file mode 100644 index fd13c1eb066..00000000000 --- a/src/interfaces/pgeasy/examples/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -#------------------------------------------------------------------------- -# -# Makefile -# Makefile for pgeasy examples -# -# IDENTIFICATION -# $Header: /cvsroot/pgsql/src/interfaces/pgeasy/examples/Attic/Makefile,v 1.1 1999/10/11 17:47:02 momjian Exp $ -# -#------------------------------------------------------------------------- - -TARGET = pginsert pgwordcount pgnulltest -LDFLAGS = -lpgeasy - -all : $(TARGET) - -pginsert: - gcc -o $@ $(CFLAGS) $@.c $(PGEASY) $(LDFLAGS) - -pgwordcount: - gcc -o $@ $(CFLAGS) $@.c $(PGEASY) $(LDFLAGS) - -pgnulltest: - gcc -o $@ $(CFLAGS) $@.c $(PGEASY) $(LDFLAGS) - -clean: - rm -f *.o $(TARGET) log core - diff --git a/src/interfaces/pgeasy/examples/pginsert.c b/src/interfaces/pgeasy/examples/pginsert.c deleted file mode 100644 index 7cb2cf5b268..00000000000 --- a/src/interfaces/pgeasy/examples/pginsert.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * insert.c - * -*/ - -#include -#include -#include -#include "halt.h" -#include "pgeasy.h" - -int -main(int argc, char **argv) -{ - char query[4000]; - int row = 1; - int aint; - float afloat; - double adouble; - char achar[11], - achar16[17], - abpchar[11], - avarchar[51], - atext[51]; - time_t aabstime; - - if (argc != 2) - halt("Usage: %s database\n", argv[0]); - - connectdb(argv[1], NULL, NULL, NULL, NULL); - - on_error_continue(); - doquery("DROP TABLE testfetch"); - on_error_stop(); - - doquery("\ - CREATE TABLE testfetch( \ - aint int4, \ - afloat float4, \ - adouble float8, \ - achar char, \ - achar16 char16, \ - abpchar char(10), \ - avarchar varchar(50), \ - atext text, \ - aabstime abstime) \ - "); - - while (1) - { - sprintf(query, "INSERT INTO testfetch VALUES ( \ - %d, \ - 2322.12, \ - '923121.0323'::float8, \ - 'A', \ - 'Betty', \ - 'Charley', \ - 'Doug', \ - 'Ernie', \ - 'now' )", row); - doquery(query); - - doquery("BEGIN WORK"); - doquery("DECLARE c_testfetch BINARY CURSOR FOR \ - SELECT * FROM testfetch"); - - doquery("FETCH ALL IN c_testfetch"); - - while (fetch( - &aint, - &afloat, - &adouble, - achar, - achar16, - abpchar, - avarchar, - atext, - &aabstime) != END_OF_TUPLES) - printf("int %d\nfloat %f\ndouble %f\nchar %s\nchar16 %s\n\ -bpchar %s\nvarchar %s\ntext %s\nabstime %s", - aint, - afloat, - adouble, - achar, - achar16, - abpchar, - avarchar, - atext, - ctime(&aabstime)); - - - doquery("CLOSE c_testfetch"); - doquery("COMMIT WORK"); - printf("--- %-d rows inserted so far\n", row); - - row++; - } - - disconnectdb(); - return 0; -} diff --git a/src/interfaces/pgeasy/examples/pgnulltest.c b/src/interfaces/pgeasy/examples/pgnulltest.c deleted file mode 100644 index 4651d77bac8..00000000000 --- a/src/interfaces/pgeasy/examples/pgnulltest.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * pgnulltest.c - * -*/ - -#define TEST_NON_NULLS - -#include -#include -#include -#include -#include - -int -main(int argc, char **argv) -{ - char query[4000]; - int row = 1; - int aint; - float afloat; - double adouble; - char achar[11], - achar16[17], - abpchar[11], - avarchar[51], - atext[51]; - time_t aabstime; - int aint_null, - afloat_null, - adouble_null, - achar_null, - achar16_null, - abpchar_null, - avarchar_null, - atext_null, - aabstime_null; - - if (argc != 2) - halt("Usage: %s database\n", argv[0]); - - connectdb(argv[1], NULL, NULL, NULL, NULL); - - on_error_continue(); - doquery("DROP TABLE testfetch"); - on_error_stop(); - - doquery("\ - CREATE TABLE testfetch( \ - aint int4, \ - afloat float4, \ - adouble float8, \ - achar char, \ - achar16 char16, \ - abpchar char(10), \ - avarchar varchar(50), \ - atext text, \ - aabstime abstime) \ - "); - -#ifdef TEST_NON_NULLS - sprintf(query, "INSERT INTO testfetch VALUES ( \ - 0, \ - 0, \ - 0, \ - '', \ - '', \ - '', \ - '', \ - '', \ - '');"); -#else - sprintf(query, "INSERT INTO testfetch VALUES ( \ - NULL, \ - NULL, \ - NULL, \ - NULL, \ - NULL, \ - NULL, \ - NULL, \ - NULL, \ - NULL);"); -#endif - doquery(query); - - doquery("BEGIN WORK"); - doquery("DECLARE c_testfetch BINARY CURSOR FOR \ - SELECT * FROM testfetch"); - - doquery("FETCH ALL IN c_testfetch"); - - if (fetchwithnulls( - &aint, - &aint_null, - &afloat, - &afloat_null, - &adouble, - &adouble_null, - achar, - &achar_null, - achar16, - &achar16_null, - abpchar, - &abpchar_null, - avarchar, - &avarchar_null, - atext, - &atext_null, - &aabstime, - &aabstime_null) != END_OF_TUPLES) - printf("int %d\nfloat %f\ndouble %f\nchar %s\nchar16 %s\n\ -bpchar %s\nvarchar %s\ntext %s\nabstime %s\n", - aint, - afloat, - adouble, - achar, - achar16, - abpchar, - avarchar, - atext, - ctime(&aabstime)); - printf("NULL:\nint %d\nfloat %d\ndouble %d\nchar %d\nchar16 %d\n\ -bpchar %d\nvarchar %d\ntext %d\nabstime %d\n", - aint_null, - afloat_null, - adouble_null, - achar_null, - achar16_null, - abpchar_null, - avarchar_null, - atext_null, - aabstime_null); - - - doquery("CLOSE c_testfetch"); - doquery("COMMIT WORK"); - printf("--- %-d rows inserted so far\n", row); - - row++; - - disconnectdb(); - return 0; -} diff --git a/src/interfaces/pgeasy/examples/pgwordcount.c b/src/interfaces/pgeasy/examples/pgwordcount.c deleted file mode 100644 index 4715f88f438..00000000000 --- a/src/interfaces/pgeasy/examples/pgwordcount.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * wordcount.c - * -*/ - -#include -#include "halt.h" -#include -#include "pgeasy.h" - -int -main(int argc, char **argv) -{ - char query[4000]; - int row = 0; - int count; - char line[4000]; - - if (argc != 2) - halt("Usage: %s database\n", argv[0]); - - connectdb(argv[1], NULL, NULL, NULL, NULL); - on_error_continue(); - doquery("DROP TABLE words"); - on_error_stop(); - - doquery("\ - CREATE TABLE words( \ - matches int4, \ - word text ) \ - "); - doquery("\ - CREATE INDEX i_words_1 ON words USING btree ( \ - word text_ops )\ - "); - - while (1) - { - if (scanf("%s", line) != 1) - break; - doquery("BEGIN WORK"); - sprintf(query, "\ - DECLARE c_words BINARY CURSOR FOR \ - SELECT count(*) \ - FROM words \ - WHERE word = '%s'", line); - doquery(query); - doquery("FETCH ALL IN c_words"); - - while (fetch(&count) == END_OF_TUPLES) - count = 0; - doquery("CLOSE c_words"); - doquery("COMMIT WORK"); - - if (count == 0) - sprintf(query, "\ - INSERT INTO words \ - VALUES (1, '%s')", line); - else - sprintf(query, "\ - UPDATE words \ - SET matches = matches + 1 \ - WHERE word = '%s'", line); - doquery(query); - row++; - } - - disconnectdb(); - return 0; -} diff --git a/src/interfaces/pgeasy/halt.c b/src/interfaces/pgeasy/halt.c deleted file mode 100644 index f56385898f8..00000000000 --- a/src/interfaces/pgeasy/halt.c +++ /dev/null @@ -1,60 +0,0 @@ -/* -** -** halt.c -** -** This is used to print out error messages and exit -*/ - -#include -#include -#include -#include -#include -#include - - -/*------------------------------------------------------------------------- -** -** halt - print error message, and call clean up routine or exit -** -**------------------------------------------------------------------------*/ - -/*VARARGS*/ -void -halt(va_alist) -va_dcl -{ - va_list arg_ptr; - char *format, - *pstr; - void (*sig_func) (); - - va_start(arg_ptr); - format = va_arg(arg_ptr, char *); - if (strncmp(format, "PERROR", 6) != 0) - vfprintf(stderr, format, arg_ptr); - else - { - for (pstr = format + 6; *pstr == ' ' || *pstr == ':'; pstr++) - ; - vfprintf(stderr, pstr, arg_ptr); - perror(""); - } - va_end(arg_ptr); - fflush(stderr); - - /* call one clean up function if defined */ - if ((sig_func = signal(SIGTERM, SIG_DFL)) !=SIG_DFL && - sig_func !=SIG_IGN) - (*sig_func) (0); - else if ((sig_func = signal(SIGHUP, SIG_DFL)) !=SIG_DFL && - sig_func !=SIG_IGN) - (*sig_func) (0); - else if ((sig_func = signal(SIGINT, SIG_DFL)) !=SIG_DFL && - sig_func !=SIG_IGN) - (*sig_func) (0); - else if ((sig_func = signal(SIGQUIT, SIG_DFL)) !=SIG_DFL && - sig_func !=SIG_IGN) - (*sig_func) (0); - exit(1); -} diff --git a/src/interfaces/pgeasy/halt.h b/src/interfaces/pgeasy/halt.h deleted file mode 100644 index 8d83ede83a9..00000000000 --- a/src/interfaces/pgeasy/halt.h +++ /dev/null @@ -1,6 +0,0 @@ -/* -** halt.h -** -*/ - -void halt(); diff --git a/src/interfaces/pgeasy/pgeasy.3 b/src/interfaces/pgeasy/pgeasy.3 deleted file mode 100644 index a24bc041105..00000000000 --- a/src/interfaces/pgeasy/pgeasy.3 +++ /dev/null @@ -1,71 +0,0 @@ -.\" This is -*-nroff-*- -.\" XXX standard disclaimer belongs here.... -.\" $Header: /cvsroot/pgsql/src/interfaces/pgeasy/Attic/pgeasy.3,v 1.1 1999/10/11 17:47:01 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/pgeasy/pgeasy.c b/src/interfaces/pgeasy/pgeasy.c deleted file mode 100644 index f3d6aae01e6..00000000000 --- a/src/interfaces/pgeasy/pgeasy.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * pgeasy.c - * -*/ - -#include -#include -#include - -#include -#include "halt.h" -#include "pgeasy.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/pgeasy/pgeasy.h b/src/interfaces/pgeasy/pgeasy.h deleted file mode 100644 index 11253acebc6..00000000000 --- a/src/interfaces/pgeasy/pgeasy.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * pglib.h - * -*/ - -PGresult *doquery(char *query); -PGconn *connectdb(); -void disconnectdb(); -int fetch(void *param,...); -int fetchwithnulls(void *param,...); -void on_error_continue(); -void on_error_stop(); -PGresult *get_result(); -void set_result(PGresult *newres); -void unset_result(PGresult *oldres); -void reset_fetch(); - -#define END_OF_TUPLES (-1) -- cgit v1.2.3