File indexing completed on 2024-04-06 12:23:06
0001 #include "OnlineDB/EcalCondDB/interface/LMFUnique.h"
0002 #include <iomanip>
0003
0004 using namespace std;
0005 using namespace oracle::occi;
0006
0007 LMFUnique::~LMFUnique() {}
0008
0009 std::string LMFUnique::sequencePostfix(const Tm& t) {
0010 std::string ts = t.str();
0011 return ts.substr(2, 2);
0012 }
0013
0014 LMFUnique& LMFUnique::setString(std::string key, std::string value) {
0015
0016 std::map<std::string, std::string>::const_iterator i = m_stringFields.find(key);
0017 if (i != m_stringFields.end()) {
0018
0019 if (i->second != value) {
0020 m_stringFields[key] = value;
0021 m_ID = 0;
0022 }
0023 } else {
0024
0025 m_stringFields[key] = value;
0026 m_ID = 0;
0027 }
0028 return *this;
0029 }
0030
0031 LMFUnique& LMFUnique::setInt(std::string key, int value) {
0032
0033 std::map<std::string, int>::const_iterator i = m_intFields.find(key);
0034 if (i != m_intFields.end()) {
0035
0036 if (i->second != value) {
0037 m_intFields[key] = value;
0038 m_ID = 0;
0039 }
0040 } else {
0041
0042 m_intFields[key] = value;
0043 m_ID = 0;
0044 }
0045 return *this;
0046 }
0047
0048 void LMFUnique::attach(std::string name, LMFUnique* u) {
0049 std::map<std::string, LMFUnique*>::const_iterator i = m_foreignKeys.find(name);
0050 if (i != m_foreignKeys.end()) {
0051 if (i->second != u) {
0052 m_foreignKeys[name] = u;
0053 m_ID = 0;
0054 }
0055 } else {
0056 m_foreignKeys[name] = u;
0057 m_ID = 0;
0058 }
0059 }
0060
0061 std::list<std::unique_ptr<LMFUnique>> LMFUnique::fetchAll() const noexcept(false) {
0062
0063
0064
0065 std::list<std::unique_ptr<LMFUnique>> l;
0066 this->checkConnection();
0067
0068 try {
0069 Statement* stmt = m_conn->createStatement();
0070 std::string sql = fetchAllSql(stmt);
0071 if (!sql.empty()) {
0072 if (m_debug) {
0073 cout << m_className + ": Query " + sql << endl;
0074 }
0075 ResultSet* rset = stmt->executeQuery();
0076 while (rset->next() != 0) {
0077 LMFUnique* o = createObject();
0078 if (m_debug) {
0079 o->debug();
0080 }
0081 if (o != nullptr) {
0082 o->setByID(rset->getInt(1));
0083 if (m_debug) {
0084 o->dump();
0085 }
0086 try {
0087 l.emplace_back(o);
0088 } catch (std::exception& e) {
0089 throw(std::runtime_error(m_className + "::fetchAll: " + e.what()));
0090 }
0091 }
0092 }
0093 }
0094 m_conn->terminateStatement(stmt);
0095 } catch (SQLException& e) {
0096 throw(std::runtime_error(m_className + "::fetchAll: " + e.getMessage()));
0097 }
0098 if (m_debug) {
0099 cout << m_className << ": list size = " << l.size() << endl;
0100 }
0101 return l;
0102 }
0103
0104 void LMFUnique::dump() const { dump(0); }
0105
0106 void LMFUnique::dump(int n) const {
0107
0108
0109
0110
0111 std::string m_indent = "";
0112 std::string m_trail = "";
0113 m_trail.resize(70 - 31 - n * 2, '#');
0114 m_indent.resize(n * 2, ' ');
0115 m_indent += "|";
0116
0117 cout << m_indent << "#################" << setw(15) << m_className << " " << m_trail << endl;
0118 cout << m_indent << "Address: " << this << endl;
0119 cout << m_indent << "Connection params : " << m_env << ", " << m_conn << endl;
0120
0121 cout << m_indent << "ID" << setw(18) << ": " << m_ID;
0122 if (m_ID == 0) {
0123 cout << " *** NULL ID ***";
0124 }
0125 if (!isValid()) {
0126 cout << " INVALID ***";
0127 }
0128 cout << endl;
0129
0130 std::map<std::string, std::string>::const_iterator is = m_stringFields.begin();
0131 std::map<std::string, std::string>::const_iterator es = m_stringFields.end();
0132 while (is != es) {
0133 std::string key = is->first;
0134 cout << m_indent << key << setw(20 - key.length()) << ": " << is->second << endl;
0135 is++;
0136 }
0137
0138 std::map<std::string, int>::const_iterator ii = m_intFields.begin();
0139 std::map<std::string, int>::const_iterator ei = m_intFields.end();
0140 while (ii != ei) {
0141 std::string key = ii->first;
0142 cout << m_indent << key << setw(20 - key.length()) << ": " << ii->second << endl;
0143 ii++;
0144 }
0145 cout << m_indent << "#################" << setw(15) << m_className << " " << m_trail << endl;
0146
0147 std::map<std::string, LMFUnique*>::const_iterator ik = m_foreignKeys.begin();
0148 std::map<std::string, LMFUnique*>::const_iterator ek = m_foreignKeys.end();
0149 m_indent.clear();
0150 m_indent.resize((n + 1) * 2, ' ');
0151 while (ik != ek) {
0152 cout << m_indent << "Foreign Key: " << ik->first << endl;
0153 ik->second->dump(n + 1);
0154 ik++;
0155 }
0156 }
0157
0158 bool LMFUnique::exists() {
0159 fetchID();
0160 bool ret = false;
0161 if (m_ID > 0) {
0162 ret = true;
0163 }
0164 return ret;
0165 }
0166
0167 std::string LMFUnique::fetchAllSql(Statement* stmt) const {
0168
0169
0170 return "";
0171 }
0172
0173 LMFUnique* LMFUnique::createObject() const {
0174
0175 return nullptr;
0176 }
0177
0178 std::string LMFUnique::getString(std::string s) const {
0179 std::string rs = "";
0180 std::map<std::string, std::string>::const_iterator i = m_stringFields.find(s);
0181 if (i != m_stringFields.end()) {
0182 rs = i->second;
0183 }
0184 return rs;
0185 }
0186
0187 int LMFUnique::getInt(std::string s) const {
0188
0189 int ret = 0;
0190 std::map<std::string, int>::const_iterator i = m_intFields.find(s);
0191 if (i != m_intFields.end()) {
0192 ret = i->second;
0193 }
0194 return ret;
0195 }
0196
0197 int LMFUnique::fetchID() noexcept(false) {
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210 if (m_ID) {
0211 return m_ID;
0212 }
0213
0214 this->checkConnection();
0215
0216
0217 try {
0218 Statement* stmt = m_conn->createStatement();
0219
0220 std::string sql = fetchIdSql(stmt);
0221 if (!sql.empty()) {
0222 if (m_debug) {
0223 cout << m_className + ": Query " + sql << endl;
0224 }
0225
0226 ResultSet* rset = stmt->executeQuery();
0227 if (rset->next() != 0) {
0228 m_ID = rset->getInt(1);
0229 } else {
0230 m_ID = 0;
0231 }
0232 if (m_debug) {
0233 cout << m_className + ": ID set to " << m_ID << endl;
0234 }
0235 int n = rset->getNumArrayRows();
0236 if (m_debug) {
0237 cout << m_className + ": Returned " << n << " rows" << endl;
0238 }
0239 if (n > 1) {
0240 throw(std::runtime_error(m_className + "::fetchID: too many rows returned " + "executing query " + sql));
0241 m_ID = 0;
0242 }
0243 }
0244 m_conn->terminateStatement(stmt);
0245 } catch (SQLException& e) {
0246 throw(std::runtime_error(m_className + "::fetchID: " + e.getMessage()));
0247 }
0248
0249 if (m_ID > 0) {
0250 setByID(m_ID);
0251 }
0252
0253 map<string, LMFUnique*>::iterator i = m_foreignKeys.begin();
0254 map<string, LMFUnique*>::iterator e = m_foreignKeys.end();
0255 while (i != e) {
0256 if (i->second->getID() == 0) {
0257 i->second->fetchID();
0258 }
0259 i++;
0260 }
0261 if (m_debug) {
0262 cout << m_className << ": fetchID:: returning " << m_ID << endl;
0263 }
0264 return m_ID;
0265 }
0266
0267 void LMFUnique::setByID(int id) noexcept(false) {
0268
0269
0270
0271 if (m_debug) {
0272 cout << m_className << ": Setting this object as ID = " << id << endl;
0273 }
0274 this->checkConnection();
0275 try {
0276 Statement* stmt = m_conn->createStatement();
0277 std::string sql = setByIDSql(stmt, id);
0278 if (sql.empty()) {
0279 throw(std::runtime_error(m_className + "::setByID: [empty sql])"));
0280 }
0281 if (m_debug) {
0282 cout << m_className + ": " + sql << endl;
0283 }
0284
0285 ResultSet* rset = stmt->executeQuery();
0286 if (rset->next() != 0) {
0287
0288 getParameters(rset);
0289 m_ID = id;
0290 if (m_debug) {
0291 cout << m_className + ": Setting done. ID set to " << m_ID << endl;
0292 }
0293 } else {
0294 throw(std::runtime_error(m_className + "::setByID: Given id is not in the database"));
0295 }
0296 m_conn->terminateStatement(stmt);
0297 } catch (SQLException& e) {
0298 throw(std::runtime_error(m_className + "::setByID: " + e.getMessage()));
0299 }
0300 }
0301
0302 int LMFUnique::writeForeignKeys() noexcept(false) {
0303 std::map<std::string, LMFUnique*>::const_iterator i = m_foreignKeys.begin();
0304 std::map<std::string, LMFUnique*>::const_iterator e = m_foreignKeys.end();
0305 int count = 0;
0306 while (i != e) {
0307 if (i->second->getID() == 0) {
0308 i->second->writeDB();
0309 count++;
0310 }
0311 i++;
0312 }
0313 return count;
0314 }
0315
0316 int LMFUnique::writeDB() noexcept(false) {
0317 clock_t start = 0;
0318 clock_t end = 0;
0319 if (_profiling) {
0320 start = clock();
0321 }
0322
0323 writeForeignKeys();
0324
0325 if (!(this->fetchID())) {
0326
0327 this->checkConnection();
0328
0329
0330 std::string sql = "";
0331 try {
0332 Statement* stmt = m_conn->createStatement();
0333
0334 sql = writeDBSql(stmt);
0335 if (!sql.empty()) {
0336 if (m_debug) {
0337 cout << m_className + ": " + sql << endl;
0338 }
0339 stmt->executeUpdate();
0340 }
0341 m_conn->commit();
0342 m_conn->terminateStatement(stmt);
0343 } catch (SQLException& e) {
0344 debug();
0345 dump();
0346 throw(std::runtime_error(m_className + "::writeDB: " + e.getMessage() + " while executing query " + sql));
0347 }
0348
0349 if (this->fetchID() == 0) {
0350 throw(std::runtime_error(m_className + "::writeDB: Failed to write"));
0351 }
0352 }
0353 if (_profiling) {
0354 end = clock();
0355 if (m_debug) {
0356 std::cout << m_className << ":: Spent time in writeDB:" << ((double)(end - start)) / CLOCKS_PER_SEC << " s"
0357 << endl;
0358 }
0359 }
0360 return m_ID;
0361 }