00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef _MSC_VER
00021 #include "stdafx.h"
00022 #else
00023 #include "config.h"
00024 #endif
00025 #include "CallStack.h"
00026
00027 #ifdef HAVE_POSTGRESQL
00028
00029 #include "PostgreSQLLog.h"
00030 #include "SessionID.h"
00031 #include "SessionSettings.h"
00032 #include "Utility.h"
00033 #include "strptime.h"
00034 #include <fstream>
00035
00036 namespace FIX
00037 {
00038
00039 const std::string PostgreSQLLogFactory::DEFAULT_DATABASE = "quickfix";
00040 const std::string PostgreSQLLogFactory::DEFAULT_USER = "postgres";
00041 const std::string PostgreSQLLogFactory::DEFAULT_PASSWORD = "";
00042 const std::string PostgreSQLLogFactory::DEFAULT_HOST = "localhost";
00043 const short PostgreSQLLogFactory::DEFAULT_PORT = 0;
00044
00045 PostgreSQLLog::PostgreSQLLog
00046 ( const SessionID& s, const DatabaseConnectionID& d, PostgreSQLConnectionPool* p )
00047 : m_pConnectionPool( p )
00048 {
00049 init();
00050 m_pSessionID = new SessionID( s );
00051 m_pConnection = m_pConnectionPool->create( d );
00052 }
00053
00054 PostgreSQLLog::PostgreSQLLog
00055 ( const DatabaseConnectionID& d, PostgreSQLConnectionPool* p )
00056 : m_pConnectionPool( p ), m_pSessionID( 0 )
00057 {
00058 init();
00059 m_pConnection = m_pConnectionPool->create( d );
00060 }
00061
00062 PostgreSQLLog::PostgreSQLLog
00063 ( const SessionID& s, const std::string& database, const std::string& user,
00064 const std::string& password, const std::string& host, short port )
00065 : m_pConnectionPool( 0 )
00066 {
00067 init();
00068 m_pSessionID = new SessionID( s );
00069 m_pConnection = new PostgreSQLConnection( database, user, password, host, port );
00070 }
00071
00072 PostgreSQLLog::PostgreSQLLog
00073 ( const std::string& database, const std::string& user,
00074 const std::string& password, const std::string& host, short port )
00075 : m_pConnectionPool( 0 ), m_pSessionID( 0 )
00076 {
00077 init();
00078 m_pConnection = new PostgreSQLConnection( database, user, password, host, port );
00079 }
00080
00081 void PostgreSQLLog::init()
00082 {
00083 setIncomingTable( "messages_log" );
00084 setOutgoingTable( "messages_log" );
00085 setEventTable( "event_log" );
00086 }
00087
00088 PostgreSQLLog::~PostgreSQLLog()
00089 {
00090 if( m_pConnectionPool )
00091 m_pConnectionPool->destroy( m_pConnection );
00092 else
00093 delete m_pConnection;
00094 delete m_pSessionID;
00095 }
00096
00097 Log* PostgreSQLLogFactory::create()
00098 { QF_STACK_PUSH(PostgreSQLLogFactory::create)
00099
00100 std::string database;
00101 std::string user;
00102 std::string password;
00103 std::string host;
00104 short port;
00105
00106 init( m_settings.get(), database, user, password, host, port );
00107 DatabaseConnectionID id( database, user, password, host, port );
00108 PostgreSQLLog* result = new PostgreSQLLog( id, m_connectionPoolPtr.get() );
00109 initLog( m_settings.get(), *result );
00110 return result;
00111
00112 QF_STACK_POP
00113 }
00114
00115 Log* PostgreSQLLogFactory::create( const SessionID& s )
00116 { QF_STACK_PUSH(PostgreSQLLogFactory::create)
00117
00118 std::string database;
00119 std::string user;
00120 std::string password;
00121 std::string host;
00122 short port;
00123
00124 Dictionary settings;
00125 if( m_settings.has(s) )
00126 settings = m_settings.get( s );
00127
00128 init( settings, database, user, password, host, port );
00129 DatabaseConnectionID id( database, user, password, host, port );
00130 PostgreSQLLog* result = new PostgreSQLLog( s, id, m_connectionPoolPtr.get() );
00131 initLog( settings, *result );
00132 return result;
00133
00134 QF_STACK_POP
00135 }
00136
00137 void PostgreSQLLogFactory::init( const Dictionary& settings,
00138 std::string& database,
00139 std::string& user,
00140 std::string& password,
00141 std::string& host,
00142 short &port )
00143 { QF_STACK_PUSH(PostgreSQLLogFactory::init)
00144
00145 database = DEFAULT_DATABASE;
00146 user = DEFAULT_USER;
00147 password = DEFAULT_PASSWORD;
00148 host = DEFAULT_HOST;
00149 port = DEFAULT_PORT;
00150
00151 if( m_useSettings )
00152 {
00153 try { database = settings.getString( POSTGRESQL_LOG_DATABASE ); }
00154 catch( ConfigError& ) {}
00155
00156 try { user = settings.getString( POSTGRESQL_LOG_USER ); }
00157 catch( ConfigError& ) {}
00158
00159 try { password = settings.getString( POSTGRESQL_LOG_PASSWORD ); }
00160 catch( ConfigError& ) {}
00161
00162 try { host = settings.getString( POSTGRESQL_LOG_HOST ); }
00163 catch( ConfigError& ) {}
00164
00165 try { port = ( short ) settings.getLong( POSTGRESQL_LOG_PORT ); }
00166 catch( ConfigError& ) {}
00167 }
00168 else
00169 {
00170 database = m_database;
00171 user = m_user;
00172 password = m_password;
00173 host = m_host;
00174 port = m_port;
00175 }
00176
00177 QF_STACK_POP
00178 }
00179
00180 void PostgreSQLLogFactory::initLog( const Dictionary& settings, PostgreSQLLog& log )
00181 {
00182 try { log.setIncomingTable( settings.getString( POSTGRESQL_LOG_INCOMING_TABLE ) ); }
00183 catch( ConfigError& ) {}
00184
00185 try { log.setOutgoingTable( settings.getString( POSTGRESQL_LOG_OUTGOING_TABLE ) ); }
00186 catch( ConfigError& ) {}
00187
00188 try { log.setEventTable( settings.getString( POSTGRESQL_LOG_EVENT_TABLE ) ); }
00189 catch( ConfigError& ) {}
00190 }
00191
00192 void PostgreSQLLogFactory::destroy( Log* pLog )
00193 { QF_STACK_PUSH(PostgreSQLLogFactory::destroy)
00194 delete pLog;
00195 QF_STACK_POP
00196 }
00197
00198 void PostgreSQLLog::clear()
00199 { QF_STACK_PUSH(PostgreSQLLog::clear)
00200
00201 std::stringstream whereClause;
00202
00203 whereClause << "WHERE ";
00204
00205 if( m_pSessionID )
00206 {
00207 whereClause
00208 << "BeginString = '" << m_pSessionID->getBeginString().getValue() << "' "
00209 << "AND SenderCompID = '" << m_pSessionID->getSenderCompID().getValue() << "' "
00210 << "AND TargetCompID = '" << m_pSessionID->getTargetCompID().getValue() << "' ";
00211
00212 if( m_pSessionID->getSessionQualifier().size() )
00213 whereClause << "AND SessionQualifier = '" << m_pSessionID->getSessionQualifier() << "'";
00214 }
00215 else
00216 {
00217 whereClause << "BeginString = NULL AND SenderCompID = NULL && TargetCompID = NULL";
00218 }
00219
00220 std::stringstream incomingQuery;
00221 std::stringstream outgoingQuery;
00222 std::stringstream eventQuery;
00223
00224 incomingQuery
00225 << "DELETE FROM " << m_incomingTable << " " << whereClause.str();
00226 outgoingQuery
00227 << "DELETE FROM " << m_outgoingTable << " " << whereClause.str();
00228 eventQuery
00229 << "DELETE FROM " << m_eventTable << " " << whereClause.str();
00230
00231 PostgreSQLQuery incoming( incomingQuery.str() );
00232 PostgreSQLQuery outgoing( outgoingQuery.str() );
00233 PostgreSQLQuery event( eventQuery.str() );
00234 m_pConnection->execute( incoming );
00235 m_pConnection->execute( outgoing );
00236 m_pConnection->execute( event );
00237
00238 QF_STACK_POP
00239 }
00240
00241 void PostgreSQLLog::backup()
00242 { QF_STACK_PUSH(PostgreSQLLog::backup)
00243 QF_STACK_POP
00244 }
00245
00246 void PostgreSQLLog::insert( const std::string& table, const std::string value )
00247 { QF_STACK_PUSH(PostgreSQLLog::insert)
00248
00249 UtcTimeStamp time;
00250 int year, month, day, hour, minute, second, millis;
00251 time.getYMD( year, month, day );
00252 time.getHMS( hour, minute, second, millis );
00253
00254 char sqlTime[ 24 ];
00255 STRING_SPRINTF( sqlTime, "%d-%02d-%02d %02d:%02d:%02d.%003d",
00256 year, month, day, hour, minute, second, millis );
00257
00258 char* valueCopy = new char[ (value.size() * 2) + 1 ];
00259 PQescapeString( valueCopy, value.c_str(), value.size() );
00260
00261 std::stringstream queryString;
00262 queryString << "INSERT INTO " << table << " "
00263 << "(time, beginstring, sendercompid, targetcompid, session_qualifier, text) "
00264 << "VALUES ("
00265 << "'" << sqlTime << "',";
00266
00267 if( m_pSessionID )
00268 {
00269 queryString
00270 << "'" << m_pSessionID->getBeginString().getValue() << "',"
00271 << "'" << m_pSessionID->getSenderCompID().getValue() << "',"
00272 << "'" << m_pSessionID->getTargetCompID().getValue() << "',";
00273 if( m_pSessionID->getSessionQualifier() == "" )
00274 queryString << "NULL" << ",";
00275 else
00276 queryString << "'" << m_pSessionID->getSessionQualifier() << "',";
00277 }
00278 else
00279 {
00280 queryString << "NULL, NULL, NULL, NULL, ";
00281 }
00282
00283 queryString << "'" << valueCopy << "')";
00284 delete [] valueCopy;
00285
00286 PostgreSQLQuery query( queryString.str() );
00287 m_pConnection->execute( query );
00288
00289 QF_STACK_POP
00290 }
00291
00292 }
00293
00294 #endif //HAVE_POSTGRESQL