00001 #include "IOManagerDB.h"
00002 #include "IONameDB.h"
00003 #include "MySqlException.h"
00004 #include "ZlibStringCompressor.h"
00005 #include "Sct/Serializable.h"
00006 #include "Sct/SctNames.h"
00007 #include "Sct/XmlStyleStream.h"
00008 #include "Sct/StdExceptionWrapper.h"
00009 #include "Sct/Archive/IONameArchiveFile.h"
00010
00011 #include "Sct/UniqueID.h"
00012 #include "SctData/ScanResult.h"
00013 #include "SctData/TestResult.h"
00014 #include "CalibrationController/Serialization/IsInfoWrapper.h"
00015 #include "CalibrationController/Serialization/TestDataWrapper.h"
00016 #include <sstream>
00017 #include "boost/lexical_cast.hpp"
00018
00019 using std::string;
00020 using std::ostringstream;
00021 using boost::shared_ptr;
00022 using namespace Sct;
00023
00024 namespace SctArchiving {
00025
00026 MysqlException::MysqlException(const string& msg, const string& file, int line){
00027 initialize("MYSQL_EXCEPTION", "ArchivingService::MysqlException", msg, 0, file, line);
00028 }
00029 MysqlException::MysqlException(const string& msg, const string& query, const string& file, int line) {
00030 std::ostringstream full_message;
00031 full_message << msg << "\nwhile executing query:\n" << query;
00032 initialize("MYSQL_EXCEPTION", "ArchivingService::MysqlException", full_message.str(), 0, file, line);
00033 }
00034
00035 MysqlException::MysqlException(){}
00036
00037 MysqlException::~MysqlException() throw(){}
00038
00039 void IOManagerDB::checkForMySqlErrors(const string& msg, const string& file, int line) const{
00040 if(mysql_errno(m_mysql)){
00041 std::ostringstream full_message;
00042 full_message << msg << "\n"
00043 << mysql_error(m_mysql) << "\n";
00044 std::cerr << "ERROR: " << full_message.str() << "\nat " << file << ":" << line << std::endl;
00045 throw MysqlException(full_message.str(), file, line);
00046 }
00047 }
00048
00049 void IOManagerDB::checkForMySqlErrors(const string& msg, const string& query, const string& file, int line) const{
00050 if(mysql_errno(m_mysql)){
00051 std::ostringstream full_message;
00052 full_message << msg << "\n"
00053 << query << "\n"
00054 << mysql_error(m_mysql) << "\n";
00055
00056
00057
00058
00059
00060 throw MysqlException(full_message.str(), file, line);
00061 }
00062 }
00063
00064
00065
00066 IOManagerDB::IOManagerDB() : m_dataSetName("nowhere"),
00067 m_nRead(0), m_nWrite(0),
00068 m_nCompress(0), m_nDecompress(0),
00069 read_time(0,0,0,0), write_time(0,0,0,0),
00070 compress_time(0,0,0,0), decompress_time(0,0,0,0)
00071 {
00072
00073 std::cout <<"Creating IOManagerDB" << std::endl;
00074 m_compressor = shared_ptr<ZlibStringCompressor>(new ZlibStringCompressor());
00075 m_mysql = mysql_init((MYSQL*) 0);
00076 checkForMySqlErrors("Problem during initialisation of MYSQL structure.", __FILE__, __LINE__);
00077
00078
00079 std::cout <<"Connecting IOManagerDB" << std::endl;
00080 mysql_real_connect(m_mysql, "localhost", "daquser", "", NULL, 3306, NULL, 0);
00081 checkForMySqlErrors("Failed to connect to mysql server", __FILE__, __LINE__);
00082 SctNames::Mrs() << MRS_TEXT("Have connected to mysql server") << "IOMANAGER_DB_CONNECT"
00083 << MRS_INFORMATION << ENDM;
00084
00085
00086 std::string dbname="test_dbSRD";
00087 std::cout <<"Connecting IOManagerDB to database name=`" << dbname << "'" << std::endl;
00088 mysql_select_db(m_mysql, dbname.c_str());
00089 std::string message("Failed to connect to database");
00090 message += dbname;
00091 checkForMySqlErrors(message, __FILE__, __LINE__);
00092 SctNames::Mrs() << MRS_TEXT("Have connected to mysql database") << "IOMANAGER_DB_CONNECT"
00093 << MRS_PARAM<const char*>("database_name",dbname.c_str())
00094 << MRS_INFORMATION << ENDM;
00095 }
00096
00097 IOManagerDB::~IOManagerDB(){
00098 #warning "AJB This never seems to get called because the manager is a static beast. **Hopefully** this dosent matter!"
00099 std::string message("Closing connection to mysql server");
00100 std::cout << message << endl;
00101 SctNames::Mrs() << MRS_TEXT(message) << "IOMANAGER_DB_CONNECT"
00102 << MRS_INFORMATION << ENDM;
00103 mysql_close(m_mysql);
00104 }
00105
00106 IOManagerDB* IOManagerDB::s_man=0;
00107
00108 IOManagerDB& IOManagerDB::instance() {
00109 if (!s_man) s_man=new IOManagerDB();
00110 return *s_man;
00111 }
00112
00113
00114
00115
00116 std::string IOManagerDB::status() const {
00117 std::ostringstream oss;
00118 oss << "IOManagerDB";
00119 if (m_compressor.get()){
00120 oss << "String compressor buffer size: "
00121 << m_compressor->getBufferSize() << std::endl;
00122 }
00123 else {
00124 oss << "String compressor not initialized" << endl;
00125 }
00126 {
00127 boost::recursive_mutex::scoped_lock lock (getMutex());
00128 oss << "write time " << write_time << " for " << m_nWrite;
00129 oss << endl;
00130
00131 oss << "read time " << read_time << " for " << m_nRead;
00132 oss << endl;
00133
00134 oss << "compress time " << compress_time << " for " << m_nCompress;
00135 oss << endl;
00136
00137 oss << "decompress time " << decompress_time << " for " << m_nDecompress;
00138 oss << endl;
00139
00140 oss << "blob-add time " << blob_add_time << " for " << m_nBlobAdd;
00141 oss << endl;
00142
00143 oss << "ostream time " << ostream_time << " for " << m_nWrite;
00144 oss << endl;
00145
00146 oss << "istream time " << istream_time << " for " << m_nRead;
00147 oss << endl;
00148
00149 }
00150 return oss.str();
00151 }
00152
00153
00154 const SctData::ResultHeader& IOManagerDB::getHeader(const Serializable& ob){
00155 const SctData::ResultHeader* header=0;
00156 if (ob.getClassName().find("TestResult")!=string::npos) {
00157 header = & dynamic_cast<const SctData::TestResult&>(ob).getHeader();
00158 }
00159 if (ob.getClassName().find("ScanResult")!=string::npos) {
00160 header = & dynamic_cast<const SctData::ScanResult&>(ob).getHeader();
00161 }
00162 if (header) {
00163 return *header;
00164 } else {
00165 ostringstream oss;
00166 oss << "Dont know how to find a header for object with class name : "
00167 << ob.getClassName() << " which has UniqueID : "
00168 << (string) ob.getUniqueID();
00169 throw IoException(oss.str(), __FILE__, __LINE__);
00170 }
00171 }
00172
00173
00174 string IOManagerDB::getTable(const Serializable& ob){
00175 return "data";
00176 }
00177
00178
00179
00180 void IOManagerDB::write(const Serializable& ob, const IOParams* par) const {
00181 using namespace boost::posix_time;
00182 ptime write_start_time(microsec_clock::local_time());
00183 using SctCalibrationController::IsInfoWrapper;
00184
00185 try{
00186 boost::recursive_mutex::scoped_lock lock (getMutex());
00187 setReadMode(false);
00188
00189 std::ostringstream oss;
00190 Sct::XmlStyleOStream out_ad(oss);
00191
00192 ptime ostream_start_time(microsec_clock::local_time());
00193 writeImpl(out_ad, ob, false);
00194 {
00195 ptime ostream_end_time(microsec_clock::local_time());
00196 boost::recursive_mutex::scoped_lock lock(timingAccess);
00197 ostream_time=ostream_time+(ostream_end_time-ostream_start_time);
00198 }
00199
00200
00201 const std::string classname = ob.getClassName();
00202 const Sct::UniqueID id = ob.getUniqueID();
00203
00204
00205 std::cout << "IOMwrite - str(id) : " << (std::string)id << std::endl;
00206 std::cout << "IOMwrite - DataSetName: " << getDataSetName() << std::endl;
00207 std::cout << "IOMwrite - ClassName : " << classname << std::endl;
00208 std::cout << "IOMwrite - Scan# : " << id.getScanNumber() << std::endl;
00209 std::cout << "IOMwrite - Run# : " << id.getRunNumber() << std::endl;
00210
00211
00212 std::string runId = getRunID(id.getRunNumber());
00213
00214
00215 if (classname == "TestData"){
00216
00217 const IsInfoWrapper& wrapper = dynamic_cast<const IsInfoWrapper&>(ob);
00218
00219
00220 boost::shared_ptr<const ISInfo> info = wrapper.getWrapped();
00221 if (info.get() == 0){
00222
00223 std::cout << "IOMwrite - debug msg, failed to get wrapped object" << std::endl;
00224 }
00225
00226
00227 boost::shared_ptr<const TestData> td = boost::dynamic_pointer_cast<const TestData>(info);
00228 if (td.get() == 0){
00229
00230 std::cout << "IOMwrite - debug msg, cast into TestData failed" << std::endl;
00231 }
00232
00233
00234 if (runId == ""){
00235 addRun(id.getRunNumber(), false);
00236
00237 runId = getRunID(id.getRunNumber());
00238 }
00239
00240
00241 std::string testId = getTestID(runId, id.getScanNumber());
00242 if (testId == ""){
00243 addTest(*td, true);
00244
00245 testId = getTestID(runId, id.getScanNumber());
00246 }
00247
00248
00249 for (unsigned int i=0; i < (*td).modules_size; ++i) {
00250
00251 std::string moduleId = getModuleID((*td).modules[i]);
00252 if (moduleId == ""){
00253
00254 addModule("DummyLayer", "0", "0", (*td).modules[i]);
00255 moduleId = getModuleID((*td).modules[i]);
00256 }
00257
00258 for (unsigned int j=0; j < (*td).nScans; ++j) {
00259
00260 std::string scanId = getScanID(testId, (*td).startScanNumber + j);
00261 addRawDataRecord(moduleId, scanId);
00262
00263 }
00264 }
00265 }
00266 else {
00267
00268 if (runId == ""){
00269 ostringstream ossMsg;
00270 ossMsg << "The requested Run was not found in the db, runNr: " << id.getRunNumber();
00271 throw IoException(ossMsg.str(), __FILE__, __LINE__);
00272 }
00273
00274
00275 unsigned firstScanNumber;
00276 std::ostringstream select;
00277 select << "SELECT Max(FirstScanNr) FROM tblTests "
00278 << "WHERE ((FirstScanNr <= " << id.getScanNumber() << ") "
00279 << "AND (RunID = " << runId << ")) "
00280 << "GROUP BY RunID ";
00281 firstScanNumber = boost::lexical_cast<int>(executeQueryReturnID(select.str()));
00282
00283
00284 std::string testId = getTestID(runId, firstScanNumber);
00285 if (testId == ""){
00286
00287 std::cout << "IOMwrite - debug msg, oops, this test is not in the db" << std::endl;
00288 }
00289
00290
00291 std::string scanId = getScanID(testId, id.getScanNumber());
00292 if (scanId == ""){
00293 ostringstream ossMsg;
00294 ossMsg << "The requested Scan was not found in the db (runNr: " << id.getRunNumber()
00295 << ", firstScanNr: " << firstScanNumber
00296 << ", ScanNr: " << id.getScanNumber() << ")";
00297 throw IoException(ossMsg.str(), __FILE__, __LINE__);
00298 }
00299
00300
00301 std::string moduleId = getModuleID(id.getModule());
00302 if (moduleId == ""){
00303 ostringstream ossMsg;
00304 ossMsg << "The requested Module was not found in the db, modNr: " << id.getModule();
00305 throw IoException(ossMsg.str(), __FILE__, __LINE__);
00306 }
00307
00308
00309 const std::string& uncompressed = oss.str();
00310 ptime compress_start_time(microsec_clock::local_time());
00311 const std::string compressed = m_compressor->compress(uncompressed, getCompressionLevel());
00312 {
00313 ptime compress_end_time(microsec_clock::local_time());
00314 boost::recursive_mutex::scoped_lock lock(timingAccess);
00315 compress_time=compress_time+(compress_end_time-compress_start_time);
00316 m_nCompress++;
00317 }
00318
00319 ptime blob_add_start_time(microsec_clock::local_time());
00320 addRawDataBlob(moduleId, scanId, compressed.c_str(), compressed.size());
00321 {
00322 ptime blob_add_end_time(microsec_clock::local_time());
00323 boost::recursive_mutex::scoped_lock lock(timingAccess);
00324 blob_add_time=blob_add_time+(blob_add_end_time-blob_add_start_time);
00325 m_nBlobAdd++;
00326 }
00327
00328
00329 std::cout << "IOMwrite - 1stScan# : " << firstScanNumber << std::endl;
00330 std::cout << "IOMwrite - RunID : " << runId << std::endl;
00331 std::cout << "IOMwrite - ModID : " << moduleId << std::endl;
00332 std::cout << "IOMwrite - TestID : " << testId << std::endl;
00333 std::cout << "IOMwrite - ScanID : " << scanId << std::endl;
00334 }
00335 }catch (Sct::Throwable& e){
00336 throw;
00337 }catch(std::exception& e){
00338 StdExceptionWrapper sew(e);
00339 throw IoException(sew, __FILE__, __LINE__);
00340 }
00341
00342 {
00343 ptime write_end_time(microsec_clock::local_time());
00344 boost::recursive_mutex::scoped_lock lock(timingAccess);
00345 write_time=write_time+(write_end_time-write_start_time);
00346 m_nWrite++;
00347 }
00348 }
00349
00350
00351 boost::shared_ptr<Serializable> IOManagerDB::read(const string& name, const IOParams* par) const {
00352 using namespace boost::posix_time;
00353 ptime read_start_time(microsec_clock::local_time());
00354
00355 using SctCalibrationController::TestDataWrapper;
00356 try{
00357 boost::recursive_mutex::scoped_lock lock (getMutex());
00358 setReadMode(true);
00359 getReadVersionMap().clear();
00360
00361 const IONameDB ioname(name);
00362 const Sct::UniqueID id = ioname.getUniqueID();
00363 const std::string classname = ioname.getClassName();
00364
00365
00366 boost::shared_ptr<Serializable> p_ob;
00367
00368
00369 std::cout << "IOMread - name : " << name << std::endl;
00370 std::cout << "IOMread - str(id) : " << (std::string)id << std::endl;
00371 std::cout << "IOMread - DataSetName: " << getDataSetName() << std::endl;
00372 std::cout << "IOMread - ClassName : " << classname << std::endl;
00373 std::cout << "IOMread - Scan# : " << id.getScanNumber() << std::endl;
00374 std::cout << "IOMread - Run# : " << id.getRunNumber() << std::endl;
00375
00376
00377 std::string runId = getRunID(id.getRunNumber());
00378 if (runId == ""){
00379 ostringstream oss;
00380 oss << "The requested Run was not found in the db, runNr: " << id.getRunNumber();
00381 throw IoException(oss.str(), __FILE__, __LINE__);
00382 }
00383
00384
00385 if (classname == "TestData"){
00386
00387 std::string testId = getTestID(runId, id.getScanNumber());
00388 if (testId == ""){
00389 ostringstream oss;
00390 oss << "The requested Test was not found in the db (runNr: " << id.getRunNumber()
00391 << ", firstScanNr: " << id.getScanNumber() << ")";
00392 throw IoException(oss.str(), __FILE__, __LINE__);
00393 }
00394
00395
00396 boost::shared_ptr<TestData> td(new TestData());
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 td->testName="blah";
00412
00413 boost::shared_ptr<TestDataWrapper> wrapper(new TestDataWrapper(td));
00414 {
00415 ptime read_end_time(microsec_clock::local_time());
00416 boost::recursive_mutex::scoped_lock lock(timingAccess);
00417 read_time=read_time+(read_end_time-read_start_time);
00418 m_nRead++;
00419 }
00420 return wrapper;
00421 }
00422 else if (classname == "SctData::RawScanResult"){
00423
00424 unsigned firstScanNumber;
00425 std::ostringstream select;
00426 select << "SELECT Max(FirstScanNr) FROM tblTests "
00427 << "WHERE ((FirstScanNr <= " << id.getScanNumber() << ") "
00428 << "AND (RunID = " << runId << ")) "
00429 << "GROUP BY RunID ";
00430 firstScanNumber = boost::lexical_cast<int>(executeQueryReturnID(select.str()));
00431
00432
00433 std::string testId = getTestID(runId, firstScanNumber);
00434 if (testId == ""){
00435
00436 std::cout << "IOMwrite - debug msg, oops, this test is not in the db" << std::endl;
00437 }
00438
00439
00440 std::string scanId = getScanID(testId, id.getScanNumber());
00441 if (scanId == ""){
00442 ostringstream oss;
00443 oss << "The requested Scan was not found in the db (runNr: " << id.getRunNumber()
00444 << ", firstScanNr: " << firstScanNumber
00445 << ", ScanNr: " << id.getScanNumber() << ")";
00446 throw IoException(oss.str(), __FILE__, __LINE__);
00447 }
00448
00449
00450 std::string moduleId = getModuleID(id.getModule());
00451 if (moduleId == ""){
00452 ostringstream oss;
00453 oss << "The requested Module was not found in the db, modNr: " << id.getModule();
00454 throw IoException(oss.str(), __FILE__, __LINE__);
00455 }
00456
00457
00458 std::cout << "IOMread - 1stScan# : " << firstScanNumber << std::endl;
00459 std::cout << "IOMread - RunID : " << runId << std::endl;
00460 std::cout << "IOMread - ModID : " << moduleId << std::endl;
00461 std::cout << "IOMread - TestID : " << testId << std::endl;
00462 std::cout << "IOMread - ScanID : " << scanId << std::endl;
00463
00464
00465 std::string compressed;
00466 compressed = getRawDataBlob(moduleId, scanId);
00467
00468
00469 ptime decompress_start_time(microsec_clock::local_time());
00470 const std::string uncompressed = m_compressor->inflate(compressed);
00471 {
00472 ptime decompress_end_time(microsec_clock::local_time());
00473 boost::recursive_mutex::scoped_lock lock(timingAccess);
00474 decompress_time=decompress_time+(decompress_end_time-decompress_start_time);
00475 m_nDecompress++;
00476 }
00477
00478 std::istringstream iss(uncompressed);
00479 XmlStyleIStream in_ad(iss);
00480
00481 ptime istream_start_time(microsec_clock::local_time());
00482 p_ob = boost::dynamic_pointer_cast<Serializable>(readImpl(in_ad));
00483 {
00484 ptime istream_end_time(microsec_clock::local_time());
00485 boost::recursive_mutex::scoped_lock lock(timingAccess);
00486 istream_time=istream_time+(istream_end_time-istream_start_time);
00487 }
00488 }
00489 else if (classname == "SctData::FitScanResult"){
00490
00491 throw Sct::LogicError("not implimented!", __FILE__, __LINE__);
00492 }
00493 else if (classname == "xxxTestResult"){
00494
00495 throw Sct::LogicError("not implimented!", __FILE__, __LINE__);
00496 }
00497 else {
00498 ostringstream oss;
00499 oss << "Unknown Class name: " << classname;
00500 throw IoException(oss.str(), __FILE__, __LINE__);
00501 }
00502
00503 {
00504 ptime read_end_time(microsec_clock::local_time());
00505 boost::recursive_mutex::scoped_lock lock(timingAccess);
00506 read_time=read_time+(read_end_time-read_start_time);
00507 m_nRead++;
00508 }
00509 return p_ob;
00510
00511 }catch (Sct::Throwable& e) {
00512 throw;
00513 }catch(std::exception& e){
00514 StdExceptionWrapper sew(e);
00515 throw IoException(sew, __FILE__, __LINE__);
00516 }
00517 }
00518
00519
00520
00521 std::string IOManagerDB::convertToMysqlDateTimeFormat(const std::string& original){
00522 std::string copy=original;
00523 unsigned t = copy.find('T');
00524 if (copy.empty()) {
00525
00526 copy = "0000-00-00 00:00:00";
00527 } else if (t==string::npos) {
00528
00529 std::ostringstream msg;
00530 msg << "could not parse date/time since I couldn't find a `T' in " << copy;
00531 throw Sct::IoException(msg.str(), __FILE__, __LINE__);
00532 } else {
00533
00534 copy = copy.erase(t,1);
00535 }
00536 return copy;
00537 }
00538
00539 void IOManagerDB::setDataSetName(const std::string& name){
00540 m_dataSetName=name;
00541 }
00542
00543 std::string IOManagerDB::getDataSetName() const{
00544 return m_dataSetName;
00545 }
00546
00547
00548
00549 std::string IOManagerDB::getDataSetID() const{
00550 std::ostringstream select;
00551 select << "SELECT DataSetID FROM tblDataSets WHERE "
00552 << "(DataSetName = '" << getDataSetName() << "')";
00553 return executeQueryReturnID(select.str());
00554 }
00555
00556 std::string IOManagerDB::getTestTypeID(const std::string& testName) const{
00557 std::ostringstream select;
00558 select << "SELECT TestTypeID FROM tblTestTypes WHERE "
00559 << "(TestTypeName = '" << testName << "')";
00560 return executeQueryReturnID(select.str());
00561 }
00562
00563 std::string IOManagerDB::getRunID(const unsigned runNumber) const{
00564 std::ostringstream select;
00565 select << "SELECT RunID FROM tblRuns WHERE "
00566 << "(DataSetID = " << getDataSetID() << ") AND "
00567 << "(RunNr = " << runNumber << ")";
00568 return executeQueryReturnID(select.str());
00569 }
00570
00571 std::string IOManagerDB::getTestID(const std::string& runId,
00572 const unsigned firstScanNumber) const{
00573 std::ostringstream select;
00574 select << "SELECT TestID FROM tblTests WHERE "
00575 << "(RunID = " << runId << ") AND "
00576 << "(FirstScanNr = " << firstScanNumber << ")";
00577 return executeQueryReturnID(select.str());
00578 }
00579
00580 std::string IOManagerDB::getScanID(const std::string& testId,
00581 const unsigned scanNumber) const{
00582 std::ostringstream select;
00583 select << "SELECT ScanID FROM tblScans WHERE "
00584 << "(TestID = " << testId << ") AND "
00585 << "(ScanNr = " << scanNumber << ")";
00586 return executeQueryReturnID(select.str());
00587 }
00588
00589 std::string IOManagerDB::getLayerID(const std::string& layerName) const{
00590 std::ostringstream select;
00591 select << "SELECT LayerID FROM tblLayers WHERE "
00592 << "(LayerName = " << "'" << layerName << "'" << ")";
00593 return executeQueryReturnID(select.str());
00594 }
00595
00596 std::string IOManagerDB::getRowID(const std::string& layerId,
00597 const std::string& LMTnr) const{
00598 std::ostringstream select;
00599 select << "SELECT RowID FROM tblRows WHERE "
00600 << "(LayerID = " << layerId << ") AND "
00601 << "(LMTNr = " << "'" << LMTnr << "'" << ")";
00602 return executeQueryReturnID(select.str());
00603 }
00604
00605 std::string IOManagerDB::getPositionID(const std::string& rowId,
00606 const std::string& positionNumber) const{
00607 std::ostringstream select;
00608 select << "SELECT PositionID FROM tblPositions WHERE "
00609 << "(RowID = " << rowId << ") AND "
00610 << "(PositionNr = " << "'" << positionNumber << "'" << ")";
00611 return executeQueryReturnID(select.str());
00612 }
00613
00614 std::string IOManagerDB::getModuleID(const std::string& moduleNumber) const{
00615 std::ostringstream select;
00616 select << "SELECT ModuleID FROM tblModules WHERE "
00617 << "(ModuleNr = " << "'" << moduleNumber << "'" << ")";
00618 return executeQueryReturnID(select.str());
00619 }
00620
00621
00622
00623 void IOManagerDB::addRun(unsigned long runNumber, bool trash) const{
00624 std::ostringstream select;
00625 select << "INSERT INTO tblRuns \n"
00626 << "(DataSetID, RunNr, Trash) \n"
00627 << "VALUES ( \n"
00628 << getDataSetID() << ", " << runNumber << ", " << trash << ")";
00629
00630 executeQuery(select.str());
00631
00632 if (mysql_affected_rows(m_mysql)!=1){
00633 throw MysqlException("Did NOT add row", select.str(), __FILE__, __LINE__);
00634 }
00635 }
00636
00637 void IOManagerDB::addTest(const TestData& testdata, bool alsoAddScans) const{
00638 std::ostringstream select;
00639 select << "INSERT INTO tblTests \n"
00640 << "(RunID, TestTypeID, FirstScanNr, StartTime, EndTime) \n"
00641 << "VALUES ( \n"
00642 << getRunID(testdata.runNumber) << ", "
00643 << getTestTypeID(testdata.testName) << ", "
00644 << testdata.startScanNumber << ", "
00645 << "'" << convertToMysqlDateTimeFormat(testdata.startTime) << "', "
00646 << "'" << convertToMysqlDateTimeFormat(testdata.endTime) << "')";
00647
00648 executeQuery(select.str());
00649
00650 if (mysql_affected_rows(m_mysql)!=1){
00651 throw MysqlException("Did NOT add row", select.str(), __FILE__, __LINE__);
00652 }
00653 if (alsoAddScans){
00654 for (unsigned iscan=testdata.startScanNumber;
00655 iscan < (testdata.startScanNumber + testdata.nScans);
00656 ++iscan){
00657 addScan(testdata, iscan);
00658 }
00659 }
00660 }
00661
00662 void IOManagerDB::addScan(const TestData& testdata, unsigned scanNumber) const{
00663 std::ostringstream select;
00664 std::string runId = getRunID(testdata.runNumber);
00665 select << "INSERT INTO tblScans \n"
00666 << "(TestID, ScanNr) \n"
00667 << "VALUES ( \n"
00668 << getTestID(runId, testdata.startScanNumber) << ", "
00669 << scanNumber << ")";
00670
00671 executeQuery(select.str());
00672
00673 if (mysql_affected_rows(m_mysql)!=1){
00674 throw MysqlException("Did NOT add row", select.str(), __FILE__, __LINE__);
00675 }
00676 }
00677
00678 void IOManagerDB::addModule(const std::string& layerName,
00679 const std::string& LMTnr,
00680 const std::string& positionNumber,
00681 const std::string& moduleNumber) const{
00682 std::ostringstream select;
00683 std::string layerId = getLayerID(layerName);
00684 std::string rowId = getRowID(layerId, LMTnr);
00685 std::string positionId = getPositionID(rowId, positionNumber);
00686
00687 select << "INSERT INTO tblModules \n"
00688 << "(PositionID, ModuleNr) \n"
00689 << "VALUES (" << positionId << ", "
00690 << "'" << moduleNumber<< "'" << ")";
00691
00692 executeQuery(select.str());
00693
00694 if (mysql_affected_rows(m_mysql)!=1){
00695 throw MysqlException("Did NOT add row", select.str(), __FILE__, __LINE__);
00696 }
00697 }
00698
00699 void IOManagerDB::addRawDataRecord(const std::string& moduleId, const std::string& scanId) const{
00700 std::ostringstream insert;
00701
00702 insert << "INSERT INTO tblRawData \n"
00703 << "(ModuleID, ScanID) \n"
00704 << "VALUES ( \n"
00705 << moduleId << ", "
00706 << scanId << ")";
00707
00708 mysql_query(m_mysql, insert.str().c_str());
00709 checkForMySqlErrors("Cannot execute: ", insert.str(), __FILE__, __LINE__);
00710 if (mysql_affected_rows(m_mysql)!=1){
00711 throw MysqlException("Did NOT add row", insert.str(), __FILE__, __LINE__);
00712 }
00713 }
00714
00715 void IOManagerDB::addRawDataBlob(const std::string& moduleId, const std::string& scanId,
00716 const char *chBuf, const long bufSize) const{
00717
00718
00719
00720
00721
00722
00723
00724
00725 char chMySql[1000000] = "UPDATE tblRawData SET RawDataBlob = '";
00726
00727
00728 char* chTail;
00729 chTail = chMySql + strlen(chMySql);
00730
00731
00732 if ((chTail + 2*bufSize) + 3 > chMySql + sizeof(chMySql)) {
00733 throw MysqlException("Buffer to small for binary data", __FILE__, __LINE__);
00734 }
00735
00736
00737 chTail += mysql_real_escape_string(m_mysql, chTail, chBuf, bufSize);
00738
00739
00740 std::string sqlEnd;
00741 sqlEnd = "' WHERE (ModuleID = " + moduleId + ") AND (" + "ScanID = " + scanId + ")";
00742 (void) strcpy (chTail, sqlEnd.c_str());
00743
00744
00745 mysql_real_query(m_mysql, chMySql, strlen(chMySql));
00746 checkForMySqlErrors("Cannot execute: ", "...(binary data)..." + sqlEnd, __FILE__, __LINE__);
00747
00748
00749
00750 if (mysql_affected_rows(m_mysql) != 1){
00751 throw MysqlException("Did NOT update row", "...(binary data)..." + sqlEnd, __FILE__, __LINE__);
00752 }
00753 }
00754
00755
00756
00757 std::string IOManagerDB::getRawDataBlob(const std::string& moduleId,
00758 const std::string& scanId) const{
00759
00760
00761
00762 MYSQL_RES* rsBin;
00763 MYSQL_ROW rwBin;
00764
00765
00766 string sSQL;
00767 sSQL = "SELECT RawDataBlob FROM tblRawData WHERE (ModuleID = "
00768 + moduleId + ") AND (" + "ScanID = " + scanId + ")";
00769
00770
00771 string sIsNullSQL;
00772 sIsNullSQL = "SELECT (" + sSQL + ") IS NULL";
00773
00774
00775 mysql_real_query(m_mysql, sIsNullSQL.c_str(), strlen(sIsNullSQL.c_str()));
00776 checkForMySqlErrors("Cannot execute: ", sIsNullSQL, __FILE__, __LINE__);
00777
00778
00779 rsBin = mysql_store_result(m_mysql);
00780 checkForMySqlErrors("Can't store the result of query: ", sIsNullSQL, __FILE__, __LINE__);
00781
00782
00783 rwBin = mysql_fetch_row(rsBin);
00784 checkForMySqlErrors("Can't fetch the first row of query: ", sIsNullSQL, __FILE__, __LINE__);
00785
00786
00787 if ((string)rwBin[0] != "0"){
00788 std::cout << "Oops, blob is null in the db. Returning zero-length-string" << std::endl;
00789 return "";
00790 }
00791
00792
00793 mysql_real_query(m_mysql, sSQL.c_str(), strlen(sSQL.c_str()));
00794 checkForMySqlErrors("Cannot execute: ", sSQL, __FILE__, __LINE__);
00795
00796
00797 std::cout << "getRawDataBlob: Binary data read from the MySQL db." << std::endl;
00798
00799
00800 rsBin = mysql_store_result(m_mysql);
00801 checkForMySqlErrors("Can't store the result of query: ", sSQL, __FILE__, __LINE__);
00802
00803
00804 std::cout << "getRawDataBlob: Recordset retrieved successfully." << std::endl;
00805
00806
00807 int iNrOfRows = (int) mysql_num_rows(rsBin);
00808
00809
00810 std::cout << "getRawDataBlob: Number of records in recordset: " << iNrOfRows << std::endl;
00811
00812
00813 rwBin = mysql_fetch_row(rsBin);
00814 checkForMySqlErrors("Can't fetch the first row of query: ", sSQL, __FILE__, __LINE__);
00815
00816
00817
00818 unsigned long *lSize;
00819 lSize = mysql_fetch_lengths(rsBin);
00820 string sBin(rwBin[0], lSize[0]);
00821
00822
00823 std::cout << "getRawDataBlob: Size of blob: " << lSize[0] << endl;
00824
00825
00826 mysql_free_result(rsBin);
00827
00828
00829 return sBin;
00830 }
00831
00832
00833
00834
00835
00836 void IOManagerDB::executeQuery(std::string query) const {
00837 using namespace boost::posix_time;
00838 ptime query_start_time(microsec_clock::local_time());
00839
00840 mysql_query(m_mysql, query.c_str());
00841
00842 {
00843 ptime query_end_time(microsec_clock::local_time());
00844 boost::recursive_mutex::scoped_lock lock(timingAccess);
00845 query_time=query_time+(query_end_time-query_start_time);
00846 m_nQueries++;
00847 }
00848
00849 checkForMySqlErrors("Cannot execute: ", query, __FILE__, __LINE__);
00850
00851 }
00852
00853
00854 std::string IOManagerDB::executeQueryReturnID(std::string query) const{
00855 executeQuery(query);
00856
00857 shared_ptr<MYSQL_RES> result = getResult();
00858
00859 unsigned nmatch = mysql_num_rows(result.get());
00860 if (nmatch != 1){
00861 return "";
00862 }
00863 MYSQL_ROW row = mysql_fetch_row(result.get());
00864 checkForMySqlErrors("Can't fetch the first row of query: ", query, __FILE__, __LINE__);
00865 return row[0];
00866 }
00867
00868 boost::shared_ptr<MYSQL_RES> IOManagerDB::getResult() const{
00869 if (!m_mysql) throw Sct::LogicError("m_mysql not initialised!", __FILE__, __LINE__);
00870
00871 MySqlFreeResultDeleter d;
00872 shared_ptr<MYSQL_RES> result (mysql_store_result(m_mysql), d);
00873 checkForMySqlErrors("Error storing result", __FILE__, __LINE__);
00874 return result;
00875 }
00876
00877 void IOManagerDB::MySqlFreeResultDeleter::operator () (MYSQL_RES* result) throw() {
00878
00879 mysql_free_result(result);
00880
00881 }
00882
00883 }