$treeview $search $mathjax $extrastylesheet
otsdaq
v2_03_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #include <dirent.h> 00002 #include <cassert> 00003 #include <iostream> 00004 #include <memory> 00005 #include <string> 00006 #include "otsdaq-core/ConfigurationInterface/ConfigurationInterface.h" 00007 #include "otsdaq-core/ConfigurationInterface/ConfigurationManagerRW.h" 00008 //#include "artdaq-database/StorageProviders/FileSystemDB/provider_filedb_index.h" 00009 //#include "artdaq-database/JsonDocument/JSONDocument.h" 00010 00011 // usage: 00012 // otsdaq_flatten_system_aliases <baseFlatVersion> <pathToSwapIn (optional)> 00013 // 00014 // if baseFlatVersion is invalid or temporary nothing is saved in the new db 00015 // (Note: this can be used to swap dbs using pathToSwapIn) 00016 00017 using namespace ots; 00018 00019 void FlattenActiveSystemAliasTableGroups(int argc, char* argv[]) 00020 { 00021 std::cout << "=================================================\n"; 00022 std::cout << "=================================================\n"; 00023 std::cout << "=================================================\n"; 00024 __COUT__ << "\nFlattening Active System Aliases!" << std::endl; 00025 00026 std::cout << "\n\nusage: Two arguments:\n\t <baseFlatVersion> <pathToSwapIn " 00027 "(optional)> \n\n" 00028 << "\t Default values: baseFlatVersion = 0, pathToSwapIn = \"\" \n\n" 00029 << std::endl; 00030 00031 std::cout << "\n\nNote: you can optionally just swap databases (and not modify their " 00032 "contents at all)" 00033 << " by providing an invalid baseFlatVersion of -1.\n\n" 00034 << std::endl; 00035 00036 std::cout << "\n\nNote: This assumes artdaq db file type interface. " 00037 << "The current database/ will be moved to database_<linuxtime>/ " 00038 << "and if a pathToSwapIn is specified it will be copied to database/ " 00039 << "before saving the currently active groups.\n\n" 00040 << std::endl; 00041 00042 std::cout << "argc = " << argc << std::endl; 00043 for(int i = 0; i < argc; i++) 00044 std::cout << "argv[" << i << "] = " << argv[i] << std::endl; 00045 00046 if(argc < 2) 00047 { 00048 std::cout << "Error! Must provide at least one parameter.\n\n" << std::endl; 00049 return; 00050 } 00051 00052 // determine if "h"elp was first parameter 00053 std::string flatVersionStr = argv[1]; 00054 if(flatVersionStr.find('h') != std::string::npos) 00055 { 00056 std::cout 00057 << "Recognized parameter 1. as a 'help' option. Usage was printed. Exiting." 00058 << std::endl; 00059 return; 00060 } 00061 00062 int flatVersion = 0; 00063 std::string pathToSwapIn = ""; 00064 if(argc >= 2) 00065 sscanf(argv[1], "%d", &flatVersion); 00066 if(argc >= 3) 00067 pathToSwapIn = argv[2]; 00068 00069 __COUT__ << "flatVersion = " << flatVersion << std::endl; 00070 __COUT__ << "pathToSwapIn = " << pathToSwapIn << std::endl; 00071 00072 // return; 00073 //============================================================================== 00074 // Define environment variables 00075 // Note: normally these environment variables are set by StartOTS.sh 00076 00077 // These are needed by 00078 // otsdaq/otsdaq-core/ConfigurationDataFormats/ConfigurationInfoReader.cc [207] 00079 setenv("CONFIGURATION_TYPE", "File", 1); // Can be File, Database, DatabaseTest 00080 setenv("CONFIGURATION_DATA_PATH", 00081 (std::string(getenv("USER_DATA")) + "/ConfigurationDataExamples").c_str(), 00082 1); 00083 setenv( 00084 "TABLE_INFO_PATH", (std::string(getenv("USER_DATA")) + "/TableInfo").c_str(), 1); 00086 00087 // Some configuration plug-ins use getenv("SERVICE_DATA_PATH") in init() so define it 00088 setenv("SERVICE_DATA_PATH", 00089 (std::string(getenv("USER_DATA")) + "/ServiceData").c_str(), 00090 1); 00091 00092 // Some configuration plug-ins use getenv("OTSDAQ_LIB") and 00093 // getenv("OTSDAQ_UTILITIES_LIB") in init() so define it to a non-sense place is ok 00094 setenv("OTSDAQ_LIB", (std::string(getenv("USER_DATA")) + "/").c_str(), 1); 00095 setenv("OTSDAQ_UTILITIES_LIB", (std::string(getenv("USER_DATA")) + "/").c_str(), 1); 00096 00097 // Some configuration plug-ins use getenv("OTS_MAIN_PORT") in init() so define it 00098 setenv("OTS_MAIN_PORT", "2015", 1); 00099 00100 // also xdaq envs for XDAQContextTable 00101 setenv("XDAQ_CONFIGURATION_DATA_PATH", 00102 (std::string(getenv("USER_DATA")) + "/XDAQConfigurations").c_str(), 00103 1); 00104 setenv("XDAQ_CONFIGURATION_XML", "otsConfigurationNoRU_CMake", 1); 00106 00107 //============================================================================== 00108 // get prepared with initial source db 00109 00110 // ConfigurationManager instance immediately loads active groups 00111 std::cout << "\n\n\n" << __COUT_HDR_FL__ << "Loading active Aliases..." << std::endl; 00112 ConfigurationManagerRW cfgMgrInst("flatten_admin"); 00113 ConfigurationManagerRW* cfgMgr = &cfgMgrInst; 00114 00115 // create set of groups to persist 00116 // include active context 00117 // include active backbone 00118 // include active iterate group 00119 // include active config group 00120 // (keep key translation separate activeGroupKeys) 00121 // include all groups with system aliases 00122 00123 // for group in set 00124 // load/activate group and flatten tables to flatVersion to new DB 00125 // save new version to modifiedTables 00126 // save group with flatVersion key to new DB 00127 // save new key to groupSet 00128 // ++flatVersion 00129 00130 // reload the active backbone (using activeGroupKeys) 00131 // modify group aliases and table aliases properly based on groupSet and 00132 // modifiedTables save new backbone with flatVersion to new DB 00133 00134 // backup the file ConfigurationManager::ACTIVE_GROUPS_FILENAME with time 00135 // and change the ConfigurationManager::ACTIVE_GROUPS_FILENAME 00136 // to reflect new group names/keys 00137 00138 /* map<<groupName, origKey>, newKey> */ 00139 std::map<std::pair<std::string, TableGroupKey>, TableGroupKey> groupSet; 00140 /* <tableName, <origVersion, newVersion> >*/ 00141 std::map<std::pair<std::string, TableVersion>, TableVersion> modifiedTables; 00142 std::map<std::string, std::pair<TableGroupKey, TableGroupKey>> activeGroupKeys; 00143 std::map<std::pair<std::string, TableGroupKey>, std::string> groupErrors; 00144 00145 std::string activeBackboneGroupName = ""; 00146 std::string activeContextGroupName = ""; 00147 std::string activeIterateGroupName = ""; 00148 std::string activeConfigGroupName = ""; 00149 00150 std::string nowTime = std::to_string(time(0)); 00151 00152 std::string thenTime = ""; 00153 if(pathToSwapIn != "") // get target then time 00154 { 00155 thenTime = pathToSwapIn.substr(pathToSwapIn.rfind('_') + 1); 00156 std::cout << __COUT_HDR_FL__ << "thenTime = " << thenTime << std::endl; 00157 // return; 00158 } 00159 00160 // add active groups to set 00161 std::map<std::string, std::pair<std::string, TableGroupKey>> activeGroupsMap = 00162 cfgMgr->getActiveTableGroups(); 00163 00164 for(const auto& activeGroup : activeGroupsMap) 00165 { 00166 groupSet.insert(std::pair<std::pair<std::string, TableGroupKey>, TableGroupKey>( 00167 std::pair<std::string, TableGroupKey>(activeGroup.second.first, 00168 activeGroup.second.second), 00169 TableGroupKey())); 00170 activeGroupKeys.insert( 00171 std::pair<std::string, std::pair<TableGroupKey, TableGroupKey>>( 00172 activeGroup.second.first, 00173 std::pair<TableGroupKey, TableGroupKey>(activeGroup.second.second, 00174 TableGroupKey()))); 00175 00176 if(activeGroup.first == ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE) 00177 { 00178 activeBackboneGroupName = activeGroup.second.first; 00179 std::cout << __COUT_HDR_FL__ 00180 << "found activeBackboneGroupName = " << activeBackboneGroupName 00181 << std::endl; 00182 } 00183 else if(activeGroup.first == ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT) 00184 { 00185 activeContextGroupName = activeGroup.second.first; 00186 std::cout << __COUT_HDR_FL__ 00187 << "found activeContextGroupName = " << activeContextGroupName 00188 << std::endl; 00189 } 00190 else if(activeGroup.first == ConfigurationManager::ACTIVE_GROUP_NAME_ITERATE) 00191 { 00192 activeIterateGroupName = activeGroup.second.first; 00193 std::cout << __COUT_HDR_FL__ 00194 << "found activeIterateGroupName = " << activeIterateGroupName 00195 << std::endl; 00196 } 00197 else if(activeGroup.first == 00198 ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION) 00199 { 00200 activeConfigGroupName = activeGroup.second.first; 00201 std::cout << __COUT_HDR_FL__ 00202 << "found activeConfigGroupName = " << activeConfigGroupName 00203 << std::endl; 00204 } 00205 } 00206 00207 // add system alias groups to set 00208 const std::string groupAliasesTableName = 00209 ConfigurationManager::GROUP_ALIASES_TABLE_NAME; 00210 std::map<std::string, TableVersion> activeVersions = cfgMgr->getActiveVersions(); 00211 if(activeVersions.find(groupAliasesTableName) == activeVersions.end()) 00212 { 00213 __SS__ << "\nActive version of " << groupAliasesTableName << " missing! " 00214 << groupAliasesTableName 00215 << " is a required member of the Backbone configuration group." 00216 << "\n\nLikely you need to activate a valid Backbone group." << std::endl; 00217 __SS_THROW__; 00218 } 00219 00220 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs = 00221 cfgMgr->getNode(groupAliasesTableName).getChildren(); 00222 for(auto& groupPair : aliasNodePairs) 00223 groupSet.insert(std::pair<std::pair<std::string, TableGroupKey>, TableGroupKey>( 00224 std::pair<std::string, TableGroupKey>( 00225 groupPair.second.getNode("GroupName").getValueAsString(), 00226 TableGroupKey(groupPair.second.getNode("GroupKey").getValueAsString())), 00227 TableGroupKey())); 00228 00229 std::cout << __COUT_HDR_FL__ << "Identified groups:" << std::endl; 00230 for(auto& group : groupSet) 00231 std::cout << __COUT_HDR_FL__ << group.first.first << " " << group.first.second 00232 << std::endl; 00233 std::cout << __COUT_HDR_FL__ << std::endl; 00234 std::cout << __COUT_HDR_FL__ << std::endl; 00235 00236 // return; 00237 //============================================================================== 00238 // prepare to manipulate directories 00239 std::string currentDir = getenv("ARTDAQ_DATABASE_URI"); 00240 00241 if(currentDir.find("filesystemdb://") != 0) 00242 { 00243 __SS__ << "filesystemdb:// was not found in $ARTDAQ_DATABASE_URI!" << std::endl; 00244 __COUT_ERR__ << "\n" << ss.str(); 00245 __SS_THROW__; 00246 } 00247 00248 currentDir = currentDir.substr(std::string("filesystemdb://").length()); 00249 while(currentDir.length() && 00250 currentDir[currentDir.length() - 1] == '/') // remove trailing '/'s 00251 currentDir = currentDir.substr(0, currentDir.length() - 1); 00252 std::string moveToDir = currentDir + "_" + nowTime; 00253 if(argc < 2) 00254 { 00255 __SS__ << ("Aborting move! Must at least give version argument to flatten to!") 00256 << std::endl; 00257 __COUT_ERR__ << "\n" << ss.str(); 00258 __SS_THROW__; 00259 } 00260 00261 if(pathToSwapIn != "") 00262 { 00263 DIR* dp; 00264 if((dp = opendir(pathToSwapIn.c_str())) == 0) 00265 { 00266 std::cout << __COUT_HDR_FL__ << "ERROR:(" << errno 00267 << "). Can't open directory: " << pathToSwapIn << std::endl; 00268 exit(0); 00269 } 00270 closedir(dp); 00271 } 00272 00273 // handle directory swap 00274 __COUT__ << "Moving current directory: \t" << currentDir << std::endl; 00275 __COUT__ << "\t... to: \t\t" << moveToDir << std::endl; 00276 // return; 00277 rename(currentDir.c_str(), moveToDir.c_str()); 00278 00279 if(pathToSwapIn != "") 00280 { 00281 __COUT__ << "Swapping in directory: \t" << pathToSwapIn << std::endl; 00282 __COUT__ << "\t.. to: \t\t" << currentDir << std::endl; 00283 rename(pathToSwapIn.c_str(), currentDir.c_str()); 00284 00285 // also swap in active groups file 00286 // check if original active file exists 00287 std::string activeGroupsFile = 00288 ConfigurationManager::ACTIVE_GROUPS_FILENAME + "." + thenTime; 00289 FILE* fp = fopen(activeGroupsFile.c_str(), "r"); 00290 if(fp) 00291 { 00292 __COUT__ << "Swapping active groups file: \t" << activeGroupsFile 00293 << std::endl; 00294 __COUT__ << "\t.. to: \t\t" << ConfigurationManager::ACTIVE_GROUPS_FILENAME 00295 << std::endl; 00296 rename(activeGroupsFile.c_str(), 00297 ConfigurationManager::ACTIVE_GROUPS_FILENAME.c_str()); 00298 } 00299 } 00300 00301 ConfigurationInterface* theInterface_ = ConfigurationInterface::getInstance( 00302 false); // true for File interface, false for artdaq database; 00303 TableView* cfgView; 00304 TableBase* config; 00305 00306 bool errDetected; 00307 std::string accumulateErrors = ""; 00308 int count = 0; 00309 00310 std::map<std::string /*name*/, TableVersion> memberMap; 00311 std::map<std::string /*name*/, std::string /*alias*/> groupAliases; 00312 std::string groupComment; 00313 std::string groupAuthor; 00314 std::string groupCreateTime; 00315 time_t groupCreateTime_t; 00316 TableBase* groupMetadataTable = cfgMgr->getMetadataTable(); 00317 00318 // don't do anything more if flatVersion is not persistent 00319 if(TableVersion(flatVersion).isInvalid() || 00320 TableVersion(flatVersion).isTemporaryVersion()) 00321 { 00322 __COUT__ << "\n\nflatVersion " << TableVersion(flatVersion) 00323 << " is an invalid or temporary version. Skipping to end!" << std::endl; 00324 goto CLEAN_UP; 00325 } 00326 00327 for(auto& groupPair : groupSet) 00328 { 00329 errDetected = false; 00330 00331 __COUT__ << "****************************" << std::endl; 00332 __COUT__ << "Loading members for " << groupPair.first.first << "(" 00333 << groupPair.first.second << ")" << std::endl; 00334 __COUT__ << "flatVersion = " << flatVersion << std::endl; 00335 00336 // handle directory swap BACK 00337 if(pathToSwapIn != "") 00338 { 00339 __COUT__ << "REVERT by Swapping back directory: \t" << currentDir 00340 << std::endl; 00341 __COUT__ << "\t.. to: \t\t" << pathToSwapIn << std::endl; 00342 if(rename(currentDir.c_str(), pathToSwapIn.c_str()) < 0) 00343 { 00344 __SS__ << "Problem!" << std::endl; 00345 __SS_THROW__; 00346 } 00347 } 00348 else if(count) // if not first time, move currentDir to temporarily holding area 00349 { 00350 __COUT__ << "REVERT by Moving directory: \t" << currentDir << std::endl; 00351 __COUT__ << "\t.. to temporary directory: \t\t" << (moveToDir + "_tmp") 00352 << std::endl; 00353 if(rename(currentDir.c_str(), (moveToDir + "_tmp").c_str()) < 0) 00354 { 00355 __SS__ << "Problem!" << std::endl; 00356 __SS_THROW__; 00357 } 00358 } 00359 00360 __COUT__ << "REVERT by Moving directory: \t" << moveToDir << std::endl; 00361 __COUT__ << "\t... to: \t\t" << currentDir << std::endl; 00362 if(rename(moveToDir.c_str(), currentDir.c_str()) < 0) 00363 { 00364 __SS__ << "Problem!" << std::endl; 00365 __SS_THROW__; 00366 } 00367 00368 //========================= 00369 // load group, group metadata, and tables from original DB 00370 try 00371 { 00372 cfgMgr->loadTableGroup(groupPair.first.first, 00373 groupPair.first.second, 00374 true /*doActivate*/, 00375 &memberMap /*memberMap*/, 00376 0 /*progressBar*/, 00377 &accumulateErrors, 00378 &groupComment, 00379 &groupAuthor, 00380 &groupCreateTime, 00381 false /*doNotLoadMember*/, 00382 0 /*groupTypeString*/, 00383 &groupAliases); 00384 } 00385 catch(std::runtime_error& e) 00386 { 00387 __COUT__ << "Error was caught loading members for " << groupPair.first.first 00388 << "(" << groupPair.first.second << ")" << std::endl; 00389 __COUT__ << e.what() << std::endl; 00390 errDetected = true; 00391 } 00392 catch(...) 00393 { 00394 __COUT__ << "Error was caught loading members for " << groupPair.first.first 00395 << "(" << groupPair.first.second << ")" << std::endl; 00396 errDetected = true; 00397 } 00398 00399 //========================= 00400 00401 // if(count == 2) break; 00402 00403 // handle directory swap 00404 __COUT__ << "Moving current directory: \t" << currentDir << std::endl; 00405 __COUT__ << "\t... to: \t\t" << moveToDir << std::endl; 00406 if(rename(currentDir.c_str(), moveToDir.c_str()) < 0) 00407 { 00408 __SS__ << "Problem!" << std::endl; 00409 __SS_THROW__; 00410 } 00411 00412 if(pathToSwapIn != "") 00413 { 00414 __COUT__ << "Swapping in directory: \t" << pathToSwapIn << std::endl; 00415 __COUT__ << "\t.. to: \t\t" << currentDir << std::endl; 00416 if(rename(pathToSwapIn.c_str(), currentDir.c_str()) < 0) 00417 { 00418 __SS__ << "Problem!" << std::endl; 00419 __SS_THROW__; 00420 } 00421 } 00422 else if(count) // if not first time, replace from temporarily holding area 00423 { 00424 __COUT__ << "Moving temporary directory: \t" << (moveToDir + "_tmp") 00425 << std::endl; 00426 __COUT__ << "\t.. to current directory: \t\t" << currentDir << std::endl; 00427 if(rename((moveToDir + "_tmp").c_str(), currentDir.c_str()) < 0) 00428 { 00429 __SS__ << "Problem!" << std::endl; 00430 __SS_THROW__; 00431 } 00432 } 00433 00434 // exit loop if any (loading) failure 00435 if(errDetected) 00436 { 00437 // goto CLEAN_UP; 00438 00439 // power on if group failed 00440 // and record error 00441 00442 groupErrors.insert( 00443 std::pair<std::pair<std::string, TableGroupKey>, std::string>( 00444 std::pair<std::string, TableGroupKey>(groupPair.first.first, 00445 groupPair.first.second), 00446 "Error caught loading the group.")); 00447 continue; 00448 } 00449 00450 //========================= 00451 // save group and its tables with new key and versions! 00452 try 00453 { 00454 // saving tables 00455 for(auto& memberPair : memberMap) 00456 { 00457 __COUT__ << memberPair.first << ":v" << memberPair.second << std::endl; 00458 00459 // check if table has already been modified by a previous group 00460 // (i.e. two groups using the same version of a table) 00461 if(modifiedTables.find(std::pair<std::string, TableVersion>( 00462 memberPair.first, memberPair.second)) != modifiedTables.end()) 00463 { 00464 __COUT__ << "Table was already modified!" << std::endl; 00465 memberPair.second = 00466 modifiedTables[std::pair<std::string, TableVersion>( 00467 memberPair.first, memberPair.second)]; 00468 __COUT__ << "\t to...\t" << memberPair.first << ":v" 00469 << memberPair.second << std::endl; 00470 continue; 00471 } 00472 00473 // change the version of the active view to flatVersion and save it 00474 config = cfgMgr->getTableByName(memberPair.first); 00475 cfgView = config->getViewP(); 00476 cfgView->setVersion(TableVersion(flatVersion)); 00477 theInterface_->saveActiveVersion(config); 00478 00479 // set it back for the table so that future groups can re-use cached 00480 // version 00481 cfgView->setVersion(memberPair.second); // IMPORTANT 00482 00483 // save new version to modifiedTables 00484 modifiedTables.insert( 00485 std::pair<std::pair<std::string, TableVersion>, TableVersion>( 00486 std::pair<std::string, TableVersion>(memberPair.first, 00487 memberPair.second), 00488 TableVersion(flatVersion))); 00489 00490 memberPair.second = flatVersion; // change version in the member map 00491 00492 __COUT__ << "\t to...\t" << memberPair.first << ":v" << memberPair.second 00493 << std::endl; 00494 } 00495 00496 // Note: this code copies actions in ConfigurationManagerRW::saveNewTableGroup 00497 00498 // add meta data 00499 __COUTV__(StringMacros::mapToString(groupAliases)); 00500 __COUTV__(groupComment); 00501 __COUTV__(groupAuthor); 00502 __COUTV__(groupCreateTime); 00503 sscanf(groupCreateTime.c_str(), "%ld", &groupCreateTime_t); 00504 __COUTV__(groupCreateTime_t); 00505 00506 // to compensate for unusual errors upstream, make sure the metadata table has 00507 // one row 00508 while(groupMetadataTable->getViewP()->getNumberOfRows() > 1) 00509 groupMetadataTable->getViewP()->deleteRow(0); 00510 if(groupMetadataTable->getViewP()->getNumberOfRows() == 0) 00511 groupMetadataTable->getViewP()->addRow(); 00512 00513 // columns are uid,comment,author,time 00514 // ConfigurationManager::METADATA_COL_ALIASES TODO 00515 groupMetadataTable->getViewP()->setValue( 00516 StringMacros::mapToString( 00517 groupAliases, "," /*primary delimiter*/, ":" /*secondary delimeter*/), 00518 0, 00519 ConfigurationManager::METADATA_COL_ALIASES); 00520 groupMetadataTable->getViewP()->setValue( 00521 groupComment, 0, ConfigurationManager::METADATA_COL_COMMENT); 00522 groupMetadataTable->getViewP()->setValue( 00523 groupAuthor, 0, ConfigurationManager::METADATA_COL_AUTHOR); 00524 groupMetadataTable->getViewP()->setValue( 00525 groupCreateTime_t, 0, ConfigurationManager::METADATA_COL_TIMESTAMP); 00526 00527 // set version of metadata table 00528 groupMetadataTable->getViewP()->setVersion(TableVersion(flatVersion)); 00529 theInterface_->saveActiveVersion(groupMetadataTable); 00530 00531 // force groupMetadataTable_ to be a member for the group 00532 memberMap[groupMetadataTable->getTableName()] = 00533 groupMetadataTable->getViewVersion(); 00534 00535 // memberMap should now consist of members with new flat version, so save 00536 // group 00537 theInterface_->saveTableGroup( 00538 memberMap, 00539 TableGroupKey::getFullGroupString(groupPair.first.first, 00540 TableGroupKey(flatVersion))); 00541 00542 // and modify groupSet and activeGroupKeys keys 00543 groupPair.second = TableGroupKey(flatVersion); 00544 00545 // if this is an active group, save key change 00546 if(activeGroupKeys.find(groupPair.first.first) != activeGroupKeys.end() && 00547 activeGroupKeys[groupPair.first.first].first == groupPair.first.second) 00548 activeGroupKeys[groupPair.first.first].second = 00549 TableGroupKey(flatVersion); 00550 } 00551 catch(std::runtime_error& e) 00552 { 00553 __COUT__ << "Error was caught saving group " << groupPair.first.first << " (" 00554 << groupPair.first.second << ") " << std::endl; 00555 __COUT__ << e.what() << std::endl; 00556 00557 groupErrors.insert( 00558 std::pair<std::pair<std::string, TableGroupKey>, std::string>( 00559 std::pair<std::string, TableGroupKey>(groupPair.first.first, 00560 groupPair.first.second), 00561 "Error caught saving the group.")); 00562 } 00563 catch(...) 00564 { 00565 __COUT__ << "Error was caught saving group " << groupPair.first.first << " (" 00566 << groupPair.first.second << ") " << std::endl; 00567 00568 groupErrors.insert( 00569 std::pair<std::pair<std::string, TableGroupKey>, std::string>( 00570 std::pair<std::string, TableGroupKey>(groupPair.first.first, 00571 groupPair.first.second), 00572 "Error caught saving the group.")); 00573 } 00574 //========================= 00575 00576 // increment flat version 00577 ++flatVersion; 00578 ++count; 00579 } 00580 00581 // record in readme for moveto 00582 { 00583 FILE* fp = fopen((moveToDir + "/README_otsdaq_flatten.txt").c_str(), "a"); 00584 if(!fp) 00585 __COUT__ << "\tError opening README file!" << std::endl; 00586 else 00587 { 00588 time_t rawtime; 00589 struct tm* timeinfo; 00590 char buffer[200]; 00591 00592 time(&rawtime); 00593 timeinfo = localtime(&rawtime); 00594 strftime(buffer, 200, "%b %d, %Y %I:%M%p %Z", timeinfo); 00595 00596 fprintf(fp, 00597 "This database was moved from...\n\t %s \nto...\n\t %s \nat this " 00598 "time \n\t %lu \t %s\n\n\n", 00599 currentDir.c_str(), 00600 moveToDir.c_str(), 00601 time(0), 00602 buffer); 00603 00604 fclose(fp); 00605 } 00606 } 00607 00608 // record in readme for swapin 00609 { 00610 FILE* fp = fopen((currentDir + "/README_otsdaq_flatten.txt").c_str(), "a"); 00611 00612 if(!fp) 00613 __COUT__ << "\tError opening README file!" << std::endl; 00614 else 00615 { 00616 time_t rawtime; 00617 struct tm* timeinfo; 00618 char buffer[200]; 00619 00620 time(&rawtime); 00621 timeinfo = localtime(&rawtime); 00622 strftime(buffer, 200, "%b %d, %Y %I:%M:%S%p %Z", timeinfo); 00623 00624 fprintf(fp, 00625 "This database was moved from...\t %s \t to...\t %s at this time \t " 00626 "%lu \t %s\n\n", 00627 pathToSwapIn.c_str(), 00628 currentDir.c_str(), 00629 time(0), 00630 buffer); 00631 fclose(fp); 00632 } 00633 } 00634 00635 // //print resulting all groups 00636 // 00637 // std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Groups:" << std::endl; 00638 // for(const auto &group: groupSet) 00639 // __COUT__<< group.first.first << ": " << 00640 // group.first.second << " => " << group.second << std::endl; 00641 // std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Groups end." << std::endl; 00642 // 00643 // 00644 // //print resulting active groups 00645 // 00646 // std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Active Groups:" << std::endl; 00647 // for(const auto &activeGroup: activeGroupKeys) 00648 // __COUT__<< activeGroup.first << ": " << 00649 // activeGroup.second.first << " => " << activeGroup.second.second << 00650 // std::endl; 00651 // 00652 // __COUT__<< activeBackboneGroupName << " is the " << 00653 // ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE << "." << std::endl; 00654 // std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Active Groups end." << 00655 // std::endl; 00656 00657 // reload the active backbone (using activeGroupKeys) 00658 // modify group aliases and table aliases properly based on groupSet and 00659 // modifiedTables save new backbone with flatVersion to new DB 00660 00661 if(activeBackboneGroupName == "") 00662 { 00663 __COUT__ << "No active Backbone table identified." << std::endl; 00664 goto CLEAN_UP; 00665 } 00666 00667 std::cout << "\n\n" 00668 << __COUT_HDR_FL__ 00669 << "Modifying the active Backbone table to reflect new table versions and " 00670 "group keys." 00671 << std::endl; 00672 00673 { 00674 cfgMgr->loadTableGroup(activeBackboneGroupName, 00675 activeGroupKeys[activeBackboneGroupName].second, 00676 true, 00677 &memberMap, 00678 0, 00679 &accumulateErrors); 00680 00681 // modify Group Aliases Table and Version Aliases Table to point 00682 // at DEFAULT and flatVersion respectively 00683 00684 const std::string groupAliasesName = 00685 ConfigurationManager::GROUP_ALIASES_TABLE_NAME; 00686 const std::string versionAliasesName = 00687 ConfigurationManager::VERSION_ALIASES_TABLE_NAME; 00688 00689 std::map<std::string, TableVersion> activeMap = cfgMgr->getActiveVersions(); 00690 00691 // modify Group Aliases Table 00692 if(activeMap.find(groupAliasesName) != activeMap.end()) 00693 { 00694 __COUT__ << "\n\nModifying " << groupAliasesName << std::endl; 00695 config = cfgMgr->getTableByName(groupAliasesName); 00696 cfgView = config->getViewP(); 00697 00698 unsigned int col1 = cfgView->findCol("GroupName"); 00699 unsigned int col2 = cfgView->findCol("GroupKey"); 00700 00701 // cfgView->print(); 00702 00703 // change all key entries found to the new key and delete rows for groups not 00704 // found 00705 bool found; 00706 for(unsigned int row = 0; row < cfgView->getNumberOfRows(); ++row) 00707 { 00708 found = false; 00709 for(const auto& group : groupSet) 00710 if(group.second.isInvalid()) 00711 continue; 00712 else if(cfgView->getDataView()[row][col1] == group.first.first && 00713 cfgView->getDataView()[row][col2] == 00714 group.first.second.toString()) 00715 { 00716 // found a matching group/key pair 00717 __COUT__ << "Changing row " << row << " for " 00718 << cfgView->getDataView()[row][col1] 00719 << " key=" << cfgView->getDataView()[row][col2] 00720 << " to NEW key=" << group.second << std::endl; 00721 cfgView->setValue(group.second.toString(), row, col2); 00722 found = true; 00723 break; 00724 } 00725 00726 if(!found) // delete row 00727 cfgView->deleteRow(row--); 00728 } 00729 // cfgView->print(); 00730 } 00731 00732 // modify Version Aliases Table 00733 if(activeMap.find(versionAliasesName) != activeMap.end()) 00734 { 00735 __COUT__ << "\n\nModifying " << versionAliasesName << std::endl; 00736 config = cfgMgr->getTableByName(versionAliasesName); 00737 cfgView = config->getViewP(); 00738 unsigned int col1 = cfgView->findCol("TableName"); 00739 unsigned int col2 = cfgView->findCol("Version"); 00740 00741 // change all version entries to the new version and delete rows with no match 00742 bool found; 00743 for(unsigned int row = 0; row < cfgView->getNumberOfRows(); ++row) 00744 { 00745 found = false; 00746 for(const auto& table : modifiedTables) 00747 if(cfgView->getDataView()[row][col1] == table.first.first && 00748 cfgView->getDataView()[row][col2] == table.first.second.toString()) 00749 { 00750 // found a matching group/key pair 00751 __COUT__ << "Changing row " << row << " for " 00752 << cfgView->getDataView()[row][col1] 00753 << " version=" << cfgView->getDataView()[row][col2] 00754 << " to NEW version=" << table.second << std::endl; 00755 cfgView->setValue(table.second.toString(), row, col2); 00756 found = true; 00757 break; 00758 } 00759 00760 if(!found) // delete row 00761 cfgView->deleteRow(row--); 00762 } 00763 } 00764 00765 // save new Group Aliases Table and Version Aliases Table 00766 00767 __COUT__ << groupAliasesName << ":v" << memberMap[groupAliasesName] << std::endl; 00768 // change the version of the active view to flatVersion and save it 00769 config = cfgMgr->getTableByName(groupAliasesName); 00770 cfgView = config->getViewP(); 00771 cfgView->setVersion(TableVersion(flatVersion)); 00772 theInterface_->saveActiveVersion(config); 00773 00774 memberMap[groupAliasesName] = flatVersion; // change version in the member map 00775 00776 __COUT__ << "\t to...\t" << groupAliasesName << ":v" 00777 << memberMap[groupAliasesName] << std::endl; 00778 00779 __COUT__ << versionAliasesName << ":v" << memberMap[versionAliasesName] 00780 << std::endl; 00781 // change the version of the active view to flatVersion and save it 00782 config = cfgMgr->getTableByName(versionAliasesName); 00783 cfgView = config->getViewP(); 00784 cfgView->setVersion(TableVersion(flatVersion)); 00785 theInterface_->saveActiveVersion(config); 00786 00787 memberMap[versionAliasesName] = flatVersion; // change version in the member map 00788 00789 __COUT__ << "\t to...\t" << versionAliasesName << ":v" 00790 << memberMap[versionAliasesName] << std::endl; 00791 00792 // memberMap should now consist of members with new flat version, so save 00793 theInterface_->saveTableGroup( 00794 memberMap, 00795 TableGroupKey::getFullGroupString(activeBackboneGroupName, 00796 TableGroupKey(flatVersion))); 00797 00798 activeGroupKeys[activeBackboneGroupName].second = TableGroupKey(flatVersion); 00799 00800 __COUT__ << "New to-be-active backbone group " << activeBackboneGroupName << ":v" 00801 << activeGroupKeys[activeBackboneGroupName].second << std::endl; 00802 } 00803 00804 // backup the file ConfigurationManager::ACTIVE_GROUPS_FILENAME with time 00805 // and change the ConfigurationManager::ACTIVE_GROUPS_FILENAME 00806 // to reflect new group names/keys 00807 00808 { 00809 std::cout << "\n\n" 00810 << __COUT_HDR_FL__ << "Manipulating the Active Groups file..." 00811 << std::endl; 00812 00813 // check if original active file exists 00814 FILE* fp = fopen(ConfigurationManager::ACTIVE_GROUPS_FILENAME.c_str(), "r"); 00815 if(!fp) 00816 { 00817 __SS__ << "Original active groups file '" 00818 << ConfigurationManager::ACTIVE_GROUPS_FILENAME << "' not found." 00819 << std::endl; 00820 goto CLEAN_UP; 00821 } 00822 00823 __COUT__ << "Backing up file: " << ConfigurationManager::ACTIVE_GROUPS_FILENAME 00824 << std::endl; 00825 00826 fclose(fp); 00827 00828 std::string renameFile = 00829 ConfigurationManager::ACTIVE_GROUPS_FILENAME + "." + nowTime; 00830 rename(ConfigurationManager::ACTIVE_GROUPS_FILENAME.c_str(), renameFile.c_str()); 00831 00832 __COUT__ << "Backup file name: " << renameFile << std::endl; 00833 00834 TableGroupKey *theConfigurationTableGroupKey_, *theContextTableGroupKey_, 00835 *theBackboneTableGroupKey_, *theIterateTableGroupKey_; 00836 std::string theConfigurationTableGroup_, theContextTableGroup_, 00837 theBackboneTableGroup_, theIterateTableGroup_; 00838 00839 theConfigurationTableGroup_ = activeConfigGroupName; 00840 theConfigurationTableGroupKey_ = &(activeGroupKeys[activeConfigGroupName].second); 00841 00842 theContextTableGroup_ = activeContextGroupName; 00843 theContextTableGroupKey_ = &(activeGroupKeys[activeContextGroupName].second); 00844 00845 theBackboneTableGroup_ = activeBackboneGroupName; 00846 theBackboneTableGroupKey_ = &(activeGroupKeys[activeBackboneGroupName].second); 00847 00848 theIterateTableGroup_ = activeIterateGroupName; 00849 theIterateTableGroupKey_ = &(activeGroupKeys[activeIterateGroupName].second); 00850 00851 // the following is copied from ConfigurationManagerRW::activateTableGroup 00852 { 00853 __COUT__ << "Updating persistent active groups to " 00854 << ConfigurationManager::ACTIVE_GROUPS_FILENAME << " ..." 00855 << std::endl; 00856 00857 std::string fn = ConfigurationManager::ACTIVE_GROUPS_FILENAME; 00858 FILE* fp = fopen(fn.c_str(), "w"); 00859 if(!fp) 00860 return; 00861 00862 fprintf(fp, "%s\n", theContextTableGroup_.c_str()); 00863 fprintf(fp, 00864 "%s\n", 00865 theContextTableGroupKey_ 00866 ? theContextTableGroupKey_->toString().c_str() 00867 : "-1"); 00868 fprintf(fp, "%s\n", theBackboneTableGroup_.c_str()); 00869 fprintf(fp, 00870 "%s\n", 00871 theBackboneTableGroupKey_ 00872 ? theBackboneTableGroupKey_->toString().c_str() 00873 : "-1"); 00874 fprintf(fp, "%s\n", theConfigurationTableGroup_.c_str()); 00875 fprintf(fp, 00876 "%s\n", 00877 theConfigurationTableGroupKey_ 00878 ? theConfigurationTableGroupKey_->toString().c_str() 00879 : "-1"); 00880 fprintf(fp, "%s\n", theIterateTableGroup_.c_str()); 00881 fprintf(fp, 00882 "%s\n", 00883 theIterateTableGroupKey_ 00884 ? theIterateTableGroupKey_->toString().c_str() 00885 : "-1"); 00886 fclose(fp); 00887 } 00888 } 00889 00890 // print resulting all groups 00891 00892 std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Groups:" << std::endl; 00893 for(const auto& group : groupSet) 00894 __COUT__ << "\t" << group.first.first << ": " << group.first.second << " => " 00895 << group.second << std::endl; 00896 std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Groups end." << std::endl; 00897 00898 // print resulting active groups 00899 00900 std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Active Groups:" << std::endl; 00901 for(const auto& activeGroup : activeGroupKeys) 00902 __COUT__ << "\t" << activeGroup.first << ": " << activeGroup.second.first 00903 << " => " << activeGroup.second.second << std::endl; 00904 00905 __COUT__ << activeBackboneGroupName << " is the " 00906 << ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE << "." << std::endl; 00907 std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Active Groups end." << std::endl; 00908 00909 CLEAN_UP: 00910 //============================================================================== 00911 std::cout << "\n\n" 00912 << __COUT_HDR_FL__ << "End of Flattening Active Table Groups!\n\n\n" 00913 << std::endl; 00914 00915 __COUT__ << "****************************" << std::endl; 00916 __COUT__ << "There were " << groupSet.size() << " groups considered, and there were " 00917 << groupErrors.size() << " errors found handling those groups." << std::endl; 00918 __COUT__ << "The following errors were found handling the groups:" << std::endl; 00919 for(auto& groupErr : groupErrors) 00920 __COUT__ << "\t" << groupErr.first.first << " " << groupErr.first.second << ": \t" 00921 << groupErr.second << std::endl; 00922 __COUT__ << "End of errors.\n\n" << std::endl; 00923 00924 __COUT__ << "Run the following to return to your previous database structure:" 00925 << std::endl; 00926 __COUT__ << "\t otsdaq_flatten_system_aliases -1 " << moveToDir << "\n\n" 00927 << std::endl; 00928 00929 return; 00930 } 00931 00932 int main(int argc, char* argv[]) 00933 { 00934 FlattenActiveSystemAliasTableGroups(argc, argv); 00935 return 0; 00936 } 00937 // BOOST_AUTO_TEST_SUITE_END()