Client 2Adding Error Checking

The client1.c application discussed has a fundamental flawthere is no way to tell whether the connection attempt was successful. This next program attempts a connection and displays an error message if the attempt fails:

 1 /*
 2 ** File: client2.c
 3 */
 4
 5 #include 
 6 #include 
 7
 8 int main( int argc, char * argv[] )
 9 {
10 PGconn * connection;
11
12 if( argc != 2 )
13 {
14 printf( "usage : %s "connection-string"
", argv[0] );
15 printf( "example: %s "user=myname password=cows"
", argv[0]);
16 exit( 1 );
17 }
18
19 if(( connection = PQconnectdb( argv[1] )) == NULL )
20 {
21 printf( "Fatal error - unable to allocate connection
" );
22 exit( 1 );
23 }
24
25 if( PQstatus( connection ) != CONNECTION_OK )
26 printf( "%s
", PQerrorMessage( connection ));
27 else
28 printf( "Connection ok, disconnecting
" );
29
30 PQfinish( connection );
31
32 exit( 0 );
33
34 }

You can specify a connection string on the command line when you run this program. If you want to include more than one connection attribute, enclose the entire connection string in double quotes. For example:

$ ./client2 user=korry
Connection ok, disconnecting

$ ./client2 "user=korry password=cows"
Connection ok, disconnecting

I recommend that you run this program a few times, feeding it a variety of invalid connect strings so you become familiar with the error messages that you might receive when things go wrong. For example:

$ ./client2 host=badhost
connectDBStart() -- unknown hostname: badhost

$ ./client2 port=1000
connectDBStart() -- connect() failed: No such file or directory
 Is the postmaster running locally
 and accepting connections on Unix socket '/tmp/.s.PGSQL.1000'?

$ ./client2 badparameter
ERROR: Missing '=' after 'badparameter' in conninfo

$ ./client2 badparameter=1000
ERROR: Unknown conninfo option 'badparameter'

 

Viewing Connection Attributes

In the get_dflts application I showed you how to use the PQconndefaults() function to view the default connection attributes that will be used to establish a connection.

libpq also provides a number of functions that you can use to retrieve the actual connection attributes after you have a PGconn object. These functions are useful because in most situations, you won't explicitly specify every connection attribute. Instead, many (perhaps all) of the connection attributes will be defaulted for you.

PQconnectdb() will return a PGconn pointer in almost every case (PQconnectdb() will return a NULL pointer only if libpq runs out of memory).

The following program attempts to make a connection and then print the set of connection parameters. I've modified client2.c to show the complete set of final connection parameters after a connection attempt. The new application is called client2b:

 1 /*
 2 ** File: client2b.c
 3 */
 4
 5 #include 
 6 #include 
 7
 8 static void show_connection_attributes( const PGconn * conn );
 9 static const char * check( const char * value );
10
11 int main( int argc, char * argv[] )
12 {
13 PGconn * connection;
14
15 if( argc != 2 )
16 {
17 printf( "usage : %s "connection-string"
", argv[0] );
18 printf( "example: %s "user=myname password=cows"
", argv[0]);
19 exit( 1 );
20 }
21
22 if(( connection = PQconnectdb( argv[1] )) == NULL )
23 {
24 printf( "Fatal error - unable to allocate connection
" );
25 exit( 1 );
26 }
27
28 if( PQstatus( connection ) != CONNECTION_OK )
29 printf( "%s
", PQerrorMessage( connection ));
30 else
31 printf( "Connection ok
" );
32
33 show_connection_attributes( connection );
34
35 PQfinish( connection );
36
37 exit( 0 );
38
39 }
40
41 static const char * check( const char * value )
42 {
43 if( value )
44 return( value );
45 else
46 return( "(null)" );
47 }
48
49 static void show_connection_attributes( const PGconn * c )
50 {
51 printf( "dbname = %s
", check( PQdb( c )));
52 printf( "user = %s
", check( PQuser( c )));
53 printf( "password = %s
", check( PQpass( c )));
54 printf( "host = %s
", check( PQhost( c )));
55 printf( "port = %s
", check( PQport( c )));
56 printf( "tty = %s
", check( PQtty( c )));
57 printf( "options = %s
", check( PQoptions( c )));
58 }

Take a look at the show_connection_attributes() function (lines 49-58). Given a PGconn pointer, you can find the connection attributes that result after all the defaults are applied by calling PQdb(), PQuser(), and so on. In some cases, one or more of these functions may return a NULL pointer, so I wrapped each function invocation in a call to check() (lines 41-47) to avoid giving any bad pointers to printf().

If, for some reason, you need to know the process ID of the server that you're connected to, you can retrieve that value by calling the PQbackendPID() function. PQbackendPID() is particularly useful if you're debugging or exploring the PostgreSQL server. You can find the version number of the server using the PQserverVersion() function. PQserverVersion() returns an integer value that encodes the server's version numberversion 7.3.2 is encoded as 70302, version 8.0.0 is encode as 80000, and so forth.

Remember that PQconnectdb() returns a PGconn pointer even when a connection attempt fails; it is often instructive to see the final connection attributes for a failed connection attempt. Here are the results when I try to connect to a nonexistent database on my system:

$ ./client2b user=korry
FATAL 1: Database "korry" does not exist in the system catalog.

dbname = korry
user = korry
password =
host = (null)
port = 5432
tty =
options =

In this case, I can see that libpq chose an invalid database name (defaulted from my username).

Part I: General PostgreSQL Use

Introduction to PostgreSQL and SQL

Working with Data in PostgreSQL

PostgreSQL SQL Syntax and Use

Performance

Part II: Programming with PostgreSQL

Introduction to PostgreSQL Programming

Extending PostgreSQL

PL/pgSQL

The PostgreSQL C APIlibpq

A Simpler C APIlibpgeasy

The New PostgreSQL C++ APIlibpqxx

Embedding SQL Commands in C Programsecpg

Using PostgreSQL from an ODBC Client Application

Using PostgreSQL from a Java Client Application

Using PostgreSQL with Perl

Using PostgreSQL with PHP

Using PostgreSQL with Tcl and Tcl/Tk

Using PostgreSQL with Python

Npgsql: The .NET Data Provider

Other Useful Programming Tools

Part III: PostgreSQL Administration

Introduction to PostgreSQL Administration

PostgreSQL Administration

Internationalization and Localization

Security

Replicating PostgreSQL Data with Slony

Contributed Modules

Index



PostgreSQL(c) The comprehensive guide to building, programming, and administering PostgreSQL databases
PostgreSQL(c) The comprehensive guide to building, programming, and administering PostgreSQL databases
ISBN: 735712573
EAN: N/A
Year: 2004
Pages: 261

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net