PostgreSQLConnection.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef HAVE_POSTGRESQL
00023 #error PostgreSQLConnection.h included, but HAVE_POSTGRESQL not defined
00024 #endif
00025
00026 #ifdef HAVE_POSTGRESQL
00027 #ifndef FIX_POSTGRESQLCONNECTION_H
00028 #define FIX_POSTGRESQLCONNECTION_H
00029
00030 #ifdef _MSC_VER
00031 #pragma warning( disable : 4503 4355 4786 4290 )
00032 #pragma comment( lib, "libpq" )
00033 #endif
00034
00035 #include <libpq-fe.h>
00036 #include "DatabaseConnectionID.h"
00037 #include "DatabaseConnectionPool.h"
00038 #include "Mutex.h"
00039
00040 namespace FIX
00041 {
00042 class PostgreSQLQuery
00043 {
00044 public:
00045 PostgreSQLQuery( const std::string& query )
00046 : m_result( 0 ), m_query( query )
00047 {}
00048
00049 ~PostgreSQLQuery()
00050 {
00051 if( m_result )
00052 PQclear( m_result );
00053 }
00054
00055 bool execute( PGconn* pConnection )
00056 {
00057 int retry = 0;
00058
00059 do
00060 {
00061 if( m_result ) PQclear( m_result );
00062 m_result = PQexec( pConnection, m_query.c_str() );
00063 m_status = PQresultStatus( m_result );
00064 if( success() ) return true;
00065 PQreset( pConnection );
00066 retry++;
00067 } while( retry <= 1 );
00068 return success();
00069 }
00070
00071 bool success()
00072 {
00073 return m_status == PGRES_TUPLES_OK
00074 || m_status == PGRES_COMMAND_OK;
00075 }
00076
00077 int rows()
00078 {
00079 return PQntuples( m_result );
00080 }
00081
00082 char* reason()
00083 {
00084 return PQresultErrorMessage( m_result );
00085 }
00086
00087 char* getValue( int row, int column )
00088 {
00089 return PQgetvalue( m_result, row, column );
00090 }
00091
00092 void throwException() throw( IOException )
00093 {
00094 if( !success() )
00095 throw IOException( "Query failed [" + m_query + "] " );
00096 }
00097
00098 private:
00099 PGresult* m_result;
00100 ExecStatusType m_status;
00101 std::string m_query;
00102 };
00103
00104 class PostgreSQLConnection
00105 {
00106 public:
00107 PostgreSQLConnection
00108 ( const DatabaseConnectionID& id )
00109 : m_connectionID( id )
00110 {
00111 connect();
00112 }
00113
00114 PostgreSQLConnection
00115 ( const std::string& database, const std::string& user,
00116 const std::string& password, const std::string& host, short port )
00117 : m_connectionID( database, user, password, host, port )
00118 {
00119 connect();
00120 }
00121
00122 ~PostgreSQLConnection()
00123 {
00124 if( m_pConnection )
00125 PQfinish( m_pConnection );
00126 }
00127
00128 const DatabaseConnectionID& connectionID()
00129 {
00130 return m_connectionID;
00131 }
00132
00133 bool connected()
00134 {
00135 Locker locker( m_mutex );
00136 return PQstatus( m_pConnection ) == CONNECTION_OK;
00137 }
00138
00139 bool reconnect()
00140 {
00141 Locker locker( m_mutex );
00142 PQreset( m_pConnection );
00143 return connected();
00144 }
00145
00146 bool execute( PostgreSQLQuery& pQuery )
00147 {
00148 Locker locker( m_mutex );
00149 return pQuery.execute( m_pConnection );
00150 }
00151
00152 private:
00153 void connect()
00154 {
00155 short port = m_connectionID.getPort();
00156 m_pConnection = PQsetdbLogin
00157 ( m_connectionID.getHost().c_str(), port == 0 ? "" : IntConvertor::convert( port ).c_str(),
00158 "", "", m_connectionID.getDatabase().c_str(), m_connectionID.getUser().c_str(), m_connectionID.getPassword().c_str() );
00159
00160 if( !connected() )
00161 throw ConfigError( "Unable to connect to database" );
00162 }
00163
00164 PGconn* m_pConnection;
00165 DatabaseConnectionID m_connectionID;
00166 Mutex m_mutex;
00167 };
00168
00169 typedef DatabaseConnectionPool<PostgreSQLConnection>
00170 PostgreSQLConnectionPool;
00171 typedef std::auto_ptr< PostgreSQLConnectionPool >
00172 PostgreSQLConnectionPoolPtr;
00173 }
00174
00175 #endif //FIX_POSTGRESQLCONNECTION_H
00176 #endif //HAVE_POSTGRESQL