1 #include "otsdaq/ConfigurationInterface/ConfigurationManagerRW.h"
8 #define __MF_SUBJECT__ "ConfigurationManagerRW"
10 #define TABLE_INFO_PATH std::string(__ENV__("TABLE_INFO_PATH")) + "/"
11 #define TABLE_INFO_EXT "Info.xml"
13 #define CORE_TABLE_INFO_FILENAME \
14 ((getenv("SERVICE_DATA_PATH") == NULL) ? (std::string(__ENV__("USER_DATA")) + "/ServiceData") : (std::string(__ENV__("SERVICE_DATA_PATH")))) + \
15 "/CoreTableInfoNames.dat"
19 ConfigurationManagerRW::ConfigurationManagerRW(
const std::string& username) :
ConfigurationManager(username)
21 __COUT__ <<
"Instantiating Config Manager with Write Access! (for " << username <<
")" << __E__;
23 theInterface_ = ConfigurationInterface::getInstance(
false);
26 mkdir((ConfigurationManager::LAST_TABLE_GROUP_SAVE_PATH).c_str(), 0755);
32 const std::set<std::string>& contextMemberNames = getContextMemberNames();
33 const std::set<std::string>& backboneMemberNames = getBackboneMemberNames();
34 const std::set<std::string>& iterateMemberNames = getIterateMemberNames();
36 FILE* fp = fopen((CORE_TABLE_INFO_FILENAME).c_str(),
"r");
42 std::vector<unsigned int> foundVector;
44 for(
const auto& name : contextMemberNames)
46 foundVector.push_back(
false);
48 while(fgets(line, 100, fp))
52 line[strlen(line) - 1] =
'\0';
53 if(strcmp(line, (
"ContextGroup/" + name).c_str()) == 0)
55 foundVector.back() =
true;
62 for(
const auto& name : backboneMemberNames)
64 foundVector.push_back(
false);
66 while(fgets(line, 100, fp))
70 line[strlen(line) - 1] =
'\0';
71 if(strcmp(line, (
"BackboneGroup/" + name).c_str()) == 0)
73 foundVector.back() =
true;
80 for(
const auto& name : iterateMemberNames)
82 foundVector.push_back(
false);
84 while(fgets(line, 100, fp))
88 line[strlen(line) - 1] =
'\0';
89 if(strcmp(line, (
"IterateGroup/" + name).c_str()) == 0)
91 foundVector.back() =
true;
104 fp = fopen((CORE_TABLE_INFO_FILENAME).c_str(),
"a");
108 for(
const auto& name : contextMemberNames)
111 fprintf(fp,
"\nContextGroup/%s", name.c_str());
115 for(
const auto& name : backboneMemberNames)
118 fprintf(fp,
"\nBackboneGroup/%s", name.c_str());
122 for(
const auto& name : iterateMemberNames)
125 fprintf(fp,
"\nIterateGroup/%s", name.c_str());
133 __SS__ <<
"Failed to open core table info file for appending: " << CORE_TABLE_INFO_FILENAME << __E__;
139 fp = fopen((CORE_TABLE_INFO_FILENAME).c_str(),
"w");
142 for(
const auto& name : contextMemberNames)
143 fprintf(fp,
"\nContextGroup/%s", name.c_str());
144 for(
const auto& name : backboneMemberNames)
145 fprintf(fp,
"\nBackboneGroup/%s", name.c_str());
146 for(
const auto& name : iterateMemberNames)
147 fprintf(fp,
"\nIterateGroup/%s", name.c_str());
152 __SS__ <<
"Failed to open core table info file: " << CORE_TABLE_INFO_FILENAME << __E__;
165 const std::map<std::string, TableInfo>& ConfigurationManagerRW::getAllTableInfo(
bool refresh,
166 std::string* accumulatedWarnings ,
167 const std::string& errorFilterName )
172 return allTableInfo_;
175 allTableInfo_.clear();
176 allGroupInfo_.clear();
183 __COUT__ <<
"======================================================== "
184 "getAllTableInfo start"
186 __COUT__ <<
"Refreshing all! Extracting list of tables..." << __E__;
188 struct dirent* entry;
189 std::string path = TABLE_INFO_PATH;
190 char fileExt[] = TABLE_INFO_EXT;
191 const unsigned char MIN_TABLE_NAME_SZ = 3;
192 if((pDIR = opendir(path.c_str())) != 0)
194 while((entry = readdir(pDIR)) != 0)
197 if(strlen(entry->d_name) < strlen(fileExt) + MIN_TABLE_NAME_SZ)
201 if(strcmp(&(entry->d_name[strlen(entry->d_name) - strlen(fileExt)]), fileExt) != 0)
204 entry->d_name[strlen(entry->d_name) - strlen(fileExt)] =
'\0';
213 theInterface_->get(table, entry->d_name, 0, 0,
216 catch(cet::exception
const&)
222 __COUT__ <<
"Skipping! No valid class found for... " << entry->d_name <<
"\n";
225 catch(std::runtime_error& e)
231 __COUT__ <<
"Skipping! No valid class found for... " << entry->d_name <<
"\n";
232 __COUT__ <<
"Error: " << e.what() << __E__;
237 if(accumulatedWarnings)
239 if(errorFilterName ==
"" || errorFilterName == entry->d_name)
241 *accumulatedWarnings += std::string(
"\nIn table '") + entry->d_name +
"'..." + e.what();
243 __SS__ <<
"Attempting to allow illegal columns!" << __E__;
244 *accumulatedWarnings += ss.str();
248 __COUT__ <<
"Attempting to allow illegal columns!" << __E__;
250 std::string returnedAccumulatedErrors;
255 table =
new TableBase(entry->d_name, &returnedAccumulatedErrors);
259 __COUT__ <<
"Skipping! Allowing illegal columns didn't work either... " << entry->d_name <<
"\n";
262 __COUT__ <<
"Error (but allowed): " << returnedAccumulatedErrors << __E__;
264 if(errorFilterName ==
"" || errorFilterName == entry->d_name)
265 *accumulatedWarnings += std::string(
"\nIn table '") + entry->d_name +
"'..." + returnedAccumulatedErrors;
273 if(nameToTableMap_[entry->d_name])
276 std::set<TableVersion> versions = nameToTableMap_[entry->d_name]->getStoredVersions();
277 for(
auto& version : versions)
278 if(version.isTemporaryVersion())
284 nameToTableMap_[entry->d_name]->setActiveView(version);
286 nameToTableMap_[entry->d_name]->getView(),
296 delete nameToTableMap_[entry->d_name];
297 nameToTableMap_[entry->d_name] = 0;
300 nameToTableMap_[entry->d_name] = table;
302 allTableInfo_[entry->d_name].tablePtr_ = table;
303 allTableInfo_[entry->d_name].versions_ = theInterface_->getVersions(table);
307 std::set<TableVersion> versions = nameToTableMap_[entry->d_name]->getStoredVersions();
308 for(
auto& version : versions)
309 if(version.isTemporaryVersion())
312 allTableInfo_[entry->d_name].versions_.emplace(version);
317 __COUT__ <<
"Extracting list of tables complete. Now initializing..." << __E__;
322 std::string tmpAccumulateWarnings;
323 init(0 ,
false , accumulatedWarnings ? &tmpAccumulateWarnings :
nullptr);
325 if(accumulatedWarnings && errorFilterName ==
"")
326 *accumulatedWarnings += tmpAccumulateWarnings;
328 __COUT__ <<
"======================================================== getAllTableInfo end" << __E__;
335 std::set<std::string > tableGroups = theInterface_->getAllTableGroupNames();
336 __COUT__ <<
"Number of Groups: " << tableGroups.size() << __E__;
340 for(
const auto& fullName : tableGroups)
342 TableGroupKey::getGroupNameAndKey(fullName, name, key);
343 cacheGroupKey(name, key);
347 for(
auto& groupInfo : allGroupInfo_)
351 loadTableGroup(groupInfo.first ,
352 groupInfo.second.getLatestKey(),
354 &groupInfo.second.latestKeyMemberMap_ ,
357 &groupInfo.second.latestKeyGroupComment_,
358 &groupInfo.second.latestKeyGroupAuthor_,
359 &groupInfo.second.latestKeyGroupCreationTime_,
361 &groupInfo.second.latestKeyGroupTypeString_);
365 __COUT_WARN__ <<
"Error occurred loading latest group info into cache for '" << groupInfo.first <<
"'..." << __E__;
366 groupInfo.second.latestKeyGroupComment_ =
"UNKNOWN";
367 groupInfo.second.latestKeyGroupAuthor_ =
"UNKNOWN";
368 groupInfo.second.latestKeyGroupCreationTime_ =
"0";
369 groupInfo.second.latestKeyGroupTypeString_ =
"UNKNOWN";
373 catch(
const std::runtime_error& e)
375 __SS__ <<
"A fatal error occurred reading the info for all table groups. Error: " << e.what() << __E__;
376 __COUT_ERR__ <<
"\n" << ss.str();
377 if(accumulatedWarnings)
378 *accumulatedWarnings += ss.str();
384 __SS__ <<
"An unknown fatal error occurred reading the info for all table groups." << __E__;
385 __COUT_ERR__ <<
"\n" << ss.str();
386 if(accumulatedWarnings)
387 *accumulatedWarnings += ss.str();
392 return allTableInfo_;
399 std::map<std::string , std::map<std::string ,
TableVersion >> ConfigurationManagerRW::getVersionAliases(
403 std::map<std::string , std::map<std::string ,
TableVersion >> retMap =
404 ConfigurationManager::getVersionAliases();
408 if(!ConfigurationInterface::isVersionTrackingEnabled())
409 for(
const auto& tableInfo : allTableInfo_)
410 for(
const auto& version : tableInfo.second.versions_)
411 if(version.isScratchVersion())
412 retMap[tableInfo.first][ConfigurationManager::SCRATCH_VERSION_ALIAS] =
TableVersion(TableVersion::SCRATCH);
421 void ConfigurationManagerRW::activateTableGroup(
const std::string& tableGroupName,
TableGroupKey tableGroupKey, std::string* accumulatedTreeErrors)
426 loadTableGroup(tableGroupName,
431 accumulatedTreeErrors);
435 __COUT_ERR__ <<
"There were errors, so de-activating group: " << tableGroupName <<
" (" << tableGroupKey <<
")" << __E__;
438 destroyTableGroup(tableGroupName,
true);
446 __COUT_INFO__ <<
"Updating persistent active groups to " << ConfigurationManager::ACTIVE_GROUPS_FILENAME <<
" ..." << __E__;
447 __MOUT_INFO__ <<
"Updating persistent active groups to " << ConfigurationManager::ACTIVE_GROUPS_FILENAME <<
" ..." << __E__;
449 std::string fn = ConfigurationManager::ACTIVE_GROUPS_FILENAME;
450 FILE* fp = fopen(fn.c_str(),
"w");
453 __SS__ <<
"Fatal Error! Unable to open the file " << ConfigurationManager::ACTIVE_GROUPS_FILENAME <<
" for editing! Is there a permissions problem?"
455 __COUT_ERR__ << ss.str();
460 __MCOUT_INFO__(
"Active Context table group: " << theContextTableGroup_ <<
"("
461 << (theContextTableGroupKey_ ? theContextTableGroupKey_->toString().c_str() :
"-1") <<
")" << __E__);
462 __MCOUT_INFO__(
"Active Backbone table group: " << theBackboneTableGroup_ <<
"("
463 << (theBackboneTableGroupKey_ ? theBackboneTableGroupKey_->toString().c_str() :
"-1") <<
")" << __E__);
464 __MCOUT_INFO__(
"Active Iterate table group: " << theIterateTableGroup_ <<
"("
465 << (theIterateTableGroupKey_ ? theIterateTableGroupKey_->toString().c_str() :
"-1") <<
")" << __E__);
466 __MCOUT_INFO__(
"Active Configuration table group: " << theConfigurationTableGroup_ <<
"("
467 << (theConfigurationTableGroupKey_ ? theConfigurationTableGroupKey_->toString().c_str() :
"-1") <<
")"
470 fprintf(fp,
"%s\n", theContextTableGroup_.c_str());
471 fprintf(fp,
"%s\n", theContextTableGroupKey_ ? theContextTableGroupKey_->toString().c_str() :
"-1");
472 fprintf(fp,
"%s\n", theBackboneTableGroup_.c_str());
473 fprintf(fp,
"%s\n", theBackboneTableGroupKey_ ? theBackboneTableGroupKey_->toString().c_str() :
"-1");
474 fprintf(fp,
"%s\n", theIterateTableGroup_.c_str());
475 fprintf(fp,
"%s\n", theIterateTableGroupKey_ ? theIterateTableGroupKey_->toString().c_str() :
"-1");
476 fprintf(fp,
"%s\n", theConfigurationTableGroup_.c_str());
477 fprintf(fp,
"%s\n", theConfigurationTableGroupKey_ ? theConfigurationTableGroupKey_->toString().c_str() :
"-1");
482 std::pair<std::string ,
TableGroupKey> activatedGroup(std::string(tableGroupName),tableGroupKey);
483 if(theConfigurationTableGroupKey_ && theConfigurationTableGroup_ == tableGroupName &&
484 *theConfigurationTableGroupKey_ == tableGroupKey)
485 ConfigurationManager::saveGroupNameAndKey(activatedGroup, LAST_ACTIVATED_CONFIG_GROUP_FILE);
486 else if(theContextTableGroupKey_ && theContextTableGroup_ == tableGroupName &&
487 *theContextTableGroupKey_ == tableGroupKey)
488 ConfigurationManager::saveGroupNameAndKey(activatedGroup, LAST_ACTIVATED_CONTEXT_GROUP_FILE);
489 else if(theBackboneTableGroupKey_ && theBackboneTableGroup_ == tableGroupName &&
490 *theBackboneTableGroupKey_ == tableGroupKey)
491 ConfigurationManager::saveGroupNameAndKey(activatedGroup, LAST_ACTIVATED_BACKBONE_GROUP_FILE);
492 else if(theIterateTableGroupKey_ && theIterateTableGroup_ == tableGroupName &&
493 *theIterateTableGroupKey_ == tableGroupKey)
494 ConfigurationManager::saveGroupNameAndKey(activatedGroup, LAST_ACTIVATED_ITERATOR_GROUP_FILE);
505 __COUT_INFO__ <<
"Creating temporary backbone view from version " << sourceViewVersion << __E__;
508 TableVersion tmpVersion = TableVersion::getNextTemporaryVersion();
510 auto backboneMemberNames = ConfigurationManager::getBackboneMemberNames();
511 for(
auto& name : backboneMemberNames)
513 retTmpVersion = ConfigurationManager::getTableByName(name)->getNextTemporaryVersion();
514 if(retTmpVersion < tmpVersion)
515 tmpVersion = retTmpVersion;
518 __COUT__ <<
"Common temporary backbone version found as " << tmpVersion << __E__;
521 for(
auto& name : backboneMemberNames)
523 retTmpVersion = getTableByName(name)->createTemporaryView(sourceViewVersion, tmpVersion);
524 if(retTmpVersion != tmpVersion)
526 __SS__ <<
"Failure! Temporary view requested was " << tmpVersion <<
". Mismatched temporary view created: " << retTmpVersion << __E__;
527 __COUT_ERR__ << ss.str();
536 TableBase* ConfigurationManagerRW::getTableByName(
const std::string& tableName)
538 if(nameToTableMap_.find(tableName) == nameToTableMap_.end())
540 if(tableName == ConfigurationManager::ARTDAQ_TOP_TABLE_NAME)
542 __COUT_WARN__ <<
"Since target table was the artdaq top configuration level, "
543 "attempting to help user by appending to core tables file: "
544 << CORE_TABLE_INFO_FILENAME << __E__;
545 FILE* fp = fopen((CORE_TABLE_INFO_FILENAME).c_str(),
"a");
548 fprintf(fp,
"\nARTDAQ/*");
553 __SS__ <<
"Table not found with name: " << tableName << __E__;
555 if((f = tableName.find(
' ')) != std::string::npos)
556 ss <<
"There was a space character found in the table name needle at "
558 << f <<
" in the string (was this intended?). " << __E__;
560 ss <<
"\nIf you think this table should exist in the core set of tables, try running 'UpdateOTS.sh --tables' to update your tables, then relaunch ots."
562 ss <<
"\nTables must be defined in $USER_DATA/TableInfo to exist in ots. Please verify your table definitions, and then restart ots." << __E__;
563 __COUT_ERR__ <<
"\n" << ss.str();
566 return nameToTableMap_[tableName];
574 TableBase* ConfigurationManagerRW::getVersionedTableByName(
const std::string& tableName,
576 bool looseColumnMatching ,
577 std::string* accumulatedErrors )
579 auto it = nameToTableMap_.find(tableName);
580 if(it == nameToTableMap_.end())
582 __SS__ <<
"\nCan not find table named '" << tableName <<
"'\n\n\n\nYou need to load the table before it can be used."
583 <<
"It probably is missing from the member list of the Table "
584 "Group that was loaded?\n\n\n\n\n"
590 if(version.isTemporaryVersion())
591 table->setActiveView(version);
593 theInterface_->get(table,
615 TableBase* table = getTableByName(tableName);
616 table->getTemporaryView(temporaryVersion)->setAuthor(username_);
620 newVersion = theInterface_->saveNewVersion(table, temporaryVersion);
622 table->setActiveView(newVersion);
625 while(!makeTemporary && !newVersion.isScratchVersion() && allTableInfo_[tableName].versions_.find(newVersion) != allTableInfo_[tableName].versions_.end())
627 __COUT_ERR__ <<
"What happenened!?? ERROR::: new persistent version v" << newVersion
628 <<
" already exists!? How is it possible? Retrace your steps and "
633 temporaryVersion = table->createTemporaryView(newVersion);
635 if(newVersion.isTemporaryVersion())
636 newVersion = temporaryVersion;
638 newVersion = TableVersion::getNextVersion(newVersion);
640 __COUT_WARN__ <<
"Attempting to recover and use v" << newVersion << __E__;
643 newVersion = theInterface_->saveNewVersion(table, temporaryVersion, newVersion);
645 table->setActiveView(newVersion);
648 if(newVersion.isInvalid())
650 __SS__ <<
"Something went wrong saving the new version v" << newVersion <<
". What happened?! (duplicates? database error?)" << __E__;
651 __COUT_ERR__ <<
"\n" << ss.str();
656 allTableInfo_[tableName].versions_.insert(newVersion);
669 void ConfigurationManagerRW::eraseTemporaryVersion(
const std::string& tableName,
TableVersion targetVersion)
671 TableBase* table = getTableByName(tableName);
673 table->trimTemporary(targetVersion);
676 if(allTableInfo_.find(tableName) == allTableInfo_.end())
680 if(targetVersion.isInvalid())
683 for(
auto it = allTableInfo_[tableName].versions_.begin(); it != allTableInfo_[tableName].versions_.end();
686 if(it->isTemporaryVersion())
688 __COUT__ <<
"Removing '" << tableName <<
"' version info: " << *it << __E__;
689 allTableInfo_[tableName].versions_.erase(it++);
698 auto it = allTableInfo_[tableName].versions_.find(targetVersion);
699 if(it == allTableInfo_[tableName].versions_.end())
701 __COUT__ <<
"Target '" << tableName <<
"' version v" << targetVersion <<
" was not found in info versions..." << __E__;
704 allTableInfo_[tableName].versions_.erase(allTableInfo_[tableName].versions_.find(targetVersion));
715 void ConfigurationManagerRW::clearCachedVersions(
const std::string& tableName)
717 TableBase* table = getTableByName(tableName);
727 void ConfigurationManagerRW::clearAllCachedVersions()
729 for(
auto configInfo : allTableInfo_)
730 configInfo.second.tablePtr_->trimCache(0);
735 TableVersion ConfigurationManagerRW::copyViewToCurrentColumns(
const std::string& tableName,
TableVersion sourceVersion)
737 getTableByName(tableName)->reset();
747 allTableInfo_[tableName].versions_.insert(newTemporaryVersion);
749 return newTemporaryVersion;
754 void ConfigurationManagerRW::cacheGroupKey(
const std::string& groupName,
TableGroupKey key)
756 allGroupInfo_[groupName].keys_.emplace(key);
768 const GroupInfo& ConfigurationManagerRW::getGroupInfo(
const std::string& groupName)
776 auto it = allGroupInfo_.find(groupName);
777 if(it == allGroupInfo_.end())
779 __SS__ <<
"Group name '" << groupName <<
"' not found in group info! (creating empty info)" << __E__;
780 __COUT_WARN__ << ss.str();
782 return allGroupInfo_[groupName];
798 TableGroupKey ConfigurationManagerRW::findTableGroup(
const std::string& groupName,
799 const std::map<std::string, TableVersion>& groupMemberMap,
800 const std::map<std::string /*name*/, std::string /*alias*/>& groupAliases)
806 const GroupInfo& groupInfo = getGroupInfo(groupName);
810 std::map<std::string ,
TableVersion > compareToMemberMap;
811 std::map<std::string , std::string > compareToGroupAliases;
814 const unsigned int MAX_DEPTH_TO_CHECK = 20;
815 unsigned int keyMinToCheck = 0;
817 if(groupInfo.keys_.size())
818 keyMinToCheck = groupInfo.keys_.rbegin()->key();
819 if(keyMinToCheck > MAX_DEPTH_TO_CHECK)
821 keyMinToCheck -= MAX_DEPTH_TO_CHECK;
822 __COUT__ <<
"Checking groups back to key... " << keyMinToCheck << __E__;
827 __COUT__ <<
"Checking all groups." << __E__;
832 for(
const auto& key : groupInfo.keys_)
836 if(key.key() < keyMinToCheck)
846 loadTableGroup(groupName,
849 &compareToMemberMap ,
857 &compareToGroupAliases);
860 for(
auto& memberPair : groupMemberMap)
864 if(groupAliases.find(memberPair.first) != groupAliases.end())
867 if(compareToGroupAliases.find(memberPair.first) == compareToGroupAliases.end() ||
868 groupAliases.at(memberPair.first) != compareToGroupAliases.at(memberPair.first))
877 else if(compareToGroupAliases.find(memberPair.first) != compareToGroupAliases.end())
885 else if(compareToMemberMap.find(memberPair.first) == compareToMemberMap.end() ||
886 memberPair.second != compareToMemberMap.at(memberPair.first))
897 if(groupMemberMap.size() != compareToMemberMap.size())
901 __COUT__ <<
"Found exact match with key: " << key << __E__;
905 __COUT__ <<
"No match found - this group is new!" << __E__;
917 TableGroupKey ConfigurationManagerRW::saveNewTableGroup(
const std::string& groupName,
918 std::map<std::string, TableVersion>& groupMembers,
919 const std::string& groupComment,
920 std::map<std::string /*table*/, std::string /*alias*/>* groupAliases)
928 if(groupMembers.size() == 0)
930 __SS__ <<
"Empty group member list. Can not create a group without members!" << __E__;
935 TableGroupKey newKey = TableGroupKey::getNextKey(theInterface_->findLatestGroupKey(groupName));
937 __COUT__ <<
"New Key for group: " << groupName <<
" found as " << newKey << __E__;
941 std::map<std::string, TableInfo> allCfgInfo = getAllTableInfo();
942 for(
auto& memberPair : groupMembers)
945 if(allCfgInfo.find(memberPair.first) == allCfgInfo.end())
947 __COUT_ERR__ <<
"Group member \"" << memberPair.first <<
"\" not found in database!";
949 if(groupMetadataTable_.getTableName() == memberPair.first)
951 __COUT_WARN__ <<
"Looks like this is the groupMetadataTable_ '" << ConfigurationInterface::GROUP_METADATA_TABLE_NAME
952 <<
".' Note that this table is added to the member map when groups "
954 <<
"It should not be part of member map when calling this function." << __E__;
955 __COUT__ <<
"Attempting to recover." << __E__;
956 groupMembers.erase(groupMembers.find(memberPair.first));
960 __SS__ << (
"Group member not found!") << __E__;
965 if(allCfgInfo[memberPair.first].versions_.find(memberPair.second) == allCfgInfo[memberPair.first].versions_.end())
967 __SS__ <<
"Group member \"" << memberPair.first <<
"\" version \"" << memberPair.second <<
"\" not found in database!";
975 for(
auto& aliasPair : *groupAliases)
978 if(groupMembers.find(aliasPair.first) == groupMembers.end())
980 __COUT_ERR__ <<
"Group member \"" << aliasPair.first <<
"\" not found in group member map!";
982 __SS__ << (
"Alias table not found in member list!") << __E__;
992 std::string groupAliasesString =
"";
994 groupAliasesString = StringMacros::mapToString(*groupAliases,
"," ,
":" );
995 __COUT__ <<
"Metadata: " << username_ <<
" " << time(0) <<
" " << groupComment <<
" " << groupAliasesString << __E__;
999 while(groupMetadataTable_.getViewP()->getNumberOfRows() > 1)
1000 groupMetadataTable_.getViewP()->deleteRow(0);
1001 if(groupMetadataTable_.getViewP()->getNumberOfRows() == 0)
1002 groupMetadataTable_.getViewP()->addRow();
1005 groupMetadataTable_.getViewP()->setValue(groupAliasesString, 0, ConfigurationManager::METADATA_COL_ALIASES);
1006 groupMetadataTable_.getViewP()->setValue(groupComment, 0, ConfigurationManager::METADATA_COL_COMMENT);
1007 groupMetadataTable_.getViewP()->setValue(username_, 0, ConfigurationManager::METADATA_COL_AUTHOR);
1008 groupMetadataTable_.getViewP()->setValue(time(0), 0, ConfigurationManager::METADATA_COL_TIMESTAMP);
1011 groupMetadataTable_.getViewP()->setVersion(TableVersion::getNextVersion(theInterface_->findLatestVersion(&groupMetadataTable_)));
1015 theInterface_->saveActiveVersion(&groupMetadataTable_);
1018 groupMembers[groupMetadataTable_.getTableName()] = groupMetadataTable_.getViewVersion();
1020 theInterface_->saveTableGroup(groupMembers, TableGroupKey::getFullGroupString(groupName, newKey));
1021 __COUT__ <<
"Created table group: " << groupName <<
":" << newKey << __E__;
1023 catch(std::runtime_error& e)
1025 __COUT_ERR__ <<
"Failed to create table group: " << groupName <<
":" << newKey << __E__;
1026 __COUT_ERR__ <<
"\n\n" << e.what() << __E__;
1031 __COUT_ERR__ <<
"Failed to create table group: " << groupName <<
":" << newKey << __E__;
1036 cacheGroupKey(groupName, newKey);
1048 __COUT_INFO__ <<
"Creating new backbone from temporary version " << temporaryVersion << __E__;
1053 auto backboneMemberNames = ConfigurationManager::getBackboneMemberNames();
1054 for(
auto& name : backboneMemberNames)
1056 retNewVersion = ConfigurationManager::getTableByName(name)->getNextVersion();
1057 __COUT__ <<
"New version for backbone member (" << name <<
"): " << retNewVersion << __E__;
1058 if(retNewVersion > newVersion)
1059 newVersion = retNewVersion;
1062 __COUT__ <<
"Common new backbone version found as " << newVersion << __E__;
1065 for(
auto& name : backboneMemberNames)
1068 retNewVersion = getConfigurationInterface()->saveNewVersion(getTableByName(name), temporaryVersion, newVersion);
1069 if(retNewVersion != newVersion)
1071 __SS__ <<
"Failure! New view requested was " << newVersion <<
". Mismatched new view created: " << retNewVersion << __E__;
1072 __COUT_ERR__ << ss.str();
1085 TableVersion ConfigurationManagerRW::saveModifiedVersion(
const std::string& tableName,
1090 bool ignoreDuplicates ,
1091 bool lookForEquivalent ,
1092 bool* foundEquivalent )
1094 bool needToEraseTemporarySource = (originalVersion.isTemporaryVersion() && !makeTemporary);
1097 *foundEquivalent =
false;
1100 if(!ignoreDuplicates)
1102 __COUT__ <<
"Checking for duplicate '" << tableName <<
"' tables..." << __E__;
1111 const std::map<std::string, TableInfo>& allTableInfo = getAllTableInfo();
1113 auto versionReverseIterator = allTableInfo.at(tableName).versions_.rbegin();
1114 __COUT__ <<
"Filling up '" << tableName <<
"' cache from " << table->getNumberOfStoredViews() <<
" to max count of " << table->MAX_VIEWS_IN_CACHE
1116 for(; table->getNumberOfStoredViews() < table->MAX_VIEWS_IN_CACHE && versionReverseIterator != allTableInfo.at(tableName).versions_.rend();
1117 ++versionReverseIterator)
1119 __COUT__ <<
"'" << tableName <<
"' versions in reverse order " << *versionReverseIterator << __E__;
1122 getVersionedTableByName(tableName, *versionReverseIterator);
1124 catch(
const std::runtime_error& e)
1135 __COUT__ <<
"Checking '" << tableName <<
"' duplicate..." << __E__;
1137 duplicateVersion = table->checkForDuplicate(
1138 temporaryModifiedVersion,
1139 (!originalVersion.isTemporaryVersion() && !makeTemporary) ?
TableVersion() :
1143 if(lookForEquivalent && !duplicateVersion.isInvalid())
1146 __COUT__ <<
"Equivalent '" << tableName <<
"' table found in version v" << duplicateVersion << __E__;
1149 if(duplicateVersion.isTemporaryVersion() && !makeTemporary)
1151 __COUT__ <<
"Need persistent. Duplicate '" << tableName
1152 <<
"' version was temporary. "
1153 "Abandoning duplicate."
1162 eraseTemporaryVersion(tableName, temporaryModifiedVersion);
1165 if(needToEraseTemporarySource)
1166 eraseTemporaryVersion(tableName, originalVersion);
1169 *foundEquivalent =
true;
1176 __COUT__ <<
"\t\t Equivalent '" << tableName <<
"' assigned version: " << duplicateVersion << __E__;
1178 return duplicateVersion;
1182 if(!duplicateVersion.isInvalid())
1184 __SS__ <<
"This version of table '" << tableName <<
"' is identical to another version currently cached v" << duplicateVersion
1185 <<
". No reason to save a duplicate." << __E__;
1186 __COUT_ERR__ <<
"\n" << ss.str();
1189 table->eraseView(temporaryModifiedVersion);
1193 __COUT__ <<
"Check for duplicate '" << tableName <<
"' tables complete." << __E__;
1197 __COUT__ <<
"\t\t**************************** Save as temporary '" << tableName <<
"' table version" << __E__;
1199 __COUT__ <<
"\t\t**************************** Save as new '" << tableName <<
"' table version" << __E__;
1201 TableVersion newAssignedVersion = saveNewTable(tableName, temporaryModifiedVersion, makeTemporary);
1203 if(needToEraseTemporarySource)
1204 eraseTemporaryVersion(tableName, originalVersion);
1209 __COUT__ <<
"\t\t '" << tableName <<
"' new assigned version: " << newAssignedVersion << __E__;
1210 return newAssignedVersion;
1214 GroupEditStruct::GroupEditStruct(
const ConfigurationManager::GroupType& groupType,
ConfigurationManagerRW* cfgMgr)
1215 : groupType_(groupType), originalGroupName_(cfgMgr->getActiveGroupName(groupType)), originalGroupKey_(cfgMgr->getActiveGroupKey(groupType)), cfgMgr_(cfgMgr)
1217 if(originalGroupName_ ==
"" || originalGroupKey_.isInvalid())
1219 __SS__ <<
"Error! No active group found for type '" << ConfigurationManager::convertGroupTypeToName(groupType)
1220 <<
".' There must be an active group to edit the group." << __E__;
1224 __COUT__ <<
"Extracting Group-Edit Struct for type " << ConfigurationManager::convertGroupTypeToName(groupType) << __E__;
1226 std::map<std::string, TableVersion> activeTables = cfgMgr->getActiveVersions();
1228 const std::set<std::string>& memberNames =
1229 groupType == ConfigurationManager::GroupType::CONTEXT_TYPE
1230 ? ConfigurationManager::getContextMemberNames()
1234 : cfgMgr->getConfigurationMemberNames()));
1236 for(
auto& memberName : memberNames)
1240 groupMembers_.emplace(std::make_pair(memberName, activeTables.at(memberName)));
1242 groupTables_.emplace(std::make_pair(memberName,
TableEditStruct(memberName, cfgMgr)));
1246 __SS__ <<
"Error! Could not find group member table '" << memberName <<
"' for group type '"
1247 << ConfigurationManager::convertGroupTypeToName(groupType) <<
".' All group members must be present to create the group editing structure."
1255 GroupEditStruct::~GroupEditStruct()
1257 __COUT__ <<
"GroupEditStruct from editing '" << originalGroupName_ <<
"(" << originalGroupKey_ <<
")' Destructing..." << __E__;
1259 __COUT__ <<
"GroupEditStruct from editing '" << originalGroupName_ <<
"(" << originalGroupKey_ <<
")' Desctructed." << __E__;
1264 TableEditStruct& GroupEditStruct::getTableEditStruct(
const std::string& tableName,
bool markModified )
1266 auto it = groupTables_.find(tableName);
1267 if(it == groupTables_.end())
1269 if(groupType_ == ConfigurationManager::GroupType::CONFIGURATION_TYPE && markModified)
1271 __COUT__ <<
"Table '" << tableName <<
"' not found in configuration table members from editing '" << originalGroupName_ <<
"(" << originalGroupKey_
1273 <<
" Attempting to add it!" << __E__;
1276 auto newIt = groupTables_.emplace(std::make_pair(tableName,
TableEditStruct(tableName, cfgMgr_)));
1279 newIt.first->second.modified_ = markModified;
1280 groupMembers_.emplace(std::make_pair(tableName, newIt.first->second.temporaryVersion_));
1281 return newIt.first->second;
1283 __COUT_ERR__ <<
"Failed to emplace new table..." << __E__;
1286 __SS__ <<
"Table '" << tableName <<
"' not found in table members from editing '" << originalGroupName_ <<
"(" << originalGroupKey_ <<
")!'" << __E__;
1289 it->second.modified_ = markModified;
1294 void GroupEditStruct::dropChanges()
1296 __COUT__ <<
"Dropping unsaved changes from editing '" << originalGroupName_ <<
"(" << originalGroupKey_ <<
")'..." << __E__;
1301 for(
auto& groupTable : groupTables_)
1302 if(groupTable.second.createdTemporaryVersion_)
1307 cfgMgr->eraseTemporaryVersion(groupTable.second.tableName_, groupTable.second.temporaryVersion_);
1308 groupTable.second.createdTemporaryVersion_ =
false;
1309 groupTable.second.modified_ =
false;
1312 __COUT__ <<
"Unsaved changes dropped from editing '" << originalGroupName_ <<
"(" << originalGroupKey_ <<
").'" << __E__;
1316 void GroupEditStruct::saveChanges(
const std::string& groupNameToSave,
1318 bool* foundEquivalentGroupKey ,
1319 bool activateNewGroup ,
1320 bool updateGroupAliases ,
1321 bool updateTableAliases ,
1323 bool* foundEquivalentBackboneKey ,
1324 std::string* accumulatedWarnings )
1326 __COUT__ <<
"Saving changes..." << __E__;
1331 if(foundEquivalentBackboneKey)
1332 *foundEquivalentBackboneKey =
false;
1336 for(
auto& groupTable : groupTables_)
1338 if(!groupTable.second.modified_)
1341 __COUT__ <<
"Original version is " << groupTable.second.tableName_ <<
"-v" << groupTable.second.originalVersion_ << __E__;
1343 groupMembers_.at(groupTable.first) =
1344 cfgMgr->saveModifiedVersion(groupTable.second.tableName_,
1345 groupTable.second.originalVersion_,
1347 groupTable.second.table_,
1348 groupTable.second.temporaryVersion_,
1351 __COUT__ <<
"Temporary target version is " << groupTable.second.tableName_ <<
"-v" << groupMembers_.at(groupTable.first) <<
"-v"
1352 << groupTable.second.temporaryVersion_ << __E__;
1354 groupMembers_.at(groupTable.first) = cfgMgr->saveModifiedVersion(groupTable.second.tableName_,
1355 groupTable.second.originalVersion_,
1357 groupTable.second.table_,
1358 groupTable.second.temporaryVersion_,
1362 __COUT__ <<
"Final target version is " << groupTable.second.tableName_ <<
"-v" << groupMembers_.at(groupTable.first) << __E__;
1364 groupTable.second.modified_ =
false;
1365 groupTable.second.createdTemporaryVersion_ =
false;
1368 for(
auto& table : groupMembers_)
1370 __COUT__ << table.first <<
" v" << table.second << __E__;
1373 __COUT__ <<
"Checking for duplicate groups..." << __E__;
1374 newGroupKey = cfgMgr->findTableGroup(groupNameToSave, groupMembers_);
1376 if(!newGroupKey.isInvalid())
1378 __COUT__ <<
"Found equivalent group key (" << newGroupKey <<
") for " << groupNameToSave <<
"." << __E__;
1379 if(foundEquivalentGroupKey)
1380 *foundEquivalentGroupKey =
true;
1384 newGroupKey = cfgMgr->saveNewTableGroup(groupNameToSave, groupMembers_);
1385 __COUT__ <<
"Saved new Context group key (" << newGroupKey <<
") for " << groupNameToSave <<
"." << __E__;
1388 bool groupAliasChange =
false;
1389 bool tableAliasChange =
false;
1391 GroupEditStruct backboneGroupEdit(ConfigurationManager::GroupType::BACKBONE_TYPE, cfgMgr);
1393 if(groupType_ != ConfigurationManager::GroupType::BACKBONE_TYPE && updateGroupAliases)
1398 TableEditStruct& groupAliasTable = backboneGroupEdit.getTableEditStruct(ConfigurationManager::GROUP_ALIASES_TABLE_NAME,
true );
1399 TableView* tableView = groupAliasTable.tableView_;
1402 unsigned int row = 0;
1404 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs = cfgMgr->getNode(ConfigurationManager::GROUP_ALIASES_TABLE_NAME).getChildren();
1405 std::string groupName, groupKey;
1406 for(
auto& aliasNodePair : aliasNodePairs)
1408 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
1409 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
1411 __COUT__ <<
"Group Alias: " << aliasNodePair.first <<
" => " << groupName <<
"(" << groupKey <<
"); row=" << row << __E__;
1413 if(groupName == originalGroupName_ &&
TableGroupKey(groupKey) == originalGroupKey_)
1415 __COUT__ <<
"Found alias! Changing group key from (" << originalGroupKey_ <<
") to (" << newGroupKey <<
")" << __E__;
1417 groupAliasChange =
true;
1419 tableView->setValueAsString(newGroupKey.toString(), row, tableView->findCol(
"GroupKey"));
1425 if(groupAliasChange)
1427 std::stringstream ss;
1428 tableView->print(ss);
1429 __COUT__ << ss.str();
1475 if(groupType_ != ConfigurationManager::GroupType::BACKBONE_TYPE && updateTableAliases)
1478 TableView* tableView = backboneGroupEdit.getTableEditStruct(ConfigurationManager::VERSION_ALIASES_TABLE_NAME,
true ).tableView_;
1480 for(
auto& groupTable : groupTables_)
1482 if(groupTable.second.originalVersion_ == groupMembers_.at(groupTable.second.tableName_))
1485 __COUT__ <<
"Checking alias... original version is " << groupTable.second.tableName_ <<
"-v" << groupTable.second.originalVersion_
1486 <<
" and new version is v" << groupMembers_.at(groupTable.second.tableName_) << __E__;
1489 unsigned int row = 0;
1491 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
1492 cfgMgr->getNode(ConfigurationManager::VERSION_ALIASES_TABLE_NAME).getChildren();
1493 std::string tableName, tableVersion;
1494 for(
auto& aliasNodePair : aliasNodePairs)
1496 tableName = aliasNodePair.second.getNode(
"TableName").getValueAsString();
1497 tableVersion = aliasNodePair.second.getNode(
"Version").getValueAsString();
1499 __COUT__ <<
"Table Alias: " << aliasNodePair.first <<
" => " << tableName <<
"-v" << tableVersion <<
"" << __E__;
1501 if(tableName == groupTable.second.tableName_ &&
TableVersion(tableVersion) == groupTable.second.originalVersion_)
1503 __COUT__ <<
"Found alias! Changing icon table version alias." << __E__;
1505 tableAliasChange =
true;
1507 tableView->setValueAsString(groupMembers_.at(groupTable.second.tableName_).toString(), row, tableView->findCol(
"Version"));
1514 if(tableAliasChange)
1516 std::stringstream ss;
1517 tableView->print(ss);
1518 __COUT__ << ss.str();
1525 if(groupAliasChange || tableAliasChange)
1527 for(
auto& table : backboneGroupEdit.groupMembers_)
1529 __COUT__ << table.first <<
" v" << table.second << __E__;
1531 backboneGroupEdit.saveChanges(
1532 backboneGroupEdit.originalGroupName_, localNewBackboneKey, foundEquivalentBackboneKey ? foundEquivalentBackboneKey :
nullptr);
1535 *newBackboneKey = localNewBackboneKey;
1541 __COUT__ <<
"Restoring active table groups, before activating new groups..." << __E__;
1543 std::string localAccumulatedWarnings;
1544 cfgMgr->restoreActiveTableGroups(
1545 false ,
"" ,
false , &localAccumulatedWarnings);
1549 if(!localNewBackboneKey.isInvalid())
1550 cfgMgr->activateTableGroup(backboneGroupEdit.originalGroupName_, localNewBackboneKey, accumulatedWarnings ? accumulatedWarnings :
nullptr);
1552 if(activateNewGroup)
1553 cfgMgr->activateTableGroup(groupNameToSave, newGroupKey, accumulatedWarnings ? accumulatedWarnings :
nullptr);
1555 __COUT__ <<
"Changes saved." << __E__;
1559 void ConfigurationManagerRW::testXDAQContext()
1563 __COUT__ <<
"Loading table..." << __E__;
1571 __COUT__ <<
"Value: " << v << __E__;
1572 __COUT__ <<
"Value index: " << t.getValue<
int>() << __E__;
1578 __COUT__ <<
"Failed to load table..." << __E__;