Index Source Files Annotated Class List Alphabetical Class List Class Hierarchy Graphical Class Hierarchy

# PostgreSQLConnection.h

Go to the documentation of this file.

    00001 /* -*- C++ -*- */
    00002
    00003 /****************************************************************************
    00004 ** Copyright (c) quickfixengine.org  All rights reserved.
    00005 **
    00006 ** This file is part of the QuickFIX FIX Engine
    00007 **
    00008 ** This file may be distributed under the terms of the quickfixengine.org
    00009 ** license as defined by quickfixengine.org and appearing in the file
    00010 ** LICENSE included in the packaging of this file.
    00011 **
    00012 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
    00013 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    00014 **
    00015 ** See http://www.quickfixengine.org/LICENSE for licensing information.
    00016 **
    00017 ** Contact ask@quickfixengine.org if any conditions of this licensing are
    00018 ** not clear to you.
    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