Thread: Suggested patches for libpq++/pgdatabase.*

Suggested patches for libpq++/pgdatabase.*

From
"J. T. Vermeulen"
Date:
Suggest the following fixes for a future version.  These include some minor
changes of interface (ints changed to bools) that should be compatible at the
source level but incompatible at the linking level, so those may have to be
skipped or deferred to some more convenient time.

Other changes: fixed possible portability problem for weird platforms (using 
memset() to clear pointers); fixed minor memory leak in PrintTuples(), and
marked PrintTuples() / DisplayTuples() as obsolescent; changed dubious 
parameter names "string" to "str".


--- postgresql-7.0.3/src/interfaces/libpq++/pgdatabase.cc    Sat Jan 29 17:58:52 2000
+++ postgresql-7.0.3-jtv/src/interfaces/libpq++/pgdatabase.cc    Mon Feb 26 14:17:32 2001
@@ -18,37 +18,41 @@#include "pgdatabase.h"
-void PgDatabase::DisplayTuples(FILE *out, int fillAlign, 
-                               const char* fieldSep, int printHeader,
-                               int /* quiet */) 
+// OBSOLESCENT (uses PQprint(), which is no longer being maintained)
+void PgDatabase::DisplayTuples(FILE *out, 
+    bool fillAlign, 
+    const char* fieldSep, 
+    bool printHeader,
+    bool /* quiet */) {    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){    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);}
@@ -126,13 +130,13 @@}
-int PgDatabase::GetIsNull(int tup_num, int field_num)
+bool PgDatabase::GetIsNull(int tup_num, int field_num){ 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){ return PQgetisnull(pgResult, tup_num,
FieldNum(field_name));}
 
@@ -150,15 +154,15 @@}
-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); }


--- postgresql-7.0.3/src/interfaces/libpq++/pgdatabase.h    Sun Apr 23 00:39:15 2000
+++ postgresql-7.0.3-jtv/src/interfaces/libpq++/pgdatabase.h    Mon Feb 26 14:17:44 2001
@@ -37,7 +37,7 @@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  
 
@@ -53,18 +53,20 @@  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);
+  bool GetIsNull(int tup_num, int field_num);
+  bool 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) ;
+
+  // OBSOLESCENT (use PQprint()):
+  void DisplayTuples(FILE *out=0, bool fillAlign=true, 
+    const char* fieldSep="|", bool printHeader=true, bool quiet=false) ;
+  void PrintTuples(FILE *out=0, bool printAttName=true, 
+    bool terseOutput=false, bool fillAlign=false) ;  // copy command related access
-  int GetLine(char* string, int length);
-  void PutLine(const char* string);
+  int GetLine(char str[], int length);
+  void PutLine(const char str[]);  const char* OidStatus();  int EndCopy();




Re: Suggested patches for libpq++/pgdatabase.*

From
"J. T. Vermeulen"
Date:
On Mon, 26 Feb 2001, J. T. Vermeulen wrote:

> Suggest the following fixes for a future version.  These include some minor
> changes of interface (ints changed to bools) that should be compatible at the
> source level but incompatible at the linking level, so those may have to be
> skipped or deferred to some more convenient time.
> 
> Other changes: fixed possible portability problem for weird platforms (using 
> memset() to clear pointers); fixed minor memory leak in PrintTuples(), and
> marked PrintTuples() / DisplayTuples() as obsolescent; changed dubious 
> parameter names "string" to "str".

Oh, and made constructor 'explicit' for greater safety.

Here's an updated version of the same patch.  Added changes:- made lots of member functions 'const'- documented
GetIsNull()-updated documentation for interface changes
 


Diffs follow:


--- postgresql-7.0.3/src/interfaces/libpq++/pgdatabase.h    Sun Apr 23 00:39:15 2000
+++ postgresql-7.0.3-jtv/src/interfaces/libpq++/pgdatabase.h    Mon Feb 26 15:06:59 2001
@@ -37,35 +37,37 @@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    // query result access
 
-  int Tuples();
-  int CmdTuples(); 
+  int Tuples() const;
+  int 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(int tup_num, int field_num) const;
+  const char* GetValue(int tup_num, const char* field_name) const;
+  bool GetIsNull(int tup_num, int field_num) const;
+  bool GetIsNull(int tup_num, const char* field_name) const;
+  int GetLength(int tup_num, int field_num) const;
+  int GetLength(int 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:




--- postgresql-7.0.3/src/interfaces/libpq++/pgdatabase.cc    Sat Jan 29 17:58:52 2000
+++ postgresql-7.0.3-jtv/src/interfaces/libpq++/pgdatabase.cc    Mon Feb 26 15:09:59 2001
@@ -18,57 +18,57 @@#include "pgdatabase.h"
-void PgDatabase::DisplayTuples(FILE *out, int fillAlign, 
-                               const char* fieldSep, int printHeader,
-                               int /* quiet */) 
+// 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;}
@@ -78,91 +78,91 @@}
-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); }




--- postgresql-7.0.3/doc/src/sgml/libpq++.sgml    Tue May  2 22:01:51 2000
+++ postgresql-7.0.3-jtv/doc/src/sgml/libpq++.sgml    Mon Feb 26 15:17:14 2001
@@ -354,7 +354,7 @@       <function>Tuples</function>       Returns the number of tuples (instances) in the query
result.       <synopsis>
 
-    int PgDatabase::Tuples()
+    int PgDatabase::Tuples() const       </synopsis>      </para>     </listitem>
@@ -364,7 +364,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>
@@ -383,7 +383,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>
@@ -393,7 +393,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>
 
@@ -405,7 +405,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>
@@ -416,7 +416,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>
@@ -426,7 +426,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 
 
@@ -440,7 +440,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 
 
@@ -454,7 +454,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()
 
@@ -474,7 +474,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() 
 
@@ -490,11 +490,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
 
@@ -508,7 +530,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
 
@@ -522,8 +544,8 @@       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>
@@ -533,8 +555,8 @@       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>
@@ -558,7 +580,7 @@      <para>       <function>OidStatus</function>       <synopsis>
-    const char *PgDatabase::OidStatus()
+    const char *PgDatabase::OidStatus() const       </synopsis>      </para>     </listitem>
@@ -612,8 +634,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 is 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>,
 


Jeroen