OSDN Git Service

Clean up markup.
authorThomas G. Lockhart <lockhart@fourpalms.org>
Sat, 10 Oct 1998 17:12:18 +0000 (17:12 +0000)
committerThomas G. Lockhart <lockhart@fourpalms.org>
Sat, 10 Oct 1998 17:12:18 +0000 (17:12 +0000)
Add new bibliographic references from Paul Aoki.
Include libpq++ docs from the old man page in the Programmer's Guide.
Update Unix installation info for ODBC.

doc/src/sgml/biblio.sgml
doc/src/sgml/compiler.sgml
doc/src/sgml/ecpg.sgml
doc/src/sgml/libpgtcl.sgml
doc/src/sgml/libpq++.sgml [new file with mode: 0644]
doc/src/sgml/libpq.sgml
doc/src/sgml/odbc.sgml
doc/src/sgml/ports.sgml
doc/src/sgml/programmer.sgml

index d7afdf6..9dafe45 100644 (file)
@@ -317,6 +317,40 @@ The POSTGRES Group
 <!--
 <BIBLIOMISC>&dash;</BIBLIOMISC>
 
+<BOOKBIBLIO ID="OLSON93">
+
+2. Olson, Nels Edward.
+     Partial indexing in POSTGRES : research project / by Nels Edward Olson.  
+   1993.
+       UCB   Engin     T7.49.1993 O676
+
+-->
+<TITLE ID="OLSON93-full">
+Partial indexing in POSTGRES : research project
+</TITLE>
+<TITLEABBREV ID="OLSON93">
+Olson, 1993
+</TITLEABBREV>
+<AUTHORGROUP>
+<AUTHOR>
+<FIRSTNAME>Nels</FIRSTNAME>
+<SURNAME>Olson</SURNAME>
+</AUTHOR>
+</AUTHORGROUP>
+<PUBDATE>1993</PUBDATE>
+<ISSN>UCB Engin T7.49.1993 O676</ISSN>
+<PUBLISHER>
+<PUBLISHERNAME>University  of  California, Berkeley CA</PUBLISHERNAME>
+</PUBLISHER>
+<!--
+</BOOKBIBLIO>
+-->
+</BIBLIOENTRY>
+
+<BIBLIOENTRY>
+<!--
+<BIBLIOMISC>&dash;</BIBLIOMISC>
+
 <BOOKBIBLIO ID="ONG90">
 -->
 <TITLE ID="ONG90-full">
@@ -381,6 +415,55 @@ Rowe and Stonebraker, 1987
 <!--
 <BIBLIOMISC>&dash;</BIBLIOMISC>
 
+<BOOKBIBLIO ID="SESHADRI95">
+
+1. CONFERENCE PAPER
+   Seshadri, P.; Swami, A.
+     Generalized partial indexes.
+   IN:  Proceedings of the Eleventh International Conference on Data
+   Engineering (Cat. No.95CH35724). (Proceedings of the Eleventh International
+   Conference on Data Engineering (Cat. No.95CH35724)Proceedings of the
+   Eleventh International Conference on Data Engineering, Taipei, Taiwan, 6-10
+   March 1995). Edited by: Yu, P.S.; Chen, A.L.P. Los Alamitos, CA, USA: IEEE
+   Comput. Soc. Press, 1995. p. 420-7.
+http://simon.cs.cornell.edu/home/praveen/papers/partindex.de95.ps.Z
+
+-->
+<TITLE ID="SESHADRI95-full">
+<ulink url="http://simon.cs.cornell.edu/home/praveen/papers/partindex.de95.ps.Z">
+Generalized partial indexes
+</ulink>
+</TITLE>
+<TITLEABBREV ID="SESHADRI95">
+</TITLEABBREV>
+<AUTHORGROUP>
+<AUTHOR>
+<FIRSTNAME>P.</FIRSTNAME>
+<SURNAME>Seshadri</SURNAME>
+</AUTHOR>
+<AUTHOR>
+<FIRSTNAME>A.</FIRSTNAME>
+<SURNAME>Swami</SURNAME>
+</AUTHOR>
+</AUTHORGROUP>
+<CONFGROUP>
+<CONFDATES>March 1995</CONFDATES>
+<CONFTITLE>Eleventh International Conference on Data Engineering</CONFTITLE>
+</CONFGROUP>
+<PUBDATE>1995</PUBDATE>
+<ISSN>Cat. No.95CH35724</ISSN>
+<PUBLISHER>
+<PUBLISHERNAME>IEEE Computer Society Press</PUBLISHERNAME>
+</PUBLISHER>
+<!--
+</BOOKBIBLIO>
+-->
+</BIBLIOENTRY>
+
+<BIBLIOENTRY>
+<!--
+<BIBLIOMISC>&dash;</BIBLIOMISC>
+
 <BOOKBIBLIO ID="STON86">
 -->
 <TITLE ID="STON86-full">
@@ -388,7 +471,6 @@ The Design of <ProductName>Postgres</ProductName>
 </TITLE>
 <TITLEABBREV ID="STON86">
 Stonebraker and Rowe, 1986
-STON86
 </TITLEABBREV>
 <AUTHORGROUP>
 <AUTHOR>
@@ -515,6 +597,42 @@ Stonebraker et al, 1989</TITLEABBREV>
 <!--
 <BIBLIOMISC>&dash;</BIBLIOMISC>
 
+<BOOKBIBLIO ID="STON89b">
+
+1. Stonebraker, M.
+     The case for partial indexes (DBMS).
+   SIGMOD Record, Dec. 1989, vol.18, (no.4):4-11.
+http://s2k-ftp.CS.Berkeley.EDU:8000/postgres/papers/ERL-M89-17.pdf
+
+-->
+<TITLE ID="STON89b-full">
+<ulink url="http://s2k-ftp.CS.Berkeley.EDU:8000/postgres/papers/ERL-M89-17.pdf">
+The case for partial indexes (DBMS)
+</ulink>
+</TITLE>
+<TITLEABBREV ID="STON89b">
+Stonebraker, M, 1989b</TITLEABBREV>
+<AUTHORGROUP>
+<AUTHOR>
+<FIRSTNAME>M.</FIRSTNAME>
+<SURNAME>Stonebraker</SURNAME>
+</AUTHOR>
+</AUTHORGROUP>
+<CONFGROUP>
+<CONFDATES>Dec. 1989</CONFDATES>
+<CONFTITLE>Record 18(no.4):4-11</CONFTITLE>
+<CONFSPONSOR>SIGMOD</CONFSPONSOR>
+<CONFNUM>1989</CONFNUM>
+</CONFGROUP>
+<!--
+</BOOKBIBLIO>
+-->
+</BIBLIOENTRY>
+
+<BIBLIOENTRY>
+<!--
+<BIBLIOMISC>&dash;</BIBLIOMISC>
+
 <BOOKBIBLIO ID="STON90a">
 -->
 <TITLE ID="STON90a-full">
index f04b48b..b7f8bef 100644 (file)
@@ -9,7 +9,7 @@
 <Date>Transcribed 1998-02-12</Date>
 </DocInfo>
 
-<Title>GCC Default Optimizations</Title>
+<Title><application>gcc</application> Default Optimizations</Title>
 
 <Para>
 <Note>
index e460ae7..7cb28cd 100644 (file)
 <Date>Transcribed 1998-02-12</Date>
 </DocInfo>
 
-<Title><Application>ecpg</Application> - Embedded <Acronym>SQL</Acronym> in <Acronym>C</Acronym></Title>
+<Title><Application>ecpg</Application> - Embedded <Acronym>SQL</Acronym> 
+in <Acronym>C</Acronym></Title>
 
 <Para>
-This describes an embedded <Acronym>SQL</Acronym> in <Acronym>C</Acronym> package for <ProductName>Postgres</ProductName>.
+This describes an embedded <Acronym>SQL</Acronym> in <Acronym>C</Acronym> 
+package for <ProductName>Postgres</ProductName>.
 
 It is written by <ULink url="mailto:linus@epact.se">Linus Tolke</ULink>
 and <ULink url="mailto:meskes@debian.org">Michael Meskes</ULink>.
@@ -40,13 +42,16 @@ to copy and use the rest of the <ProductName>PostgreSQL</ProductName>.
 <Title>Why Embedded <Acronym>SQL</Acronym>?</Title>
 
 <Para>
-Embedded <Acronym>SQL</Acronym> has some small advantages over other ways to handle <Acronym>SQL</Acronym>
+Embedded <Acronym>SQL</Acronym> has some small advantages over other ways 
+to handle <Acronym>SQL</Acronym>
 queries. It takes care of all the tedious moving of information to and
-from variables in your <Acronym>C</Acronym> program. Many <Acronym>RDBMS</Acronym> packages
+from variables in your <Acronym>C</Acronym> program. 
+Many <Acronym>RDBMS</Acronym> packages
 support this embedded language.
 
 <Para> There is an ANSI-standard describing how the embedded language should
-work. <Application>ecpg</Application> was designed to meet this standard as much as possible. So it is
+work. <Application>ecpg</Application> was designed to meet this standard 
+as much as possible. So it is
 possible to port programs with embedded <Acronym>SQL</Acronym> written for
 other <Acronym>RDBMS</Acronym> packages to
 <ProductName>Postgres</ProductName> and thus promoting the spirit of free
@@ -56,28 +61,36 @@ software.
 <Title>The Concept</Title>
 
 <Para>
-You write your program in <Acronym>C</Acronym> with some special <Acronym>SQL</Acronym> things.
-For declaring variables that can be used in <Acronym>SQL</Acronym> statements you need to
+You write your program in <Acronym>C</Acronym> with some 
+special <Acronym>SQL</Acronym> things.
+For declaring variables that can be used in 
+<Acronym>SQL</Acronym> statements you need to
 put them in a special declare section.
 You use a special syntax for the <Acronym>SQL</Acronym> queries.
 
 <Para>
-Before compiling you run the file through the embedded <Acronym>SQL</Acronym> <Acronym>C</Acronym>
-preprocessor and it converts the <Acronym>SQL</Acronym> statements you used to function
+Before compiling you run the file through 
+the embedded <Acronym>SQL</Acronym> <Acronym>C</Acronym>
+preprocessor and it converts the <Acronym>SQL</Acronym> statements you used 
+to function
 calls with the variables used as arguments. Both variables that are used
-as input to the <Acronym>SQL</Acronym> statements and variables that will contain the
+as input to the <Acronym>SQL</Acronym> statements and variables that will 
+contain the
 result are passed.
 
 <Para>
 Then you compile and at link time you link with a special library that
 contains the functions used. These functions (actually it is mostly one
 single function) fetches the information from the arguments, performs
-the <Acronym>SQL</Acronym> query using the ordinary interface (<FileName>libpq</FileName>) and puts back
+the <Acronym>SQL</Acronym> query using the ordinary interface 
+(<FileName>libpq</FileName>) and puts back
 the result in the arguments dedicated for output.
 
 <Para>
-Then you run your program and when the control arrives to the <Acronym>SQL</Acronym>
-statement the <Acronym>SQL</Acronym> statement is performed against the database and you
+Then you run your program and when the control arrives to 
+the <Acronym>SQL</Acronym>
+statement the <Acronym>SQL</Acronym> statement is performed against 
+the database and you
 can continue with the result.
 
 
@@ -91,14 +104,16 @@ This section describes how to use the <Application>egpc</Application> tool.
 <Title>Preprocessor
 
 <Para>
-The preprocessor is called <Application>ecpg</Application>. After installation it resides in
+The preprocessor is called <Application>ecpg</Application>. 
+After installation it resides in
 the <ProductName>Postgres</ProductName> <FileName>bin/</FileName> directory. 
 
 <Sect2>
 <Title>Library
 
 <Para>
-The <Application>ecpg</Application> library is called <FileName>libecpg.a</FileName> or
+The <Application>ecpg</Application> library is called 
+<FileName>libecpg.a</FileName> or
 <FileName>libecpg.so</FileName>. Additionally, the library
 uses the <FileName>libpq</FileName> library for communication to the 
 <ProductName>Postgres</ProductName> server so you will
@@ -108,42 +123,42 @@ have to link your program with <Parameter>-lecpg -lpq</Parameter>.
 The library has some methods that are "hidden" but that could prove very
 useful sometime.
 
-<VariableList>
-<VarListEntry>
-<Term>ECPGdebug(int, FILE *stream)</Term>
-<ListItem>
-<Para>
-If this is called, with the first argument non-zero, then debuglogging is turned
-on. Debuglogging is done on <Function>stream</Function>. Most <Acronym>SQL</Acronym> statement logs its
-arguments and result.
-
-<Para>
-The most important one (<Function>ECPGdo</Function>) that is called on all <Acronym>SQL</Acronym>
-statements except <Command>EXEC SQL COMMIT</Command>, <Command>EXEC SQL ROLLBACK</Command>, 
-<Command>EXEC SQL CONNECT</Command> logs both its expanded string, i.e. the string
+<itemizedlist>
+<listitem>
+<para>
+<function>ECPGdebug(int <replaceable class="parameter">on</replaceable>, FILE *<replaceable class="parameter">stream</replaceable>)</function>
+turns on debug logging if called with the first argument non-zero.
+Debug logging is done on <replaceable class="parameter">stream</replaceable>.
+ Most <Acronym>SQL</Acronym> statement logs its arguments and result.
+
+<Para>
+The most important one (<Function>ECPGdo</Function>) 
+that is called on all <Acronym>SQL</Acronym>
+statements except <Command>EXEC SQL COMMIT</Command>, 
+<Command>EXEC SQL ROLLBACK</Command>, 
+<Command>EXEC SQL CONNECT</Command> logs both its expanded string,
+ i.e. the string
 with all the input variables inserted, and the result from the
-<ProductName>Postgres</ProductName> server. This can be very useful when searching for errors
+<ProductName>Postgres</ProductName> server.
+ This can be very useful when searching for errors
 in your <Acronym>SQL</Acronym> statements.
 </Para>
 </ListItem>
-</VarListEntry>
 
-<VarListEntry>
-<Term>ECPGstatus()</Term>
-<ListItem>
-<Para>
+<listitem>
+<para>
+<function>ECPGstatus()</function>
 This method returns TRUE if we are connected to a database and FALSE if not.
 </Para>
 </ListItem>
-</VarListEntry>
-</VariableList>
+</itemizedlist>
 
 <Sect2>
 <Title>Error handling
 
 <Para>
-To be able to detect errors from the <ProductName>Postgres</ProductName> server you include a line
-like
+To be able to detect errors from the <ProductName>Postgres</ProductName> 
+server you include a line like
 <ProgramListing>
 exec sql include sqlca;
 </ProgramListing>
@@ -160,8 +175,10 @@ struct sqlca {
 </ProgramListing>
 
 <Para>
-If an error occured in the last <Acronym>SQL</Acronym> statement then <Parameter>sqlca.sqlcode</Parameter>
-will be non-zero. If <Parameter>sqlca.sqlcode</Parameter> is less that 0 then this is
+If an error occured in the last <Acronym>SQL</Acronym> statement 
+then <Parameter>sqlca.sqlcode</Parameter>
+will be non-zero. If <Parameter>sqlca.sqlcode</Parameter> is less that 0
+ then this is
 some kind of serious error, like the database definition does not match
 the query given. If it is bigger than 0 then this is a normal error like
 the table did not contain the requested row.
@@ -209,7 +226,8 @@ The preprocessor has goofed up and generated some incorrect code.
 <Term>-1, Error starting transaction line %d.</Term>
 <ListItem>
 <Para>
-<ProductName>Postgres</ProductName> signalled to us that we cannot open the connection.
+<ProductName>Postgres</ProductName> signalled to us that we cannot open 
+the connection.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -218,7 +236,8 @@ The preprocessor has goofed up and generated some incorrect code.
 <Term>-1, Postgres error: %s line %d.</Term>
 <ListItem>
 <Para>
-Some <ProductName>Postgres</ProductName> error. The message contains the error message from the
+Some <ProductName>Postgres</ProductName> error. 
+The message contains the error message from the
 <ProductName>Postgres</ProductName> backend.
 </Para>
 </ListItem>
@@ -238,8 +257,8 @@ be found or we have gone through the cursor.
 <Term>-1, To many matches line %d.</Term>
 <ListItem>
 <Para>
-This means that the query has returned several lines. The <Command>SELECT</Command>
-you made probably was not unique.
+This means that the query has returned several lines. 
+The <Command>SELECT</Command> you made probably was not unique.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -249,8 +268,9 @@ you made probably was not unique.
 <ListItem>
 <Para>
 This means that the host variable is of an <Type>int</Type> type and the field
-in the <ProductName>Postgres</ProductName> database is of another type and contains a value that
-cannot be interpreted as an <Type>int</Type>. The library uses <Function>strtol</Function>
+in the <ProductName>Postgres</ProductName> database is of another type and 
+contains a value that cannot be interpreted as an <Type>int</Type>. 
+The library uses <Function>strtol</Function>
 for this conversion.
 </Para>
 </ListItem>
@@ -261,7 +281,8 @@ for this conversion.
 <ListItem>
 <Para>
 This means that the host variable is of an <Type>unsigned int</Type> type and
-the field in the <ProductName>Postgres</ProductName> database is of another type and contains a
+the field in the <ProductName>Postgres</ProductName> database is of another 
+type and contains a
 value that cannot be interpreted as an <Type>unsigned int</Type>. The library
 uses <Function>strtoul</Function> for this conversion.
 </Para>
@@ -273,7 +294,8 @@ uses <Function>strtoul</Function> for this conversion.
 <ListItem>
 <Para>
 This means that the host variable is of an <Type>float</Type> type and
-the field in the <ProductName>Postgres</ProductName> database is of another type and contains a
+the field in the <ProductName>Postgres</ProductName> database is of another 
+type and contains a
 value that cannot be interpreted as an <Type>float</Type>. The library
 uses <Function>strtod</Function> for this conversion.
 </Para>
@@ -284,7 +306,8 @@ uses <Function>strtod</Function> for this conversion.
 <Term>-1, Too few arguments line %d.</Term>
 <ListItem>
 <Para>
-This means that <ProductName>Postgres</ProductName> has returned more records than we have
+This means that <ProductName>Postgres</ProductName> has returned more records 
+than we have
 matching variables. Perhaps you have forgotten a couple of the host
 variables in the <Command>INTO :var1,:var2</Command>-list.
 </Para>
@@ -295,7 +318,8 @@ variables in the <Command>INTO :var1,:var2</Command>-list.
 <Term>-1, Too many arguments line %d.</Term>
 <ListItem>
 <Para>
-This means that <ProductName>Postgres</ProductName> has returned fewer records than we have
+This means that <ProductName>Postgres</ProductName> has returned fewer records 
+than we have
 host variables. Perhaps you have to many host variables in the 
 <Command>INTO :var1,:var2</Command>-list.
 </Para>
@@ -326,8 +350,10 @@ and why is explained in the message.
 <Term>-1, Postgres error line %d.</Term>
 <ListItem>
 <Para>
-<ProductName>Postgres</ProductName> returns something that the library does not know how to
-handle. This is probably because the version of <ProductName>Postgres</ProductName> does not
+<ProductName>Postgres</ProductName> returns something that the library does 
+not know how to
+handle. This is probably because the version of 
+<ProductName>Postgres</ProductName> does not
 match the version of the <Application>ecpg</Application> library.
 </Para>
 </ListItem>
@@ -337,8 +363,10 @@ match the version of the <Application>ecpg</Application> library.
 <Term>-1, Error committing line %d.</Term>
 <ListItem>
 <Para>
-Error during <Command>COMMIT</Command>. <Command>EXEC SQL COMMIT</Command> is translated to an
-<Command>end</Command> operation in <ProductName>Postgres</ProductName> and that is the operation that could
+Error during <Command>COMMIT</Command>. <Command>EXEC SQL COMMIT</Command> 
+is translated to an
+<Command>end</Command> operation in <ProductName>Postgres</ProductName> 
+and that is the operation that could
 not be performed.
 </Para>
 </ListItem>
@@ -348,8 +376,10 @@ not be performed.
 <Term>-1, Error rolling back line %d.</Term>
 <ListItem>
 <Para>
-Error during <Command>ROLLBACK</Command>. <Command>EXEC SQL ROLLBACK</Command> is translated to
-an <Command>abort</Command> operation in <ProductName>Postgres</ProductName> and that is the operation that
+Error during <Command>ROLLBACK</Command>. 
+<Command>EXEC SQL ROLLBACK</Command> is translated to
+an <Command>abort</Command> operation in <ProductName>Postgres</ProductName> 
+and that is the operation that
 could not be performed.
 </Para>
 </ListItem>
@@ -398,27 +428,31 @@ that effort can not justify the performance gained.
 <Title>Porting From Other <Acronym>RDBMS</Acronym> Packages</Title>
 
 <Para>
-To be written by persons that knows the different <Acronym>RDBMS</Acronym> packages and that
+To be written by someone who knows the different 
+<Acronym>RDBMS</Acronym> packages and who
 actually does port something...
 
 <Sect1>
 <Title>Installation</Title>
 
 <Para>
-Since version 0.5 <Application>ecpg</Application> is distributed together with <ProductName>Postgres</ProductName>. So you
+Since version 0.5 <Application>ecpg</Application> is distributed 
+together with <ProductName>Postgres</ProductName>. So you
 should get your precompiler, libraries and header files compiled and
-installed on the fly.
+installed by default as a part of your installation.
 
 <Sect1>
 <Title>For the Developer</Title>
 
 <Para>
-This section is for those that wants to develop the <Application>ecpg</Application> interface. It
+This section is for those who want to develop the 
+<Application>ecpg</Application> interface. It
 describes how the things work. The ambition is to make this section
 contain things for those that want to have a look inside and the section
 on How to use it should be enough for all normal questions.
 
-So, read this before looking at the internals of the <Application>ecpg</Application>. If
+So, read this before looking at the internals of the 
+<Application>ecpg</Application>. If
 you are not interested in how it really works, skip this section.
 
 <Sect2>
@@ -433,7 +467,8 @@ This version the preprocessor has some flaws:
 <ListItem>
 <Para>
 The PQ interface, and most of all the PQexec function, that is used by
-the <Application>ecpg</Application> relies on that the request is built up as a string. In some
+the <Application>ecpg</Application> relies on that the request is built 
+up as a string. In some
 cases, like when the data contains the null character, this will be a
 serious problem.
 </Para>
@@ -534,8 +569,8 @@ DESCRIPTOR statement will be ignored.
 <Para>
 To set up a database you need a few scripts with table definitions and
 other configuration parameters. If you have these scripts for an old
-database you would like to just apply them to get a <ProductName>Postgres</ProductName> database
-that works in the same way.
+database you would like to just apply them to get a 
+<ProductName>Postgres</ProductName> database that works in the same way.
 
 <Para>
 To set up a database you need a few scripts with table definitions and
@@ -562,8 +597,8 @@ everything to the output without looking at it further.
 
 <Para>
 When it comes to an <Command>EXEC SQL</Command> statements it interviens and
-changes them depending on what iit is. The <Command>EXEC SQL</Command> statement can
-be one of these:
+changes them depending on what iit is. 
+The <Command>EXEC SQL</Command> statement can be one of these:
 
 <VariableList>
 <VarListEntry>
@@ -682,20 +717,23 @@ ECPGrollback(__LINE__);
 <ListItem>
 <Para>
 Other <Acronym>SQL</Acronym> statements are other statements that start with 
-<Command>exec sql</Command> and ends with <Command>;</Command>. Everything inbetween is treated
+<Command>exec sql</Command> and ends with <Command>;</Command>. 
+Everything inbetween is treated
 as an <Acronym>SQL</Acronym> statement and parsed for variable substitution.
 
 <Para>
 Variable substitution occur when a symbol starts with a colon
-(<Command>:</Command>). Then a variable with that name is found among the variables
+(<Command>:</Command>). 
+Then a variable with that name is found among the variables
 that were previously declared within a declare section and depending on
-whether or not the <Acronym>SQL</Acronym> statements knows it to be a variable for input or
+whether or not the <Acronym>SQL</Acronym> statements knows it to be 
+a variable for input or
 output the pointers to the variables are written to the output to allow
 for access by the function.
 
 <Para>
-For every variable that is part of the <Acronym>SQL</Acronym> request the function gets
-another five arguments.
+For every variable that is part of the <Acronym>SQL</Acronym> request 
+the function gets another five arguments:
 
 <SimpleList>
 <Member>The type as a special symbol</Member>
@@ -776,7 +814,8 @@ This is a line number for the original line used in error messages only.
 <Term>A string</Term>
 <ListItem>
 <Para>
-This is the <Acronym>SQL</Acronym> request that is to be issued. This request is modified
+This is the <Acronym>SQL</Acronym> request that is to be issued. 
+This request is modified
 by the input variables, i.e. the variables that where not known at
 compile time but are to be entered in the request. Where the variables
 should go the string contains <Quote>;</Quote>.
@@ -824,7 +863,8 @@ An enum telling that there are no more variables.
 </VariableList>
 
 <Para>
-All the <Acronym>SQL</Acronym> statements are performed in one transaction unless you issue
+All the <Acronym>SQL</Acronym> statements are performed in one transaction 
+unless you issue
 a commit transaction. This works so that the first transaction or the
 first after a commit or rollback always begins a transaction.
 
index 245043d..ed6758b 100644 (file)
@@ -165,14 +165,13 @@ proc getDBs { {host "localhost"} {port "5432"} } {
 <DATE>1997-12-24</DATE>
 </REFSYNOPSISDIVINFO>
 <SYNOPSIS>
+pg_connect -conninfo <REPLACEABLE CLASS="PARAMETER">connectOptions</REPLACEABLE>
 pg_connect <REPLACEABLE CLASS="PARAMETER">dbName</REPLACEABLE> <OPTIONAL>-host <REPLACEABLE CLASS="PARAMETER">hostName</REPLACEABLE></OPTIONAL>
   <OPTIONAL>-port <REPLACEABLE
   CLASS="PARAMETER">portNumber</REPLACEABLE></OPTIONAL> <OPTIONAL>-tty
   <REPLACEABLE CLASS="PARAMETER">pqtty</REPLACEABLE></OPTIONAL>
   <OPTIONAL>-options <REPLACEABLE
   CLASS="PARAMETER">optionalBackendArgs</REPLACEABLE></OPTIONAL>
-<para>
-pg_connect -conninfo <REPLACEABLE CLASS="PARAMETER">connectOptions</REPLACEABLE>
 </SYNOPSIS>
 
 <REFSECT2 ID="R2-PGTCL-PGCONNECT-1">
@@ -438,6 +437,8 @@ where the optname is usable as an option in pg_connect -conninfo.
 </REFSECT1INFO>
 <TITLE>Description
 </TITLE>
+
+<para>
 <FUNCTION>pg_conndefaults</FUNCTION> returns info about the connection
 options available in <FUNCTION>pg_connect -conninfo</FUNCTION> and the
 current default value for each option.
diff --git a/doc/src/sgml/libpq++.sgml b/doc/src/sgml/libpq++.sgml
new file mode 100644 (file)
index 0000000..8e98cc1
--- /dev/null
@@ -0,0 +1,584 @@
+<chapter id="libpqplusplus">
+<title>libpq C++ Binding</title>
+
+<para>
+<filename>libpq++</filename> is the C++ API to 
+<productname>Postgres</productname>.
+<filename>libpq++</filename>  is a set of classes which allow
+client programs to connect to the 
+<productname>Postgres</productname> backend server. These connections
+come in two forms: a Database Class and a Large Object class.
+
+<para>
+The Database Class is intended for manipulating a database. You can
+send all sorts of SQL queries to the <productname>Postgres</productname> 
+backend server and retrieve the responses of the server.
+
+<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>Postgres</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 future it should behave much like the C++ file
+streams
+<literal>cin</literal>,
+<literal>cout</literal>
+and
+<literal>cerr</literal>.
+
+<para>
+This chapter is based on the documentation
+for the <filename>libpq</filename> C library.  Three
+short programs are listed at the end of this section as examples of
+<filename>libpq++</filename> programming 
+(though not necessarily of good programming).
+There are several examples of <filename>libpq++</filename> 
+applications in
+<filename>src/libpq++/examples</filename>, including the source
+code for the three examples in this chapter.
+
+<sect1>
+<title>Control and Initialization</title>
+
+<para>
+
+<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 the <xref linkend="libpq" endterm="libpq-envars"> for a complete
+list of available connection options.
+</note>
+
+<Para>
+The following environment variables can be used to select default
+connection parameter values, which will be used by PQconnectdb or
+PQsetdbLogin if no value is directly specified by the calling code.
+These are useful to avoid hard-coding database names into simple
+application programs.
+
+<ItemizedList>
+<ListItem>
+<Para>
+<Acronym>PGHOST</Acronym> sets the default server name.
+If a non-zero-length string is specified, TCP/IP communication is used.
+Without a host name, libpq will connect using a local Unix domain socket.
+</Para>
+</ListItem>
+<ListItem>
+<Para>
+<Acronym>PGPORT</Acronym>  sets the default port or local Unix domain socket
+file extension for communicating with the <ProductName>Postgres</ProductName>
+backend.
+</Para>
+</ListItem>
+<ListItem>
+<Para>
+<Acronym>PGDATABASE</Acronym>  sets the default 
+<ProductName>Postgres</ProductName> database name.
+</Para>
+</ListItem>
+<ListItem>
+<Para>
+<Acronym>PGUSER</Acronym>
+sets the username used to connect to the database and for authentication.
+</Para>
+</ListItem>
+<ListItem>
+<Para>
+<Acronym>PGPASSWORD</Acronym>
+sets the password used if the backend demands password authentication.
+</Para>
+</ListItem>
+<ListItem>
+<Para>
+<Acronym>PGREALM</Acronym> sets the Kerberos realm to  use  with  
+<ProductName>Postgres</ProductName>,
+  if  it is different from the local realm.  If
+<Acronym>PGREALM</Acronym> is set, <ProductName>Postgres</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>
+<Acronym>PGOPTIONS</Acronym> sets additional runtime  options  for  
+the <ProductName>Postgres</ProductName> backend.
+</Para>
+</ListItem>
+<ListItem>
+<Para>
+<Acronym>PGTTY</Acronym> sets the file or tty 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 Postgres session:
+
+<ItemizedList>
+<ListItem>
+<Para>
+<Acronym>PGDATESTYLE</Acronym>
+sets the default style of date/time representation.
+</Para>
+</ListItem>
+<ListItem>
+<Para>
+<Acronym>PGTZ</Acronym>
+sets the default time zone.
+</Para>
+</ListItem>
+</ItemizedList>
+</Para>
+
+<Para>
+The following environment variables can be used to specify default internal
+behavior for every Postgres session:
+
+<ItemizedList>
+<ListItem>
+<Para>
+<Acronym>PGGEQO</Acronym>
+sets the default mode for the genetic optimizer.
+</Para>
+</ListItem>
+<ListItem>
+<Para>
+<Acronym>PGRPLANS</Acronym>
+sets the default mode to allow or disable right-sided plans in the optimizer.
+</Para>
+</ListItem>
+<ListItem>
+<Para>
+<Acronym>PGCOSTHEAP</Acronym>
+sets the default cost for heap searches for the optimizer.
+</Para>
+</ListItem>
+<ListItem>
+<Para>
+<Acronym>PGCOSTINDEX</Acronym>
+sets the default cost for indexed searches for the 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>
+
+<sect1>
+<title>Database Connection Functions</title>
+
+<para>
+
+<sect2>
+<title>Database Environment Class: <classname>PGenv</classname></title>
+
+<para>
+The database environment class provides C++ objects for manipulating the
+above environment variables:
+
+<itemizedlist>
+<listitem>
+<para>
+<function>PGenv</function>
+creates an environment for the running program.
+
+<synopsis>
+PGenv()
+PGenv(char* auth, char* host, char* port, char* option, char* tty)
+</synopsis>
+
+The first form of this object's constructor sets up the defaults for
+the program from the environment variables listed above.
+The second allows the programmer to hardcode the values into the program.
+The values of the second form relate directly to the environment variables
+above.
+
+</itemizedlist>
+
+<sect2>
+<title>Database Class: <classname>PGdatabase</classname></title>
+
+<para>
+The database class is a provides C++ objects that have a connection
+to a backend server. To create such an object one first need
+the apropriate environment for the backend to access.
+The following constructors deal with making a connection to a backend
+server from a C++ program.
+
+<itemizedlist>
+<listitem>
+<para>
+<function>PGdatabase</function>
+makes a new connection to a backend database server.
+<synopsis>
+PGdatabase(PGenv *env, char *dbName)
+</synopsis>
+After a PGdatabase has been created it should be checked to make sure
+the connection to the database succeded before sending
+queries to the object. This can easily be done by
+retrieving the current status of the PGdatabase object with the
+<function>status</function> method.
+
+<listitem>
+<para>
+<function>status</function>
+returns the status of the PGdatabase object.
+<synopsis>
+ConnStatus PGdatabase::status()
+</synopsis>
+
+The following values are allowed:
+<simplelist>
+<member>
+CONNECTION_OK
+<member>
+CONNECTION_BAD
+</simplelist>
+
+</itemizedlist>
+
+<sect1>
+<title>Query Execution Functions</title>
+
+<para>
+<itemizedlist>
+<listitem>
+<para>
+<function>PGdatabase::exec</function>
+submits a query to <productname>Postgres</productname> 
+and returns result status. In case of an error 
+<function>PGdatabase::errormessage</function>
+can be used to get more information on the error.
+<synopsis>
+void ExecStatusType PGdatabase::exec(char *query);
+</synopsis>
+
+The following status results can be expected:
+
+<simplelist>
+<member>
+PGRES_EMPTY_QUERY
+<member>
+PGRES_COMMAND_OK, if the query was a command
+<member>
+PGRES_TUPLES_OK, if the query successfully returned tuples
+<member>
+PGRES_COPY_OUT
+<member>
+PGRES_COPY_IN
+<member>
+PGRES_BAD_RESPONSE, if an unexpected response was received
+<member>
+PGRES_NONFATAL_ERROR
+<member>
+PGRES_FATAL_ERROR
+</simplelist>
+
+</itemizedlist>
+
+<para>
+If the result status is PGRES_TUPLES_OK, then the following routines can
+be used to retrieve the tuples returned by the query.
+
+<itemizedlist>
+<listitem>
+<para>
+<function>PGdatabase::ntuples</function>
+returns the number of tuples (instances) in the query result.
+<synopsis>
+int PGdatabase::ntuples()
+</synopsis>
+
+<listitem>
+<para>
+<function>PGdatabase::nfields</function>
+returns the number of fields (attributes) in the query result.
+<synopsis>
+int PGdatabase::nfields()
+</synopsis>
+
+<listitem>
+<para>
+<function>PGdatabase::fieldname</function>
+returns the field (attribute) name associated with the given field index.
+Field indices start at zero.
+<synopsis>
+char* PGdatabase::fieldname(int field_index)
+</synopsis>
+
+<listitem>
+<para>
+<function>PGdatabase::fieldnum</function>
+returns the field (attribute) index associated with the given field name.
+<synopsis>
+int PGdatabase::fieldnum(char* field_name)
+</synopsis>
+
+<listitem>
+<para>
+<function>PGdatabase::fieldtype</function>
+returns the field type of associated with the given field index or name.
+The integer returned is an internal coding of the type. Field indices start
+at zero.
+<synopsis>
+Oid PGdatabase::fieldtype(int field_index)
+Oid PGdatabase::fieldtype(char* field_name)
+</synopsis>
+
+<listitem>
+<para>
+<function>PGdatabase::fieldsize</function>
+returns the size in bytes of the field associated with the given field
+index or name. If the size returned is -1, the field is a variable length
+field. Field indices start at zero. 
+<synopsis>
+int2 PGdatabase::fieldsize(int field_index)
+int2 PGdatabase::fieldsize(char* field_name)
+</synopsis>
+
+<listitem>
+<para>
+<function>PGdatabase::getvalue</function>
+returns the field (attribute) value.  For most queries, the values
+returned by 
+<function>PGdatabase::getvalue</function>
+is a null-terminated ASCII string representation
+of the attribute value.  If the query was a result of a 
+<parameter>BINARY</parameter>
+cursor, then the values returned by
+<function>PGdatabase::getvalue</function>
+is the binary representation of the type in the internal format of the
+backend server.  It is the programmer's responsibility to cast and
+convert the data to the correct C++ type.  The value return by 
+<function>PGdatabase::getvalue</function>
+points to storage that is part of the <classname>PGdatabase</classname> structure.
+  One must
+explicitly copy the value into other storage if it is to be used past
+the next query.
+<synopsis>
+char* PGdatabase::getvalue(int tup_num, int field_index)
+char* PGdatabase::getvalue(int tup_num, char* field_name)
+</synopsis>
+
+<listitem>
+<para>
+<function>PGdatabase::getlength</function>
+returns the length of a field (attribute) in bytes.  If the field
+is a <literal>struct varlena</literal>,
+the length returned here does 
+<emphasis>not</emphasis>
+include the size field of the <literal>varlena</literal>, 
+i.e., it is 4 bytes less.
+<synopsis>
+int PGdatabase::getlength(int tup_num, int field_index)
+int PGdatabase::getlength(int tup_num, char* field_name)
+</synopsis>
+
+<listitem>
+<para>
+<function>PGdatabase::printtuples</function>
+prints out all the tuples and, optionally, the attribute names to the
+specified output stream.
+<synopsis>
+void PGdatabase::printtuples(
+       FILE* fout,      /* output stream */
+       int printAttName,/* print attribute names or not*/
+       int terseOutput, /* delimiter bars or not?*/
+       int width        /* width of column, variable width if 0*/
+       );
+</synopsis>
+
+</itemizedlist>
+
+<sect1>
+<title>Asynchronous Notification</title>
+
+<para>
+<productname>Postgres</productname> supports asynchronous notification 
+via the <command>LISTEN</command> and <command>NOTIFY</command>
+commands.  A backend registers its interest in a particular semaphore
+with the <command>LISTEN</command> command.
+  All backends that are listening on a
+particular named semaphore 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 the relation.
+
+<note>
+<para>
+In the past, the documentation has associated the names used for asyncronous
+notification with relations or classes. However, there is in fact no
+direct linkage of the two concepts in the implementation, and the
+named semaphore in fact does not need to have a corresponding relation
+previously defined.
+</note>
+
+<para>
+<filename>libpq++</filename> 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 <filename>libpq++</filename> application
+must poll the backend to see if there is any pending notification
+information.  After the execution of a query, 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 eturns NULL if there is 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>
+
+</itemizedlist>
+
+<para>
+The second sample program gives an example of the use of asynchronous
+notification.
+
+<sect1>
+<title>Functions Associated with the COPY Command</title>
+
+<para>
+The <command>copy</command> command in <productname>Postgres</productname> 
+has options to read from or write to the network
+connection used by <filename>libpq++</filename>.  
+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>
+Like the Unix system routine
+<function>fgets (3)</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 (3)</function>,
+however, in that it converts the terminating newline into a null
+character.
+
+<para>
+<function>PGdatabase::getline</function>
+returns EOF 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>
+Notice that the application must check to see if a new line consists
+of a single period ("."), 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.
+
+<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>
+The application must explicitly send a single period character (".")
+to indicate to the backend that it has finished sending its data.
+
+<listitem>
+<para>
+<function>PGdatabase::endcopy</function>
+syncs 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 query.
+
+<para>
+The return value is 0 on successful completion, nonzero otherwise.
+
+</itemizedlist>
+
+<para>
+As an example:
+
+<programlisting>
+PGdatabase data;
+data.exec("create table foo (a int4, b char16, d float8)");
+data.exec("copy foo from stdin");
+data.putline("3\etHello World\et4.5\en");
+data.putline("4\etGoodbye World\et7.11\en");
+\&...
+data.putline(".\en");
+data.endcopy();
+
+</programlisting>
+
+<sect1>
+<title>Caveats</title>
+
+<para>
+The query buffer is 8192 bytes long, and queries over that length will
+be silently truncated.
+
+<para>
+The <classname>PGlobj</classname> class is largely untested.  Use with caution.
+
+</chapter>
\ No newline at end of file
index a78fdb6..c38ef7c 100644 (file)
@@ -51,7 +51,7 @@ header file <FileName>libpq-fe.h</FileName> and must link with the
 <Para>
 <Function>PQsetdbLogin</Function> 
           Makes a new connection to a backend.
-<ProgramListing>
+<synopsis>
 PGconn *PQsetdbLogin(const char *pghost,
                 const char *pgport,
                 const char *pgoptions,
@@ -59,7 +59,7 @@ PGconn *PQsetdbLogin(const char *pghost,
                 const char *dbName,
                 const char *login,
                 const char *pwd)
-</ProgramListing>
+</synopsis>
           If  any  argument  is NULL, then the corresponding
           environment variable (see "Environment Variables" section)
           is checked. If the  environment  variable
@@ -73,13 +73,13 @@ PGconn *PQsetdbLogin(const char *pghost,
 <Para>
 <Function>PQsetdb</Function> 
           Makes a new connection to a backend.
-<ProgramListing>
+<synopsis>
 PGconn *PQsetdb(char *pghost,
                 char *pgport,
                 char *pgoptions,
                 char *pgtty,
                 char *dbName)
-</ProgramListing>
+</synopsis>
           This is a macro that calls PQsetdbLogin() with null pointers
           for the login and pwd parameters.  It is provided primarily
          for backward compatibility with old programs.
@@ -90,9 +90,9 @@ PGconn *PQsetdb(char *pghost,
 <Para>
 <Function>PQconnectdb</Function> 
           Makes a new connection to a backend.
-<ProgramListing>
+<synopsis>
 PGconn *PQconnectdb(const char *conninfo)
-</ProgramListing>
+</synopsis>
           This routine opens a new database connection using parameters
           taken from a string.  Unlike PQsetdbLogin(), the parameter set
           can be extended without changing the function signature, so use
@@ -162,7 +162,7 @@ default values for unspecified options.
 <Para>
 <Function>PQconndefaults</Function>  
          Returns the default connection options.
-<ProgramListing>
+<synopsis>
 PQconninfoOption *PQconndefaults(void)
 
 struct PQconninfoOption
@@ -181,7 +181,7 @@ struct PQconninfoOption
                int     dispsize;  /* Field size in characters for dialog */
        };
 
-</ProgramListing>
+</synopsis>
        Returns the address of the connection options structure.  This may
        be used to determine all possible PQconnectdb options and their
        current default values.  The return value points to an array of
@@ -197,9 +197,9 @@ struct PQconninfoOption
 <Function>PQfinish</Function>
           Close  the  connection to the backend.  Also frees
           memory used by the PGconn object.
-<ProgramListing>
+<synopsis>
 void PQfinish(PGconn *conn)
-</ProgramListing>
+</synopsis>
 Note that even if the backend connection attempt fails (as
 indicated by PQstatus), the application should call PQfinish
 to free the memory used by the PGconn object.
@@ -211,9 +211,9 @@ The PGconn pointer should not be used after PQfinish has been called.
 <Para>
 <Function>PQreset</Function>
           Reset the communication  port  with  the  backend.
-<ProgramListing>
+<synopsis>
 void PQreset(PGconn *conn)
-</ProgramListing>
+</synopsis>
           This function will close the connection
           to the backend and attempt to  reestablish  a  new
           connection to the same postmaster, using all the same
@@ -240,9 +240,9 @@ soon.)
 <Para>
 <Function>PQdb</Function>  
          Returns the database name of the connection.
-<ProgramListing>
+<synopsis>
 char *PQdb(PGconn *conn)
-</ProgramListing>
+</synopsis>
 PQdb and the next several functions return the values established
 at connection.  These values are fixed for the life of the PGconn
 object.
@@ -253,9 +253,9 @@ object.
 <Para>
 <Function>PQuser</Function>
          Returns the user name of the connection.
-<ProgramListing>
+<synopsis>
 char *PQuser(PGconn *conn)
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 
@@ -263,9 +263,9 @@ char *PQuser(PGconn *conn)
 <Para>
 <Function>PQpass</Function>
          Returns the password of the connection.
-<ProgramListing>
+<synopsis>
 char *PQpass(PGconn *conn)
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 
@@ -273,9 +273,9 @@ char *PQpass(PGconn *conn)
 <Para>
 <Function>PQhost</Function>
          Returns the server host name of the connection.
-<ProgramListing>
+<synopsis>
 char *PQhost(PGconn *conn)
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 
@@ -283,9 +283,9 @@ char *PQhost(PGconn *conn)
 <Para>
 <Function>PQport</Function>
          Returns the port of the connection.
-<ProgramListing>
+<synopsis>
 char *PQport(PGconn *conn)
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 
@@ -293,9 +293,9 @@ char *PQport(PGconn *conn)
 <Para>
 <Function>PQtty</Function>
          Returns the debug tty of the connection.
-<ProgramListing>
+<synopsis>
 char *PQtty(PGconn *conn)
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 
@@ -303,9 +303,9 @@ char *PQtty(PGconn *conn)
 <Para>
 <Function>PQoptions</Function>
        Returns the backend options used in  the  connection.
-<ProgramListing>
+<synopsis>
 char *PQoptions(PGconn *conn)
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 
@@ -314,10 +314,11 @@ char *PQoptions(PGconn *conn)
 <Function>PQstatus</Function>
          Returns the status of the connection. 
          The status can be CONNECTION_OK or CONNECTION_BAD.
-<ProgramListing>
+<synopsis>
 ConnStatusType *PQstatus(PGconn *conn)
-</ProgramListing>
-</Para>
+</synopsis>
+
+<Para>
 A failed connection attempt is signaled by status CONNECTION_BAD.
 Ordinarily, an OK status will remain so until PQfinish, but a
 communications failure might result in the status changing to
@@ -330,10 +331,11 @@ try to recover by calling PQreset.
 <Function>PQerrorMessage</Function>
          Returns the error message most recently generated by
          an operation on the connection.
-<ProgramListing>
+<synopsis>
 char *PQerrorMessage(PGconn* conn);
-</ProgramListing>
-</Para>
+</synopsis>
+
+<Para>
 Nearly all libpq functions will set PQerrorMessage if they fail.
 Note that by libpq convention, a non-empty PQerrorMessage will
 include a trailing newline.
@@ -344,9 +346,9 @@ include a trailing newline.
 <Function>PQbackendPID</Function>
          Returns the process ID of the backend server handling this
         connection.
-<ProgramListing>
+<synopsis>
 int PQbackendPID(PGconn *conn);
-</ProgramListing>
+</synopsis>
 The backend PID is useful for debugging purposes and for comparison
 to NOTIFY messages (which include the PID of the notifying backend).
 Note that the PID belongs to a process executing on the database
@@ -371,10 +373,10 @@ SQL queries and commands.
 <Function>PQexec</Function>
           Submit a query to <ProductName>Postgres</ProductName>
           and wait for the result.
-<ProgramListing>
+<synopsis>
 PGresult *PQexec(PGconn *conn,
                  const char *query);
-</ProgramListing>
+</synopsis>
           Returns  a  PGresult pointer or possibly a NULL pointer.
           A non-NULL pointer will generally be returned except in
           out-of-memory conditions or serious errors such as inability
@@ -405,7 +407,7 @@ soon.)
 <Para>
 <Function>PQresultStatus</Function>
           Returns the result status of the query.  PQresultStatus can return one of the following values:
-<ProgramListing>
+<synopsis>
 PGRES_EMPTY_QUERY,
 PGRES_COMMAND_OK,  /* the query was a command returning no data */
 PGRES_TUPLES_OK,  /* the query successfully returned tuples */
@@ -414,7 +416,7 @@ PGRES_COPY_IN,  /* Copy In (to server) data transfer started */
 PGRES_BAD_RESPONSE, /* an unexpected response was received */
 PGRES_NONFATAL_ERROR,
 PGRES_FATAL_ERROR
-</ProgramListing>
+</synopsis>
           If  the result status is PGRES_TUPLES_OK, then the
           routines described below can be  used  to  retrieve  the
           tuples returned by the query.  Note that a SELECT that
@@ -428,9 +430,9 @@ PGRES_FATAL_ERROR
 <Function>PQresultErrorMessage</Function>
 returns the error message associated with the query, or an empty string
 if there was no error.
-<ProgramListing>
+<synopsis>
 const char *PQresultErrorMessage(PGresult *res);
-</ProgramListing>
+</synopsis>
 Immediately following a PQexec or PQgetResult call, PQerrorMessage
 (on the connection) will return the same string as PQresultErrorMessage
 (on the result).  However, a PGresult will retain its error message
@@ -446,9 +448,9 @@ when you want to know the status from the latest operation on the connection.
 <Function>PQntuples</Function>
           Returns the number of tuples (instances)
           in the query result.
-<ProgramListing>
+<synopsis>
 int PQntuples(PGresult *res);
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 
@@ -457,9 +459,9 @@ int PQntuples(PGresult *res);
 <Function>PQnfields</Function>
           Returns   the   number    of    fields
           (attributes) in each tuple of the query result.
-<ProgramListing>
+<synopsis>
 int PQnfields(PGresult *res);
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 
@@ -468,9 +470,9 @@ int PQnfields(PGresult *res);
 <Function>PQbinaryTuples</Function>
           Returns 1 if the PGresult contains binary tuple data,
          0 if it contains ASCII data.
-<ProgramListing>
+<synopsis>
 int PQbinaryTuples(PGresult *res);
-</ProgramListing>
+</synopsis>
 Currently, binary tuple data can only be returned by a query that
 extracts data from a <Acronym>BINARY</Acronym> cursor.
 </Para>
@@ -479,12 +481,12 @@ extracts data from a <Acronym>BINARY</Acronym> cursor.
 <ListItem>
 <Para>
 <Function>PQfname</Function>
-            Returns the field (attribute) name associated with the given field  index.   Field  indices
         start at 0.
-<ProgramListing>
+ Returns the field (attribute) name associated with the given field  index.
Field  indices start at 0.
+<synopsis>
 char *PQfname(PGresult *res,
               int field_index);
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 
@@ -493,11 +495,12 @@ char *PQfname(PGresult *res,
 <Function>PQfnumber</Function>
             Returns  the  field  (attribute)  index
           associated with the given field name.
-<ProgramListing>
+<synopsis>
 int PQfnumber(PGresult *res,
               char* field_name);
-</ProgramListing>
-</Para>
+</synopsis>
+
+<Para>
         -1 is returned if the given name does not match any field.
 </ListItem>
 
@@ -508,10 +511,10 @@ int PQfnumber(PGresult *res,
           given  field  index.  The  integer  returned is an
           internal coding of the type.  Field indices  start
           at 0.
-<ProgramListing>
+<synopsis>
 Oid PQftype(PGresult *res,
             int field_num);
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 
@@ -522,10 +525,10 @@ Oid PQftype(PGresult *res,
           associated with the given field index. If the size
           returned  is  -1,  the  field is a variable length
           field.  Field indices start at 0.
-<ProgramListing>
+<synopsis>
 int PQfsize(PGresult *res,
             int field_index);
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 
@@ -535,10 +538,10 @@ int PQfsize(PGresult *res,
           Returns  the type-specific modification data of the field
           associated with the given field index.
           Field indices start at 0.
-<ProgramListing>
+<synopsis>
 int PQfmod(PGresult *res,
            int field_index);
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 
@@ -548,11 +551,11 @@ int PQfmod(PGresult *res,
             Returns a single field  (attribute)  value of one tuple
            of a PGresult.
            Tuple and field indices start at 0.
-<ProgramListing>
+<synopsis>
 char* PQgetvalue(PGresult *res,
                  int tup_num,
                  int field_num);
-</ProgramListing>
+</synopsis>
           For most queries, the value returned by PQgetvalue
           is a null-terminated ASCII  string  representation
           of the attribute value.  If the query extracted data from
@@ -574,11 +577,11 @@ char* PQgetvalue(PGresult *res,
 <Function>PQgetisnull</Function>
            Tests a field for a NULL entry.
            Tuple and field indices start at 0.
-<ProgramListing>
+<synopsis>
 int PQgetisnull(PGresult *res,
                 int tup_num,
                 int field_num);
-</ProgramListing>
+</synopsis>
             This function returns  1 if the field contains a NULL, 0 if
             it contains a non-null value.  (Note that PQgetvalue
             will return an empty string, not a null pointer, for a NULL
@@ -592,11 +595,11 @@ int PQgetisnull(PGresult *res,
           Returns   the   length  of  a  field
           (attribute) in bytes.
           Tuple and field indices start at 0.
-<ProgramListing>
+<synopsis>
 int PQgetlength(PGresult *res,
                 int tup_num,
                 int field_num);
-</ProgramListing>
+</synopsis>
 This is the actual data length for the particular data value,
 whereas PQfsize shows the allocated space for all entries in
 this column.
@@ -612,9 +615,9 @@ If the field  is  a  struct
 <Function>PQcmdStatus</Function>
           Returns the command status string from the SQL command that
          generated the PGresult.
-<ProgramListing>
+<synopsis>
 char *PQcmdStatus(PGresult *res);
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 
@@ -622,9 +625,9 @@ char *PQcmdStatus(PGresult *res);
 <Para>
 <Function>PQcmdTuples</Function>
          Returns the number of rows affected by the SQL command.
-<ProgramListing>
+<synopsis>
 const char *PQcmdTuples(PGresult *res);
-</ProgramListing>
+</synopsis>
           If the SQL command that generated the
          PGresult was INSERT, UPDATE or DELETE, this returns a
          string containing the number of rows affected.  If the
@@ -638,9 +641,9 @@ const char *PQcmdTuples(PGresult *res);
           Returns a string with the object id of  the  tuple
           inserted,  if  the SQL command was an INSERT.
           Otherwise, returns an empty string.
-<ProgramListing>
+<synopsis>
 char* PQoidStatus(PGresult *res);
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 
@@ -649,7 +652,7 @@ char* PQoidStatus(PGresult *res);
 <Function>PQprint</Function>
           Prints out all the  tuples  and,  optionally,  the
           attribute  names  to  the specified output stream.
-<ProgramListing>
+<synopsis>
 void PQprint(FILE* fout,      /* output stream */
              PGresult* res,
              PQprintOpt* po);
@@ -667,7 +670,7 @@ struct _PQprintOpt
                char    *caption;    /* HTML &lt;caption&gt; */
                char    **fieldName; /* null terminated array of replacement field names */
        };
-</ProgramListing>
+</synopsis>
        This function is intended to replace PQprintTuples(), which is
        now obsolete.  The <FileName>psql</FileName> program uses
        PQprint() to display query results.
@@ -679,13 +682,13 @@ struct _PQprintOpt
 <Function>PQprintTuples</Function>
           Prints out all the  tuples  and,  optionally,  the
           attribute  names  to  the specified output stream.
-<ProgramListing>
+<synopsis>
 void PQprintTuples(PGresult* res,
                    FILE* fout,      /* output stream */
                    int printAttName,/* print attribute names or not*/
                    int terseOutput, /* delimiter bars or not?*/
                    int width);      /* width of column, variable width if 0*/
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 
@@ -694,14 +697,14 @@ void PQprintTuples(PGresult* res,
 <Function>PQdisplayTuples</Function>
           Prints out all the  tuples  and,  optionally,  the
           attribute  names  to  the specified output stream.
-<ProgramListing>
+<synopsis>
 void PQdisplayTuples(PGresult* res,
                      FILE* fout,           /* output stream */
                      int fillAlign,        /* space fill to align columns */
                      const char *fieldSep, /* field separator */
                      int printHeader,      /* display headers? */
                      int quiet);           /* suppress print of row count at end */
-</ProgramListing>
+</synopsis>
           PQdisplayTuples() was intended to supersede PQprintTuples(), and
           is in turn superseded by PQprint().
 </Para>
@@ -712,9 +715,9 @@ void PQdisplayTuples(PGresult* res,
           Frees  the  storage  associated with the PGresult.
           Every query result should be freed via PQclear  when
           it  is  no  longer needed.
-<ProgramListing>
+<synopsis>
 void PQclear(PQresult *res);
-</ProgramListing>
+</synopsis>
           You can keep a PGresult object around for as long as you
           need it; it does not go away when you issue a new query,
           nor even if you close the connection.  To get rid of it,
@@ -727,9 +730,9 @@ void PQclear(PQresult *res);
 <Para>
 <Function>PQmakeEmptyPGresult</Function>
           Constructs an empty PGresult object with the given status.
-<ProgramListing>
+<synopsis>
 PGresult* PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status);
-</ProgramListing>
+</synopsis>
 This is libpq's internal routine to allocate and initialize an empty
 PGresult object.  It is exported because some applications find it
 useful to generate result objects (particularly objects with error
@@ -791,10 +794,10 @@ PQgetResult.
          waiting for the result(s).  TRUE is returned if the query was
          successfully dispatched, FALSE if not (in which case, use
          PQerrorMessage to get more information about the failure).
-<ProgramListing>
+<synopsis>
 int PQsendQuery(PGconn *conn,
                 const char *query);
-</ProgramListing>
+</synopsis>
          After successfully calling PQsendQuery, call PQgetResult one or more
          times to obtain the query results.  PQsendQuery may not be called
          again (on the same connection) until PQgetResult has returned NULL,
@@ -808,9 +811,9 @@ int PQsendQuery(PGconn *conn,
           Wait for the next result from a prior PQsendQuery,
          and return it.  NULL is returned when the query is complete
          and there will be no more results.
-<ProgramListing>
+<synopsis>
 PGresult *PQgetResult(PGconn *conn);
-</ProgramListing>
+</synopsis>
          PQgetResult must be called repeatedly until it returns NULL,
          indicating that the query is done.  (If called when no query is
          active, PQgetResult will just return NULL at once.)
@@ -842,9 +845,9 @@ functions:
 <Para>
 <Function>PQconsumeInput</Function>
          If input is available from the backend, consume it.
-<ProgramListing>
+<synopsis>
 int PQconsumeInput(PGconn *conn);
-</ProgramListing>
+</synopsis>
 PQconsumeInput normally returns 1 indicating "no error", but returns
 0 if there was some kind of trouble (in which case PQerrorMessage
 is set).  Note that the result does not say whether any input data
@@ -866,9 +869,9 @@ has changed.
          Returns TRUE if a query is busy, that is, PQgetResult would block
          waiting for input.  A FALSE return indicates that PQgetResult can
          be called with assurance of not blocking.
-<ProgramListing>
+<synopsis>
 int PQisBusy(PGconn *conn);
-</ProgramListing>
+</synopsis>
          PQisBusy will not itself attempt to read data from the backend;
          therefore PQconsumeInput must be invoked first, or the busy
          state will never end.
@@ -881,9 +884,9 @@ int PQisBusy(PGconn *conn);
          Obtain the file descriptor number for the backend connection socket.
          A valid descriptor will be >= 0; a result of -1 indicates that
          no backend connection is currently open.
-<ProgramListing>
+<synopsis>
 int PQsocket(PGconn *conn);
-</ProgramListing>
+</synopsis>
          PQsocket should be used to obtain the backend socket descriptor
          in preparation for executing select(2).  This allows an application
          to wait for either backend responses or other conditions.
@@ -919,9 +922,9 @@ a query that is still being processed by the backend.
 <Function>PQrequestCancel</Function>
          Request that <ProductName>Postgres</ProductName> abandon
          processing of the current query.
-<ProgramListing>
+<synopsis>
 int PQrequestCancel(PGconn *conn);
-</ProgramListing>
+</synopsis>
          The return value is TRUE if the cancel request was successfully
          dispatched, FALSE if not.  (If not, PQerrorMessage tells why not.)
          Successful dispatch is no guarantee that the request will have any
@@ -963,7 +966,7 @@ or the backend is not currently processing a query.
  calls to the backend.  This  is  a  trapdoor  into
      system  internals and can be a potential security hole.
      Most users will not need this feature.
-<ProgramListing>
+<synopsis>
 PGresult* PQfn(PGconn* conn,
                int fnid,
                int *result_buf,
@@ -971,7 +974,7 @@ PGresult* PQfn(PGconn* conn,
                int result_is_int,
                PQArgBlock *args,
                int nargs);
-</ProgramListing>
+</synopsis>
      The fnid argument is the object identifier of the function to be
      executed.
      result_buf is the buffer in which
@@ -982,7 +985,7 @@ PGresult* PQfn(PGconn* conn,
      value, than result_is_int should be set to 1; otherwise
      it  should  be  set  to  0.  args and nargs specify the
      arguments to the function.
-<ProgramListing>
+<synopsis>
 typedef struct {
              int len;
              int isint;
@@ -991,7 +994,7 @@ typedef struct {
                  int integer;
              } u;
          } PQArgBlock;
-</ProgramListing>
+</synopsis>
      PQfn always returns a valid PGresult*.  The  resultStatus  should be checked before the result is used.   The
      caller is responsible for  freeing  the  PGresult  with
      PQclear when it is no longer needed.
@@ -1032,9 +1035,9 @@ messages can be detected by calling PQnotifies().
           there are no pending notifications.  Once a notification is
          returned from PQnotifies, it is considered handled and will be
          removed from the list of notifications.
-<ProgramListing>
+<synopsis>
 PGnotify* PQnotifies(PGconn *conn);
-</ProgramListing>
+</synopsis>
          After processing a PGnotify object returned by PQnotifies,
          be sure to free it with free() to avoid a memory leak.
 </Para>
@@ -1087,11 +1090,11 @@ processing of the query.
           Reads  a  newline-terminated  line  of  characters
           (transmitted  by the backend server) into a buffer
           string of size length.
-<ProgramListing>
+<synopsis>
 int PQgetline(PGconn *conn,
               char *string,
               int length)
-</ProgramListing>
+</synopsis>
   Like fgets(3),  this  routine copies up to length-1 characters into string.
           It is like gets(3), however, in that  it  converts
           the terminating newline into a null character.
@@ -1121,11 +1124,11 @@ contains routines that correctly handle  the  copy protocol.
           Reads  a  newline-terminated  line  of  characters
           (transmitted  by the backend server) into a buffer
           without blocking.
-<ProgramListing>
+<synopsis>
 int PQgetlineAsync(PGconn *conn,
                    char *buffer,
                    int bufsize)
-</ProgramListing>
+</synopsis>
 This routine is similar to PQgetline, but it can be used by applications
 that must read COPY data asynchronously, that is without blocking.
 Having issued the COPY command and gotten a PGRES_COPY_OUT response, the
@@ -1156,10 +1159,10 @@ actually available.)
 <Function>PQputline</Function>
 Sends  a  null-terminated  string  to  the backend server.
 Returns 0 if OK, EOF if unable to send the string.
-<ProgramListing>
+<synopsis>
 int PQputline(PGconn *conn,
               char *string);
-</ProgramListing>
+</synopsis>
 Note the application must explicitly  send  the  two
 characters  "\." on a final line  to indicate to the backend that it
 has finished sending its data.
@@ -1171,11 +1174,11 @@ has finished sending its data.
 <Function>PQputnbytes</Function>
 Sends  a  non-null-terminated  string  to  the backend server.
 Returns 0 if OK, EOF if unable to send the string.
-<ProgramListing>
+<synopsis>
 int PQputnbytes(PGconn *conn,
                 const char *buffer,
                 int nbytes);
-</ProgramListing>
+</synopsis>
 This is exactly like PQputline, except that the data buffer need
 not be null-terminated since the number of bytes to send is
 specified directly.
@@ -1196,9 +1199,9 @@ specified directly.
           receive the next query.
           The return value is 0  on  successful  completion,
           nonzero otherwise.
-<ProgramListing>
+<synopsis>
 int PQendcopy(PGconn *conn);
-</ProgramListing>
+</synopsis>
 
 <Para>
 As an example:
@@ -1244,10 +1247,10 @@ SQL command in the query string.
 <Para>
 <Function>PQtrace</Function>
           Enable  tracing of the frontend/backend communication to a debugging file stream.
-<ProgramListing>
+<synopsis>
 void PQtrace(PGconn *conn
              FILE *debug_port)
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 
@@ -1255,9 +1258,9 @@ void PQtrace(PGconn *conn
 <Para>
 <Function>PQuntrace</Function>
           Disable tracing started by PQtrace
-<ProgramListing>
+<synopsis>
 void PQuntrace(PGconn *conn)
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 </ItemizedList>
@@ -1275,11 +1278,11 @@ void PQuntrace(PGconn *conn)
 <Para>
 <Function>PQsetNoticeProcessor</Function>
 Control reporting of notice and warning messages generated by libpq.
-<ProgramListing>
+<synopsis>
 void PQsetNoticeProcessor (PGconn * conn,
         void (*noticeProcessor) (void * arg, const char * message),
         void * arg)
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 </ItemizedList>
@@ -1330,9 +1333,9 @@ routines no longer have any effect and should not be used.
           user name is not the same as  value  of  the  <Acronym>USER</Acronym>
           environment   variable  or  the  user's  entry  in
           <FileName>/etc/passwd</FileName>.
-<ProgramListing>
+<synopsis>
 char *fe_getauthname(char* errorMessage)
-</ProgramListing>
+</synopsis>
 </Para>
 </ListItem>
 
@@ -1343,10 +1346,10 @@ char *fe_getauthname(char* errorMessage)
           service  name rather than its compiled-in default.
           This value is typically taken from a  command-line
           switch.
-<ProgramListing>
+<synopsis>
 void fe_setauthsvc(char *name,
                    char* errorMessage)
-</ProgramListing>
+</synopsis>
           Any   error   messages   from  the  authentication
           attempts are returned in  the  errorMessage  argument.
 </Para>
@@ -1356,7 +1359,7 @@ void fe_setauthsvc(char *name,
 
 </Sect1>
 
-<Sect1>
+<Sect1 id="libpq-envars">
 <Title>Environment Variables</Title>
 
 <Para>
@@ -1383,7 +1386,8 @@ backend.
 </ListItem>
 <ListItem>
 <Para>
-<Acronym>PGDATABASE</Acronym>  sets the default <ProductName>Postgres</ProductName> database name.
+<Acronym>PGDATABASE</Acronym>  sets the default 
+<ProductName>Postgres</ProductName> database name.
 </Para>
 </ListItem>
 <ListItem>
@@ -1400,9 +1404,11 @@ sets the password used if the backend demands password authentication.
 </ListItem>
 <ListItem>
 <Para>
-<Acronym>PGREALM</Acronym> sets the Kerberos realm to  use  with  <ProductName>Postgres</ProductName>,
+<Acronym>PGREALM</Acronym> sets the Kerberos realm to  use  with  
+<ProductName>Postgres</ProductName>,
   if  it is different from the local realm.  If
-<Acronym>PGREALM</Acronym> is set, <ProductName>Postgres</ProductName> applications  will  attempt
+<Acronym>PGREALM</Acronym> is set, <ProductName>Postgres</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
@@ -1411,12 +1417,14 @@ sets the password used if the backend demands password authentication.
 </ListItem>
 <ListItem>
 <Para>
-<Acronym>PGOPTIONS</Acronym> sets additional runtime  options  for  the <ProductName>Postgres</ProductName> backend.
+<Acronym>PGOPTIONS</Acronym> sets additional runtime  options  for  
+the <ProductName>Postgres</ProductName> backend.
 </Para>
 </ListItem>
 <ListItem>
 <Para>
-<Acronym>PGTTY</Acronym> sets the file or tty on which  debugging  messages from the backend server are displayed.
+<Acronym>PGTTY</Acronym> sets the file or tty on which  debugging  
+messages from the backend server are displayed.
 </Para>
 </ListItem>
 </ItemizedList>
@@ -1498,115 +1506,115 @@ for information on correct values for these environment variables.
 
 <Para>
 <ProgramListing>
-         /*
-          * testlibpq.c
-          *   Test the C version of LIBPQ, the <ProductName>Postgres</ProductName> frontend library.
-          *
-          *
-          */
-         #include &lt;stdio.h&gt;
-         #include "libpq-fe.h"
-
-         void
-         exit_nicely(PGconn* conn)
-         {
-           PQfinish(conn);
-           exit(1);
-         }
-
-         main()
-         {
-           char *pghost, *pgport, *pgoptions, *pgtty;
-           char* dbName;
-           int nFields;
-           int i,j;
-
-         /*  FILE *debug; */
-
-           PGconn* conn;
-           PGresult* res;
-
-           /* begin, by setting the parameters for a backend connection
-              if the parameters are null, then the system will try to use
-              reasonable defaults by looking up environment variables
-              or, failing that, using hardwired constants */
-           pghost = NULL;  /* host name of the backend server */
-           pgport = NULL;  /* port of the backend server */
-           pgoptions = NULL; /* special options to start up the backend server */
-           pgtty = NULL;     /* debugging tty for the backend server */
-           dbName = "template1";
-
-           /* make a connection to the database */
-           conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
-
-           /* check to see that the backend connection was successfully made */
-           if (PQstatus(conn) == CONNECTION_BAD) {
-             fprintf(stderr,"Connection to database '&percnt;s' failed.\n", dbName);
-             fprintf(stderr,"&percnt;s",PQerrorMessage(conn));
-             exit_nicely(conn);
-           }
-
-         /*  debug = fopen("/tmp/trace.out","w");  */
-         /*   PQtrace(conn, debug);  */
-
-           /* start a transaction block */
-
-           res = PQexec(conn,"BEGIN");
-           if (PQresultStatus(res) != PGRES_COMMAND_OK) {
-             fprintf(stderr,"BEGIN command failed\n");
-             PQclear(res);
-             exit_nicely(conn);
-           }
-           /* should PQclear PGresult whenever it is no longer needed to avoid
-              memory leaks */
-           PQclear(res);
-
-           /* fetch instances from the pg_database, the system catalog of databases*/
-           res = PQexec(conn,"DECLARE mycursor CURSOR FOR select * from pg_database");
-           if (PQresultStatus(res) != PGRES_COMMAND_OK) {
-             fprintf(stderr,"DECLARE CURSOR command failed\n");
-             PQclear(res);
-             exit_nicely(conn);
-           }
-           PQclear(res);
-
-           res = PQexec(conn,"FETCH ALL in mycursor");
-           if (PQresultStatus(res) != PGRES_TUPLES_OK) {
-             fprintf(stderr,"FETCH ALL command didn't return tuples properly\n");
-             PQclear(res);
-             exit_nicely(conn);
-           }
-
-           /* first, print out the attribute names */
-           nFields = PQnfields(res);
-           for (i=0; i &lt; nFields; i++) {
-             printf("&percnt;-15s",PQfname(res,i));
-           }
-           printf("\n");
-
-           /* next, print out the instances */
-           for (i=0; i &lt; PQntuples(res); i++) {
-             for (j=0  ; j &lt; nFields; j++) {
-               printf("&percnt;-15s", PQgetvalue(res,i,j));
-             }
-             printf("\n");
-           }
-
-           PQclear(res);
-
-           /* close the cursor */
-           res = PQexec(conn, "CLOSE mycursor");
-           PQclear(res);
-
-           /* end the transaction */
-           res = PQexec(conn, "END");
-           PQclear(res);
-
-           /* close the connection to the database and cleanup */
-           PQfinish(conn);
-
-         /*   fclose(debug); */
-         }
+/*
+* testlibpq.c
+*   Test the C version of LIBPQ,
++   the <ProductName>Postgres</ProductName> frontend library.
+*
+*
+*/
+#include &lt;stdio.h&gt;
+#include "libpq-fe.h"
+
+void
+exit_nicely(PGconn* conn)
+{
+     PQfinish(conn);
+     exit(1);
+}
+
+main()
+{
+  char *pghost, *pgport, *pgoptions, *pgtty;
+  char* dbName;
+  int nFields;
+  int i,j;
+
+/*  FILE *debug; */
+
+  PGconn* conn;
+  PGresult* res;
+
+  /* begin, by setting the parameters for a backend connection
+     if the parameters are null, then the system will try to use
+     reasonable defaults by looking up environment variables
+     or, failing that, using hardwired constants */
+  pghost = NULL;  /* host name of the backend server */
+  pgport = NULL;  /* port of the backend server */
+  pgoptions = NULL; /* special options to start up the backend server */
+  pgtty = NULL;     /* debugging tty for the backend server */
+  dbName = "template1";
+
+  /* make a connection to the database */
+  conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
+
+  /* check to see that the backend connection was successfully made */
+  if (PQstatus(conn) == CONNECTION_BAD) {
+    fprintf(stderr,"Connection to database '&percnt;s' failed.\n", dbName);
+    fprintf(stderr,"&percnt;s",PQerrorMessage(conn));
+    exit_nicely(conn);
+  }
+
+  /*  debug = fopen("/tmp/trace.out","w");  */
+  /*   PQtrace(conn, debug);  */
+
+  /* start a transaction block */
+
+  res = PQexec(conn,"BEGIN");
+  if (PQresultStatus(res) != PGRES_COMMAND_OK) {
+    fprintf(stderr,"BEGIN command failed\n");
+    PQclear(res);
+    exit_nicely(conn);
+  }
+  /* should PQclear PGresult when done to avoid memory leaks */
+  PQclear(res);
+
+  /* fetch instances from the pg_database, the system catalog of databases*/
+  res = PQexec(conn,"DECLARE mycursor CURSOR FOR select * from pg_database");
+  if (PQresultStatus(res) != PGRES_COMMAND_OK) {
+    fprintf(stderr,"DECLARE CURSOR command failed\n");
+    PQclear(res);
+    exit_nicely(conn);
+  }
+  PQclear(res);
+
+  res = PQexec(conn,"FETCH ALL in mycursor");
+  if (PQresultStatus(res) != PGRES_TUPLES_OK) {
+    fprintf(stderr,"FETCH ALL command didn't return tuples properly\n");
+    PQclear(res);
+    exit_nicely(conn);
+  }
+
+  /* first, print out the attribute names */
+  nFields = PQnfields(res);
+  for (i=0; i &lt; nFields; i++) {
+    printf("&percnt;-15s",PQfname(res,i));
+  }
+  printf("\n");
+
+  /* next, print out the instances */
+  for (i=0; i &lt; PQntuples(res); i++) {
+    for (j=0  ; j &lt; nFields; j++) {
+      printf("&percnt;-15s", PQgetvalue(res,i,j));
+    }
+    printf("\n");
+  }
+
+  PQclear(res);
+
+  /* close the cursor */
+  res = PQexec(conn, "CLOSE mycursor");
+  PQclear(res);
+
+  /* end the transaction */
+  res = PQexec(conn, "END");
+  PQclear(res);
+
+  /* close the connection to the database and cleanup */
+  PQfinish(conn);
+
+/*   fclose(debug); */
+}
 </ProgramListing>
 </Para>
 </Sect2>
@@ -1616,96 +1624,97 @@ for information on correct values for these environment variables.
 
 <Para>
 <ProgramListing>
-         /*
-          * testlibpq2.c
-          *   Test of the asynchronous notification interface
-          *
-            populate a database with the following:
-
-         CREATE TABLE TBL1 (i int4);
-
-         CREATE TABLE TBL2 (i int4);
-
-         CREATE RULE r1 AS ON INSERT TO TBL1 DO [INSERT INTO TBL2 values (new.i); NOTIFY TBL2];
-
-          * Then start up this program
-          * After the program has begun, do
-
-         INSERT INTO TBL1 values (10);
-
-          *
-          *
-          */
-         #include &lt;stdio.h&gt;
-         #include "libpq-fe.h"
-
-         void exit_nicely(PGconn* conn)
-         {
-           PQfinish(conn);
-           exit(1);
-         }
-
-         main()
-         {
-           char *pghost, *pgport, *pgoptions, *pgtty;
-           char* dbName;
-           int nFields;
-           int i,j;
-
-           PGconn* conn;
-           PGresult* res;
-           PGnotify* notify;
-
-           /* begin, by setting the parameters for a backend connection
-              if the parameters are null, then the system will try to use
-              reasonable defaults by looking up environment variables
-              or, failing that, using hardwired constants */
-           pghost = NULL;  /* host name of the backend server */
-           pgport = NULL;  /* port of the backend server */
-           pgoptions = NULL; /* special options to start up the backend server */
-           pgtty = NULL;     /* debugging tty for the backend server */
-           dbName = getenv("USER"); /* change this to the name of your test database*/
-
-           /* make a connection to the database */
-           conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
-
-           /* check to see that the backend connection was successfully made */
-           if (PQstatus(conn) == CONNECTION_BAD) {
-             fprintf(stderr,"Connection to database '&percnt;s' failed.\n", dbName);
-             fprintf(stderr,"&percnt;s",PQerrorMessage(conn));
-             exit_nicely(conn);
-           }
-
-           res = PQexec(conn, "LISTEN TBL2");
-           if (PQresultStatus(res) != PGRES_COMMAND_OK) {
-             fprintf(stderr,"LISTEN command failed\n");
-             PQclear(res);
-             exit_nicely(conn);
-           }
-           /* should PQclear PGresult whenever it is no longer needed to avoid
-              memory leaks */
-           PQclear(res);
-
-           while (1) {
-              /* wait a little bit between checks;
-               * waiting with select() would be more efficient.
-               */
-              sleep(1);
-              /* collect any asynchronous backend messages */
-              PQconsumeInput(conn);
-               /* check for asynchronous notify messages */
-               while ((notify = PQnotifies(conn)) != NULL) {
-                fprintf(stderr,
-                     "ASYNC NOTIFY of '&percnt;s' from backend pid '&percnt;d' received\n",
-                     notify-&gt;relname, notify-&gt;be_pid);
-                free(notify);
-               }
-           }
-
-           /* close the connection to the database and cleanup */
-           PQfinish(conn);
-
-         }
+/*
+ * testlibpq2.c
+ *   Test of the asynchronous notification interface
+ *
+   populate a database with the following:
+
+   CREATE TABLE TBL1 (i int4);
+
+   CREATE TABLE TBL2 (i int4);
+
+   CREATE RULE r1 AS ON INSERT TO TBL1 
+   DO [INSERT INTO TBL2 values (new.i); NOTIFY TBL2];
+
+* Then start up this program
+* After the program has begun, do
+
+   INSERT INTO TBL1 values (10);
+
+*
+*
+*/
+#include &lt;stdio.h&gt;
+#include "libpq-fe.h"
+
+void exit_nicely(PGconn* conn)
+{
+  PQfinish(conn);
+  exit(1);
+}
+
+main()
+{
+  char *pghost, *pgport, *pgoptions, *pgtty;
+  char* dbName;
+  int nFields;
+  int i,j;
+
+  PGconn* conn;
+  PGresult* res;
+  PGnotify* notify;
+
+  /* begin, by setting the parameters for a backend connection
+     if the parameters are null, then the system will try to use
+     reasonable defaults by looking up environment variables
+     or, failing that, using hardwired constants */
+  pghost = NULL;  /* host name of the backend server */
+  pgport = NULL;  /* port of the backend server */
+  pgoptions = NULL; /* special options to start up the backend server */
+  pgtty = NULL;     /* debugging tty for the backend server */
+  dbName = getenv("USER"); /* change this to the name of your test database*/
+
+  /* make a connection to the database */
+  conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
+
+  /* check to see that the backend connection was successfully made */
+  if (PQstatus(conn) == CONNECTION_BAD) {
+    fprintf(stderr,"Connection to database '&percnt;s' failed.\n", dbName);
+    fprintf(stderr,"&percnt;s",PQerrorMessage(conn));
+    exit_nicely(conn);
+  }
+
+  res = PQexec(conn, "LISTEN TBL2");
+  if (PQresultStatus(res) != PGRES_COMMAND_OK) {
+    fprintf(stderr,"LISTEN command failed\n");
+    PQclear(res);
+    exit_nicely(conn);
+  }
+  /* should PQclear PGresult whenever it is no longer needed to avoid
+     memory leaks */
+  PQclear(res);
+
+  while (1) {
+    /* wait a little bit between checks;
+     * waiting with select() would be more efficient.
+     */
+    sleep(1);
+    /* collect any asynchronous backend messages */
+    PQconsumeInput(conn);
+    /* check for asynchronous notify messages */
+    while ((notify = PQnotifies(conn)) != NULL) {
+      fprintf(stderr,
+        "ASYNC NOTIFY of '&percnt;s' from backend pid '&percnt;d' received\n",
+        notify-&gt;relname, notify-&gt;be_pid);
+      free(notify);
+    }
+  }
+
+  /* close the connection to the database and cleanup */
+  PQfinish(conn);
+
+}
 </ProgramListing>
 </Para>
 </Sect2>
@@ -1715,154 +1724,158 @@ for information on correct values for these environment variables.
 
 <Para>
 <ProgramListing>
-         /*
-          * testlibpq3.c
-          *   Test the C version of LIBPQ, the <ProductName>Postgres</ProductName> frontend library.
-          *   tests the binary cursor interface
-          *
-          *
-          *
-          populate a database by doing the following:
-
-         CREATE TABLE test1 (i int4, d float4, p polygon);
-
-         INSERT INTO test1 values (1, 3.567, '(3.0, 4.0, 1.0, 2.0)'::polygon);
-
-         INSERT INTO test1 values (2, 89.05, '(4.0, 3.0, 2.0, 1.0)'::polygon);
-
-          the expected output is:
-
-         tuple 0: got
-          i = (4 bytes) 1,
-          d = (4 bytes) 3.567000,
-          p = (4 bytes) 2 points         boundbox = (hi=3.000000/4.000000, lo = 1.000000,2.000000)
-         tuple 1: got
-          i = (4 bytes) 2,
-          d = (4 bytes) 89.050003,
-          p = (4 bytes) 2 points         boundbox = (hi=4.000000/3.000000, lo = 2.000000,1.000000)
-
-          *
-          */
-         #include &lt;stdio.h&gt;
-         #include "libpq-fe.h"
-         #include "utils/geo-decls.h" /* for the POLYGON type */
-
-         void exit_nicely(PGconn* conn)
-         {
-           PQfinish(conn);
-           exit(1);
-         }
-
-         main()
-         {
-           char *pghost, *pgport, *pgoptions, *pgtty;
-           char* dbName;
-           int nFields;
-           int i,j;
-           int i_fnum, d_fnum, p_fnum;
-
-           PGconn* conn;
-           PGresult* res;
-
-           /* begin, by setting the parameters for a backend connection
-              if the parameters are null, then the system will try to use
-              reasonable defaults by looking up environment variables
-              or, failing that, using hardwired constants */
-           pghost = NULL;  /* host name of the backend server */
-           pgport = NULL;  /* port of the backend server */
-           pgoptions = NULL; /* special options to start up the backend server */
-           pgtty = NULL;     /* debugging tty for the backend server */
-
-           dbName = getenv("USER");  /* change this to the name of your test database*/
-
-           /* make a connection to the database */
-           conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
-
-           /* check to see that the backend connection was successfully made */
-           if (PQstatus(conn) == CONNECTION_BAD) {
-             fprintf(stderr,"Connection to database '&percnt;s' failed.\n", dbName);
-             fprintf(stderr,"&percnt;s",PQerrorMessage(conn));
-             exit_nicely(conn);
-           }
-
-           /* start a transaction block */
-           res = PQexec(conn,"BEGIN");
-           if (PQresultStatus(res) != PGRES_COMMAND_OK) {
-             fprintf(stderr,"BEGIN command failed\n");
-             PQclear(res);
-             exit_nicely(conn);
-           }
-           /* should PQclear PGresult whenever it is no longer needed to avoid
-              memory leaks */
-           PQclear(res);
-
-           /* fetch instances from the pg_database, the system catalog of databases*/
-           res = PQexec(conn,"DECLARE mycursor BINARY CURSOR FOR select * from test1");
-           if (PQresultStatus(res) != PGRES_COMMAND_OK) {
-             fprintf(stderr,"DECLARE CURSOR command failed\n");
-             PQclear(res);
-             exit_nicely(conn);
-           }
-           PQclear(res);
-
-           res = PQexec(conn,"FETCH ALL in mycursor");
-           if (PQresultStatus(res) != PGRES_TUPLES_OK) {
-             fprintf(stderr,"FETCH ALL command didn't return tuples properly\n");
-             PQclear(res);
-             exit_nicely(conn);
-           }
-
-           i_fnum = PQfnumber(res,"i");
-           d_fnum = PQfnumber(res,"d");
-           p_fnum = PQfnumber(res,"p");
-
-           for (i=0;i&lt;3;i++) {
-               printf("type[&percnt;d] = &percnt;d, size[&percnt;d] = &percnt;d\n",
-                   i, PQftype(res,i),
-                   i, PQfsize(res,i));
-           }
-           for (i=0; i &lt; PQntuples(res); i++) {
-             int *ival;
-             float *dval;
-             int plen;
-             POLYGON* pval;
-             /*/
-             ival =  (int*)PQgetvalue(res,i,i_fnum);
-             dval =  (float*)PQgetvalue(res,i,d_fnum);
-             plen = PQgetlength(res,i,p_fnum);
-
-             /* plen doesn't include the length field so need to increment by VARHDSZ*/
-             pval = (POLYGON*) malloc(plen + VARHDRSZ);
-             pval-&gt;size = plen;
-             memmove((char*)&amp;pval-&gt;npts, PQgetvalue(res,i,p_fnum), plen);
-             printf("tuple &percnt;d: got\n", i);
-             printf(" i = (&percnt;d bytes) &percnt;d,\n",
-                 PQgetlength(res,i,i_fnum), *ival);
-             printf(" d = (&percnt;d bytes) &percnt;f,\n",
-                 PQgetlength(res,i,d_fnum), *dval);
-             printf(" p = (&percnt;d bytes) &percnt;d points boundbox = (hi=&percnt;f/&percnt;f, lo = &percnt;f,&percnt;f)\n",
-                 PQgetlength(res,i,d_fnum),
-                 pval-&gt;npts,
-                 pval-&gt;boundbox.xh,
-                 pval-&gt;boundbox.yh,
-                 pval-&gt;boundbox.xl,
-                 pval-&gt;boundbox.yl);
-           }
-
-           PQclear(res);
-
-           /* close the cursor */
-           res = PQexec(conn, "CLOSE mycursor");
-           PQclear(res);
-
-           /* end the transaction */
-           res = PQexec(conn, "END");
-           PQclear(res);
-
-           /* close the connection to the database and cleanup */
-           PQfinish(conn);
-
-         }
+/*
+ * testlibpq3.c
+ *   Test the C version of LIBPQ,
+ +   the <ProductName>Postgres</ProductName> frontend library
+ *   tests the binary cursor interface
+ *
+ *
+ *
+   populate a database by doing the following:
+
+   CREATE TABLE test1 (i int4, d float4, p polygon);
+
+   INSERT INTO test1 values (1, 3.567, '(3.0, 4.0, 1.0, 2.0)'::polygon);
+
+   INSERT INTO test1 values (2, 89.05, '(4.0, 3.0, 2.0, 1.0)'::polygon);
+
+   the expected output is:
+
+  tuple 0: got
+  i = (4 bytes) 1,
+  d = (4 bytes) 3.567000,
+  p = (4 bytes) 2 points
+         boundbox = (hi=3.000000/4.000000, lo = 1.000000,2.000000)
+ tuple 1: got
+  i = (4 bytes) 2,
+  d = (4 bytes) 89.050003,
+  p = (4 bytes) 2 points
+         boundbox = (hi=4.000000/3.000000, lo = 2.000000,1.000000)
+ *
+ */
+#include &lt;stdio.h&gt;
+#include "libpq-fe.h"
+#include "utils/geo-decls.h" /* for the POLYGON type */
+
+void exit_nicely(PGconn* conn)
+{
+  PQfinish(conn);
+  exit(1);
+}
+
+main()
+{
+  char *pghost, *pgport, *pgoptions, *pgtty;
+  char* dbName;
+  int nFields;
+  int i,j;
+  int i_fnum, d_fnum, p_fnum;
+
+  PGconn* conn;
+  PGresult* res;
+
+  /* begin, by setting the parameters for a backend connection
+     if the parameters are null, then the system will try to use
+     reasonable defaults by looking up environment variables
+     or, failing that, using hardwired constants */
+  pghost = NULL;  /* host name of the backend server */
+  pgport = NULL;  /* port of the backend server */
+  pgoptions = NULL; /* special options to start up the backend server */
+  pgtty = NULL;     /* debugging tty for the backend server */
+
+  dbName = getenv("USER");  /* change this to the name of your test database*/
+
+  /* make a connection to the database */
+  conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
+
+  /* check to see that the backend connection was successfully made */
+  if (PQstatus(conn) == CONNECTION_BAD) {
+    fprintf(stderr,"Connection to database '&percnt;s' failed.\n", dbName);
+    fprintf(stderr,"&percnt;s",PQerrorMessage(conn));
+    exit_nicely(conn);
+  }
+
+  /* start a transaction block */
+  res = PQexec(conn,"BEGIN");
+  if (PQresultStatus(res) != PGRES_COMMAND_OK) {
+    fprintf(stderr,"BEGIN command failed\n");
+    PQclear(res);
+    exit_nicely(conn);
+  }
+  /* should PQclear PGresult whenever it is no longer needed to avoid
+     memory leaks */
+  PQclear(res);
+
+  /* fetch instances from the pg_database, the system catalog of databases*/
+  res = PQexec(conn,"DECLARE mycursor BINARY CURSOR FOR select * from test1");
+  if (PQresultStatus(res) != PGRES_COMMAND_OK) {
+    fprintf(stderr,"DECLARE CURSOR command failed\n");
+    PQclear(res);
+    exit_nicely(conn);
+  }
+  PQclear(res);
+
+  res = PQexec(conn,"FETCH ALL in mycursor");
+  if (PQresultStatus(res) != PGRES_TUPLES_OK) {
+    fprintf(stderr,"FETCH ALL command didn't return tuples properly\n");
+    PQclear(res);
+    exit_nicely(conn);
+  }
+
+  i_fnum = PQfnumber(res,"i");
+  d_fnum = PQfnumber(res,"d");
+  p_fnum = PQfnumber(res,"p");
+
+  for (i=0;i&lt;3;i++) {
+      printf("type[&percnt;d] = &percnt;d, size[&percnt;d] = &percnt;d\n",
+ i, PQftype(res,i),
+          i, PQfsize(res,i));
+  }
+  for (i=0; i &lt; PQntuples(res); i++) {
+    int *ival;
+    float *dval;
+    int plen;
+    POLYGON* pval;
+    /*/
+    ival =  (int*)PQgetvalue(res,i,i_fnum);
+    dval =  (float*)PQgetvalue(res,i,d_fnum);
+    plen = PQgetlength(res,i,p_fnum);
+
+    /* plen doesn't include the length field so need to increment by VARHDSZ*/
+    pval = (POLYGON*) malloc(plen + VARHDRSZ);
+    pval-&gt;size = plen;
+    memmove((char*)&amp;pval-&gt;npts, PQgetvalue(res,i,p_fnum), plen);
+    printf("tuple &percnt;d: got\n", i);
+    printf(" i = (&percnt;d bytes) &percnt;d,\n",
+        PQgetlength(res,i,i_fnum), *ival);
+    printf(" d = (&percnt;d bytes) &percnt;f,\n",
+        PQgetlength(res,i,d_fnum), *dval);
+    printf(" p = (&percnt;d bytes) &percnt;d points"
+           " boundbox = (hi=&percnt;f/&percnt;f"
+           ", lo = &percnt;f,&percnt;f)\n",
+        PQgetlength(res,i,d_fnum),
+        pval-&gt;npts,
+        pval-&gt;boundbox.xh,
+        pval-&gt;boundbox.yh,
+        pval-&gt;boundbox.xl,
+        pval-&gt;boundbox.yl);
+  }
+
+  PQclear(res);
+
+  /* close the cursor */
+  res = PQexec(conn, "CLOSE mycursor");
+  PQclear(res);
+
+  /* end the transaction */
+  res = PQexec(conn, "END");
+  PQclear(res);
+
+  /* close the connection to the database and cleanup */
+  PQfinish(conn);
+
+}
 </ProgramListing>
 <Para>
 
index 4ecc1d4..223eb41 100644 (file)
@@ -41,34 +41,41 @@ This could be anything from a text file to an Oracle or
 <productname>Postgres</productname> <acronym>RDBMS</acronym>.
 
 <Para>
-The backend access come from <acronym>ODBC</acronym> drivers, or vendor specifc drivers that
-allow data access.   <productname>psqlODBC</productname> is such a driver, along with others that are
+The backend access come from <acronym>ODBC</acronym> drivers, 
+or vendor specifc drivers that
+allow data access.   <productname>psqlODBC</productname> is such a driver,
+ along with others that are
 available, such as the OpenLink <acronym>ODBC</acronym> drivers.
 
 <Para>
-Once you write an <acronym>ODBC</acronym> application, you SHOULD be able to connect to ANY
+Once you write an <acronym>ODBC</acronym> application, 
+you <emphasis>should</emphasis> be able to connect to <emphasis>any</emphasis>
 back end database, regardless of the vendor, as long as the database schema
 is the same.
 
 <Para>
 For example. you could have <productname>MS SQL Server</productname>
  and <productname>Postgres</productname> servers which have
-exactly the same data.  Using <acronym>ODBC</acronym>, your Windows app would make exactly the
-same calls and the back end data source would look the same (to the windows
+exactly the same data.  Using <acronym>ODBC</acronym>, 
+your Windows app would make exactly the
+same calls and the back end data source would look the same (to the Windows
 app).
 
 <para>
-<ulink url="http://www.insightdist.com/">Insight Distributors</ulink> provides active and ongoing
-support for the core <productname>psqlODBC</productname> distribution. They provide a
-<ulink url="http://www.insightdist.com/psqlodbc/"><acronym>FAQ</acronym></ulink>, ongoing development
-on the code base, and actively participate on the 
+<ulink url="http://www.insightdist.com/">Insight Distributors</ulink> 
+provides active and ongoing
+support for the core <productname>psqlODBC</productname> distribution. 
+They provide a
+<ulink url="http://www.insightdist.com/psqlodbc/"><acronym>FAQ</acronym></ulink>,
+ ongoing development on the code base, and actively participate on the 
 <ulink url="mailto:interfaces@postgresql.org">interfaces mailing list</ulink>.
 
 <sect1>
 <title><productname>Windows</productname> Applications</title>
 
 <Para>
-In the real world, differences in drivers and the level of <acronym>ODBC</acronym> support
+In the real world, differences in drivers and the level of 
+<acronym>ODBC</acronym> support
 lessens the potential of <acronym>ODBC</acronym>:
 
 <SimpleList>
@@ -76,7 +83,8 @@ lessens the potential of <acronym>ODBC</acronym>:
 Access, Delphi, and Visual Basic all support <acronym>ODBC</acronym> directly.
 
 <Member>
-Under C++, such as Visual C++, you can use the C++ <acronym>ODBC</acronym> <acronym>API</acronym>.
+Under C++, such as Visual C++, 
+you can use the C++ <acronym>ODBC</acronym> <acronym>API</acronym>.
 
 <Member>
 In Visual C++, you can use the CRecordSet class, which wraps the 
@@ -88,24 +96,27 @@ Windows C++ development under Windows NT.
 <Para>
 If I write an app for <productname>Postgres</productname> 
 can I write it using <acronym>ODBC</acronym> calls
-to the <productname>Postgres</productname> server, or is that only when another database program 
+to the <productname>Postgres</productname> server, 
+or is that only when another database program 
 like MS SQL Server or Access needs to access the data?
 
 <Para>
-Again, the <acronym>ODBC</acronym> <acronym>API</acronym> set is the way to go.
-You can find out more at
-Microsoft's web site or in your Visual C++ docs (if that's what you are using.)
+Again, the <acronym>ODBC</acronym> <acronym>API</acronym> set 
+is the way to go.
+For <productname>Visual C++</productname> you can find out more at
+Microsoft's web site or in your docs.
 
 <Para>
-Visual Basic and the other RAD tools have Recordset objects that use <acronym>ODBC</acronym>
+Visual Basic and the other RAD tools have Recordset objects 
+that use <acronym>ODBC</acronym>
 directly to access data.  Using the data-aware controls, you can quickly
-link to the <acronym>ODBC</acronym> back end database (<Emphasis>very</Emphasis> quickly).
+link to the <acronym>ODBC</acronym> back end database 
+(<Emphasis>very</Emphasis> quickly).
 
 <Para>
 Playing around with MS Access will help you sort this out.  Try using
-File->Get External Data
+<literal>File->Get External Data</literal>.
 
-<Para>
 <Tip>
 <Para>
 You'll have to set up a DSN first.
@@ -125,21 +136,103 @@ The <productname>Postgres</productname> datetime type will break MS Access.
 <title>Unix Applications</title>
 
 <para>
-<productname>ApplixWare</productname> has an <acronym>ODBC</acronym> database interface
-supported on at least some platforms. <productname>ApplixWare</productname> v4.4.1 has been
+<productname>ApplixWare</productname> has an 
+<acronym>ODBC</acronym> database interface
+supported on at least some platforms. 
+<productname>ApplixWare</productname> v4.4.1 has been
 demonstrated under Linux with <productname>Postgres</productname> v6.4 
 using the <productname>psqlODBC</productname>
 driver contained in the <productname>Postgres</productname> distribution.
 
 <sect2>
+<title>Building the Driver</title>
+
+<para>
+The driver can be built in a standalone, client-only installation, or can be 
+built as a part of the main <productname>Postgres</productname> distribution.
+The standalone installation is convenient if you have <acronym>ODBC</acronym>
+client applications on multiple, heterogeneous platforms. The integrated
+installation is convenient when the target client is the same as the
+server, or when the client and server have similar runtime configurations.
+
+<sect3>
+<title>Integrated Installation</title>
+
+<para>
+For an integrated installation, specify the <option>--with-odbc</option>
+command-line argument for src/configure:
+
+<programlisting>
+./configure --with-odbc
+</programlisting>
+
+Once configured, the <acronym>ODBC</acronym> driver will be built and installed
+into the areas defined for the other components of the
+<productname>Postgres</productname> system. The installation-wide
+<acronym>ODBC</acronym> configuration file will be placed into
+the top directory of the Postgres target tree (<envar>POSTGRESDIR</envar>).
+This can be overridden from the <application>make</application> command-line
+as
+<programlisting>
+% make ODBCINST=<replaceable>filename</replaceable>
+</programlisting>
+
+<sect3>
+<title>Standalone Installation</title>
+
+<para>
+A standalone installation is not integrated with or built on the normal
+<productname>Postgres</productname> distribution. It should be best suited
+for building the <acronym>ODBC</acronym> driver for multiple, heterogeneous
+clients who do not have a locally-installed <productname>Postgres</productname>
+source tree.
+
+<para>
+The standalone installation distribution can be built from the
+<productname>Postgres</productname> distribution or may be obtained
+from <ulink url="http://insightdist.com/psqlodbc">Insight Distributors</ulink>,
+the current maintainers of the non-Unix sources.
+
+<para>
+To create a tar file for a complete standalone installation, first
+configure the main <productname>Postgres</productname> distribution.
+Then, create the tar file:
+
+<programlisting>
+% cd interfaces/odbc
+% make standalone
+</programlisting>
+
+<para>
+Copy the output tar file to your target system, unpack it into a clean
+directory, and then:
+
+<programlisting>
+% ./configure --with-odbcinst=<replaceable>instfile</replaceable>
+% make POSTGRESDIR=<replaceable>targettree</replaceable> ODBCINST=<replaceable>instfile</replaceable>
+</programlisting>
+
+<note>
+<para>
+The <envar>ODBCINST</envar> can be specified on either or both command lines.
+</note>
+
+<para>
+If you would like to install components into different trees, then you
+can specify various destinations explicitly:
+
+<programlisting>
+% make BINDIR=<replaceable>bindir</replaceable> LIBDIR=<replaceable>libdir</replaceable> HEADERDIR=<replaceable>headerdir</replaceable> ODBCINST=<replaceable>instfile</replaceable>
+</programlisting>
+
+<sect2>
 <title>Configuration Files</title>
 
 <para>
-The <filename>~/.odbc.ini</filename> contains user-specified access information 
-for the <productname>psqlODBC</productname>
-driver. The file uses conventions typical for <productname>Windows</productname> 
-Registry files, but despite this
-restriction can be made to work.
+<filename>~/.odbc.ini</filename> contains user-specified access information 
+for the <productname>psqlODBC</productname> driver. 
+The file uses conventions typical for <productname>Windows</productname> 
+Registry files, but despite this restriction can be made to work.
 
 <para>
 Here is an example <filename>.odbc.ini</filename> file, 
index 35d478f..08c7e24 100644 (file)
     <ENTRY>linux 2.0.x</ENTRY>
     <ENTRY>x86</ENTRY>
     <ENTRY>v6.4</ENTRY>
-    <ENTRY>1998-09-14</ENTRY>
+    <ENTRY>1998-10-09</ENTRY>
     <ENTRY>(<ULink url="mailto:lockhart@alumni.caltech.edu">Thomas Lockhart</ULink>,
 <ULink url="mailto:t-ishii@sra.co.jp">Tatsuo Ishii</ULink>)</ENTRY>
   </ROW>
   <ROW>
     <ENTRY>SVR4</ENTRY>
     <ENTRY>MIPS</ENTRY>
-    <ENTRY>v6.3</ENTRY>
-    <ENTRY>1998-03-01</ENTRY>
-    <ENTRY>similar to v6.2.1; "mostly working" (<ULink url="mailto:ridderbusch.pad@sni.de">Frank Ridderbusch</ULink>)</ENTRY>
+    <ENTRY>v6.4</ENTRY>
+    <ENTRY>1998-10-08</ENTRY>
+    <ENTRY>no 64-bit int support (<ULink url="mailto:ridderbusch.pad@sni.de">Frank Ridderbusch</ULink>)</ENTRY>
   </ROW>
   <ROW>
     <ENTRY>SVR4 4.4</ENTRY>
   <ROW>
     <ENTRY>Unixware</ENTRY>
     <ENTRY>x86</ENTRY>
-    <ENTRY>v6.3</ENTRY>
-    <ENTRY>1998-03-01</ENTRY>
+    <ENTRY>v6.4</ENTRY>
+    <ENTRY>1998-10-04</ENTRY>
     <ENTRY>aka UNIVEL (<ULink url="mailto:Bill.Allie@mug.org">Billy G. Allie</ULink>)</ENTRY>
   </ROW>
   <ROW>
-    <ENTRY>NextStep</ENTRY>
+    <ENTRY>Windows NT</ENTRY>
     <ENTRY>x86</ENTRY>
-    <ENTRY>v6.x</ENTRY>
-    <ENTRY>1998-03-01</ENTRY>
-    <ENTRY>client-only support; v1.0.9 worked with patches (<ULink url="mailto:dave@turbocat.de">David Wetzel</ULink>)</ENTRY>
+    <ENTRY>v6.4</ENTRY>
+    <ENTRY>1998-10-08</ENTRY>
+    <ENTRY>Mostly working with the Cygwin library. No DLLs yet. <ulink url="mailto:horak@mmp.plzen-city.cz">Horak Daniel</ulink> </ENTRY>
   </ROW>
 </TBODY>
 </TGROUP>
 </TABLE>
 
+<note>
+<para>
+For <productname>Windows NT</productname>, look for patches on the
+<ulink url="http://postgresql.org">Postgres web site</ulink>.
+</note>
+
 <Sect1>
 <Title>Unsupported Platforms</Title>
 
@@ -238,18 +244,18 @@ Others listed here do not provide sufficient library support for an attempt.
     <ENTRY>Amiga, HP300, Mac; not yet working (<ULink url="mailto:hotz@jpl.nasa.gov">Henry Hotz</ULink>)</ENTRY>
   </ROW>
   <ROW>
-    <ENTRY>Ultrix</ENTRY>
-    <ENTRY>MIPS,VAX?</ENTRY>
+    <ENTRY>NextStep</ENTRY>
+    <ENTRY>x86</ENTRY>
     <ENTRY>v6.x</ENTRY>
     <ENTRY>1998-03-01</ENTRY>
-    <ENTRY>no recent reports; obsolete?</ENTRY>
+    <ENTRY>client-only support; v1.0.9 worked with patches (<ULink url="mailto:dave@turbocat.de">David Wetzel</ULink>)</ENTRY>
   </ROW>
   <ROW>
-    <ENTRY>Windows NT</ENTRY>
-    <ENTRY>all</ENTRY>
-    <ENTRY>v6.3</ENTRY>
+    <ENTRY>Ultrix</ENTRY>
+    <ENTRY>MIPS,VAX?</ENTRY>
+    <ENTRY>v6.x</ENTRY>
     <ENTRY>1998-03-01</ENTRY>
-    <ENTRY>not library compatible; client side maybe; use ODBC/JDBC</ENTRY>
+    <ENTRY>no recent reports; obsolete?</ENTRY>
   </ROW>
   <ROW>
     <ENTRY>Windows</ENTRY>
index 2a5b1c7..301fbb7 100644 (file)
@@ -55,6 +55,7 @@ $log$
 <!entity spi      SYSTEM "spi.sgml">
 <!entity func-ref SYSTEM "func-ref.sgml">
 <!entity libpq    SYSTEM "libpq.sgml">
+<!entity libpqpp  SYSTEM "libpq++.sgml">
 <!entity libpgtcl SYSTEM "libpgtcl.sgml">
 <!entity ecpg     SYSTEM "ecpg.sgml">
 <!entity odbc     SYSTEM "odbc.sgml">
@@ -135,8 +136,8 @@ Your name here...
  now becoming available in some commercial databases.
 It provides SQL92/SQL3 language support,
  transaction integrity, and type extensibility.
- <ProductName>PostgreSQL</ProductName> is a public-domain, open source descendant
- of this original Berkeley code.
+ <ProductName>PostgreSQL</ProductName> is a public-domain, 
+ open source descendant of this original Berkeley code.
 </Para>
 </Preface>
 
@@ -151,16 +152,17 @@ It provides SQL92/SQL3 language support,
 &xindex;
 &gist;
 &dfunc;
-&trigger;
-&spi;
 
 <!-- reference -->
 
 &func-ref;
+&trigger;
+&spi;
 &lobj;
-&ecpg;
 &libpq;
+&libpqpp;
 &libpgtcl;
+&ecpg;
 &odbc;
 &jdbc;