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