00001 #include "CondCore/DBOutputService/interface/PoolDBOutputService.h"
00002 #include "CondCore/DBCommon/interface/DbScopedTransaction.h"
00003 #include "CondCore/DBCommon/interface/DbTransaction.h"
00004 #include "CondCore/DBCommon/interface/TagInfo.h"
00005 #include "DataFormats/Provenance/interface/EventID.h"
00006 #include "DataFormats/Provenance/interface/Timestamp.h"
00007 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00008 #include "CondCore/IOVService/interface/IOVEditor.h"
00009 #include "CondCore/IOVService/interface/IOVProxy.h"
00010 #include "CondCore/IOVService/interface/IOVSchemaUtility.h"
00011 #include "CondCore/DBCommon/interface/Exception.h"
00012 #include "CondCore/DBOutputService/interface/Exception.h"
00013
00014
00015 #include "CondCore/DBCommon/interface/UserLogInfo.h"
00016 #include "CondCore/DBCommon/interface/IOVInfo.h"
00017
00018
00019 #include <vector>
00020 #include<memory>
00021
00022 namespace {
00023 std::string dsw("DataWrapper");
00024 }
00025
00026 unsigned int cond::service::GetToken::sizeDSW() {
00027 return dsw.size();
00028 }
00029
00030 void
00031 cond::service::PoolDBOutputService::fillRecord( edm::ParameterSet & pset) {
00032 Record thisrecord;
00033
00034 thisrecord.m_idName = pset.getParameter<std::string>("record");
00035 thisrecord.m_tag = pset.getParameter<std::string>("tag");
00036
00037 thisrecord.m_closeIOV =
00038 pset.getUntrackedParameter<bool>("closeIOV", m_closeIOV);
00039
00040 thisrecord.m_withWrapper =
00041 pset.getUntrackedParameter<bool>("withWrapper", m_withWrapper);
00042
00043 thisrecord.m_freeInsert =
00044 pset.getUntrackedParameter<bool>("outOfOrder",m_freeInsert);
00045
00046 thisrecord.m_timetype=cond::findSpecs(pset.getUntrackedParameter< std::string >("timetype",m_timetypestr)).type;
00047
00048 m_callbacks.insert(std::make_pair(thisrecord.m_idName,thisrecord));
00049
00050 if(m_logdbOn){
00051 cond::UserLogInfo userloginfo;
00052 m_logheaders.insert(std::make_pair(thisrecord.m_idName,userloginfo));
00053 }
00054
00055
00056 }
00057
00058
00059 cond::service::PoolDBOutputService::PoolDBOutputService(const edm::ParameterSet & iConfig,edm::ActivityRegistry & iAR ):
00060 m_currentTime( 0 ),
00061 m_connection(),
00062 m_session(),
00063 m_logSession(),
00064 m_dbstarted( false ),
00065 m_logdb( 0 ),
00066 m_logdbOn( false ),
00067 m_closeIOV(false),
00068 m_freeInsert(false),
00069 m_withWrapper(false)
00070 {
00071
00072 m_closeIOV=iConfig.getUntrackedParameter<bool>("closeIOV",m_closeIOV);
00073
00074 if( iConfig.exists("outOfOrder") ){
00075 m_freeInsert=iConfig.getUntrackedParameter<bool>("outOfOrder");
00076 }
00077
00078 m_timetypestr=iConfig.getUntrackedParameter< std::string >("timetype","runnumber");
00079 m_timetype=cond::findSpecs( m_timetypestr).type;
00080
00081 std::string connect=iConfig.getParameter<std::string>("connect");
00082 std::string logconnect("");
00083 if( iConfig.exists("logconnect") ){
00084 logconnect=iConfig.getUntrackedParameter<std::string>("logconnect");
00085 }
00086
00087 edm::ParameterSet connectionPset = iConfig.getParameter<edm::ParameterSet>("DBParameters");
00088 m_connection.configuration().setParameters( connectionPset );
00089 m_connection.configure();
00090
00091 m_session = m_connection.createSession();
00092
00093 m_session.open( connect );
00094
00095 if( !logconnect.empty() ){
00096 m_logdbOn=true;
00097 m_logSession = m_connection.createSession();
00098 m_logSession.open( logconnect );
00099 }
00100
00101 typedef std::vector< edm::ParameterSet > Parameters;
00102 Parameters toPut=iConfig.getParameter<Parameters>("toPut");
00103 for(Parameters::iterator itToPut = toPut.begin(); itToPut != toPut.end(); ++itToPut)
00104 fillRecord( *itToPut);
00105
00106
00107 iAR.watchPreProcessEvent(this,&cond::service::PoolDBOutputService::preEventProcessing);
00108 iAR.watchPostEndJob(this,&cond::service::PoolDBOutputService::postEndJob);
00109 iAR.watchPreModule(this,&cond::service::PoolDBOutputService::preModule);
00110 iAR.watchPostModule(this,&cond::service::PoolDBOutputService::postModule);
00111 iAR.watchPreBeginLumi(this,&cond::service::PoolDBOutputService::preBeginLumi);
00112 }
00113
00114 cond::DbSession
00115 cond::service::PoolDBOutputService::session() const{
00116 return m_session;
00117 }
00118
00119 std::string
00120 cond::service::PoolDBOutputService::tag( const std::string& recordName ){
00121 return this->lookUpRecord(recordName).m_tag;
00122 }
00123
00124 bool
00125 cond::service::PoolDBOutputService::isNewTagRequest( const std::string& recordName ){
00126 Record& myrecord=this->lookUpRecord(recordName);
00127 if(!m_dbstarted) this->initDB();
00128 return myrecord.m_isNewTag;
00129 }
00130
00131
00132 void
00133 cond::service::PoolDBOutputService::initDB()
00134 {
00135 if(m_dbstarted) return;
00136 try{
00137 cond::DbScopedTransaction transaction( m_session );
00138 transaction.start(false);
00139 IOVSchemaUtility ut(m_session);
00140 ut.create();
00141 cond::MetaData metadata(m_session);
00142 for(std::map<std::string,Record>::iterator it=m_callbacks.begin(); it!=m_callbacks.end(); ++it){
00143
00144 if( !metadata.hasTag(it->second.m_tag) ){
00145 it->second.m_iovtoken="";
00146 it->second.m_isNewTag=true;
00147 }else{
00148 it->second.m_iovtoken=metadata.getToken(it->second.m_tag);
00149 it->second.m_isNewTag=false;
00150 }
00151 }
00152 transaction.commit();
00153
00154 if(m_logdbOn){
00155 m_logdb=new cond::Logger(m_logSession);
00156
00157 m_logdb->createLogDBIfNonExist();
00158
00159 }
00160 }catch( const std::exception& er ){
00161 throw cond::Exception( std::string(er.what()) + " from PoolDBOutputService::initDB" );
00162 }
00163 m_dbstarted=true;
00164 }
00165
00166 void
00167 cond::service::PoolDBOutputService::postEndJob()
00168 {
00169 if(m_logdb){
00170 delete m_logdb;
00171 }
00172 }
00173
00174 void
00175 cond::service::PoolDBOutputService::preEventProcessing(const edm::EventID& iEvtid, const edm::Timestamp& iTime)
00176 {
00177 if( m_timetype == cond::runnumber ){
00178 m_currentTime=iEvtid.run();
00179 }else if( m_timetype == cond::timestamp ){
00180 m_currentTime=iTime.value();
00181 }
00182 }
00183
00184 void
00185 cond::service::PoolDBOutputService::preModule(const edm::ModuleDescription& desc){
00186 }
00187
00188 void
00189 cond::service::PoolDBOutputService::preBeginLumi(const edm::LuminosityBlockID& iLumiid, const edm::Timestamp& iTime ){
00190 if( m_timetype == cond::lumiid ){
00191 m_currentTime=iLumiid.value();
00192 }
00193 }
00194
00195 void
00196 cond::service::PoolDBOutputService::postModule(const edm::ModuleDescription& desc){
00197 }
00198
00199 cond::service::PoolDBOutputService::~PoolDBOutputService(){
00200 }
00201
00202
00203 cond::Time_t
00204 cond::service::PoolDBOutputService::endOfTime() const{
00205 return timeTypeSpecs[m_timetype].endValue;
00206 }
00207
00208 cond::Time_t
00209 cond::service::PoolDBOutputService::beginOfTime() const{
00210 return timeTypeSpecs[m_timetype].beginValue;
00211 }
00212
00213 cond::Time_t
00214 cond::service::PoolDBOutputService::currentTime() const{
00215 return m_currentTime;
00216 }
00217
00218 void
00219 cond::service::PoolDBOutputService::createNewIOV( GetToken const & payloadToken, cond::Time_t firstSinceTime, cond::Time_t firstTillTime,const std::string& recordName, bool withlogging){
00220 Record& myrecord=this->lookUpRecord(recordName);
00221 if (!m_dbstarted) this->initDB();
00222 if(!myrecord.m_isNewTag) throw cond::Exception(myrecord.m_tag + " is not a new tag from PoolDBOutputService::createNewIOV");
00223 std::string iovToken;
00224 if(withlogging){
00225 if(!m_logdb) throw cond::Exception("Log db was not set from PoolDBOutputService::createNewIOV");
00226 m_logdb->getWriteLock();
00227 }
00228
00229 std::string objToken;
00230 unsigned int payloadIdx=0;
00231 try{
00232 cond::DbScopedTransaction transaction(m_session);
00233 transaction.start(false);
00234
00235 cond::IOVEditor editor(m_session);
00236 editor.create(myrecord.m_timetype, firstTillTime);
00237 objToken = payloadToken(m_session,myrecord.m_withWrapper);
00238 unsigned int payloadIdx=editor.append(firstSinceTime, objToken);
00239 iovToken=editor.token();
00240 editor.stamp(cond::userInfo(),false);
00241
00242 cond::MetaData metadata(m_session);
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 metadata.addMapping(myrecord.m_tag,iovToken,myrecord.m_timetype);
00253 transaction.commit();
00254
00255 m_newtags.push_back( std::pair<std::string,std::string>(myrecord.m_tag,iovToken) );
00256 myrecord.m_iovtoken=iovToken;
00257 myrecord.m_isNewTag=false;
00258 if(withlogging){
00259 std::string destconnect=m_session.connectionString();
00260 cond::UserLogInfo a=this->lookUpUserLogInfo(recordName);
00261 m_logdb->logOperationNow(a,destconnect,objToken,myrecord.m_tag,myrecord.timetypestr(),payloadIdx,firstSinceTime);
00262 }
00263 }catch(const std::exception& er){
00264 if(withlogging){
00265 std::string destconnect=m_session.connectionString();
00266 cond::UserLogInfo a=this->lookUpUserLogInfo(recordName);
00267 m_logdb->logFailedOperationNow(a,destconnect,objToken,myrecord.m_tag,myrecord.timetypestr(),payloadIdx,firstSinceTime,std::string(er.what()));
00268 m_logdb->releaseWriteLock();
00269 }
00270 throw cond::Exception(std::string(er.what()) + " from PoolDBOutputService::createNewIOV ");
00271 }
00272 if(withlogging){
00273 m_logdb->releaseWriteLock();
00274 }
00275 }
00276
00277
00278 void
00279 cond::service::PoolDBOutputService::add( GetToken const & payloadToken,
00280 cond::Time_t time,
00281 const std::string& recordName,
00282 bool withlogging) {
00283 Record& myrecord=this->lookUpRecord(recordName);
00284 if (!m_dbstarted) this->initDB();
00285 if(withlogging){
00286 if(!m_logdb) throw cond::Exception("Log db was not set from PoolDBOutputService::add");
00287 m_logdb->getWriteLock();
00288 }
00289
00290 std::string objToken;
00291 unsigned int payloadIdx=0;
00292
00293 try{
00294 cond::DbScopedTransaction transaction(m_session);
00295 transaction.start(false);
00296 objToken = payloadToken(m_session,myrecord.m_withWrapper);
00297 payloadIdx= appendIOV(m_session,myrecord,objToken,time);
00298 transaction.commit();
00299 if(withlogging){
00300 std::string destconnect=m_session.connectionString();
00301 cond::UserLogInfo a=this->lookUpUserLogInfo(recordName);
00302 m_logdb->logOperationNow(a,destconnect,objToken,myrecord.m_tag,myrecord.timetypestr(),payloadIdx,time);
00303 }
00304 }catch(const std::exception& er){
00305 if(withlogging){
00306 std::string destconnect=m_session.connectionString();
00307 cond::UserLogInfo a=this->lookUpUserLogInfo(recordName);
00308 m_logdb->logFailedOperationNow(a,destconnect,objToken,myrecord.m_tag,myrecord.timetypestr(),payloadIdx,time,std::string(er.what()));
00309 m_logdb->releaseWriteLock();
00310 }
00311 throw cond::Exception(std::string(er.what()) + " from PoolDBOutputService::add ");
00312 }
00313 if(withlogging){
00314 m_logdb->releaseWriteLock();
00315 }
00316 }
00317
00318 cond::service::PoolDBOutputService::Record&
00319 cond::service::PoolDBOutputService::lookUpRecord(const std::string& recordName){
00320 std::map<std::string,Record>::iterator it=m_callbacks.find(recordName);
00321 if(it==m_callbacks.end()) throw cond::UnregisteredRecordException(recordName + " from PoolDBOutputService::lookUpRecord");
00322 return it->second;
00323 }
00324
00325 cond::UserLogInfo&
00326 cond::service::PoolDBOutputService::lookUpUserLogInfo(const std::string& recordName){
00327 std::map<std::string,cond::UserLogInfo>::iterator it=m_logheaders.find(recordName);
00328 if(it==m_logheaders.end()) throw cond::Exception("Log db was not set for record " + recordName + " from PoolDBOutputService::lookUpUserLogInfo");
00329 return it->second;
00330 }
00331
00332
00333 unsigned int
00334 cond::service::PoolDBOutputService::appendIOV(cond::DbSession& pooldb,
00335 Record& record,
00336 const std::string& payloadToken,
00337 cond::Time_t sinceTime){
00338 if( record.m_isNewTag ) {
00339 throw cond::Exception(std::string("Cannot append to non-existing tag ") + record.m_tag + std::string(" from PoolDBOutputService::appendIOV"));
00340 }
00341
00342 cond::IOVEditor editor(pooldb,record.m_iovtoken);
00343
00344 unsigned int payloadIdx = record.m_freeInsert ?
00345 editor.freeInsert(sinceTime,payloadToken) :
00346 editor.append(sinceTime,payloadToken);
00347 if (record.m_closeIOV) editor.updateClosure(sinceTime);
00348 editor.stamp(cond::userInfo(),false);
00349 return payloadIdx;
00350 }
00351
00352 void
00353 cond::service::PoolDBOutputService::closeIOV(Time_t lastTill, const std::string& recordName,
00354 bool withlogging) {
00355
00356 Record & record = lookUpRecord(recordName);
00357 if( record.m_isNewTag ) {
00358 throw cond::Exception(std::string("Cannot close non-existing tag ") + record.m_tag + std::string(" from PoolDBOutputService::closeIOV"));
00359 }
00360 cond::DbScopedTransaction transaction(m_session);
00361 transaction.start(false);
00362 cond::IOVEditor editor(m_session,record.m_iovtoken);
00363 editor.updateClosure(lastTill);
00364 editor.stamp(cond::userInfo(),false);
00365 transaction.commit();
00366 }
00367
00368
00369
00370 void
00371 cond::service::PoolDBOutputService::setLogHeaderForRecord(const std::string& recordName,const std::string& dataprovenance,const std::string& usertext)
00372 {
00373 cond::UserLogInfo& myloginfo=this->lookUpUserLogInfo(recordName);
00374 myloginfo.provenance=dataprovenance;
00375 myloginfo.usertext=usertext;
00376 }
00377
00378
00379 const cond::Logger&
00380 cond::service::PoolDBOutputService::queryLog()const{
00381 if(!m_logdb) throw cond::Exception("Log database is not set from PoolDBOutputService::queryLog");
00382 return *m_logdb;
00383 }
00384
00385
00386 void
00387 cond::service::PoolDBOutputService::tagInfo(const std::string& recordName,cond::TagInfo& result ){
00388 if (!m_dbstarted) initDB();
00389 Record& record = lookUpRecord(recordName);
00390 result.name=record.m_tag;
00391 result.token=record.m_iovtoken;
00392
00393 cond::IOVProxy iov(m_session, record.m_iovtoken, true, false);
00394 result.size=iov.size();
00395 if (result.size>0) {
00396
00397 iov.tail(1);
00398 cond::IOVElementProxy last = *iov.begin();
00399 result.lastInterval = cond::ValidityInterval(last.since(), last.till());
00400 result.lastPayloadToken=last.token();
00401 }
00402 }