Main Page | Namespace List | Alphabetical List | Class List | Directories | File List | Class Members | File Members

DBInterface.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   SpikeStream Library                                                   *
00003  *   Copyright (C) 2007 by David Gamez                                     *
00004  *   david@davidgamez.eu                                                   *
00005  *   Version 0.1                                                           *
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  *   This program is distributed in the hope that it will be useful,       *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU General Public License for more details.                          *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU General Public License     *
00018  *   along with this program; if not, write to the                         *
00019  *   Free Software Foundation, Inc.,                                       *
00020  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00021  ***************************************************************************/
00022 
00023 //SpikeStream includes
00024 #include "DBInterface.h"
00025 #include "Utilities.h"
00026 #include "GlobalVariables.h"
00027 
00028 //Other includes
00029 #include <iostream>
00030 #include <iomanip>
00031 using namespace std;
00032 using namespace mysqlpp;
00033 
00034 
00035 /*! Empty default constructor - not used. */
00036 DBInterface::DBInterface(){
00037 }
00038 
00039 
00040 /*! Main constructor. */
00041 DBInterface::DBInterface(const char* host, const char* user, const char* password, const char* database){
00042         Utilities::safeCStringCopy(dbParam.host, host, dbParam.maxParamLength);
00043         Utilities::safeCStringCopy(dbParam.user, user, dbParam.maxParamLength);
00044         Utilities::safeCStringCopy(dbParam.password, password, dbParam.maxParamLength);
00045         Utilities::safeCStringCopy(dbParam.database, database, dbParam.maxParamLength);
00046 }
00047 
00048 
00049 /*! Destructor. */
00050 DBInterface::~DBInterface(){
00051         #ifdef MEMORY_DEBUG
00052                 cout<<"DELETING DBINTERFACE. NUMBER OF EXTRA CONNECTIONS: "<<connectionVector.size()<<";"<<endl;
00053         #endif//MEMORY_DEBUG
00054         
00055         //Close and delete the standard connection
00056         if(connection->connected()){
00057                 connection->close();
00058         }
00059         delete connection;
00060         
00061         //Close and delete any connections that were created by getNewConnection()
00062         for(vector<Connection*>::iterator iter = connectionVector.begin(); iter != connectionVector.end(); ++iter){
00063                 if((*iter)->connected()){
00064                         (*iter)->close();
00065                 }
00066                 delete *iter;
00067         }
00068 }
00069 
00070 
00071 //---------------------------------------------------------------------------
00072 //---------------------------- PUBLIC METHODS -------------------------------
00073 //---------------------------------------------------------------------------
00074 
00075 /*! Checks the supplied database connection. If it cannot be reconnected, 
00076         an exception is thrown. */
00077 void DBInterface::checkDatabaseConnection(Connection*& conn){
00078         /* Ping database to see if we are still connected
00079                 Returns zero if we are ok.*/
00080         int pingRes = conn->ping();
00081 
00082         //If ping fails, ping a few more times to see if the automatic reconnection works.
00083         unsigned int reconnectCounter = 1;
00084         while(pingRes){
00085                 cout<<"DBInterface: Trying to ping "<<dbParam.database<<" database."<<endl;
00086 
00087                 //Try to reconnect to the database
00088                 pingRes = conn->ping();
00089 
00090                 //Sleep if we have failed less than the maximum number of attempts
00091                 if(pingRes && reconnectCounter <= MAX_NUMBER_RECONNECT_ATTEMPTS)
00092                         sleep(1);
00093 
00094                 /* Try creating a new connection object and if this fails, throw
00095                         an exception if we have pinged more than the maximum number.*/
00096                 else if (reconnectCounter > MAX_NUMBER_RECONNECT_ATTEMPTS){
00097                         cout<<"DBInterface. Cannot ping "<<dbParam.database<<" on existing connection. Trying to reconnect to database."<<endl;
00098 
00099                         if(connectToDatabase(conn))//Have successfully reconnected to database
00100                                 pingRes = 0;
00101                         else
00102                                 throw ConnectionFailed("DBInterface: Failed to reconnect to the database.");
00103                 }
00104 
00105                 //Increase the count of the number of failed attempts
00106                 ++reconnectCounter;
00107         }
00108 }
00109 
00110 
00111 /*! Connects to the database using the parameters stored in the constructor. */
00112 bool DBInterface::connectToDatabase(bool useEx){
00113         //Record whether we are using exceptions or not
00114         useExceptions = useEx;
00115 
00116         //Create a connection using the main connection object of this class
00117         connection = new Connection(useExceptions);
00118         return connectToDatabase(connection);
00119 }
00120 
00121 
00122 /*! Returns the database parameters.
00123         Mainly used for passing dbparameters to spawned processes. */
00124 const DBParameters DBInterface::getDBParameters(){
00125         return dbParam;
00126 }
00127 
00128 
00129 /*! Creates a new connection and returns it. This is generally used for large 
00130         queries, which need to use ResUse instead of Result.
00131         NOTE: Exception handling should be done by the calling class.*/
00132 Connection* DBInterface::getNewConnection(){
00133         // Create a new connection
00134         Connection *tempConnection = new Connection(useExceptions);
00135 
00136         //Connect this connection to the database
00137         if(!connectToDatabase(tempConnection)){
00138                 cerr<<"DBInterface: NEW CONNECTION TO DATABASE FAILED: "<<tempConnection->error()<<endl;
00139                 return 0;
00140         }
00141         else{
00142                 connectionVector.push_back(tempConnection);//Store a reference to the query for deletion later
00143                 return tempConnection;
00144         }
00145 }
00146 
00147 
00148 /*! Returns the query from the main connection.
00149         Throws an exception if the database connection has failed and cannot be restored.*/
00150 Query DBInterface::getQuery(){
00151 
00152         /* Check the database connection before returning the query.
00153                 This will throw an exception if the database cannot be
00154                 reconnected.*/
00155         checkDatabaseConnection(connection);
00156 
00157         //Return the query if we have not thrown an exception
00158         return connection->query();
00159 }
00160 
00161 
00162 //---------------------------------------------------------------------------
00163 //---------------------------- PRIVATE METHODS -------------------------------
00164 //---------------------------------------------------------------------------
00165 
00166 /*! Connects the specified connection to the database.*/
00167 bool DBInterface::connectToDatabase(Connection*& conn){
00168         try{
00169                 conn->connect(dbParam.database, dbParam.host, dbParam.user, dbParam.password);
00170                 if(!conn->connected()){
00171                         cerr<<"DBInterface: CONNECTION TO DATABASE FAILED: "<<connection->error()<<endl;
00172                         return false;
00173                 }
00174                 else{
00175                         return true;
00176                 }
00177         }
00178         catch (const std::exception er) {
00179                 cerr<<"DBInterface: EXCEPTION THROWN CONNECTING TO DATABASE: "<<er.what()<<endl;
00180         return false;
00181     }
00182 }
00183 
00184 

Generated on Mon Sep 3 22:18:50 2007 for SpikeStream Library by  doxygen 1.4.4