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
00014 #include <sqlplus.hh>
00015 #include <custom.hh>
00016 #include <sstream>
00017 #include <boost/date_time/posix_time/posix_time.hpp>
00018
00019 using std::string;
00020 using std::ostringstream;
00021 using boost::posix_time::to_simple_string;
00022 using boost::shared_ptr;
00023 using namespace Sct;
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 namespace SctArchiving {
00035
00036 IOManagerDB::IOManagerDB() {
00037 m_compressor = shared_ptr<ZlibStringCompressor>(new ZlibStringCompressor());
00038 m_connection = shared_ptr<Connection>(new Connection("test_db") );
00039 }
00040
00041 IOManagerDB::~IOManagerDB() {
00042 }
00043
00044 IOManagerDB* IOManagerDB::s_man=0;
00045
00046 IOManagerDB& IOManagerDB::instance() {
00047 if (!s_man) s_man=new IOManagerDB();
00048 return *s_man;
00049 }
00050
00051 std::string IOManagerDB::status() const {
00052 std::ostringstream oss;
00053 oss << "IOManagerDB";
00054 if (m_compressor.get()){
00055 oss << "String compressor buffer size : "
00056 << m_compressor->getBufferSize() << std::endl;
00057 } else {
00058 oss << "String compressor not initialized" << endl;
00059 }
00060 return oss.str();
00061 }
00062
00063 Query IOManagerDB::getQuery() const{
00064 return m_connection->query();
00065 }
00066
00067
00068 const SctData::ResultHeader& IOManagerDB::getHeader(const Serializable& ob){
00069 const SctData::ResultHeader* header=0;
00070 if (ob.getClassName().find("TestResult")!=string::npos) {
00071 header = & dynamic_cast<const SctData::TestResult&>(ob).getHeader();
00072 }
00073 if (ob.getClassName().find("ScanResult")!=string::npos) {
00074 header = & dynamic_cast<const SctData::ScanResult&>(ob).getHeader();
00075 }
00076 if (header) {
00077 return *header;
00078 } else {
00079 ostringstream oss;
00080 oss << "Dont know how to find a header for object with class name : "
00081 << ob.getClassName() << " which has UniqueID : "
00082 << (string) ob.getUniqueID();
00083 throw IoException(oss.str(), __FILE__, __LINE__);
00084 }
00085 }
00086
00087 void IOManagerDB::prepareInsertion(const Serializable& ob, MysqlQuery& query) const{
00088 const SctData::ResultHeader& header = getHeader(ob);
00089 SctData::UniqueID id(header.getUniqueID());
00090
00091 ostringstream oss;
00092 XmlStyleOStream out_ad(oss);
00093 writeImpl(out_ad, ob, false);
00094
00095 query << string("INSERT INTO ") << getTable(ob) << string(" VALUES ('")
00096 << ob.getClassName() << string("','")
00097 << id.getRunNumber() << string("','")
00098 << id.getScanNumber() << string("','")
00099 << id.getModule() << string("','")
00100 << to_simple_string(header.getStartTime()) << string("','")
00101 << to_simple_string(header.getEndTime()) << string("','")
00102 << m_compressor->compress(oss.str(), getCompressionLevel()) << string("')");
00103 }
00104
00105 string IOManagerDB::getTable(const Serializable& ob){
00106 return "data";
00107 }
00108
00109 void IOManagerDB::write(const Serializable& ob, const IOParams* par) const {
00110 try{
00111 boost::recursive_mutex::scoped_lock lock (getMutex());
00112 setReadMode(false);
00113
00114 MysqlQuery query = getQuery();
00115 prepareInsertion(ob, query);
00116 query.execute();
00117
00118
00119 }catch(BadQuery& er){
00120 ostringstream oss;
00121 oss << "Bad Query error number : " << er.error;
00122 throw MySqlException(oss.str(), __FILE__, __LINE__);
00123 }catch (BadConversion& er) {
00124 ostringstream oss;
00125 oss << "Tried to convert \"" << er.data << "\" to a \""
00126 << er.type_name << "\"." << endl;
00127 throw MySqlException(oss.str(), __FILE__, __LINE__);
00128 }catch (Sct::Throwable& e){
00129 throw;
00130 }catch(std::exception& e){
00131 StdExceptionWrapper sew(e);
00132 throw IoException(sew, __FILE__, __LINE__);
00133 }
00134 }
00135
00136 string getQueryMatching(const string& name){
00137 Archive::IONameArchiveFile ioname(name);
00138 SctData::UniqueID id(ioname.getUniqueID());
00139 ostringstream oss;
00140 oss << " WHERE className = " << ioname.getClassName()
00141 << " AND runNumber = " << id.getRunNumber()
00142 << " AND scanNumber = " << id.getScanNumber()
00143 << " AND moduleName = " << id.getModule();
00144 return oss.str();
00145 }
00146
00147 boost::shared_ptr<Serializable> IOManagerDB::read(const string& name, const IOParams* par) const {
00148 try{
00149 boost::recursive_mutex::scoped_lock lock (getMutex());
00150 setReadMode(true);
00151 getReadVersionMap().clear();
00152 MysqlQuery query = getQuery();
00153 query << string("SELECT dataBlob FROM DATA ") << getQueryMatching(name);
00154 Row row = query.use().fetch_row();
00155
00156 const string compressed (row[0]);
00157 std::istringstream iss(m_compressor->inflate(compressed));
00158 XmlStyleIStream in_ad(iss);
00159
00160 return boost::dynamic_pointer_cast<Serializable>(readImpl(in_ad));
00161
00162
00163 }catch(BadQuery& er){
00164 ostringstream oss;
00165 oss << "Bad Query error number : " << er.error;
00166 throw MySqlException(oss.str(), __FILE__, __LINE__);
00167 }catch (BadConversion& er) {
00168 ostringstream oss;
00169 oss << "Tried to convert \"" << er.data << "\" to a \""
00170 << er.type_name << "\"." << endl;
00171 throw MySqlException(oss.str(), __FILE__, __LINE__);
00172 }catch (Sct::Throwable& e) {
00173 throw;
00174 }catch(std::exception& e){
00175 StdExceptionWrapper sew(e);
00176 throw IoException(sew, __FILE__, __LINE__);
00177 }
00178 }
00179 }