$treeview $search $mathjax $extrastylesheet
otsdaq
v2_03_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #include "otsdaq-core/ConfigurationInterface/ConfigurationManagerRW.h" 00002 00003 // backbone includes 00004 //#include "otsdaq-core/TablePluginDataFormats/ConfigurationAliases.h" 00005 //#include "otsdaq-core/TablePluginDataFormats/Configurations.h" 00006 //#include "otsdaq-core/TablePluginDataFormats/DefaultConfigurations.h" 00007 //#include "otsdaq-core/TablePluginDataFormats/VersionAliases.h" 00008 00009 //#include "otsdaq-core/ConfigurationInterface/ConfigurationInterface.h"//All configurable 00010 // objects are included here 00011 00012 // 00013 //#include "otsdaq-core/TablePluginDataFormats/DetectorTable.h" 00014 //#include "otsdaq-core/TablePluginDataFormats/MaskTable.h" 00015 //#include "otsdaq-core/TablePluginDataFormats/DetectorToFETable.h" 00016 // 00017 00018 //#include "otsdaq-core/ConfigurationInterface/DACStream.h" 00019 //#include "otsdaq-core/ConfigurationDataFormats/TableGroupKey.h" 00020 // 00021 //#include "otsdaq-core/ConfigurationInterface/FileConfigurationInterface.h" 00022 // 00023 //#include <cassert> 00024 00025 #include <dirent.h> 00026 00027 using namespace ots; 00028 00029 #undef __MF_SUBJECT__ 00030 #define __MF_SUBJECT__ "ConfigurationManagerRW" 00031 00032 #define TABLE_INFO_PATH std::string(getenv("TABLE_INFO_PATH")) + "/" 00033 #define TABLE_INFO_EXT "Info.xml" 00034 00035 #define CORE_TABLE_INFO_FILENAME \ 00036 ((getenv("SERVICE_DATA_PATH") == NULL) \ 00037 ? (std::string(getenv("USER_DATA")) + "/ServiceData") \ 00038 : (std::string(getenv("SERVICE_DATA_PATH")))) + \ 00039 "/CoreTableInfoNames.dat" 00040 00041 //============================================================================== 00042 // ConfigurationManagerRW 00043 ConfigurationManagerRW::ConfigurationManagerRW(std::string username) 00044 : ConfigurationManager(username) // for use as author of new views 00045 { 00046 __COUT__ << "Using Config Mgr with Write Access! (for " << username << ")" << __E__; 00047 00048 // FIXME only necessarily temporarily while Lore is still using fileSystem xml 00049 theInterface_ = 00050 ConfigurationInterface::getInstance(false); // false to use artdaq DB 00051 // FIXME -- can delete this change of 00052 // interface once RW and regular use 00053 // same interface instance 00054 00055 //========================= 00056 // dump names of core tables (so UpdateOTS.sh can copy core tables for user) 00057 // only if table does not exist 00058 { 00059 const std::set<std::string>& contextMemberNames = getContextMemberNames(); 00060 const std::set<std::string>& backboneMemberNames = getBackboneMemberNames(); 00061 const std::set<std::string>& iterateMemberNames = getIterateMemberNames(); 00062 00063 FILE* fp = fopen((CORE_TABLE_INFO_FILENAME).c_str(), "r"); 00064 00065 __COUT__ << "Updating core tables table..." << __E__; 00066 00067 if(fp) // check for all core table names in file, and force their presence 00068 { 00069 std::vector<unsigned int> foundVector; 00070 char line[100]; 00071 for(const auto& name : contextMemberNames) 00072 { 00073 foundVector.push_back(false); 00074 rewind(fp); 00075 while(fgets(line, 100, fp)) 00076 { 00077 if(strlen(line) < 1) 00078 continue; 00079 line[strlen(line) - 1] = '\0'; // remove endline 00080 if(strcmp(line, ("ContextGroup/" + name).c_str()) == 0) // is match? 00081 { 00082 foundVector.back() = true; 00083 //__COUTV__(name); 00084 break; 00085 } 00086 } 00087 } 00088 00089 for(const auto& name : backboneMemberNames) 00090 { 00091 foundVector.push_back(false); 00092 rewind(fp); 00093 while(fgets(line, 100, fp)) 00094 { 00095 if(strlen(line) < 1) 00096 continue; 00097 line[strlen(line) - 1] = '\0'; // remove endline 00098 if(strcmp(line, ("BackboneGroup/" + name).c_str()) == 0) // is match? 00099 { 00100 foundVector.back() = true; 00101 //__COUTV__(name); 00102 break; 00103 } 00104 } 00105 } 00106 00107 for(const auto& name : iterateMemberNames) 00108 { 00109 foundVector.push_back(false); 00110 rewind(fp); 00111 while(fgets(line, 100, fp)) 00112 { 00113 if(strlen(line) < 1) 00114 continue; 00115 line[strlen(line) - 1] = '\0'; // remove endline 00116 if(strcmp(line, ("IterateGroup/" + name).c_str()) == 0) // is match? 00117 { 00118 foundVector.back() = true; 00119 //__COUTV__(name); 00120 break; 00121 } 00122 } 00123 } 00124 00125 fclose(fp); 00126 00127 // for(const auto &found:foundVector) 00128 // __COUTV__(found); 00129 00130 // open file for appending the missing names 00131 fp = fopen((CORE_TABLE_INFO_FILENAME).c_str(), "a"); 00132 if(fp) 00133 { 00134 unsigned int i = 0; 00135 for(const auto& name : contextMemberNames) 00136 { 00137 if(!foundVector[i]) 00138 fprintf(fp, "ContextGroup/%s\n", name.c_str()); 00139 00140 ++i; 00141 } 00142 for(const auto& name : backboneMemberNames) 00143 { 00144 if(!foundVector[i]) 00145 fprintf(fp, "BackboneGroup/%s\n", name.c_str()); 00146 00147 ++i; 00148 } 00149 for(const auto& name : iterateMemberNames) 00150 { 00151 if(!foundVector[i]) 00152 fprintf(fp, "IterateGroup/%s\n", name.c_str()); 00153 00154 ++i; 00155 } 00156 fclose(fp); 00157 } 00158 else 00159 { 00160 __SS__ << "Failed to open core table info file for appending: " 00161 << CORE_TABLE_INFO_FILENAME << __E__; 00162 __SS_THROW__; 00163 } 00164 } 00165 else 00166 { 00167 fp = fopen((CORE_TABLE_INFO_FILENAME).c_str(), "w"); 00168 if(fp) 00169 { 00170 for(const auto& name : contextMemberNames) 00171 fprintf(fp, "ContextGroup/%s\n", name.c_str()); 00172 for(const auto& name : backboneMemberNames) 00173 fprintf(fp, "BackboneGroup/%s\n", name.c_str()); 00174 for(const auto& name : iterateMemberNames) 00175 fprintf(fp, "IterateGroup/%s\n", name.c_str()); 00176 fclose(fp); 00177 } 00178 else 00179 { 00180 __SS__ << "Failed to open core table info file: " 00181 << CORE_TABLE_INFO_FILENAME << __E__; 00182 __SS_THROW__; 00183 } 00184 } 00185 } // end dump names of core tables 00186 } // end constructor 00187 00188 //============================================================================== 00189 // getAllTableInfo() 00190 // Used by ConfigurationGUISupervisor to get all the info for the existing configurations 00191 // 00192 // if(accumulatedErrors) 00193 // this implies allowing column errors and accumulating such errors in given string 00194 const std::map<std::string, TableInfo>& ConfigurationManagerRW::getAllTableInfo( 00195 bool refresh, std::string* accumulatedErrors, const std::string& errorFilterName) 00196 { 00197 // allTableInfo_ is container to be returned 00198 00199 if(accumulatedErrors) 00200 *accumulatedErrors = ""; 00201 00202 if(!refresh) 00203 return allTableInfo_; 00204 00205 // else refresh! 00206 allTableInfo_.clear(); 00207 allGroupInfo_.clear(); 00208 00209 TableBase* table; 00210 00211 // existing configurations are defined by which infos are in TABLE_INFO_PATH 00212 // can test that the class exists based on this 00213 // and then which versions 00214 __COUT__ << "======================================================== " 00215 "getAllTableInfo start" 00216 << __E__; 00217 __COUT__ << "Refreshing all! Extracting list of tables..." << __E__; 00218 DIR* pDIR; 00219 struct dirent* entry; 00220 std::string path = TABLE_INFO_PATH; 00221 char fileExt[] = TABLE_INFO_EXT; 00222 const unsigned char MIN_TABLE_NAME_SZ = 3; 00223 if((pDIR = opendir(path.c_str())) != 0) 00224 { 00225 while((entry = readdir(pDIR)) != 0) 00226 { 00227 // enforce table name length 00228 if(strlen(entry->d_name) < strlen(fileExt) + MIN_TABLE_NAME_SZ) 00229 continue; 00230 00231 // find file names with correct file extenstion 00232 if(strcmp(&(entry->d_name[strlen(entry->d_name) - strlen(fileExt)]), 00233 fileExt) != 0) 00234 continue; // skip different extentions 00235 00236 entry->d_name[strlen(entry->d_name) - strlen(fileExt)] = 00237 '\0'; // remove file extension to get table name 00238 00239 //__COUT__ << entry->d_name << __E__; 00240 00241 // 0 will force the creation of new instance (and reload from Info) 00242 table = 0; 00243 00244 try // only add valid table instances to maps 00245 { 00246 theInterface_->get(table, entry->d_name, 0, 0, 00247 true); // dont fill 00248 } 00249 catch(cet::exception) 00250 { 00251 if(table) 00252 delete table; 00253 table = 0; 00254 00255 __COUT__ << "Skipping! No valid class found for... " << entry->d_name 00256 << "\n"; 00257 continue; 00258 } 00259 catch(std::runtime_error& e) 00260 { 00261 if(table) 00262 delete table; 00263 table = 0; 00264 00265 __COUT__ << "Skipping! No valid class found for... " << entry->d_name 00266 << "\n"; 00267 __COUT__ << "Error: " << e.what() << __E__; 00268 00269 // for a runtime_error, it is likely that columns are the problem 00270 // the Table Editor needs to still fix these.. so attempt to 00271 // proceed. 00272 if(accumulatedErrors) 00273 { 00274 if(errorFilterName == "" || errorFilterName == entry->d_name) 00275 { 00276 *accumulatedErrors += std::string("\nIn table '") + 00277 entry->d_name + "'..." + 00278 e.what(); // global accumulate 00279 00280 __SS__ << "Attempting to allow illegal columns!" << __E__; 00281 *accumulatedErrors += ss.str(); 00282 } 00283 00284 // attempt to recover and build a mock-up 00285 __COUT__ << "Attempting to allow illegal columns!" << __E__; 00286 00287 std::string returnedAccumulatedErrors; 00288 try 00289 { 00290 // table = new TableBase(entry->d_name, 00291 // &returnedAccumulatedErrors); 00292 table = new TableBase(entry->d_name, &returnedAccumulatedErrors); 00293 } 00294 catch(...) 00295 { 00296 __COUT__ 00297 << "Skipping! Allowing illegal columns didn't work either... " 00298 << entry->d_name << "\n"; 00299 continue; 00300 } 00301 __COUT__ << "Error (but allowed): " << returnedAccumulatedErrors 00302 << __E__; 00303 00304 if(errorFilterName == "" || errorFilterName == entry->d_name) 00305 *accumulatedErrors += 00306 std::string("\nIn table '") + entry->d_name + "'..." + 00307 returnedAccumulatedErrors; // global accumulate 00308 } 00309 else 00310 continue; 00311 } 00312 00313 //__COUT__ << "Instance created: " << entry->d_name << "\n"; //found! 00314 00315 if(nameToTableMap_[entry->d_name]) // handle if instance existed 00316 { 00317 // copy the temporary versions! (or else all is lost) 00318 std::set<TableVersion> versions = 00319 nameToTableMap_[entry->d_name]->getStoredVersions(); 00320 for(auto& version : versions) 00321 if(version.isTemporaryVersion()) 00322 { 00323 //__COUT__ << "copying tmp = " << version << __E__; 00324 00325 try // do NOT let TableView::init() throw here 00326 { 00327 nameToTableMap_[entry->d_name]->setActiveView(version); 00328 table->copyView( // this calls TableView::init() 00329 nameToTableMap_[entry->d_name]->getView(), 00330 version, 00331 username_); 00332 } 00333 catch(...) // do NOT let invalid temporary version throw at this 00334 // point 00335 { 00336 } // just trust configurationBase throws out the failed version 00337 } 00338 //__COUT__ << "deleting: " << entry->d_name << "\n"; //found! 00339 delete nameToTableMap_[entry->d_name]; 00340 nameToTableMap_[entry->d_name] = 0; 00341 } 00342 00343 nameToTableMap_[entry->d_name] = table; 00344 00345 allTableInfo_[entry->d_name].tablePtr_ = table; 00346 allTableInfo_[entry->d_name].versions_ = theInterface_->getVersions(table); 00347 00348 // also add any existing temporary versions to all table info 00349 // because the interface wont find those versions 00350 std::set<TableVersion> versions = 00351 nameToTableMap_[entry->d_name]->getStoredVersions(); 00352 for(auto& version : versions) 00353 if(version.isTemporaryVersion()) 00354 { 00355 //__COUT__ << "surviving tmp = " << version << __E__; 00356 allTableInfo_[entry->d_name].versions_.emplace(version); 00357 } 00358 } 00359 closedir(pDIR); 00360 } 00361 __COUT__ << "Extracting list of tables complete" << __E__; 00362 00363 // call init to load active versions by default 00364 init(accumulatedErrors); 00365 00366 __COUT__ 00367 << "======================================================== getAllTableInfo end" 00368 << __E__; 00369 00370 // get Group Info too! 00371 try 00372 { 00373 // build allGroupInfo_ for the ConfigurationManagerRW 00374 00375 std::set<std::string /*name*/> tableGroups = 00376 theInterface_->getAllTableGroupNames(); 00377 __COUT__ << "Number of Groups: " << tableGroups.size() << __E__; 00378 00379 TableGroupKey key; 00380 std::string name; 00381 for(const auto& fullName : tableGroups) 00382 { 00383 TableGroupKey::getGroupNameAndKey(fullName, name, key); 00384 cacheGroupKey(name, key); 00385 } 00386 00387 // for each group get member map & comment, author, time, and type for latest key 00388 for(auto& groupInfo : allGroupInfo_) 00389 { 00390 try 00391 { 00392 loadTableGroup(groupInfo.first /*groupName*/, 00393 groupInfo.second.getLatestKey(), 00394 false /*doActivate*/, 00395 &groupInfo.second.latestKeyMemberMap_ /*groupMembers*/, 00396 0 /*progressBar*/, 00397 0 /*accumulateErrors*/, 00398 &groupInfo.second.latestKeyGroupComment_, 00399 &groupInfo.second.latestKeyGroupAuthor_, 00400 &groupInfo.second.latestKeyGroupCreationTime_, 00401 true /*doNotLoadMember*/, 00402 &groupInfo.second.latestKeyGroupTypeString_); 00403 } 00404 catch(...) 00405 { 00406 __COUT_WARN__ 00407 << "Error occurred loading latest group info into cache for '" 00408 << groupInfo.first << "'..." << __E__; 00409 groupInfo.second.latestKeyGroupComment_ = "UNKNOWN"; 00410 groupInfo.second.latestKeyGroupAuthor_ = "UNKNOWN"; 00411 groupInfo.second.latestKeyGroupCreationTime_ = "0"; 00412 groupInfo.second.latestKeyGroupTypeString_ = "UNKNOWN"; 00413 } 00414 } // end group info loop 00415 } // end get group info 00416 catch(const std::runtime_error& e) 00417 { 00418 __SS__ << "A fatal error occurred reading the info for all table groups. Error: " 00419 << e.what() << __E__; 00420 __COUT_ERR__ << "\n" << ss.str(); 00421 if(accumulatedErrors) 00422 *accumulatedErrors += ss.str(); 00423 else 00424 throw; 00425 } 00426 catch(...) 00427 { 00428 __SS__ << "An unknown fatal error occurred reading the info for all table groups." 00429 << __E__; 00430 __COUT_ERR__ << "\n" << ss.str(); 00431 if(accumulatedErrors) 00432 *accumulatedErrors += ss.str(); 00433 else 00434 throw; 00435 } 00436 00437 return allTableInfo_; 00438 } // end getAllTableInfo 00439 00440 //============================================================================== 00441 // getVersionAliases() 00442 // get version aliases organized by table, for currently active backbone tables 00443 // add scratch versions to the alias map returned by ConfigurationManager 00444 std::map<std::string /*table name*/, 00445 std::map<std::string /*version alias*/, TableVersion /*aliased version*/> > 00446 ConfigurationManagerRW::getVersionAliases(void) const 00447 { 00448 //__COUT__ << "getVersionAliases()" << __E__; 00449 std::map<std::string /*table name*/, 00450 std::map<std::string /*version alias*/, TableVersion /*aliased version*/> > 00451 retMap = ConfigurationManager::getVersionAliases(); 00452 00453 // always have scratch alias for each table that has a scratch version 00454 // overwrite map entry if necessary 00455 if(!ConfigurationInterface::isVersionTrackingEnabled()) 00456 for(const auto& tableInfo : allTableInfo_) 00457 for(const auto& version : tableInfo.second.versions_) 00458 if(version.isScratchVersion()) 00459 retMap[tableInfo.first][ConfigurationManager::SCRATCH_VERSION_ALIAS] = 00460 TableVersion(TableVersion::SCRATCH); 00461 00462 return retMap; 00463 } // end getVersionAliases() 00464 00465 //============================================================================== 00466 // setActiveGlobalConfiguration 00467 // load table group and activate 00468 // deactivates previous table group of same type if necessary 00469 void ConfigurationManagerRW::activateTableGroup(const std::string& configGroupName, 00470 TableGroupKey configGroupKey, 00471 std::string* accumulatedTreeErrors) 00472 { 00473 loadTableGroup(configGroupName, 00474 configGroupKey, 00475 true, // loads and activates 00476 0, // no members needed 00477 0, // no progress bar 00478 accumulatedTreeErrors); // accumulate warnings or not 00479 00480 if(accumulatedTreeErrors && *accumulatedTreeErrors != "") 00481 { 00482 __COUT_ERR__ << "Errors were accumulated so de-activating group: " 00483 << configGroupName << " (" << configGroupKey << ")" << __E__; 00484 try // just in case any lingering pieces, lets deactivate 00485 { 00486 destroyTableGroup(configGroupName, true); 00487 } 00488 catch(...) 00489 { 00490 } 00491 } 00492 00493 __COUT_INFO__ << "Updating persistent active groups to " 00494 << ConfigurationManager::ACTIVE_GROUPS_FILENAME << " ..." << __E__; 00495 __MOUT_INFO__ << "Updating persistent active groups to " 00496 << ConfigurationManager::ACTIVE_GROUPS_FILENAME << " ..." << __E__; 00497 00498 std::string fn = ConfigurationManager::ACTIVE_GROUPS_FILENAME; 00499 FILE* fp = fopen(fn.c_str(), "w"); 00500 if(!fp) 00501 { 00502 __SS__ << "Fatal Error! Unable to open the file " 00503 << ConfigurationManager::ACTIVE_GROUPS_FILENAME 00504 << " for editing! Is there a permissions problem?" << __E__; 00505 __COUT_ERR__ << ss.str(); 00506 __SS_THROW__; 00507 return; 00508 } 00509 00510 __MCOUT_INFO__("Active Context table group: " 00511 << theContextTableGroup_ << "(" 00512 << (theContextTableGroupKey_ 00513 ? theContextTableGroupKey_->toString().c_str() 00514 : "-1") 00515 << ")" << __E__); 00516 __MCOUT_INFO__("Active Backbone table group: " 00517 << theBackboneTableGroup_ << "(" 00518 << (theBackboneTableGroupKey_ 00519 ? theBackboneTableGroupKey_->toString().c_str() 00520 : "-1") 00521 << ")" << __E__); 00522 __MCOUT_INFO__("Active Iterate table group: " 00523 << theIterateTableGroup_ << "(" 00524 << (theIterateTableGroupKey_ 00525 ? theIterateTableGroupKey_->toString().c_str() 00526 : "-1") 00527 << ")" << __E__); 00528 __MCOUT_INFO__("Active Configuration table group: " 00529 << theConfigurationTableGroup_ << "(" 00530 << (theConfigurationTableGroupKey_ 00531 ? theConfigurationTableGroupKey_->toString().c_str() 00532 : "-1") 00533 << ")" << __E__); 00534 00535 fprintf(fp, "%s\n", theContextTableGroup_.c_str()); 00536 fprintf( 00537 fp, 00538 "%s\n", 00539 theContextTableGroupKey_ ? theContextTableGroupKey_->toString().c_str() : "-1"); 00540 fprintf(fp, "%s\n", theBackboneTableGroup_.c_str()); 00541 fprintf( 00542 fp, 00543 "%s\n", 00544 theBackboneTableGroupKey_ ? theBackboneTableGroupKey_->toString().c_str() : "-1"); 00545 fprintf(fp, "%s\n", theIterateTableGroup_.c_str()); 00546 fprintf( 00547 fp, 00548 "%s\n", 00549 theIterateTableGroupKey_ ? theIterateTableGroupKey_->toString().c_str() : "-1"); 00550 fprintf(fp, "%s\n", theConfigurationTableGroup_.c_str()); 00551 fprintf(fp, 00552 "%s\n", 00553 theConfigurationTableGroupKey_ 00554 ? theConfigurationTableGroupKey_->toString().c_str() 00555 : "-1"); 00556 fclose(fp); 00557 } 00558 00559 //============================================================================== 00560 // createTemporaryBackboneView 00561 // sourceViewVersion of INVALID is from MockUp, else from valid view version 00562 // returns temporary version number (which is always negative) 00563 TableVersion ConfigurationManagerRW::createTemporaryBackboneView( 00564 TableVersion sourceViewVersion) 00565 { 00566 __COUT_INFO__ << "Creating temporary backbone view from version " << sourceViewVersion 00567 << __E__; 00568 00569 // find common available temporary version among backbone members 00570 TableVersion tmpVersion = 00571 TableVersion::getNextTemporaryVersion(); // get the default temporary version 00572 TableVersion retTmpVersion; 00573 auto backboneMemberNames = ConfigurationManager::getBackboneMemberNames(); 00574 for(auto& name : backboneMemberNames) 00575 { 00576 retTmpVersion = 00577 ConfigurationManager::getTableByName(name)->getNextTemporaryVersion(); 00578 if(retTmpVersion < tmpVersion) 00579 tmpVersion = retTmpVersion; 00580 } 00581 00582 __COUT__ << "Common temporary backbone version found as " << tmpVersion << __E__; 00583 00584 // create temporary views from source version to destination temporary version 00585 for(auto& name : backboneMemberNames) 00586 { 00587 retTmpVersion = 00588 getTableByName(name)->createTemporaryView(sourceViewVersion, tmpVersion); 00589 if(retTmpVersion != tmpVersion) 00590 { 00591 __SS__ << "Failure! Temporary view requested was " << tmpVersion 00592 << ". Mismatched temporary view created: " << retTmpVersion << __E__; 00593 __COUT_ERR__ << ss.str(); 00594 __SS_THROW__; 00595 } 00596 } 00597 00598 return tmpVersion; 00599 } 00600 00601 //============================================================================== 00602 TableBase* ConfigurationManagerRW::getTableByName(const std::string& tableName) 00603 { 00604 if(nameToTableMap_.find(tableName) == nameToTableMap_.end()) 00605 { 00606 __SS__ << "Table not found with name: " << tableName << __E__; 00607 size_t f; 00608 if((f = tableName.find(' ')) != std::string::npos) 00609 ss << "There was a space character found in the table name needle at " 00610 "position " 00611 << f << " in the string (was this intended?). " << __E__; 00612 __COUT_ERR__ << "\n" << ss.str(); 00613 __SS_THROW__; 00614 } 00615 return nameToTableMap_[tableName]; 00616 } 00617 00618 //============================================================================== 00619 // getVersionedTableByName 00620 // Used by table GUI to load a particular table-version pair as the active version. 00621 // This table instance must already exist and be owned by ConfigurationManager. 00622 // return null pointer on failure, on success return table pointer. 00623 TableBase* ConfigurationManagerRW::getVersionedTableByName(const std::string& tableName, 00624 TableVersion version, 00625 bool looseColumnMatching) 00626 { 00627 auto it = nameToTableMap_.find(tableName); 00628 if(it == nameToTableMap_.end()) 00629 { 00630 __SS__ << "\nCan not find table named '" << tableName 00631 << "'\n\n\n\nYou need to load the table before it can be used." 00632 << "It probably is missing from the member list of the Table " 00633 "Group that was loaded?\n\n\n\n\n" 00634 << __E__; 00635 __SS_THROW__; 00636 } 00637 TableBase* table = it->second; 00638 theInterface_->get(table, 00639 tableName, 00640 0, 00641 0, 00642 false, // fill w/version 00643 version, 00644 false, // do not reset 00645 looseColumnMatching); 00646 return table; 00647 } 00648 00649 //============================================================================== 00650 // saveNewTable 00651 // saves version, makes the new version the active version, and returns new version 00652 TableVersion ConfigurationManagerRW::saveNewTable(const std::string& tableName, 00653 TableVersion temporaryVersion, 00654 bool makeTemporary) //, 00655 // bool saveToScratchVersion) 00656 { 00657 TableVersion newVersion(temporaryVersion); 00658 00659 // set author of version 00660 TableBase* table = getTableByName(tableName); 00661 table->getTemporaryView(temporaryVersion)->setAuthor(username_); 00662 // NOTE: somehow? author is assigned to permanent versions when saved to DBI? 00663 00664 if(!makeTemporary) // saveNewVersion makes the new version the active version 00665 newVersion = theInterface_->saveNewVersion(table, temporaryVersion); 00666 else // make the temporary version active 00667 table->setActiveView(newVersion); 00668 00669 // if there is a problem, try to recover 00670 while(!makeTemporary && !newVersion.isScratchVersion() && 00671 allTableInfo_[tableName].versions_.find(newVersion) != 00672 allTableInfo_[tableName].versions_.end()) 00673 { 00674 __COUT_ERR__ << "What happenened!?? ERROR::: new persistent version v" 00675 << newVersion 00676 << " already exists!? How is it possible? Retrace your steps and " 00677 "tell an admin." 00678 << __E__; 00679 00680 // create a new temporary version of the target view 00681 temporaryVersion = table->createTemporaryView(newVersion); 00682 00683 if(newVersion.isTemporaryVersion()) 00684 newVersion = temporaryVersion; 00685 else 00686 newVersion = TableVersion::getNextVersion(newVersion); 00687 00688 __COUT_WARN__ << "Attempting to recover and use v" << newVersion << __E__; 00689 00690 if(!makeTemporary) // saveNewVersion makes the new version the active version 00691 newVersion = 00692 theInterface_->saveNewVersion(table, temporaryVersion, newVersion); 00693 else // make the temporary version active 00694 table->setActiveView(newVersion); 00695 } 00696 00697 if(newVersion.isInvalid()) 00698 { 00699 __SS__ << "Something went wrong saving the new version v" << newVersion 00700 << ". What happened?! (duplicates? database error?)" << __E__; 00701 __COUT_ERR__ << "\n" << ss.str(); 00702 __SS_THROW__; 00703 } 00704 00705 // update allTableInfo_ with the new version 00706 allTableInfo_[tableName].versions_.insert(newVersion); 00707 00708 __COUT__ << "New version added to info " << newVersion << __E__; 00709 00710 return newVersion; 00711 } 00712 00713 //============================================================================== 00714 // eraseTemporaryVersion 00715 // if version is invalid then erases ALL temporary versions 00716 // 00717 // maintains allTableInfo_ also while erasing 00718 void ConfigurationManagerRW::eraseTemporaryVersion(const std::string& tableName, 00719 TableVersion targetVersion) 00720 { 00721 TableBase* table = getTableByName(tableName); 00722 00723 table->trimTemporary(targetVersion); 00724 00725 // if allTableInfo_ is not setup, then done 00726 if(allTableInfo_.find(tableName) == allTableInfo_.end()) 00727 return; 00728 // else cleanup table info 00729 00730 if(targetVersion.isInvalid()) 00731 { 00732 // erase all temporary versions! 00733 for(auto it = allTableInfo_[tableName].versions_.begin(); 00734 it != allTableInfo_[tableName].versions_.end(); 00735 /*no increment*/) 00736 { 00737 if(it->isTemporaryVersion()) 00738 { 00739 __COUT__ << "Removing version info: " << *it << __E__; 00740 allTableInfo_[tableName].versions_.erase(it++); 00741 } 00742 else 00743 ++it; 00744 } 00745 } 00746 else // erase target version only 00747 { 00748 __COUT__ << "Removing version info: " << targetVersion << __E__; 00749 auto it = allTableInfo_[tableName].versions_.find(targetVersion); 00750 if(it == allTableInfo_[tableName].versions_.end()) 00751 { 00752 __COUT__ << "Target version was not found in info versions..." << __E__; 00753 return; 00754 } 00755 allTableInfo_[tableName].versions_.erase( 00756 allTableInfo_[tableName].versions_.find(targetVersion)); 00757 __COUT__ << "Target version was erased from info." << __E__; 00758 } 00759 } 00760 00761 //============================================================================== 00762 // clearCachedVersions 00763 // clear ALL cached persistent versions (does not erase temporary versions) 00764 // 00765 // maintains allTableInfo_ also while erasing (trivial, do nothing) 00766 void ConfigurationManagerRW::clearCachedVersions(const std::string& tableName) 00767 { 00768 TableBase* table = getTableByName(tableName); 00769 00770 table->trimCache(0); 00771 } 00772 00773 //============================================================================== 00774 // clearAllCachedVersions 00775 // clear ALL cached persistent versions (does not erase temporary versions) 00776 // 00777 // maintains allTableInfo_ also while erasing (trivial, do nothing) 00778 void ConfigurationManagerRW::clearAllCachedVersions() 00779 { 00780 for(auto configInfo : allTableInfo_) 00781 configInfo.second.tablePtr_->trimCache(0); 00782 } 00783 00784 //============================================================================== 00785 // copyViewToCurrentColumns 00786 TableVersion ConfigurationManagerRW::copyViewToCurrentColumns( 00787 const std::string& tableName, TableVersion sourceVersion) 00788 { 00789 getTableByName(tableName)->reset(); 00790 00791 // make sure source version is loaded 00792 // need to load with loose column rules! 00793 TableBase* table = 00794 getVersionedTableByName(tableName, TableVersion(sourceVersion), true); 00795 00796 // copy from source version to a new temporary version 00797 TableVersion newTemporaryVersion = 00798 table->copyView(table->getView(), TableVersion(), username_); 00799 00800 // update allTableInfo_ with the new version 00801 allTableInfo_[tableName].versions_.insert(newTemporaryVersion); 00802 00803 return newTemporaryVersion; 00804 } 00805 00806 //============================================================================== 00807 // cacheGroupKey 00808 void ConfigurationManagerRW::cacheGroupKey(const std::string& groupName, 00809 TableGroupKey key) 00810 { 00811 allGroupInfo_[groupName].keys_.emplace(key); 00812 } 00813 00814 //============================================================================== 00815 // getGroupInfo 00816 // the interface is slow when there are a lot of groups.. 00817 // so plan is to maintain local cache of recent group info 00818 const GroupInfo& ConfigurationManagerRW::getGroupInfo(const std::string& groupName) 00819 { 00820 // //NOTE: seems like this filter is taking the long amount of time 00821 // std::set<std::string /*name*/> fullGroupNames = 00822 // theInterface_->getAllTableGroupNames(groupName); //db filter by 00823 // group name 00824 00825 // so instead caching ourselves... 00826 auto it = allGroupInfo_.find(groupName); 00827 if(it == allGroupInfo_.end()) 00828 { 00829 __SS__ << "Group name '" << groupName 00830 << "' not found in group info! (creating empty info)" << __E__; 00831 __COUT_WARN__ << ss.str(); 00832 //__SS_THROW__; 00833 return allGroupInfo_[groupName]; 00834 } 00835 return it->second; 00836 } 00837 00838 //============================================================================== 00839 // findTableGroup 00840 // return group with same name and same members and same aliases 00841 // else return invalid key 00842 // 00843 // Note: if aliases, then member alias is matched (not member 00844 // 00845 // Note: this is taking too long when there are a ton of groups. 00846 // Change to going back only a limited number.. (but the order also comes in alpha order 00847 // from theInterface_->getAllTableGroupNames which is a problem for choosing 00848 // the most recent to check. ) 00849 TableGroupKey ConfigurationManagerRW::findTableGroup( 00850 const std::string& groupName, 00851 const std::map<std::string, TableVersion>& groupMemberMap, 00852 const std::map<std::string /*name*/, std::string /*alias*/>& groupAliases) 00853 { 00854 // //NOTE: seems like this filter is taking the long amount of time 00855 // std::set<std::string /*name*/> fullGroupNames = 00856 // theInterface_->getAllTableGroupNames(groupName); //db filter by 00857 // group name 00858 const GroupInfo& groupInfo = getGroupInfo(groupName); 00859 00860 // std::string name; 00861 // TableGroupKey key; 00862 std::map<std::string /*name*/, TableVersion /*version*/> compareToMemberMap; 00863 std::map<std::string /*name*/, std::string /*alias*/> compareToGroupAliases; 00864 bool isDifferent; 00865 00866 const unsigned int MAX_DEPTH_TO_CHECK = 20; 00867 unsigned int keyMinToCheck = 0; 00868 00869 if(groupInfo.keys_.size()) 00870 keyMinToCheck = groupInfo.keys_.rbegin()->key(); 00871 if(keyMinToCheck > MAX_DEPTH_TO_CHECK) 00872 { 00873 keyMinToCheck -= MAX_DEPTH_TO_CHECK; 00874 __COUT__ << "Checking groups back to key... " << keyMinToCheck << __E__; 00875 } 00876 else 00877 { 00878 keyMinToCheck = 0; 00879 __COUT__ << "Checking all groups." << __E__; 00880 } 00881 00882 // have min key to check, now loop through and check groups 00883 // std::string fullName; 00884 for(const auto& key : groupInfo.keys_) 00885 { 00886 // TableGroupKey::getGroupNameAndKey(fullName,name,key); 00887 00888 if(key.key() < keyMinToCheck) 00889 continue; // skip keys that are too old 00890 00891 // fullName = TableGroupKey::getFullGroupString(groupName,key); 00892 // 00893 // __COUT__ << "checking group... " << fullName << __E__; 00894 // 00895 // compareToMemberMap = 00896 // theInterface_->getTableGroupMembers(fullName); 00897 00898 loadTableGroup(groupName, 00899 key, 00900 false /*doActivate*/, 00901 &compareToMemberMap /*memberMap*/, 00902 0, 00903 0, 00904 0, 00905 0, 00906 0, /*null pointers*/ 00907 true /*doNotLoadMember*/, 00908 0 /*groupTypeString*/, 00909 &compareToGroupAliases); 00910 00911 isDifferent = false; 00912 for(auto& memberPair : groupMemberMap) 00913 { 00914 //__COUT__ << memberPair.first << " - " << memberPair.second << __E__; 00915 00916 if(groupAliases.find(memberPair.first) != groupAliases.end()) 00917 { 00918 // handle this table as alias, not version 00919 if(compareToGroupAliases.find(memberPair.first) == 00920 compareToGroupAliases.end() || // alias is missing 00921 groupAliases.at(memberPair.first) != 00922 compareToGroupAliases.at(memberPair.first)) 00923 { // then different 00924 //__COUT__ << "alias mismatch found!" << __E__; 00925 isDifferent = true; 00926 break; 00927 } 00928 else 00929 continue; 00930 } // else check if compareTo group is using an alias for table 00931 else if(compareToGroupAliases.find(memberPair.first) != 00932 compareToGroupAliases.end()) 00933 { 00934 // then different 00935 //__COUT__ << "alias mismatch found!" << __E__; 00936 isDifferent = true; 00937 break; 00938 00939 } // else handle as table version comparison 00940 else if(compareToMemberMap.find(memberPair.first) == 00941 compareToMemberMap.end() || // name is missing 00942 memberPair.second != 00943 compareToMemberMap.at(memberPair.first)) // or version mismatch 00944 { // then different 00945 //__COUT__ << "mismatch found!" << __E__; 00946 isDifferent = true; 00947 break; 00948 } 00949 } 00950 if(isDifferent) 00951 continue; 00952 00953 // check member size for exact match 00954 if(groupMemberMap.size() != compareToMemberMap.size()) 00955 continue; // different size, so not same (groupMemberMap is a subset of 00956 // memberPairs) 00957 00958 __COUT__ << "Found exact match with key: " << key << __E__; 00959 // else found an exact match! 00960 return key; 00961 } 00962 __COUT__ << "No match found - this group is new!" << __E__; 00963 // if here, then no match found 00964 return TableGroupKey(); // return invalid key 00965 } 00966 00967 //============================================================================== 00968 // saveNewTableGroup 00969 // saves new group and returns the new group key 00970 // if previousVersion is provided, attempts to just bump that version 00971 // else, bumps latest version found in db 00972 // 00973 // Note: groupMembers map will get modified with group metadata table version 00974 TableGroupKey ConfigurationManagerRW::saveNewTableGroup( 00975 const std::string& groupName, 00976 std::map<std::string, TableVersion>& groupMembers, 00977 const std::string& groupComment, 00978 std::map<std::string /*table*/, std::string /*alias*/>* groupAliases) 00979 { 00980 // steps: 00981 // determine new group key 00982 // verify group members 00983 // verify groupNameWithKey 00984 // verify store 00985 00986 if(groupMembers.size() == 0) // do not allow empty groups 00987 { 00988 __SS__ << "Empty group member list. Can not create a group without members!" 00989 << __E__; 00990 __SS_THROW__; 00991 } 00992 00993 // determine new group key 00994 TableGroupKey newKey = 00995 TableGroupKey::getNextKey(theInterface_->findLatestGroupKey(groupName)); 00996 00997 __COUT__ << "New Key for group: " << groupName << " found as " << newKey << __E__; 00998 00999 // verify group members 01000 // - use all table info 01001 std::map<std::string, TableInfo> allCfgInfo = getAllTableInfo(); 01002 for(auto& memberPair : groupMembers) 01003 { 01004 // check member name 01005 if(allCfgInfo.find(memberPair.first) == allCfgInfo.end()) 01006 { 01007 __COUT_ERR__ << "Group member \"" << memberPair.first 01008 << "\" not found in database!"; 01009 01010 if(groupMetadataTable_.getTableName() == memberPair.first) 01011 { 01012 __COUT_WARN__ 01013 << "Looks like this is the groupMetadataTable_ '" 01014 << ConfigurationInterface::GROUP_METADATA_TABLE_NAME 01015 << ".' Note that this table is added to the member map when groups " 01016 "are saved." 01017 << "It should not be part of member map when calling this function." 01018 << __E__; 01019 __COUT__ << "Attempting to recover." << __E__; 01020 groupMembers.erase(groupMembers.find(memberPair.first)); 01021 } 01022 else 01023 { 01024 __SS__ << ("Group member not found!") << __E__; 01025 __SS_THROW__; 01026 } 01027 } 01028 // check member version 01029 if(allCfgInfo[memberPair.first].versions_.find(memberPair.second) == 01030 allCfgInfo[memberPair.first].versions_.end()) 01031 { 01032 __SS__ << "Group member \"" << memberPair.first << "\" version \"" 01033 << memberPair.second << "\" not found in database!"; 01034 __SS_THROW__; 01035 } 01036 } // end verify members 01037 01038 // verify group aliases 01039 if(groupAliases) 01040 { 01041 for(auto& aliasPair : *groupAliases) 01042 { 01043 // check for alias table in member names 01044 if(groupMembers.find(aliasPair.first) == groupMembers.end()) 01045 { 01046 __COUT_ERR__ << "Group member \"" << aliasPair.first 01047 << "\" not found in group member map!"; 01048 01049 __SS__ << ("Alias table not found in member list!") << __E__; 01050 __SS_THROW__; 01051 } 01052 } 01053 } // end verify group aliases 01054 01055 // verify groupNameWithKey and attempt to store 01056 try 01057 { 01058 // save meta data for group; reuse groupMetadataTable_ 01059 std::string groupAliasesString = ""; 01060 if(groupAliases) 01061 groupAliasesString = StringMacros::mapToString( 01062 *groupAliases, "," /*primary delimeter*/, ":" /*secondary delimeter*/); 01063 __COUT__ << "Metadata: " << username_ << " " << time(0) << " " << groupComment 01064 << " " << groupAliasesString << __E__; 01065 01066 // to compensate for unusual errors upstream, make sure the metadata table has one 01067 // row 01068 while(groupMetadataTable_.getViewP()->getNumberOfRows() > 1) 01069 groupMetadataTable_.getViewP()->deleteRow(0); 01070 if(groupMetadataTable_.getViewP()->getNumberOfRows() == 0) 01071 groupMetadataTable_.getViewP()->addRow(); 01072 01073 // columns are uid,comment,author,time 01074 groupMetadataTable_.getViewP()->setValue( 01075 groupAliasesString, 0, ConfigurationManager::METADATA_COL_ALIASES); 01076 groupMetadataTable_.getViewP()->setValue( 01077 groupComment, 0, ConfigurationManager::METADATA_COL_COMMENT); 01078 groupMetadataTable_.getViewP()->setValue( 01079 username_, 0, ConfigurationManager::METADATA_COL_AUTHOR); 01080 groupMetadataTable_.getViewP()->setValue( 01081 time(0), 0, ConfigurationManager::METADATA_COL_TIMESTAMP); 01082 01083 // set version to first available persistent version 01084 groupMetadataTable_.getViewP()->setVersion(TableVersion::getNextVersion( 01085 theInterface_->findLatestVersion(&groupMetadataTable_))); 01086 01087 // groupMetadataTable_.print(); 01088 01089 theInterface_->saveActiveVersion(&groupMetadataTable_); 01090 01091 // force groupMetadataTable_ to be a member for the group 01092 groupMembers[groupMetadataTable_.getTableName()] = 01093 groupMetadataTable_.getViewVersion(); 01094 01095 theInterface_->saveTableGroup( 01096 groupMembers, TableGroupKey::getFullGroupString(groupName, newKey)); 01097 __COUT__ << "Created table group: " << groupName << ":" << newKey << __E__; 01098 } 01099 catch(std::runtime_error& e) 01100 { 01101 __COUT_ERR__ << "Failed to create table group: " << groupName << ":" << newKey 01102 << __E__; 01103 __COUT_ERR__ << "\n\n" << e.what() << __E__; 01104 throw; 01105 } 01106 catch(...) 01107 { 01108 __COUT_ERR__ << "Failed to create table group: " << groupName << ":" << newKey 01109 << __E__; 01110 throw; 01111 } 01112 01113 // store cache of recent groups 01114 cacheGroupKey(groupName, newKey); 01115 01116 // at this point succeeded! 01117 return newKey; 01118 } 01119 01120 //============================================================================== 01121 // saveNewBackbone 01122 // makes the new version the active version and returns new version number 01123 // INVALID will give a new backbone from mockup 01124 TableVersion ConfigurationManagerRW::saveNewBackbone(TableVersion temporaryVersion) 01125 { 01126 __COUT_INFO__ << "Creating new backbone from temporary version " << temporaryVersion 01127 << __E__; 01128 01129 // find common available temporary version among backbone members 01130 TableVersion newVersion(TableVersion::DEFAULT); 01131 TableVersion retNewVersion; 01132 auto backboneMemberNames = ConfigurationManager::getBackboneMemberNames(); 01133 for(auto& name : backboneMemberNames) 01134 { 01135 retNewVersion = ConfigurationManager::getTableByName(name)->getNextVersion(); 01136 __COUT__ << "New version for backbone member (" << name << "): " << retNewVersion 01137 << __E__; 01138 if(retNewVersion > newVersion) 01139 newVersion = retNewVersion; 01140 } 01141 01142 __COUT__ << "Common new backbone version found as " << newVersion << __E__; 01143 01144 // create new views from source temporary version 01145 for(auto& name : backboneMemberNames) 01146 { 01147 // saveNewVersion makes the new version the active version 01148 retNewVersion = getConfigurationInterface()->saveNewVersion( 01149 getTableByName(name), temporaryVersion, newVersion); 01150 if(retNewVersion != newVersion) 01151 { 01152 __SS__ << "Failure! New view requested was " << newVersion 01153 << ". Mismatched new view created: " << retNewVersion << __E__; 01154 __COUT_ERR__ << ss.str(); 01155 __SS_THROW__; 01156 } 01157 } 01158 01159 return newVersion; 01160 } 01161 01162 //============================================================================== 01163 void ConfigurationManagerRW::testXDAQContext() 01164 { 01165 // //test creating table group with author, create time, and comment 01166 // { 01167 // __COUT__ << __E__; 01168 // 01169 // std::string groupName = "testGroup"; 01170 // TableGroupKey newKey; 01171 // //TableGroupMetadata 01172 // 01173 // try 01174 // { 01175 // { 01176 // std::map<std::string, TableVersion> members; 01177 // members["ARTDAQAggregatorTable"] = TableVersion(1); 01178 // 01179 // //TableGroupKey 01180 // // saveNewTableGroup 01181 // // (const std::string &groupName, const std::map<std::string, 01182 // // TableVersion> &groupMembers, TableGroupKey 01183 // previousVersion=TableGroupKey()); newKey = 01184 // saveNewTableGroup(groupName,members); 01185 // } 01186 // 01187 // //std::map<std::string, TableVersion > 01188 // // loadTableGroup 01189 // // (const std::string &configGroupName, 01190 // // TableGroupKey configGroupKey, bool doActivate=false, ProgressBar* 01191 // progressBar=0, std::string *accumulateWarnings=0); 01192 // { 01193 // std::map<std::string, TableVersion > memberMap = 01194 // loadTableGroup(groupName,newKey); 01195 // __COUT__ << "Group members:" << __E__; 01196 // for(const auto &member: memberMap) 01197 // __COUT__ << member.first << " " << member.second << __E__; 01198 // } 01199 // 01200 // 01201 // 01202 // //do it again 01203 // { 01204 // std::map<std::string, TableVersion> members; 01205 // members["ARTDAQAggregatorTable"] = TableVersion(1); 01206 // 01207 // //TableGroupKey 01208 // // saveNewTableGroup 01209 // // (const std::string &groupName, const std::map<std::string, 01210 // // TableVersion> &groupMembers, TableGroupKey 01211 // previousVersion=TableGroupKey()); newKey = 01212 // saveNewTableGroup(groupName,members); 01213 // } 01214 // 01215 // //std::map<std::string, TableVersion > 01216 // // loadTableGroup 01217 // // (const std::string &configGroupName, 01218 // // TableGroupKey configGroupKey, bool doActivate=false, ProgressBar* 01219 // progressBar=0, std::string *accumulateWarnings=0); 01220 // { 01221 // std::map<std::string, TableVersion > memberMap = 01222 // loadTableGroup(groupName,newKey); 01223 // __COUT__ << "Group members:" << __E__; 01224 // for(const auto &member: memberMap) 01225 // __COUT__ << member.first << " " << member.second << __E__; 01226 // } 01227 // 01228 // 01229 // } 01230 // catch(std::runtime_error &e) 01231 // { 01232 // __COUT_ERR__ << "Failed to create table group: " << groupName << ":" << 01233 // newKey 01234 //<< __E__; 01235 // __COUT_ERR__ << "\n\n" << e.what() << __E__; 01236 // } 01237 // catch(...) 01238 // { 01239 // __COUT_ERR__ << "Failed to create table group: " << groupName << ":" << 01240 // newKey 01241 //<< __E__; 01242 // } 01243 // 01244 // return; 01245 // } 01246 01247 // //test creating table group and reading 01248 // { 01249 // __COUT__ << __E__; 01250 // 01251 // auto gcfgs = theInterface_->getAllTableGroupNames(); 01252 // __COUT__ << "Global table size: " << gcfgs.size() << __E__; 01253 // for(auto &g:gcfgs) 01254 // { 01255 // __COUT__ << "Global table " << g << __E__; 01256 // auto gcMap = theInterface_->getTableGroupMembers(g, true 01258 // 01259 // for(auto &cv:gcMap) 01260 // __COUT__ << "\tMember table " << cv.first << ":" << cv.second << 01261 // __E__; 01262 // } 01263 // 01264 // auto cfgs = theInterface_->getAllTableNames(); 01265 // __COUT__ << "Sub-table size: " << cfgs.size() << __E__; 01266 // for(auto &c:cfgs) 01267 // { 01268 // __COUT__ << "table " << c << __E__; 01269 // auto vs = theInterface_->getVersions(getTableByName(c)); 01270 // for(auto &v:vs) 01271 // __COUT__ << "\tversion " << v << __E__; 01272 // } 01273 // 01274 // if(0) //create a table group (storeGlobalConfiguration) 01275 // { 01276 // //storeGlobalConfiguration with latest of each 01277 // std::map<std::string /*name*/, TableVersion /*version*/> gcMap; 01278 // 01279 // for(auto &c:cfgs) //for each sub-table, take latest version 01280 // { 01281 // auto vs = theInterface_->getVersions(getTableByName(c)); 01282 // if(1 && vs.rbegin() != vs.rend()) //create latest! 01283 // { 01284 // gcMap[c] = *(vs.rbegin()); 01285 // __COUT__ << "Adding table " << c << ":" << gcMap[c] << __E__; 01286 // } 01287 // else if(vs.begin() != vs.end()) //create oldest! 01288 // { 01289 // gcMap[c] = *(vs.begin()); 01290 // __COUT__ << "Adding table " << c << ":" << gcMap[c] << __E__; 01291 // } 01292 // } 01293 // 01294 // int i = 0; 01295 // bool done = false; 01296 // char gcname[100]; 01297 // bool found; 01298 // while(!done && i<1) 01299 // { 01300 // do //avoid conflicting global table names 01301 // { 01302 // found = false; 01303 // sprintf(gcname,"GConfig_v%d",i++); 01304 // for(auto &g:gcfgs) 01305 // if(g == gcname) {found = true; break;} 01306 // } 01307 // while(found); 01308 // __COUT__ << "Trying Global table: " << gcname<< __E__; 01309 // 01310 // try 01311 // { 01312 // theInterface_->saveTableGroup(gcMap,gcname); 01313 // done = true; 01314 // __COUT__ << "Created Global table: " << gcname<< __E__; 01315 // } 01316 // catch(...) {++i;} //repeat names are not allowed, so increment name 01317 // } 01318 // 01319 // } 01320 // 01321 // //return; 01322 // } 01323 // 01324 // this is to test table tree 01325 try 01326 { 01327 __COUT__ << "Loading table..." << __E__; 01328 loadTableGroup("FETest", TableGroupKey(2)); // Context_1 01329 ConfigurationTree t = getNode("/FETable/DEFAULT/FrontEndType"); 01330 01331 std::string v; 01332 01333 __COUT__ << __E__; 01334 t.getValue(v); 01335 __COUT__ << "Value: " << v << __E__; 01336 __COUT__ << "Value index: " << t.getValue<int>() << __E__; 01337 01338 return; 01339 01340 // ConfigurationTree t = getNode("XDAQContextTable"); 01341 // ConfigurationTree t = getNode("/FETable/OtsUDPFSSR3/FrontEndType"); 01342 // ConfigurationTree t = getNode("/FETable").getNode("OtsUDPFSSR3"); 01343 // ConfigurationTree t = getNode("/XDAQContextTable/testContext/"); 01344 // 01345 // __COUT__ << __E__; 01346 // t.getValue(v); 01347 // __COUT__ << "Value: " << v << __E__; 01348 // 01349 // if(!t.isValueNode()) 01350 // { 01351 // auto C = t.getChildrenNames(); 01352 // for(auto &c: C) 01353 // __COUT__ << "\t+ " << c << __E__; 01354 // 01355 // std::stringstream ss; 01356 // t.print(-1,ss); 01357 // __COUT__ << "\n" << ss.str() << __E__; 01358 // 01359 // try 01360 // { 01361 // ConfigurationTree tt = t.getNode("OtsUDPFSSR3"); 01362 // tt.getValue(v); 01363 // __COUT__ << "Value: " << v << __E__; 01364 // 01365 // C = tt.getChildrenNames(); 01366 // for(auto &c: C) 01367 // __COUT__ << "\t+ " << c << __E__; 01368 // } 01369 // catch(...) 01370 // { 01371 // __COUT__ << "Failed to find extra node." << __E__; 01372 // } 01373 // } 01374 } 01375 catch(...) 01376 { 01377 __COUT__ << "Failed to load table..." << __E__; 01378 } 01379 }