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