MySQLConnection.h
Go to the documentation of this file.
1 /* -*- C++ -*- */
2 
3 /****************************************************************************
4 ** Copyright (c) 2001-2014
5 **
6 ** This file is part of the QuickFIX FIX Engine
7 **
8 ** This file may be distributed under the terms of the quickfixengine.org
9 ** license as defined by quickfixengine.org and appearing in the file
10 ** LICENSE included in the packaging of this file.
11 **
12 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
13 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14 **
15 ** See http://www.quickfixengine.org/LICENSE for licensing information.
16 **
17 ** Contact ask@quickfixengine.org if any conditions of this licensing are
18 ** not clear to you.
19 **
20 ****************************************************************************/
21 
22 #ifndef HAVE_MYSQL
23 #error MySQLConnection.h included, but HAVE_MYSQL not defined
24 #endif
25 
26 #ifdef HAVE_MYSQL
27 #ifndef FIX_MYSQLCONNECTION_H
28 #define FIX_MYSQLCONNECTION_H
29 
30 #ifdef _MSC_VER
31 #pragma warning( disable : 4503 4355 4786 4290 )
32 #pragma comment( lib, "libMySQL" )
33 #endif
34 
35 #include <mysql.h>
36 #include <errmsg.h>
37 #include "DatabaseConnectionID.h"
38 #include "DatabaseConnectionPool.h"
39 #include "Mutex.h"
40 
41 #undef MYSQL_PORT
42 
43 namespace FIX
44 {
45 class MySQLQuery
46 {
47 public:
48  MySQLQuery( const std::string& query )
49  : m_result( 0 ), m_query( query )
50  {}
51 
52  ~MySQLQuery()
53  {
54  if( m_result )
55  mysql_free_result( m_result );
56  }
57 
58  bool execute( MYSQL* pConnection )
59  {
60  int retry = 0;
61 
62  do
63  {
64  if( m_result ) mysql_free_result( m_result );
65  int errcode = mysql_query( pConnection, m_query.c_str() );
66  m_result = mysql_store_result( pConnection );
67  if( errcode == 0 )
68  return true;
69  m_status = mysql_errno( pConnection );
70  m_reason = mysql_error( pConnection );
71  mysql_ping( pConnection );
72  retry++;
73  } while( retry <= 1 );
74  return success();
75  }
76 
77  bool success()
78  {
79  return m_status == 0;
80  }
81 
82  int rows()
83  {
84  return (int)mysql_num_rows( m_result );
85  }
86 
87  const std::string& reason()
88  {
89  return m_reason;
90  }
91 
92  char* getValue( int row, int column )
93  {
94  if( m_rows.empty() )
95  {
96  MYSQL_ROW row = 0;
97  while( (row = mysql_fetch_row( m_result )) )
98  m_rows.push_back(row);
99  }
100  return m_rows[row][column];
101  }
102 
103  void throwException() throw( IOException )
104  {
105  if( !success() )
106  throw IOException( "Query failed [" + m_query + "] " + reason() );
107  }
108 
109 private:
110  MYSQL_RES* m_result;
111  int m_status;
112  std::string m_query;
113  std::string m_reason;
114  std::vector<MYSQL_ROW> m_rows;
115 };
116 
117 class MySQLConnection
118 {
119 public:
120  MySQLConnection
121  ( const DatabaseConnectionID& id )
122  : m_connectionID( id )
123  {
124  connect();
125  }
126 
127  MySQLConnection
128  ( const std::string& database, const std::string& user,
129  const std::string& password, const std::string& host, short port )
130  : m_connectionID( database, user, password, host, port )
131  {
132  connect();
133  }
134 
135  ~MySQLConnection()
136  {
137  if( m_pConnection )
138  mysql_close( m_pConnection );
139  }
140 
141  const DatabaseConnectionID& connectionID()
142  {
143  return m_connectionID;
144  }
145 
146  bool connected()
147  {
148  Locker locker( m_mutex );
149  return mysql_ping( m_pConnection ) == 0;
150  }
151 
152  bool reconnect()
153  {
154  Locker locker( m_mutex );
155  return mysql_ping( m_pConnection ) == 0;
156  }
157 
158  bool execute( MySQLQuery& pQuery )
159  {
160  Locker locker( m_mutex );
161  return pQuery.execute( m_pConnection );
162  }
163 
164 private:
165  void connect()
166  {
167  short port = m_connectionID.getPort();
168  m_pConnection = mysql_init( NULL );
169  if( !mysql_real_connect
170  ( m_pConnection, m_connectionID.getHost().c_str(), m_connectionID.getUser().c_str(),
171  m_connectionID.getPassword().c_str(), m_connectionID.getDatabase().c_str(), port, 0, 0 ) )
172  {
173  if( !connected() )
174  throw ConfigError( std::string("Unable to connect to database [") + mysql_error(m_pConnection) + "]" );
175  }
176  #if( MYSQL_VERSION_ID > 50000 )
177  my_bool reconnect = 1;
178  mysql_options( m_pConnection, MYSQL_OPT_RECONNECT, static_cast<char*>(&reconnect) );
179  #endif
180  }
181 
182  MYSQL* m_pConnection;
183  DatabaseConnectionID m_connectionID;
184  Mutex m_mutex;
185 };
186 
187 typedef DatabaseConnectionPool<MySQLConnection>
188  MySQLConnectionPool;
189 typedef SmartPtr< MySQLConnectionPool >
190  MySQLConnectionPoolPtr;
191 }
192 
193 #endif //FIX_MYSQLCONNECTION_H
194 #endif //HAVE_MYSQL
DatabaseConnectionID.h
Mutex.h
FIX
Definition: Acceptor.cpp:34
DatabaseConnectionPool.h

Generated on Wed Apr 29 2020 19:41:30 for QuickFIX by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2001