PostgreSQLConnection.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /* -*- C++ -*- */
  2. /****************************************************************************
  3. ** Copyright (c) 2001-2014
  4. **
  5. ** This file is part of the QuickFIX FIX Engine
  6. **
  7. ** This file may be distributed under the terms of the quickfixengine.org
  8. ** license as defined by quickfixengine.org and appearing in the file
  9. ** LICENSE included in the packaging of this file.
  10. **
  11. ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
  12. ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  13. **
  14. ** See http://www.quickfixengine.org/LICENSE for licensing information.
  15. **
  16. ** Contact ask@quickfixengine.org if any conditions of this licensing are
  17. ** not clear to you.
  18. **
  19. ****************************************************************************/
  20. #ifndef HAVE_POSTGRESQL
  21. #error PostgreSQLConnection.h included, but HAVE_POSTGRESQL not defined
  22. #endif
  23. #ifdef HAVE_POSTGRESQL
  24. #ifndef FIX_POSTGRESQLCONNECTION_H
  25. #define FIX_POSTGRESQLCONNECTION_H
  26. #ifdef _MSC_VER
  27. #pragma warning( disable : 4503 4355 4786 4290 )
  28. #pragma comment( lib, "libpq" )
  29. #endif
  30. #include <libpq-fe.h>
  31. #include "DatabaseConnectionID.h"
  32. #include "DatabaseConnectionPool.h"
  33. #include "Mutex.h"
  34. namespace FIX
  35. {
  36. class PostgreSQLQuery
  37. {
  38. public:
  39. PostgreSQLQuery( const std::string& query )
  40. : m_result( 0 ), m_query( query )
  41. {}
  42. ~PostgreSQLQuery()
  43. {
  44. if( m_result )
  45. PQclear( m_result );
  46. }
  47. bool execute( PGconn* pConnection )
  48. {
  49. int retry = 0;
  50. do
  51. {
  52. if( m_result ) PQclear( m_result );
  53. m_result = PQexec( pConnection, m_query.c_str() );
  54. m_status = PQresultStatus( m_result );
  55. if( success() ) return true;
  56. PQreset( pConnection );
  57. retry++;
  58. } while( retry <= 1 );
  59. return success();
  60. }
  61. bool success()
  62. {
  63. return m_status == PGRES_TUPLES_OK
  64. || m_status == PGRES_COMMAND_OK;
  65. }
  66. int rows()
  67. {
  68. return PQntuples( m_result );
  69. }
  70. char* reason()
  71. {
  72. return PQresultErrorMessage( m_result );
  73. }
  74. char* getValue( int row, int column )
  75. {
  76. return PQgetvalue( m_result, row, column );
  77. }
  78. void throwException() throw( IOException )
  79. {
  80. if( !success() )
  81. throw IOException( "Query failed [" + m_query + "] " );
  82. }
  83. private:
  84. PGresult* m_result;
  85. ExecStatusType m_status;
  86. std::string m_query;
  87. };
  88. class PostgreSQLConnection
  89. {
  90. public:
  91. PostgreSQLConnection
  92. ( const DatabaseConnectionID& id )
  93. : m_connectionID( id )
  94. {
  95. connect();
  96. }
  97. PostgreSQLConnection
  98. ( const std::string& database, const std::string& user,
  99. const std::string& password, const std::string& host, short port )
  100. : m_connectionID( database, user, password, host, port )
  101. {
  102. connect();
  103. }
  104. ~PostgreSQLConnection()
  105. {
  106. if( m_pConnection )
  107. PQfinish( m_pConnection );
  108. }
  109. const DatabaseConnectionID& connectionID()
  110. {
  111. return m_connectionID;
  112. }
  113. bool connected()
  114. {
  115. Locker locker( m_mutex );
  116. return PQstatus( m_pConnection ) == CONNECTION_OK;
  117. }
  118. bool reconnect()
  119. {
  120. Locker locker( m_mutex );
  121. PQreset( m_pConnection );
  122. return connected();
  123. }
  124. bool execute( PostgreSQLQuery& pQuery )
  125. {
  126. Locker locker( m_mutex );
  127. return pQuery.execute( m_pConnection );
  128. }
  129. private:
  130. void connect()
  131. {
  132. short port = m_connectionID.getPort();
  133. m_pConnection = PQsetdbLogin
  134. ( m_connectionID.getHost().c_str(), port == 0 ? "" : IntConvertor::convert( port ).c_str(),
  135. "", "", m_connectionID.getDatabase().c_str(), m_connectionID.getUser().c_str(), m_connectionID.getPassword().c_str() );
  136. if( !connected() )
  137. throw ConfigError( "Unable to connect to database" );
  138. }
  139. PGconn* m_pConnection;
  140. DatabaseConnectionID m_connectionID;
  141. Mutex m_mutex;
  142. };
  143. typedef DatabaseConnectionPool<PostgreSQLConnection>
  144. PostgreSQLConnectionPool;
  145. typedef std::auto_ptr< PostgreSQLConnectionPool >
  146. PostgreSQLConnectionPoolPtr;
  147. }
  148. #endif //FIX_POSTGRESQLCONNECTION_H
  149. #endif //HAVE_POSTGRESQL