1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-09 06:21:09 +03:00

Bring in Leo's <lsh@lubrizol.com> massive changes to libpq++

This commit is contained in:
Marc G. Fournier
1997-02-13 10:01:05 +00:00
parent d62267c707
commit eacd0fd938
25 changed files with 1335 additions and 606 deletions

View File

@@ -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)

View File

@@ -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()

View File

@@ -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");
}

View File

@@ -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");
}

View File

@@ -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;
}

View File

@@ -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;
}

View 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];

View 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);
}
}

View 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);

View 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");
}

View File

@@ -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 ???
}