mirror of
https://github.com/postgres/postgres.git
synced 2025-04-25 21:42:33 +03:00
Bring in Leo's <lsh@lubrizol.com> massive changes to libpq++
This commit is contained in:
parent
d62267c707
commit
eacd0fd938
@ -7,12 +7,16 @@
|
||||
#
|
||||
#
|
||||
# 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"
|
||||
@ -22,48 +26,72 @@ CXXFLAGS= $(CFLAGS) -Wno-error
|
||||
|
||||
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
|
||||
|
||||
libpq++.a: $(OBJS)
|
||||
all: $(LIBNAME).a install examples
|
||||
|
||||
$(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
|
||||
.PHONY: install install-$(LIBNAME) doc
|
||||
|
||||
install: install-headers install-libpq++ doc
|
||||
install: install-headers install-$(LIBNAME) doc
|
||||
|
||||
install-headers: beforeinstall-headers libpq++.H
|
||||
$(INSTALL) $(INSTLOPTS) libpq++.H $(HEADERDIR)/libpq++.H
|
||||
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
|
||||
|
||||
|
36
src/interfaces/libpq++/dependencies
Normal file
36
src/interfaces/libpq++/dependencies
Normal file
@ -0,0 +1,36 @@
|
||||
###########################################################################
|
||||
# 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
|
@ -5,6 +5,8 @@
|
||||
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.
|
||||
@ -15,8 +17,8 @@ INCLUDE_OPT= \
|
||||
-I.. \
|
||||
-I../../backend \
|
||||
-I../../include \
|
||||
-I$(LIBPQDIR)
|
||||
|
||||
-I$(LIBPQDIR) \
|
||||
-I$(HEADERDIR)
|
||||
CXXFLAGS+= $(INCLUDE_OPT)
|
||||
|
||||
LD_ADD+= -L.. -lpq++ -L$(LIBPQDIR) -lpq
|
||||
@ -29,19 +31,21 @@ LD_ADD+= $(KRBLIBS)
|
||||
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)
|
||||
|
||||
|
@ -9,41 +9,44 @@
|
||||
*
|
||||
*
|
||||
* 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()
|
||||
{
|
||||
ExecStatusType status;
|
||||
PGenv env;
|
||||
PGdatabase* data;
|
||||
|
||||
char buf[10000];
|
||||
int done = 0;
|
||||
|
||||
data = new PGdatabase(&env, "template1");
|
||||
|
||||
if (data->status() == CONNECTION_BAD)
|
||||
printf("connection was unsuccessful\n%s\n", data->errormessage());
|
||||
// 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
|
||||
printf("connection successful\n");
|
||||
|
||||
cout << "Connection successful... Enter queries below:" << endl;
|
||||
|
||||
// Interactively obtain and execute queries
|
||||
ExecStatusType status;
|
||||
string buf;
|
||||
int done = 0;
|
||||
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()
|
||||
|
@ -1,84 +1,67 @@
|
||||
/*
|
||||
* 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()
|
||||
#include <iostream.h>
|
||||
#include <iomanip.h>
|
||||
#include <libpq++.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char* dbName;
|
||||
int nFields;
|
||||
int i,j;
|
||||
// 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);
|
||||
|
||||
/* 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;
|
||||
// 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);
|
||||
}
|
||||
|
||||
/* Select a database */
|
||||
dbName = "template1";
|
||||
|
||||
/* 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;
|
||||
// start a transaction block
|
||||
if ( !data.ExecCommandOk("BEGIN") ) {
|
||||
cerr << "BEGIN command failed" << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* start a transaction block */
|
||||
if(data->exec("BEGIN") != PGRES_COMMAND_OK) {
|
||||
fprintf(stderr,"BEGIN 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);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
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");
|
||||
// Close the portal
|
||||
data.Exec("CLOSE myportal");
|
||||
|
||||
/* end the transaction */
|
||||
data->exec("END");
|
||||
|
||||
/* close the connection to the database and cleanup */
|
||||
delete data;
|
||||
// End the transaction
|
||||
data.Exec("END");
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,69 +1,56 @@
|
||||
/*
|
||||
* 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()
|
||||
#include <iostream.h>
|
||||
#include <iomanip.h>
|
||||
#include <libpq++.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char* dbName;
|
||||
// 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);
|
||||
|
||||
/* 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;
|
||||
// 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);
|
||||
}
|
||||
|
||||
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;
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
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;
|
||||
}
|
||||
// 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");
|
||||
}
|
||||
|
@ -1,130 +1,56 @@
|
||||
/*
|
||||
* 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()
|
||||
#include <iostream.h>
|
||||
#include <iomanip.h>
|
||||
#include <libpq++.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char* dbName;
|
||||
int i_fnum, d_fnum, p_fnum;
|
||||
int i;
|
||||
// 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");
|
||||
|
||||
/* 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;
|
||||
// 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);
|
||||
}
|
||||
|
||||
// submit command to the backend
|
||||
if ( !cData.Declare("select * from pg_database") ) {
|
||||
cerr << "DECLARE CURSOR command failed" << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* start a transaction block */
|
||||
if (data->exec("BEGIN") != PGRES_COMMAND_OK) {
|
||||
fprintf(stderr,"BEGIN command failed\n");
|
||||
delete data;
|
||||
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;
|
||||
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));
|
||||
// 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;
|
||||
}
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* close the portal */
|
||||
data->exec("CLOSE mycursor");
|
||||
|
||||
/* end the transaction */
|
||||
data->exec("END");
|
||||
|
||||
/* close the connection to the database and cleanup */
|
||||
delete data;
|
||||
}
|
||||
|
@ -1,66 +1,58 @@
|
||||
/*
|
||||
* testlibpq4.cc
|
||||
* Test the C++ version of LIBPQ, the POSTGRES frontend library.
|
||||
* tests the copy in features
|
||||
* Test of the asynchronous notification interface
|
||||
*
|
||||
populate a test database with the following (use testlibpq4.sql):
|
||||
|
||||
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);
|
||||
|
||||
*
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "libpq++.H"
|
||||
#include <iostream.h>
|
||||
#include <libpq++.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
main()
|
||||
{
|
||||
char* dbName;
|
||||
// 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);
|
||||
|
||||
/* 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;
|
||||
|
||||
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;
|
||||
// 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);
|
||||
}
|
||||
|
||||
/* start a transaction block */
|
||||
if(data->exec("BEGIN") != PGRES_COMMAND_OK) {
|
||||
fprintf(stderr,"BEGIN command failed\n");
|
||||
delete data;
|
||||
// Listen to a table
|
||||
if ( !data.ExecCommandOk("LISTEN TBL2") ) {
|
||||
cerr << "LISTEN command failed" << 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);
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
if (data->exec("COPY foo FROM STDIN") != PGRES_COMMAND_OK) {
|
||||
fprintf(stderr,"COPY foo FROM STDIN\n");
|
||||
delete data;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
5
src/interfaces/libpq++/examples/testlibpq4.sql
Normal file
5
src/interfaces/libpq++/examples/testlibpq4.sql
Normal file
@ -0,0 +1,5 @@
|
||||
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];
|
102
src/interfaces/libpq++/examples/testlibpq5.cc
Normal file
102
src/interfaces/libpq++/examples/testlibpq5.cc
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
6
src/interfaces/libpq++/examples/testlibpq5.sql
Normal file
6
src/interfaces/libpq++/examples/testlibpq5.sql
Normal file
@ -0,0 +1,6 @@
|
||||
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);
|
||||
|
59
src/interfaces/libpq++/examples/testlibpq6.cc
Normal file
59
src/interfaces/libpq++/examples/testlibpq6.cc
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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");
|
||||
}
|
@ -7,56 +7,43 @@
|
||||
*
|
||||
*
|
||||
* 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.ConnectionBad() ) {
|
||||
cerr << "Connection to database '" << database << "' failed." << endl
|
||||
<< object.ErrorMessage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
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 ???
|
||||
}
|
||||
|
33
src/interfaces/libpq++/libpq++.h
Normal file
33
src/interfaces/libpq++/libpq++.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* 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
|
||||
|
@ -1,94 +1,169 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* 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"
|
||||
|
||||
// default constructor
|
||||
// checks environment variable for database name
|
||||
PGconnection::PGconnection()
|
||||
extern "C" {
|
||||
#include "fe-auth.h"
|
||||
}
|
||||
|
||||
|
||||
// ****************************************************************
|
||||
//
|
||||
// PgConnection Implementation
|
||||
//
|
||||
// ****************************************************************
|
||||
// default constructor -- initialize everything
|
||||
PgConnection::PgConnection()
|
||||
: pgConn(NULL), pgResult(NULL), pgCloseConnection(0)
|
||||
{}
|
||||
|
||||
// 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)
|
||||
{
|
||||
char* name;
|
||||
PGenv* newenv;
|
||||
|
||||
conn = NULL;
|
||||
result = NULL;
|
||||
errorMessage[0] = '\0';
|
||||
|
||||
newenv = new PGenv(); // use reasonable defaults for the environment
|
||||
if (!(name = getenv(ENV_DEFAULT_DBASE)))
|
||||
return;
|
||||
connect(newenv, name);
|
||||
// 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
|
||||
// Turn the trace on
|
||||
#if defined(DEBUG)
|
||||
FILE *debug = fopen("/tmp/trace.out","w");
|
||||
PQtrace(pgConn, 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;
|
||||
// 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;
|
||||
}
|
||||
|
75
src/interfaces/libpq++/pgconnection.h
Normal file
75
src/interfaces/libpq++/pgconnection.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* 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
|
90
src/interfaces/libpq++/pgcursordb.cc
Normal file
90
src/interfaces/libpq++/pgcursordb.cc
Normal file
@ -0,0 +1,90 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* 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()
|
61
src/interfaces/libpq++/pgcursordb.h
Normal file
61
src/interfaces/libpq++/pgcursordb.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* 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
|
85
src/interfaces/libpq++/pgdatabase.h
Normal file
85
src/interfaces/libpq++/pgdatabase.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* 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
|
@ -1,10 +1,10 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
@ -14,94 +14,55 @@
|
||||
* 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 : "");
|
||||
}
|
||||
|
79
src/interfaces/libpq++/pgenv.h
Normal file
79
src/interfaces/libpq++/pgenv.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* 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
|
@ -1,154 +1,129 @@
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* 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
|
||||
// destructor -- closes large object
|
||||
PgLargeObject::~PgLargeObject()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
// PgLargeObject::Init
|
||||
// Initialize the variables
|
||||
void PgLargeObject::Init(Oid lobjId)
|
||||
{
|
||||
pgFd = -1;
|
||||
pgObject = lobjId;
|
||||
}
|
||||
|
||||
// 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" );
|
||||
}
|
||||
|
||||
// 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 );
|
||||
}
|
||||
|
||||
// PgLargeObject::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;
|
||||
int PgLargeObject::Unlink()
|
||||
{
|
||||
// Unlink the object
|
||||
int temp = lo_unlink(pgConn, pgObject);
|
||||
|
||||
// Initialize the large object upon success
|
||||
if (!temp) {
|
||||
Close();
|
||||
Init();
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// default destructor -- closes large object
|
||||
PGlobj::~PGlobj() {
|
||||
if (fd >= 0)
|
||||
lo_close(conn, fd);
|
||||
|
||||
// Return the status
|
||||
return temp;
|
||||
}
|
||||
|
64
src/interfaces/libpq++/pglobject.h
Normal file
64
src/interfaces/libpq++/pglobject.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* 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
|
65
src/interfaces/libpq++/pgtransdb.cc
Normal file
65
src/interfaces/libpq++/pgtransdb.cc
Normal file
@ -0,0 +1,65 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* 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()
|
48
src/interfaces/libpq++/pgtransdb.h
Normal file
48
src/interfaces/libpq++/pgtransdb.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* 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
|
Loading…
x
Reference in New Issue
Block a user