123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- /* -*- 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() throw( 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 std::auto_ptr< MySQLConnectionPool >
- MySQLConnectionPoolPtr;
- }
- #endif //FIX_MYSQLCONNECTION_H
- #endif //HAVE_MYSQL
|