Clean up markup.

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.
This commit is contained in:
Thomas G. Lockhart 1998-10-10 17:12:18 +00:00
parent 03cb232a1f
commit d98011d8de
9 changed files with 1394 additions and 537 deletions

View 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">

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

View File

@ -21,10 +21,12 @@
<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.
<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
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.

View 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.

584
doc/src/sgml/libpq++.sgml Normal file
View File

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

File diff suppressed because it is too large Load Diff

View 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,

View File

@ -115,7 +115,7 @@
<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>
@ -165,9 +165,9 @@
<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>
@ -179,21 +179,27 @@
<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>
@ -237,6 +243,13 @@ Others listed here do not provide sufficient library support for an attempt.
<ENTRY>1998-03-01</ENTRY>
<ENTRY>Amiga, HP300, Mac; not yet working (<ULink url="mailto:hotz@jpl.nasa.gov">Henry Hotz</ULink>)</ENTRY>
</ROW>
<ROW>
<ENTRY>NextStep</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>
</ROW>
<ROW>
<ENTRY>Ultrix</ENTRY>
<ENTRY>MIPS,VAX?</ENTRY>
@ -244,13 +257,6 @@ Others listed here do not provide sufficient library support for an attempt.
<ENTRY>1998-03-01</ENTRY>
<ENTRY>no recent reports; obsolete?</ENTRY>
</ROW>
<ROW>
<ENTRY>Windows NT</ENTRY>
<ENTRY>all</ENTRY>
<ENTRY>v6.3</ENTRY>
<ENTRY>1998-03-01</ENTRY>
<ENTRY>not library compatible; client side maybe; use ODBC/JDBC</ENTRY>
</ROW>
<ROW>
<ENTRY>Windows</ENTRY>
<ENTRY>x86</ENTRY>

View 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;