1 #include "otsdaq/ConfigurationInterface/Database_configInterface.h"
2 #include "otsdaq/Macros/ConfigurationInterfacePluginMacros.h"
3 #include "otsdaq/Macros/CoutMacros.h"
4 #include "otsdaq/MessageFacility/MessageFacility.h"
11 #include "artdaq-database/BasicTypes/basictypes.h"
12 #include "artdaq-database/ConfigurationDB/configurationdbifc.h"
13 #include "otsdaq/TableCore/TableBase.h"
15 #include "artdaq-database/ConfigurationDB/configuration_common.h"
16 #include "artdaq-database/ConfigurationDB/dispatch_common.h"
17 #include "artdaq-database/StorageProviders/FileSystemDB/provider_filedb.h"
18 #include "artdaq-database/StorageProviders/FileSystemDB/provider_filedb_index.h"
22 using artdaq::database::basictypes::FhiclData;
23 using artdaq::database::basictypes::JsonData;
26 using table_version_map_t = ots::DatabaseConfigurationInterface::table_version_map_t;
28 namespace db = artdaq::database::configuration;
29 using VersionInfoList_t = db::ConfigurationInterface::VersionInfoList_t;
31 constexpr
auto default_dbprovider =
"filesystem";
32 constexpr
auto default_entity =
"OTSROOT";
35 DatabaseConfigurationInterface::DatabaseConfigurationInterface()
37 #ifdef ARTDAQ_DATABASE_DEBUG_ENABLE
40 artdaq::database::configuration::debug::ExportImport();
41 artdaq::database::configuration::debug::ManageAliases();
42 artdaq::database::configuration::debug::ManageConfigs();
43 artdaq::database::configuration::debug::ManageDocuments();
44 artdaq::database::configuration::debug::Metadata();
46 artdaq::database::configuration::debug::detail::ExportImport();
47 artdaq::database::configuration::debug::detail::ManageAliases();
48 artdaq::database::configuration::debug::detail::ManageConfigs();
49 artdaq::database::configuration::debug::detail::ManageDocuments();
50 artdaq::database::configuration::debug::detail::Metadata();
52 artdaq::database::configuration::debug::options::OperationBase();
53 artdaq::database::configuration::debug::options::BulkOperations();
54 artdaq::database::configuration::debug::options::ManageDocuments();
55 artdaq::database::configuration::debug::options::ManageConfigs();
56 artdaq::database::configuration::debug::options::ManageAliases();
58 artdaq::database::configuration::debug::MongoDB();
59 artdaq::database::configuration::debug::UconDB();
60 artdaq::database::configuration::debug::FileSystemDB();
65 artdaq::database::filesystem::debug::enable();
74 artdaq::database::configuration::Multitasker();
75 TRACE_CNTL(
"modeS",
true);
79 std::string envVar = __ENV__(
"ARTDAQ_DATABASE_URI");
82 IS_FILESYSTEM_DB =
false;
84 IS_FILESYSTEM_DB =
true;
85 __COUTV__(IS_FILESYSTEM_DB);
94 auto start = std::chrono::high_resolution_clock::now();
96 auto ifc = db::ConfigurationInterface{default_dbprovider};
98 auto versionstring = version.
toString();
100 auto result = ifc.template loadVersion<decltype(table), JsonData>(
101 table, versionstring, default_entity);
103 auto end = std::chrono::high_resolution_clock::now();
105 std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
106 __COUTT__ <<
"Time taken to call DatabaseConfigurationInterface::fill(tableName="
107 << table->
getTableName() <<
", version=" << versionstring <<
") "
108 << duration <<
" milliseconds." << std::endl;
116 __SS__ <<
"\n\nDBI Error while filling '" << table->
getTableName() <<
"' version '"
117 << versionstring <<
"' - are you sure this version exists?\n"
118 <<
"Here is the error:\n\n"
119 << result.second << __E__;
126 bool overwrite)
const
129 auto start = std::chrono::high_resolution_clock::now();
131 auto ifc = db::ConfigurationInterface{default_dbprovider};
133 auto versionstring = table->getView().getVersion().
toString();
139 auto result = overwrite ? ifc.template overwriteVersion<decltype(table), JsonData>(
140 table, versionstring, default_entity)
141 : ifc.template storeVersion<decltype(table), JsonData>(
142 table, versionstring, default_entity);
144 auto end = std::chrono::high_resolution_clock::now();
146 std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
147 __COUTT__ <<
"Time taken to call "
148 "DatabaseConfigurationInterface::saveActiveVersion(tableName="
149 << table->
getTableName() <<
", versionstring=" << versionstring <<
") "
150 << duration <<
" milliseconds" << std::endl;
155 __SS__ <<
"DBI saveActiveVersion Error:" << result.second << __E__;
164 auto versions = getVersions(table);
176 return *(versions.rbegin());
185 auto start = std::chrono::high_resolution_clock::now();
187 auto ifc = db::ConfigurationInterface{default_dbprovider};
188 auto result = ifc.template getVersions<decltype(table)>(table, default_entity);
190 auto end = std::chrono::high_resolution_clock::now();
192 std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
194 <<
"Time taken to call DatabaseConfigurationInterface::getVersions(tableName="
195 << table->getTableName() <<
") " << duration <<
" milliseconds." << std::endl;
197 auto resultSet = std::set<TableVersion>{};
198 for(std::string
const& version : result)
199 resultSet.insert(
TableVersion(std::stol(version, 0, 10)));
216 catch(std::exception
const& e)
218 __COUT_WARN__ <<
"DBI Exception:" << e.what() <<
"\n";
227 auto start = std::chrono::high_resolution_clock::now();
229 auto ifc = db::ConfigurationInterface{default_dbprovider};
230 auto collection_name_prefix = std::string{};
232 auto result = ifc.listCollections(collection_name_prefix);
234 auto end = std::chrono::high_resolution_clock::now();
236 std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
238 <<
"Time taken to call "
239 "DatabaseConfigurationInterface::getAllTableNames(collection_name_prefix="
240 << collection_name_prefix <<
") " << duration <<
" milliseconds." << std::endl;
244 catch(std::exception
const& e)
246 __SS__ <<
"DBI Exception:" << e.what() <<
"\n";
251 __SS__ <<
"DBI Unknown exception.\n";
258 std::string
const& filterString)
const
261 auto start = std::chrono::high_resolution_clock::now();
263 auto ifc = db::ConfigurationInterface{default_dbprovider};
265 auto result = std::set<std::string>();
267 if(filterString ==
"")
268 result = ifc.findGlobalConfigurations(
"*");
272 result = ifc.findGlobalConfigurations(filterString +
"*");
277 auto end = std::chrono::high_resolution_clock::now();
279 std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
280 __COUTT__ <<
"Time taken to call "
281 "DatabaseConfigurationInterface::getAllTableGroupNames(filterString="
282 << filterString <<
") " << duration <<
" milliseconds." << std::endl;
286 catch(std::exception
const& e)
288 __SS__ <<
"Filter string '" << filterString <<
"' yielded DBI Exception:" << e.what()
294 __SS__ <<
"Filter string '" << filterString <<
"' yielded DBI Unknown exception.\n";
302 const std::string& groupName)
const noexcept
306 return *(keys.crbegin());
315 const std::string& groupName)
const
317 std::set<TableGroupKey> retSet;
320 if(n.find(groupName) == 0)
328 std::string
const& tableGroup,
bool includeMetaDataTable )
const
331 auto start = std::chrono::high_resolution_clock::now();
346 table_version_map_t retMap = getCachedTableGroupMembers(tableGroup);
347 __COUTV__(tableGroup);
348 __COUT_TYPE__(TLVL_DEBUG + 20)
351 if(!includeMetaDataTable)
354 auto metaTable = retMap.find(GROUP_METADATA_TABLE_NAME);
355 if(metaTable != retMap.end())
356 retMap.erase(metaTable);
359 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
360 std::chrono::high_resolution_clock::now() - start)
362 __COUTT__ <<
"Time taken to call "
363 "DatabaseConfigurationInterface::getTableGroupMembers(tableGroup="
364 << tableGroup <<
") " << duration <<
" milliseconds." << std::endl;
369 __COUTT__ <<
"Ignoring error "
370 "DatabaseConfigurationInterface::getTableGroupMembers(tableGroup="
371 << tableGroup <<
") " << __E__;
374 auto ifc = db::ConfigurationInterface{default_dbprovider};
375 auto result = ifc.loadGlobalConfiguration(tableGroup);
380 auto to_map = [](
auto const& inputList,
bool includeMetaDataTable) {
381 auto resultMap = table_version_map_t{};
383 std::for_each(inputList.begin(), inputList.end(), [&resultMap](
auto const& info) {
384 resultMap[info.configuration] = std::stol(info.version, 0, 10);
387 if(!includeMetaDataTable)
390 auto metaTable = resultMap.find(GROUP_METADATA_TABLE_NAME);
391 if(metaTable != resultMap.end())
392 resultMap.erase(metaTable);
397 table_version_map_t retMap = to_map(result, includeMetaDataTable);
400 saveTableGroupMemberCache(retMap, tableGroup);
405 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
406 std::chrono::high_resolution_clock::now() - start)
408 __COUTT__ <<
"Time taken to call "
409 "DatabaseConfigurationInterface::getTableGroupMembers(tableGroup="
410 << tableGroup <<
") " << duration <<
" milliseconds." << std::endl;
414 catch(std::exception
const& e)
416 __SS__ <<
"DBI Exception getting Group's member tables for '" << tableGroup
419 if(std::string(e.what()).find(
"connection refused") != std::string::npos)
421 ss <<
"\n\nConnection to database refused. Perhaps your ssh tunnel has "
428 __SS__ <<
"DBI Unknown exception getting Group's member tables for '" << tableGroup
430 __COUT_ERR__ << ss.str();
437 table_version_map_t DatabaseConfigurationInterface::getCachedTableGroupMembers(
438 std::string
const& tableGroup)
const
441 table_version_map_t retMap;
455 std::size_t vi = tableGroup.rfind(
"_v");
456 std::string groupName = tableGroup.substr(0, vi);
457 std::string groupKey = tableGroup.substr(vi + 2);
458 __COUTT__ <<
"Getting cache for " << groupName <<
"(" << groupKey <<
")" << __E__;
460 TableBase localGroupMemberCacheSaver(TableBase::GROUP_CACHE_PREPEND + groupName);
466 __COUTT__ <<
"IS_FILESYSTEM_DB=true, so checking cached keys for " << groupName
467 <<
"(" << groupKey <<
")" << __E__;
468 std::set<TableVersion> versions = getVersions(&localGroupMemberCacheSaver);
469 if(versions.find(localVersion) == versions.end())
471 __SS__ <<
"Cached member table versions not found for " << groupName <<
"("
472 << groupKey <<
")" << __E__;
477 localGroupMemberCacheSaver.changeVersionAndActivateView(
478 localGroupMemberCacheSaver.createTemporaryView(), localVersion);
480 fill(&localGroupMemberCacheSaver, localVersion);
482 __COUT_TYPE__(TLVL_DEBUG + 20)
483 << __COUT_HDR__ <<
"Loaded cache member map string "
484 << localGroupMemberCacheSaver.getViewP()->getCustomStorageData() << __E__;
487 localGroupMemberCacheSaver.getViewP()->getCustomStorageData(), retMap);
489 __COUT_TYPE__(TLVL_DEBUG + 20) << __COUT_HDR__ <<
"Loaded cache member map string "
494 catch(std::exception
const& e)
496 __SS__ <<
"DBI Exception getCachedTableGroupMembers for '" << tableGroup <<
"':\n\n"
502 __SS__ <<
"DBI Unknown exception getCachedTableGroupMembers for '" << tableGroup
509 void DatabaseConfigurationInterface::saveTableGroupMemberCache(
510 table_version_map_t
const& memberMap, std::string
const& tableGroup)
const
525 std::size_t vi = tableGroup.rfind(
"_v");
526 std::string groupName = tableGroup.substr(0, vi);
527 std::string groupKey = tableGroup.substr(vi + 2);
528 __COUTT__ <<
"Saving cache for " << groupName <<
"(" << groupKey <<
")" << __E__;
530 TableBase localGroupMemberCacheSaver(TableBase::GROUP_CACHE_PREPEND + groupName);
531 localGroupMemberCacheSaver.changeVersionAndActivateView(
532 localGroupMemberCacheSaver.createTemporaryView(),
536 std::stringstream groupCacheData;
537 groupCacheData <<
"{ ";
538 for(
const auto& member : memberMap)
539 groupCacheData << (member.first == memberMap.begin()->first ?
"" :
", ")
541 "\"" << member.first <<
"\" : \"" << member.second <<
"\"";
542 groupCacheData <<
"}";
544 localGroupMemberCacheSaver.getViewP()->setCustomStorageData(groupCacheData.str());
547 __COUTT__ <<
"Saving member map string "
548 << localGroupMemberCacheSaver.getViewP()->getCustomStorageData() << __E__;
550 __COUTT__ <<
"Saving cache table "
551 << localGroupMemberCacheSaver.getView().getTableName() <<
"("
552 << localGroupMemberCacheSaver.getView().getVersion().toString() <<
")"
556 saveActiveVersion(&localGroupMemberCacheSaver,
false );
559 catch(std::exception
const& e)
561 __SS__ <<
"DBI Exception saveTableGroupMemberCache for '" << tableGroup <<
"':\n\n"
563 __COUT_ERR__ << ss.str();
568 __SS__ <<
"DBI Unknown exception saveTableGroupMemberCache for '" << tableGroup
570 __COUT_ERR__ << ss.str();
577 std::string
const& tableGroup)
const
580 auto start = std::chrono::high_resolution_clock::now();
582 auto ifc = db::ConfigurationInterface{default_dbprovider};
584 auto to_list = [](
auto const& inputMap) {
585 auto resultList = VersionInfoList_t{};
589 std::back_inserter(resultList),
590 [](
auto const& mapEntry) {
591 return VersionInfoList_t::value_type{
592 mapEntry.first, mapEntry.second.toString(), default_entity};
598 auto result = IS_FILESYSTEM_DB
599 ? ifc.storeGlobalConfiguration(to_list(memberMap), tableGroup)
600 : ifc.storeGlobalConfiguration_mt(to_list(memberMap), tableGroup);
602 auto end = std::chrono::high_resolution_clock::now();
604 std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
606 <<
"Time taken to call DatabaseConfigurationInterface::saveTableGroup(tableGroup="
607 << tableGroup <<
") " << duration <<
" milliseconds." << std::endl;
614 saveTableGroupMemberCache(memberMap, tableGroup);
618 __COUT_WARN__ <<
"Ignoring errors during saveTableGroupMemberCache()"
625 __THROW__(result.second);
627 catch(std::exception
const& e)
629 __SS__ <<
"DBI Exception saveTableGroup for '" << tableGroup <<
"':\n\n"
635 __SS__ <<
"DBI Unknown exception saveTableGroup for '" << tableGroup <<
".'\n";
640 std::pair<std::string, TableVersion> DatabaseConfigurationInterface::saveCustomJSON(
641 const std::string& json,
const std::string& documentNameToSave)
const
644 __COUTT__ <<
"Saving doc '" << documentNameToSave <<
"'" << __E__;
646 TableBase localDocSaver(TableBase::JSON_DOC_PREPEND + documentNameToSave);
648 std::set<TableVersion> versions = getVersions(&localDocSaver);
651 version = TableVersion::getNextVersion(*versions.rbegin());
653 version = TableVersion::DEFAULT;
656 localDocSaver.changeVersionAndActivateView(localDocSaver.createTemporaryView(),
659 localDocSaver.getViewP()->setCustomStorageData(json);
661 __COUTT__ <<
"Saving JSON string: "
662 << localDocSaver.getViewP()->getCustomStorageData() << __E__;
664 __COUTT__ <<
"Saving JSON doc as " << localDocSaver.getView().getTableName() <<
"("
665 << localDocSaver.getView().getVersion().toString() <<
")" << __E__;
668 saveActiveVersion(&localDocSaver,
false );
670 return std::make_pair(localDocSaver.getTableName(),
671 localDocSaver.getView().getVersion());
673 catch(std::exception
const& e)
675 __SS__ <<
"DBI Exception saveCustomJSON for '" << documentNameToSave <<
"':\n\n"
677 __COUT_ERR__ << ss.str();
682 __SS__ <<
"DBI Unknown exception saveCustomJSON for '" << documentNameToSave
684 __COUT_ERR__ << ss.str();
689 std::string DatabaseConfigurationInterface::loadCustomJSON(
690 const std::string& documentNameToLoad,
TableVersion documentVersionToLoad)
const
693 __COUTT__ <<
"Loading doc '" << documentNameToLoad <<
"-v" << documentVersionToLoad
696 TableBase localDocLoader(TableBase::JSON_DOC_PREPEND + documentNameToLoad);
698 localDocLoader.changeVersionAndActivateView(localDocLoader.createTemporaryView(),
699 documentVersionToLoad);
701 fill(&localDocLoader, documentVersionToLoad);
703 __COUTT__ <<
"Loaded JSON doc string "
704 << localDocLoader.getViewP()->getCustomStorageData() << __E__;
706 return localDocLoader.getViewP()->getCustomStorageData();
708 catch(std::exception
const& e)
710 __SS__ <<
"DBI Exception saveCustomJSON for '" << documentNameToLoad <<
"-v"
711 << documentVersionToLoad <<
"':\n\n"
713 __COUT_ERR__ << ss.str();
718 __SS__ <<
"DBI Unknown exception saveCustomJSON for '" << documentNameToLoad <<
"-v"
719 << documentVersionToLoad <<
".'\n";
720 __COUT_ERR__ << ss.str();
void saveTableGroup(table_version_map_t const &memberMap, std::string const &tableGroup) const override
create a new table group from the contents map
TableVersion findLatestVersion(const TableBase *table) const noexcept override
find the latest table version by table type
table_version_map_t getTableGroupMembers(std::string const &tableGroup, bool includeMetaDataTable=false) const override
return the contents of a table group
std::set< std::string > getAllTableGroupNames(std::string const &filterString="") const override
find all table groups in database
std::set< TableGroupKey > getKeys(const std::string &groupName) const override
find all configuration groups in database
std::set< TableVersion > getVersions(const TableBase *table) const noexcept override
find all table versions by table type
std::set< std::string > getAllTableNames(void) const override
returns a list of all table names
void fill(TableBase *table, TableVersion version) const override
read table from database
TableGroupKey findLatestGroupKey(const std::string &groupName) const noexcept override
void saveActiveVersion(const TableBase *table, bool overwrite=false) const override
write table to database
const std::string & getTableName(void) const
Getters.
std::string toString(void) const
toString
void setVersion(const T &version)
< in included .icc source
static std::string mapToString(const std::map< std::string, T > &mapToReturn, const std::string &primaryDelimeter=", ", const std::string &secondaryDelimeter=": ")
static void getMapFromString(const std::string &inputString, std::map< S, T > &mapToReturn, const std::set< char > &pairPairDelimiter={',', '|', '&'}, const std::set< char > &nameValueDelimiter={'=', ':'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'})
getMapFromString ~