From f6353c6ee4a11faa36141339a03a16bc25cd0b10 Mon Sep 17 00:00:00 2001 From: Bruce Momjian <bruce@momjian.us> Date: Thu, 22 Aug 2002 03:17:38 +0000 Subject: [PATCH] Remove libpq++ SGML documentation. --- doc/src/sgml/filelist.sgml | 3 +- doc/src/sgml/libpq++.sgml | 845 ----------------------------------- doc/src/sgml/programmer.sgml | 3 +- 3 files changed, 2 insertions(+), 849 deletions(-) delete mode 100644 doc/src/sgml/libpq++.sgml diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml index e767bd173f9..b520e466adb 100644 --- a/doc/src/sgml/filelist.sgml +++ b/doc/src/sgml/filelist.sgml @@ -1,4 +1,4 @@ -<!-- $Header: /cvsroot/pgsql/doc/src/sgml/filelist.sgml,v 1.21 2002/08/05 19:43:31 petere Exp $ --> +<!-- $Header: /cvsroot/pgsql/doc/src/sgml/filelist.sgml,v 1.22 2002/08/22 03:17:37 momjian Exp $ --> <!entity history SYSTEM "history.sgml"> <!entity info SYSTEM "info.sgml"> @@ -68,7 +68,6 @@ <!entity jdbc SYSTEM "jdbc.sgml"> <!entity libpgeasy SYSTEM "libpgeasy.sgml"> <!entity libpq SYSTEM "libpq.sgml"> -<!entity libpqpp SYSTEM "libpq++.sgml"> <!entity libpgtcl SYSTEM "libpgtcl.sgml"> <!entity pygresql SYSTEM "pygresql.sgml"> <!entity lobj SYSTEM "lobj.sgml"> diff --git a/doc/src/sgml/libpq++.sgml b/doc/src/sgml/libpq++.sgml deleted file mode 100644 index 1fa7d5c129a..00000000000 --- a/doc/src/sgml/libpq++.sgml +++ /dev/null @@ -1,845 +0,0 @@ -<!-- -$Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.43 2002/08/19 04:05:00 ishii Exp $ ---> - - <chapter id="libpqplusplus"> - <title><application>libpq++</application> - C++ Binding Library</title> - - <indexterm zone="libpqplusplus"> - <primary>libpq++</primary> - </indexterm> - <indexterm zone="libpqplusplus"> - <primary>C++</primary> - </indexterm> - - <sect1 id="libpqpp-introduction"> - <title>Introduction</title> - - <para> - <application>libpq++</application> is the C++ API to - <productname>PostgreSQL</productname>. - <application>libpq++</application> is a set of classes that allow - client programs to connect to the - <productname>PostgreSQL</productname> backend server. These connections - come in two forms: a database class and a large object class. - </para> - - <para> - The database class is intended for manipulating a database. You can - send all sorts of SQL queries and commands to the <productname>PostgreSQL</productname> - backend server and retrieve the responses of the server. - </para> - - <para> - The large object class is intended for manipulating a large object - in a database. Although a large object instance can send normal - queries to the <productname>PostgreSQL</productname> backend server - it is only intended for simple - queries that do not return any data. A large object should be seen - as a file stream. In the future it should behave much like the C++ file - streams - <literal>cin</literal>, - <literal>cout</literal> - and - <literal>cerr</literal>. - </para> - - <para> - This chapter is based on the documentation for the - <application>libpq</application> C library (see <xref - linkend="libpq">). There - are several examples of <application>libpq++</application> - applications in - <filename>src/interfaces/libpq++/examples</filename> in the source - distribution. - </para> - </sect1> - - <sect1 id="libpqpp-init"> - <title>Control and Initialization</title> - - <sect2> - <title>Environment Variables</title> - <para> - The following environment variables can be used to set up default - values for an environment and to avoid hard-coding database names into - an application program: - <note> - <para> - Refer to <xref linkend="libpq-envars"> for a complete - list of available connection options. - </para> - </note> - </para> - - <para> - The following environment variables can be used to select default - connection parameter values, which will be used by - <function>PQconnectdb</> or - <function>PQsetdbLogin</> if no value is directly specified by the calling code. - These are useful to avoid hard-coding database names into simple - application programs. - <note> - <para> - <filename>libpq++</filename> uses only environment variables or - <filename>libpq</>'s <function>PQconnectdb</> - <parameter>conninfo</parameter> style strings. - </para> - </note> - - <itemizedlist> - <listitem> - <para> - <envar>PGHOST</envar> sets the default server name. - If this begins with a slash, it specifies Unix-domain communication - rather than TCP/IP communication; the value is the name of the - directory in which the socket file is stored (default <filename>/tmp</filename>). - </para> - </listitem> - <listitem> - <para> - <envar>PGPORT</envar> sets the default TCP port number or Unix-domain - socket file extension for communicating with the - <productname>PostgreSQL</productname> backend. - </para> - </listitem> - <listitem> - <para> - <envar>PGDATABASE</envar> sets the default - <productname>PostgreSQL</productname> database name. - </para> - </listitem> - <listitem> - <para> - <envar>PGUSER</envar> - sets the user name used to connect to the database and for authentication. - </para> - </listitem> - <listitem> - <para> - <envar>PGPASSWORD</envar> - sets the password used if the backend demands password - authentication. This is deprecated; use <envar>PGPASSWORDFILE</envar> instead. - </para> - </listitem> - <listitem> - <para> - <envar>PGPASSWORDFILE</envar> - sets the password file used if the backend demands password - authentication. Refer to the libpq documentation for more details. - </para> - </listitem> - <listitem> - <para> - <envar>PGREALM</envar> sets the Kerberos realm to use with - <productname>PostgreSQL</productname>, - if it is different from the local realm. If - <envar>PGREALM</envar> is set, <productname>PostgreSQL</productname> - applications will attempt - authentication with servers for this realm and use - separate ticket files to avoid conflicts with local - ticket files. This environment variable is only - used if Kerberos authentication is selected by the backend. - </para> - </listitem> - <listitem> - <para> - <envar>PGOPTIONS</envar> sets additional run-time options for - the <productname>PostgreSQL</productname> backend. - </para> - </listitem> - <listitem> - <para> - <envar>PGTTY</envar> sets the file or <acronym>tty</acronym> on which debugging - messages from the backend server are displayed. - </para> - </listitem> - </itemizedlist> - </para> - - <para> - The following environment variables can be used to specify user-level default - behavior for every <productname>PostgreSQL</productname> session: - - <itemizedlist> - <listitem> - <para> - <envar>PGDATESTYLE</envar> - sets the default style of date/time representation. - </para> - </listitem> - <listitem> - <para> - <envar>PGTZ</envar> - sets the default time zone. - </para> - </listitem> - </itemizedlist> - </para> - - <para> - The following environment variables can be used to specify default internal - behavior for every <productname>PostgreSQL</productname> session: - - <itemizedlist> - <listitem> - <para> - <envar>PGGEQO</envar> - sets the default mode for the genetic optimizer. - </para> - </listitem> - </itemizedlist> - </para> - - <para> - Refer to the <command>SET</command> <acronym>SQL</acronym> command - for information on correct values for these environment variables. - </para> - </sect2> - </sect1> - - <sect1 id="libpqpp-classes"> - <title><application>libpq++</application> Classes</title> - - <sect2> - <title>Connection Class: <classname>PgConnection</classname></title> - - <para> - The connection class makes the actual connection to the database and is inherited - by all of the access classes. - </para> - </sect2> - - <sect2> - <title>Database Class: <classname>PgDatabase</classname></title> - - <para> - The database class provides C++ objects that have a connection - to a backend server. To create such an object one first needs - the appropriate environment for the backend to access. - The following constructors deal with making a connection to a backend - server from a C++ program. - </para> - </sect2> - </sect1> - - <sect1 id="libpqpp-connect"> - <title>Database Connection Functions</title> - <para> - <itemizedlist> - <listitem> - <para> - <function>PgConnection</function> - makes a new connection to a backend database server. -<synopsis> -PgConnection::PgConnection(const char *conninfo) -</synopsis> - The <parameter>conninfo</> string is the same as for the underlying - <application>libpq</> <function>PQconnectdb</> function. - </para> - - <para> - Although typically called from one of the access classes, a connection to - a backend server is possible by creating a <classname>PgConnection</> object. - </para> - </listitem> - - <listitem> - <para> - <function>ConnectionBad</function> - returns whether or not the connection to the backend server succeeded or - failed. -<synopsis> -bool PgConnection::ConnectionBad() const -</synopsis> - Returns true if the connection failed. - </para> - </listitem> - - <listitem> - <para> - <function>Status</function> - returns the status of the connection to the backend server. -<synopsis> -ConnStatusType PgConnection::Status() -</synopsis> - Returns either <symbol>CONNECTION_OK</> or - <symbol>CONNECTION_BAD</> depending on the state of the - connection. - </para> - </listitem> - - <listitem> - <para> - <function>PgDatabase</function> - makes a new connection to a backend database server. -<synopsis> -PgDatabase(const char *conninfo) -</synopsis> - After a <classname>PgDatabase</classname> has been created it should be checked to make sure - the connection to the database succeeded before sending - queries to the object. This can easily be done by - retrieving the current status of the <classname>PgDatabase</classname> object with the - <function>Status</function> or <function>ConnectionBad</function> methods. - </para> - </listitem> - - <listitem> - <para> - <function>DBName</function> - returns the name of the current database. -<synopsis> -const char *PgConnection::DBName() -</synopsis> - </para> - </listitem> - - <listitem> - <para> - <function>Notifies</function> - returns the next notification from a list of unhandled notification messages - received from the backend. -<synopsis> -PGnotify* PgConnection::Notifies() -</synopsis> - See <function>PQnotifies</function> in <application>libpq</> for details. - </para> - </listitem> - </itemizedlist> - </para> - </sect1> - - <sect1 id="libpqpp-exec"> - <title>Query Execution Functions</title> - -<sect2 id="libpqpp-exec-main"> - <title>Main Routines</title> - <para> - <itemizedlist> - <listitem> - <para> - <function>Exec</function> - sends a command to the backend server. It's probably more desirable to - use one of the next two functions. -<synopsis> -ExecStatusType PgConnection::Exec(const char* query) -</synopsis> - Returns the result status of the command. The following status - results can be expected: - - <simplelist> - <member> - <symbol>PGRES_EMPTY_QUERY</symbol> - </member> - <member> - <symbol>PGRES_COMMAND_OK</symbol>, if the command was not a query - </member> - <member> - <symbol>PGRES_TUPLES_OK</symbol>, if the query successfully returned tuples - </member> - <member> - <symbol>PGRES_COPY_OUT</symbol> - </member> - <member> - <symbol>PGRES_COPY_IN</symbol> - </member> - <member> - <symbol>PGRES_BAD_RESPONSE</symbol>, if an unexpected response was received - </member> - <member> - <symbol>PGRES_NONFATAL_ERROR</symbol> - </member> - <member> - <symbol>PGRES_FATAL_ERROR</symbol> - </member> - </simplelist> - </para> - </listitem> - - <listitem> - <para> - <function>ExecCommandOk</function> sends a non-query command - (one that does not return rows) to the backend server. -<synopsis> -int PgConnection::ExecCommandOk(const char *query) -</synopsis> - Returns true (1) if the command succeeds. - </para> - </listitem> - - <listitem> - <para> - <function>ExecTuplesOk</function> - Sends a query command (one that returns rows) to the backend server. -<synopsis> -int PgConnection::ExecTuplesOk(const char *query) -</synopsis> - Returns true (1) if the query succeeds. - </para> - </listitem> - - <listitem> - <para> - <function>ErrorMessage</function> - returns the last error message text. -<synopsis> -const char *PgConnection::ErrorMessage() -</synopsis> - </para> - </listitem> - </itemizedlist> - </para> -</sect2> - -<sect2 id="libpqpp-exec-select-info"> - <title>Retrieving SELECT Result Information</title> - - <itemizedlist> - <listitem> - <para> - <function>Tuples</function> - returns the number of tuples (rows) in the query result. -<synopsis> -int PgDatabase::Tuples() const -</synopsis> - </para> - </listitem> - - <listitem> - <para> - <function>Fields</function> - returns the number of fields (rows) in each tuple of the query result. -<synopsis> -int PgDatabase::Fields() -</synopsis> - </para> - </listitem> - - <listitem> - <para> - <function>FieldName</function> - returns the field (column) name associated with the given field index. - Field indices start at 0. -<synopsis> -const char *PgDatabase::FieldName(int field_num) const -</synopsis> - </para> - </listitem> - - <listitem> - <para> - <function>FieldNum</function> - returns the field (column) index associated with - the given field name. -<synopsis> -int PgDatabase::FieldNum(const char* field_name) const -</synopsis> - -1 is returned if the given name does not match any field. - </para> - </listitem> - - <listitem> - <para> - <function>FieldType</function> - returns the field type associated with the given field index. The - integer returned is an internal coding of the type. Field indices - start at 0. -<synopsis> -Oid PgDatabase::FieldType(int field_num) const -</synopsis> - </para> - </listitem> - - <listitem> - <para> - <function>FieldType</function> - returns the field type associated with the given field name. The - integer returned is an internal coding of the type. Field indices - start at 0. -<synopsis> -Oid PgDatabase::FieldType(const char* field_name) const -</synopsis> - </para> - </listitem> - - <listitem> - <para> - <function>FieldSize</function> - 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 representation of the data type. -1 is returned if the - field is variable size. - </para> - </listitem> - - <listitem> - <para> - <function>FieldSize</function> - 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 representation of the data type. -1 is returned if the - field is variable size. - </para> - </listitem> - </itemizedlist> - </sect2> - - -<sect2 id="libpqpp-exec-select-values"> - <title>Retrieving SELECT Result Values</title> - - <itemizedlist> - <listitem> - <para> - <function>GetValue</function> returns a single field (column) - value of one tuple of a <structname>PGresult</structname>. - Tuple and field indices start at 0. -<synopsis> -const char *PgDatabase::GetValue(int tup_num, int field_num) const -</synopsis> - For most queries, the value returned by - <function>GetValue</function> is a null-terminated string - representation of the attribute value. But if - <function>BinaryTuples</function> is true, the value returned by - <function>GetValue</function> is the binary representation of - the type in the internal format of the backend server (but not - including the size word, if the field is variable-length). It is - then the programmer's responsibility to cast and convert the - data to the correct C type. The pointer returned by - <function>GetValue</function> points to storage that is part of - the <structname>PGresult</structname> structure. One should not - modify it, and one must explicitly copy the value into other - storage if it is to be used past the lifetime of the - <structname>PGresult</structname> structure itself. - <function>BinaryTuples</function> is not yet implemented. - </para> - </listitem> - - <listitem> - <para> - <function>GetValue</function> returns a single field (column) - value of one tuple of a <structname>PGresult</structname>. - Tuple and field indices start at 0. -<synopsis> -const char *PgDatabase::GetValue(int tup_num, const char *field_name) const -</synopsis> - For most queries, the value returned by - <function>GetValue</function> is a null-terminated string - representation of the attribute value. But if - <function>BinaryTuples</function> is true, the value returned by - <function>GetValue</function> is the binary representation of - the type in the internal format of the backend server (but not - including the size word, if the field is variable-length). It is - then the programmer's responsibility to cast and convert the - data to the correct C type. The pointer returned by - <function>GetValue</function> points to storage that is part of - the <structname>PGresult</structname> structure. One should not - modify it, and one must explicitly copy the value into other - storage if it is to be used past the lifetime of the - <structname>PGresult</structname> structure itself. - <function>BinaryTuples</function> is not yet implemented. - </para> - </listitem> - - <listitem> - <para> - <function>GetLength</function> returns the length of a field - (column) in bytes. Tuple and field indices start at 0. -<synopsis> -int PgDatabase::GetLength(int tup_num, int field_num) const -</synopsis> - This is the actual data length for the particular data value, - that is the size of the object pointed to by - <function>GetValue</function>. Note that for - character-represented values, this size has little to do with - the binary size reported by <function>PQfsize</function>. - </para> - </listitem> - - <listitem> - <para> - <function>GetLength</function> returns the length of a field - (column) in bytes. Tuple and field indices start at 0. -<synopsis> -int PgDatabase::GetLength(int tup_num, const char* field_name) const -</synopsis> - This is the actual data length for the particular data value, - that is the size of the object pointed to by - <function>GetValue</function>. Note that for - character-represented values, this size has little to do with - the binary size reported by <function>PQfsize</function>. - </para> - </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 <function>GetValue</function> 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 <function>GetValue</function> will return the empty - string for null fields, not the NULL pointer. - </para> - </listitem> - - <listitem> - <para> - <function>DisplayTuples</function> prints out all the tuples - and, optionally, the attribute names to the specified output - stream. -<synopsis> -void PgDatabase::DisplayTuples(FILE *out = 0, bool fillAlign = true, -const char* fieldSep = "|", bool printHeader = true, bool quiet = false) const -</synopsis> - This function is obsolescent. - </para> - </listitem> - - <listitem> - <para> - <function>PrintTuples</function> prints out all the tuples and, - optionally, the attribute names to the specified output stream. -<synopsis> -void PgDatabase::PrintTuples(FILE *out = 0, bool printAttName = true, -bool terseOutput = false, bool fillAlign = false) const -</synopsis> - This function is obsolescent. - </para> - </listitem> - </itemizedlist> - </sect2> - -<sect2 id="libpqpp-exec-nonselect"> - <title>Retrieving Non-SELECT Result Information</title> - - <itemizedlist> - <listitem> - <para> - <function>CmdTuples</function> returns the number of rows - affected after an <command>INSERT</command>, - <command>UPDATE</command>, or <command>DELETE</command>. If the - command was anything else, it returns -1. -<synopsis> -int PgDatabase::CmdTuples() const -</synopsis> - </para> - </listitem> - - <listitem> - <para> - <function>OidStatus</function> -<synopsis> -const char *PgDatabase::OidStatus() const -</synopsis> - </para> - </listitem> - </itemizedlist> - </sect2> - - </sect1> - - <sect1 id="libpqpp-notify"> - <title>Asynchronous Notification</title> - - <para> - <productname>PostgreSQL</productname> supports asynchronous - notification via the <command>LISTEN</command> and - <command>NOTIFY</command> commands. A backend registers its - interest in a particular notification condition with the - <command>LISTEN</command> command. All backends that are - listening on a particular condition will be notified - asynchronously when a <command>NOTIFY</command> of that name is - executed by another backend. No additional information is passed - from the notifier to the listener. Thus, typically, any actual - data that needs to be communicated is transferred through a - relation. - </para> - - <para> - <application>libpq++</application> applications are notified whenever a - connected backend has - received an asynchronous notification. However, the communication from - the backend to the frontend is not asynchronous. - The <application>libpq++</application> application - must poll the backend to see if there is any pending notification - information. After the execution of a command, a frontend may call - <function>PgDatabase::Notifies</function> - 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 returns <symbol>NULL</symbol> if there are no pending notifications - from the backend. - <function>PgDatabase::Notifies</function> - behaves like the popping of a stack. Once a notification is returned - from <function>PgDatabase::Notifies</function>, - it is considered handled and will be removed from the list of - notifications. - - <itemizedlist> - <listitem> - <para> - <function>PgDatabase::Notifies</function> - retrieves pending notifications from the server. - -<synopsis> -PGnotify* PgDatabase::Notifies() -</synopsis> - </para> - </listitem> - </itemizedlist> - </para> - <para> - The second sample program gives an example of the use of asynchronous - notification. - </para> - </sect1> - - <sect1 id="libpqpp-copy"> - <title>Functions Associated with the COPY Command</title> - - <para> - The <command>COPY</command> command in <productname>PostgreSQL</productname> - has options to read from or write to the network - connection used by <application>libpq++</application>. - Therefore, functions are necessary to - access this network connection directly so applications may take full - advantage of this capability. - - <itemizedlist> - <listitem> - <para> - <function>PgDatabase::GetLine</function> - reads a newline-terminated line of characters (transmitted by the - backend server) into a buffer - <replaceable class="parameter">string</replaceable> - of size <replaceable class="parameter">length</replaceable>. -<synopsis> -int PgDatabase::GetLine(char* string, int length) -</synopsis> - </para> - - <para> - Like the Unix system routine - <function>fgets()</function>, - this routine copies up to - <literal><replaceable class="parameter">length</replaceable>-1</literal> - characters into - <replaceable class="parameter">string</replaceable>. - It is like - <function>gets()</function>, - however, in that it converts the terminating newline into a zero byte. - </para> - <para> - <function>PgDatabase::GetLine</function> - returns <symbol>EOF</symbol> at end of file, 0 if the entire line has been read, and 1 if the - buffer is full but the terminating newline has not yet been read. - </para> - <para> - Notice that the application must check to see if a new line consists - of a backslash followed by a period (<literal>\.</>), which indicates - that the backend - server has finished sending the results of the - <command>COPY</command>. - Therefore, if the application ever expects to receive lines - that are more than - <literal><replaceable class="parameter">length</replaceable>-1</literal> - characters long, the application must be sure to check the return - value of <function>PgDatabase::GetLine</function> very carefully. - </para> - </listitem> - <listitem> - <para> - <function>PgDatabase::PutLine</function> - Sends a null-terminated <replaceable class="parameter">string</replaceable> - to the backend server. -<synopsis> -void PgDatabase::PutLine(char* string) -</synopsis> - </para> - <para> - The application must explicitly send the characters <literal>\.</literal> - to indicate to the backend that it has finished sending its data. - </para> - </listitem> - <listitem> - <para> - <function>PgDatabase::EndCopy</function> - synchronizes with the backend. -<synopsis> -int PgDatabase::EndCopy() -</synopsis> - This function waits until the backend has - finished processing the <command>COPY</command>. - It should either be issued when the - last string has been sent to the backend using - <function>PgDatabase::PutLine</function> - or when the last string has been received from the backend using - <function>PgDatabase::GetLine</function>. - It must be issued or the backend may get <quote>out of sync</quote> with - the frontend. Upon return from this function, the backend is ready to - receive the next command. - </para> - <para> - The return value is 0 on successful completion, nonzero otherwise. - </para> - </listitem> - </itemizedlist> - </para> - - <para> - As an example: - -<programlisting> -PgDatabase data; -data.Exec("CREATE TABLE foo (a int4, b char(16), d double precision)"); -data.Exec("COPY foo FROM STDIN"); -data.PutLine("3\tHello World\t4.5\n"); -data.PutLine("4\tGoodbye World\t7.11\n"); -... -data.PutLine("\\.\n"); -data.EndCopy(); -</programlisting> - </para> - </sect1> - - </chapter> - -<!-- Keep this comment at the end of the file -Local variables: -mode:sgml -sgml-omittag:nil -sgml-shorttag:t -sgml-minimize-attributes:nil -sgml-always-quote-attributes:t -sgml-indent-step:1 -sgml-indent-data:t -sgml-parent-document:nil -sgml-default-dtd-file:"./reference.ced" -sgml-exposed-tags:nil -sgml-local-catalogs:("/usr/lib/sgml/catalog") -sgml-local-ecat-files:nil -End: ---> diff --git a/doc/src/sgml/programmer.sgml b/doc/src/sgml/programmer.sgml index 0777979e8ba..0d4040b704e 100644 --- a/doc/src/sgml/programmer.sgml +++ b/doc/src/sgml/programmer.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/Attic/programmer.sgml,v 1.39 2002/01/07 02:29:13 petere Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/Attic/programmer.sgml,v 1.40 2002/08/22 03:17:38 momjian Exp $ PostgreSQL Programmer's Guide. --> @@ -29,7 +29,6 @@ PostgreSQL Programmer's Guide. &libpq; &lobj; - &libpqpp; &libpgtcl; &libpgeasy; &ecpg; -- GitLab