Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Related Pages

IOManagerDB.cpp

00001 #include "IOManagerDB.h"
00002 #include "MySqlException.h"
00003 #include "ZlibStringCompressor.h"
00004 #include "Sct/Serializable.h"
00005 #include "Sct/SctNames.h"
00006 #include "Sct/XmlStyleStream.h"
00007 #include "Sct/StdExceptionWrapper.h"
00008 #include "Sct/Archive/IONameArchiveFile.h"
00009 
00010 #include "Sct/UniqueID.h"
00011 #include "SctData/ScanResult.h"
00012 #include "SctData/TestResult.h"
00013 #include <sstream>
00014 #include <boost/date_time/posix_time/posix_time.hpp>
00015 
00016 using std::string;
00017 using std::ostringstream;
00018 using boost::posix_time::to_simple_string;
00019 using boost::shared_ptr;
00020 using namespace Sct;
00021 
00022 namespace SctArchiving {
00023   MysqlException::MysqlException(const string& msg, const string& file, int line){
00024     initialize("MYSQL_EXCEPTION", "ArchivingService::MysqlException", msg, 0, file, line);
00025   }
00026 
00027   MysqlException::MysqlException(const string& msg, const string& query, const string& file, int line) {
00028     std::ostringstream full_message;
00029     full_message << msg << "\nwhile executing query:\n" << query;
00030     initialize("MYSQL_EXCEPTION", "ArchivingService::MysqlException", full_message.str(), 0, file, line);
00031   }
00032   
00033   MysqlException::MysqlException(){}
00034   
00035   MysqlException::~MysqlException() throw(){}
00036   
00037   void IOManagerDB::checkForErrors(const string& msg, const string& file, int line){
00038     if(mysql_errno(m_mysql)){
00039       std::ostringstream full_message;
00040       full_message << msg << "\n" 
00041            << mysql_error(m_mysql);
00042       std::cerr << "ERROR:" << full_message.str() << "\nat " << file << ":" << line << std::endl;
00043       throw MysqlException(full_message.str(), file, line);
00044     }
00045   }
00046   
00047   void IOManagerDB::checkForErrors(const string& msg, const string& query, const string& file, int line){
00048     if(mysql_errno(m_mysql)){
00049       std::ostringstream full_message;
00050       full_message << msg << "\n" 
00051            << mysql_error(m_mysql);
00052       std::cerr << "ERROR:" << full_message.str()
00053         << "\n executing: "
00054         << query
00055         << "\nat " << file << ":" << line << std::endl;
00056       throw MysqlException(full_message.str(), query, file, line);
00057     }
00058   }
00059   
00060   
00061   
00062   IOManagerDB::IOManagerDB() : m_locationName("nowhere") {
00063     std::cout <<"Creating IOManagerDB" << std::endl;
00064     m_compressor = shared_ptr<ZlibStringCompressor>(new ZlibStringCompressor());
00065     m_mysql = mysql_init((MYSQL*) 0);
00066     checkForErrors("Problem during initialisation of MYSQL structure.", __FILE__, __LINE__);
00067     
00068     // connect to the server
00069     std::cout <<"Connecting IOManagerDB" << std::endl;
00070     mysql_real_connect(m_mysql, "localhost", "daquser", "", NULL, 3306, NULL, 0);
00071     checkForErrors("Failed to connect to mysql server", __FILE__, __LINE__);
00072     SctNames::Mrs() << MRS_TEXT("Have connected to mysql server") << "IOMANAGER_DB_CONNECT" 
00073             << MRS_INFORMATION << ENDM;
00074 
00075     // connect to the database
00076     std::string dbname="test_srd";
00077     std::cout <<"Connecting IOManagerDB to database name=`" << dbname << "'" << std::endl;
00078     mysql_select_db(m_mysql, dbname.c_str());
00079     std::string message("Failed to connect to database");
00080     message += dbname;
00081     checkForErrors(message, __FILE__, __LINE__);
00082     SctNames::Mrs() << MRS_TEXT("Have connected to mysql database") << "IOMANAGER_DB_CONNECT" 
00083             << MRS_PARAM<const char*>("database_name",dbname.c_str())
00084             << MRS_INFORMATION << ENDM;
00085   }
00086   
00087   IOManagerDB::~IOManagerDB(){
00088 #warning "AJB This never seems to get called because the manager is a static beast. **Hopefully** this dosent matter!"
00089     std::string message("Closing connection to mysql server");
00090     std::cout << message << endl;
00091     SctNames::Mrs() << MRS_TEXT(message) << "IOMANAGER_DB_CONNECT" 
00092             << MRS_INFORMATION << ENDM;
00093     mysql_close(m_mysql);
00094   }
00095   
00096   IOManagerDB* IOManagerDB::s_man=0;
00097   
00098   IOManagerDB& IOManagerDB::instance() {
00099     if (!s_man) s_man=new IOManagerDB();
00100     return *s_man;
00101   }
00102   
00103   std::string IOManagerDB::status() const {
00104     std::ostringstream oss;
00105     oss << "IOManagerDB";
00106     if (m_compressor.get()){
00107       oss << "String compressor buffer size : " 
00108       << m_compressor->getBufferSize() << std::endl;
00109     } else {
00110       oss << "String compressor not initialized" << endl;
00111     }
00112     return oss.str();
00113   }
00114 
00115   const SctData::ResultHeader& IOManagerDB::getHeader(const Serializable& ob){
00116     const SctData::ResultHeader* header=0;
00117     if (ob.getClassName().find("TestResult")!=string::npos) {
00118       header = & dynamic_cast<const SctData::TestResult&>(ob).getHeader();
00119     } 
00120     if (ob.getClassName().find("ScanResult")!=string::npos) {
00121       header = & dynamic_cast<const SctData::ScanResult&>(ob).getHeader();
00122     }
00123     if (header) {
00124       return *header;
00125     } else {
00126       ostringstream oss;
00127       oss << "Dont know how to find a header for object with class name : " 
00128       << ob.getClassName() << " which has UniqueID : " 
00129       << (string) ob.getUniqueID();
00130       throw IoException(oss.str(), __FILE__, __LINE__);
00131     }
00132   }
00133   
00134   string IOManagerDB::getTable(const Serializable& ob){
00135     return "data";
00136   }
00137 
00138   void IOManagerDB::write(const Serializable& ob, const IOParams* par) const {
00139     try{
00140       boost::recursive_mutex::scoped_lock lock (getMutex());
00141       setReadMode(false);
00142       
00143     }catch (Sct::Throwable& e){
00144       throw;
00145     }catch(std::exception& e){
00146       StdExceptionWrapper sew(e);
00147       throw IoException(sew, __FILE__, __LINE__);
00148     }
00149   }
00150 
00151   boost::shared_ptr<Serializable> IOManagerDB::read(const string& name, const IOParams* par) const {
00152     try{
00153       boost::recursive_mutex::scoped_lock lock (getMutex());
00154       setReadMode(true);
00155       getReadVersionMap().clear();
00156       const string compressed;
00157 #warning "AJB added null string above"
00158       std::istringstream iss(m_compressor->inflate(compressed));
00159       XmlStyleIStream in_ad(iss);
00160       return boost::dynamic_pointer_cast<Serializable>(readImpl(in_ad));      
00161     }catch (Sct::Throwable& e) {
00162       throw;
00163     }catch(std::exception& e){
00164       StdExceptionWrapper sew(e);
00165       throw IoException(sew, __FILE__, __LINE__);
00166     }
00167   }
00168   
00169 bool IOManagerDB::testExists(const TestData& testdata){
00170   const std::string tableName="tblTests";
00171   std::ostringstream select;
00172   select << "SELECT tblTests.* FROM tblTestTypes " 
00173      << "\nINNER JOIN ((tblLocations INNER JOIN tblRuns ON "
00174      << "\ntblLocations.LocationID = tblRuns.LocationID) INNER JOIN tblTests ON "
00175      << "tblRuns.RunID = tblTests.RunID) ON tblTestTypes.TestTypeID = tblTests.TestTypeID"
00176      << "\nWHERE (((tblTestTypes.TestTypeName) = '" << testdata.testName << "' )\n" 
00177      << "AND ((tblLocations.LocationName) = '" << getLocationName() << "')" 
00178      << "\n AND ((tblRuns.RunNr)="  << testdata.runNumber
00179      << ")\n AND ((tblTests.StartTime)='"
00180      << convertToMysqlDateTimeFormat(testdata.startTime)
00181      << "'))";
00182   
00183   mysql_query(m_mysql, select.str().c_str());
00184   checkForErrors("Could not check for test", select.str(), __FILE__, __LINE__);
00185   
00186   shared_ptr<MYSQL_RES> result (mysql_store_result(m_mysql));
00187   checkForErrors("Error storing result", select.str(), __FILE__, __LINE__);
00188   
00189   unsigned number_of_rows = mysql_num_rows(result.get());
00190   return (number_of_rows);
00191 }
00192 
00193 
00194 bool IOManagerDB::runExists(unsigned long runNumber){
00195   const std::string tableName="tblRuns";
00196   std::ostringstream select;
00197   select << "SELECT * FROM tblLocations INNER JOIN tblRuns "
00198      <<" ON tblLocations.LocationID = tblRuns.LocationID "
00199      <<" WHERE (((tblLocations.LocationName)='"
00200      << getLocationName()
00201      << "') AND ((tblRuns.RunNr)=" << runNumber << "))";
00202   mysql_query(m_mysql, select.str().c_str());
00203   
00204   checkForErrors("Could not check for run", select.str(), __FILE__, __LINE__);
00205   
00206   shared_ptr<MYSQL_RES> result (mysql_store_result(m_mysql));
00207   checkForErrors("Error storing result", __FILE__, __LINE__);
00208   
00209   unsigned number_of_rows = mysql_num_rows(result.get());
00210   return (number_of_rows);
00211 }
00212 
00213 void IOManagerDB::addRun(unsigned long runNumber){
00214   const std::string tableName="tblRuns";
00215   bool trash;
00216   std::ostringstream select;
00217   select << "INSERT INTO " << tableName << "\n("
00218      << "LocationID, RunNr, Trash"
00219      << ")"
00220      << "\nSELECT tblLocations.LocationID" << ", "
00221      << runNumber << " AS RunNr, 0 AS Trash "
00222      << "\nFROM tblLocations"
00223      << "\nWHERE ((tblLocations.LocationName) = '" 
00224      << getLocationName()
00225      << "')";
00226   mysql_query(m_mysql, select.str().c_str());
00227   checkForErrors("Cannot execute", select.str(), __FILE__, __LINE__);
00228   if (mysql_affected_rows(m_mysql)!=1){
00229     throw MysqlException("Did NOT add row", select.str(), __FILE__, __LINE__);
00230   }
00231 }
00232 
00233 std::string IOManagerDB::convertToMysqlDateTimeFormat(const std::string& original){
00234   std::string copy=original;
00235   unsigned t = copy.find('T');
00236   if (t==string::npos) {
00237     std::ostringstream msg;
00238     msg << "could not parse date/time since I couldn't find a `T' in " << copy;
00239     throw Sct::IoException(msg.str(), __FILE__, __LINE__);
00240   }
00241   return copy.erase(t,1);
00242 }
00243 
00244 void IOManagerDB::addTest(const TestData& testdata, bool alsoAddScans){
00245   const std::string tableName="tblTests";
00246   std::ostringstream select;
00247 
00248   select << "INSERT INTO " << tableName
00249      << "\n(RunID, TestTypeID, StartTime, EndTime )"
00250      << "\nSELECT tblRuns.RunID, tblTestTypes.TestTypeID, "
00251      << "'" << convertToMysqlDateTimeFormat( testdata.startTime )
00252      << "' AS StartTime, "
00253      << "'" << convertToMysqlDateTimeFormat( testdata.endTime )
00254      << "' AS EndTime ";
00255   select << "\nFROM " << "tblTestTypes" << ", " << "tblLocations"
00256      << " INNER JOIN " << "tblRuns" << " ON "
00257      << "tblLocations.LocationID = tblRuns.LocationID";
00258   select << "\nWHERE ((" 
00259      << "(tblTestTypes.TestTypeName) = '" <<  testdata.testName << "')"
00260      << "\nAND ((tblRuns.RunNr) = " << testdata.runNumber << ")"
00261      << "\nAND ((tblLocations.LocationName) = '" << getLocationName() << "'))";
00262 
00263   mysql_query(m_mysql, select.str().c_str());
00264   checkForErrors("Cannot execute", select.str(), __FILE__, __LINE__);
00265   if (mysql_affected_rows(m_mysql)!=1){
00266     throw MysqlException("Did NOT add row", select.str(), __FILE__, __LINE__);
00267   }
00268   if (alsoAddScans){
00269     for (unsigned iscan=testdata.startScanNumber; 
00270      iscan < (testdata.startScanNumber + testdata.nScans);
00271      ++iscan){
00272       addScan(testdata, iscan);
00273     }
00274   }
00275 }
00276 
00277 bool IOManagerDB::scanExists(const TestData& testdata, unsigned scanNumber){
00278 #warning "NOT IMPLIMENTED"
00279   return false;
00280 }
00281 
00282 void IOManagerDB::addScan(const TestData& testdata, unsigned scanNumber){
00283   const std::string tableName="tblScans";
00284   std::ostringstream select;
00285   
00286   select << "INSERT INTO " << tableName
00287      << "\n(TestID, ScanNr)"
00288      << "\nSELECT tblTests.TestID, " << scanNumber
00289      << " AS ScanNr ";
00290   select << "\nFROM " << "tblTestTypes INNER JOIN (" << "tblLocations"
00291      << " INNER JOIN (" << "tblRuns INNER JOIN "
00292          << "tblTests ON tblRuns.RunID = tblTests.RunID)"
00293          << " ON tblLocations.LocationID = tblRuns.LocationID)"
00294          << " ON tblTestTypes.TestTypeID = tblTests.TestTYpeID";
00295   select << "\nWHERE ((" 
00296      << "(tblTestTypes.TestTypeName) = '" <<  testdata.testName << "')"
00297      << "\nAND ((tblRuns.RunNr) = " << testdata.runNumber << ")"
00298      << "\nAND ((tblLocations.LocationName) = '" << getLocationName() << "'))"
00299          << "\nAND ((tblTests.StartTime) = '" << convertToMysqlDateTimeFormat(testdata.startTime) << "')";
00300   
00301   mysql_query(m_mysql, select.str().c_str());
00302   checkForErrors("Cannot execute", select.str(), __FILE__, __LINE__);
00303   if (mysql_affected_rows(m_mysql)!=1){
00304     throw MysqlException("Did NOT add row", select.str(), __FILE__, __LINE__);
00305   }
00306 }
00307 
00308 void IOManagerDB::setLocationName(const std::string& name){
00309   m_locationName=name;
00310 }
00311 
00312 std::string IOManagerDB::getLocationName(){
00313   return m_locationName;
00314 }
00315 
00316 }

Generated on Fri Sep 16 18:01:52 2005 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5