1 #include "otsdaq/ConfigurationInterface/ConfigurationManagerRW.h"
9 #define __MF_SUBJECT__ "ConfigurationManagerRW"
11 #define TABLE_INFO_PATH std::string(__ENV__("TABLE_INFO_PATH")) + "/"
12 #define TABLE_INFO_EXT "Info.xml"
14 #define CORE_TABLE_INFO_FILENAME \
15 ((getenv("SERVICE_DATA_PATH") == NULL) \
16 ? (std::string(__ENV__("USER_DATA")) + "/ServiceData") \
17 : (std::string(__ENV__("SERVICE_DATA_PATH")))) + \
18 "/CoreTableInfoNames.dat"
20 std::atomic<bool> ConfigurationManagerRW::firstTimeConstructed_ =
true;
22 std::mutex ConfigurationManagerRW::versionCreationTimeCacheMutex_;
23 std::map<std::string, std::map<TableVersion, time_t>>
24 ConfigurationManagerRW::versionCreationTimeCache_;
31 __GEN_COUT__ <<
"Instantiating Config Manager with Write Access! (for " << username
32 <<
") time=" << time(0) <<
" runTimeSeconds()=" << runTimeSeconds()
35 theInterface_ = ConfigurationInterface::getInstance(
36 ConfigurationInterface::CONFIGURATION_MODE::
42 if(firstTimeConstructed_)
44 firstTimeConstructed_ =
false;
47 mkdir((ConfigurationManager::LAST_TABLE_GROUP_SAVE_PATH).c_str(), 0755);
49 const std::set<std::string>& contextMemberNames = getFixedContextMemberNames();
50 const std::set<std::string>& backboneMemberNames = getBackboneMemberNames();
51 const std::set<std::string>& iterateMemberNames = getIterateMemberNames();
53 FILE* fp = fopen((CORE_TABLE_INFO_FILENAME).c_str(),
"r");
57 std::vector<unsigned int> foundVector;
59 for(
const auto& name : contextMemberNames)
61 foundVector.push_back(
false);
63 while(fgets(line, 100, fp))
67 line[strlen(line) - 1] =
'\0';
68 if(strcmp(line, (
"ContextGroup/" + name).c_str()) == 0)
70 foundVector.back() =
true;
76 for(
const auto& name : backboneMemberNames)
78 foundVector.push_back(
false);
80 while(fgets(line, 100, fp))
84 line[strlen(line) - 1] =
'\0';
85 if(strcmp(line, (
"BackboneGroup/" + name).c_str()) == 0)
87 foundVector.back() =
true;
93 for(
const auto& name : iterateMemberNames)
95 foundVector.push_back(
false);
97 while(fgets(line, 100, fp))
101 line[strlen(line) - 1] =
'\0';
102 if(strcmp(line, (
"IterateGroup/" + name).c_str()) == 0)
104 foundVector.back() =
true;
112 foundVector.push_back(
false);
114 while(fgets(line, 100, fp))
118 line[strlen(line) - 1] =
'\0';
121 ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE)
124 foundVector.back() =
true;
133 fp = fopen((CORE_TABLE_INFO_FILENAME).c_str(),
"a");
137 for(
const auto& name : contextMemberNames)
140 fprintf(fp,
"\nContextGroup/%s", name.c_str());
144 for(
const auto& name : backboneMemberNames)
147 fprintf(fp,
"\nBackboneGroup/%s", name.c_str());
151 for(
const auto& name : iterateMemberNames)
154 fprintf(fp,
"\nIterateGroup/%s", name.c_str());
164 ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE.c_str());
170 __SS__ <<
"Failed to open core table info file for appending: "
171 << CORE_TABLE_INFO_FILENAME << __E__;
177 fp = fopen((CORE_TABLE_INFO_FILENAME).c_str(),
"w");
180 fprintf(fp,
"ARTDAQ/*");
181 fprintf(fp,
"\nConfigCore/*");
182 for(
const auto& name : contextMemberNames)
183 fprintf(fp,
"\nContextGroup/%s", name.c_str());
184 for(
const auto& name : backboneMemberNames)
185 fprintf(fp,
"\nBackboneGroup/%s", name.c_str());
186 for(
const auto& name : iterateMemberNames)
187 fprintf(fp,
"\nIterateGroup/%s", name.c_str());
192 __SS__ <<
"Failed to open core table info file: "
193 << CORE_TABLE_INFO_FILENAME << __E__;
199 __GEN_COUTV__(runTimeSeconds());
211 std::string* accumulatedWarnings ,
212 const std::string& errorFilterName ,
215 bool initializeActiveGroups )
220 return allTableInfo_;
223 allTableInfo_.clear();
230 __GEN_COUT__ <<
"======================================================== "
231 "getAllTableInfo start runTimeSeconds()="
232 << runTimeSeconds() << __E__;
234 __GEN_COUT__ <<
"Refreshing all! Extracting list of tables..." << __E__;
236 struct dirent* entry;
237 std::string path = TABLE_INFO_PATH;
238 char fileExt[] = TABLE_INFO_EXT;
239 const unsigned char MIN_TABLE_NAME_SZ = 3;
241 const int numOfThreads = StringMacros::getConcurrencyCount() / 2;
242 __GEN_COUT__ <<
" getConcurrencyCount " << StringMacros::getConcurrencyCount()
243 <<
" ==> " << numOfThreads <<
" threads." << __E__;
246 if((pDIR = opendir(path.c_str())) != 0)
248 while((entry = readdir(pDIR)) != 0)
251 if(strlen(entry->d_name) < strlen(fileExt) + MIN_TABLE_NAME_SZ)
255 if(strcmp(&(entry->d_name[strlen(entry->d_name) - strlen(fileExt)]),
259 entry->d_name[strlen(entry->d_name) - strlen(fileExt)] =
267 theInterface_->get(table,
273 catch(cet::exception
const&)
279 __GEN_COUT__ <<
"Skipping! No valid class found for... "
280 << entry->d_name <<
"\n";
283 catch(std::runtime_error& e)
289 __GEN_COUT__ <<
"Skipping! No valid class found for... "
290 << entry->d_name <<
"\n";
291 __GEN_COUT__ <<
"Error: " << e.what() << __E__;
296 if(accumulatedWarnings)
298 if(errorFilterName ==
"" || errorFilterName == entry->d_name)
300 *accumulatedWarnings += std::string(
"\nIn table '") +
301 entry->d_name +
"'..." +
304 __SS__ <<
"Attempting to allow illegal columns!" << __E__;
305 *accumulatedWarnings += ss.str();
309 __GEN_COUT__ <<
"Attempting to allow illegal columns!"
312 std::string returnedAccumulatedErrors;
316 &returnedAccumulatedErrors);
320 __GEN_COUT__ <<
"Skipping! Allowing illegal columns "
321 "didn't work either... "
322 << entry->d_name <<
"\n";
326 <<
"Error (but allowed): " << returnedAccumulatedErrors
329 if(errorFilterName ==
"" || errorFilterName == entry->d_name)
330 *accumulatedWarnings +=
331 std::string(
"\nIn table '") + entry->d_name +
"'..." +
332 returnedAccumulatedErrors;
338 if(nameToTableMap_[entry->d_name])
341 std::set<TableVersion> versions =
342 nameToTableMap_[entry->d_name]->getStoredVersions();
343 for(
auto& version : versions)
344 if(version.isTemporaryVersion())
348 nameToTableMap_[entry->d_name]->setActiveView(
351 nameToTableMap_[entry->d_name]->getView(),
362 delete nameToTableMap_[entry->d_name];
363 nameToTableMap_[entry->d_name] = 0;
366 nameToTableMap_[entry->d_name] = table;
368 allTableInfo_[entry->d_name].tablePtr_ = table;
369 allTableInfo_[entry->d_name].versions_ =
370 theInterface_->getVersions(table);
374 std::set<TableVersion> versions =
375 nameToTableMap_[entry->d_name]->getStoredVersions();
376 for(
auto& version : versions)
377 if(version.isTemporaryVersion())
379 allTableInfo_[entry->d_name].versions_.emplace(version);
387 int threadsLaunched = 0;
388 int foundThreadIndex = 0;
389 std::string tableName;
391 std::vector<std::shared_ptr<std::atomic<bool>>> threadDone;
392 for(
int i = 0; i < numOfThreads; ++i)
393 threadDone.push_back(std::make_shared<std::atomic<bool>>(
true));
395 std::vector<std::shared_ptr<ots::TableInfo>> sharedTableInfoPtrs;
397 if((pDIR = opendir(path.c_str())) != 0)
399 while((entry = readdir(pDIR)) != 0)
402 if(strlen(entry->d_name) < strlen(fileExt) + MIN_TABLE_NAME_SZ)
406 if(strcmp(&(entry->d_name[strlen(entry->d_name) - strlen(fileExt)]),
410 entry->d_name[strlen(entry->d_name) - strlen(fileExt)] =
417 sharedTableInfoPtrs.push_back(std::make_shared<ots::TableInfo>());
418 sharedTableInfoPtrs.back()->accumulatedWarnings_ =
419 accumulatedWarnings ?
"ALLOW"
422 if(threadsLaunched >= numOfThreads)
425 foundThreadIndex = -1;
427 while(foundThreadIndex == -1)
429 for(
int i = 0; i < numOfThreads; ++i)
432 foundThreadIndex = i;
435 if(foundThreadIndex == -1)
437 __GEN_COUT_TYPE__(TLVL_DEBUG + 2)
439 <<
"Waiting for available thread... iteration # "
443 __GEN_SS__ <<
"Threads seem to be stuck getting "
444 "table info! Timeout while waiting..."
451 threadsLaunched = numOfThreads - 1;
453 __GEN_COUTT__ <<
"Starting thread... " << foundThreadIndex
454 <<
" for table " << tableName << __E__;
456 *(threadDone[foundThreadIndex]) =
false;
459 std::string theTableName,
461 std::shared_ptr<ots::TableInfo> theTableInfo,
462 std::shared_ptr<std::atomic<bool>> theThreadDone) {
471 nameToTableMap_[tableName],
472 sharedTableInfoPtrs.back(),
473 threadDone[foundThreadIndex])
485 foundThreadIndex = -1;
486 for(
int i = 0; i < numOfThreads; ++i)
487 if(!*(threadDone[i]))
489 foundThreadIndex = i;
492 if(foundThreadIndex != -1)
494 __GEN_COUTT__ <<
"Waiting for thread to finish... "
495 << foundThreadIndex << __E__;
498 }
while(foundThreadIndex != -1);
501 for(
auto& tableInfo : sharedTableInfoPtrs)
503 if(tableInfo->tablePtr_ ==
nullptr)
505 __SS__ <<
"Fatal error occurred loading table info into cache! "
506 "Perhaps there is an illegal Table schema definition? "
507 "Check logs to resolve."
511 __GEN_COUT_TYPE__(TLVL_DEBUG + 3)
512 << __COUT_HDR__ <<
"Copying table info for "
513 << tableInfo->tablePtr_->getTableName() << __E__;
514 nameToTableMap_[tableInfo->tablePtr_->getTableName()] =
515 tableInfo->tablePtr_;
516 allTableInfo_[tableInfo->tablePtr_->getTableName()].tablePtr_ =
517 tableInfo->tablePtr_;
518 allTableInfo_[tableInfo->tablePtr_->getTableName()].versions_ =
519 tableInfo->versions_;
522 __GEN_COUT__ <<
"Extracting list of tables complete." << __E__;
526 if(initializeActiveGroups)
528 __GEN_COUT__ <<
"Now initializing..." << __E__;
530 std::string tmpAccumulateWarnings;
533 accumulatedWarnings ? &tmpAccumulateWarnings :
nullptr);
535 if(accumulatedWarnings && errorFilterName ==
"")
536 *accumulatedWarnings += tmpAccumulateWarnings;
538 __GEN_COUT__ <<
"======================================================== "
539 "getAllTableInfo end runTimeSeconds()="
540 << runTimeSeconds() << __E__;
545 allGroupInfo_.clear();
550 std::set<std::string > tableGroups =
551 theInterface_->getAllTableGroupNames();
552 __GEN_COUT__ <<
"Number of Groups: " << tableGroups.size() << __E__;
554 __GEN_COUTT__ <<
"Group Info start runTimeSeconds()=" << runTimeSeconds()
559 for(
const auto& fullName : tableGroups)
562 allGroupInfo_[name].keys_.emplace(key);
565 __GEN_COUTT__ <<
"Group Keys end runTimeSeconds()=" << runTimeSeconds()
571 const int numOfThreads = StringMacros::getConcurrencyCount() / 2;
572 __GEN_COUT__ <<
" getConcurrencyCount "
573 << StringMacros::getConcurrencyCount() <<
" ==> "
574 << numOfThreads <<
" threads." << __E__;
576 for(
auto& groupInfo : allGroupInfo_)
580 groupInfo.second.latestKey_ = groupInfo.second.getLastKey();
583 groupInfo.second.latestKey_,
585 &groupInfo.second.latestKeyMemberMap_ ,
588 &groupInfo.second.latestKeyGroupComment_,
589 &groupInfo.second.latestKeyGroupAuthor_,
590 &groupInfo.second.latestKeyGroupCreationTime_,
592 &groupInfo.second.latestKeyGroupTypeString_);
596 __GEN_COUT_WARN__ <<
"Error occurred loading latest group "
597 "info into cache for '"
598 << groupInfo.first <<
"("
599 << groupInfo.second.latestKey_ <<
")'..."
601 groupInfo.second.latestKey_ = TableGroupKey::INVALID;
602 groupInfo.second.latestKeyGroupComment_ =
603 ConfigurationManager::UNKNOWN_INFO;
604 groupInfo.second.latestKeyGroupAuthor_ =
605 ConfigurationManager::UNKNOWN_INFO;
606 groupInfo.second.latestKeyGroupCreationTime_ =
607 ConfigurationManager::UNKNOWN_TIME;
608 groupInfo.second.latestKeyGroupTypeString_ =
609 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
610 groupInfo.second.latestKeyMemberMap_ = {};
615 int threadsLaunched = 0;
616 int foundThreadIndex = 0;
618 std::vector<std::shared_ptr<std::atomic<bool>>> threadDone;
619 for(
int i = 0; i < numOfThreads; ++i)
620 threadDone.push_back(std::make_shared<std::atomic<bool>>(
true));
622 std::vector<std::shared_ptr<ots::GroupInfo>> sharedGroupInfoPtrs;
624 for(
auto& groupInfo : allGroupInfo_)
627 sharedGroupInfoPtrs.push_back(std::make_shared<ots::GroupInfo>());
629 if(threadsLaunched >= numOfThreads)
632 foundThreadIndex = -1;
633 while(foundThreadIndex == -1)
635 for(
int i = 0; i < numOfThreads; ++i)
638 foundThreadIndex = i;
641 if(foundThreadIndex == -1)
643 __GEN_COUTT__ <<
"Waiting for available thread..."
648 threadsLaunched = numOfThreads - 1;
650 __GEN_COUTT__ <<
"Starting thread... " << foundThreadIndex
651 <<
" for " << groupInfo.first <<
"("
652 << groupInfo.second.getLastKey() <<
")" << __E__;
654 *(threadDone[foundThreadIndex]) =
false;
658 std::string theGroupName,
660 std::shared_ptr<ots::GroupInfo> theGroupInfo,
661 std::shared_ptr<std::atomic<bool>> theThreadDone) {
671 groupInfo.second.getLastKey(),
672 sharedGroupInfoPtrs.back(),
673 threadDone[foundThreadIndex])
683 foundThreadIndex = -1;
684 for(
int i = 0; i < numOfThreads; ++i)
685 if(!*(threadDone[i]))
687 foundThreadIndex = i;
690 if(foundThreadIndex != -1)
692 __GEN_COUTT__ <<
"Waiting for thread to finish... "
693 << foundThreadIndex << __E__;
696 }
while(foundThreadIndex != -1);
700 for(
auto& groupInfo : allGroupInfo_)
702 groupInfo.second.latestKey_ = sharedGroupInfoPtrs[i]->latestKey_;
703 groupInfo.second.latestKeyGroupComment_ =
704 sharedGroupInfoPtrs[i]->latestKeyGroupComment_;
705 groupInfo.second.latestKeyGroupAuthor_ =
706 sharedGroupInfoPtrs[i]->latestKeyGroupAuthor_;
707 groupInfo.second.latestKeyGroupCreationTime_ =
708 sharedGroupInfoPtrs[i]->latestKeyGroupCreationTime_;
709 groupInfo.second.latestKeyGroupTypeString_ =
710 sharedGroupInfoPtrs[i]->latestKeyGroupTypeString_;
711 groupInfo.second.latestKeyMemberMap_ =
712 sharedGroupInfoPtrs[i]->latestKeyMemberMap_;
719 catch(
const std::runtime_error& e)
722 <<
"A fatal error occurred reading the info for all table groups. Error: "
723 << e.what() << __E__;
724 __GEN_COUT_ERR__ <<
"Error at time: " << time(0) <<
"\n" << ss.str();
725 if(accumulatedWarnings)
726 *accumulatedWarnings += ss.str();
732 __SS__ <<
"An unknown fatal error occurred reading the info for all table "
739 catch(
const std::exception& e)
741 ss <<
"Exception message: " << e.what();
746 __GEN_COUT_ERR__ <<
"\n" << ss.str();
747 if(accumulatedWarnings)
748 *accumulatedWarnings += ss.str();
752 __GEN_COUTT__ <<
"Group Info end runTimeSeconds()=" << runTimeSeconds() << __E__;
755 __GEN_COUTT__ <<
"Table Info end runTimeSeconds()=" << runTimeSeconds() << __E__;
757 return allTableInfo_;
764 std::string tableName,
766 std::shared_ptr<ots::TableInfo> tableInfo,
767 std::shared_ptr<std::atomic<bool>> threadDone)
770 __COUTT__ <<
"Thread started... table " << tableName << __E__;
773 tableInfo->tablePtr_ = 0;
777 cfgMgr->theInterface_->get(tableInfo->tablePtr_,
783 catch(cet::exception
const&)
785 if(tableInfo->tablePtr_)
786 delete tableInfo->tablePtr_;
787 tableInfo->tablePtr_ = 0;
789 __COUT__ <<
"Skipping! No valid class found for... " << tableName <<
"\n";
790 *(threadDone) =
true;
793 catch(std::runtime_error& e)
795 if(tableInfo->tablePtr_)
796 delete tableInfo->tablePtr_;
797 tableInfo->tablePtr_ = 0;
799 __COUT__ <<
"Skipping! No valid class found for... " << tableName <<
"\n";
800 __COUTT__ <<
"Error: " << e.what() << __E__;
805 if(tableInfo->accumulatedWarnings_ ==
"ALLOW")
807 tableInfo->accumulatedWarnings_ =
"";
810 tableInfo->accumulatedWarnings_ += std::string(
"\nIn table '") +
814 __SS__ <<
"Attempting to allow illegal columns!" << __E__;
815 tableInfo->accumulatedWarnings_ += ss.str();
819 __COUT__ <<
"Attempting to allow illegal columns!" << __E__;
821 std::string returnedAccumulatedErrors;
824 tableInfo->tablePtr_ =
825 new TableBase(tableName, &returnedAccumulatedErrors);
829 __COUT__ <<
"Skipping! Allowing illegal columns didn't work either... "
830 << tableName <<
"\n";
831 *(threadDone) =
true;
834 __COUT_WARN__ <<
"Error (but allowed): " << returnedAccumulatedErrors
838 tableInfo->accumulatedWarnings_ +=
839 std::string(
"\nIn table '") + tableName +
"'..." +
840 returnedAccumulatedErrors;
844 tableInfo->accumulatedWarnings_ =
"";
845 *(threadDone) =
true;
852 __COUTT__ <<
"Copying temporary version from existing table object for "
853 << tableName << __E__;
855 std::set<TableVersion> versions = existingTable->getStoredVersions();
856 for(
auto& version : versions)
857 if(version.isTemporaryVersion())
861 existingTable->setActiveView(version);
862 tableInfo->tablePtr_->copyView(
863 existingTable->getView(),
873 delete existingTable;
877 tableInfo->versions_ = cfgMgr->theInterface_->getVersions(tableInfo->tablePtr_);
881 std::set<TableVersion> versions = tableInfo->tablePtr_->getStoredVersions();
882 for(
auto& version : versions)
883 if(version.isTemporaryVersion())
885 tableInfo->versions_.emplace(version);
888 __COUTT__ <<
"Thread done... table " << tableName << __E__;
889 *(threadDone) =
true;
893 __COUT_ERR__ <<
"Error occurred loading latest table info into cache for '"
894 << tableName <<
"'..." << __E__;
895 *(threadDone) =
true;
902 const std::string& groupName,
905 std::map<std::string /*table name*/, TableVersion>*
908 std::string* accumulatedWarnings ,
909 std::string* groupComment ,
910 std::string* groupAuthor ,
911 std::string* groupCreateTime ,
912 bool doNotLoadMembers ,
913 std::string* groupTypeString ,
914 std::map<std::string /*name*/, std::string /*alias*/>*
916 ConfigurationManager::LoadGroupType
918 bool ignoreVersionTracking )
933 ignoreVersionTracking);
935 if(!groupMembers || !groupMembers->size() || !groupComment || groupKey.
isInvalid() ||
936 !groupAuthor || !groupCreateTime)
940 auto groupInfo = allGroupInfo_.find(groupName);
941 if(groupInfo == allGroupInfo_.end())
944 groupInfo->second.latestKey_ = groupKey;
945 groupInfo->second.latestKeyGroupComment_ = *groupComment;
946 groupInfo->second.latestKeyGroupAuthor_ = *groupAuthor;
947 groupInfo->second.latestKeyGroupCreationTime_ = *groupCreateTime;
949 groupInfo->second.latestKeyGroupTypeString_ = *groupTypeString;
950 groupInfo->second.latestKeyMemberMap_ = *groupMembers;
958 std::string groupName,
960 std::shared_ptr<ots::GroupInfo> groupInfo,
961 std::shared_ptr<std::atomic<bool>> threadDone)
964 __COUTT__ <<
"Thread started... " << groupName <<
"(" << groupKey <<
")" << __E__;
966 groupInfo->latestKey_ = groupKey;
970 &(groupInfo->latestKeyMemberMap_) ,
973 &(groupInfo->latestKeyGroupComment_),
974 &(groupInfo->latestKeyGroupAuthor_),
975 &(groupInfo->latestKeyGroupCreationTime_),
977 &(groupInfo->latestKeyGroupTypeString_));
979 *(threadDone) =
true;
983 __COUT_WARN__ <<
"Error occurred loading latest group info into cache for '"
984 << groupName <<
"(" << groupInfo->latestKey_ <<
")'..." << __E__;
985 groupInfo->latestKey_ = TableGroupKey::INVALID;
986 groupInfo->latestKeyGroupComment_ = ConfigurationManager::UNKNOWN_INFO;
987 groupInfo->latestKeyGroupAuthor_ = ConfigurationManager::UNKNOWN_INFO;
988 groupInfo->latestKeyGroupCreationTime_ = ConfigurationManager::UNKNOWN_TIME;
989 groupInfo->latestKeyGroupTypeString_ = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
990 groupInfo->latestKeyMemberMap_ = {};
991 *(threadDone) =
true;
1000 std::string groupName,
1002 const std::map<std::string, TableVersion>& groupMemberMap,
1003 const std::map<std::string /*name*/, std::string /*alias*/>& memberTableAliases,
1004 std::atomic<bool>* foundIdentical,
1006 std::mutex* threadMutex,
1007 std::shared_ptr<std::atomic<bool>> threadDone)
1010 std::map<std::string ,
TableVersion > compareToMemberMap;
1011 std::map<std::string , std::string > compareToMemberTableAliases;
1012 std::map<std::string , std::string >*
1013 compareToMemberTableAliasesPtr =
nullptr;
1014 if(memberTableAliases
1016 compareToMemberTableAliasesPtr = &compareToMemberTableAliases;
1021 &compareToMemberMap ,
1029 compareToMemberTableAliasesPtr);
1035 for(
auto& memberPair : groupMemberMap)
1036 __COUTS__(9) <<
"member " << memberPair.first <<
" (" << memberPair.second
1038 for(
auto& memberPair : compareToMemberMap)
1039 __COUTS__(9) <<
"compare " << groupName <<
" (" << groupKeyToCompare
1040 <<
") member:" << memberPair.first <<
" (" << memberPair.second
1044 bool isDifferent =
false;
1045 for(
auto& memberPair : groupMemberMap)
1049 if(memberTableAliases.find(memberPair.first) != memberTableAliases.end())
1052 if(compareToMemberTableAliases.find(memberPair.first) ==
1053 compareToMemberTableAliases.end() ||
1054 memberTableAliases.at(memberPair.first) !=
1055 compareToMemberTableAliases.at(memberPair.first))
1059 __COUTT__ <<
"diff " << groupName <<
" (" << groupKeyToCompare
1060 <<
") on alias " << memberPair.first << __E__;
1064 else if(compareToMemberTableAliases.find(memberPair.first) !=
1065 compareToMemberTableAliases.end())
1070 __COUTT__ <<
"diff " << groupName <<
" (" << groupKeyToCompare
1071 <<
") on reverse alias " << memberPair.first << __E__;
1077 if(compareToMemberMap.find(memberPair.first) ==
1078 compareToMemberMap.end() ||
1079 memberPair.second !=
1080 compareToMemberMap.at(memberPair.first))
1085 __COUTT__ <<
"diff " << groupName <<
" (" << groupKeyToCompare
1086 <<
") on mismatch " << memberPair.first << __E__;
1093 groupMemberMap.size() !=
1100 __COUTT__ <<
"diff " << groupName <<
" (" << groupKeyToCompare <<
") on size "
1106 *foundIdentical =
true;
1107 __COUT__ <<
"=====> Found exact match with key: " << groupKeyToCompare << __E__;
1109 std::lock_guard<std::mutex> lock(*threadMutex);
1110 *identicalKey = groupKeyToCompare;
1113 *(threadDone) =
true;
1117 __COUT_WARN__ <<
"Error occurred comparing group '" << groupName <<
"("
1118 << groupKeyToCompare <<
")'..." << __E__;
1120 *(threadDone) =
true;
1127 std::map<std::string ,
1131 std::map<std::string ,
1137 if(!ConfigurationInterface::isVersionTrackingEnabled())
1138 for(
const auto& tableInfo : allTableInfo_)
1139 for(
const auto& version : tableInfo.second.versions_)
1140 if(version.isScratchVersion())
1141 retMap[tableInfo.first][ConfigurationManager::SCRATCH_VERSION_ALIAS] =
1153 std::string* accumulatedTreeErrors,
1154 std::string* groupTypeString)
1163 accumulatedTreeErrors,
1172 __GEN_COUT_ERR__ <<
"There were errors, so de-activating group: "
1173 << tableGroupName <<
" (" << tableGroupKey <<
")" << __E__;
1184 __GEN_COUT_INFO__ <<
"Updating persistent active groups to "
1187 __COUT_INFO__ <<
"Active Context table group: " << theContextTableGroup_ <<
"("
1188 << (theContextTableGroupKey_
1189 ? theContextTableGroupKey_->toString().c_str()
1192 __COUT_INFO__ <<
"Active Backbone table group: " << theBackboneTableGroup_ <<
"("
1193 << (theBackboneTableGroupKey_
1194 ? theBackboneTableGroupKey_->toString().c_str()
1197 __COUT_INFO__ <<
"Active Iterate table group: " << theIterateTableGroup_ <<
"("
1198 << (theIterateTableGroupKey_
1199 ? theIterateTableGroupKey_->toString().c_str()
1202 __COUT_INFO__ <<
"Active Configuration table group: " << theConfigurationTableGroup_
1204 << (theConfigurationTableGroupKey_
1205 ? theConfigurationTableGroupKey_->toString().c_str()
1210 FILE* fp = fopen(fn.c_str(),
"w");
1213 __SS__ <<
"Fatal Error! Unable to open the file "
1215 <<
" for editing! Is there a permissions problem?" << __E__;
1216 __GEN_COUT_ERR__ << ss.str();
1220 fprintf(fp,
"%s\n", theContextTableGroup_.c_str());
1224 theContextTableGroupKey_ ? theContextTableGroupKey_->toString().c_str() :
"-1");
1225 fprintf(fp,
"%s\n", theBackboneTableGroup_.c_str());
1229 theBackboneTableGroupKey_ ? theBackboneTableGroupKey_->toString().c_str() :
"-1");
1230 fprintf(fp,
"%s\n", theIterateTableGroup_.c_str());
1234 theIterateTableGroupKey_ ? theIterateTableGroupKey_->toString().c_str() :
"-1");
1235 fprintf(fp,
"%s\n", theConfigurationTableGroup_.c_str());
1238 theConfigurationTableGroupKey_
1239 ? theConfigurationTableGroupKey_->toString().c_str()
1246 std::string(tableGroupName), tableGroupKey);
1247 if(theConfigurationTableGroupKey_ &&
1248 theConfigurationTableGroup_ == tableGroupName &&
1249 *theConfigurationTableGroupKey_ == tableGroupKey)
1251 ConfigurationManager::saveGroupNameAndKey(
1253 ConfigurationManager::LAST_ACTIVATED_CONFIG_GROUP_FILE,
1256 ConfigurationManager::saveGroupNameAndKey(
1258 ConfigurationManager::ACTIVATED_CONFIGS_FILE,
1262 else if(theContextTableGroupKey_ && theContextTableGroup_ == tableGroupName &&
1263 *theContextTableGroupKey_ == tableGroupKey)
1265 ConfigurationManager::saveGroupNameAndKey(
1267 ConfigurationManager::LAST_ACTIVATED_CONTEXT_GROUP_FILE,
1270 ConfigurationManager::saveGroupNameAndKey(
1272 ConfigurationManager::ACTIVATED_CONTEXTS_FILE,
1276 else if(theBackboneTableGroupKey_ && theBackboneTableGroup_ == tableGroupName &&
1277 *theBackboneTableGroupKey_ == tableGroupKey)
1279 ConfigurationManager::saveGroupNameAndKey(
1281 ConfigurationManager::LAST_ACTIVATED_BACKBONE_GROUP_FILE,
1284 ConfigurationManager::saveGroupNameAndKey(
1286 ConfigurationManager::ACTIVATED_BACKBONES_FILE,
1290 else if(theIterateTableGroupKey_ && theIterateTableGroup_ == tableGroupName &&
1291 *theIterateTableGroupKey_ == tableGroupKey)
1293 ConfigurationManager::saveGroupNameAndKey(
1295 ConfigurationManager::LAST_ACTIVATED_ITERATE_GROUP_FILE,
1298 ConfigurationManager::saveGroupNameAndKey(
1300 ConfigurationManager::ACTIVATED_ITERATES_FILE,
1315 __GEN_COUT_INFO__ <<
"Creating temporary backbone view from version "
1316 << sourceViewVersion << __E__;
1322 auto backboneMemberNames = ConfigurationManager::getBackboneMemberNames();
1323 for(
auto& name : backboneMemberNames)
1327 if(retTmpVersion < tmpVersion)
1328 tmpVersion = retTmpVersion;
1331 __GEN_COUT__ <<
"Common temporary backbone version found as " << tmpVersion << __E__;
1334 for(
auto& name : backboneMemberNames)
1338 if(retTmpVersion != tmpVersion)
1340 __SS__ <<
"Failure! Temporary view requested was " << tmpVersion
1341 <<
". Mismatched temporary view created: " << retTmpVersion << __E__;
1342 __GEN_COUT_ERR__ << ss.str();
1351 TableBase* ConfigurationManagerRW::getTableByName(
const std::string& tableName)
1353 if(nameToTableMap_.find(tableName) == nameToTableMap_.end())
1355 if(tableName == ConfigurationManager::ARTDAQ_TOP_TABLE_NAME)
1358 <<
"Since target table was the artdaq top configuration level, "
1359 "attempting to help user by appending to core tables file: "
1360 << CORE_TABLE_INFO_FILENAME << __E__;
1361 FILE* fp = fopen((CORE_TABLE_INFO_FILENAME).c_str(),
"a");
1364 fprintf(fp,
"\nARTDAQ/*");
1369 __SS__ <<
"Table not found with name: " << tableName << __E__;
1371 if((f = tableName.find(
' ')) != std::string::npos)
1372 ss <<
"There was a space character found in the table name needle at "
1374 << f <<
" in the string (was this intended?). " << __E__;
1376 ss <<
"\nIf you think this table should exist in the core set of tables, try "
1377 "running 'UpdateOTS.sh --tables' to update your tables, then relaunch ots."
1379 ss <<
"\nTables must be defined at path $USER_DATA/TableInfo/ to exist in ots. "
1380 "Please verify your table definitions, and then restart ots."
1382 __GEN_COUT_ERR__ <<
"\n" << ss.str();
1385 return nameToTableMap_[tableName];
1397 std::lock_guard<std::mutex> lock(versionCreationTimeCacheMutex_);
1399 auto tableIt = versionCreationTimeCache_.find(tableName);
1400 if(tableIt != versionCreationTimeCache_.end())
1402 auto versionIt = tableIt->second.find(version);
1403 if(versionIt != tableIt->second.end())
1404 return versionIt->second;
1408 std::string localAccumulatedErrors;
1409 const auto loadStartTime = std::chrono::steady_clock::now();
1410 time_t creationTime = getVersionedTableByName(tableName,
1413 &localAccumulatedErrors,
1420 std::chrono::duration<double>(std::chrono::steady_clock::now() - loadStartTime)
1423 __GEN_COUT_WARN__ <<
"Slow creation time lookup: table '" << tableName
1424 <<
"' version v" << version <<
" load took " << loadSec <<
" s"
1429 std::lock_guard<std::mutex> lock(versionCreationTimeCacheMutex_);
1430 versionCreationTimeCache_[tableName][version] = creationTime;
1433 return creationTime;
1445 const auto preloadStartTime = std::chrono::steady_clock::now();
1448 std::vector<std::pair<std::string, std::vector<TableVersion>>> groupedWork;
1449 size_t missingCount = 0;
1451 std::lock_guard<std::mutex> lock(versionCreationTimeCacheMutex_);
1453 for(
const auto& tableInfoPair : allTableInfo_)
1455 auto tableIt = versionCreationTimeCache_.find(tableInfoPair.first);
1457 std::vector<TableVersion> missingVersions;
1458 for(
const auto& version : tableInfoPair.second.versions_)
1460 if(version.isTemporaryVersion() || version.isScratchVersion())
1462 if(tableIt != versionCreationTimeCache_.end() &&
1463 tableIt->second.find(version) != tableIt->second.end())
1465 missingVersions.push_back(version);
1467 if(missingVersions.size())
1469 missingCount += missingVersions.size();
1470 groupedWork.emplace_back(tableInfoPair.first, std::move(missingVersions));
1474 if(groupedWork.empty())
1478 std::vector<std::pair<std::string, TableVersion>> flatWork;
1479 flatWork.reserve(missingCount);
1481 size_t maxVersions = 0;
1482 for(
const auto& gw : groupedWork)
1483 if(gw.second.size() > maxVersions)
1484 maxVersions = gw.second.size();
1485 for(
size_t vi = 0; vi < maxVersions; ++vi)
1486 for(
const auto& gw : groupedWork)
1487 if(vi < gw.second.size())
1488 flatWork.emplace_back(gw.first, gw.second[vi]);
1491 __GEN_COUT__ <<
"preloadVersionCreationTimes() loading " << missingCount
1492 <<
" version creation times for " << groupedWork.size() <<
" tables..."
1495 int numOfThreads = StringMacros::getConcurrencyCount() / 2;
1496 if(numOfThreads > (
int)flatWork.size())
1497 numOfThreads = flatWork.size();
1499 if(numOfThreads < 2)
1501 for(
const auto& work : flatWork)
1509 __GEN_COUT__ <<
"Failed to get creation time for table '" << work.first
1510 <<
"' version v" << work.second <<
", skipping." << __E__;
1516 std::atomic<size_t> workIndex(0);
1517 std::vector<std::thread> threads;
1518 auto* iface = theInterface_;
1520 for(
int i = 0; i < numOfThreads; ++i)
1521 threads.emplace_back([iface, &workIndex, &flatWork,
this]() {
1522 std::map<std::string, TableBase*> localTables;
1527 while((w = workIndex++) < flatWork.size())
1529 const auto& tableName = flatWork[w].first;
1530 const auto& version = flatWork[w].second;
1534 TableBase*& table = localTables[tableName];
1537 std::string localAccumulatedErrors;
1538 table = new TableBase(tableName, &localAccumulatedErrors);
1541 std::string localAccumulatedErrors;
1551 &localAccumulatedErrors,
1554 time_t creationTime =
1555 table->getView(version).getCreationTime();
1558 std::lock_guard<std::mutex> lock(
1559 versionCreationTimeCacheMutex_);
1560 versionCreationTimeCache_[tableName][version] =
1566 __GEN_COUT__ <<
"Failed to get creation time for table '"
1567 << tableName <<
"' version v" << version
1568 <<
", skipping." << __E__;
1574 __GEN_COUT_ERR__ <<
"Unexpected error in preload thread." << __E__;
1577 for(
auto& pair : localTables)
1582 for(
auto& thread : threads)
1586 __GEN_COUT__ <<
"preloadVersionCreationTimes() loaded " << missingCount
1587 <<
" version creation times with " << numOfThreads <<
" thread(s) in "
1588 << std::chrono::duration<double>(std::chrono::steady_clock::now() -
1601 time_t ConfigurationManagerRW::getVersionLastAccessTime(
const std::string& tableName,
1604 auto it = nameToTableMap_.find(tableName);
1605 if(it == nameToTableMap_.end() || !it->second->isStored(version))
1608 return it->second->getView(version).getLastAccessTime();
1622 TableBase* table = getTableByName(tableName);
1627 newVersion = theInterface_->saveNewVersion(table, temporaryVersion);
1629 table->setActiveView(newVersion);
1633 allTableInfo_[tableName].versions_.find(newVersion) !=
1634 allTableInfo_[tableName].versions_.end())
1637 <<
"What happenened!?? ERROR::: new persistent version v" << newVersion
1638 <<
" already exists!? How is it possible? Retrace your steps and "
1646 newVersion = temporaryVersion;
1650 __GEN_COUT_WARN__ <<
"Attempting to recover and use v" << newVersion << __E__;
1654 theInterface_->saveNewVersion(table, temporaryVersion, newVersion);
1656 table->setActiveView(newVersion);
1661 __SS__ <<
"Something went wrong saving the new version v" << newVersion
1662 <<
". What happened?! (duplicates? database error?)" << __E__;
1663 __GEN_COUT_ERR__ <<
"\n" << ss.str();
1668 allTableInfo_[tableName].versions_.insert(newVersion);
1682 TableBase* table = getTableByName(tableName);
1687 if(allTableInfo_.find(tableName) == allTableInfo_.end())
1694 for(
auto it = allTableInfo_[tableName].versions_.begin();
1695 it != allTableInfo_[tableName].versions_.end();
1698 if(it->isTemporaryVersion())
1700 __GEN_COUT__ <<
"Removing '" << tableName <<
"' version info: " << *it
1702 allTableInfo_[tableName].versions_.erase(it++);
1711 auto it = allTableInfo_[tableName].versions_.find(targetVersion);
1712 if(it == allTableInfo_[tableName].versions_.end())
1714 __GEN_COUT__ <<
"Target '" << tableName <<
"' version v" << targetVersion
1715 <<
" was not found in info versions..." << __E__;
1718 allTableInfo_[tableName].versions_.erase(
1719 allTableInfo_[tableName].versions_.find(targetVersion));
1730 TableBase* table = getTableByName(tableName);
1742 for(
auto configInfo : allTableInfo_)
1743 configInfo.second.tablePtr_->trimCache(0);
1749 const std::string& tableName,
TableVersion sourceVersion)
1751 getTableByName(tableName)->reset();
1756 getVersionedTableByName(tableName,
TableVersion(sourceVersion),
true);
1763 allTableInfo_[tableName].versions_.insert(newTemporaryVersion);
1765 return newTemporaryVersion;
1773 const std::string& groupName,
bool attemptToReloadKeys )
1780 auto it = allGroupInfo_.find(groupName);
1781 if(it == allGroupInfo_.end())
1783 __SS__ <<
"Group name '" << groupName
1784 <<
"' not found in group info! (creating empty info)" << __E__;
1785 __GEN_COUT_WARN__ << ss.str();
1787 return allGroupInfo_[groupName];
1790 if(attemptToReloadKeys)
1792 __GEN_COUT__ <<
"Reloading keys from special db group cache if it exists..."
1795 std::set<TableGroupKey> keys;
1798 bool cacheFailed =
false;
1804 TableBase::GROUP_CACHE_PREPEND + groupName);
1805 auto versions = theInterface_->getVersions(&localGroupMemberCacheLoader);
1806 for(
const auto& version : versions)
1811 __GEN_COUT__ <<
"Ignoring cache loading error. Doing full load of keys..."
1816 if(cacheFailed && 0)
1817 keys = theInterface_->getKeys(groupName);
1821 __GEN_COUT__ <<
"Key from special db group cache were loaded." << __E__;
1822 it->second.keys_ = keys;
1841 const std::string& groupName,
1842 const std::map<std::string, TableVersion>& groupMemberMap,
1843 const std::map<std::string /*name*/, std::string /*alias*/>& memberTableAliases)
1845 if(!groupMemberMap.size() || groupName.empty())
1847 __SS__ <<
"Illegal name/members for requested group of name '" << groupName
1848 <<
"' and member count = " << groupMemberMap.size() << __E__;
1856 std::set<TableGroupKey> keys;
1859 bool cacheFailed =
false;
1865 TableBase::GROUP_CACHE_PREPEND + groupName);
1866 auto versions = theInterface_->getVersions(&localGroupMemberCacheLoader);
1867 for(
const auto& version : versions)
1872 __COUT__ <<
"Ignoring cache loading error. Doing full load of keys..."
1878 keys = theInterface_->getKeys(groupName);
1883 const unsigned int MAX_DEPTH_TO_CHECK = 20;
1884 unsigned int keyMinToCheck = 0;
1887 keyMinToCheck = keys.rbegin()->key();
1888 if(keyMinToCheck > MAX_DEPTH_TO_CHECK)
1890 keyMinToCheck -= MAX_DEPTH_TO_CHECK;
1891 __GEN_COUT__ <<
"Checking groups back to key... " << keyMinToCheck << __E__;
1896 __GEN_COUT__ <<
"Checking all groups." << __E__;
1903 const int numOfThreads = StringMacros::getConcurrencyCount() / 2;
1904 __GEN_COUT__ <<
" getConcurrencyCount " << StringMacros::getConcurrencyCount()
1905 <<
" ==> " << numOfThreads <<
" threads." << __E__;
1906 if(numOfThreads < 2)
1908 std::map<std::string ,
TableVersion > compareToMemberMap;
1909 std::map<std::string , std::string > compareToMemberTableAliases;
1910 std::map<std::string , std::string >*
1911 compareToMemberTableAliasesPtr =
nullptr;
1912 if(memberTableAliases.size())
1913 compareToMemberTableAliasesPtr = &compareToMemberTableAliases;
1916 for(
const auto& key : keys)
1918 if(key.key() < keyMinToCheck)
1924 &compareToMemberMap ,
1932 compareToMemberTableAliasesPtr);
1934 isDifferent =
false;
1935 for(
auto& memberPair : groupMemberMap)
1937 if(memberTableAliases.find(memberPair.first) != memberTableAliases.end())
1940 if(compareToMemberTableAliases.find(memberPair.first) ==
1941 compareToMemberTableAliases.end() ||
1942 memberTableAliases.at(memberPair.first) !=
1943 compareToMemberTableAliases.at(memberPair.first))
1950 else if(compareToMemberTableAliases.find(memberPair.first) !=
1951 compareToMemberTableAliases.end())
1961 if(compareToMemberMap.find(memberPair.first) ==
1962 compareToMemberMap.end() ||
1963 memberPair.second !=
1964 compareToMemberMap.at(memberPair.first))
1975 if(groupMemberMap.size() != compareToMemberMap.size())
1979 __GEN_COUT__ <<
"Found exact match with key: " << key << __E__;
1983 __GEN_COUT__ <<
"No match found - this group is new!" << __E__;
1989 int threadsLaunched = 0;
1990 int foundThreadIndex = 0;
1991 std::atomic<bool> foundIdentical =
false;
1993 std::mutex threadMutex;
1995 std::vector<std::shared_ptr<std::atomic<bool>>> threadDone;
1996 for(
int i = 0; i < numOfThreads; ++i)
1997 threadDone.push_back(std::make_shared<std::atomic<bool>>(
true));
1999 for(
const auto& key : keys)
2003 if(key.key() < keyMinToCheck)
2006 if(threadsLaunched >= numOfThreads)
2009 foundThreadIndex = -1;
2010 while(foundThreadIndex == -1)
2015 for(
int i = 0; i < numOfThreads; ++i)
2016 if(*(threadDone[i]))
2018 foundThreadIndex = i;
2021 if(foundThreadIndex == -1)
2023 __GEN_COUTT__ <<
"Waiting for available thread..." << __E__;
2027 threadsLaunched = numOfThreads - 1;
2032 __GEN_COUTT__ <<
"Starting thread... " << foundThreadIndex << __E__;
2033 *(threadDone[foundThreadIndex]) =
false;
2037 std::string theGroupName,
2039 const std::map<std::string, TableVersion>& groupMemberMap,
2040 const std::map<std::string /*name*/, std::string /*alias*/>&
2042 std::atomic<bool>* theFoundIdentical,
2044 std::mutex* theThreadMutex,
2045 std::shared_ptr<std::atomic<bool>> theThreadDone) {
2064 threadDone[foundThreadIndex])
2074 foundThreadIndex = -1;
2075 for(
int i = 0; i < numOfThreads; ++i)
2076 if(!*(threadDone[i]))
2078 foundThreadIndex = i;
2081 if(foundThreadIndex != -1)
2083 __GEN_COUTT__ <<
"Waiting for thread to finish... " << foundThreadIndex
2087 }
while(foundThreadIndex != -1);
2091 __GEN_COUT__ <<
"Found exact match with key: " << identicalKey << __E__;
2092 return identicalKey;
2109 return &groupMetadataTable_;
2113 std::lock_guard<std::mutex> lock(metaDataTableMutex_);
2116 while(groupMetadataTable_.getView().getNumberOfRows())
2117 groupMetadataTable_.getViewP()->deleteRow(0);
2122 theInterface_->fill(&groupMetadataTable_, fillVersion);
2124 catch(
const std::runtime_error& e)
2126 __GEN_COUT_WARN__ <<
"Failed to load " << groupMetadataTable_.getTableName()
2127 <<
"-v" << fillVersion <<
". Metadata error: " << e.what()
2132 __GEN_COUT_WARN__ <<
"Failed to load " << groupMetadataTable_.getTableName()
2133 <<
"-v" << fillVersion <<
". Ignoring unknown metadata error. "
2138 if(groupMetadataTable_.getView().getNumberOfRows() != 1)
2140 groupMetadataTable_.print();
2141 __GEN_COUT_ERR__ <<
"Ignoring that groupMetadataTable_ v" << fillVersion
2143 "number of rows!' Must "
2144 "be 1. Going with anonymous defaults."
2148 while(groupMetadataTable_.getViewP()->getNumberOfRows() > 1)
2149 groupMetadataTable_.getViewP()->deleteRow(0);
2150 if(groupMetadataTable_.getViewP()->getNumberOfRows() == 0)
2151 groupMetadataTable_.getViewP()->addRow();
2154 return &groupMetadataTable_;
2165 const std::string& groupName,
2166 std::map<std::string, TableVersion>& groupMembers,
2167 const std::string& groupComment,
2168 std::map<std::string /*table*/, std::string /*alias*/>* groupAliases)
2176 if(groupMembers.size() == 0)
2178 __SS__ <<
"Empty group member list. Can not create a group without members!"
2183 __GEN_COUTT__ <<
"saveNewTableGroup runTimeSeconds()=" << runTimeSeconds() << __E__;
2188 for(
auto& memberPair : groupMembers)
2191 if(allCfgInfo.find(memberPair.first) == allCfgInfo.end())
2193 __GEN_COUT_ERR__ <<
"Group member \"" << memberPair.first
2194 <<
"\" not found in database!";
2196 if(groupMetadataTable_.getTableName() == memberPair.first)
2199 <<
"Looks like this is the groupMetadataTable_ '"
2200 << TableBase::GROUP_METADATA_TABLE_NAME
2201 <<
".' Note that this table is added to the member map when groups "
2203 <<
"It should not be part of member map when calling this function."
2205 __GEN_COUT__ <<
"Attempting to recover." << __E__;
2206 groupMembers.erase(groupMembers.find(memberPair.first));
2210 __SS__ << (
"Group member not found!") << __E__;
2215 if(allCfgInfo[memberPair.first].versions_.find(memberPair.second) ==
2216 allCfgInfo[memberPair.first].versions_.end())
2218 __SS__ <<
"Group member \"" << memberPair.first <<
"\" version \""
2219 << memberPair.second <<
"\" not found in database!";
2224 __GEN_COUTT__ <<
"saveNewTableGroup runTimeSeconds()=" << runTimeSeconds() << __E__;
2229 for(
auto& aliasPair : *groupAliases)
2232 if(groupMembers.find(aliasPair.first) == groupMembers.end())
2234 __GEN_COUT_ERR__ <<
"Group member \"" << aliasPair.first
2235 <<
"\" not found in group member map!";
2237 __SS__ << (
"Alias table not found in member list!") << __E__;
2245 __GEN_COUT__ <<
"New Key for group: " << groupName <<
" found as " << newKey << __E__;
2246 __GEN_COUTT__ <<
"saveNewTableGroup runTimeSeconds()=" << runTimeSeconds() << __E__;
2248 time_t groupCreationTime = time(0);
2251 std::map<std::string ,
TableVersion > groupMembersWithoutMeta =
2258 std::string groupAliasesString =
"";
2261 *groupAliases,
"," ,
":" );
2262 __GEN_COUT__ <<
"Metadata: " << username_ <<
" " << groupCreationTime <<
" "
2263 << groupComment <<
" " << groupAliasesString <<
" " << groupType
2268 while(groupMetadataTable_.getViewP()->getNumberOfRows() > 1)
2269 groupMetadataTable_.getViewP()->deleteRow(0);
2270 if(groupMetadataTable_.getViewP()->getNumberOfRows() == 0)
2271 groupMetadataTable_.getViewP()->addRow();
2274 groupMetadataTable_.getViewP()->setValue(
2275 groupAliasesString, 0, ConfigurationManager::METADATA_COL_ALIASES);
2276 groupMetadataTable_.getViewP()->setValue(
2277 groupComment, 0, ConfigurationManager::METADATA_COL_COMMENT);
2278 groupMetadataTable_.getViewP()->setValue(
2279 username_, 0, ConfigurationManager::METADATA_COL_AUTHOR);
2280 groupMetadataTable_.getViewP()->setValue(
2281 groupCreationTime, 0, ConfigurationManager::METADATA_COL_TIMESTAMP);
2285 std::stringstream ss;
2286 groupMetadataTable_.print(ss);
2287 __COUT_MULTI__(2, ss.str());
2294 theInterface_->findLatestVersion(&groupMetadataTable_));
2295 groupMetadataTable_.getViewP()->setVersion(newVersion);
2297 uint16_t retries = 0;
2302 theInterface_->saveActiveVersion(&groupMetadataTable_);
2304 catch(
const std::runtime_error& e)
2306 __GEN_COUT__ <<
"Caught runtime_error exception during table save."
2308 if(std::string(e.what()).find(
"there was a collision") !=
2312 <<
"There was a collision saving the new table "
2313 << groupMetadataTable_ <<
"(" << newVersion
2314 <<
"), trying incremented table version... retries="
2315 << retries << __E__;
2320 groupMetadataTable_.getViewP()->setVersion(newVersion);
2321 __GEN_COUT__ <<
"New version for table: " << groupMetadataTable_
2322 <<
" found as " << newVersion << __E__;
2329 __GEN_COUT__ <<
"Created table: " << groupMetadataTable_ <<
"-v"
2330 << newVersion << __E__;
2335 __GEN_COUTT__ <<
"saveNewTableGroup runTimeSeconds()=" << runTimeSeconds()
2339 groupMembers[groupMetadataTable_.getTableName()] =
2340 groupMetadataTable_.getViewVersion();
2344 uint16_t retries = 0;
2347 __GEN_COUTT__ <<
"saveNewTableGroup runTimeSeconds()=" << runTimeSeconds()
2352 theInterface_->saveTableGroup(
2356 catch(
const std::runtime_error& e)
2358 __GEN_COUT__ <<
"Caught runtime_error exception during group save."
2360 if(std::string(e.what()).find(
"there was a collision") !=
2364 <<
"There was a collision saving the new group " << groupName
2366 <<
"), trying incremented group key... retries=" << retries
2371 __GEN_COUT__ <<
"New Key for group: " << groupName <<
" found as "
2379 __GEN_COUT__ <<
"Created table group: " << groupName <<
"(" << newKey
2385 __GEN_COUTT__ <<
"saveNewTableGroup runTimeSeconds()=" << runTimeSeconds()
2388 catch(std::runtime_error& e)
2390 __GEN_COUT_ERR__ <<
"Failed to create table group: " << groupName <<
"(" << newKey
2392 __GEN_COUT_ERR__ <<
"\n\n" << e.what() << __E__;
2397 __GEN_COUT_ERR__ <<
"Failed to create table group: " << groupName <<
":" << newKey
2402 __GEN_COUTT__ <<
"saveNewTableGroup runTimeSeconds()=" << runTimeSeconds() << __E__;
2405 allGroupInfo_[groupName].keys_.emplace(newKey);
2407 allGroupInfo_.at(groupName).latestKey_ = newKey;
2408 allGroupInfo_.at(groupName).latestKeyGroupAuthor_ = username_;
2409 allGroupInfo_.at(groupName).latestKeyGroupComment_ = groupComment;
2410 allGroupInfo_.at(groupName).latestKeyGroupCreationTime_ = groupCreationTime;
2411 allGroupInfo_.at(groupName).latestKeyGroupTypeString_ = groupType;
2412 allGroupInfo_.at(groupName).latestKeyMemberMap_ = groupMembersWithoutMeta;
2414 __GEN_COUT__ <<
"Saved " << groupName <<
"(" << newKey <<
") of type " << groupType
2417 __GEN_COUTT__ <<
"saveNewTableGroup runTimeSeconds()=" << runTimeSeconds() << __E__;
2429 __GEN_COUT_INFO__ <<
"Creating new backbone from temporary version "
2430 << temporaryVersion << __E__;
2435 auto backboneMemberNames = ConfigurationManager::getBackboneMemberNames();
2436 for(
auto& name : backboneMemberNames)
2439 __GEN_COUT__ <<
"New version for backbone member (" << name
2440 <<
"): " << retNewVersion << __E__;
2441 if(retNewVersion > newVersion)
2442 newVersion = retNewVersion;
2445 __GEN_COUT__ <<
"Common new backbone version found as " << newVersion << __E__;
2448 for(
auto& name : backboneMemberNames)
2452 getTableByName(name), temporaryVersion, newVersion);
2453 if(retNewVersion != newVersion)
2455 __SS__ <<
"Failure! New view requested was " << newVersion
2456 <<
". Mismatched new view created: " << retNewVersion << __E__;
2457 __GEN_COUT_ERR__ << ss.str();
2471 const std::string& tableName,
2476 bool ignoreDuplicates ,
2477 bool lookForEquivalent ,
2478 bool* foundEquivalent )
2480 bool needToEraseTemporarySource =
2484 *foundEquivalent =
false;
2487 if(!ignoreDuplicates)
2489 __GEN_COUT__ <<
"Checking for duplicate '" << tableName <<
"' tables..." << __E__;
2497 const std::map<std::string, TableInfo>& allTableInfo =
2500 auto versionReverseIterator =
2501 allTableInfo.at(tableName).versions_.rbegin();
2502 __GEN_COUT__ <<
"Filling up '" << tableName <<
"' cache from "
2506 versionReverseIterator != allTableInfo.at(tableName).versions_.rend();
2507 ++versionReverseIterator)
2509 __GEN_COUTT__ <<
"'" << tableName <<
"' versions in reverse order "
2510 << *versionReverseIterator << __E__;
2513 getVersionedTableByName(tableName,
2514 *versionReverseIterator);
2516 catch(
const std::runtime_error& e)
2519 __COUTT__ <<
"'" << tableName
2520 <<
"' version failed to load: " << *versionReverseIterator
2526 __GEN_COUT__ <<
"Checking '" << tableName <<
"' for duplicate..." << __E__;
2529 temporaryModifiedVersion,
2535 if(lookForEquivalent && !duplicateVersion.
isInvalid())
2538 __GEN_COUT__ <<
"Equivalent '" << tableName <<
"' table found in version v"
2539 << duplicateVersion << __E__;
2544 __GEN_COUT__ <<
"Need persistent. Duplicate '" << tableName
2545 <<
"' version was temporary. "
2546 "Abandoning duplicate."
2558 if(needToEraseTemporarySource)
2562 *foundEquivalent =
true;
2564 __GEN_COUT__ <<
"\t\t Equivalent '" << tableName
2565 <<
"' assigned version: " << duplicateVersion << __E__;
2567 return duplicateVersion;
2573 __SS__ <<
"This version of table '" << tableName
2574 <<
"' is identical to another version currently cached v"
2575 << duplicateVersion <<
". No reason to save a duplicate." << __E__;
2576 __GEN_COUT_ERR__ <<
"\n" << ss.str();
2579 table->eraseView(temporaryModifiedVersion);
2583 __GEN_COUT__ <<
"Check for duplicate '" << tableName <<
"' tables complete."
2588 __GEN_COUT__ <<
"\t\t**************************** Save as temporary '"
2589 << tableName <<
"' table version" << __E__;
2591 __GEN_COUT__ <<
"\t\t**************************** Save as new '" << tableName
2592 <<
"' table version" << __E__;
2595 saveNewTable(tableName, temporaryModifiedVersion, makeTemporary);
2597 __GEN_COUTTV__(table->getView().getComment());
2599 if(needToEraseTemporarySource)
2602 __GEN_COUT__ <<
"\t\t '" << tableName
2603 <<
"' new assigned version: " << newAssignedVersion << __E__;
2604 return newAssignedVersion;
2621 const std::string& tableName,
2622 const std::map<std::string, std::map<std::string, std::string>>& cellUpdates,
2623 const std::string& author,
2625 const std::string& versionAlias ,
2626 const std::string& sourceAlias ,
2627 const std::string& comment )
2629 TableBase* table = getTableByName(tableName);
2632 if(!sourceAlias.empty())
2635 auto tableIt = allAliases.find(tableName);
2636 if(tableIt == allAliases.end())
2638 __SS__ <<
"No version aliases found for table '" << tableName <<
"'."
2642 auto aliasIt = tableIt->second.find(sourceAlias);
2643 if(aliasIt == tableIt->second.end())
2645 __SS__ <<
"Version alias '" << sourceAlias <<
"' not found for table '"
2646 << tableName <<
"'. Available aliases: ";
2647 for(
const auto& a : tableIt->second)
2648 ss <<
"'" << a.first <<
"' (v" << a.second <<
"), ";
2652 sourceVersion = aliasIt->second;
2653 __GEN_COUT__ <<
"Resolved source alias '" << sourceAlias <<
"' to version "
2654 << sourceVersion <<
" for table '" << tableName <<
"'" << __E__;
2662 __SS__ <<
"No source version specified and table '" << tableName
2663 <<
"' has no active version. Please specify a version or "
2664 "ensure active groups are initialized."
2668 sourceVersion = table->getView().getVersion();
2669 __GEN_COUT__ <<
"Using active version " << sourceVersion <<
" for table '"
2670 << tableName <<
"'" << __E__;
2673 getVersionedTableByName(tableName, sourceVersion);
2675 __GEN_COUT__ <<
"Updating cells in table '" << tableName <<
"' from source version "
2676 << sourceVersion << __E__;
2680 __GEN_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
2686 unsigned int uidCol = cfgView->
getColUID();
2687 int authorCol = cfgView->
findColByType(TableViewColumnInfo::TYPE_AUTHOR);
2688 int timestampCol = cfgView->
findColByType(TableViewColumnInfo::TYPE_TIMESTAMP);
2689 unsigned int cellsModified = 0;
2691 for(
const auto& rowUpdate : cellUpdates)
2693 const std::string& uid = rowUpdate.first;
2694 unsigned int row = cfgView->
findRow(uidCol, uid);
2696 __GEN_COUT__ <<
"Updating UID '" << uid <<
"' at row " << row << __E__;
2698 bool rowModified =
false;
2699 for(
const auto& colVal : rowUpdate.second)
2701 unsigned int col = cfgView->
findCol(colVal.first);
2702 __GEN_COUT__ <<
"Setting [" << uid <<
"][" << colVal.first <<
"] = '"
2703 << colVal.second <<
"'" << __E__;
2709 if(rowModified && !author.empty())
2712 cfgView->
setValue(author, row, authorCol);
2713 if(timestampCol >= 0)
2714 cfgView->
setValue(time(0), row, timestampCol);
2718 __GEN_COUT__ << cellsModified <<
" cell(s) modified." << __E__;
2720 std::stringstream commentSS;
2721 commentSS << cellsModified <<
" cell(s) updated via updateTableCells().";
2722 if(!comment.empty())
2723 commentSS <<
" Notes: " << comment;
2724 cfgView->setComment(commentSS.str());
2728 __GEN_COUT__ <<
"Caught error while editing. Erasing temporary version." << __E__;
2729 table->eraseView(temporaryVersion);
2733 bool foundEquivalent;
2744 __GEN_COUT_WARN__ <<
"Found equivalent version as " << tableName <<
"-v"
2745 << newVersion <<
". No new version created." << __E__;
2747 __GEN_COUT_INFO__ << tableName <<
"-v" << newVersion
2748 <<
" created with updated cells." << __E__;
2751 if(!versionAlias.empty())
2753 __GEN_COUT__ <<
"Setting version alias '" << versionAlias <<
"' for " << tableName
2754 <<
"-v" << newVersion << __E__;
2756 GroupEditStruct backboneGroupEdit(ConfigurationManager::GroupType::BACKBONE_TYPE,
2765 unsigned int colTableName = aliasTableView->
findCol(
"TableName");
2766 unsigned int colVersionAlias = aliasTableView->
findCol(
"VersionAlias");
2767 unsigned int colVersion = aliasTableView->
findCol(
"Version");
2770 bool aliasFound =
false;
2771 for(
unsigned int row = 0; row < aliasTableView->getNumberOfRows(); ++row)
2773 if(aliasTableView->getDataView()[row][colTableName] == tableName &&
2774 aliasTableView->getDataView()[row][colVersionAlias] == versionAlias)
2776 __GEN_COUT__ <<
"Updating existing alias at row " << row << __E__;
2785 __GEN_COUT__ <<
"Adding new alias row." << __E__;
2786 unsigned int newRow = aliasTableView->
addRow(
2787 author,
true ,
"versionAlias");
2794 backboneGroupEdit.saveChanges(backboneGroupEdit.originalGroupName_,
2799 __GEN_COUT_INFO__ <<
"Version alias '" << versionAlias <<
"' set to " << tableName
2800 <<
"-v" << newVersion <<
" (backbone key " << newBackboneKey
2808 GroupEditStruct::GroupEditStruct(
const ConfigurationManager::GroupType& groupType,
2810 : groupType_(groupType)
2811 , originalGroupName_(cfgMgr->getActiveGroupName(groupType))
2812 , originalGroupKey_(cfgMgr->getActiveGroupKey(groupType))
2814 , mfSubject_(cfgMgr->getUsername())
2816 if(originalGroupName_ ==
"" || originalGroupKey_.isInvalid())
2818 __SS__ <<
"Error! No active group found for type '"
2820 <<
".' There must be an active group to edit the group." << __E__ << __E__
2825 __GEN_COUT__ <<
"Extracting Group-Edit Struct for type "
2830 const std::set<std::string>& memberNames =
2831 groupType == ConfigurationManager::GroupType::CONTEXT_TYPE
2832 ? cfgMgr->getActiveContextMemberNames()
2833 : (groupType == ConfigurationManager::GroupType::BACKBONE_TYPE
2834 ? ConfigurationManager::getBackboneMemberNames()
2837 : cfgMgr->getConfigurationMemberNames()));
2839 for(
auto& memberName : memberNames)
2842 groupMembers_.emplace(
2843 std::make_pair(memberName, activeTables.at(memberName)));
2844 groupTables_.emplace(std::make_pair(
2851 __SS__ <<
"Error! Could not find group member table '" << memberName
2852 <<
"' for group type '"
2854 <<
".' All group members must be present to create the group editing "
2863 GroupEditStruct::~GroupEditStruct()
2865 __GEN_COUT__ <<
"GroupEditStruct from editing '" << originalGroupName_ <<
"("
2866 << originalGroupKey_ <<
")' Destructing..." << __E__;
2868 __GEN_COUT__ <<
"GroupEditStruct from editing '" << originalGroupName_ <<
"("
2869 << originalGroupKey_ <<
")' Desctructed." << __E__;
2877 auto it = groupTables_.find(tableName);
2878 if(it == groupTables_.end())
2880 if(groupType_ == ConfigurationManager::GroupType::CONFIGURATION_TYPE &&
2883 __GEN_COUT__ <<
"Table '" << tableName
2884 <<
"' not found in configuration table members from editing '"
2885 << originalGroupName_ <<
"(" << originalGroupKey_ <<
")..."
2886 <<
" Attempting to add it!" << __E__;
2889 auto newIt = groupTables_.emplace(std::make_pair(
2894 newIt.first->second.modified_ =
2896 groupMembers_.emplace(
2897 std::make_pair(tableName, newIt.first->second.temporaryVersion_));
2898 return newIt.first->second;
2900 __GEN_COUT_ERR__ <<
"Failed to emplace new table..." << __E__;
2903 __SS__ <<
"Table '" << tableName <<
"' not found in table members from editing '"
2904 << originalGroupName_ <<
"(" << originalGroupKey_ <<
")!'" << __E__;
2907 it->second.modified_ =
2913 void GroupEditStruct::dropChanges()
2915 __GEN_COUT__ <<
"Dropping unsaved changes from editing '" << originalGroupName_ <<
"("
2916 << originalGroupKey_ <<
")'..." << __E__;
2921 for(
auto& groupTable : groupTables_)
2922 if(groupTable.second
2923 .createdTemporaryVersion_)
2927 groupTable.second.temporaryVersion_);
2928 groupTable.second.createdTemporaryVersion_ =
false;
2929 groupTable.second.modified_ =
false;
2932 __GEN_COUT__ <<
"Unsaved changes dropped from editing '" << originalGroupName_ <<
"("
2933 << originalGroupKey_ <<
").'" << __E__;
2937 void GroupEditStruct::saveChanges(
const std::string& groupNameToSave,
2939 bool* foundEquivalentGroupKey ,
2940 bool activateNewGroup ,
2941 bool updateGroupAliases ,
2942 bool updateTableAliases ,
2944 bool* foundEquivalentBackboneKey ,
2945 std::string* accumulatedWarnings )
2947 __GEN_COUT__ <<
"Saving changes..." << __E__;
2952 if(foundEquivalentBackboneKey)
2953 *foundEquivalentBackboneKey =
false;
2957 bool anyTableNew =
false;
2958 for(
auto& groupTable : groupTables_)
2960 if(!groupTable.second.modified_)
2963 __GEN_COUT__ <<
"Original version is " << groupTable.second.tableName_ <<
"-v"
2964 << groupTable.second.originalVersion_ << __E__;
2967 groupTable.second.tableName_,
2968 groupTable.second.originalVersion_,
2970 groupTable.second.table_,
2971 groupTable.second.temporaryVersion_,
2974 __GEN_COUT__ <<
"Temporary target version is " << groupTable.second.tableName_
2975 <<
"-v" << groupMembers_.at(groupTable.first) <<
"-v"
2976 << groupTable.second.temporaryVersion_ << __E__;
2979 groupTable.second.tableName_,
2980 groupTable.second.originalVersion_,
2982 groupTable.second.table_,
2983 groupTable.second.temporaryVersion_,
2987 if(groupTable.second.originalVersion_ != groupMembers_.at(groupTable.first))
2990 __GEN_COUT__ <<
"Final NEW target version is " << groupTable.second.tableName_
2991 <<
"-v" << groupMembers_.at(groupTable.first) << __E__;
2994 __GEN_COUT__ <<
"Final target version is " << groupTable.second.tableName_
2995 <<
"-v" << groupMembers_.at(groupTable.first) << __E__;
2997 groupTable.second.modified_ =
false;
2998 groupTable.second.createdTemporaryVersion_ =
false;
3001 for(
auto& table : groupMembers_)
3003 __GEN_COUT__ << table.first <<
" v" << table.second << __E__;
3008 __GEN_COUT__ <<
"Checking for duplicate groups..." << __E__;
3009 newGroupKey = cfgMgr->
findTableGroup(groupNameToSave, groupMembers_);
3012 __GEN_COUT__ <<
"New table found, so no need to check duplicate groups." << __E__;
3016 __GEN_COUT__ <<
"Found equivalent group key (" << newGroupKey <<
") for "
3017 << groupNameToSave <<
"." << __E__;
3018 if(foundEquivalentGroupKey)
3019 *foundEquivalentGroupKey =
true;
3024 __GEN_COUT__ <<
"Saved new Context group key (" << newGroupKey <<
") for "
3025 << groupNameToSave <<
"." << __E__;
3028 bool groupAliasChange =
false;
3029 bool tableAliasChange =
false;
3032 ConfigurationManager::GroupType::
3035 GroupEditStruct backboneGroupEdit(ConfigurationManager::GroupType::BACKBONE_TYPE,
3038 if(groupType_ != ConfigurationManager::GroupType::BACKBONE_TYPE &&
3044 TableEditStruct& groupAliasTable = backboneGroupEdit.getTableEditStruct(
3045 ConfigurationManager::GROUP_ALIASES_TABLE_NAME,
true );
3046 TableView* tableView = groupAliasTable.tableView_;
3049 unsigned int row = 0;
3051 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
3052 cfgMgr->
getNode(ConfigurationManager::GROUP_ALIASES_TABLE_NAME)
3054 std::string groupName, groupKey;
3055 for(
auto& aliasNodePair : aliasNodePairs)
3057 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
3058 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
3060 __GEN_COUT__ <<
"Group Alias: " << aliasNodePair.first <<
" => "
3061 << groupName <<
"(" << groupKey <<
"); row=" << row << __E__;
3063 if(groupName == originalGroupName_ &&
3066 __GEN_COUT__ <<
"Found alias! Changing group key from ("
3067 << originalGroupKey_ <<
") to (" << newGroupKey <<
")"
3070 groupAliasChange =
true;
3079 if(groupAliasChange)
3081 std::stringstream ss;
3082 tableView->print(ss);
3083 __GEN_COUT__ << ss.str();
3087 if(groupType_ != ConfigurationManager::GroupType::BACKBONE_TYPE &&
3093 .getTableEditStruct(ConfigurationManager::VERSION_ALIASES_TABLE_NAME,
3097 for(
auto& groupTable : groupTables_)
3099 if(groupTable.second.originalVersion_ ==
3100 groupMembers_.at(groupTable.second.tableName_))
3103 __GEN_COUT__ <<
"Checking alias... original version is "
3104 << groupTable.second.tableName_ <<
"-v"
3105 << groupTable.second.originalVersion_
3106 <<
" and new version is v"
3107 << groupMembers_.at(groupTable.second.tableName_) << __E__;
3110 unsigned int row = 0;
3112 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
3113 cfgMgr->
getNode(ConfigurationManager::VERSION_ALIASES_TABLE_NAME)
3115 std::string tableName, tableVersion;
3116 for(
auto& aliasNodePair : aliasNodePairs)
3119 aliasNodePair.second.getNode(
"TableName").getValueAsString();
3121 aliasNodePair.second.getNode(
"Version").getValueAsString();
3123 __GEN_COUT__ <<
"Table Alias: " << aliasNodePair.first <<
" => "
3124 << tableName <<
"-v" << tableVersion <<
"" << __E__;
3126 if(tableName == groupTable.second.tableName_ &&
3127 TableVersion(tableVersion) == groupTable.second.originalVersion_)
3129 __GEN_COUT__ <<
"Found alias! Changing icon table version alias."
3132 tableAliasChange =
true;
3135 groupMembers_.at(groupTable.second.tableName_).toString(),
3137 tableView->
findCol(
"Version"));
3144 if(tableAliasChange)
3146 std::stringstream ss;
3147 tableView->print(ss);
3148 __GEN_COUT__ << ss.str();
3154 if(groupAliasChange || tableAliasChange)
3156 for(
auto& table : backboneGroupEdit.groupMembers_)
3158 __GEN_COUT__ << table.first <<
" v" << table.second << __E__;
3160 backboneGroupEdit.saveChanges(
3161 backboneGroupEdit.originalGroupName_,
3162 localNewBackboneKey,
3163 foundEquivalentBackboneKey ? foundEquivalentBackboneKey :
nullptr);
3166 *newBackboneKey = localNewBackboneKey;
3173 <<
"Restoring active table groups, before activating new groups..."
3176 std::string localAccumulatedWarnings;
3180 ConfigurationManager::LoadGroupType::
3182 &localAccumulatedWarnings);
3188 backboneGroupEdit.originalGroupName_,
3189 localNewBackboneKey,
3190 accumulatedWarnings ? accumulatedWarnings :
nullptr);
3199 <<
"Restoring active table groups, before activating new groups..."
3202 std::string localAccumulatedWarnings;
3206 ConfigurationManager::LoadGroupType::
3208 &localAccumulatedWarnings);
3212 if(activateNewGroup)
3215 accumulatedWarnings ? accumulatedWarnings :
nullptr);
3217 __GEN_COUT__ <<
"Changes saved." << __E__;
3226 __GEN_COUTV__(runTimeSeconds());
3228 std::string accumulatedWarningsStr;
3229 std::string* accumulatedWarnings = &accumulatedWarningsStr;
3236 std::string documentNameToLoad =
"XDAQApplicationTable";
3240 std::set<std::string> groupsContainingTable =
3241 theInterface_->findGroupsWithTable(documentNameToLoad,
3242 documentVersionToLoad);
3243 __GEN_COUT__ <<
"Groups containing " << documentNameToLoad <<
"-v"
3244 << documentVersionToLoad
3245 <<
" count: " << groupsContainingTable.size() << __E__;
3246 for(
const auto& group : groupsContainingTable)
3248 __GEN_COUT__ <<
"\t" << group << __E__;
3252 std::string debugGroupName =
"Mu2eHWEmulatorContext";
3257 theInterface_->findLatestGroupKey(debugGroupName);
3258 __GEN_COUTV__(latestGroupKey);
3260 __GEN_COUTV__(runTimeSeconds());
3267 std::set<std::string > tableGroups =
3268 theInterface_->getAllTableGroupNames();
3269 __GEN_COUT__ <<
"Number of Groups: " << tableGroups.size() << __E__;
3271 __GEN_COUTV__(runTimeSeconds());
3276 for(
const auto& fullName : tableGroups)
3279 allGroupInfo_[name].keys_.emplace(key);
3281 if(name == debugGroupName)
3286 __GEN_COUTV__(runTimeSeconds());
3288 std::set<std::string > tableNames = theInterface_->getAllTableNames();
3289 __GEN_COUT__ <<
"Number of Tables: " << tableNames.size() << __E__;
3291 __GEN_COUTV__(runTimeSeconds());
3293 for(
const auto& fullName : tableNames)
3295 if(fullName.find(debugGroupName) != std::string::npos)
3297 __GEN_COUTV__(fullName);
3300 __GEN_COUTV__(runTimeSeconds());
3302 TableGroupKey latestGroupKey = theInterface_->findLatestGroupKey(debugGroupName);
3303 __GEN_COUTV__(latestGroupKey);
3305 __GEN_COUTV__(runTimeSeconds());
3310 TableBase::GROUP_CACHE_PREPEND + debugGroupName);
3312 theInterface_->findLatestVersion(&localGroupMemberCacheSaver);
3313 __GEN_COUTV__(lastestGroupCacheKey);
3315 __GEN_COUTV__(runTimeSeconds());
3321 __GEN_COUT__ <<
"Testing group save of pre-existing " << debugGroupName <<
"("
3322 << groupKey <<
")" << __E__;
3323 std::map<std::string, TableVersion> groupMembers;
3325 theInterface_->saveTableGroup(
3331 __GEN_COUT__ <<
"Exception during group save." << __E__;
3333 __GEN_COUTV__(runTimeSeconds());
3338 std::string debugGroupName =
"testGroupSave";
3340 __GEN_COUT__ <<
"Testing group save of non-existing " << debugGroupName <<
"("
3341 << groupKey <<
")" << __E__;
3342 std::map<std::string, TableVersion> groupMembers;
3344 groupMembers[
"MessageFacilityTable"] =
TableVersion(7);
3345 theInterface_->saveTableGroup(
3351 __GEN_COUT__ <<
"Exception during new group save." << __E__;
3353 __GEN_COUTV__(runTimeSeconds());
3357 std::string documentNameToLoad =
"XDAQApplicationTable";
3360 __GEN_COUT__ <<
"Testing table save of pre-existing " << documentNameToLoad
3365 documentNameToLoad);
3366 localDocLoader.changeVersionAndActivateView(
3368 theInterface_->fill(&localDocLoader, documentVersionToLoad);
3370 localDocLoader.
print(ss);
3371 __GEN_COUTV__(ss.str());
3373 __GEN_COUTV__(runTimeSeconds());
3377 std::string documentNameToSave = documentNameToLoad;
3380 documentNameToSave);
3381 localDocSaver.changeVersionAndActivateView(
3384 std::string json =
"{ }";
3387 __COUTT__ <<
"Saving JSON string: "
3390 __COUTT__ <<
"Saving JSON doc as "
3391 << localDocSaver.getView().getTableName() <<
"("
3392 << localDocSaver.getView().getVersion().
toString() <<
")"
3396 theInterface_->saveActiveVersion(&localDocSaver,
false );
3400 __GEN_COUT__ <<
"Exception during table save." << __E__;
3402 __GEN_COUTV__(runTimeSeconds());
3406 documentNameToLoad);
3407 localDocLoader.changeVersionAndActivateView(
3409 theInterface_->fill(&localDocLoader, documentVersionToLoad);
3411 localDocLoader.
print(ss);
3412 __GEN_COUTV__(ss.str());
3414 __GEN_COUTV__(runTimeSeconds());
3416 __GEN_COUTV__(runTimeSeconds());
3420 std::string documentNameToLoad =
"MessageFacilityTable";
3423 documentNameToLoad);
3425 __GEN_COUT__ <<
"Testing table save of non-existing " << documentNameToLoad
3429 localDocLoader.changeVersionAndActivateView(
3431 theInterface_->fill(&localDocLoader, documentVersionToLoad);
3433 localDocLoader.
print(ss);
3434 __GEN_COUTV__(ss.str());
3435 __GEN_COUTV__(runTimeSeconds());
3437 __GEN_COUTV__(runTimeSeconds());
3444 theInterface_->findLatestVersion(&localDocLoader));
3445 localDocLoader.getViewP()->
setVersion(newVersion);
3447 __GEN_COUTT__ <<
"Saving new table as "
3448 << localDocLoader.getView().getTableName() <<
"("
3449 << localDocLoader.getView().getVersion().
toString() <<
")"
3453 "10.226.9.17", 0, 4);
3456 localDocLoader.
print(ss);
3457 __GEN_COUTV__(ss.str());
3460 theInterface_->saveActiveVersion(&localDocLoader,
false );
3464 __GEN_COUT__ <<
"Exception during new table save." << __E__;
3466 __GEN_COUTV__(runTimeSeconds());
3468 __GEN_COUTV__(runTimeSeconds());
3472 for(
auto& groupInfo : allGroupInfo_)
3476 groupInfo.second.latestKey_ = groupInfo.second.getLastKey();
3478 groupInfo.second.latestKey_,
3480 &groupInfo.second.latestKeyMemberMap_ ,
3483 &groupInfo.second.latestKeyGroupComment_,
3484 &groupInfo.second.latestKeyGroupAuthor_,
3485 &groupInfo.second.latestKeyGroupCreationTime_,
3487 &groupInfo.second.latestKeyGroupTypeString_);
3489 catch(
const std::runtime_error& e)
3492 <<
"Error occurred loading latest group info into cache for '"
3493 << groupInfo.first <<
"(" << groupInfo.second.latestKey_ <<
")': \n"
3494 << e.what() << __E__;
3496 groupInfo.second.latestKey_ = TableGroupKey::INVALID;
3497 groupInfo.second.latestKeyGroupComment_ =
3498 ConfigurationManager::UNKNOWN_INFO;
3499 groupInfo.second.latestKeyGroupAuthor_ =
3500 ConfigurationManager::UNKNOWN_INFO;
3501 groupInfo.second.latestKeyGroupCreationTime_ =
3502 ConfigurationManager::UNKNOWN_TIME;
3503 groupInfo.second.latestKeyGroupTypeString_ =
3504 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
3505 groupInfo.second.latestKeyMemberMap_ = {};
3510 <<
"Error occurred loading latest group info into cache for '"
3511 << groupInfo.first <<
"(" << groupInfo.second.latestKey_ <<
")'..."
3514 groupInfo.second.latestKey_ = TableGroupKey::INVALID;
3515 groupInfo.second.latestKeyGroupComment_ =
3516 ConfigurationManager::UNKNOWN_INFO;
3517 groupInfo.second.latestKeyGroupAuthor_ =
3518 ConfigurationManager::UNKNOWN_INFO;
3519 groupInfo.second.latestKeyGroupCreationTime_ =
3520 ConfigurationManager::UNKNOWN_TIME;
3521 groupInfo.second.latestKeyGroupTypeString_ =
3522 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
3523 groupInfo.second.latestKeyMemberMap_ = {};
3526 __GEN_COUTV__(runTimeSeconds());
3528 catch(
const std::runtime_error& e)
3530 __SS__ <<
"A fatal error occurred reading the info for all table groups. Error: "
3531 << e.what() << __E__;
3532 __GEN_COUT_ERR__ <<
"\n" << ss.str();
3533 if(accumulatedWarnings)
3534 *accumulatedWarnings += ss.str();
3540 __SS__ <<
"An unknown fatal error occurred reading the info for all table groups."
3542 __GEN_COUT_ERR__ <<
"\n" << ss.str();
3543 if(accumulatedWarnings)
3544 *accumulatedWarnings += ss.str();
3549 __GEN_COUT__ <<
"testXDAQContext() end runTimeSeconds()=" << runTimeSeconds()
3555 __GEN_COUT__ <<
"Loading table..." << __E__;
3561 __GEN_COUT__ << __E__;
3563 __GEN_COUT__ <<
"Value: " << v << __E__;
3564 __GEN_COUT__ <<
"Value index: " << t.
getValue<
int>() << __E__;
3570 __GEN_COUT__ <<
"Failed to load table..." << __E__;
TableVersion saveNewVersion(TableBase *table, TableVersion temporaryVersion, TableVersion newVersion=TableVersion())
TableVersion saveNewTable(const std::string &tableName, TableVersion temporaryVersion=TableVersion(), bool makeTemporary=false)
modifiers of generic TableBase
TableGroupKey findTableGroup(const std::string &groupName, const std::map< std::string, TableVersion > &groupMembers, const std::map< std::string, std::string > &groupAliases=std::map< std::string, std::string >())
TableVersion updateTableCells(const std::string &tableName, const std::map< std::string, std::map< std::string, std::string >> &cellUpdates, const std::string &author, TableVersion sourceVersion=TableVersion(), const std::string &versionAlias="", const std::string &sourceAlias="", const std::string &comment="")
void testXDAQContext(void)
for debugging
TableVersion saveNewBackbone(TableVersion temporaryVersion=TableVersion())
const GroupInfo & getGroupInfo(const std::string &groupName, bool attemptToReloadKeys=false)
public group cache handling
void clearAllCachedVersions(void)
const std::map< std::string, TableInfo > & getAllTableInfo(bool refresh=false, std::string *accumulatedWarnings=0, const std::string &errorFilterName="", bool getGroupKeys=false, bool getGroupInfo=false, bool initializeActiveGroups=false)
void loadTableGroup(const std::string &tableGroupName, const TableGroupKey &tableGroupKey, bool doActivate=false, std::map< std::string, TableVersion > *groupMembers=0, ProgressBar *progressBar=0, std::string *accumulateWarnings=0, std::string *groupComment=0, std::string *groupAuthor=0, std::string *groupCreateTime=0, bool doNotLoadMember=false, std::string *groupTypeString=0, std::map< std::string, std::string > *groupAliases=0, ConfigurationManager::LoadGroupType groupTypeToLoad=ConfigurationManager::LoadGroupType::ALL_TYPES, bool ignoreVersionTracking=false)
TableVersion copyViewToCurrentColumns(const std::string &tableName, TableVersion sourceVersion)
copyViewToCurrentColumns
TableGroupKey saveNewTableGroup(const std::string &groupName, std::map< std::string, TableVersion > &groupMembers, const std::string &groupComment=TableViewColumnInfo::DATATYPE_COMMENT_DEFAULT, std::map< std::string, std::string > *groupAliases=0)
modifiers of a table group based on alias, e.g. "Physics"
void activateTableGroup(const std::string &tableGroupName, TableGroupKey tableGroupKey, std::string *accumulatedTreeErrors=0, std::string *groupTypeString=0)
modifiers of table groups
TableBase * getMetadataTable(TableVersion fillVersion=TableVersion())
created for use in otsdaq_flatten_system_aliases and otsdaq_export_system_aliases,...
TableVersion saveModifiedVersion(const std::string &tableName, TableVersion originalVersion, bool makeTemporary, TableBase *config, TableVersion temporaryModifiedVersion, bool ignoreDuplicates=false, bool lookForEquivalent=false, bool *foundEquivalent=nullptr)
TableVersion createTemporaryBackboneView(TableVersion sourceViewVersion=TableVersion())
-1, from MockUp, else from valid backbone view version
void clearCachedVersions(const std::string &tableName)
std::map< std::string, std::map< std::string, TableVersion > > getVersionAliases(void) const
void eraseTemporaryVersion(const std::string &tableName, TableVersion targetVersion=TableVersion())
void preloadVersionCreationTimes(void)
parallel load of all version creation times into the process-wide cache
static void compareTableGroupThread(ConfigurationManagerRW *cfgMgr, std::string groupName, ots::TableGroupKey groupKeyToCompare, const std::map< std::string, TableVersion > &groupMemberMap, const std::map< std::string, std::string > &memberTableAliases, std::atomic< bool > *theFoundIdentical, ots::TableGroupKey *theIdenticalKey, std::mutex *theThreadMutex, std::shared_ptr< std::atomic< bool >> theThreadDone)
static void loadTableGroupThread(ConfigurationManagerRW *cfgMgr, std::string groupName, ots::TableGroupKey groupKey, std::shared_ptr< ots::GroupInfo > theGroupInfo, std::shared_ptr< std::atomic< bool >> theThreadDone)
loadTableGroupThread()
time_t getVersionCreationTime(const std::string &tableName, TableVersion version)
static void loadTableInfoThread(ConfigurationManagerRW *cfgMgr, std::string tableName, TableBase *existingTable, std::shared_ptr< ots::TableInfo > tableInfo, std::shared_ptr< std::atomic< bool >> threadDone)
loadTableInfoThread()
std::map< std::string, std::map< std::string, TableVersion > > getVersionAliases(void) const
static const std::string & convertGroupTypeToName(const ConfigurationManager::GroupType &groupTypeId)
void restoreActiveTableGroups(bool throwErrors=false, const std::string &pathToActiveGroupsFile="", ConfigurationManager::LoadGroupType onlyLoadIfBackboneOrContext=ConfigurationManager::LoadGroupType::ALL_TYPES, std::string *accumulatedWarnings=0)
std::map< std::string, TableVersion > getActiveVersions(void) const
getActiveVersions
ConfigurationTree getNode(const std::string &nodeString, bool doNotThrowOnBrokenUIDLinks=false) const
"root/parent/parent/"
void loadTableGroup(const std::string &tableGroupName, const TableGroupKey &tableGroupKey, bool doActivate=false, std::map< std::string, TableVersion > *groupMembers=0, ProgressBar *progressBar=0, std::string *accumulateWarnings=0, std::string *groupComment=0, std::string *groupAuthor=0, std::string *groupCreateTime=0, bool doNotLoadMember=false, std::string *groupTypeString=0, std::map< std::string, std::string > *groupAliases=0, ConfigurationManager::LoadGroupType groupTypeToLoad=ConfigurationManager::LoadGroupType::ALL_TYPES, bool ignoreVersionTracking=false, std::map< std::string, TableVersion > mergeInTables={}, std::map< std::string, TableVersion > overrideTables={})
void init(std::string *accumulatedErrors=0, bool initForWriteAccess=false, std::string *accumulatedWarnings=0)
static const std::string & getTypeNameOfGroup(const std::map< std::string, TableVersion > &memberMap)
void destroyTableGroup(const std::string &theGroup="", bool onlyDeactivate=false)
static const std::string ACTIVE_GROUPS_FILENAME
added env check for otsdaq_flatten_active_to_version to function
const TableBase * getTableByName(const std::string &configurationName) const
friend class ConfigurationManagerRW
void getValue(T &value) const
std::vector< std::pair< std::string, ConfigurationTree > > getChildren(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool byPriority=false, bool onlyStatusTrue=false) const
TableVersion createTemporaryView(TableVersion sourceViewVersion=TableVersion(), TableVersion destTemporaryViewVersion=TableVersion::getNextTemporaryVersion())
source of -1, from MockUp, else from valid view version
void trimTemporary(TableVersion targetVersion=TableVersion())
unsigned int getNumberOfStoredViews(void) const
TableVersion checkForDuplicate(TableVersion needleVersion, TableVersion ignoreVersion=TableVersion()) const
bool isActive(void)
isActive
TableView * getTemporaryView(TableVersion temporaryVersion)
const unsigned int MAX_VIEWS_IN_CACHE
TableVersion getNextVersion(void) const
TableVersion copyView(const TableView &sourceView, TableVersion destinationVersion, const std::string &author, bool looseColumnMatching=false)
void print(std::ostream &out=std::cout) const
always prints active view
TableVersion getNextTemporaryVersion(void) const
void trimCache(unsigned int trimSize=-1)
std::string toString(void) const
toString
static TableGroupKey getNextKey(const TableGroupKey &key=TableGroupKey())
static void getGroupNameAndKey(const std::string &fullGroupString, std::string &groupName, TableGroupKey &key)
requires fullGroupString created as name + "_v" + key + ""
bool isInvalid(void) const
isInvalid
static std::string getFullGroupString(const std::string &groupName, const TableGroupKey &key, const std::string &preKey="_v", const std::string &postKey="")
bool isMockupVersion(void) const
std::string toString(void) const
toString
bool isInvalid(void) const
isInvalid
static TableVersion getNextVersion(const TableVersion &version=TableVersion())
bool isScratchVersion(void) const
bool isTemporaryVersion(void) const
static TableVersion getNextTemporaryVersion(const TableVersion &version=TableVersion())
unsigned int findRow(unsigned int col, const T &value, unsigned int offsetRow=0, bool doNotThrow=false) const
< in included .icc source
void setValueAsString(const std::string &value, unsigned int row, unsigned int col)
unsigned int findColByType(const std::string &type, unsigned int startingCol=0) const
void setVersion(const T &version)
< in included .icc source
const std::string & getCustomStorageData(void) const
Getters.
unsigned int getColUID(void) const
unsigned int findCol(const std::string &name) const
void setValue(const T &value, unsigned int row, unsigned int col)
< in included .icc source
unsigned int addRow(const std::string &author="", unsigned char incrementUniqueData=false, const std::string &baseNameAutoUID="", unsigned int rowToAdd=(unsigned int) -1, std::string childLinkIndex="", std::string groupId="")
void setCustomStorageData(const std::string &storageData)
defines used also by OtsConfigurationWizardSupervisor
TableEditStruct & getTableEditStruct(const std::string &tableName, bool markModified=false)
Note: if markModified, and table not found in group, this function will try to add it to group.
static std::string setToString(const std::set< T > &setToReturn, const std::string &delimeter=", ")
setToString ~
static std::string mapToString(const std::map< std::string, T > &mapToReturn, const std::string &primaryDelimeter=", ", const std::string &secondaryDelimeter=": ")
static std::string stackTrace(void)