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

# OdbcLog.cpp

Go to the documentation of this file.

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