Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:01:28

0001 #include "CondCore/CondDB/interface/Exception.h"
0002 #include "CondCore/CondDB/interface/Auth.h"
0003 #include "CondCore/CondDB/interface/DecodingKey.h"
0004 #include "SessionImpl.h"
0005 
0006 #include <memory>
0007 
0008 #include "DbConnectionString.h"
0009 //
0010 //
0011 #include "RelationalAccess/ISessionProxy.h"
0012 #include "RelationalAccess/ITransaction.h"
0013 
0014 namespace cond {
0015 
0016   namespace persistency {
0017 
0018     class CondDBTransaction : public ITransaction {
0019     public:
0020       CondDBTransaction(const std::shared_ptr<coral::ISessionProxy>& coralSession) : m_session(coralSession) {}
0021       ~CondDBTransaction() override {}
0022 
0023       void commit() override { m_session->transaction().commit(); }
0024 
0025       void rollback() override { m_session->transaction().rollback(); }
0026 
0027       bool isActive() override { return m_session->transaction().isActive(); }
0028 
0029     private:
0030       std::shared_ptr<coral::ISessionProxy> m_session;
0031     };
0032 
0033     SessionImpl::SessionImpl() : coralSession() {}
0034 
0035     SessionImpl::SessionImpl(std::shared_ptr<coral::ISessionProxy>& session,
0036                              const std::string& connectionStr,
0037                              const std::string& principalNm)
0038         : coralSession(session), sessionHash(""), connectionString(connectionStr), principalName(principalNm) {
0039       cond::auth::KeyGenerator kg;
0040       sessionHash = kg.make(cond::auth::COND_SESSION_HASH_SIZE);
0041     }
0042 
0043     SessionImpl::~SessionImpl() { close(); }
0044 
0045     void SessionImpl::close() {
0046       if (isActive()) {
0047         if (coralSession->transaction().isActive()) {
0048           rollbackTransaction();
0049         }
0050         if (!lockedTags.empty()) {
0051           startTransaction(false);
0052           releaseTagLocks();
0053           commitTransaction();
0054         }
0055         coralSession.reset();
0056       }
0057       transaction.reset();
0058     }
0059 
0060     bool SessionImpl::isActive() const { return coralSession.get(); }
0061 
0062     void SessionImpl::startTransaction(bool readOnly) {
0063       std::unique_lock<std::recursive_mutex> lock(transactionMutex);
0064       if (!transaction.get()) {
0065         coralSession->transaction().start(readOnly);
0066         iovSchemaHandle = std::make_unique<IOVSchema>(coralSession->nominalSchema());
0067         gtSchemaHandle = std::make_unique<GTSchema>(coralSession->nominalSchema());
0068         runInfoSchemaHandle = std::make_unique<RunInfoSchema>(coralSession->nominalSchema());
0069         transaction = std::make_unique<CondDBTransaction>(coralSession);
0070       } else {
0071         if (!readOnly)
0072           throwException("An update transaction is already active.", "SessionImpl::startTransaction");
0073       }
0074       transaction->clients++;
0075       transactionLock.swap(lock);
0076     }
0077 
0078     void SessionImpl::commitTransaction() {
0079       std::unique_lock<std::recursive_mutex> lock;
0080       lock.swap(transactionLock);
0081       if (transaction) {
0082         transaction->clients--;
0083         if (!transaction->clients) {
0084           transaction->commit();
0085           transaction.reset();
0086           iovSchemaHandle.reset();
0087           gtSchemaHandle.reset();
0088           runInfoSchemaHandle.reset();
0089         }
0090       }
0091     }
0092 
0093     void SessionImpl::rollbackTransaction() {
0094       std::unique_lock<std::recursive_mutex> lock;
0095       lock.swap(transactionLock);
0096       if (transaction) {
0097         transaction->rollback();
0098         transaction.reset();
0099         iovSchemaHandle.reset();
0100         gtSchemaHandle.reset();
0101         runInfoSchemaHandle.reset();
0102       }
0103     }
0104 
0105     bool SessionImpl::isTransactionActive(bool deep) const {
0106       if (!transaction)
0107         return false;
0108       if (!deep)
0109         return true;
0110       return transaction->isActive();
0111     }
0112 
0113     void SessionImpl::releaseTagLocks() {
0114       iovSchema().tagAccessPermissionTable().removeEntriesForCredential(sessionHash,
0115                                                                         cond::auth::COND_SESSION_HASH_CODE);
0116       std::string lt("-");
0117       std::string action("Lock removed by session ");
0118       action += sessionHash;
0119       for (const auto& tag : lockedTags) {
0120         iovSchema().tagTable().unsetProtectionCode(tag, cond::auth::COND_DBTAG_LOCK_ACCESS_CODE);
0121         iovSchema().tagLogTable().insert(tag,
0122                                          boost::posix_time::microsec_clock::universal_time(),
0123                                          cond::getUserName(),
0124                                          cond::getHostName(),
0125                                          cond::getCommand(),
0126                                          action,
0127                                          lt);
0128       }
0129     }
0130 
0131     void SessionImpl::openIovDb(SessionImpl::FailureOnOpeningPolicy policy) {
0132       if (!transaction.get())
0133         throwException("The transaction is not active.", "SessionImpl::openIovDb");
0134       if (!transaction->iovDbOpen) {
0135         transaction->iovDbExists = iovSchemaHandle->exists();
0136         transaction->iovDbOpen = true;
0137       }
0138       if (!transaction->iovDbExists) {
0139         if (policy == CREATE) {
0140           iovSchemaHandle->create();
0141           transaction->iovDbExists = true;
0142         } else {
0143           if (policy == THROW)
0144             throwException("IOV Database does not exist.", "SessionImpl::openIovDb");
0145         }
0146       }
0147     }
0148 
0149     void SessionImpl::openGTDb(SessionImpl::FailureOnOpeningPolicy policy) {
0150       if (!transaction.get())
0151         throwException("The transaction is not active.", "SessionImpl::openGTDb");
0152       if (!transaction->gtDbOpen) {
0153         transaction->gtDbExists = gtSchemaHandle->exists();
0154         transaction->gtDbOpen = true;
0155       }
0156       if (!transaction->gtDbExists) {
0157         if (policy == CREATE) {
0158           gtSchemaHandle->create();
0159           transaction->gtDbExists = true;
0160         } else {
0161           if (policy == THROW)
0162             throwException("GT Database does not exist.", "SessionImpl::openGTDb");
0163         }
0164       }
0165     }
0166 
0167     void SessionImpl::openRunInfoDb() {
0168       if (!transaction.get())
0169         throwException("The transaction is not active.", "SessionImpl::openRunInfoDb");
0170       if (!transaction->runInfoDbOpen) {
0171         transaction->runInfoDbExists = runInfoSchemaHandle->exists();
0172         transaction->runInfoDbOpen = true;
0173       }
0174       if (!transaction->runInfoDbExists) {
0175         throwException("RunInfo Database does not exist.", "SessionImpl::openRunInfoDb");
0176       }
0177     }
0178 
0179     void SessionImpl::openDb() {
0180       if (!transaction.get())
0181         throwException("The transaction is not active.", "SessionImpl::openIovDb");
0182       if (!transaction->iovDbOpen) {
0183         transaction->iovDbExists = iovSchemaHandle->exists();
0184         transaction->iovDbOpen = true;
0185       }
0186       if (!transaction->gtDbOpen) {
0187         transaction->gtDbExists = gtSchemaHandle->exists();
0188         transaction->gtDbOpen = true;
0189       }
0190       if (!transaction->iovDbExists) {
0191         iovSchemaHandle->create();
0192         transaction->iovDbExists = true;
0193         if (!transaction->gtDbExists) {
0194           gtSchemaHandle->create();
0195           transaction->gtDbExists = true;
0196         }
0197       }
0198     }
0199 
0200     IIOVSchema& SessionImpl::iovSchema() { return *iovSchemaHandle; }
0201 
0202     IGTSchema& SessionImpl::gtSchema() { return *gtSchemaHandle; }
0203 
0204     IRunInfoSchema& SessionImpl::runInfoSchema() { return *runInfoSchemaHandle; }
0205   }  // namespace persistency
0206 }  // namespace cond