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_ODBC
00028
00029 #include "OdbcLog.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 OdbcLogFactory::DEFAULT_USER = "sa";
00040 const std::string OdbcLogFactory::DEFAULT_PASSWORD = "";
00041 const std::string OdbcLogFactory::DEFAULT_CONNECTION_STRING
00042 = "DATABASE=quickfix;DRIVER={SQL Server};SERVER=(local);";
00043
00044 OdbcLog::OdbcLog
00045 ( const SessionID& s, const std::string& user, const std::string& password,
00046 const std::string& connectionString )
00047 {
00048 init();
00049 m_pSessionID = new SessionID( s );
00050 m_pConnection = new OdbcConnection( user, password, connectionString );
00051 }
00052
00053 OdbcLog::OdbcLog
00054 ( const std::string& user, const std::string& password,
00055 const std::string& connectionString )
00056 : m_pSessionID( 0 )
00057 {
00058 init();
00059 m_pConnection = new OdbcConnection( user, password, connectionString );
00060 }
00061
00062 void OdbcLog::init()
00063 {
00064 setIncomingTable( "messages_log" );
00065 setOutgoingTable( "messages_log" );
00066 setEventTable( "event_log" );
00067 }
00068
00069 OdbcLog::~OdbcLog()
00070 {
00071 delete m_pSessionID;
00072 delete m_pConnection;
00073 }
00074
00075 OdbcLogFactory::OdbcLogFactory( const std::string& user, const std::string& password,
00076 const std::string& connectionString )
00077 : m_user( user ), m_password( password ), m_connectionString( connectionString ),
00078 m_useSettings( false )
00079 {
00080 }
00081
00082 OdbcLogFactory::OdbcLogFactory()
00083 : m_user( DEFAULT_USER ), m_password( DEFAULT_PASSWORD ),
00084 m_connectionString( DEFAULT_CONNECTION_STRING ), m_useSettings( false )
00085 {
00086 }
00087
00088 OdbcLogFactory::~OdbcLogFactory()
00089 {
00090 }
00091
00092 Log* OdbcLogFactory::create()
00093 { QF_STACK_PUSH(OdbcLogFactory::create)
00094
00095 std::string database;
00096 std::string user;
00097 std::string connectionString;
00098
00099 init( m_settings.get(), database, user, connectionString );
00100 OdbcLog* result = new OdbcLog( database, user, connectionString );
00101 initLog( m_settings.get(), *result );
00102 return result;
00103
00104 QF_STACK_POP
00105 }
00106
00107 Log* OdbcLogFactory::create( const SessionID& s )
00108 { QF_STACK_PUSH(OdbcLogFactory::create)
00109
00110 std::string database;
00111 std::string user;
00112 std::string connectionString;
00113
00114 Dictionary settings;
00115 if( m_settings.has(s) )
00116 settings = m_settings.get( s );
00117
00118 init( settings, database, user, connectionString );
00119 OdbcLog* result = new OdbcLog( s, database, user, connectionString );
00120 initLog( settings, *result );
00121 return result;
00122
00123 QF_STACK_POP
00124 }
00125
00126 void OdbcLogFactory::init( const Dictionary& settings,
00127 std::string& user,
00128 std::string& password,
00129 std::string& connectionString )
00130 { QF_STACK_PUSH(OdbcLogFactory::init)
00131
00132 user = DEFAULT_USER;
00133 password = DEFAULT_PASSWORD;
00134 connectionString = DEFAULT_CONNECTION_STRING;
00135
00136 if( m_useSettings )
00137 {
00138 try { user = settings.getString( ODBC_LOG_USER ); }
00139 catch( ConfigError& ) {}
00140
00141 try { password = settings.getString( ODBC_LOG_PASSWORD ); }
00142 catch( ConfigError& ) {}
00143
00144 try { connectionString = settings.getString( ODBC_LOG_CONNECTION_STRING ); }
00145 catch( ConfigError& ) {}
00146 }
00147 else
00148 {
00149 user = m_user;
00150 password = m_password;
00151 connectionString = m_connectionString;
00152 }
00153
00154 QF_STACK_POP
00155 }
00156
00157 void OdbcLogFactory::initLog( const Dictionary& settings, OdbcLog& log )
00158 {
00159 try { log.setIncomingTable( settings.getString( ODBC_LOG_INCOMING_TABLE ) ); }
00160 catch( ConfigError& ) {}
00161
00162 try { log.setOutgoingTable( settings.getString( ODBC_LOG_OUTGOING_TABLE ) ); }
00163 catch( ConfigError& ) {}
00164
00165 try { log.setEventTable( settings.getString( ODBC_LOG_EVENT_TABLE ) ); }
00166 catch( ConfigError& ) {}
00167 }
00168
00169 void OdbcLogFactory::destroy( Log* pLog )
00170 { QF_STACK_PUSH(OdbcLogFactory::destroy)
00171
00172 delete pLog;
00173
00174 QF_STACK_POP
00175 }
00176
00177 void OdbcLog::clear()
00178 { QF_STACK_PUSH(OdbcLog::clear)
00179
00180 std::stringstream whereClause;
00181
00182 whereClause << "WHERE ";
00183
00184 if( m_pSessionID )
00185 {
00186 whereClause
00187 << "BeginString = '" << m_pSessionID->getBeginString().getValue() << "' "
00188 << "AND SenderCompID = '" << m_pSessionID->getSenderCompID().getValue() << "' "
00189 << "AND TargetCompID = '" << m_pSessionID->getTargetCompID().getValue() << "' ";
00190
00191 if( m_pSessionID->getSessionQualifier().size() )
00192 whereClause << "AND SessionQualifier = '" << m_pSessionID->getSessionQualifier() << "'";
00193 }
00194 else
00195 {
00196 whereClause << "BeginString = NULL AND SenderCompID = NULL && TargetCompID = NULL";
00197 }
00198
00199 std::stringstream incomingQuery;
00200 std::stringstream outgoingQuery;
00201 std::stringstream eventQuery;
00202
00203 incomingQuery
00204 << "DELETE FROM " << m_incomingTable << " " << whereClause.str();
00205 outgoingQuery
00206 << "DELETE FROM " << m_outgoingTable << " " << whereClause.str();
00207 eventQuery
00208 << "DELETE FROM " << m_eventTable << " " << whereClause.str();
00209
00210 OdbcQuery incoming( incomingQuery.str() );
00211 OdbcQuery outgoing( outgoingQuery.str() );
00212 OdbcQuery event( eventQuery.str() );
00213 m_pConnection->execute( incoming );
00214 m_pConnection->execute( outgoing );
00215 m_pConnection->execute( event );
00216
00217 QF_STACK_POP
00218 }
00219
00220 void OdbcLog::backup()
00221 { QF_STACK_PUSH(OdbcLog::backup)
00222 QF_STACK_POP
00223 }
00224
00225 void OdbcLog::insert( const std::string& table, const std::string value )
00226 { QF_STACK_PUSH(OdbcLog::insert)
00227
00228 UtcTimeStamp time;
00229 int year, month, day, hour, minute, second, millis;
00230 time.getYMD( year, month, day );
00231 time.getHMS( hour, minute, second, millis );
00232
00233 char sqlTime[ 24 ];
00234 STRING_SPRINTF( sqlTime, "%d-%02d-%02d %02d:%02d:%02d.%003d",
00235 year, month, day, hour, minute, second, millis );
00236
00237 std::string valueCopy = value;
00238 string_replace( "'", "''", valueCopy );
00239
00240 std::stringstream queryString;
00241 queryString << "INSERT INTO " << table << " "
00242 << "(time, beginstring, sendercompid, targetcompid, session_qualifier, text) "
00243 << "VALUES ("
00244 << "{ts '" << sqlTime << "'},";
00245
00246 if( m_pSessionID )
00247 {
00248 queryString
00249 << "'" << m_pSessionID->getBeginString().getValue() << "',"
00250 << "'" << m_pSessionID->getSenderCompID().getValue() << "',"
00251 << "'" << m_pSessionID->getTargetCompID().getValue() << "',";
00252 if( m_pSessionID->getSessionQualifier() == "" )
00253 queryString << "NULL" << ",";
00254 else
00255 queryString << "'" << m_pSessionID->getSessionQualifier() << "',";
00256 }
00257 else
00258 {
00259 queryString << "NULL, NULL, NULL, NULL, ";
00260 }
00261
00262 queryString << "'" << valueCopy << "')";
00263
00264 OdbcQuery query( queryString.str() );
00265 m_pConnection->execute( query );
00266
00267 QF_STACK_POP
00268 }
00269
00270 }
00271
00272 #endif