Thread: libpq++: combined patches based on 7.1b5

libpq++: combined patches based on 7.1b5

From
"J. T. Vermeulen"
Date:
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
pointerequals all-zero bit pattern)
 
(*) PrintTuples(): renamed width parameter to fillAlign to conform with other    usage; fixed memory leak and compile
issuew.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
PGSTDto 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


Diffs:


diff -r -u postgresql-7.1beta5/doc/src/sgml/libpq++.sgml postgresql-7.1beta5-jtv/doc/src/sgml/libpq++.sgml
--- postgresql-7.1beta5/doc/src/sgml/libpq++.sgml    Mon Jan 29 03:53:33 2001
+++ postgresql-7.1beta5-jtv/doc/src/sgml/libpq++.sgml    Mon Mar 12 16:39:06 2001
@@ -225,9 +225,9 @@       returns whether or not the connection to the backend server succeeded or       failed.
<synopsis>
 
-    int PgConnection::ConnectionBad()
+    bool PgConnection::ConnectionBad() const       </synopsis>
-       Returns TRUE if the connection failed.
+       Returns true if the connection failed.      </para>     </listitem>     <listitem>
@@ -355,7 +355,7 @@       <function>Tuples</function>       Returns the number of tuples (rows) in the query result.
   <synopsis>
 
-    int PgDatabase::Tuples()
+    int PgDatabase::Tuples() const       </synopsis>      </para>     </listitem>
@@ -365,7 +365,7 @@              Returns the number of rows affected after an INSERT, UPDATE or DELETE.
Ifthe command was anything else, it returns -1.        <synopsis>
 
-      int PgDatabase::CmdTuples()
+      int PgDatabase::CmdTuples() const       </synopsis>      </para>     </listitem>
@@ -384,7 +384,7 @@       Returns the field (attribute) name associated with the given field index.        Field
indicesstart at 0.        <synopsis>
 
-    const char *PgDatabase::FieldName(int field_num)
+    const char *PgDatabase::FieldName(int field_num) const       </synopsis>      </para>     </listitem>
@@ -394,7 +394,7 @@       PQfnumber Returns the field (attribute) index associated with        the given field name.
   <synopsis>
 
-    int PgDatabase::FieldNum(const char* field_name)
+    int PgDatabase::FieldNum(const char* field_name) const       </synopsis>       -1 is returned if the given name
doesnot match any field.      </para>
 
@@ -406,7 +406,7 @@       integer returned is an internal coding of the type. Field indices       start at 0.
<synopsis>
-    Oid PgDatabase::FieldType(int field_num)
+    Oid PgDatabase::FieldType(int field_num) const       </synopsis>      </para>     </listitem>
@@ -417,7 +417,7 @@       integer returned is an internal coding of the type. Field indices       start at 0.
<synopsis>
-    Oid PgDatabase::FieldType(const char* field_name)
+    Oid PgDatabase::FieldType(const char* field_name) const       </synopsis>      </para>     </listitem>
@@ -427,7 +427,7 @@       Returns the size in bytes of the field associated with the given        field index. Field
indicesstart at 0.        <synopsis>
 
-    short PgDatabase::FieldSize(int field_num)
+    short PgDatabase::FieldSize(int field_num) const       </synopsis>       Returns the space allocated for this
fieldin a database tuple given       the field number. In other words the size of the server's binary 
 
@@ -441,7 +441,7 @@       Returns the size in bytes of the field associated with the given        field index. Field
indicesstart at 0.        <synopsis>
 
-    short PgDatabase::FieldSize(const char *field_name)
+    short PgDatabase::FieldSize(const char *field_name) const       </synopsis>       Returns the space allocated for
thisfield in a database tuple given       the field name. In other words the size of the server's binary 
 
@@ -455,7 +455,7 @@       Returns a single field (attribute) value of one tuple of a PGresult.        Tuple and field
indicesstart at 0.        <synopsis>
 
-    const char *PgDatabase::GetValue(int tup_num, int field_num)
+    const char *PgDatabase::GetValue(int tup_num, int field_num) const       </synopsis>       For most queries, the
valuereturned by GetValue is a null-terminated        ASCII string representation of the attribute value. But if
BinaryTuples()
 
@@ -475,7 +475,7 @@       Returns a single field (attribute) value of one tuple of a PGresult.        Tuple and field
indicesstart at 0.        <synopsis>
 
-    const char *PgDatabase::GetValue(int tup_num, const char *field_name)
+    const char *PgDatabase::GetValue(int tup_num, const char *field_name) const       </synopsis>       For most
queries,the value returned by GetValue is a null-terminated        ASCII string representation of the attribute value.
Butif BinaryTuples() 
 
@@ -491,11 +491,33 @@     </listitem>     <listitem>      <para>
+       <function>GetIsNull</function>
+       Returns whether a field has the null value.
+       <synopsis>
+        bool GetIsNull(int tup_num, int field_num) const
+       </synopsis>
+       Note that GetValue will return the empty string for null fields, not
+       the NULL pointer.
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+       <function>GetIsNull</function>
+       Returns whether a field has the null value.
+       <synopsis>
+        bool GetIsNull(int tup_num, const char *field_name) const
+       </synopsis>
+       Note that GetValue will return the empty string for null fields, not
+       the NULL pointer.
+      </para>
+     </listitem>
+     <listitem>
+      <para>       <function>GetLength</function>       Returns the length of a field (attribute) in bytes. Tuple and
field       indices start at 0.        <synopsis>
 
-    int PgDatabase::GetLength(int tup_num, int field_num)
+    int PgDatabase::GetLength(int tup_num, int field_num) const       </synopsis>       This is the actual data length
forthe particular data value, that        is the size of the object pointed to by GetValue. Note that for
 
@@ -509,7 +531,7 @@       Returns the length of a field (attribute) in bytes. Tuple and field        indices start at
0.       <synopsis>
 
-    int PgDatabase::GetLength(int tup_num, const char* field_name)
+    int PgDatabase::GetLength(int tup_num, const char* field_name) const       </synopsis>       This is the actual
datalength for the particular data value, that        is the size of the object pointed to by GetValue. Note that for
 
@@ -520,22 +542,22 @@     <listitem>      <para>       <function>DisplayTuples</function>
-       Prints out all the tuples and, optionally, the attribute names to the 
+       OBSOLESCENT: Prints out all the tuples and, optionally, the attribute names to the        specified output
stream.       <synopsis>
 
-    void PgDatabase::DisplayTuples(FILE *out = 0, int fillAlign = 1, 
-    const char* fieldSep = "|",int printHeader = 1, int quiet = 0)
+    void PgDatabase::DisplayTuples(FILE *out = 0, bool fillAlign = true, 
+    const char* fieldSep = "|",bool printHeader = true, bool quiet = false) const       </synopsis>      </para>
</listitem>    <listitem>      <para>       <function>PrintTuples</function>
 
-       Prints out all the tuples and, optionally, the attribute names to the 
+       OBSOLESCENT: Prints out all the tuples and, optionally, the attribute names to the        specified output
stream.       <synopsis>
 
-    void PgDatabase::PrintTuples(FILE *out = 0, int printAttName = 1, 
-    int terseOutput = 0, int width = 0) 
+    void PgDatabase::PrintTuples(FILE *out = 0, bool printAttName = true, 
+    bool terseOutput = false, bool fillAlign = false) const       </synopsis>      </para>     </listitem>
@@ -559,7 +581,7 @@      <para>       <function>OidStatus</function>       <synopsis>
-    const char *PgDatabase::OidStatus()
+    const char *PgDatabase::OidStatus() const       </synopsis>      </para>     </listitem>
@@ -613,8 +635,8 @@    to see if any notification data is currently available from the backend.
<function>PgDatabase::Notifies</function>   returns the notification from a list of unhandled notifications from the
 
-    backend. The function eturns NULL if there is no pending notifications from the
-    backend.   
+    backend. The function returns NULL if there are no pending notifications 
+    from the backend.       <function>PgDatabase::Notifies</function>    behaves like the popping of a stack.  Once a
notificationis returned    from <function>PgDatabase::Notifies</function>,
 
diff -r -u postgresql-7.1beta5/src/interfaces/libpq++/examples/testlibpq4.cc
postgresql-7.1beta5-jtv/src/interfaces/libpq++/examples/testlibpq4.cc
--- postgresql-7.1beta5/src/interfaces/libpq++/examples/testlibpq4.cc    Mon May 29 23:25:04 2000
+++ postgresql-7.1beta5-jtv/src/interfaces/libpq++/examples/testlibpq4.cc    Thu Mar  8 00:24:32 2001
@@ -22,12 +22,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
userprior 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
successfullymade
 
diff -r -u postgresql-7.1beta5/src/interfaces/libpq++/examples/testlibpq5.cc
postgresql-7.1beta5-jtv/src/interfaces/libpq++/examples/testlibpq5.cc
--- postgresql-7.1beta5/src/interfaces/libpq++/examples/testlibpq5.cc    Mon May 29 23:25:04 2000
+++ postgresql-7.1beta5-jtv/src/interfaces/libpq++/examples/testlibpq5.cc    Thu Mar  8 00:24:20 2001
@@ -34,12 +34,12 @@#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
userprior 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
 
diff -r -u postgresql-7.1beta5/src/interfaces/libpq++/examples/testlibpq6.cc
postgresql-7.1beta5-jtv/src/interfaces/libpq++/examples/testlibpq6.cc
--- postgresql-7.1beta5/src/interfaces/libpq++/examples/testlibpq6.cc    Mon May 29 23:25:04 2000
+++ postgresql-7.1beta5-jtv/src/interfaces/libpq++/examples/testlibpq6.cc    Thu Mar  8 00:24:04 2001
@@ -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
userprior 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
wassuccessfully made
 
diff -r -u postgresql-7.1beta5/src/interfaces/libpq++/pgconnection.cc
postgresql-7.1beta5-jtv/src/interfaces/libpq++/pgconnection.cc
--- postgresql-7.1beta5/src/interfaces/libpq++/pgconnection.cc    Thu Jul 27 21:44:01 2000
+++ postgresql-7.1beta5-jtv/src/interfaces/libpq++/pgconnection.cc    Thu Mar  8 01:19:47 2001
@@ -17,6 +17,8 @@#include "pgconnection.h"
+using namespace std;
+// ****************************************************************//
@@ -25,14 +27,14 @@// ****************************************************************// default constructor --
initializeeverythingPgConnection::PgConnection()
 
-    : pgConn(NULL), pgResult(NULL), pgCloseConnection(0)
+    : pgConn(NULL), pgResult(NULL), pgCloseConnection(false){}// constructor -- checks environment variable for
databasename// Now uses PQconnectdbPgConnection::PgConnection(const char* conninfo)
 
-    : pgConn(NULL), pgResult(NULL), pgCloseConnection(1)
+    : pgConn(NULL), pgResult(NULL), pgCloseConnection(true){      // Connect to the database
@@ -60,14 +62,14 @@       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 @@  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 @@// From Integer To String Conversion Functionstring 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); }
diff -r -u postgresql-7.1beta5/src/interfaces/libpq++/pgconnection.h
postgresql-7.1beta5-jtv/src/interfaces/libpq++/pgconnection.h
--- postgresql-7.1beta5/src/interfaces/libpq++/pgconnection.h    Fri Feb 23 19:12:26 2001
+++ postgresql-7.1beta5-jtv/src/interfaces/libpq++/pgconnection.h    Thu Mar  8 01:20:58 2001
@@ -43,7 +43,9 @@}#ifdef HAVE_NAMESPACE_STD
-using namespace std;
+#define PGSTD std::
+#else
+#define PGSTD#endif
@@ -57,21 +59,21 @@// 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
queryto the backend
 
@@ -82,7 +84,7 @@protected:   ConnStatusType Connect(const char* conninfo);   void CloseConnection();
-   string IntToString(int);
+   static PGSTD string IntToString(int);   // Default constructor is only available to subclasses   PgConnection();
@@ -92,5 +94,11 @@   PgConnection(const PgConnection&);   PgConnection& operator= (const PgConnection&);};
+
+
+#ifdef HAVE_NAMESPACE_STD
+#undef PGSTD
+#endif
+#endif    // PGCONNECTION_H
diff -r -u postgresql-7.1beta5/src/interfaces/libpq++/pgcursordb.cc
postgresql-7.1beta5-jtv/src/interfaces/libpq++/pgcursordb.cc
--- postgresql-7.1beta5/src/interfaces/libpq++/pgcursordb.cc    Tue Jun  1 04:43:37 1999
+++ postgresql-7.1beta5-jtv/src/interfaces/libpq++/pgcursordb.cc    Thu Mar  8 00:36:35 2001
@@ -17,6 +17,10 @@ #include "pgcursordb.h" 
+
+using namespace std;
+
+// ****************************************************************//// PgCursor Implementation
@@ -48,7 +52,7 @@//// ****************************************************************// Declare a cursor: name has
alreadybeen 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 @@} // 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() );
 
diff -r -u postgresql-7.1beta5/src/interfaces/libpq++/pgcursordb.h
postgresql-7.1beta5-jtv/src/interfaces/libpq++/pgcursordb.h
--- postgresql-7.1beta5/src/interfaces/libpq++/pgcursordb.h    Mon Jan 29 03:53:57 2001
+++ postgresql-7.1beta5-jtv/src/interfaces/libpq++/pgcursordb.h    Mon Mar 12 17:24:22 2001
@@ -26,6 +26,12 @@#include "pgtransdb.h"#endif
+#ifdef HAVE_NAMESPACE_STD
+#define PGSTD std::
+#else
+#define PGSTD
+#endif
+// ****************************************************************//
@@ -44,20 +50,22 @@  ~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 @@   PgCursor& operator= (const PgCursor&);}; // End PgCursor Class Declaration
+
+#ifdef HAVE_NAMESPACE_STD
+#undef PGSTD
+#endif
+#endif    // PGCURSORDB_H
+
diff -r -u postgresql-7.1beta5/src/interfaces/libpq++/pgdatabase.cc
postgresql-7.1beta5-jtv/src/interfaces/libpq++/pgdatabase.cc
--- postgresql-7.1beta5/src/interfaces/libpq++/pgdatabase.cc    Sat Jan 29 17:58:52 2000
+++ postgresql-7.1beta5-jtv/src/interfaces/libpq++/pgdatabase.cc    Thu Mar  8 01:24:43 2001
@@ -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); }
diff -r -u postgresql-7.1beta5/src/interfaces/libpq++/pgdatabase.h
postgresql-7.1beta5-jtv/src/interfaces/libpq++/pgdatabase.h
--- postgresql-7.1beta5/src/interfaces/libpq++/pgdatabase.h    Mon Jan 29 03:53:57 2001
+++ postgresql-7.1beta5-jtv/src/interfaces/libpq++/pgdatabase.h    Thu Mar  8 01:25:40 2001
@@ -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
connectionand 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:
diff -r -u postgresql-7.1beta5/src/interfaces/libpq++/pglobject.cc
postgresql-7.1beta5-jtv/src/interfaces/libpq++/pglobject.cc
--- postgresql-7.1beta5/src/interfaces/libpq++/pglobject.cc    Sun Apr 23 00:39:15 2000
+++ postgresql-7.1beta5-jtv/src/interfaces/libpq++/pglobject.cc    Thu Mar  8 01:26:09 2001
@@ -21,6 +21,10 @@#include "libpq/libpq-fs.h"}
+
+using namespace std;
+
+// ****************************************************************//// PgLargeObject Implementation
@@ -142,7 +146,7 @@}
-int PgLargeObject::Tell()
+int PgLargeObject::Tell() const{   return lo_tell(pgConn, pgFd); }
@@ -160,7 +164,7 @@}
-string PgLargeObject::Status() 
+string PgLargeObject::Status() const{   return loStatus; }
diff -r -u postgresql-7.1beta5/src/interfaces/libpq++/pglobject.h
postgresql-7.1beta5-jtv/src/interfaces/libpq++/pglobject.h
--- postgresql-7.1beta5/src/interfaces/libpq++/pglobject.h    Mon Jan 29 03:53:57 2001
+++ postgresql-7.1beta5-jtv/src/interfaces/libpq++/pglobject.h    Thu Mar  8 00:57:00 2001
@@ -23,6 +23,12 @@#include "pgconnection.h"#endif
+#ifdef HAVE_NAMESPACE_STD
+#define PGSTD std::
+#else
+#define PGSTD
+#endif
+// ****************************************************************//
@@ -33,12 +39,12 @@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 @@  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,
@@ -60,5 +66,11 @@   PgLargeObject(const PgLargeObject&);   PgLargeObject& operator= (const PgLargeObject&);};
+
+
+#ifdef HAVE_NAMESPACE_STD
+#undef PGSTD
+#endif
+#endif    // PGLOBJECT_H
diff -r -u postgresql-7.1beta5/src/interfaces/libpq++/pgtransdb.cc
postgresql-7.1beta5-jtv/src/interfaces/libpq++/pgtransdb.cc
--- postgresql-7.1beta5/src/interfaces/libpq++/pgtransdb.cc    Sun May 30 17:17:58 1999
+++ postgresql-7.1beta5-jtv/src/interfaces/libpq++/pgtransdb.cc    Thu Mar  8 00:58:56 2001
@@ -25,7 +25,8 @@// Make a connection to the specified database with default environment// See PQconnectdb() for
conninfousage. PgTransaction::PgTransaction(const char* conninfo)
 
-   : PgDatabase(conninfo)
+   : PgDatabase(conninfo),
+     pgCommitted(true){    BeginTransaction();}
@@ -33,17 +34,20 @@// Destructor: End the transaction blockPgTransaction::~PgTransaction(){
-    EndTransaction();
+    if (!pgCommitted) Exec("ABORT");}// Begin the transaction blockExecStatusType PgTransaction::BeginTransaction(){
+    pgCommitted = false;    return Exec("BEGIN");} // End BeginTransaction()// Begin the transaction
blockExecStatusTypePgTransaction::EndTransaction(){
 
+    pgCommitted = true;    return Exec("END");} // End EndTransaction()
+
diff -r -u postgresql-7.1beta5/src/interfaces/libpq++/pgtransdb.h
postgresql-7.1beta5-jtv/src/interfaces/libpq++/pgtransdb.h
--- postgresql-7.1beta5/src/interfaces/libpq++/pgtransdb.h    Mon Jan 29 03:53:57 2001
+++ postgresql-7.1beta5-jtv/src/interfaces/libpq++/pgtransdb.h    Thu Mar  8 01:00:11 2001
@@ -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
databasewith given environment and database name
 
-  // PgTransaction(const PgConnection&);
+  // explicit PgTransaction(const PgConnection&);  ~PgTransaction();    // close connection and clean up  protected:
@@ -46,9 +46,11 @@  ExecStatusType EndTransaction();  protected:
-  PgTransaction() : PgDatabase() {}    // Do not connect
+  PgTransaction() : PgDatabase(), pgCommitted(true) {}    // Do not connectprivate:
+  bool pgCommitted;
+// We don't support copying of PgTransaction objects,// so make copy constructor and assignment op private.
PgTransaction(constPgTransaction&);
 




Re: libpq++: combined patches based on 7.1b5

From
Tom Lane
Date:
"J. T. Vermeulen" <jtv@cistron-office.nl> writes:
> 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?

Yes.  It's too late in the 7.1 cycle for anything except bug fixes,
though (and even there, probably only critical fixes...)
        regards, tom lane


Re: libpq++: combined patches based on 7.1b5

From
"J. T. Vermeulen"
Date:
On Mon, 12 Mar 2001, Tom Lane wrote:

> Yes.  It's too late in the 7.1 cycle for anything except bug fixes,
> though (and even there, probably only critical fixes...)

I'm aware of that side--right now my worry is more whether 7.2 might be too
early.


Jeroen



Re: libpq++: combined patches based on 7.1b5

From
Bruce Momjian
Date:
> > 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?
> >
>
> As far as changes, 7.2 would be fine for changing the API, if there is a
> good reason to do it.  For example, I see getLength returns a short.
> With 7.1's new longer tuples, that should now be changed to int, at
> least.  (I have updated libpq++/TODO to mention this.)

I was wrong.  It was not getLength, but FieldSize that was the problem.

OK, I thought, how hard can it be to change, and indeed, it was quite
easy.  Patch attached and applied.  Seems we have to break the API to
allow long field values.  Max field length is now 1GB.

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
Index: doc/src/sgml/libpq++.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/libpq++.sgml,v
retrieving revision 1.29
diff -c -r1.29 libpq++.sgml
*** doc/src/sgml/libpq++.sgml    2001/05/09 17:29:09    1.29
--- doc/src/sgml/libpq++.sgml    2001/05/09 17:43:20
***************
*** 430,436 ****
         Returns the size in bytes of the field associated with the given
         field index. Field indices start at 0.
         <synopsis>
!     short PgDatabase::FieldSize(int field_num) const
         </synopsis>
         Returns the space allocated for this field in a database tuple given
         the field number. In other words the size of the server's binary
--- 430,436 ----
         Returns the size in bytes of the field associated with the given
         field index. Field indices start at 0.
         <synopsis>
!     int PgDatabase::FieldSize(int field_num) const
         </synopsis>
         Returns the space allocated for this field in a database tuple given
         the field number. In other words the size of the server's binary
***************
*** 444,450 ****
         Returns the size in bytes of the field associated with the given
         field index. Field indices start at 0.
         <synopsis>
!     short PgDatabase::FieldSize(const char *field_name) const
         </synopsis>
         Returns the space allocated for this field in a database tuple given
         the field name. In other words the size of the server's binary
--- 444,450 ----
         Returns the size in bytes of the field associated with the given
         field index. Field indices start at 0.
         <synopsis>
!     int PgDatabase::FieldSize(const char *field_name) const
         </synopsis>
         Returns the space allocated for this field in a database tuple given
         the field name. In other words the size of the server's binary
Index: src/interfaces/libpq++/TODO
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/TODO,v
retrieving revision 1.3
diff -c -r1.3 TODO
*** src/interfaces/libpq++/TODO    2001/05/09 17:37:17    1.3
--- src/interfaces/libpq++/TODO    2001/05/09 17:43:25
***************
*** 1,5 ****

  *    Implement exceptions
  *    Many other things I have yet to discover
- *    fix getLength to return an int and not a short

--- 1,4 ----
Index: src/interfaces/libpq++/pgdatabase.cc
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/pgdatabase.cc,v
retrieving revision 1.10
diff -c -r1.10 pgdatabase.cc
*** src/interfaces/libpq++/pgdatabase.cc    2001/05/09 17:29:10    1.10
--- src/interfaces/libpq++/pgdatabase.cc    2001/05/09 17:43:25
***************
*** 106,118 ****
  }


! short PgDatabase::FieldSize(int field_num) const
  {
  return PQfsize(pgResult, field_num);
  }


! short PgDatabase::FieldSize(const char* field_name) const
  {
  return PQfsize(pgResult, FieldNum(field_name));
  }
--- 106,118 ----
  }


! int PgDatabase::FieldSize(int field_num) const
  {
  return PQfsize(pgResult, field_num);
  }


! int PgDatabase::FieldSize(const char* field_name) const
  {
  return PQfsize(pgResult, FieldNum(field_name));
  }
Index: src/interfaces/libpq++/pgdatabase.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/pgdatabase.h,v
retrieving revision 1.10
diff -c -r1.10 pgdatabase.h
*** src/interfaces/libpq++/pgdatabase.h    2001/05/09 17:29:10    1.10
--- src/interfaces/libpq++/pgdatabase.h    2001/05/09 17:43:25
***************
*** 51,58 ****
    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;
--- 51,58 ----
    int FieldNum(const char* field_name) const;
    Oid FieldType(int field_num) const;
    Oid FieldType(const char* field_name) const;
!   int FieldSize(int field_num) const;
!   int 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;

Re: libpq++: combined patches based on 7.1b5

From
Bruce Momjian
Date:
OK, I have applied this mega-patch.  It applied cleanly, except for the
documentation changes.  This is because I restructured the order of the
functions recently.  I manually added your doc changes.

As this includes all your previous patches, my guess is that we are all
caught up with you now in the CVS tree for 7.2.


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

As far as changes, 7.2 would be fine for changing the API, if there is a
good reason to do it.  For example, I see getLength returns a short. 
With 7.1's new longer tuples, that should now be changed to int, at
least.  (I have updated libpq++/TODO to mention this.)

Not sure what else you have in mind, but you are in pretty much total
control of the C++ library if you want to improve it.

Thanks for the patches. 

> 
> 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
> 
> 
> Diffs:

--  Bruce Momjian                        |  http://candle.pha.pa.us pgman@candle.pha.pa.us               |  (610)
853-3000+  If your life is a hard drive,     |  830 Blythe Avenue +  Christ can be your backup.        |  Drexel Hill,
Pennsylvania19026
 


Re: libpq++: combined patches based on 7.1b5

From
"J. T. Vermeulen"
Date:
On Wed, 09 May 2001, Bruce Momjian wrote:

> As this includes all your previous patches, my guess is that we are all
> caught up with you now in the CVS tree for 7.2.
Yup.  BTW maybe it would be better to just deprecate the existing API, doing
just bugfixes on it (like the wider getLength() and such) and start afresh on 
a new, completely incompatible one along the lines I've described.

On a different note, please note that since I'm changing jobs in a few weeks' 
time I'll have to revert to my private email address, jtv@xs4all.nl.

Jeroen