INTRODUCTION(LIBPQ++)
DESCRIPTION
LIBPQ++ is the C++ API to POSTGRES95. LIBPQ++ is a set of
classes which allow client programs to connect to the
POSTGRES95 backend server. These connections come in two
forms: a Database Class and a Large Object class.
The Database Class is intended for manipulating a
database. You can send all sorts of SQL queries to the
POSTGRES95 backend server and retrieve the responses of
the server.
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 POSTGRES95 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 cin, cout and cerr. This version of the documen-
tation is based on the C library. Three short programs
are listed at the end of this section as examples of
LIBPQ++ programming (though not necessarily of good pro-
gramming).
There are several examples of LIBPQ++ applications in the
following directory:
.../src/libpq++/examples
CONTROL AND INITIALIZATION
Environment Variables
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:
PGDATABASE sets the default POSTGRES95 database name.
PGHOST sets the default server name.
PGOPTIONS sets additional runtime options for the
POSTGRES95 backend.
PGPORT sets the default communication port with
the POSTGRES95 backend.
PGTTY sets the file or tty on which debugging
messages from the backend server are dis-
played.
PGREALM sets the Kerberos realm to use with POST-
GRES95, if it is different from the local
realm. If PGREALM is set, POSTGRES95
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 authenti-
cation is enabled.
PGAUTH sets the type of authentication which
should be used. Currently only unauth,
krb4, and krb5. are supported. Depending
on whether you compiled in support for
those.
DATABASE ENVIRONMENT CLASS: PGenv
The database environment class provides C++ objects for
manipulating the above environment variables.
PGenv Create an environment for the running pro-
gram.
PGenv()
PGenv(char* auth, char* host, char* port, char* option, char* tty)
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 hard-
code the values into the program. The val-
ues of the second form relate directly to
the environment variables above.
DATABASE CLASS: PGdatabase
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.
PGdatabase Make a new connection to a backend database
server.
PGdatabase(PGenv *env, char *dbName);
After a PGdatabase has been created it
should be checked to make sure the connec-
tion to the database succeded before send-
ing queries to the object. This can easily
be done by retrieving the current status of
the PGdatabase object with the status com-
mand. PGdatabase::status Returns the sta-
tus of the PGdatabase object.
ConnStatus PGdatabase::status()
the following values are allowed
CONNECTION_OK
CONNECTION_BAD
QUERY EXECUTION FUNCTIONS
PGdatabase::exec
Submits a query to POSTGRES95 and returns
result status. In case of an error
PGdatabase::errormessage can be used to get
more information on the error.
void
ExecStatusType PGdatabase::exec(char *query);
The following status results can be
expected.
PGRES_EMPTY_QUERY,
PGRES_COMMAND_OK, /* the query was a command */
PGRES_TUPLES_OK, /* the query successfully returned tuples */
PGRES_COPY_OUT,
PGRES_COPY_IN,
PGRES_BAD_RESPONSE, /* an unexpected response was received */
PGRES_NONFATAL_ERROR,
PGRES_FATAL_ERROR
If the result status is PGRES_TUPLES_OK,
then the following routines can be used to
retrieve the tuples returned by the query.
PGdatabase::ntuples returns the number of
tuples (instances) in the query result.
int PGdatabase::ntuples();
PGdatabase::nfields returns the number of
fields (attributes) in the query result.
int PGdatabase::nfields();
PGdatabase::fieldname returns the field
(attribute) name associated with the given
field index. Field indices start at 0.
char* PGdatabase::fieldname(int field_index);
PGdatabase::fieldnum returns the field
(attribute) index associated with the given
field name.
int PGdatabase::fieldnum(char* field_name);
PGdatabase::fieldtype 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 0.
Oid PGdatabase::fieldtype(int field_index);
Oid PGdatabase::fieldtype(char* field_name);
PGdatabase::fieldsize 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 0.
int2 PGdatabase::fieldsize(int field_index);
int2 PGdatabase::fieldsize(char* field_name);
PGdatabase::getvalue returns the field
(attribute) value. For most queries, the
values returned by PGdatabase::getvalue is
a null-terminated ASCII string representa-
tion of the attribute value. If the query
was a result of a BINARY cursor, then the
values returned by PGdatabase::getvalue 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
PGdatabase::getvalue points to storage that
is part of the PGdatabase structure. One
must explicitly copy the value into other
storage if it is to be used past the next
query.
char* PGdatabase::getvalue(int tup_num, int field_index);
char* PGdatabase::getvalue(int tup_num, char* field_name);
PGdatabase::getlength returns the length of
a field (attribute) in bytes. If the field
is a struct varlena, the length returned
here does not include the size field of the
varlena, i.e., it is 4 bytes less.
int PGdatabase::getlength(int tup_num, int field_index);
int PGdatabase::getlength(int tup_num, char* field_name);
PGdatabase::printtuples prints out all the
tuples and, optionally, the attribute names
to the specified output stream.
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*/
);
ASYNCHRONOUS NOTIFICATION
POSTGRES95 supports asynchronous notification via the LIS-
TEN and NOTIFY commands. A backend registers its interest
in a particular relation with the LISTEN command. All
backends that are listening on a particular relation will
be notified asynchronously when a NOTIFY of that relation
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 communi-
cated is transferred through the relation.
LIBPQ++ applications are notified whenever a connected
backend has received an asynchronous notification. How-
ever, the communication from the backend to the frontend
is not asynchronous. The LIBPQ++ application must poll
the backend to see if there is any pending notification
information. After the execution of a query, a frontend
may call PGdatabase::notifies to see if any notification
data is currently available from the backend.
PGdatabase::notifies
returns the notification from a list of
unhandled notifications from the backend.
Returns NULL if there is no pending notifi-
cations from the backend.
PGdatabase::notifies behaves like the pop-
ping of a stack. Once a notification is
returned from PGdatabase::notifies, it is
considered handled and will be removed from
the list of notifications.
PGnotify* PGdatabase::notifies()
The second sample program gives an example of the use of
asynchronous notification.
FUNCTIONS ASSOCIATED WITH THE COPY COMMAND
The copy command in POSTGRES95 has options to read from or
write to the network connection used by LIBPQ++. There-
fore, functions are necessary to access this network con-
nection directly so applications may take full advantage
of this capability.
PGdatabase::getline
Reads a newline-terminated line of
characters (transmitted by the backend
server) into a buffer string of size
length. Like fgets(3), this routine copies
up to length-1 characters into string. It
is like gets(3), however, in that it con-
verts the terminating newline into a null
character.
PGdatabase::getline returns EOF at EOF, 0
if the entire line has been read, and 1 if
the buffer is full but the terminating new-
line has not yet been read.
Notice that the application must check to
see if a new line consists of the single
character ".", which indicates that the
backend server has finished sending the
results of the copy command. Therefore, if
the application ever expects to receive
lines that are more than length-1 charac-
ters long, the application must be sure to
check the return value of PGdatabase::get-
line very carefully.
int PGdatabase::getline(char* string, int length)
PGdatabase::putline
Sends a null-terminated string to the back-
end server.
The application must explicitly send the
single character "." to indicate to the
backend that it has finished sending its
data.
void PGdatabase::putline(char* string)
PGdatabase::endcopy
Syncs with the backend. This function
waits until the backend has finished pro-
cessing the copy. It should either be
issued when the last string has been sent
to the backend using PGdatabase::putline or
when the last string has been received from
the backend using PGdatabase::getline. It
must be issued or the backend may get "out
of sync" with the frontend. Upon return
from this function, the backend is ready to
receive the next query.
The return value is 0 on successful
completion, nonzero otherwise.
int PGdatabase::endcopy()
As an example:
PGdatabase data;
data.exec("create table foo (a int4, b char16, d float8)");
data.exec("copy foo from stdin");
data.putline("3\tHello World\t4.5\n");
data.putline("4\tGoodbye World\t7.11\n");
...
data.putline(".\n");
data.endcopy();
BUGS
The query buffer is 8192 bytes long, and queries over that
length will be silently truncated.
The PGlobj class is largely untested. Use with caution.