00001 #include "CondCore/IOVService/interface/IOVEditor.h"
00002 #include "CondCore/DBCommon/interface/Exception.h"
00003 #include "CondCore/IOVService/interface/IOVNames.h"
00004 #include "CondFormats/Common/interface/IOVSequence.h"
00005
00006
00007 #include<ostream>
00008 #include<sstream>
00009
00010 namespace cond {
00011
00012 IOVEditor::~IOVEditor(){}
00013
00014 IOVEditor::IOVEditor( cond::DbSession& dbSess):m_dbSess(dbSess),
00015 m_isActive(false){
00016 }
00017
00018 IOVEditor::IOVEditor( cond::DbSession& dbSess,
00019 const std::string& token
00020 ):m_dbSess(dbSess),m_token(token),
00021 m_isActive(false){
00022 }
00023
00024 IOVSequence & IOVEditor::iov(){ return *m_iov;}
00025
00026
00027 void IOVEditor::debugInfo(std::ostream & co) const {
00028 co << "IOVEditor: ";
00029 co << "db " << m_dbSess.connectionString();
00030 if(m_token.empty()) {
00031 co << " no token"; return;
00032 }
00033 if (!m_iov.get() ) {
00034 co << " no iov for token " << m_token;
00035 return;
00036 }
00037 co << " iov token " << m_token;
00038 co << "\nStamp: " << m_iov->comment()
00039 << "; time " << m_iov->timestamp()
00040 << "; revision " << m_iov->revision();
00041 co <<". TimeType " << cond::timeTypeSpecs[ m_iov->timeType()].name;
00042 if( m_iov->iovs().empty() )
00043 co << ". empty";
00044 else
00045 co << ". size " << m_iov->iovs().size()
00046 << "; last since " << m_iov->iovs().back().sinceTime();
00047 }
00048
00049 void IOVEditor::reportError(std::string message) const {
00050 std::ostringstream out;
00051 out << "Error in ";
00052 debugInfo(out);
00053 out << "\n" << message;
00054 throw cond::Exception(out.str());
00055 }
00056
00057 void IOVEditor::reportError(std::string message, cond::Time_t time) const {
00058 std::ostringstream out;
00059 out << "Error in";
00060 debugInfo(out);
00061 out << "\n" << message << " for time: " << time;
00062 throw cond::Exception(out.str());
00063 }
00064
00065
00066
00067 void IOVEditor::create(cond::TimeType timetype) {
00068 if(!m_token.empty()){
00069
00070 reportError("cond::IOVEditor::create cannot create a IOV using an initialized Editor");
00071 }
00072
00073 m_iov.reset( new cond::IOVSequence(timetype) );
00074 m_token = m_dbSess.storeObject( m_iov.get(), cond::IOVNames::container());
00075 m_isActive=true;
00076
00077 }
00078
00079 void IOVEditor::create(cond::TimeType timetype,cond::Time_t lastTill) {
00080 if(!m_token.empty()){
00081
00082 reportError("cond::IOVEditor::create cannot create a IOV using an initialized Editor");
00083 }
00084
00085 if(!validTime(lastTill, timetype))
00086 reportError("cond::IOVEditor::create time not in global range",lastTill);
00087
00088 m_iov.reset( new cond::IOVSequence((int)timetype,lastTill," ") );
00089 m_token = m_dbSess.storeObject( m_iov.get(),cond::IOVNames::container());
00090 m_isActive=true;
00091 }
00092
00093 void IOVEditor::init(){
00094 if(m_token.empty()){
00095
00096 reportError("cond::IOVEditor::init cannot init w/o token change");
00097 }
00098
00099 m_iov = m_dbSess.getTypedObject<cond::IOVSequence>(m_token);
00100 m_isActive=true;
00101
00102 }
00103
00104
00105 Time_t IOVEditor::firstSince() const {
00106 return m_iov->firstSince();
00107 }
00108
00109 Time_t IOVEditor::lastTill() const {
00110 return m_iov->lastTill();
00111 }
00112
00113 TimeType IOVEditor::timetype() const {
00114 return m_iov->timeType();
00115 }
00116
00117
00118 bool IOVEditor::validTime(cond::Time_t time, cond::TimeType timetype) const {
00119 return time>=timeTypeSpecs[timetype].beginValue && time<=timeTypeSpecs[timetype].endValue;
00120
00121 }
00122
00123 bool IOVEditor::validTime(cond::Time_t time) const {
00124 return validTime(time,timetype());
00125 }
00126
00127
00128
00129 unsigned int
00130 IOVEditor::insert( cond::Time_t tillTime,
00131 const std::string& payloadToken
00132 ){
00133 if(!m_isActive) this->init();
00134
00135 if( m_iov->iovs().empty() )
00136 reportError("cond::IOVEditor::insert cannot inser into empty IOV sequence",tillTime);
00137
00138 if(!validTime(tillTime))
00139 reportError("cond::IOVEditor::insert time not in global range",tillTime);
00140
00141 if(tillTime<=lastTill() )
00142 reportError("cond::IOVEditor::insert IOV not in range",tillTime);
00143
00144 cond::Time_t newSince=lastTill()+1;
00145 unsigned int ret = m_iov->add(newSince, payloadToken);
00146 updateClosure(tillTime);
00147 m_dbSess.updateObject( m_iov.get(), m_token );
00148 return ret;
00149 }
00150
00151 void
00152 IOVEditor::bulkAppend(std::vector< std::pair<cond::Time_t,std::string> >& values){
00153 if (values.empty()) return;
00154 if(!m_isActive) this->init();
00155 cond::Time_t firstTime = values.front().first;
00156 cond::Time_t lastTime = values.back().first;
00157 if(!validTime(firstTime))
00158 reportError("cond::IOVEditor::bulkInsert first time not in global range",firstTime);
00159
00160 if(!validTime(lastTime))
00161 reportError("cond::IOVEditor::bulkInsert last time not in global range",lastTime);
00162
00163 if(lastTime>=lastTill() ||
00164 ( !m_iov->iovs().empty() && firstTime<=m_iov->iovs().back().sinceTime())
00165 )
00166 reportError("cond::IOVEditor::bulkInsert IOV not in range",firstTime);
00167
00168 for(std::vector< std::pair<cond::Time_t,std::string> >::const_iterator it=values.begin(); it!=values.end(); ++it){
00169
00170 m_iov->add(it->first,it->second);
00171 }
00172 m_dbSess.updateObject( m_iov.get(), m_token );
00173 }
00174
00175 void
00176 IOVEditor::bulkAppend(std::vector< cond::IOVElement >& values){
00177 if (values.empty()) return;
00178 if(!m_isActive) this->init();
00179 cond::Time_t firstTime = values.front().sinceTime();
00180 cond::Time_t lastTime = values.back().sinceTime();
00181 if(!validTime(firstTime))
00182 reportError("cond::IOVEditor::bulkInsert first time not in global range",firstTime);
00183
00184 if(!validTime(lastTime))
00185 reportError("cond::IOVEditor::bulkInsert last time not in global range",lastTime);
00186
00187 if(lastTime>=lastTill() ||
00188 ( !m_iov->iovs().empty() && firstTime<=m_iov->iovs().back().sinceTime())
00189 ) reportError("cond::IOVEditor::bulkInsert IOV not in range",firstTime);
00190
00191 m_dbSess.updateObject( m_iov.get(), m_token );
00192 }
00193
00194
00195 void
00196 IOVEditor::stamp(std::string const & icomment, bool append) {
00197 if(!m_isActive) this->init();
00198 m_iov->stamp(icomment, append);
00199 m_dbSess.updateObject( m_iov.get(), m_token );
00200 }
00201
00202
00203 void
00204 IOVEditor::updateClosure( cond::Time_t newtillTime ){
00205 if( m_token.empty() ) reportError("cond::IOVEditor::updateClosure cannot change non-existing IOV index");
00206 if(!m_isActive) this->init();
00207 m_iov->updateLastTill(newtillTime);
00208 m_dbSess.updateObject( m_iov.get(), m_token );
00209 }
00210
00211 unsigned int
00212 IOVEditor::append( cond::Time_t sinceTime,
00213 const std::string&payloadToken
00214 ){
00215 if( m_token.empty() ) {
00216 reportError("cond::IOVEditor::appendIOV cannot append to non-existing IOV index");
00217 }
00218
00219 if(!m_isActive) {
00220 this->init();
00221 }
00222
00223 if(!validTime(sinceTime))
00224 reportError("cond::IOVEditor::append time not in global range",sinceTime);
00225
00226
00227 if( !m_iov->iovs().empty() ){
00228
00229 cond::Time_t lastValidSince=m_iov->iovs().back().sinceTime();
00230 if( sinceTime<= lastValidSince){
00231 reportError("IOVEditor::append Error: since time out of range: below last since",sinceTime);
00232 }
00233 }
00234
00235
00236 if (lastTill()<=sinceTime) updateClosure(timeTypeSpecs[timetype()].endValue);
00237 unsigned int ret = m_iov->add(sinceTime,payloadToken);
00238 m_dbSess.updateObject( m_iov.get(), m_token );
00239 return ret;
00240 }
00241
00242
00243 unsigned int
00244 IOVEditor::freeInsert( cond::Time_t sinceTime ,
00245 const std::string& payloadToken
00246 ){
00247
00248
00249 if( m_token.empty() ) {
00250 reportError("cond::IOVEditor::freeInsert cannot append to non-existing IOV index");
00251 }
00252
00253 if(!m_isActive) {
00254 this->init();
00255 }
00256
00257
00258
00259
00260 if(!validTime(sinceTime))
00261 reportError("cond::IOVEditor::freeInsert time not in global range",sinceTime);
00262
00263
00264
00265 if (m_iov->exist(sinceTime))
00266 reportError("cond::IOVEditor::freeInsert sinceTime already existing",sinceTime);
00267
00268
00269
00270
00271 if (lastTill()<sinceTime) updateClosure(timeTypeSpecs[timetype()].endValue);
00272 unsigned int ret = m_iov->add(sinceTime,payloadToken);
00273
00274 m_dbSess.updateObject( m_iov.get(), m_token );
00275 return ret;
00276 }
00277
00278
00279
00280 unsigned int IOVEditor::truncate(bool withPayload) {
00281 if( m_token.empty() ) reportError("cond::IOVEditor::truncate cannot delete to non-existing IOV sequence");
00282 if(!m_isActive) this->init();
00283 if (m_iov->piovs().empty()) return 0;
00284 if(withPayload){
00285 std::string tokenStr = m_iov->piovs().back().wrapperToken();
00286 m_dbSess.deleteObject( tokenStr );
00287 }
00288 unsigned int ret = m_iov->truncate();
00289 m_dbSess.updateObject( m_iov.get(), m_token );
00290 return ret;
00291
00292 }
00293
00294
00295 void
00296 IOVEditor::deleteEntries(bool withPayload){
00297 if( m_token.empty() ) reportError("cond::IOVEditor::deleteEntries cannot delete to non-existing IOV sequence");
00298 if(!m_isActive) this->init();
00299 if(withPayload){
00300 std::string tokenStr;
00301 IOVSequence::const_iterator payloadIt;
00302 IOVSequence::const_iterator payloadItEnd=m_iov->piovs().end();
00303 for(payloadIt=m_iov->piovs().begin();payloadIt!=payloadItEnd;++payloadIt){
00304 tokenStr=payloadIt->wrapperToken();
00305 m_dbSess.deleteObject( tokenStr );
00306 }
00307 }
00308 m_dbSess.deleteObject( m_token );
00309 m_iov->piovs().clear();
00310 }
00311
00312 void
00313 IOVEditor::import( const std::string& sourceIOVtoken ){
00314 if( !m_token.empty() ) reportError("cond::IOVEditor::import IOV sequence already exists, cannot import");
00315 m_iov = m_dbSess.getTypedObject<cond::IOVSequence>(sourceIOVtoken);
00316
00317 m_token=sourceIOVtoken;
00318 }
00319
00320
00321 }