Client 2 - Adding Error Checking

You may have noticed (in client1.cpp) that I did not wrap the definition of the conn variable inside a try{} catch{} block. The PgConnection constructor does not throw any exceptions. If the PgConnection constructor doesn't throw an exception on failure and it doesn't return a status value, how do you tell whether the connection attempt failed?

The next code example (see Listing 10.2) shows you how to detect a connection failure.

Listing 10.2 client2.cpp

/* client2.cpp */

#include <libpq++.h>

#include <iostream.h>

int main( int argc, char * argv[] )


    PgConnection connect( "" );

    if( connect.ConnectionBad())


        cout << "Connection was unsuccessful..." << endl

             << "Error message returned: "

             << connect.ErrorMessage() << endl;

        return( 1 );



After the connect object is initialized, you can call either the PgConnection:: ConnectionBad() or PgConnection::Status() member functions to determine the success or failure of the connection attempt.

The PgConnection::ConnectionBad() member function returns a non-zero value if the connection attempt failed. You could instead use the PgConnection::Status() member function, which returns either CONNECTION_OK or CONNECTION_BAD. You can use whichever of these two functions you find more convenient?they are completely interchangeable.

If the connection attempt has failed, you probably want to know what went wrong. The PgConnection::ErrorMessage() function returns an error message in the form of a NULL-terminated string. The error messages returned by PgConnection::ErrorMessage() are the same as those returned by the PQerrorMessage() function provided by libpq.

Besides the constructor that takes a connection string, PgConnection also provides a protected default constructor (that is, a constructor that takes zero arguments). The default constructor does not connect to a database. Instead, the default constructor simply initializes the PgConnection object. You would use the PgConnection::Connect() function later to create a connection. Using the default constructor gives you more control over the timing of the connection process?you may want to allocate a PgConnection object in one function, but defer the connection attempt until a later time. Notice that the default constructor is "protected"?you can't use that constructor unless you create a new class that inherits from PgConnection.

The Relationship Between libpq and libpq++

I mentioned earlier that libpq++ is a wrapper around the libpq API. The PgConnection class is a wrapper around a PgConn *. If you were to look at the source code for the PgConnection::ErrorMessage() function you would see

const char* PgConnection::ErrorMessage()


    return (const char *)PQerrorMessage(pgConn);


Each PgConnection object contains a PgConn *. The member functions provided by PgConnection correspond closely to the set of libpq functions requiring a PgConn *.

If the PgConnection class doesn't provide a function that you need, you can get to the embedded PgConn *, even though it is declared as protected, by creating your own class that inherits from PgConnection.

Now that you know how to attempt a database connection and how to tell whether the connection succeeded, let's look at the code required to process a simple query.

    Part II: Programming with PostgreSQL