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

MySQLConnection.h

Go to the documentation of this file.
00001 /* -*- C++ -*- */
00002 
00003 /****************************************************************************
00004 ** Copyright (c) quickfixengine.org  All rights reserved.
00005 **
00006 ** This file is part of the QuickFIX FIX Engine
00007 **
00008 ** This file may be distributed under the terms of the quickfixengine.org
00009 ** license as defined by quickfixengine.org and appearing in the file
00010 ** LICENSE included in the packaging of this file.
00011 **
00012 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014 **
00015 ** See http://www.quickfixengine.org/LICENSE for licensing information.
00016 **
00017 ** Contact ask@quickfixengine.org if any conditions of this licensing are
00018 ** not clear to you.
00019 **
00020 ****************************************************************************/
00021 
00022 #ifndef HAVE_MYSQL
00023 #error MySQLConnection.h included, but HAVE_MYSQL not defined
00024 #endif
00025 
00026 #ifdef HAVE_MYSQL
00027 #ifndef FIX_MYSQLCONNECTION_H
00028 #define FIX_MYSQLCONNECTION_H
00029 
00030 #ifdef _MSC_VER
00031 #pragma warning( disable : 4503 4355 4786 4290 )
00032 #pragma comment( lib, "libMySQL" )
00033 #endif
00034 
00035 #include <mysql.h>
00036 #include <errmsg.h>
00037 #include "DatabaseConnectionID.h"
00038 #include "DatabaseConnectionPool.h"
00039 #include "Mutex.h"
00040 
00041 #undef MYSQL_PORT
00042 
00043 namespace FIX
00044 {
00045 class MySQLQuery
00046 {
00047 public:
00048   MySQLQuery( const std::string& query ) 
00049   : m_result( 0 ), m_query( query ) 
00050   {}
00051 
00052   ~MySQLQuery()
00053   {
00054     if( m_result )
00055       mysql_free_result( m_result );
00056   }
00057 
00058   bool execute( MYSQL* pConnection )
00059   {
00060     int retry = 0;
00061     
00062     do
00063     {
00064       if( m_result ) mysql_free_result( m_result );
00065       int errcode = mysql_query( pConnection, m_query.c_str() );
00066       m_result = mysql_store_result( pConnection );
00067       if( errcode == 0 )
00068         return true;
00069       m_status = mysql_errno( pConnection );
00070       m_reason = mysql_error( pConnection );
00071       mysql_ping( pConnection );
00072       retry++;
00073     } while( retry <= 1 );
00074     return success();
00075   }
00076 
00077   bool success()
00078   {
00079     return m_status == 0;
00080   }
00081 
00082   int rows()
00083   {
00084     return (int)mysql_num_rows( m_result );
00085   }
00086 
00087   const std::string& reason()
00088   {
00089     return m_reason;
00090   }
00091 
00092   char* getValue( int row, int column )
00093   {
00094     if( m_rows.empty() )
00095     {
00096       MYSQL_ROW row = 0;
00097       while( (row = mysql_fetch_row( m_result )) )
00098         m_rows.push_back(row);
00099     }
00100     return m_rows[row][column];
00101   }
00102 
00103   void throwException() throw( IOException )
00104   {
00105     if( !success() )
00106       throw IOException( "Query failed [" + m_query + "] " + reason() );
00107   }
00108 
00109 private:
00110   MYSQL_RES* m_result;
00111   int m_status;
00112   std::string m_query; 
00113   std::string m_reason;
00114   std::vector<MYSQL_ROW> m_rows;
00115 };
00116 
00117 class MySQLConnection
00118 {
00119 public:
00120   MySQLConnection
00121   ( const DatabaseConnectionID& id )
00122   : m_connectionID( id )
00123   {
00124     connect();
00125   }
00126 
00127   MySQLConnection
00128   ( const std::string& database, const std::string& user,
00129     const std::string& password, const std::string& host, short port )
00130   : m_connectionID( database, user, password, host, port )
00131   {
00132     connect();
00133   }
00134 
00135   ~MySQLConnection()
00136   {
00137     if( m_pConnection )
00138       mysql_close( m_pConnection );
00139   }
00140 
00141   const DatabaseConnectionID& connectionID()
00142   {
00143     return m_connectionID;
00144   }
00145 
00146   bool connected()
00147   {
00148     Locker locker( m_mutex );
00149     return mysql_ping( m_pConnection ) == 0;
00150   }
00151 
00152   bool reconnect()
00153   {
00154     Locker locker( m_mutex );
00155     return mysql_ping( m_pConnection ) == 0;
00156   }
00157 
00158   bool execute( MySQLQuery& pQuery )
00159   {
00160     Locker locker( m_mutex );
00161     return pQuery.execute( m_pConnection );
00162   }
00163 
00164 private:
00165   void connect()
00166   {
00167     short port = m_connectionID.getPort();
00168     m_pConnection = mysql_init( NULL );
00169     if( !mysql_real_connect
00170       ( m_pConnection, m_connectionID.getHost().c_str(), m_connectionID.getUser().c_str(), 
00171         m_connectionID.getPassword().c_str(), m_connectionID.getDatabase().c_str(), port, 0, 0 ) )
00172     {
00173         if( !connected() )
00174           throw ConfigError( std::string("Unable to connect to database [") + mysql_error(m_pConnection) + "]" );
00175     }
00176     #if( MYSQL_VERSION_ID > 50000 )
00177     my_bool reconnect = 1;
00178     mysql_options( m_pConnection, MYSQL_OPT_RECONNECT, static_cast<char*>(&reconnect) );
00179     #endif
00180   }
00181 
00182   MYSQL* m_pConnection;
00183   DatabaseConnectionID m_connectionID;
00184   Mutex m_mutex;
00185 };
00186 
00187 typedef DatabaseConnectionPool<MySQLConnection>
00188   MySQLConnectionPool;
00189 typedef std::auto_ptr< MySQLConnectionPool >
00190   MySQLConnectionPoolPtr;
00191 }
00192 
00193 #endif //FIX_MYSQLCONNECTION_H
00194 #endif //HAVE_MYSQL

Generated on Mon Apr 5 20:59:50 2010 for QuickFIX by doxygen 1.6.1 written by Dimitri van Heesch, © 1997-2001