File indexing completed on 2024-04-06 12:01:27
0001 #include "CondCore/CondDB/interface/IOVEditor.h"
0002 #include "CondCore/CondDB/interface/Auth.h"
0003 #include "CondCore/CondDB/interface/Utils.h"
0004 #include "SessionImpl.h"
0005
0006
0007 namespace cond {
0008
0009 namespace persistency {
0010
0011
0012 class IOVEditorData {
0013 public:
0014 explicit IOVEditorData()
0015 : tag(""),
0016 timeType(cond::invalid),
0017 payloadType(""),
0018 synchronizationType(cond::SYNCH_ANY),
0019 description(""),
0020 iovBuffer(),
0021 deleteBuffer(),
0022 changes() {}
0023 std::string tag;
0024 cond::TimeType timeType;
0025 std::string payloadType;
0026 cond::SynchronizationType synchronizationType;
0027 std::string description;
0028 cond::Time_t endOfValidity = cond::time::MAX_VAL;
0029 cond::Time_t lastValidatedTime = cond::time::MIN_VAL;
0030 boost::posix_time::ptime creationTime;
0031 bool change = false;
0032 bool metadataChange = false;
0033 bool exists = false;
0034
0035 std::vector<std::tuple<cond::Time_t, cond::Hash, boost::posix_time::ptime> > iovBuffer;
0036 std::vector<std::tuple<cond::Time_t, cond::Hash> > deleteBuffer;
0037 std::set<std::string> changes;
0038 int protectionCode = 0;
0039 };
0040
0041 IOVEditor::IOVEditor() : m_data(), m_session() {}
0042
0043 IOVEditor::IOVEditor(const std::shared_ptr<SessionImpl>& session) : m_data(new IOVEditorData), m_session(session) {}
0044
0045 IOVEditor::IOVEditor(const std::shared_ptr<SessionImpl>& session,
0046 const std::string& tag,
0047 cond::TimeType timeType,
0048 const std::string& payloadObjectType,
0049 cond::SynchronizationType synchronizationType,
0050 const boost::posix_time::ptime& creationTime)
0051 : m_data(new IOVEditorData), m_session(session) {
0052 m_data->tag = tag;
0053 m_data->timeType = timeType;
0054 m_data->payloadType = payloadObjectType;
0055 m_data->synchronizationType = synchronizationType;
0056 m_data->creationTime = creationTime;
0057 m_data->change = true;
0058 m_data->metadataChange = true;
0059 }
0060
0061 IOVEditor::IOVEditor(const IOVEditor& rhs) : m_data(rhs.m_data), m_session(rhs.m_session) {}
0062
0063 IOVEditor::~IOVEditor() {}
0064
0065 IOVEditor& IOVEditor::operator=(const IOVEditor& rhs) {
0066 m_data = rhs.m_data;
0067 m_session = rhs.m_session;
0068 return *this;
0069 }
0070
0071 void IOVEditor::load(const std::string& tag) {
0072 checkTransaction("IOVEditor::load");
0073
0074 if (!m_session->iovSchema().tagTable().select(tag,
0075 m_data->timeType,
0076 m_data->payloadType,
0077 m_data->synchronizationType,
0078 m_data->endOfValidity,
0079 m_data->lastValidatedTime,
0080 m_data->protectionCode)) {
0081 cond::throwException("Tag \"" + tag + "\" has not been found in the database.", "IOVEditor::load");
0082 }
0083 if (m_data->protectionCode) {
0084 if (m_data->protectionCode & cond::auth::COND_DBTAG_WRITE_ACCESS_CODE) {
0085 bool writeAllowed = m_session->iovSchema().tagAccessPermissionTable().getAccessPermission(
0086 tag,
0087 m_session->principalName,
0088 cond::auth::COND_DBKEY_CREDENTIAL_CODE,
0089 cond::auth::COND_DBTAG_WRITE_ACCESS_CODE);
0090 if (!writeAllowed)
0091 cond::throwException(
0092 "Tag \"" + tag + "\" can't be accessed for update by db-user \"" + m_session->principalName + "\".",
0093 "IOVEditor::load");
0094 }
0095 if (m_data->protectionCode & cond::auth::COND_DBTAG_LOCK_ACCESS_CODE) {
0096 bool mylock = m_session->iovSchema().tagAccessPermissionTable().getAccessPermission(
0097 tag, m_session->sessionHash, cond::auth::COND_SESSION_HASH_CODE, cond::auth::COND_DBTAG_LOCK_ACCESS_CODE);
0098 if (!mylock)
0099 cond::throwException(
0100 "Tag \"" + tag + "\" can't be accessed for update, because it has been locked by an other session.",
0101 "IOVEditor::load");
0102 }
0103 }
0104 m_data->tag = tag;
0105 m_data->exists = true;
0106 m_data->change = false;
0107 }
0108
0109 std::string IOVEditor::tag() const { return m_data.get() ? m_data->tag : ""; }
0110
0111 cond::TimeType IOVEditor::timeType() const { return m_data.get() ? m_data->timeType : cond::invalid; }
0112
0113 std::string IOVEditor::payloadType() const { return m_data.get() ? m_data->payloadType : ""; }
0114
0115 cond::SynchronizationType IOVEditor::synchronizationType() const {
0116 return m_data.get() ? m_data->synchronizationType : cond::SYNCH_ANY;
0117 }
0118
0119 void IOVEditor::setSynchronizationType(cond::SynchronizationType synchronizationType) {
0120 if (m_data.get()) {
0121 m_data->synchronizationType = synchronizationType;
0122 m_data->change = true;
0123 m_data->changes.insert("SynchronizationType");
0124 }
0125 }
0126
0127 cond::Time_t IOVEditor::endOfValidity() const { return m_data.get() ? m_data->endOfValidity : cond::time::MIN_VAL; }
0128
0129 void IOVEditor::setEndOfValidity(cond::Time_t time) {
0130 if (m_data.get()) {
0131 m_data->endOfValidity = time;
0132 m_data->change = true;
0133 m_data->changes.insert("EndOfValidity");
0134 }
0135 }
0136
0137 std::string IOVEditor::description() const { return m_data.get() ? m_data->description : ""; }
0138
0139 void IOVEditor::setDescription(const std::string& description) {
0140 if (m_data.get()) {
0141 m_data->description = description;
0142 m_data->metadataChange = true;
0143 m_data->changes.insert("Description");
0144 }
0145 }
0146
0147 cond::Time_t IOVEditor::lastValidatedTime() const {
0148 return m_data.get() ? m_data->lastValidatedTime : cond::time::MIN_VAL;
0149 }
0150
0151 void IOVEditor::setLastValidatedTime(cond::Time_t time) {
0152 if (m_data.get()) {
0153 m_data->lastValidatedTime = time;
0154 m_data->change = true;
0155 m_data->changes.insert("LastValidatedTime");
0156 }
0157 }
0158
0159 void IOVEditor::insert(cond::Time_t since, const cond::Hash& payloadHash, bool checkType) {
0160 boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
0161 insert(since, payloadHash, now, checkType);
0162 }
0163
0164 void IOVEditor::insert(cond::Time_t since,
0165 const cond::Hash& payloadHash,
0166 const boost::posix_time::ptime& insertionTime,
0167 bool) {
0168 if (m_data.get()) {
0169
0170 m_data->iovBuffer.push_back(std::tie(since, payloadHash, insertionTime));
0171 }
0172 }
0173
0174 void IOVEditor::erase(cond::Time_t since, const cond::Hash& payloadHash) {
0175 if (m_data.get()) {
0176 m_data->deleteBuffer.push_back(std::tie(since, payloadHash));
0177 }
0178 }
0179
0180 bool iovSorter(const std::tuple<cond::Time_t, cond::Hash, boost::posix_time::ptime>& f,
0181 const std::tuple<cond::Time_t, cond::Hash, boost::posix_time::ptime>& s) {
0182 return std::get<0>(f) < std::get<0>(s);
0183 }
0184
0185 bool IOVEditor::flush(const std::string& logText,
0186 const boost::posix_time::ptime& operationTime,
0187 bool forceInsertion) {
0188 bool ret = false;
0189 checkTransaction("IOVEditor::flush");
0190 std::string lt = logText;
0191 if (lt.empty())
0192 lt = "-";
0193 if (m_data->change || m_data->metadataChange) {
0194 if (m_data->metadataChange && m_data->description.empty())
0195 throwException("A non-empty description string is mandatory.", "IOVEditor::flush");
0196
0197
0198 if (!m_data->exists) {
0199
0200 if (m_data->creationTime.is_not_a_date_time())
0201 m_data->creationTime = operationTime;
0202 m_session->iovSchema().tagTable().insert(m_data->tag,
0203 m_data->timeType,
0204 m_data->payloadType,
0205 m_data->synchronizationType,
0206 m_data->endOfValidity,
0207 m_data->description,
0208 m_data->lastValidatedTime,
0209 m_data->creationTime);
0210 if (m_session->iovSchema().tagLogTable().exists())
0211 m_session->iovSchema().tagLogTable().insert(m_data->tag,
0212 m_data->creationTime,
0213 cond::getUserName(),
0214 cond::getHostName(),
0215 cond::getCommand(),
0216 std::string("New tag created."),
0217 lt);
0218 m_data->exists = true;
0219 ret = true;
0220 } else {
0221 if (m_data->change) {
0222 m_session->iovSchema().tagTable().update(m_data->tag,
0223 m_data->synchronizationType,
0224 m_data->endOfValidity,
0225 m_data->lastValidatedTime,
0226 operationTime);
0227 }
0228 if (m_data->metadataChange) {
0229 m_session->iovSchema().tagTable().updateMetadata(m_data->tag, m_data->description, operationTime);
0230 }
0231 if (m_session->iovSchema().tagLogTable().exists()) {
0232 std::string action("Tag header updated. Changes involve: ");
0233 size_t i = 0;
0234 for (const auto& c : m_data->changes) {
0235 action += c;
0236 if (i == (m_data->changes.size() - 1))
0237 action += ".";
0238 else
0239 action += ", ";
0240 i++;
0241 }
0242 m_session->iovSchema().tagLogTable().insert(
0243 m_data->tag, operationTime, cond::getUserName(), cond::getHostName(), cond::getCommand(), action, lt);
0244 }
0245 ret = true;
0246 }
0247 m_data->change = false;
0248 }
0249 if (!m_data->iovBuffer.empty()) {
0250 std::sort(m_data->iovBuffer.begin(), m_data->iovBuffer.end(), iovSorter);
0251 cond::Time_t l = std::get<0>(m_data->iovBuffer.front());
0252
0253
0254
0255
0256 if (!forceInsertion && m_data->synchronizationType != cond::SYNCH_ANY &&
0257 m_data->synchronizationType != cond::SYNCH_VALIDATION) {
0258
0259 cond::Time_t last = 0;
0260 cond::Hash h;
0261 boost::posix_time::ptime no_time;
0262 m_session->iovSchema().iovTable().getLastIov(m_data->tag, no_time, last, h);
0263
0264 if (l <= last) {
0265 std::stringstream msg;
0266 msg << "Can't insert iov since " << l << " on the tag " << m_data->tag << ": last since is " << last
0267 << " and synchronization is \"" << cond::synchronizationTypeNames(m_data->synchronizationType) << "\"";
0268 throwException(msg.str(), "IOVEditor::flush");
0269 }
0270 }
0271
0272 for (auto& iov : m_data->iovBuffer) {
0273 boost::posix_time::ptime& insertionTime = std::get<2>(iov);
0274 if (insertionTime.is_not_a_date_time())
0275 insertionTime = operationTime;
0276 }
0277
0278 m_session->iovSchema().iovTable().insertMany(m_data->tag, m_data->iovBuffer);
0279 ret = true;
0280 }
0281 if (!m_data->deleteBuffer.empty()) {
0282
0283 m_session->iovSchema().iovTable().eraseMany(m_data->tag, m_data->deleteBuffer);
0284 ret = true;
0285 }
0286 if (m_session->iovSchema().tagLogTable().exists()) {
0287 std::stringstream msg;
0288 if (!m_data->iovBuffer.empty())
0289 msg << m_data->iovBuffer.size() << " iov(s) inserted";
0290 if (!msg.str().empty())
0291 msg << "; ";
0292 else
0293 msg << ".";
0294 if (!m_data->deleteBuffer.empty())
0295 msg << m_data->deleteBuffer.size() << " iov(s) deleted.";
0296 if (ret) {
0297 m_session->iovSchema().tagLogTable().insert(
0298 m_data->tag, operationTime, cond::getUserName(), cond::getHostName(), cond::getCommand(), msg.str(), lt);
0299 }
0300 }
0301 m_data->iovBuffer.clear();
0302 m_data->deleteBuffer.clear();
0303 m_data->changes.clear();
0304 return ret;
0305 }
0306
0307 bool IOVEditor::flush(const std::string& logText) {
0308 return flush(logText, boost::posix_time::microsec_clock::universal_time(), false);
0309 }
0310
0311 bool IOVEditor::flush(const boost::posix_time::ptime& operationTime) {
0312 return flush(std::string("-"), operationTime, false);
0313 }
0314
0315 bool IOVEditor::flush() {
0316 return flush(std::string("-"), boost::posix_time::microsec_clock::universal_time(), false);
0317 }
0318
0319 bool IOVEditor::flush(const std::string& logText, bool forceInsertion) {
0320 return flush(logText, boost::posix_time::microsec_clock::universal_time(), forceInsertion);
0321 }
0322
0323 bool IOVEditor::isLocked() const { return m_data->protectionCode & cond::auth::COND_DBTAG_LOCK_ACCESS_CODE; }
0324
0325 void IOVEditor::lock() {
0326 if (isLocked())
0327 return;
0328 checkTransaction("IOVEditor::lock");
0329 m_session->iovSchema().tagAccessPermissionTable().setAccessPermission(m_data->tag,
0330 m_session->sessionHash,
0331 cond::auth::COND_SESSION_HASH_CODE,
0332 cond::auth::COND_DBTAG_LOCK_ACCESS_CODE);
0333 m_data->protectionCode |= cond::auth::COND_DBTAG_LOCK_ACCESS_CODE;
0334 m_session->iovSchema().tagTable().setProtectionCode(m_data->tag, cond::auth::COND_DBTAG_LOCK_ACCESS_CODE);
0335 m_session->lockedTags.insert(m_data->tag);
0336 std::string lt("-");
0337 std::string action("Lock set by session ");
0338 action += m_session->sessionHash;
0339 m_session->iovSchema().tagLogTable().insert(m_data->tag,
0340 boost::posix_time::microsec_clock::universal_time(),
0341 cond::getUserName(),
0342 cond::getHostName(),
0343 cond::getCommand(),
0344 action,
0345 lt);
0346 }
0347
0348 void IOVEditor::unlock() {
0349 if (!isLocked())
0350 return;
0351 checkTransaction("IOVEditor::unlock");
0352 m_session->iovSchema().tagAccessPermissionTable().removeAccessPermission(
0353 m_data->tag, m_session->sessionHash, cond::auth::COND_SESSION_HASH_CODE);
0354 m_data->protectionCode &= cond::auth::COND_DBTAG_WRITE_ACCESS_CODE;
0355 m_session->iovSchema().tagTable().unsetProtectionCode(m_data->tag, cond::auth::COND_DBTAG_LOCK_ACCESS_CODE);
0356 m_session->lockedTags.erase(m_data->tag);
0357 std::string lt("-");
0358 std::string action("Lock released by session ");
0359 action += m_session->sessionHash;
0360 m_session->iovSchema().tagLogTable().insert(m_data->tag,
0361 boost::posix_time::microsec_clock::universal_time(),
0362 cond::getUserName(),
0363 cond::getHostName(),
0364 cond::getCommand(),
0365 action,
0366 lt);
0367 }
0368
0369 void IOVEditor::checkTransaction(const std::string& ctx) {
0370 if (!m_session.get())
0371 throwException("The session is not active.", ctx);
0372 if (!m_session->isTransactionActive(false))
0373 throwException("The transaction is not active.", ctx);
0374 }
0375
0376 }
0377 }