WARNING: This is NOT an official release. As of 12/10/21 20:23, the latest release of the quickfix lib (1.15.1) does not support c++17 (the FIX::Application class has fns with dynamic exceptions). This commit upgrades to a more recent (unreleased) build which supports c++17.
195 lines
4.3 KiB
C++
195 lines
4.3 KiB
C++
/* -*- C++ -*- */
|
|
|
|
/****************************************************************************
|
|
** Copyright (c) 2001-2014
|
|
**
|
|
** This file is part of the QuickFIX FIX Engine
|
|
**
|
|
** This file may be distributed under the terms of the quickfixengine.org
|
|
** license as defined by quickfixengine.org and appearing in the file
|
|
** LICENSE included in the packaging of this file.
|
|
**
|
|
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
**
|
|
** See http://www.quickfixengine.org/LICENSE for licensing information.
|
|
**
|
|
** Contact ask@quickfixengine.org if any conditions of this licensing are
|
|
** not clear to you.
|
|
**
|
|
****************************************************************************/
|
|
|
|
#ifndef HAVE_MYSQL
|
|
#error MySQLConnection.h included, but HAVE_MYSQL not defined
|
|
#endif
|
|
|
|
#ifdef HAVE_MYSQL
|
|
#ifndef FIX_MYSQLCONNECTION_H
|
|
#define FIX_MYSQLCONNECTION_H
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning( disable : 4503 4355 4786 4290 )
|
|
#pragma comment( lib, "libMySQL" )
|
|
#endif
|
|
|
|
#include <mysql.h>
|
|
#include <errmsg.h>
|
|
#include "DatabaseConnectionID.h"
|
|
#include "DatabaseConnectionPool.h"
|
|
#include "Mutex.h"
|
|
|
|
#undef MYSQL_PORT
|
|
|
|
namespace FIX
|
|
{
|
|
class MySQLQuery
|
|
{
|
|
public:
|
|
MySQLQuery( const std::string& query )
|
|
: m_result( 0 ), m_query( query )
|
|
{}
|
|
|
|
~MySQLQuery()
|
|
{
|
|
if( m_result )
|
|
mysql_free_result( m_result );
|
|
}
|
|
|
|
bool execute( MYSQL* pConnection )
|
|
{
|
|
int retry = 0;
|
|
|
|
do
|
|
{
|
|
if( m_result ) mysql_free_result( m_result );
|
|
int errcode = mysql_query( pConnection, m_query.c_str() );
|
|
m_result = mysql_store_result( pConnection );
|
|
if( errcode == 0 )
|
|
return true;
|
|
m_status = mysql_errno( pConnection );
|
|
m_reason = mysql_error( pConnection );
|
|
mysql_ping( pConnection );
|
|
retry++;
|
|
} while( retry <= 1 );
|
|
return success();
|
|
}
|
|
|
|
bool success()
|
|
{
|
|
return m_status == 0;
|
|
}
|
|
|
|
int rows()
|
|
{
|
|
return (int)mysql_num_rows( m_result );
|
|
}
|
|
|
|
const std::string& reason()
|
|
{
|
|
return m_reason;
|
|
}
|
|
|
|
char* getValue( int row, int column )
|
|
{
|
|
if( m_rows.empty() )
|
|
{
|
|
MYSQL_ROW row = 0;
|
|
while( (row = mysql_fetch_row( m_result )) )
|
|
m_rows.push_back(row);
|
|
}
|
|
return m_rows[row][column];
|
|
}
|
|
|
|
void throwException() EXCEPT ( IOException )
|
|
{
|
|
if( !success() )
|
|
throw IOException( "Query failed [" + m_query + "] " + reason() );
|
|
}
|
|
|
|
private:
|
|
MYSQL_RES* m_result;
|
|
int m_status;
|
|
std::string m_query;
|
|
std::string m_reason;
|
|
std::vector<MYSQL_ROW> m_rows;
|
|
};
|
|
|
|
class MySQLConnection
|
|
{
|
|
public:
|
|
MySQLConnection
|
|
( const DatabaseConnectionID& id )
|
|
: m_connectionID( id )
|
|
{
|
|
connect();
|
|
}
|
|
|
|
MySQLConnection
|
|
( const std::string& database, const std::string& user,
|
|
const std::string& password, const std::string& host, short port )
|
|
: m_connectionID( database, user, password, host, port )
|
|
{
|
|
connect();
|
|
}
|
|
|
|
~MySQLConnection()
|
|
{
|
|
if( m_pConnection )
|
|
mysql_close( m_pConnection );
|
|
}
|
|
|
|
const DatabaseConnectionID& connectionID()
|
|
{
|
|
return m_connectionID;
|
|
}
|
|
|
|
bool connected()
|
|
{
|
|
Locker locker( m_mutex );
|
|
return mysql_ping( m_pConnection ) == 0;
|
|
}
|
|
|
|
bool reconnect()
|
|
{
|
|
Locker locker( m_mutex );
|
|
return mysql_ping( m_pConnection ) == 0;
|
|
}
|
|
|
|
bool execute( MySQLQuery& pQuery )
|
|
{
|
|
Locker locker( m_mutex );
|
|
return pQuery.execute( m_pConnection );
|
|
}
|
|
|
|
private:
|
|
void connect()
|
|
{
|
|
short port = m_connectionID.getPort();
|
|
m_pConnection = mysql_init( NULL );
|
|
if( !mysql_real_connect
|
|
( m_pConnection, m_connectionID.getHost().c_str(), m_connectionID.getUser().c_str(),
|
|
m_connectionID.getPassword().c_str(), m_connectionID.getDatabase().c_str(), port, 0, 0 ) )
|
|
{
|
|
if( !connected() )
|
|
throw ConfigError( std::string("Unable to connect to database [") + mysql_error(m_pConnection) + "]" );
|
|
}
|
|
#if( MYSQL_VERSION_ID > 50000 )
|
|
my_bool reconnect = 1;
|
|
mysql_options( m_pConnection, MYSQL_OPT_RECONNECT, static_cast<char*>(&reconnect) );
|
|
#endif
|
|
}
|
|
|
|
MYSQL* m_pConnection;
|
|
DatabaseConnectionID m_connectionID;
|
|
Mutex m_mutex;
|
|
};
|
|
|
|
typedef DatabaseConnectionPool<MySQLConnection>
|
|
MySQLConnectionPool;
|
|
typedef SmartPtr< MySQLConnectionPool >
|
|
MySQLConnectionPoolPtr;
|
|
}
|
|
|
|
#endif //FIX_MYSQLCONNECTION_H
|
|
#endif //HAVE_MYSQL
|