⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mysqlconnection.cpp

📁 C++连接一写常用数据库的接口
💻 CPP
字号:
/* * MysqlConnection object defines the needed connection functions for the dbConnect MySQL driver * Copyright (C) 2002 Johnathan Ingram, jingram@rogueware.org * * This library is free software; you can redistribute it and/or *   modify it under the terms of the GNU Lesser General Public *   License as published by the Free Software Foundation; either *   version 2.1 of the License, or (at your option) any later version. * *   This library is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *   Lesser General Public License for more details. * *   You should have received a copy of the GNU Lesser General Public *   License along with this library; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  US * */#include "mysqlConnection.h"#include "mysqlBindParam.h"#include "mysqlQuery.h"// -----------------------------------------------------------------------------// PRIVATE:// -----------------------------------------------------------------------------// -----------------------------------------------------------------------------// MysqlConnection::_mysqlConnect// -----------------------------------------------------------------------------void MysqlConnection::_mysqlConnect(         int index){
   // Make sure the handle is valid and we are not already connected.   if (index > _numHandles || index < 0)      throw Error("_mysqlConnect(): Invalid index to database handle.");   if (_handles[index]->status != BaseHandle::DISCONNECTED)      throw AlreadyConnected("_mysqlConnect(): "         "The database connection is already connected to the database.");   // Connect to the MySQL database.   mysql_init(&_handles[index]->__mysql__);   // Enable Mysql compression for the connection if specified.   if (_mysqlOptions.mysqlOptCompress)   {      mysql_options(&_handles[index]->__mysql__, MYSQL_OPT_COMPRESS, 0);   }   // Connect to the mysql database.   if (!mysql_real_connect(&_handles[index]->__mysql__, host.c_str(),                            username.c_str(), password.c_str(),                            databaseName.c_str(), 0, NULL, 0))   {      string err = "_mysqlConnect(): ";      err += mysql_error(&_handles[index]->__mysql__);      throw ErrorConnecting(err);   }     _handles[index]->status = BaseHandle::CONNECTED;   _handles[index]->lastUsed = time(NULL);} // MysqlConnection::_mysqlConnect// -----------------------------------------------------------------------------// MysqlConnection::_mysqlDisconnect// -----------------------------------------------------------------------------void MysqlConnection::_mysqlDisconnect(         int index){   // Make sure the handle is valid and we are not already connected.   if (index > _numHandles || index < 0)      throw Error("_mysqlDisconnect(): Invalid index to database handle.");      if (_handles[index]->status == BaseHandle::DISCONNECTED ||        _handles[index]->status == BaseHandle::UNKNOWN)      throw NotConnected("_mysqlDisconnect(): "         "The database handle does not have a valid connection to the database.");   // Disconnect from the server.   mysql_close(&_handles[index]->__mysql__);   _handles[index]->status = BaseHandle::DISCONNECTED;   _handles[index]->lastUsed = time(NULL);} // MysqlConnection::_mysqlDisconnect// -----------------------------------------------------------------------------// MysqlConnection::_mysqlPing// -----------------------------------------------------------------------------void MysqlConnection::_mysqlPing(      int index){   // Make sure the handle is valid.   if (index > _numHandles || index < 0)      throw Error("_mysqlPing(): Invalid index to database handle.");   // Only ping the connection if the ping interval has expired since the   //   connection was last used.	time_t currentTime = time(NULL);	if (currentTime - _handles[index]->lastUsed >= pingInterval)	{      // Timeout, lets make sure we still have a connection to the database.       // mysql_ping will try to reconnect if the connection is stale      		if (mysql_ping(&_handles[index]->__mysql__) != 0)		{         // Synchronize the function as we dont want this connection taken from us         SimpleThread_Synchronize sync(classMutex);                  // Could not reconnect using the mysql_ping, so force a connect retry         //1. Disconnect ingnoring errors         try                  {            _mysqlDisconnect(index);         }         catch(...)         { }  // Ignore any errors from the disconnect.         //2. Try get a new connection         try         {            _mysqlConnect(index);                        // Force the connection to be in use again            _handles[index]->status = BaseHandle::CONNECTED_USED;         }         catch(...)         {            string err = "_mysqlPing(): Unable to establish new connection, ";            throw ErrorPingingConnection(err);                     }         		}	}} // MysqlConnection::_mysqlPing// -----------------------------------------------------------------------------// MysqlConnection::_mysqlQuery// -----------------------------------------------------------------------------void MysqlConnection::_mysqlQuery(      int           index,      const string& sqlStatement){   // Make sure the handle is in the connected used state.   if (_handles[index]->status != BaseHandle::CONNECTED_USED)      throw ErrorQuerying("_mysqlQuery(): The database connection is not valid. May have been terminated by the connection object?");   //Execute the query   if (mysql_real_query(&_handles[index]->__mysql__, sqlStatement.c_str(), sqlStatement.length()) != 0)   {      // Something went wrong while trying to execute the sql statement, so throw an exception.      string err = "_mysqlQuery(): ";      err += "SQL statement: ";      err += sqlStatement;      err += ", ";      err += mysql_error(&_handles[index]->__mysql__);      throw ErrorQuerying(err);   }   // Set the last used   _handles[index]->lastUsed = time(NULL);} // MysqlConnection::_mysqlQuery      //------------------------------------------------------------------------------// MysqlConnection::_freeCollection//------------------------------------------------------------------------------void MysqlConnection::_freeCollection(      CollectionType type){   int i;   switch (type)   {      case CONNECTION_HANDLES:         if (_handles)         {            for (i=0; i<_numHandles; i++)            {               if (_handles[i])               {                  delete _handles[i];                  _handles[i] = NULL;                        }            }            free(_handles);            _handles = NULL;            _numHandles = 0;         }               break;          }} // MysqlConnection::_freeCollection// -----------------------------------------------------------------------------// PUBLIC:// -----------------------------------------------------------------------------// -----------------------------------------------------------------------------// MysqlConnection::MysqlConnection// -----------------------------------------------------------------------------MysqlConnection::MysqlConnection(      int argc,       const char** argv):     BaseConnection(MYSQL_DRIVERNAME),   _numHandles(0),   _handles(NULL){   // Store any arguments in a easy to use structure. (Must be even number)   // All argument names will be in lowercase.   if (argc % 2 == 0)      for (int i=0; i<argc; i+=2)      {         // Check for compression been enabled (If no entry in config file, then use default)         if (strcasecmp(argv[i], "mysql_opt_compress") ==0)            if (strcasecmp(argv[i+1], "yes") == 0)               _mysqlOptions.mysqlOptCompress = true;            else               _mysqlOptions.mysqlOptCompress = false;                  // Check for transaction support been enabled (Only supported for MYISAM tables)         if (strcasecmp(argv[i], "mysql_opt_transaction") == 0)            if (strcasecmp(argv[i+1], "yes") == 0)               _mysqlOptions.mysqlOptTransaction = true;            else               _mysqlOptions.mysqlOptTransaction = false;      }} // MysqlConnection::MysqlConnection// -----------------------------------------------------------------------------// MysqlConnection::~MysqlConnection// -----------------------------------------------------------------------------MysqlConnection::~MysqlConnection(){	// Make sure we disconnect from the database.	if (isConnected)	{		disconnect(120);  // 2 Minute timeout.	}   // Free any handles.      _freeCollection(CONNECTION_HANDLES);   } // MysqlConnection::~MysqlConnection// -----------------------------------------------------------------------------// MysqlConnection::connect// -----------------------------------------------------------------------------void MysqlConnection::connect(      const string &username,       const string &password,       const string &databaseName,       const string &host,       int          maxConnections,      int          minConnections,      const string &optParam1,      const string &optParam2){   // Synchronize the function.   SimpleThread_Synchronize sync(classMutex);   // Make sure we are not already connected.   if (isConnected)      throw ErrorConnecting("connect(): Already connected to the database.");   // Check and set the parameters. (Use the base class for this)   BaseConnection::connect(username, password, databaseName, host,      maxConnections, minConnections, optParam1, optParam2);   // Free any handles used before.   _freeCollection(CONNECTION_HANDLES);      // Create the collection to hold the needed handle information.   _numHandles = maxConnections;   _handles = (MysqlHandle**)malloc(_numHandles * sizeof(MysqlHandle*));   for (int i=0; i<_numHandles; i++)   {      _handles[i] = new MysqlHandle();      _handles[i]->status = BaseHandle::DISCONNECTED;   }         // Connect the required specified minimum connections. The rest will be on demand.   for (int j=0; j<minConnections; j++)      _mysqlConnect(j);   isConnected = true;}  // MysqlConnection::connect                           // -----------------------------------------------------------------------------// MysqlConnection::disconnect// -----------------------------------------------------------------------------voidMysqlConnection::disconnect(      time_t timeout){   // Synchronize the function.   SimpleThread_Synchronize sync(classMutex);   bool doneTimeout = false;   // Only disconnect if we are connected.   if (!isConnected)      throw NotConnected("disconnect(): Not connected to the database.");        // Disconnect all the open connections.        for (int i=0; i<_numHandles; i++)   {      // Free the query object if it is still attached.      // TODO      if (_handles[i]->status == BaseHandle::CONNECTED ||           _handles[i]->status == BaseHandle::CONNECTED_USED)      {         // If the handle is USED wait for the timeout.         // Only wait once for the timeout for all connections.         if (_handles[i]->status == BaseHandle::CONNECTED_USED && !doneTimeout)         {            SimpleThread::sleep(timeout * 1000);            doneTimeout = true;         }                     _mysqlDisconnect(i);      }   }              isConnected = false;} // MysqlConnection::disconnect// -----------------------------------------------------------------------------// MysqlConnection::requestQueryConnection// -----------------------------------------------------------------------------void*MysqlConnection::requestQueryConnection(){   // This function must act as a fifo stack. The first thread in must get the first    //   available connection.   // Synchronize the function.   SimpleThread_Synchronize sync(classMutex);      // Make sure we are connected.   if (!isConnected)      throw NotConnected("requestQueryConnection(): Not connected to the database.");    // Flag that a request is occuring.   isRequestQueryConnectionOccuring = true;      // Loop until we have a valid connection or an error.   // Built in timeout of 1 min per thread to retrieve a connection.   int i;   time_t now = time(NULL);   while (time(NULL) <= now + 60)   {      // Try and obtain a connection      for (i=0; i<_numHandles; i++)      {         // We have an available handle thats already connected.         if (_handles[i]->status == BaseHandle::CONNECTED)         {            _handles[i]->queryObject = new MysqlQuery(this, i);            _handles[i]->status = BaseHandle::CONNECTED_USED;            isRequestQueryConnectionOccuring = false;            return _handles[i]->queryObject;         }                  // We have an available handle that needs to be connected.         if (_handles[i]->status == BaseHandle::DISCONNECTED)         {            _mysqlConnect(i);            _handles[i]->queryObject = new MysqlQuery(this, i);            _handles[i]->status = BaseHandle::CONNECTED_USED;            isRequestQueryConnectionOccuring = false;            return _handles[i]->queryObject;         }      }      // Sleep for a second to conserve resources      SimpleThread::sleep(1000);   }   // If we got this far a timeout occured.   isRequestQueryConnectionOccuring = false;   throw QueryConnectionTimeout("requestQueryConnection(): A timout occured "         "while trying to obtain a query connection.");} // MysqlConnection::requestQueryConnection// -----------------------------------------------------------------------------// MysqlConnection::releaseQueryConnection// -----------------------------------------------------------------------------voidMysqlConnection::releaseQueryConnection(   void* queryObject){   // Don't synchronize as we may need to release a connection to allow   //  requestQueryConnection to get an available one      // Find the handle that has the query connection instance   int i;   for (i=0; i<_numHandles; i++)   {      if (_handles[i]->queryObject == queryObject)      {         _handles[i]->queryObject = NULL;         _handles[i]->status = BaseHandle::CONNECTED;                  // Check if we need to release the connection.         // We release the connection if the connection is outside of the minimum         // connections and there is no current request for a connection waiting.         if (i >= minConnections && !isRequestQueryConnectionOccuring)         {            _mysqlDisconnect(i);                     }                 break;      }   }} // MysqlConnection::releaseQueryConnection

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -