#
#
# IDENTIFICATION
-# $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/Makefile,v 1.5 1996/11/18 01:43:54 bryanh Exp $
+# $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/Makefile,v 1.6 1997/02/13 10:00:23 scrappy Exp $
#
#-------------------------------------------------------------------------
SRCDIR= ..
include ../Makefile.global
+SRCHEADERDIR = ../include
+LIBPQHEADERDIR = $(SRCHEADERDIR)/libpq
+
+LIBNAME= libpq++
# We have to override -Werror, which makes warnings, fatal, because we
# inevitably get the warning, "abstract declarator used as declaration"
INCLUDE_OPT= \
-I../backend \
- -I../include \
- -I$(LIBPQDIR)
+ -I$(SRCHEADERDIR) \
+ -I$(LIBPQDIR)
CXXFLAGS+= $(INCLUDE_OPT)
+#CXXFLAGS+= -DDEBUG
ifdef KRBVERS
CXXFLAGS+= $(KRBFLAGS)
endif
-OBJS= pgenv.o pgconnection.o pglobject.o
-all: libpq++.a examples
+OBJS = pgenv.o pgconnection.o pgtransdb.o pgcursordb.o pglobject.o
+
+all: $(LIBNAME).a install examples
-libpq++.a: $(OBJS)
+$(LIBNAME).a: $(OBJS)
ifdef MK_NO_LORDER
- $(AR) $(AROPT) libpq++.a $(OBJS)
+ $(AR) $(AROPT) $(LIBNAME).a $(OBJS)
else
- $(AR) $(AROPT) libpq++.a `lorder $(OBJS) | tsort`
+ $(AR) $(AROPT) $(LIBNAME).a `lorder $(OBJS) | tsort`
endif
- $(RANLIB) libpq++.a
+ $(RANLIB) $(LIBNAME).a
.PHONY: examples
examples:
$(MAKE) -C examples all
.PHONY: beforeinstall-headers install-headers
-.PHONY: install install-libpq++ doc
-
-install: install-headers install-libpq++ doc
-
-install-headers: beforeinstall-headers libpq++.H
- $(INSTALL) $(INSTLOPTS) libpq++.H $(HEADERDIR)/libpq++.H
+.PHONY: install install-$(LIBNAME) doc
+
+install: install-headers install-$(LIBNAME) doc
+
+LIBPGXXDIR = $(LIBNAME)
+LIBPGXXHEADERDIR = $(HEADERDIR)/$(LIBPGXXDIR)
+MAINHEADER = $(LIBNAME).h
+LIBPGXXHEADERS = pgenv.h \
+ pgconnection.h \
+ pgdatabase.h \
+ pgtransdb.h \
+ pgcursordb.h \
+ pglobject.h
+
+install-headers: beforeinstall-headers $(MAINHEADER)
+ @$(INSTALL) $(INSTLOPTS) $(MAINHEADER) $(HEADERDIR)/$(MAINHEADER)
+ @for i in ${LIBPGXXHEADERS}; do \
+ echo "Installing $(LIBPGXXHEADERDIR)/$$i."; \
+ $(INSTALL) $(INSTLOPTS) $$i $(LIBPGXXHEADERDIR)/$$i; \
+ done
beforeinstall-headers:
@if [ ! -d $(HEADERDIR) ]; then mkdir $(HEADERDIR); fi
+ @if [ ! -d $(LIBPGXXHEADERDIR) ]; then mkdir $(LIBPGXXHEADERDIR); fi
-install-libpq++: libpq++.a
- $(INSTALL) $(INSTL_LIB_OPTS) libpq++.a $(DESTDIR)$(LIBDIR)/libpq++.a
+install-$(LIBNAME): $(LIBNAME).a
+ $(INSTALL) $(INSTL_LIB_OPTS) $(LIBNAME).a $(DESTDIR)$(LIBDIR)/$(LIBNAME).a
doc:
$(MAKE) -C man install
clean:
- rm libpq++.a $(OBJS)
+ rm $(LIBNAME).a $(OBJS)
$(MAKE) -C examples clean
+
+
+###########################################################################
+# Dependencies for the library
+###########################################################################
+include ./dependencies
+
--- /dev/null
+###########################################################################
+# Dependencies for libpq++ C++ library for Postgres SQL
+#
+# Author: Leo Shuster (lsh@lubrizol.com)
+###########################################################################
+pgenv.o :: pgenv.cc \
+ pgenv.h
+
+pgconnection.o :: pgconnection.cc \
+ pgconnection.h \
+ pgenv.h \
+ $(LIBPQDIR)/libpq-fe.h \
+ $(LIBPQDIR)/fe-auth.h
+
+pgtransdb.o :: pgtransdb.cc \
+ pgtransdb.h \
+ pgdatabase.h \
+ pgconnection.h \
+ pgenv.h \
+ $(LIBPQDIR)/libpq-fe.h \
+ $(LIBPQDIR)/fe-auth.h
+
+pgcursordb.o :: pgcursordb.cc \
+ pgcursordb.h \
+ pgdatabase.h \
+ pgconnection.h \
+ pgenv.h \
+ $(LIBPQDIR)/libpq-fe.h \
+ $(LIBPQDIR)/fe-auth.h
+
+pglobject.o :: pglobject.cc \
+ pglobject.h \
+ pgconnection.h \
+ pgenv.h \
+ $(LIBPQDIR)/libpq-fe.h \
+ $(LIBPQHEADERDIR)/libpq-fs.h
SRCDIR= ../..
include ../../Makefile.global
+LIBNAME= libpq++
+
# We have to override -Werror, which makes warnings, fatal, because we
# inevitably get the warning, "abstract declarator used as declaration"
# because of our inclusion of c.h and we don't know how to stop that.
-I.. \
-I../../backend \
-I../../include \
- -I$(LIBPQDIR)
-
+ -I$(LIBPQDIR) \
+ -I$(HEADERDIR)
CXXFLAGS+= $(INCLUDE_OPT)
LD_ADD+= -L.. -lpq++ -L$(LIBPQDIR) -lpq
CXXFLAGS+= $(KRBFLAGS)
endif
-PROGS= testlibpq0 testlibpq1 testlibpq2 testlibpq3 testlibpq4 testlo
+PROGS= testlibpq0 testlibpq1 testlibpq2 testlibpq3 \
+ testlibpq4 testlibpq5 testlibpq6 testlo
all: submake $(PROGS)
-$(PROGS): % : %.cc ../libpq++.a
+$(PROGS): % : %.cc ../$(LIBNAME).a
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $@.cc $(LD_ADD)
.PHONY: submake
submake:
- $(MAKE) -C.. libpq++.a
+ $(MAKE) -C.. $(LIBNAME).a
-../libpq++.a:
- $(MAKE) -C.. libpq++.a
+../$(LIBNAME).a:
+ $(MAKE) -C.. $(LIBNAME).a
clean:
rm -f $(PROGS)
+
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq++/examples/Attic/testlibpq0.cc,v 1.2 1996/11/18 01:44:23 bryanh Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq++/examples/Attic/testlibpq0.cc,v 1.3 1997/02/13 10:00:42 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
-#include <stdio.h>
-#include "libpq++.H"
+#include <iostream.h>
+#include <libpq++.h>
-int
-main()
+int main()
{
+ // Open the connection to the database and make sure it's OK
+ PgDatabase data("template1");
+ if ( data.ConnectionBad() ) {
+ cout << "Connection was unsuccessful..." << endl
+ << "Error message returned: " << data.ErrorMessage() << endl;
+ return 1;
+ }
+ else
+ cout << "Connection successful... Enter queries below:" << endl;
+
+ // Interactively obtain and execute queries
ExecStatusType status;
- PGenv env;
- PGdatabase* data;
-
- char buf[10000];
+ string buf;
int done = 0;
-
- data = new PGdatabase(&env, "template1");
-
- if (data->status() == CONNECTION_BAD)
- printf("connection was unsuccessful\n%s\n", data->errormessage());
- else
- printf("connection successful\n");
-
while (!done)
{
- printf("> ");fflush(stdout);
- if (gets(buf) && buf[0]!='\0')
- if((status = data->exec(buf)) == PGRES_TUPLES_OK)
- data->printtuples(stdout, 1, "|", 1, 0);
- else
- printf("status = %d\nerrorMessage = %s\n", status,
- data->errormessage());
+ cout << "> ";
+ cout.flush();
+ getline(cin, buf);
+ if ( buf != "" )
+ if ( (status = data.Exec( buf.c_str() )) == PGRES_TUPLES_OK )
+ data.DisplayTuples();
+ else
+ cout << "No tuples returned..." << endl
+ << "status = " << status << endl
+ << "Error returned: " << data.ErrorMessage() << endl;
else
- done = 1;
- }
-}
+ done = 1;
+ }
+ return 0;
+} // End main()
/*
- * testlibpq.cc
+ * testlibpq1.cc
* Test the C++ version of LIBPQ, the POSTGRES frontend library.
*
* queries the template1 database for a list of database names
*
*/
-#include <stdio.h>
-#include "libpq++.H"
-main()
-{
- char* dbName;
- int nFields;
- int i,j;
-
- /* begin, by creating the parameter environtment for a backend
- connection. When no parameters are given then the system will
- try to use reasonable defaults by looking up environment variables
- or, failing that, using hardwired constants */
- PGenv env;
- PGdatabase* data;
+#include <iostream.h>
+#include <iomanip.h>
+#include <libpq++.h>
- /* Select a database */
- dbName = "template1";
-
- /* make a connection to the database */
- data = new PGdatabase(&env, dbName);
+int main()
+{
+ // Begin, by establishing a connection to the backend.
+ // When no parameters are given then the system will
+ // try to use reasonable defaults by looking up environment variables
+ // or, failing that, using hardwired constants
+ const char* dbName = "template1";
+ PgDatabase data(dbName);
- /* check to see that the backend connection was successfully made */
- if (data->status() == CONNECTION_BAD) {
- fprintf(stderr,"Connection to database '%s' failed.\n", dbName);
- fprintf(stderr,"%s",data->errormessage());
- delete data;
- exit(1);
+ // check to see that the backend connection was successfully made
+ if ( data.ConnectionBad() ) {
+ cerr << "Connection to database '" << dbName << "' failed." << endl
+ << "Error returned: " << data.ErrorMessage() << endl;
+ exit(1);
}
- /* start a transaction block */
- if(data->exec("BEGIN") != PGRES_COMMAND_OK) {
- fprintf(stderr,"BEGIN command failed\n");
- delete data;
+ // start a transaction block
+ if ( !data.ExecCommandOk("BEGIN") ) {
+ cerr << "BEGIN command failed" << endl;
exit(1);
}
- /* fetch instances from the pg_database, the system catalog of databases*/
- if (data->exec("DECLARE myportal CURSOR FOR select * from pg_database")
- != PGRES_COMMAND_OK) {
- fprintf(stderr,"DECLARE CURSOR command failed\n");
- delete data;
+ // submit command to the backend
+ if ( !data.ExecCommandOk("DECLARE myportal CURSOR FOR select * from pg_database") ) {
+ cerr << "DECLARE CURSOR command failed" << endl;
exit(1);
}
- if(data->exec("FETCH ALL in myportal") != PGRES_TUPLES_OK) {
- fprintf(stderr,"FETCH ALL command didn't return tuples properly\n");
- delete data;
+ // fetch instances from the pg_database, the system catalog of databases
+ if ( !data.ExecTuplesOk("FETCH ALL in myportal") ) {
+ cerr << "FETCH ALL command didn't return tuples properly" << endl;
exit(1);
}
- /* first, print out the attribute names */
- nFields = data->nfields();
- for (i=0; i < nFields; i++) {
- printf("%-15s",data->fieldname(i));
- }
- printf("\n\n");
+ // first, print out the attribute names
+ int nFields = data.Fields();
+ for (int i=0; i < nFields; i++)
+ cout << setiosflags(ios::right) << setw(15) << data.FieldName(i);
+ cout << endl << endl;
- /* next, print out the instances */
- for (i=0; i < data->ntuples(); i++) {
- for (j=0 ; j < nFields; j++) {
- printf("%-15s", data->getvalue(i,j));
- }
- printf("\n");
+ // next, print out the instances
+ for (int i=0; i < data.Tuples(); i++) {
+ for (int j=0; j < nFields; j++)
+ cout << setiosflags(ios::right) << setw(15) << data.GetValue(i,j);
+ cout << endl;
}
- /* close the portal */
- data->exec("CLOSE myportal");
-
- /* end the transaction */
- data->exec("END");
+ // Close the portal
+ data.Exec("CLOSE myportal");
- /* close the connection to the database and cleanup */
- delete data;
+ // End the transaction
+ data.Exec("END");
}
/*
* testlibpq2.cc
- * Test of the asynchronous notification interface
- *
- populate a database with the following:
-
-CREATE TABLE TBL1 (i int4);
-
-CREATE TABLE TBL2 (i int4);
-
-CREATE RULE r1 AS ON INSERT TO TBL1 DO [INSERT INTO TBL2 values (new.i); NOTIFY TBL2];
-
- * Then start up this program
- * After the program has begun, do
-
-INSERT INTO TBL1 values (10);
-
+ * Test the C++ version of LIBPQ, the POSTGRES frontend library.
*
+ * queries the template1 database for a list of database names using transaction block
*
*/
-#include <stdio.h>
-#include "libpq++.H"
-main()
-{
- char* dbName;
-
- /* begin, by creating the parameter environtment for a backend
- connection. When no parameters are given then the system will
- try to use reasonable defaults by looking up environment variables
- or, failing that, using hardwired constants */
- PGenv env;
- PGdatabase* data;
- PGnotify* notify;
+#include <iostream.h>
+#include <iomanip.h>
+#include <libpq++.h>
- dbName = getenv("USER"); /* change this to the name of your test database */
-
- /* make a connection to the database */
- data = new PGdatabase(&env, dbName);
+int main()
+{
+ // Begin, by establishing a connection to the backend.
+ // When no parameters are given then the system will
+ // try to use reasonable defaults by looking up environment variables
+ // or, failing that, using hardwired constants
+ const char* dbName = "template1";
+ PgTransaction data(dbName);
+
+ // check to see that the backend connection was successfully made
+ if ( data.ConnectionBad() ) {
+ cerr << "Connection to database '" << dbName << "' failed." << endl
+ << "Error returned: " << data.ErrorMessage() << endl;
+ exit(1);
+ }
- /* check to see that the backend connection was successfully made */
- if (data->status() == CONNECTION_BAD) {
- fprintf(stderr,"Connection to database '%s' failed.\n", dbName);
- fprintf(stderr,"%s",data->errormessage());
- delete data;
+ // submit command to the backend
+ if ( !data.ExecCommandOk("DECLARE myportal CURSOR FOR select * from pg_database") ) {
+ cerr << "DECLARE CURSOR command failed" << endl;
exit(1);
}
- if (data->exec("LISTEN TBL2") != PGRES_COMMAND_OK) {
- fprintf(stderr,"LISTEN command failed\n");
- delete data;
+ // fetch instances from the pg_database, the system catalog of databases
+ if ( !data.ExecTuplesOk("FETCH ALL in myportal") ) {
+ cerr << "FETCH ALL command didn't return tuples properly" << endl;
exit(1);
}
-
- while (1) {
- /* check for asynchronous returns */
- notify = data->notifies();
- if (notify) {
- fprintf(stderr,
- "ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
- notify->relname, notify->be_pid);
- free(notify);
- break;
- }
+
+ // first, print out the attribute names
+ int nFields = data.Fields();
+ for (int i=0; i < nFields; i++)
+ cout << setiosflags(ios::right) << setw(15) << data.FieldName(i);
+ cout << endl << endl;
+
+ // next, print out the instances
+ for (int i=0; i < data.Tuples(); i++) {
+ for (int j=0; j < nFields; j++)
+ cout << setiosflags(ios::right) << setw(15) << data.GetValue(i,j);
+ cout << endl;
}
-
- /* close the connection to the database and cleanup */
- delete data;
+
+ // close the portal
+ data.Exec("CLOSE myportal");
}
/*
* testlibpq3.cc
* Test the C++ version of LIBPQ, the POSTGRES frontend library.
- * tests the binary cursor interface
*
- *
- *
- populate a database by doing the following:
-
-CREATE TABLE test1 (i int4, d float4, p polygon);
-
-INSERT INTO test1 values (1, 3.567, '(3.0, 4.0, 1.0, 2.0)'::polygon);
-
-INSERT INTO test1 values (2, 89.05, '(4.0, 3.0, 2.0, 1.0)'::polygon);
-
- the expected output is:
-
-tuple 0: got
- i = (4 bytes) 1,
- d = (4 bytes) 3.567000,
- p = (4 bytes) 2 points boundbox = (hi=3.000000/4.000000, lo = 1.000000,2.000000)
-tuple 1: got
- i = (4 bytes) 2,
- d = (4 bytes) 89.050003,
- p = (4 bytes) 2 points boundbox = (hi=4.000000/3.000000, lo = 2.000000,1.000000)
-
+ * queries the template1 database for a list of database names using transaction block
+ * and cursor interface.
*
*/
-#include <stdio.h>
-#include "libpq++.H"
-extern "C" {
-#include "utils/geo-decls.h" /* for the POLYGON type */
-}
-
-main()
-{
- char* dbName;
- int i_fnum, d_fnum, p_fnum;
- int i;
-
- /* begin, by creating the parameter environtment for a backend
- connection. When no parameters are given then the system will
- try to use reasonable defaults by looking up environment variables
- or, failing that, using hardwired constants */
- PGenv env;
- PGdatabase* data;
-
- dbName = getenv("USER"); /* change this to the name of your test database */
-
- /* make a connection to the database */
- data = new PGdatabase(&env, dbName);
- /* check to see that the backend connection was successfully made */
- if (data->status() == CONNECTION_BAD) {
- fprintf(stderr,"Connection to database '%s' failed.\n", dbName);
- fprintf(stderr,"%s",data->errormessage());
- delete data;
- exit(1);
- }
+#include <iostream.h>
+#include <iomanip.h>
+#include <libpq++.h>
- /* start a transaction block */
- if (data->exec("BEGIN") != PGRES_COMMAND_OK) {
- fprintf(stderr,"BEGIN command failed\n");
- delete data;
- exit(1);
+int main()
+{
+ // Begin, by establishing a connection to the backend.
+ // When no parameters are given then the system will
+ // try to use reasonable defaults by looking up environment variables
+ // or, failing that, using hardwired constants.
+ // Create a cursor database query object.
+ // All queries using cursor will be performed through this object.
+ const char* dbName = "template1";
+ PgCursor cData(dbName, "myportal");
+
+ // check to see that the backend connection was successfully made
+ if ( cData.ConnectionBad() ) {
+ cerr << "Connection to database '" << dbName << "' failed." << endl
+ << "Error returned: " << cData.ErrorMessage() << endl;
+ exit(1);
}
-
- /* fetch instances from the pg_database, the system catalog of databases*/
- if (data->exec("DECLARE mycursor BINARY CURSOR FOR select * from test1")
- != PGRES_COMMAND_OK) {
- fprintf(stderr,"DECLARE CURSOR command failed\n");
- delete data;
+
+ // submit command to the backend
+ if ( !cData.Declare("select * from pg_database") ) {
+ cerr << "DECLARE CURSOR command failed" << endl;
exit(1);
}
- if (data->exec("FETCH ALL in mycursor") != PGRES_TUPLES_OK) {
- fprintf(stderr,"FETCH ALL command didn't return tuples properly\n");
- delete data;
+ // fetch instances from the pg_cDatabase, the system catalog of cDatabases
+ if ( !cData.Fetch() ) {
+ cerr << "FETCH ALL command didn't return tuples properly" << endl;
exit(1);
}
- i_fnum = data->fieldnum("i");
- d_fnum = data->fieldnum("d");
- p_fnum = data->fieldnum("p");
-
-/*
- for (i=0;i<3;i++) {
- printf("type[%d] = %d, size[%d] = %d\n",
- i, data->fieldtype(i),
- i, data->fieldsize(i));
- }
-*/
-
- for (i=0; i < data->ntuples(); i++) {
- int *ival;
- float *dval;
- int plen;
- POLYGON* pval;
- /* we hard-wire this to the 3 fields we know about */
- ival = (int*)data->getvalue(i,i_fnum);
- dval = (float*)data->getvalue(i,d_fnum);
- plen = data->getlength(i,p_fnum);
-
- /* plen doesn't include the length field so need to increment by VARHDSZ*/
- pval = (POLYGON*) malloc(plen + VARHDRSZ);
- pval->size = plen;
- memmove((char*)&pval->npts, data->getvalue(i,p_fnum), plen);
- printf("tuple %d: got\n", i);
- printf(" i = (%d bytes) %d,\n",
- data->getlength(i,i_fnum), *ival);
- printf(" d = (%d bytes) %f,\n",
- data->getlength(i,d_fnum), *dval);
- printf(" p = (%d bytes) %d points \tboundbox = (hi=%f/%f, lo = %f,%f)\n",
- data->getlength(i,d_fnum),
- pval->npts,
- pval->boundbox.xh,
- pval->boundbox.yh,
- pval->boundbox.xl,
- pval->boundbox.yl);
+ // first, print out the attribute names
+ int nFields = cData.Fields();
+ for (int i=0; i < nFields; i++)
+ cout << setiosflags(ios::right) << setw(15) << cData.FieldName(i);
+ cout << endl << endl;
+
+ // next, print out the instances
+ for (int i=0; i < cData.Tuples(); i++) {
+ for (int j=0; j < nFields; j++)
+ cout << setiosflags(ios::right) << setw(15) << cData.GetValue(i,j);
+ cout << endl;
}
-
- /* close the portal */
- data->exec("CLOSE mycursor");
-
- /* end the transaction */
- data->exec("END");
-
- /* close the connection to the database and cleanup */
- delete data;
}
/*
* testlibpq4.cc
- * Test the C++ version of LIBPQ, the POSTGRES frontend library.
- * tests the copy in features
+ * Test of the asynchronous notification interface
*
- */
-#include <stdio.h>
-#include "libpq++.H"
+ populate a test database with the following (use testlibpq4.sql):
-main()
-{
- char* dbName;
+CREATE TABLE TBL1 (i int4);
- /* begin, by creating the parameter environment for a backend
- connection. When no parameters are given then the system will
- try to use reasonable defaults by looking up environment variables
- or, failing that, using hardwired constants */
- PGenv env;
- PGdatabase* data;
+CREATE TABLE TBL2 (i int4);
- dbName = getenv("USER"); /* change this to the name of your test database */
+CREATE RULE r1 AS ON INSERT TO TBL1 DO [INSERT INTO TBL2 values (new.i); NOTIFY TBL2];
- /* make a connection to the database */
- data = new PGdatabase(&env, dbName);
+ * Then start up this program
+ * After the program has begun, do
- /* check to see that the backend connection was successfully made */
- if (data->status() == CONNECTION_BAD) {
- fprintf(stderr,"Connection to database '%s' failed.\n", dbName);
- fprintf(stderr,"%s",data->errormessage());
- delete data;
- exit(1);
- }
+INSERT INTO TBL1 values (10);
+
+ *
+ *
+ */
+#include <iostream.h>
+#include <libpq++.h>
+#include <stdlib.h>
- /* start a transaction block */
- if(data->exec("BEGIN") != PGRES_COMMAND_OK) {
- fprintf(stderr,"BEGIN command failed\n");
- delete data;
+main()
+{
+ // Begin, by connecting to the backend using hardwired constants
+ // and a test database created by the user prior to the invokation
+ // of this test program.
+ char* dbName = getenv("USER"); // change this to the name of your test database
+ PgDatabase data(dbName);
+
+ // Check to see that the backend connection was successfully made
+ if ( data.ConnectionBad() ) {
+ cerr << "Connection to database '" << dbName << "' failed." << endl
+ << data.ErrorMessage() << endl;
exit(1);
}
- if (data->exec("CREATE TABLE foo (a int4, b char16, d float8)") !=
- PGRES_COMMAND_OK) {
- fprintf(stderr,"CREATE TABLE foo command failed\n");
- delete data;
- exit(1);
+ // Listen to a table
+ if ( !data.ExecCommandOk("LISTEN TBL2") ) {
+ cerr << "LISTEN command failed" << endl;
+ exit(1);
}
- if (data->exec("COPY foo FROM STDIN") != PGRES_COMMAND_OK) {
- fprintf(stderr,"COPY foo FROM STDIN\n");
- delete data;
- exit(1);
+ // Test asynchronous notification
+ while (1) {
+ // check for asynchronous returns
+ PGnotify* notify = data.Notifies();
+ if (notify) {
+ cerr << "ASYNC NOTIFY of '" << notify->relname
+ << "' from backend pid '" << notify->be_pid
+ << "' received" << endl;
+ free(notify);
+ break;
+ }
}
-
- data->putline("3\thello world\t4.5\n");
- data->putline("4\tgoodbye word\t7.11\n");
- data->putline(".\n");
- data->endcopy();
- data->exec("SELECT * FROM foo");
- data->printtuples(stdout,1,"|",1,0);
- data->exec("DROP TABLE foo");
- // end the transaction
- data->exec("END");
-
- // close the connection to the database and cleanup
- delete data;
}
--- /dev/null
+CREATE TABLE TBL1 (i int4);
+
+CREATE TABLE TBL2 (i int4);
+
+CREATE RULE r1 AS ON INSERT TO TBL1 DO [INSERT INTO TBL2 values (new.i); NOTIFY TBL2];
--- /dev/null
+/*
+ * testlibpq5.cc
+ * Test the C++ version of LIBPQ, the POSTGRES frontend library.
+ * tests the binary cursor interface
+ *
+ *
+ *
+ populate a database by doing the following (use testlibpq5.sql):
+
+CREATE TABLE test1 (i int4, d float4, p polygon);
+
+INSERT INTO test1 values (1, 3.567, '(3.0, 4.0, 1.0, 2.0)'::polygon);
+
+INSERT INTO test1 values (2, 89.05, '(4.0, 3.0, 2.0, 1.0)'::polygon);
+
+ the expected output is:
+
+tuple 0: got
+ i = (4 bytes) 1,
+ d = (4 bytes) 3.567000,
+ p = (4 bytes) 2 points boundbox = (hi=3.000000/4.000000, lo = 1.000000,2.000000)
+tuple 1: got
+ i = (4 bytes) 2,
+ d = (4 bytes) 89.050003,
+ p = (4 bytes) 2 points boundbox = (hi=4.000000/3.000000, lo = 2.000000,1.000000)
+
+ *
+ */
+#include <iostream.h>
+#include <libpq++.h>
+#include <stdlib.h>
+extern "C" {
+#include "postgres.h" // for Postgres types
+#include "utils/geo-decls.h" // for the POLYGON type
+}
+
+main()
+{
+ // Begin, by connecting to the backend using hardwired constants
+ // and a test database created by the user prior to the invokation
+ // of this test program. Connect using cursor interface.
+ char* dbName = getenv("USER"); // change this to the name of your test database
+ PgCursor data(dbName, "mycursor");
+
+ // check to see that the backend connection was successfully made
+ if ( data.ConnectionBad() ) {
+ cerr << "Connection to database '" << dbName << "' failed." << endl
+ << data.ErrorMessage();
+ exit(1);
+ }
+
+ // Declare a binary cursor for all the tuples in database 'test1'
+ if ( !data.Declare("select * from test1", 1) ) {
+ cerr << "DECLARE CURSOR command failed" << endl;
+ exit(1);
+ }
+
+ // fetch all instances from the current cursor
+ if ( !data.Fetch() ) {
+ cerr << "FETCH ALL command didn't return tuples properly" << endl;
+ exit(1);
+ }
+
+ // Find the field numbers for the columns 'i', 'd', and 'p'
+ int i_fnum = data.FieldNum("i");
+ int d_fnum = data.FieldNum("d");
+ int p_fnum = data.FieldNum("p");
+
+/*
+ for (i=0;i<3;i++) {
+ printf("type[%d] = %d, size[%d] = %d\n",
+ i, data.FieldType(i),
+ i, data.FieldSize(i));
+ }
+*/
+
+ // Print out the information about the extracted tuple
+ for (int i=0; i < data.Tuples(); i++) {
+ // we hard-wire this to the 3 fields we know about
+ int* ival = (int*)data.GetValue(i,i_fnum);
+ float* dval = (float*)data.GetValue(i,d_fnum);
+ int plen = data.GetLength(i,p_fnum);
+
+ // Allocate correct memory space for the Polygon struct and copy
+ // the extracted data into it.
+ // plen doesn't include the length field so need to increment by VARHDSZ
+ POLYGON* pval = (POLYGON*) malloc(plen + VARHDRSZ);
+ pval->size = plen;
+ memmove((char*)&pval->npts, data.GetValue(i,p_fnum), plen);
+
+ // Display Polygon Information
+ cout << "tuple " << i << ": got" << endl
+ << " i = (" << data.GetLength(i,i_fnum) << " bytes) " << *ival << "," << endl
+ << " d = (" << data.GetLength(i,d_fnum) << " bytes) " << *dval << "," << endl
+ << " p = (" << data.GetLength(i,d_fnum) << " bytes) " << pval->npts << " points"
+ << "\tboundbox = (hi=" << pval->boundbox.xh << "/" << pval->boundbox.yh << ","
+ << "lo = " << pval->boundbox.xl << "," << pval->boundbox.yl << ")" << endl;
+
+ // Deallocate memory allocated for the Polygon structure
+ free(pval);
+ }
+}
--- /dev/null
+CREATE TABLE test1 (i int4, d float4, p polygon);
+
+INSERT INTO test1 values (1, 3.567, '(3.0, 4.0, 1.0, 2.0)'::polygon);
+
+INSERT INTO test1 values (2, 89.05, '(4.0, 3.0, 2.0, 1.0)'::polygon);
+
--- /dev/null
+/*
+ * testlibpq4.cc
+ * Test the C++ version of LIBPQ, the POSTGRES frontend library.
+ * tests the copy in features
+ *
+ */
+#include <iostream.h>
+#include <libpq++.h>
+#include <stdlib.h>
+
+main()
+{
+ // Begin, by connecting to the backend using hardwired constants
+ // and a test database created by the user prior to the invokation
+ // of this test program. Connect using transaction interface.
+ char* dbName = getenv("USER"); // change this to the name of your test database
+ PgTransaction data(dbName);
+
+ // check to see that the backend connection was successfully made
+ if ( data.ConnectionBad() ) {
+ cerr << "Connection to database '" << dbName << "' failed." << endl
+ << data.ErrorMessage();
+ exit(1);
+ }
+ else cout << "Connected to database '" << dbName << "'..." << endl;
+
+ // Create a new table
+ if ( !data.ExecCommandOk("CREATE TABLE foo (a int4, b char16, d float8)") ) {
+ cerr << "CREATE TABLE foo command failed" << endl;
+ exit(1);
+ }
+ else cout << "CREATEd TABLE foo successfully.." << endl;
+
+ // Initiate Copy command
+ if ( data.ExecCommandOk("COPY foo FROM STDIN") ) {
+ cerr << "COPY foo FROM STDIN" << endl;
+ exit(1);
+ }
+ else cout << "COPY foo FROM STDIN was successful.." << endl;
+
+ // Put some test data into the table
+ data.PutLine("3\thello world\t4.5\n");
+ cout << "Line: \"3\thello world\t4.5\" copied..." << endl;
+ data.PutLine("4\tgoodbye word\t7.11\n");
+ cout << "Line: \"4\tgoodbye word\t7.11\" copied..." << endl;
+ data.PutLine(".\n");
+ cout << "Line: \".\" copied..." << endl;
+ if ( !data.EndCopy() )
+ cout << "Ended COPY succesfully..." << endl;
+ else cerr << "End Copy failed..." << endl;
+
+ // Print the data that was inserted into the table
+ if ( data.ExecTuplesOk("SELECT * FROM foo") )
+ data.PrintTuples();
+ else cerr << "SELECT * FROM foo failed..." << endl;
+
+ // Drop the test table
+ data.Exec("DROP TABLE foo");
+}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq++/examples/Attic/testlo.cc,v 1.2 1996/11/18 01:44:28 bryanh Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq++/examples/Attic/testlo.cc,v 1.3 1997/02/13 10:01:05 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
-#include <stdio.h>
-#include "libpq++.H"
-extern "C" {
-#include "libpq/libpq-fs.h"
-}
+#include <iostream.h>
+#include <libpq++.h>
+#include <stdlib.h>
-int
-main(int argc, char **argv)
+int main(int argc, char **argv)
{
- char *in_filename, *out_filename;
- char *database;
- PGenv env;
- PGlobj *object;
-
+ // Check if the program was invoked correctly; if not, signal error
if (argc < 4 || argc > 5) {
- fprintf(stderr, "Usage: %s database_name in_filename out_filename [oid]\n",
- argv[0]);
+ cerr << "Usage: " << argv[0] << " database_name in_filename out_filename [oid]" << endl;
exit(1);
}
- database = argv[1];
- in_filename = argv[2];
- out_filename = argv[3];
+ // Get the arguments passed to the program
+ char* database = argv[1];
+ char* in_filename = argv[2];
+ char* out_filename = argv[3];
- /*
- * set up the connection and create a largeobject for us
- */
- if (argc == 4) {
- object = new PGlobj(&env, database);
- } else {
- object = new PGlobj(&env, database, atoi(argv[4]));
- }
+ // Set up the connection and create a large object
+ int lobjId = ( argc == 4 ? 0 : atoi(argv[4]) );
+ PgLargeObject object(lobjId, database);
- /* check to see that the backend connection was successfully made */
- if (object->status() == CONNECTION_BAD) {
- fprintf(stderr,"Connection to database '%s' failed.\n", database);
- fprintf(stderr,"%s",object->errormessage());
- delete object;
- exit(1);
+ // check to see that the backend connection was successfully made
+ if ( object.ConnectionBad() ) {
+ cerr << "Connection to database '" << database << "' failed." << endl
+ << object.ErrorMessage();
+ exit(1);
}
-
- object->exec("BEGIN");
- printf("importing file \"%s\" ...\n", in_filename);
- object->import(in_filename);
- printf("exporting large object to file \"%s\" ...\n", out_filename);
- object->export(out_filename);
- object->exec("END"); // WHY DOES IT CORE DUMP HERE ???
- delete object;
+
+ // Test the import and export features of the Large Object interface
+ object.Exec("BEGIN");
+ cout << "Importing file \"" << in_filename << "\"..." << endl;
+ object.Import(in_filename);
+ cout << "Exporting large object to file \"" << out_filename << "\"..." << endl;
+ object.Export(out_filename);
+ object.Exec("END"); // WHY DOES IT CORE DUMP HERE ???
}
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * libpq++.H
+ *
+ *
+ * DESCRIPTION
+ * C++ client interface to Postgres
+ * used for building front-end applications
+ *
+ * NOTES
+ * Currently under construction.
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ *
+ * $Id: libpq++.h,v 1.1 1997/02/13 10:00:25 scrappy Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef LIBPQXX_H
+#define LIBPQXX_H
+
+#include "libpq++/pgenv.h"
+#include "libpq++/pgconnection.h"
+#include "libpq++/pgdatabase.h"
+#include "libpq++/pgtransdb.h"
+#include "libpq++/pgcursordb.h"
+#include "libpq++/pglobject.h"
+
+#endif // LIBPQXX_H
+
/*-------------------------------------------------------------------------
*
* FILE
- * pgconnection.cc
+ * pgconnection.cpp
*
* DESCRIPTION
- * implementation of the PGconnection class.
- * PGconnection encapsulates a frontend to backend connection
+ * implementation of the PgConnection class.
+ * PgConnection encapsulates a frontend to backend connection
*
* Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pgconnection.cc,v 1.1.1.1 1996/07/09 06:22:18 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pgconnection.cc,v 1.2 1997/02/13 10:00:27 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
-#include "libpq++.H"
+#include <stdlib.h>
+#include <string.h>
+#include "pgconnection.h"
+
+extern "C" {
+#include "fe-auth.h"
+}
-// default constructor
-// checks environment variable for database name
-PGconnection::PGconnection()
-{
- char* name;
- PGenv* newenv;
- conn = NULL;
- result = NULL;
- errorMessage[0] = '\0';
+// ****************************************************************
+//
+// PgConnection Implementation
+//
+// ****************************************************************
+// default constructor -- initialize everything
+PgConnection::PgConnection()
+ : pgConn(NULL), pgResult(NULL), pgCloseConnection(0)
+{}
- newenv = new PGenv(); // use reasonable defaults for the environment
- if (!(name = getenv(ENV_DEFAULT_DBASE)))
- return;
- connect(newenv, name);
+// copy constructor -- copy the pointers; no deep copy required
+PgConnection::PgConnection(const PgConnection& conn)
+ : pgEnv(conn.pgEnv), pgConn(conn.pgConn), pgResult(conn.pgResult),
+ pgCloseConnection(conn.pgCloseConnection)
+{}
+
+// constructor -- checks environment variable for database name
+PgConnection::PgConnection(const char* dbName)
+ : pgConn(NULL), pgResult(NULL), pgCloseConnection(1)
+{
+ // Get a default database name to connect to
+ char* defDB = (char*)dbName;
+ if ( !dbName )
+ if ( !(defDB = getenv(ENV_DEFAULT_DBASE)) )
+ return;
+
+ // Connect to the database
+ Connect( defDB );
}
// constructor -- for given environment and database name
-PGconnection::PGconnection(PGenv* env, char* dbName)
+PgConnection::PgConnection(const PgEnv& env, const char* dbName)
+ : pgEnv(env), pgConn(NULL), pgResult(NULL), pgCloseConnection(1)
{
- conn = NULL;
- result = NULL;
- errorMessage[0] = '\0';
- connect(env, dbName);
+ Connect( dbName );
}
// destructor - closes down the connection and cleanup
-PGconnection::~PGconnection()
+PgConnection::~PgConnection()
{
- if (result) PQclear(result);
- if (conn) PQfinish(conn);
+ // Terminate the debugging output if it was turned on
+ #if defined(DEBUG)
+ PQuntrace(pgConn);
+ #endif
+
+ // Close the conneciton only if needed
+ // This feature will most probably be used by the derived classes that
+ // need not close the connection after they are destructed.
+ if ( pgCloseConnection ) {
+ if (pgResult) PQclear(pgResult);
+ if (pgConn) PQfinish(pgConn);
+ }
}
-// PGconnection::connect
+// PgConnection::connect
// establish a connection to a backend
-ConnStatusType
-PGconnection::connect(PGenv* newenv, char* dbName)
+ConnStatusType PgConnection::Connect(const char* dbName)
{
-#if 0
- FILE *debug;
- debug = fopen("/tmp/trace.out","w");
- PQtrace(conn, debug);
-#endif
-
- env = newenv;
- fe_setauthsvc(env->pgauth, errorMessage);
- conn = PQsetdb(env->pghost, env->pgport, env->pgoption, env->pgtty, dbName);
- if(strlen(errorMessage))
- return CONNECTION_BAD;
+ // Turn the trace on
+ #if defined(DEBUG)
+ FILE *debug = fopen("/tmp/trace.out","w");
+ PQtrace(pgConn, debug);
+ #endif
+
+ // Set Host Authentication service
+ char errorMessage[ERROR_MSG_LENGTH];
+ memset(errorMessage, 0, sizeof(errorMessage));
+ fe_setauthsvc(pgEnv.Auth(), errorMessage);
+
+ // Connect to the database
+ pgConn = PQsetdb(pgEnv.Host(), pgEnv.Port(), pgEnv.Option(), pgEnv.TTY(), dbName);
+
+ // Return the connection status
+ if (errorMessage) {
+ SetErrorMessage( errorMessage );
+ return CONNECTION_BAD;
+ }
else
- return status();
+ return Status();
}
-// PGconnection::status -- return connection or result status
-ConnStatusType
-PGconnection::status()
+// PgConnection::status -- return connection or result status
+ConnStatusType PgConnection::Status()
{
- return PQstatus(conn);
+ return PQstatus(pgConn);
}
-// PGconnection::exec -- send a query to the backend
-ExecStatusType
-PGconnection::exec(char* query)
+// PgConnection::exec -- send a query to the backend
+ExecStatusType PgConnection::Exec(const char* query)
{
- if (result)
- PQclear(result);
+ // Clear the Result Stucture if needed
+ if (pgResult)
+ PQclear(pgResult);
- result = PQexec(conn, query);
- if (result)
- return PQresultStatus(result);
+ // Execute the given query
+ pgResult = PQexec(pgConn, query);
+
+ // Return the status
+ if (pgResult)
+ return PQresultStatus(pgResult);
else {
- strcpy(errorMessage, PQerrorMessage(conn));
+ SetErrorMessage( PQerrorMessage(pgConn) );
return PGRES_FATAL_ERROR;
}
}
+
+// Return true if the Postgres command was executed OK
+int PgConnection::ExecCommandOk(const char* query)
+{
+ return Exec(query) == PGRES_COMMAND_OK;
+} // End ExecCommandOk()
+
+int PgConnection::ExecTuplesOk(const char* query)
+{
+ return Exec(query) == PGRES_TUPLES_OK;
+} // End ExecTuplesOk()
+
+
+// PgConnection::notifies() -- returns a notification from a list of unhandled notifications
+PGnotify* PgConnection::Notifies()
+{
+ Exec(" ");
+ return PQnotifies(pgConn);
+}
+
+// PgConnection::SetErrorMessage
+// sets error message to the given string
+void PgConnection::SetErrorMessage(const string& msg, int append)
+{
+ if ( append )
+ pgErrorMessage += msg;
+ else
+ pgErrorMessage = msg;
+}
+
+// From Integer To String Conversion Function
+string PgConnection::IntToString(int n)
+{
+ char buffer [32];
+ memset(buffer, 0, sizeof(buffer));
+ sprintf(buffer, "%d", n);
+ return buffer;
+}
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * pgconnection.h
+ *
+ *
+ * DESCRIPTION
+ * Postgres Connection Class:
+ * Manage Postgres backend connection
+ *
+ * NOTES
+ * Currently under construction.
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef PGCONN_H
+#define PGCONN_H
+
+#include <stdio.h>
+#include "pgenv.h"
+
+extern "C" {
+#include "libpq-fe.h"
+}
+
+
+// ****************************************************************
+//
+// PgConnection - a connection made to a postgres backend
+//
+// ****************************************************************
+// This class contains all the information about the connection
+// to the backend process. All the database classes should be
+// derived from this class to obtain the connection interface.
+class PgConnection {
+protected:
+ PgEnv pgEnv; // Current connection environment
+ PGconn* pgConn; // Connection Structures
+ PGresult* pgResult; // Query Result
+ string pgErrorMessage; // Error messages container
+ int pgCloseConnection; // Flag indicating whether the connection should be closed or not
+
+public:
+ PgConnection(const char* dbName); // use reasonable defaults
+ PgConnection(const PgEnv& env, const char* dbName); // connect to the database with
+ // given environment and database name
+ virtual ~PgConnection(); // close connection and clean up
+
+ // Connection status and error messages
+ ConnStatusType Status();
+ int ConnectionBad() { return Status() == CONNECTION_BAD; }
+ const char* ErrorMessage() const { return pgErrorMessage.c_str(); }
+
+ // returns the database name of the connection
+ const char* DBName() const { return PQdb(pgConn); }
+
+ // Query Execution interface
+ ExecStatusType Exec(const char* query); // send a query to the backend
+ int ExecCommandOk(const char* query); // send a command and check if it's OK
+ int ExecTuplesOk(const char* query); // send a command and check if tuples are returned
+ PGnotify* Notifies();
+
+protected:
+ ConnStatusType Connect(const char* dbName);
+ void SetErrorMessage(const string&, int append = 0);
+ string IntToString(int);
+
+protected:
+ PgConnection();
+ PgConnection(const PgConnection&);
+};
+
+#endif // PGCONN_H
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * FILE
+ * pgcursordb.cpp
+ *
+ * DESCRIPTION
+ * implementation of the PgCursor class.
+ * PgCursor encapsulates a cursor interface to the backend
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pgcursordb.cc,v 1.1 1997/02/13 10:00:30 scrappy Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+ #include "pgcursordb.h"
+
+
+// ****************************************************************
+//
+// PgCursor Implementation
+//
+// ****************************************************************
+// Make a connection to the specified database with default environment
+PgCursor::PgCursor(const char* dbName, const char* cursor)
+ : PgTransaction(dbName), pgCursor(cursor)
+{}
+
+// Make a connection to the specified database with the given environment
+PgCursor::PgCursor(const PgEnv& env, const char* dbName, const char* cursor)
+ : PgTransaction(env, dbName), pgCursor(cursor)
+{}
+
+// Do not make a connection to the backend -- just query
+// Connection should not be closed after the object destructs since some
+// other object is using the connection
+PgCursor::PgCursor(const PgConnection& conn, const char* cursor)
+ : PgTransaction(conn), pgCursor(cursor)
+{}
+
+// Destructor: End the transaction block
+PgCursor::~PgCursor()
+{
+ Close();
+}
+
+
+// ****************************************************************
+//
+// PgCursor: Cursor Interface Implementation
+//
+// ****************************************************************
+// Declare a cursor: name has already been supplied in the constructor
+int PgCursor::Declare(const string& query, int binary)
+{
+ string cmd = "DECLARE " + pgCursor;
+ if ( binary )
+ cmd += " BINARY";
+ cmd += " CURSOR FOR " + query;
+ return ExecCommandOk( cmd.c_str() );
+} // End Declare()
+
+// Fetch ALL tuples in given direction
+int PgCursor::Fetch(const char* dir)
+{
+ return Fetch("ALL", dir);
+} // End Fetch()
+
+// Fetch specified amount of tuples in given direction
+int PgCursor::Fetch(unsigned num, const char* dir)
+{
+ return Fetch( IntToString(num), dir );
+} // End Fetch()
+
+// Create and execute the actual fetch command with the given arguments
+int PgCursor::Fetch(const string& num, const string& dir)
+{
+ string cmd = "FETCH " + dir + " " + num + " IN " + pgCursor;
+ return ExecTuplesOk( cmd.c_str() );
+} // End Fetch()
+
+// Close the cursor: no more queries using the cursor should be allowed
+// Actually, the backend should take care of it.
+int PgCursor::Close()
+{
+ string cmd = "CLOSE " + pgCursor;
+ return ExecCommandOk( cmd.c_str() );
+} // End CloseCursor()
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * pgcursordb.h
+ *
+ *
+ * DESCRIPTION
+ * Postgres Cursor Database Class:
+ * Query Postgres backend using a cursor
+ *
+ * NOTES
+ * Currently under construction.
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef PGCURSOR_H
+#define PGCURSOR_H
+
+#include "pgtransdb.h"
+
+
+// ****************************************************************
+//
+// PgCursor - a class for querying databases using a cursor
+//
+// ****************************************************************
+// This is the database access class that declares a cursor and
+// manipulates data through it. The interface will introduce some
+// ease of use through the methods that will allow cursor specific
+// operations, like fetch, forward, etc.
+class PgCursor : public PgTransaction {
+public:
+ PgCursor(const char* dbName, const char* cursor); // use reasonable defaults
+ // connect to the database with given environment and database name
+ PgCursor(const PgEnv& env, const char* dbName, const char* cursor);
+ PgCursor(const PgConnection&, const char* cursor);
+ virtual ~PgCursor(); // close connection and clean up
+
+ // Commands associated with cursor interface
+ int Declare(const string& query, int binary = 0); // Declare a cursor with given name
+ int Fetch(const char* dir = "FORWARD"); // Fetch ALL tuples in given direction
+ int Fetch(unsigned num, const char* dir = "FORWARD"); // Fetch specified amount of tuples
+ int Close(); // Close the cursor
+
+ // Accessors to the cursor name
+ const char* Cursor() const { return pgCursor.c_str(); }
+ void Cursor(const string& cursor) { pgCursor = cursor; }
+
+protected:
+ int Fetch(const string& num, const string& dir);
+
+protected:
+ string pgCursor;
+
+protected:
+ PgCursor() : PgTransaction() {} // Do not connect
+}; // End PgCursor Class Declaration
+
+#endif // PGCURSOR_H
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * pgdatabase.h
+ *
+ *
+ * DESCRIPTION
+ * Postgres Database Class:
+ * Query Postgres backend to obtain query results
+ *
+ * NOTES
+ * Currently under construction.
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef PGDATABASE_H
+#define PGDATABASE_H
+
+#include "pgconnection.h"
+
+
+// ****************************************************************
+//
+// PgDatabase - a class for accessing databases
+//
+// ****************************************************************
+// This is the basic database access class. Its interface should
+// be used only after a query has been sent to the backend and
+// results are being received.
+class PgDatabase : public PgConnection {
+public:
+ PgDatabase(const char* dbName) : PgConnection(dbName) {} // use reasonable defaults
+ // connect to the database with given environment and database name
+ PgDatabase(const PgEnv& env, const char* dbName) : PgConnection(env, dbName) {}
+ PgDatabase(const PgConnection& conn) : PgConnection(conn) {pgCloseConnection = 0;}
+ ~PgDatabase() {} // close connection and clean up
+
+ // query result access
+ int Tuples()
+ { return PQntuples(pgResult); }
+ int Fields()
+ { return PQnfields(pgResult); }
+ const char* FieldName(int field_num)
+ { return PQfname(pgResult, field_num); }
+ int FieldNum(const char* field_name)
+ { return PQfnumber(pgResult, field_name); }
+ Oid FieldType(int field_num)
+ { return PQftype(pgResult, field_num); }
+ Oid FieldType(const char* field_name)
+ { return PQftype(pgResult, FieldNum(field_name)); }
+ short FieldSize(int field_num)
+ { return PQfsize(pgResult, field_num); }
+ short FieldSize(const char* field_name)
+ { return PQfsize(pgResult, FieldNum(field_name)); }
+ const char* GetValue(int tup_num, int field_num)
+ { return PQgetvalue(pgResult, tup_num, field_num); }
+ const char* GetValue(int tup_num, const char* field_name)
+ { return PQgetvalue(pgResult, tup_num, FieldNum(field_name)); }
+ int GetLength(int tup_num, int field_num)
+ { return PQgetlength(pgResult, tup_num, field_num); }
+ int GetLength(int tup_num, const char* field_name)
+ { return PQgetlength(pgResult, tup_num, FieldNum(field_name)); }
+ void DisplayTuples(FILE *out = 0, int fillAlign = 1, const char* fieldSep = "|",
+ int printHeader = 1, int quiet = 0)
+ { PQdisplayTuples(pgResult, (out ? out : stdout), fillAlign, fieldSep, printHeader, quiet); }
+ void PrintTuples(FILE *out = 0, int printAttName = 1, int terseOutput = 0, int width = 0)
+ { PQprintTuples(pgResult, (out ? out : stdout), printAttName, terseOutput, width); }
+
+ // copy command related access
+ int GetLine(char* string, int length)
+ { return PQgetline(pgConn, string, length); }
+ void PutLine(const char* string)
+ { PQputline(pgConn, string); }
+ const char* OidStatus()
+ { return PQoidStatus(pgResult); }
+ int EndCopy()
+ { return PQendcopy(pgConn); }
+
+protected:
+ PgDatabase() : PgConnection() {} // Do not connect
+};
+
+#endif // PGDATABASE_H
/*-------------------------------------------------------------------------
*
* FILE
- * PGenv.cc
+ * PgEnv.cc
*
* DESCRIPTION
- * PGenv is the environment for setting up a connection to a
+ * PgEnv is the environment for setting up a connection to a
* postgres backend, captures the host, port, tty, options and
* authentication type.
*
* Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pgenv.cc,v 1.2 1996/11/18 01:43:55 bryanh Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pgenv.cc,v 1.3 1997/02/13 10:00:33 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#include <stdlib.h>
-#include "libpq++.H"
+#include "pgenv.h"
-#define DefaultAuth DEFAULT_CLIENT_AUTHSVC
-#define DefaultPort "5432"
-// default constructor for PGenv
+#define DefaultAuth DEFAULT_CLIENT_AUTHSVC
+#define DefaultPort POSTPORT
+
+
+// ****************************************************************
+//
+// PgEnv Implementation
+//
+// ****************************************************************
+// Default constructor for PgEnv
// checks the environment variables
-PGenv::PGenv()
+PgEnv::PgEnv()
{
- pgauth = NULL;
- pghost = NULL;
- pgport = NULL;
- pgoption = NULL;
- pgtty = NULL;
-
- setValues(getenv(ENV_DEFAULT_AUTH), getenv(ENV_DEFAULT_HOST),
+ SetValues(getenv(ENV_DEFAULT_AUTH), getenv(ENV_DEFAULT_HOST),
getenv(ENV_DEFAULT_PORT), getenv(ENV_DEFAULT_OPTION),
- getenv(ENV_DEFAULT_TTY));
+ getenv(ENV_DEFAULT_TTY));
}
// constructor for given environment
-PGenv::PGenv(char* auth, char* host, char* port, char* option, char* tty)
+PgEnv::PgEnv(const string& auth, const string& host, const string& port,
+ const string& option, const string& tty)
{
- pgauth = NULL;
- pghost = NULL;
- pgport = NULL;
- pgoption = NULL;
- pgtty = NULL;
-
- setValues(auth, host, port, option, tty);
+ SetValues(auth, host, port, option, tty);
}
// allocate memory and set internal structures to match
// required environment
-void
-PGenv::setValues(char* auth, char* host, char* port, char* option, char* tty)
+void PgEnv::SetValues(const string& auth, const string& host, const string& port,
+ const string& option, const string& tty)
{
- char* temp;
-
- temp = (auth) ? auth : DefaultAuth;
-
- if (pgauth)
- free(pgauth);
- pgauth = strdup(temp);
-
- temp = (host) ? host : DefaultHost;
-
- if (pghost)
- free(pghost);
- pghost = strdup(temp);
-
- temp = (port) ? port : DefaultPort;
-
- if (pgport)
- free(pgport);
- pgport = strdup(temp);
-
- temp = (option) ? option : DefaultOption;
-
- if (pgoption)
- free(pgoption);
- pgoption = strdup(temp);
-
- temp = (tty) ? tty : DefaultTty;
-
- if (pgtty)
- free(pgtty);
- pgtty = strdup(temp);
+ Auth( auth );
+ Host( host );
+ Port( port );
+ Option( option );
+ TTY( tty );
}
-// default destrutor
-// frees allocated memory for internal structures
-PGenv::~PGenv()
+// read a string from the environment and convert it to string
+string PgEnv::getenv(const char* name)
{
- if (pgauth)
- free(pgauth);
- if (pghost)
- free(pghost);
- if (pgport)
- free(pgport);
- if (pgoption)
- free(pgoption);
- if (pgtty)
- free(pgtty);
+ char* env = ::getenv(name);
+ return (env ? env : "");
}
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * pgenv.h
+ *
+ *
+ * DESCRIPTION
+ * Postgres Environment Class: manages and stores all the required
+ * connection variables.
+ *
+ * NOTES
+ * Currently under construction.
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef PGENV_H
+#define PGENV_H
+
+#include <string>
+
+
+//
+// these are the environment variables used for getting defaults
+//
+
+#define ENV_DEFAULT_AUTH "PGAUTH"
+#define ENV_DEFAULT_DBASE "PGDATABASE"
+#define ENV_DEFAULT_HOST "PGHOST"
+#define ENV_DEFAULT_OPTION "PGOPTION"
+#define ENV_DEFAULT_PORT "PGPORT"
+#define ENV_DEFAULT_TTY "PGTTY"
+
+
+// ****************************************************************
+//
+// PgEnv - the environment for setting up a connection to postgres
+//
+// ****************************************************************
+class PgEnv {
+private:
+ string pgAuth;
+ string pgHost;
+ string pgPort;
+ string pgOption;
+ string pgTty;
+
+public:
+ PgEnv(); // default ctor will use reasonable defaults
+ // will use environment variables PGHOST, PGPORT,
+ // PGOPTION, PGTTY
+ PgEnv(const string& auth, const string& host, const string& port,
+ const string& option, const string& tty);
+
+ // Access methods to all the environment variables
+ const char* Auth() { return pgAuth.c_str(); }
+ void Auth(const string& auth) { pgAuth = auth; }
+
+ const char* Host() { return pgHost.c_str(); }
+ void Host(const string& host) { pgHost = host; }
+
+ const char* Port() { return pgPort.c_str(); }
+ void Port(const string& port) { pgPort = port; }
+
+ const char* Option() { return pgOption.c_str(); }
+ void Option(const string& option) { pgOption = option; }
+
+ const char* TTY() { return pgTty.c_str(); }
+ void TTY(const string& tty) { pgTty = tty; }
+
+ void SetValues(const string& auth, const string& host, const string& port,
+ const string& option, const string& tty);
+
+protected:
+ string getenv(const char*);
+};
+
+#endif // PGENV_H
-
/*-------------------------------------------------------------------------
*
* FILE
* pglobject.cc
*
* DESCRIPTION
- * implementation of the PGlobj class.
- * PGlobj encapsulates a frontend to backend connection
+ * implementation of the PgLargeObject class.
+ * PgLargeObject encapsulates a frontend to backend connection
*
* Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pglobject.cc,v 1.2 1996/11/12 11:42:31 bryanh Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pglobject.cc,v 1.3 1997/02/13 10:00:34 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
-#include "libpq++.H"
-
+
extern "C" {
-#include <unistd.h>
-#include <fcntl.h>
#include "libpq/libpq-fs.h"
}
+#include "pglobject.h"
+
+
+
+// ****************************************************************
+//
+// PgLargeObject Implementation
+//
+// ****************************************************************
// default constructor
// creates a large object in the default database
-PGlobj::PGlobj() : PGconnection::PGconnection() {
- object = lo_creat(conn, INV_READ|INV_WRITE);
- if (object == 0) {
- sprintf(errorMessage, "PGlobj: can't create large object");
- }
- fd = lo_open(conn, object, INV_READ|INV_WRITE);
- if (fd < 0) {
- sprintf(errorMessage, "PGlobj: can't open large object %d", object);
- } else
- sprintf(errorMessage, "PGlobj: created and opened large object %d",
- object);
-
+PgLargeObject::PgLargeObject(const char* dbName)
+ : PgConnection(dbName)
+{
+ Init();
+ Create();
+ Open();
}
// constructor
// open an existing large object in the default database
-PGlobj::PGlobj(Oid lobjId) : PGconnection::PGconnection() {
- object = lobjId;
- fd = lo_open(conn, object, INV_READ|INV_WRITE);
- if (fd < 0) {
- sprintf(errorMessage, "PGlobj: can't open large object %d", object);
- } else
- sprintf(errorMessage, "PGlobj: opened large object %d",
- object);
+PgLargeObject::PgLargeObject(Oid lobjId, const char* dbName)
+ : PgConnection(dbName)
+{
+ Init(lobjId);
+ if ( !pgObject )
+ Create();
+ Open();
}
// constructor
// create a large object in the given database
-PGlobj::PGlobj(PGenv* env, char* dbName) : PGconnection::PGconnection(env,dbName) {
- object = lo_creat(conn, INV_READ|INV_WRITE);
- if (object == 0) {
- sprintf(errorMessage, "PGlobj: can't create large object");
- }
- fd = lo_open(conn, object, INV_READ|INV_WRITE);
- if (fd < 0) {
- sprintf(errorMessage, "PGlobj: can't open large object %d", object);
- } else
- sprintf(errorMessage, "PGlobj: created and opened large object %d",
- object);
+PgLargeObject::PgLargeObject(const PgEnv& env, const char* dbName)
+ : PgConnection(env, dbName)
+{
+ Init();
+ Create();
+ Open();
}
// constructor
// open an existing large object in the given database
-PGlobj::PGlobj(PGenv* env, char* dbName, Oid lobjId) : PGconnection::PGconnection(env,dbName) {
- object = lobjId;
- fd = lo_open(conn, object, INV_READ|INV_WRITE);
- if (fd < 0) {
- sprintf(errorMessage, "PGlobj: can't open large object %d", object);
- } else
- sprintf(errorMessage, "PGlobj: created and opened large object %d",
- object);
+PgLargeObject::PgLargeObject(const PgEnv& env, const char* dbName, Oid lobjId)
+ : PgConnection(env, dbName)
+{
+ Init(lobjId);
+ if ( !pgObject )
+ Create();
+ Open();
}
-// PGlobj::unlink
-// destruct large object and delete from it from the database
-int
-PGlobj::unlink() {
- int temp = lo_unlink(conn, object);
- if (temp) {
- return temp;
- } else {
- delete this;
- return temp;
- }
+// destructor -- closes large object
+PgLargeObject::~PgLargeObject()
+{
+ Close();
}
-// PGlobj::import -- import a given file into the large object
-int
-PGlobj::import(char* filename) {
- char buf[BUFSIZE];
- int nbytes, tmp;
- int in_fd;
-
- // open the file to be read in
- in_fd = open(filename, O_RDONLY, 0666);
- if (in_fd < 0) { /* error */
- sprintf(errorMessage, "PGlobj::import: can't open unix file\"%s\"", filename);
- return -1;
- }
-
- // read in from the Unix file and write to the inversion file
- while ((nbytes = ::read(in_fd, buf, BUFSIZE)) > 0) {
- tmp = lo_write(conn, fd, buf, nbytes);
- if (tmp < nbytes) {
- sprintf(errorMessage, "PGlobj::import: error while reading \"%s\"",
- filename);
- return -1;
- }
- }
-
- (void) close(in_fd);
- return 0;
+// PgLargeObject::Init
+// Initialize the variables
+void PgLargeObject::Init(Oid lobjId)
+{
+ pgFd = -1;
+ pgObject = lobjId;
}
-// PGlobj::export -- export large object to given file
-int
-PGlobj::export(char* filename) {
- int out_fd;
- char buf[BUFSIZE];
- int nbytes, tmp;
-
- // open the file to be written to
- out_fd = open(filename, O_CREAT|O_WRONLY, 0666);
- if (out_fd < 0) { /* error */
- sprintf(errorMessage, "PGlobj::export: can't open unix file\"%s\"",
- filename);
- return -1;
- }
+// PgLargeObject::create
+// create large object and check for errors
+void PgLargeObject::Create()
+{
+ // Create the object
+ pgObject = lo_creat(pgConn, INV_READ|INV_WRITE);
+
+ // Check for possible errors
+ if (!pgObject)
+ SetErrorMessage( "PgLargeObject: can't create large object" );
+}
- // read in from the Unix file and write to the inversion file
- while ((nbytes = lo_read(conn, fd, buf, BUFSIZE)) > 0) {
- tmp = ::write(out_fd, buf, nbytes);
- if (tmp < nbytes) {
- sprintf(errorMessage,"PGlobj::export: error while writing \"%s\"",
- filename);
- return -1;
- }
- }
- (void) close(out_fd);
- return 0;
+// PgLargeObject::open
+// open large object and check for errors
+void PgLargeObject::Open()
+{
+ // Open the object
+ pgFd = lo_open(pgConn, pgObject, INV_READ|INV_WRITE);
+
+ // Check for possible errors
+ string objStr( IntToString(pgObject) );
+ if (pgFd < 0)
+ SetErrorMessage( "PgLargeObject: can't open large object " + objStr );
+ else
+ SetErrorMessage( "PgLargeObject: created and opened large object " + objStr );
}
-// default destructor -- closes large object
-PGlobj::~PGlobj() {
- if (fd >= 0)
- lo_close(conn, fd);
+// PgLargeObject::unlink
+// destruct large object and delete from it from the database
+int PgLargeObject::Unlink()
+{
+ // Unlink the object
+ int temp = lo_unlink(pgConn, pgObject);
+
+ // Initialize the large object upon success
+ if (!temp) {
+ Close();
+ Init();
+ }
+
+ // Return the status
+ return temp;
}
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * FILE
+ * pglobject.h
+ *
+ * DESCRIPTION
+ * declaration of the PGlobj class.
+ * PGlobj encapsulates a large object interface to Postgres backend
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pglobject.h,v 1.1 1997/02/13 10:00:35 scrappy Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef PGLOBJ_H
+#define PGLOBJ_H
+
+#include "pgconnection.h"
+
+// buffer size
+#define BUFSIZE 1024
+
+
+// ****************************************************************
+//
+// PgLargeObject - a class for accessing Large Object in a database
+//
+// ****************************************************************
+class PgLargeObject : public PgConnection {
+private:
+ int pgFd;
+ Oid pgObject;
+
+public:
+ PgLargeObject(const char* dbName = 0); // use reasonable defaults and create large object
+ PgLargeObject(Oid lobjId, const char* dbName = 0); // use reasonable defaults and open large object
+ PgLargeObject(const PgEnv& env, const char* dbName); // create large object
+ PgLargeObject(const PgEnv& env, const char* dbName, Oid lobjId); // open large object
+ ~PgLargeObject(); // close connection and clean up
+
+ void Create();
+ void Open();
+ void Close()
+ { if (pgFd >= 0) lo_close(pgConn, pgFd); }
+ int Read(char* buf, int len)
+ { return lo_read(pgConn, pgFd, buf, len); }
+ int Write(const char* buf, int len)
+ { return lo_write(pgConn, pgFd, (char*)buf, len); }
+ int LSeek(int offset, int whence)
+ { return lo_lseek(pgConn, pgFd, offset, whence); }
+ int Tell()
+ { return lo_tell(pgConn, pgFd); }
+ int Unlink();
+ Oid Import(const char* filename) { return pgObject = lo_import(pgConn, (char*)filename); }
+ int Export(const char* filename) { return lo_export(pgConn, pgObject, (char*)filename); }
+
+private:
+ void Init(Oid lobjId = 0);
+};
+
+#endif // PGLOBJ_H
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * FILE
+ * pgtransdb.cpp
+ *
+ * DESCRIPTION
+ * implementation of the PgTransaction class.
+ * PgConnection encapsulates a transaction querying to backend
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pgtransdb.cc,v 1.1 1997/02/13 10:00:36 scrappy Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+ #include "pgtransdb.h"
+
+
+// ****************************************************************
+//
+// PgTransaction Implementation
+//
+// ****************************************************************
+// Make a connection to the specified database with default environment
+PgTransaction::PgTransaction(const char* dbName)
+ : PgDatabase(dbName)
+{
+ BeginTransaction();
+}
+
+// Make a connection to the specified database with the given environment
+PgTransaction::PgTransaction(const PgEnv& env, const char* dbName)
+ : PgDatabase(env, dbName)
+{
+ BeginTransaction();
+}
+
+// Do not make a connection to the backend -- just query
+// Connection should not be closed after the object destructs since some
+// other object is using the connection
+PgTransaction::PgTransaction(const PgConnection& conn)
+ : PgDatabase(conn)
+{
+ BeginTransaction();
+}
+
+// Destructor: End the transaction block
+PgTransaction::~PgTransaction()
+{
+ EndTransaction();
+}
+
+// Begin the transaction block
+ExecStatusType PgTransaction::BeginTransaction()
+{
+ return Exec("BEGIN");
+} // End BeginTransaction()
+
+// Begin the transaction block
+ExecStatusType PgTransaction::EndTransaction()
+{
+ return Exec("END");
+} // End EndTransaction()
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * pgtransdb.h
+ *
+ *
+ * DESCRIPTION
+ * Postgres Transaction Database Class:
+ * Query Postgres backend using a transaction block
+ *
+ * NOTES
+ * Currently under construction.
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef PGTRANSDB_H
+#define PGTRANSDB_H
+
+#include "pgdatabase.h"
+
+
+// ****************************************************************
+//
+// PgTransaction - a class for running transactions against databases
+//
+// ****************************************************************
+// This is the database access class that keeps an open
+// transaction block during its lifetime. The block is ENDed when
+// the object is destroyed.
+class PgTransaction : public PgDatabase {
+public:
+ PgTransaction(const char* dbName); // use reasonable defaults
+ // connect to the database with given environment and database name
+ PgTransaction(const PgEnv& env, const char* dbName);
+ PgTransaction(const PgConnection&);
+ virtual ~PgTransaction(); // close connection and clean up
+
+protected:
+ ExecStatusType BeginTransaction();
+ ExecStatusType EndTransaction();
+
+protected:
+ PgTransaction() : PgDatabase() {} // Do not connect
+}; // End PgTransaction Class Declaration
+
+#endif // PGTRANSDB_H