1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-22 12:22:45 +03:00

Here's a version of my suggested diffs transplanted to 7.1 beta 5. I'm

still looking at the best way to integrate Tom Vijlbrief's fixes
(insofar as they're still needed); would 7.2 be a suitable time for
incompatible API changes?


Jeroen


Changes:

(*) Introduced bool, true, false (replacing some int, 1, 0)
(*) Made some member functions const
(*) Documented GetIsNull()
(*) Marked DisplayTuples() and PrintTuples() as obsolescent; fixed possible
    portability problem (assumed that NULL pointer equals all-zero bit pattern)
(*) PrintTuples(): renamed width parameter to fillAlign to conform with other
    usage; fixed memory leak and compile issue w.r.t. field separator (should
    also slightly improve performance)
(*) Fixed some minor compilation issues
(*) Moved "using namespace std;" out of headers, where they didn't belong; used
    new (temporary) preprocessor macro PGSTD to do this
(*) Made ToString() static, removed unneeded memset(), made buffer size adapt
    to sizeof(int)
(*) Made some constructors explicit
(*) Changed some const std::string & parameters to plain std::string
(*) Marked PgCursor::Cursor(std::string) as obsolescent (setter with same name
    as getter--bad style)
(*) Renamed some paramaters previously named "string"
(*) Introduced size_type typedef for number of tuples in result set
(*) PgTransaction now supports re-opening after closing, and aborts if not
    explicitly committed prior to destruction

J. T. Vermeulen
This commit is contained in:
Bruce Momjian
2001-05-09 17:29:10 +00:00
parent c8db55f78a
commit a79b698adb
18 changed files with 338 additions and 146 deletions

View File

@@ -22,12 +22,12 @@ INSERT INTO TBL1 values (10);
#include "libpq++.h"
#include <stdlib.h>
main()
int main()
{
// Begin, by connecting to the backend using hardwired constants
// and a test database created by the user prior to the invokation
// of this test program.
char* dbName = "dbname=template1";
const char* dbName = "dbname=template1";
PgDatabase data(dbName);
// Check to see that the backend connection was successfully made

View File

@@ -34,12 +34,12 @@ extern "C" {
#include "utils/geo_decls.h" // for the POLYGON type
}
main()
int 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 = "dbname=template1"; // change this to the name of your test database
const char* dbName = "dbname=template1"; // change this to the name of your test database
PgCursor data(dbName, "mycursor");
// check to see that the backend connection was successfully made

View File

@@ -8,12 +8,12 @@
#include "libpq++.h"
#include <stdlib.h>
main()
int 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 = "dbname=template1";
const char* dbName = "dbname=template1";
PgTransaction data(dbName);
// check to see that the backend connection was successfully made

View File

@@ -10,13 +10,15 @@
* Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pgconnection.cc,v 1.10 2000/07/27 19:44:01 momjian Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pgconnection.cc,v 1.11 2001/05/09 17:29:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include "pgconnection.h"
using namespace std;
// ****************************************************************
//
@@ -25,14 +27,14 @@
// ****************************************************************
// default constructor -- initialize everything
PgConnection::PgConnection()
: pgConn(NULL), pgResult(NULL), pgCloseConnection(0)
: pgConn(NULL), pgResult(NULL), pgCloseConnection(false)
{}
// constructor -- checks environment variable for database name
// Now uses PQconnectdb
PgConnection::PgConnection(const char* conninfo)
: pgConn(NULL), pgResult(NULL), pgCloseConnection(1)
: pgConn(NULL), pgResult(NULL), pgCloseConnection(true)
{
// Connect to the database
@@ -60,14 +62,14 @@ void PgConnection::CloseConnection()
pgResult=NULL;
if(pgConn) PQfinish(pgConn);
pgConn=NULL;
pgCloseConnection=0;
pgCloseConnection=false;
}
}
// PgConnection::connect
// establish a connection to a backend
ConnStatusType PgConnection::Connect(const char* conninfo)
ConnStatusType PgConnection::Connect(const char conninfo[])
{
// if the connection is open, close it first
CloseConnection();
@@ -76,14 +78,14 @@ ConnStatusType PgConnection::Connect(const char* conninfo)
pgConn = PQconnectdb(conninfo);
// Now we have a connection we must close (even if it's bad!)
pgCloseConnection = 1;
pgCloseConnection = true;
// Status will return either CONNECTION_OK or CONNECTION_BAD
return Status();
}
// PgConnection::status -- return connection or result status
ConnStatusType PgConnection::Status()
ConnStatusType PgConnection::Status() const
{
return PQstatus(pgConn);
}
@@ -131,27 +133,26 @@ PGnotify* PgConnection::Notifies()
// From Integer To String Conversion Function
string PgConnection::IntToString(int n)
{
char buffer [32];
memset(buffer, 0, sizeof(buffer));
char buffer [4*sizeof(n) + 2];
sprintf(buffer, "%d", n);
return buffer;
}
int PgConnection::ConnectionBad()
bool PgConnection::ConnectionBad() const
{
return Status() == CONNECTION_BAD;
}
const char* PgConnection::ErrorMessage()
const char* PgConnection::ErrorMessage() const
{
return (const char *)PQerrorMessage(pgConn);
}
const char* PgConnection::DBName()
const char* PgConnection::DBName() const
{
return (const char *)PQdb(pgConn);
}

View File

@@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pgconnection.h,v 1.10 2001/02/10 02:31:30 tgl Exp $
* $Id: pgconnection.h,v 1.11 2001/05/09 17:29:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -43,7 +43,9 @@ extern "C" {
}
#ifdef HAVE_NAMESPACE_STD
using namespace std;
#define PGSTD std::
#else
#define PGSTD
#endif
@@ -57,21 +59,21 @@ using namespace std;
// derived from this class to obtain the connection interface.
class PgConnection {
protected:
PGconn* pgConn; // Connection Structure
PGconn* pgConn; // Connection Structure
PGresult* pgResult; // Current Query Result
int pgCloseConnection; // TRUE if connection should be closed by destructor
bool pgCloseConnection; // true if connection should be closed by destructor
public:
PgConnection(const char* conninfo); // use reasonable & environment defaults
explicit PgConnection(const char* conninfo); // use reasonable & environment defaults
virtual ~PgConnection(); // close connection and clean up
// Connection status and error messages
ConnStatusType Status();
int ConnectionBad();
const char* ErrorMessage();
ConnStatusType Status() const;
bool ConnectionBad() const;
const char* ErrorMessage() const;
// returns the database name of the connection
const char* DBName();
const char* DBName() const;
// Query Execution interface
ExecStatusType Exec(const char* query); // send a query to the backend
@@ -82,7 +84,7 @@ public:
protected:
ConnStatusType Connect(const char* conninfo);
void CloseConnection();
string IntToString(int);
static PGSTD string IntToString(int);
// Default constructor is only available to subclasses
PgConnection();
@@ -93,4 +95,10 @@ private:
PgConnection& operator= (const PgConnection&);
};
#ifdef HAVE_NAMESPACE_STD
#undef PGSTD
#endif
#endif // PGCONNECTION_H

View File

@@ -10,13 +10,17 @@
* Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pgcursordb.cc,v 1.4 1999/06/01 02:43:37 momjian Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pgcursordb.cc,v 1.5 2001/05/09 17:29:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include "pgcursordb.h"
using namespace std;
// ****************************************************************
//
// PgCursor Implementation
@@ -48,7 +52,7 @@ PgCursor::~PgCursor()
//
// ****************************************************************
// Declare a cursor: name has already been supplied in the constructor
int PgCursor::Declare(const string& query, int binary)
int PgCursor::Declare(string query, bool binary)
{
string cmd = "DECLARE " + pgCursor;
if ( binary )
@@ -70,7 +74,7 @@ int PgCursor::Fetch(unsigned num, const char* dir)
} // End Fetch()
// Create and execute the actual fetch command with the given arguments
int PgCursor::Fetch(const string& num, const string& dir)
int PgCursor::Fetch(string num, string dir)
{
string cmd = "FETCH " + dir + " " + num + " IN " + pgCursor;
return ExecTuplesOk( cmd.c_str() );

View File

@@ -14,7 +14,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: pgcursordb.h,v 1.6 2001/01/24 19:43:32 momjian Exp $
* $Id: pgcursordb.h,v 1.7 2001/05/09 17:29:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -26,6 +26,12 @@
#include "pgtransdb.h"
#endif
#ifdef HAVE_NAMESPACE_STD
#define PGSTD std::
#else
#define PGSTD
#endif
// ****************************************************************
//
@@ -44,20 +50,22 @@ public:
~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 Declare(PGSTD string query, bool binary=false); // 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; }
// TODO: Setter has same name as getter--ouch!
// OBSOLESCENT
void Cursor(PGSTD string cursor) { pgCursor = cursor; }
protected:
int Fetch(const string& num, const string& dir);
int Fetch(PGSTD string num, PGSTD string dir);
protected:
string pgCursor;
PGSTD string pgCursor;
protected:
PgCursor() : PgTransaction() {} // Do not connect
@@ -69,4 +77,10 @@ private:
PgCursor& operator= (const PgCursor&);
}; // End PgCursor Class Declaration
#ifdef HAVE_NAMESPACE_STD
#undef PGSTD
#endif
#endif // PGCURSORDB_H

View File

@@ -10,7 +10,7 @@
* Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pgdatabase.cc,v 1.9 2000/01/29 16:58:52 petere Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pgdatabase.cc,v 1.10 2001/05/09 17:29:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,151 +18,155 @@
#include "pgdatabase.h"
void PgDatabase::DisplayTuples(FILE *out, int fillAlign,
const char* fieldSep, int printHeader,
int /* quiet */)
using namespace std;
// OBSOLESCENT (uses PQprint(), which is no longer being maintained)
void PgDatabase::DisplayTuples(FILE *out,
bool fillAlign,
const char* fieldSep,
bool printHeader,
bool /* quiet */) const
{
PQprintOpt po;
memset(&po,0,sizeof(po));
po.align = fillAlign;
po.fieldSep = (char *)fieldSep;
po.header = printHeader;
po.align = fillAlign;
po.standard = po.html3 = po.expanded = po.pager = 0;
po.fieldSep = const_cast<char *>(fieldSep);
po.tableOpt = po.caption = 0;
po.fieldName = 0;
PQprint(out,pgResult,&po);
}
void PgDatabase::PrintTuples(FILE *out, int printAttName, int terseOutput,
int width)
// OBSOLESCENT (uses PQprint(), which is no longer being maintained)
void PgDatabase::PrintTuples(FILE *out,
bool printAttName,
bool terseOutput,
bool fillAlign) const
{
PQprintOpt po;
memset(&po,0,sizeof(po));
po.align = width;
if(terseOutput) po.fieldSep = strdup("|");
else po.fieldSep = "";
po.header = printAttName;
po.align = fillAlign;
po.standard = po.html3 = po.expanded = po.pager = 0;
po.tableOpt = po.caption = 0;
po.fieldSep = const_cast<char *>(terseOutput ? "" : "|");
po.fieldName = 0;
PQprint(out,pgResult,&po);
}
int PgDatabase::Tuples()
int PgDatabase::Tuples() const
{
return PQntuples(pgResult);
}
int PgDatabase::CmdTuples()
int PgDatabase::CmdTuples() const
{
char *a;
a = (char *)PQcmdTuples(pgResult);
if(!a[0]) return -1;
return atoi(a);
const char *a = PQcmdTuples(pgResult);
return a[0] ? atoi(a) : -1;
}
// TODO: Make const?
int PgDatabase::Fields()
{
return PQnfields(pgResult);
}
const char* PgDatabase::FieldName(int field_num)
const char* PgDatabase::FieldName(int field_num) const
{
return PQfname(pgResult, field_num);
}
int PgDatabase::FieldNum(const char* field_name)
int PgDatabase::FieldNum(const char* field_name) const
{
return PQfnumber(pgResult, field_name);
}
Oid PgDatabase::FieldType(int field_num)
Oid PgDatabase::FieldType(int field_num) const
{
return PQftype(pgResult, field_num);
}
Oid PgDatabase::FieldType(const char* field_name)
Oid PgDatabase::FieldType(const char* field_name) const
{
return PQftype(pgResult, FieldNum(field_name));
}
short PgDatabase::FieldSize(int field_num)
short PgDatabase::FieldSize(int field_num) const
{
return PQfsize(pgResult, field_num);
}
short PgDatabase::FieldSize(const char* field_name)
short PgDatabase::FieldSize(const char* field_name) const
{
return PQfsize(pgResult, FieldNum(field_name));
}
const char* PgDatabase::GetValue(int tup_num, int field_num)
const char* PgDatabase::GetValue(int tup_num, int field_num) const
{
return PQgetvalue(pgResult, tup_num, field_num);
}
const char* PgDatabase::GetValue(int tup_num, const char* field_name)
const char* PgDatabase::GetValue(int tup_num, const char* field_name) const
{
return PQgetvalue(pgResult, tup_num, FieldNum(field_name));
}
int PgDatabase::GetIsNull(int tup_num, int field_num)
bool PgDatabase::GetIsNull(int tup_num, int field_num) const
{
return PQgetisnull(pgResult, tup_num, field_num);
}
int PgDatabase::GetIsNull(int tup_num, const char* field_name)
bool PgDatabase::GetIsNull(int tup_num, const char* field_name) const
{
return PQgetisnull(pgResult, tup_num, FieldNum(field_name));
}
int PgDatabase::GetLength(int tup_num, int field_num)
int PgDatabase::GetLength(int tup_num, int field_num) const
{
return PQgetlength(pgResult, tup_num, field_num);
}
int PgDatabase::GetLength(int tup_num, const char* field_name)
int PgDatabase::GetLength(int tup_num, const char* field_name) const
{
return PQgetlength(pgResult, tup_num, FieldNum(field_name));
}
int PgDatabase::GetLine(char* string, int length)
int PgDatabase::GetLine(char str[], int length)
{
return PQgetline(pgConn, string, length);
return PQgetline(pgConn, str, length);
}
void PgDatabase::PutLine(const char* string)
void PgDatabase::PutLine(const char str[])
{
PQputline(pgConn, string);
PQputline(pgConn, str);
}
const char* PgDatabase::OidStatus()
const char* PgDatabase::OidStatus() const
{
return PQoidStatus(pgResult);
}

View File

@@ -14,7 +14,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: pgdatabase.h,v 1.9 2001/01/24 19:43:32 momjian Exp $
* $Id: pgdatabase.h,v 1.10 2001/05/09 17:29:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -37,35 +37,39 @@
class PgDatabase : public PgConnection {
public:
// connect to the database with conninfo
PgDatabase(const char* conninfo) : PgConnection(conninfo) {}
explicit PgDatabase(const char* conninfo) : PgConnection(conninfo) {}
~PgDatabase() {} // close connection and clean up
typedef int size_type;
// query result access
int Tuples();
int CmdTuples();
size_type Tuples() const;
size_type CmdTuples() const;
int Fields();
const char* FieldName(int field_num);
int FieldNum(const char* field_name);
Oid FieldType(int field_num);
Oid FieldType(const char* field_name);
short FieldSize(int field_num);
short FieldSize(const char* field_name);
const char* GetValue(int tup_num, int field_num);
const char* GetValue(int tup_num, const char* field_name);
int GetIsNull(int tup_num, int field_num);
int GetIsNull(int tup_num, const char* field_name);
int GetLength(int tup_num, int field_num);
int GetLength(int tup_num, const char* field_name);
void DisplayTuples(FILE *out = 0, int fillAlign = 1,
const char* fieldSep = "|",int printHeader = 1, int quiet = 0) ;
void PrintTuples(FILE *out = 0, int printAttName = 1,
int terseOutput = 0, int width = 0) ;
const char* FieldName(int field_num) const;
int FieldNum(const char* field_name) const;
Oid FieldType(int field_num) const;
Oid FieldType(const char* field_name) const;
short FieldSize(int field_num) const;
short FieldSize(const char* field_name) const;
const char* GetValue(size_type tup_num, int field_num) const;
const char* GetValue(size_type tup_num, const char* field_name) const;
bool GetIsNull(size_type tup_num, int field_num) const;
bool GetIsNull(size_type tup_num, const char* field_name) const;
int GetLength(size_type tup_num, int field_num) const;
int GetLength(size_type tup_num, const char* field_name) const;
// OBSOLESCENT (use PQprint()):
void DisplayTuples(FILE *out=0, bool fillAlign=true,
const char* fieldSep="|", bool printHeader=true, bool quiet=false) const;
void PrintTuples(FILE *out=0, bool printAttName=true,
bool terseOutput=false, bool fillAlign=false) const;
// copy command related access
int GetLine(char* string, int length);
void PutLine(const char* string);
const char* OidStatus();
int GetLine(char str[], int length);
void PutLine(const char str[]);
const char* OidStatus() const;
int EndCopy();
protected:

View File

@@ -10,7 +10,7 @@
* Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pglobject.cc,v 1.6 2000/04/22 22:39:15 tgl Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pglobject.cc,v 1.7 2001/05/09 17:29:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,6 +21,10 @@ extern "C" {
#include "libpq/libpq-fs.h"
}
using namespace std;
// ****************************************************************
//
// PgLargeObject Implementation
@@ -142,7 +146,7 @@ int PgLargeObject::LSeek(int offset, int whence)
}
int PgLargeObject::Tell()
int PgLargeObject::Tell() const
{
return lo_tell(pgConn, pgFd);
}
@@ -160,7 +164,7 @@ int PgLargeObject::Export(const char* filename)
}
string PgLargeObject::Status()
string PgLargeObject::Status() const
{
return loStatus;
}

View File

@@ -11,7 +11,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: pglobject.h,v 1.6 2001/01/24 19:43:32 momjian Exp $
* $Id: pglobject.h,v 1.7 2001/05/09 17:29:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,6 +23,12 @@
#include "pgconnection.h"
#endif
#ifdef HAVE_NAMESPACE_STD
#define PGSTD std::
#else
#define PGSTD
#endif
// ****************************************************************
//
@@ -33,12 +39,12 @@ class PgLargeObject : public PgConnection {
private:
int pgFd;
Oid pgObject;
string loStatus;
PGSTD string loStatus;
void Init(Oid lobjId = 0);
public:
PgLargeObject(const char* conninfo = 0); // use reasonable defaults and create large object
PgLargeObject(Oid lobjId, const char* conninfo = 0); // use reasonable defaults and open large object
explicit PgLargeObject(const char* conninfo = 0); // use reasonable defaults and create large object
explicit PgLargeObject(Oid lobjId, const char* conninfo = 0); // use reasonable defaults and open large object
~PgLargeObject(); // close connection and clean up
void Create();
@@ -47,12 +53,12 @@ public:
int Read(char* buf, int len);
int Write(const char* buf, int len);
int LSeek(int offset, int whence);
int Tell();
int Tell() const;
int Unlink();
Oid LOid();
Oid Import(const char* filename);
int Export(const char* filename);
string Status();
PGSTD string Status() const;
private:
// We don't support copying of PgLargeObject objects,
@@ -61,4 +67,10 @@ private:
PgLargeObject& operator= (const PgLargeObject&);
};
#ifdef HAVE_NAMESPACE_STD
#undef PGSTD
#endif
#endif // PGLOBJECT_H

View File

@@ -10,7 +10,7 @@
* Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pgtransdb.cc,v 1.3 1999/05/30 15:17:58 tgl Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pgtransdb.cc,v 1.4 2001/05/09 17:29:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -25,7 +25,8 @@
// Make a connection to the specified database with default environment
// See PQconnectdb() for conninfo usage.
PgTransaction::PgTransaction(const char* conninfo)
: PgDatabase(conninfo)
: PgDatabase(conninfo),
pgCommitted(true)
{
BeginTransaction();
}
@@ -33,17 +34,20 @@ PgTransaction::PgTransaction(const char* conninfo)
// Destructor: End the transaction block
PgTransaction::~PgTransaction()
{
EndTransaction();
if (!pgCommitted) Exec("ABORT");
}
// Begin the transaction block
ExecStatusType PgTransaction::BeginTransaction()
{
pgCommitted = false;
return Exec("BEGIN");
} // End BeginTransaction()
// Begin the transaction block
ExecStatusType PgTransaction::EndTransaction()
{
pgCommitted = true;
return Exec("END");
} // End EndTransaction()

View File

@@ -14,7 +14,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: pgtransdb.h,v 1.6 2001/01/24 19:43:32 momjian Exp $
* $Id: pgtransdb.h,v 1.7 2001/05/09 17:29:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -36,9 +36,9 @@
// the object is destroyed.
class PgTransaction : public PgDatabase {
public:
PgTransaction(const char* conninfo); // use reasonable & environment defaults
explicit PgTransaction(const char* conninfo); // use reasonable & environment defaults
// connect to the database with given environment and database name
// PgTransaction(const PgConnection&);
// explicit PgTransaction(const PgConnection&);
~PgTransaction(); // close connection and clean up
protected:
@@ -46,9 +46,11 @@ protected:
ExecStatusType EndTransaction();
protected:
PgTransaction() : PgDatabase() {} // Do not connect
PgTransaction() : PgDatabase(), pgCommitted(true) {} // Do not connect
private:
bool pgCommitted;
// We don't support copying of PgTransaction objects,
// so make copy constructor and assignment op private.
PgTransaction(const PgTransaction&);