PostgreSQLConnection.h
Go to the documentation of this file.
00001 /* -*- C++ -*- */
00002 
00003 /****************************************************************************
00004 ** Copyright (c) 2001-2014
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

Generated on Mon Sep 15 2014 01:23:54 for QuickFIX by doxygen 1.7.6.1 written by Dimitri van Heesch, © 1997-2001