diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/configure.in | 1 | ||||
-rw-r--r-- | src/interfaces/Makefile | 3 | ||||
-rw-r--r-- | src/interfaces/libpgtcl/Makefile.in | 4 | ||||
-rw-r--r-- | src/interfaces/libpq/Makefile.in | 4 | ||||
-rw-r--r-- | src/interfaces/pgeasy/Makefile.in | 89 | ||||
-rw-r--r-- | src/interfaces/pgeasy/README | 10 | ||||
-rw-r--r-- | src/interfaces/pgeasy/examples/Makefile | 27 | ||||
-rw-r--r-- | src/interfaces/pgeasy/examples/pginsert.c | 101 | ||||
-rw-r--r-- | src/interfaces/pgeasy/examples/pgnulltest.c | 142 | ||||
-rw-r--r-- | src/interfaces/pgeasy/examples/pgwordcount.c | 70 | ||||
-rw-r--r-- | src/interfaces/pgeasy/halt.c | 60 | ||||
-rw-r--r-- | src/interfaces/pgeasy/halt.h | 6 | ||||
-rw-r--r-- | src/interfaces/pgeasy/pgeasy.3 | 71 | ||||
-rw-r--r-- | src/interfaces/pgeasy/pgeasy.c | 287 | ||||
-rw-r--r-- | src/interfaces/pgeasy/pgeasy.h | 18 |
15 files changed, 888 insertions, 5 deletions
diff --git a/src/configure.in b/src/configure.in index a02a46778f6..115096f724f 100644 --- a/src/configure.in +++ b/src/configure.in @@ -1220,6 +1220,7 @@ AC_OUTPUT( interfaces/libpq/Makefile interfaces/ecpg/lib/Makefile interfaces/libpq++/Makefile + interfaces/libpgeasy/Makefile interfaces/libpgtcl/Makefile interfaces/odbc/GNUmakefile interfaces/odbc/Makefile.global diff --git a/src/interfaces/Makefile b/src/interfaces/Makefile index 632ae7832d1..ae54cd29d03 100644 --- a/src/interfaces/Makefile +++ b/src/interfaces/Makefile @@ -7,7 +7,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/interfaces/Makefile,v 1.27 1999/10/08 04:28:57 momjian Exp $ +# $Header: /cvsroot/pgsql/src/interfaces/Makefile,v 1.28 1999/10/11 17:46:58 momjian Exp $ # #------------------------------------------------------------------------- @@ -44,6 +44,7 @@ endif ifeq ($(USE_ODBC), true) $(MAKE) -C odbc $@ endif + $(MAKE) -C pgeasy$@ perl5/Makefile: perl5/Makefile.PL cd perl5 && $(PERL) Makefile.PL diff --git a/src/interfaces/libpgtcl/Makefile.in b/src/interfaces/libpgtcl/Makefile.in index 1912c1198ca..7e351603802 100644 --- a/src/interfaces/libpgtcl/Makefile.in +++ b/src/interfaces/libpgtcl/Makefile.in @@ -6,7 +6,7 @@ # Copyright (c) 1994, Regents of the University of California # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/Makefile.in,v 1.35 1999/06/30 23:57:24 tgl Exp $ +# $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/Makefile.in,v 1.36 1999/10/11 17:46:59 momjian Exp $ # #------------------------------------------------------------------------- @@ -52,7 +52,7 @@ beforeinstall-headers: .PHONY: clean clean: clean-shlib - rm -f $(OBJS) lib$(NAME).a + rm -f lib$(NAME).a $(OBJS) depend dep: $(CC) -MM $(CFLAGS) *.c >depend diff --git a/src/interfaces/libpq/Makefile.in b/src/interfaces/libpq/Makefile.in index ec955dcd4bc..e67ee1d2caa 100644 --- a/src/interfaces/libpq/Makefile.in +++ b/src/interfaces/libpq/Makefile.in @@ -6,7 +6,7 @@ # Copyright (c) 1994, Regents of the University of California # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/interfaces/libpq/Attic/Makefile.in,v 1.47 1999/08/31 01:37:36 tgl Exp $ +# $Header: /cvsroot/pgsql/src/interfaces/libpq/Attic/Makefile.in,v 1.48 1999/10/11 17:47:01 momjian Exp $ # #------------------------------------------------------------------------- @@ -86,7 +86,7 @@ install-headers: libpq-fe.h libpq-int.h .PHONY: clean clean: clean-shlib - rm -f libpq.a $(OBJS) + rm -f lib$(NAME).a $(OBJS) rm -f dllist.c common.c wchar.c conv.c big5.c ifeq ($(PORTNAME), win) rm -f pq.def diff --git a/src/interfaces/pgeasy/Makefile.in b/src/interfaces/pgeasy/Makefile.in new file mode 100644 index 00000000000..f535e46e390 --- /dev/null +++ b/src/interfaces/pgeasy/Makefile.in @@ -0,0 +1,89 @@ +#------------------------------------------------------------------------- +# +# 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 new file mode 100644 index 00000000000..b8e26d40a10 --- /dev/null +++ b/src/interfaces/pgeasy/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/pgeasy/examples/Makefile b/src/interfaces/pgeasy/examples/Makefile new file mode 100644 index 00000000000..fd13c1eb066 --- /dev/null +++ b/src/interfaces/pgeasy/examples/Makefile @@ -0,0 +1,27 @@ +#------------------------------------------------------------------------- +# +# 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 new file mode 100644 index 00000000000..7cb2cf5b268 --- /dev/null +++ b/src/interfaces/pgeasy/examples/pginsert.c @@ -0,0 +1,101 @@ +/* + * insert.c + * +*/ + +#include <stdio.h> +#include <time.h> +#include <libpq-fe.h> +#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 new file mode 100644 index 00000000000..4651d77bac8 --- /dev/null +++ b/src/interfaces/pgeasy/examples/pgnulltest.c @@ -0,0 +1,142 @@ +/* + * pgnulltest.c + * +*/ + +#define TEST_NON_NULLS + +#include <stdio.h> +#include <time.h> +#include <halt.h> +#include <libpq-fe.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; + 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 new file mode 100644 index 00000000000..4715f88f438 --- /dev/null +++ b/src/interfaces/pgeasy/examples/pgwordcount.c @@ -0,0 +1,70 @@ +/* + * wordcount.c + * +*/ + +#include <stdio.h> +#include "halt.h" +#include <libpq-fe.h> +#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 new file mode 100644 index 00000000000..f56385898f8 --- /dev/null +++ b/src/interfaces/pgeasy/halt.c @@ -0,0 +1,60 @@ +/* +** +** halt.c +** +** This is used to print out error messages and exit +*/ + +#include <varargs.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + + +/*------------------------------------------------------------------------- +** +** 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 new file mode 100644 index 00000000000..8d83ede83a9 --- /dev/null +++ b/src/interfaces/pgeasy/halt.h @@ -0,0 +1,6 @@ +/* +** halt.h +** +*/ + +void halt(); diff --git a/src/interfaces/pgeasy/pgeasy.3 b/src/interfaces/pgeasy/pgeasy.3 new file mode 100644 index 00000000000..a24bc041105 --- /dev/null +++ b/src/interfaces/pgeasy/pgeasy.3 @@ -0,0 +1,71 @@ +.\" 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 new file mode 100644 index 00000000000..f3d6aae01e6 --- /dev/null +++ b/src/interfaces/pgeasy/pgeasy.c @@ -0,0 +1,287 @@ +/* + * pgeasy.c + * +*/ + +#include <stdio.h> +#include <string.h> +#include <stdarg.h> + +#include <libpq-fe.h> +#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 new file mode 100644 index 00000000000..11253acebc6 --- /dev/null +++ b/src/interfaces/pgeasy/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) |