00001 #include "CondCore/Utilities/interface/ExportIOVUtilities.h"
00002
00003 #include "CondCore/DBCommon/interface/DbSession.h"
00004 #include "CondCore/DBCommon/interface/DbScopedTransaction.h"
00005 #include "CondCore/DBCommon/interface/DbTransaction.h"
00006 #include "CondCore/DBCommon/interface/Exception.h"
00007 #include "CondCore/DBCommon/interface/Auth.h"
00008
00009 #include "CondCore/MetaDataService/interface/MetaData.h"
00010 #include "CondCore/IOVService/interface/IOVProxy.h"
00011
00012 #include "CondCore/DBCommon/interface/Logger.h"
00013 #include "CondCore/DBCommon/interface/LogDBEntry.h"
00014 #include "CondCore/DBCommon/interface/TagInfo.h"
00015
00016 #include "CondCore/IOVService/interface/IOVNames.h"
00017 #include "CondCore/IOVService/interface/IOVSchemaUtility.h"
00018 #include "CondCore/IOVService/interface/IOVEditor.h"
00019 #include <iterator>
00020 #include <limits>
00021 #include <iostream>
00022 #include <fstream>
00023 #include <sstream>
00024 #include <stdexcept>
00025
00026 cond::ExportIOVUtilities::ExportIOVUtilities(std::string const & name):Utilities(name){
00027 addDictionaryOption();
00028 addAuthenticationOptions();
00029 addConfigFileOption();
00030 addLogDBOption();
00031 addConnectOption("sourceConnect","s","source connection string(required)");
00032 addConnectOption("destConnect","d","destionation connection string(required)");
00033 addOption<std::string>("inputTag","i","tag to export( default = destination tag)");
00034 addOption<std::string>("destTag","t","destination tag (required)");
00035 addOption<cond::Time_t>("beginTime","b","begin time (first since) (optional)");
00036 addOption<cond::Time_t>("endTime","e","end time (last till) (optional)");
00037 addOption<bool>("outOfOrder","o","allow out of order merge (optional, default=false)");
00038 addOption<size_t>("bunchSize","n","iterate with bunches of specific size (optional)");
00039 addOption<std::string>("usertext","x","user text, to be included in usertext column (optional, must be enclosed in double quotes)");
00040 addSQLOutputOption();
00041 }
00042
00043 cond::ExportIOVUtilities::~ExportIOVUtilities(){
00044 }
00045
00046 int cond::ExportIOVUtilities::execute(){
00047
00048 std::string sourceConnect = getOptionValue<std::string>("sourceConnect");
00049 std::string destConnect = getOptionValue<std::string>("destConnect");
00050
00051 std::string destTag = getOptionValue<std::string>("destTag");
00052 std::string inputTag(destTag);
00053 if( hasOptionValue("inputTag") ) inputTag = getOptionValue<std::string>("inputTag");
00054 std::string usertext("no user comments");
00055 if( hasOptionValue("usertext")) usertext = getOptionValue<std::string>("usertext");
00056 bool doLog = hasOptionValue("logDB");
00057
00058 cond::Time_t since = std::numeric_limits<cond::Time_t>::min();
00059 if( hasOptionValue("beginTime" )) since = getOptionValue<cond::Time_t>("beginTime");
00060 cond::Time_t till = std::numeric_limits<cond::Time_t>::max();
00061 if( hasOptionValue("endTime" )) till = getOptionValue<cond::Time_t>("endTime");
00062
00063 size_t bunchSize = 1;
00064 if(hasOptionValue("bunchSize")) bunchSize = getOptionValue<size_t>("bunchSize");
00065
00066 std::string sqlOutputFileName("sqlmonitoring.out");
00067 bool debug=hasDebug();
00068 bool outOfOrder = hasOptionValue("outOfOrder");
00069
00070 std::string sourceIovToken("");
00071 std::string destIovToken("");
00072 bool newIOV = false;
00073 cond::TimeType sourceIovType;
00074
00075 cond::DbSession sourceDb = openDbSession("sourceConnect", Auth::COND_READER_ROLE, true);
00076 cond::DbSession destDb = openDbSession("destConnect", Auth::COND_WRITER_ROLE );
00077
00078 std::auto_ptr<cond::Logger> logDb;
00079 cond::DbSession logSession;
00080
00081 std::string payloadToken("");
00082 std::string payloadClasses("");
00083 int iovSize = 0;
00084 int ncopied = 0;
00085 cond::UserLogInfo a;
00086 if (doLog) {
00087 logSession = openDbSession( "logDB",Auth::COND_WRITER_ROLE );
00088 logDb.reset(new cond::Logger(logSession));
00089 logDb->createLogDBIfNonExist();
00090 a.provenance=sourceConnect+"/"+inputTag;
00091 a.usertext="exportIOV V4.0;";
00092 }
00093
00094
00095 sourceDb.transaction().start(true);
00096 cond::MetaData sourceMetadata(sourceDb);
00097 sourceIovToken=sourceMetadata.getToken(inputTag);
00098 if(sourceIovToken.empty())
00099 throw std::runtime_error(std::string("tag ")+inputTag+std::string(" not found") );
00100
00101 if(debug){
00102 std::cout<<"source iov token "<<sourceIovToken<<std::endl;
00103 }
00104
00105 cond::IOVProxy sourceIov( sourceDb );
00106 sourceIov.load( sourceIovToken );
00107 sourceIovType = sourceIov.timetype();
00108 std::string const & timetypestr = cond::timeTypeSpecs[sourceIovType].name;
00109 if(debug){
00110 std::cout<<"source iov type "<<sourceIovType<<std::endl;
00111 }
00112
00113 if( doLog ){
00114 std::set<std::string> pclasses = sourceIov.payloadClasses();
00115 iovSize = sourceIov.size();
00116 std::ostringstream stream;
00117 std::copy(pclasses.begin(), pclasses.end(), std::ostream_iterator<std::string>(stream, ", "));
00118 payloadClasses = stream.str();
00119 }
00120
00121 try{
00122
00123 cond::DbScopedTransaction transaction(destDb);
00124 transaction.start(false);
00125
00126 int oldSize=0;
00127 cond::IOVEditor destIov( destDb );
00128 destIov.createIOVContainerIfNecessary();
00129 destDb.storage().lockContainer( IOVNames::container() );
00130
00131 cond::MetaData destMetadata( destDb );
00132 if( destMetadata.hasTag(destTag) ){
00133 destIovToken=destMetadata.getToken(destTag);
00134 destIov.load( destIovToken );
00135 oldSize = destIov.proxy().size();
00136 if (sourceIovType!=destIov.timetype()) {
00137 throw std::runtime_error("iov type in source and dest differs");
00138 }
00139 } else {
00140 newIOV = true;
00141 destIovToken=destIov.create( sourceIovType, sourceIov.iov().lastTill(),sourceIov.iov().metadata() );
00142 destMetadata.addMapping(destTag,destIovToken,sourceIovType);
00143 destIov.setScope( cond::IOVSequence::Tag );
00144 }
00145 if(debug){
00146 std::cout<<"dest iov token "<<destIovToken<<std::endl;
00147 std::cout<<"dest iov type "<<sourceIovType<<std::endl;
00148 }
00149
00150 since = std::max(since, cond::timeTypeSpecs[sourceIovType].beginValue);
00151 till = std::min(till, cond::timeTypeSpecs[sourceIovType].endValue);
00152
00153 boost::shared_ptr<IOVImportIterator> importIterator = destIov.importIterator();
00154 importIterator->setUp( sourceIov, since, till, outOfOrder, bunchSize );
00155
00156 size_t totalImported = 0;
00157 if( bunchSize>1 ){
00158 unsigned int iter = 0;
00159 while( importIterator->hasMoreElements() ){
00160 if(iter>0){
00161 transaction.commit();
00162 transaction.start();
00163 destIov.reload();
00164 }
00165 iter++;
00166 size_t imported = importIterator->importMoreElements();
00167 totalImported += imported;
00168 std::cout <<"Iteration #"<<iter<<": "<<imported<<" element(s)."<<std::endl;
00169 }
00170 } else {
00171 totalImported = importIterator->importAll();
00172 }
00173 std::cout <<totalImported<<" element(s) exported."<<std::endl;
00174
00175 ::sleep(1);
00176
00177
00178
00179 if (doLog) {
00180 IOVProxy diov = destIov.proxy();
00181 std::ostringstream stream;
00182 std::copy(diov.payloadClasses().begin(), diov.payloadClasses().end(), std::ostream_iterator<std::string>(stream, ", "));
00183 payloadClasses = stream.str();
00184 iovSize = diov.size();
00185 ncopied = iovSize-oldSize;
00186 if ( ncopied == 1) {
00187
00188 const IOVElement& last = diov.iov().iovs().back();
00189 payloadToken=last.token();
00190 payloadClasses = destDb.classNameForItem( payloadToken );
00191 }
00192 if (newIOV) a.usertext+= "new tag;";
00193 std::ostringstream ss;
00194 ss << "since="<< since <<", till="<< till << ", " << usertext << ";";
00195 ss << " copied="<< ncopied <<";";
00196 a.usertext +=ss.str();
00197 logDb->logOperationNow(a,destConnect,payloadClasses,payloadToken,destTag,timetypestr,iovSize-1,since);
00198 }
00199 transaction.commit();
00200 sourceDb.transaction().commit();
00201 }catch ( cond::Exception const& er ){
00202 if (doLog) {
00203 if (newIOV) a.usertext+= "new tag;";
00204 std::ostringstream ss;
00205 ss << "since="<< since <<", till="<< till << ", " << usertext << ";";
00206 ss << " copied="<< ncopied <<";";
00207 a.usertext +=ss.str();
00208 logDb->logFailedOperationNow(a,destConnect,payloadClasses,payloadToken,destTag,timetypestr,iovSize-1,since,std::string(er.what()));
00209 }
00210 sourceDb.transaction().commit();
00211 throw;
00212 }
00213
00214 return 0;
00215 }
00216
00217