tdaq-develop-2025-02-12
otsdaq_fix_new_table_fields_tool.cc
1 #include <dirent.h>
2 #include <cassert>
3 #include <iostream>
4 #include <memory>
5 #include <string>
6 
7 #include "otsdaq/ConfigurationInterface/ConfigurationInterface.h"
8 #include "otsdaq/ConfigurationInterface/ConfigurationManagerRW.h"
9 // #include "artdaq-database/StorageProviders/FileSystemDB/provider_filedb_index.h"
10 // #include "artdaq-database/JsonDocument/JSONDocument.h"
11 
18 using namespace ots;
19 
20 void FixNewTableFields(int argc, char* argv[])
21 {
22  std::cout << "=================================================\n";
23  std::cout << "=================================================\n";
24  std::cout << "=================================================\n";
25  __COUT__ << "\nFixing new table fields!" << __E__;
26 
27  std::cout << "\n\nusage: Two arguments:\n\t <pathToSwapIn (optional)> \n\n"
28  << "\t Default values: pathToSwapIn = \"\" \n\n"
29  << __E__;
30 
31  std::cout << "\n\nNote: This assumes artdaq db file type interface. "
32  << "The current database/ will be moved to database_<linuxtime>/ "
33  << "unless a pathToSwapIn is specified, in which case the path will "
34  << "be copied overwriting database/ \n\n"
35  << __E__;
36 
37  std::cout << "argc = " << argc << __E__;
38  for(int i = 0; i < argc; i++)
39  std::cout << "argv[" << i << "] = " << argv[i] << __E__;
40 
41  if(argc > 2)
42  {
43  std::cout << "Error! Must provide at most one parameter.\n\n" << __E__;
44  return;
45  }
46 
47  // determine if "h"elp was first parameter
48  std::string pathToSwapIn = "";
49  if(argc >= 2)
50  pathToSwapIn = argv[1];
51 
52  if(pathToSwapIn == "-h" || pathToSwapIn == "--help")
53  {
54  std::cout
55  << "Recognized parameter 1 as a 'help' option. Usage was printed. Exiting."
56  << __E__;
57  return;
58  }
59 
60  __COUTV__(pathToSwapIn);
61 
62  // return;
63  //==============================================================================
64  // Define environment variables
65  // Note: normally these environment variables are set by StartOTS.sh
66 
67  // These are needed by
68  // otsdaq/otsdaq/ConfigurationDataFormats/ConfigurationInfoReader.cc [207]
69  setenv("CONFIGURATION_TYPE", "File", 1); // Can be File, Database, DatabaseTest
70  setenv("CONFIGURATION_DATA_PATH",
71  (std::string(__ENV__("USER_DATA")) + "/ConfigurationDataExamples").c_str(),
72  1);
73  setenv(
74  "TABLE_INFO_PATH", (std::string(__ENV__("USER_DATA")) + "/TableInfo").c_str(), 1);
76 
77  // Some configuration plug-ins use __ENV__("SERVICE_DATA_PATH") in init() so define it
78  setenv("SERVICE_DATA_PATH",
79  (std::string(__ENV__("USER_DATA")) + "/ServiceData").c_str(),
80  1);
81 
82  // Some configuration plug-ins use __ENV__("OTSDAQ_LIB") and
83  // __ENV__("OTSDAQ_UTILITIES_LIB") in init() so define it to a non-sense place is ok
84  setenv("OTSDAQ_LIB", (std::string(__ENV__("USER_DATA")) + "/").c_str(), 1);
85  setenv("OTSDAQ_UTILITIES_LIB", (std::string(__ENV__("USER_DATA")) + "/").c_str(), 1);
86 
87  // Some configuration plug-ins use __ENV__("OTS_MAIN_PORT") in init() so define it
88  setenv("OTS_MAIN_PORT", "2015", 1);
89 
90  // also xdaq envs for XDAQContextTable
91  setenv("XDAQ_CONFIGURATION_DATA_PATH",
92  (std::string(__ENV__("USER_DATA")) + "/XDAQConfigurations").c_str(),
93  1);
94  setenv("XDAQ_CONFIGURATION_XML", "otsConfigurationNoRU_CMake", 1);
96 
97  //==============================================================================
98  // get prepared with initial source db
99 
100  // ConfigurationManager instance immediately loads active groups
101  __COUT__ << "Loading active Aliases..." << __E__;
102  ConfigurationManagerRW cfgMgrInst("flatten_admin");
103  ConfigurationManagerRW* cfgMgr = &cfgMgrInst;
104 
105  {
106  std::string accumulatedWarnings;
107  cfgMgr->restoreActiveTableGroups(false /*throwErrors*/,
108  "" /*pathToActiveGroupsFile*/,
109  ConfigurationManager::LoadGroupType::ALL_TYPES,
110  &accumulatedWarnings);
111 
112  __COUT__ << "Done Loading active groups: \n" << accumulatedWarnings << std::endl;
113  }
114 
115  // create set of groups to persist
116  // include active context
117  // include active backbone
118  // include active iterate group
119  // include active config group
120  // (keep key translation separate activeGroupKeys)
121  // include all groups with system aliases
122 
123  // for group in set
124  // load/activate group and flatten tables to flatVersion to new DB
125  // save new version to modifiedTables
126  // save group with flatVersion key to new DB
127  // save new key to groupSet
128  // ++flatVersion
129 
130  // reload the active backbone (using activeGroupKeys)
131  // modify group aliases and table aliases properly based on groupSet and
132  // modifiedTables save new backbone with flatVersion to new DB
133 
134  // backup the file ConfigurationManager::ACTIVE_GROUPS_FILENAME with time
135  // and change the ConfigurationManager::ACTIVE_GROUPS_FILENAME
136  // to reflect new group names/keys
137 
138  /* map<<groupName, origKey>, newKey> */
139  std::map<std::pair<std::string, TableGroupKey>, TableGroupKey> groupSet;
140  /* <tableName, <origVersion, newVersion> >*/
141  std::map<std::pair<std::string, TableVersion>, TableVersion> modifiedTables;
142  std::map<std::string, std::pair<TableGroupKey, TableGroupKey>> activeGroupKeys;
143  std::map<std::pair<std::string, TableGroupKey>, std::string> groupErrors;
144 
145  std::string activeBackboneGroupName = "";
146  std::string activeContextGroupName = "";
147  std::string activeIterateGroupName = "";
148  std::string activeConfigGroupName = "";
149 
150  std::string nowTime = std::to_string(time(0));
151 
152  std::string thenTime = "";
153  if(pathToSwapIn != "") // get target then time
154  {
155  thenTime = pathToSwapIn.substr(pathToSwapIn.rfind('_') + 1);
156  __COUT__ << "thenTime = " << thenTime << __E__;
157  // return;
158  }
159 
160  // add active groups to set
161  std::map<std::string, std::pair<std::string, TableGroupKey>> activeGroupsMap =
162  cfgMgr->getActiveTableGroups();
163 
164  for(const auto& activeGroup : activeGroupsMap)
165  {
166  groupSet.insert(std::pair<std::pair<std::string, TableGroupKey>, TableGroupKey>(
167  std::pair<std::string, TableGroupKey>(activeGroup.second.first,
168  activeGroup.second.second),
169  TableGroupKey()));
170  activeGroupKeys.insert(
171  std::pair<std::string, std::pair<TableGroupKey, TableGroupKey>>(
172  activeGroup.second.first,
173  std::pair<TableGroupKey, TableGroupKey>(activeGroup.second.second,
174  TableGroupKey())));
175 
176  if(activeGroup.first == ConfigurationManager::GROUP_TYPE_NAME_BACKBONE)
177  {
178  activeBackboneGroupName = activeGroup.second.first;
179  __COUT__ << "found activeBackboneGroupName = " << activeBackboneGroupName
180  << __E__;
181  }
182  else if(activeGroup.first == ConfigurationManager::GROUP_TYPE_NAME_CONTEXT)
183  {
184  activeContextGroupName = activeGroup.second.first;
185  __COUT__ << "found activeContextGroupName = " << activeContextGroupName
186  << __E__;
187  }
188  else if(activeGroup.first == ConfigurationManager::GROUP_TYPE_NAME_ITERATE)
189  {
190  activeIterateGroupName = activeGroup.second.first;
191  __COUT__ << "found activeIterateGroupName = " << activeIterateGroupName
192  << __E__;
193  }
194  else if(activeGroup.first == ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION)
195  {
196  activeConfigGroupName = activeGroup.second.first;
197  __COUT__ << "found activeConfigGroupName = " << activeConfigGroupName
198  << __E__;
199  }
200  }
201 
202  // add system alias groups to set
203  const std::string groupAliasesTableName =
204  ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
205  std::map<std::string, TableVersion> activeVersions = cfgMgr->getActiveVersions();
206  if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
207  {
208  __SS__ << "\nActive version of " << groupAliasesTableName << " missing! "
209  << groupAliasesTableName
210  << " is a required member of the Backbone configuration group."
211  << "\n\nLikely you need to activate a valid Backbone group." << __E__;
212  __SS_THROW__;
213  }
214 
215  std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
216  cfgMgr->getNode(groupAliasesTableName).getChildren();
217  for(auto& groupPair : aliasNodePairs)
218  groupSet.insert(std::pair<std::pair<std::string, TableGroupKey>, TableGroupKey>(
219  std::pair<std::string, TableGroupKey>(
220  groupPair.second.getNode("GroupName").getValueAsString(),
221  TableGroupKey(groupPair.second.getNode("GroupKey").getValueAsString())),
222  TableGroupKey()));
223 
224  __COUT__ << "Identified groups:" << __E__;
225  for(auto& group : groupSet)
226  __COUT__ << group.first.first << " " << group.first.second << __E__;
227  __COUT__ << __E__;
228  __COUT__ << __E__;
229 
230  // return;
231  //==============================================================================
232  // prepare to manipulate directories
233  std::string currentDir = __ENV__("ARTDAQ_DATABASE_URI");
234 
235  if(currentDir.find("filesystemdb://") != 0)
236  {
237  __SS__ << "filesystemdb:// was not found in $ARTDAQ_DATABASE_URI!" << __E__;
238  __SS_THROW__;
239  }
240 
241  currentDir = currentDir.substr(std::string("filesystemdb://").length());
242  while(currentDir.length() &&
243  currentDir[currentDir.length() - 1] == '/') // remove trailing '/'s
244  currentDir = currentDir.substr(0, currentDir.length() - 1);
245  std::string moveToDir = currentDir + "_" + nowTime;
246 
247  if(pathToSwapIn != "")
248  {
249  DIR* dp;
250  if((dp = opendir(pathToSwapIn.c_str())) == 0)
251  {
252  __COUT__ << "ERROR:(" << errno << "). Can't open directory: " << pathToSwapIn
253  << __E__;
254  exit(0);
255  }
256  closedir(dp);
257  }
258 
259  // handle directory swap
260  __COUT__ << "Copying current directory: \t" << currentDir << __E__;
261  __COUT__ << "\t... to: \t\t" << moveToDir << __E__;
262  // return;
263  rename(currentDir.c_str(), moveToDir.c_str());
264 
265  if(pathToSwapIn != "") // move the swap in directory in
266  {
267  __COUT__ << "Swapping in directory: \t" << pathToSwapIn << __E__;
268  __COUT__ << "\t.. to: \t\t" << currentDir << __E__;
269  rename(pathToSwapIn.c_str(), currentDir.c_str());
270 
271  // also swap in active groups file
272  // check if original active file exists
273  std::string activeGroupsFile =
275  FILE* fp = fopen(activeGroupsFile.c_str(), "r");
276  if(fp)
277  {
278  __COUT__ << "Swapping active groups file: \t" << activeGroupsFile << __E__;
279  __COUT__ << "\t.. to: \t\t" << ConfigurationManager::ACTIVE_GROUPS_FILENAME
280  << __E__;
281  rename(activeGroupsFile.c_str(),
283  }
284 
285  __COUT__ << "Path swapped in. Done." << __E__;
286  return;
287  }
288  else // copy the bkup back
289  std::system(("cp -r " + moveToDir + " " + currentDir).c_str());
290 
291  // return;
292 
293  //=============
294  // now ready to save each member table of active groups
295  // to new version fixing column names.
296 
297  // int flatVersion = 0;
298 
299  // ConfigurationInterface* theInterface_ = ConfigurationInterface::getInstance(false);
300  // //true for File interface, false for artdaq database;
301  TableView* cfgView;
302  TableBase* config;
303 
304  bool errDetected = false;
305  std::string accumulateErrors = "";
306 
307  std::map<std::string /*name*/, TableVersion> memberMap;
308  std::map<std::string /*name*/, std::string /*alias*/> groupAliases;
309  std::string groupComment;
310  // std::string groupAuthor;
311  // std::string groupCreateTime;
312  // time_t groupCreateTime_t;
313  // TableBase* groupMetadataTable = cfgMgr->getMetadataTable();
314 
315  // //don't do anything more if flatVersion is not persistent
316  // if(TableVersion(flatVersion).isInvalid() ||
317  // TableVersion(flatVersion).isTemporaryVersion())
318  // {
319  // __COUT__<< "\n\nflatVersion " << TableVersion(flatVersion) <<
320  // " is an invalid or temporary version. Skipping to end!" << __E__;
321  // goto CLEAN_UP;
322  // }
323 
324  for(auto& groupPair : groupSet)
325  {
326  errDetected = false;
327 
328  __COUT__ << "****************************" << __E__;
329  __COUT__ << "Loading members for " << groupPair.first.first << "("
330  << groupPair.first.second << ")" << __E__;
331 
332  //=========================
333  // load group, group metadata, and tables from original DB
334  try
335  {
336  cfgMgr->loadTableGroup(groupPair.first.first,
337  groupPair.first.second,
338  false /*doActivate*/,
339  &memberMap /*memberMap*/,
340  0 /*progressBar*/,
341  &accumulateErrors,
342  &groupComment,
343  0, //&groupAuthor,
344  0, //&groupCreateTime,
345  false /*doNotLoadMember*/,
346  0 /*groupTypeString*/,
347  &groupAliases);
348  }
349  catch(std::runtime_error& e)
350  {
351  __COUT__ << "Error was caught loading members for " << groupPair.first.first
352  << "(" << groupPair.first.second << ")" << __E__;
353  __COUT__ << e.what() << __E__;
354  errDetected = true;
355  }
356  catch(...)
357  {
358  __COUT__ << "Error was caught loading members for " << groupPair.first.first
359  << "(" << groupPair.first.second << ")" << __E__;
360  errDetected = true;
361  }
362 
363  //=========================
364 
365  // note error if any (loading) failure
366  if(errDetected)
367  {
368  // power on if group failed
369  // and record error
370 
371  groupErrors.insert(
372  std::pair<std::pair<std::string, TableGroupKey>, std::string>(
373  std::pair<std::string, TableGroupKey>(groupPair.first.first,
374  groupPair.first.second),
375  "Error caught loading the group."));
376  continue;
377  }
378 
379  //=========================
380  // save group and its tables with new key and versions!
381  try
382  {
383  __COUT__ << "Before member map: " << StringMacros::mapToString(memberMap)
384  << __E__;
385 
386  // saving tables
387  for(auto& memberPair : memberMap)
388  {
389  __COUT__ << memberPair.first << ":v" << memberPair.second << __E__;
390 
391  // check if table has already been modified by a previous group
392  // (i.e. two groups using the same version of a table)
393  if(modifiedTables.find(std::pair<std::string, TableVersion>(
394  memberPair.first, memberPair.second)) != modifiedTables.end())
395  {
396  __COUT__ << "Table was already modified!" << __E__;
397  memberPair.second =
398  modifiedTables[std::pair<std::string, TableVersion>(
399  memberPair.first, memberPair.second)];
400  __COUT__ << "\t to...\t" << memberPair.first << ":v"
401  << memberPair.second << __E__;
402  continue;
403  }
404 
405  // save new version, and then record new version in map
406 
407  // first copy to new column names
408  TableVersion temporaryVersion = cfgMgr->copyViewToCurrentColumns(
409  memberPair.first /*table name*/, memberPair.second /*source version*/
410  );
411 
412  // then save temporary to persistent version
413  TableVersion persistentVersion = cfgMgr->saveNewTable(
414  memberPair.first /*table name*/, temporaryVersion);
415 
416  // //change the version of the active view to flatVersion and
417  // save it config =
418  // cfgMgr->getTableByName(memberPair.first); cfgView =
419  // config->getViewP();
420  // cfgView->setVersion(TableVersion(flatVersion));
421  // theInterface_->saveActiveVersion(config);
422  //
423  // //set it back for the table so that future groups can
424  // re-use cached version
425  // cfgView->setVersion(memberPair.second);
427 
428  // save new version to modifiedTables
429  modifiedTables.insert(
430  std::pair<std::pair<std::string, TableVersion>, TableVersion>(
431  std::pair<std::string, TableVersion>(memberPair.first,
432  memberPair.second),
433  persistentVersion));
434 
435  memberPair.second = persistentVersion; // change version in the member
436  // map
437 
438  __COUT__ << "\t to...\t" << memberPair.first << ":v" << memberPair.second
439  << __E__;
440  } // end table member loop
441 
442  // now save new group
443  __COUT__ << "After member map: " << StringMacros::mapToString(memberMap)
444  << __E__;
445 
446  // return;
447 
448  TableGroupKey newGroupKey =
449  cfgMgr->saveNewTableGroup(groupPair.first.first /*groupName*/,
450  memberMap,
451  groupComment,
452  &groupAliases);
453 
454  //
455  //
456  //
457  // //Note: this code copies actions in
458  // ConfigurationManagerRW::saveNewTableGroup
459  //
460  // //add meta data
461  // __COUTV__(StringMacros::mapToString(groupAliases));
462  // __COUTV__(groupComment);
463  // __COUTV__(groupAuthor);
464  // __COUTV__(groupCreateTime);
465  // sscanf(groupCreateTime.c_str(),"%ld",&groupCreateTime_t);
466  // __COUTV__(groupCreateTime_t);
467  //
468  // //to compensate for unusual errors upstream, make sure the
469  // metadata table has one row
470  // while(groupMetadataTable->getViewP()->getNumberOfRows() > 1)
471  // groupMetadataTable->getViewP()->deleteRow(0);
472  // if(groupMetadataTable->getViewP()->getNumberOfRows() == 0)
473  // groupMetadataTable->getViewP()->addRow();
474  //
475  // //columns are uid,comment,author,time
476  // //ConfigurationManager::METADATA_COL_ALIASES TODO
477  // groupMetadataTable->getViewP()->setValue(
478  // StringMacros::mapToString(groupAliases,
479  // "," /*primary delimiter*/,":" /*secondary
480  // delimeter*/),
481  // 0,ConfigurationManager::METADATA_COL_ALIASES);
482  // groupMetadataTable->getViewP()->setValue(groupComment
483  //,0,ConfigurationManager::METADATA_COL_COMMENT);
484  // groupMetadataTable->getViewP()->setValue(groupAuthor
485  //,0,ConfigurationManager::METADATA_COL_AUTHOR);
486  // groupMetadataTable->getViewP()->setValue(groupCreateTime_t
487  //,0,ConfigurationManager::METADATA_COL_TIMESTAMP);
488  //
489  // //set version of metadata table
490  // groupMetadataTable->getViewP()->setVersion(TableVersion(flatVersion));
491  // theInterface_->saveActiveVersion(groupMetadataTable);
492  //
493  // //force groupMetadataTable_ to be a member for the group
494  // memberMap[groupMetadataTable->getTableName()] =
495  // groupMetadataTable->getViewVersion();
496  //
497  // //memberMap should now consist of members with new flat version,
498  // so save group theInterface_->saveTableGroup(memberMap,
499  // TableGroupKey::getFullGroupString(
500  // groupPair.first.first,
501  // TableGroupKey(flatVersion)));
502  //
503 
504  // and modify groupSet and activeGroupKeys keys
505  groupPair.second = TableGroupKey(newGroupKey);
506 
507  // if this is an active group, save key change
508  if(activeGroupKeys.find(groupPair.first.first) != activeGroupKeys.end() &&
509  activeGroupKeys[groupPair.first.first].first == groupPair.first.second)
510  activeGroupKeys[groupPair.first.first].second =
511  TableGroupKey(newGroupKey);
512  }
513  catch(std::runtime_error& e)
514  {
515  __COUT__ << "Error was caught saving group " << groupPair.first.first << " ("
516  << groupPair.first.second << ") " << __E__;
517  __COUT__ << e.what() << __E__;
518 
519  groupErrors.insert(
520  std::pair<std::pair<std::string, TableGroupKey>, std::string>(
521  std::pair<std::string, TableGroupKey>(groupPair.first.first,
522  groupPair.first.second),
523  "Error caught saving the group."));
524  }
525  catch(...)
526  {
527  __COUT__ << "Error was caught saving group " << groupPair.first.first << " ("
528  << groupPair.first.second << ") " << __E__;
529 
530  groupErrors.insert(
531  std::pair<std::pair<std::string, TableGroupKey>, std::string>(
532  std::pair<std::string, TableGroupKey>(groupPair.first.first,
533  groupPair.first.second),
534  "Error caught saving the group."));
535  }
536  //=========================
537 
538  } // end group loop
539 
540  // record in readme of moveToDir
541  {
542  FILE* fp = fopen((moveToDir + "/README_fix_new_table_fields.txt").c_str(), "a");
543  if(!fp)
544  __COUT__ << "\tError opening README file!" << __E__;
545  else
546  {
547  time_t rawtime;
548  struct tm* timeinfo;
549  char buffer[200];
550 
551  time(&rawtime);
552  timeinfo = localtime(&rawtime);
553  strftime(buffer, 200, "%b %d, %Y %I:%M%p %Z", timeinfo);
554 
555  fprintf(fp,
556  "This database %s \n\t is a backup of %s \n\t BEFORE forcing to new "
557  "table fields \n\t and was created at this time \n\t %lu \t %s\n\n\n",
558  currentDir.c_str(),
559  moveToDir.c_str(),
560  time(0),
561  buffer);
562 
563  fclose(fp);
564  }
565  }
566 
567  // record in readme for currentDir
568  {
569  FILE* fp = fopen((currentDir + "/README_otsdaq_flatten.txt").c_str(), "a");
570 
571  if(!fp)
572  __COUT__ << "\tError opening README file!" << __E__;
573  else
574  {
575  time_t rawtime;
576  struct tm* timeinfo;
577  char buffer[200];
578 
579  time(&rawtime);
580  timeinfo = localtime(&rawtime);
581  strftime(buffer, 200, "%b %d, %Y %I:%M:%S%p %Z", timeinfo);
582 
583  fprintf(fp,
584  "This database %s \n\t was forced to new table fields \n\t at this "
585  "time \n\t %lu \t %s\n\n\n",
586  currentDir.c_str(),
587  time(0),
588  buffer);
589 
590  fclose(fp);
591  }
592  }
593 
594  // //print resulting all groups
595  //
596  // __COUT__ << "Resulting Groups:" << __E__;
597  // for(const auto &group: groupSet)
598  // __COUT__<< group.first.first << ": " <<
599  // group.first.second << " => " << group.second << __E__;
600  // __COUT__ << "Resulting Groups end." << __E__;
601  //
602  //
603  // //print resulting active groups
604  //
605  // __COUT__ << "Resulting Active Groups:" << __E__;
606  // for(const auto &activeGroup: activeGroupKeys)
607  // __COUT__<< activeGroup.first << ": " <<
608  // activeGroup.second.first << " => " << activeGroup.second.second << __E__;
609  //
610  // __COUT__<< activeBackboneGroupName << " is the " <<
611  // ConfigurationManager::GROUP_TYPE_NAME_BACKBONE << "." << __E__;
612  // __COUT__ << "Resulting Active Groups end." << __E__;
613 
614  // reload the active backbone (using activeGroupKeys)
615  // modify group aliases and table aliases properly based on groupSet and
616  // modifiedTables save new backbone with flatVersion to new DB
617 
618  if(activeBackboneGroupName == "")
619  {
620  __COUT__ << "No active Backbone table identified." << __E__;
621  goto CLEAN_UP;
622  }
623 
624  __COUT__ << "Modifying the active Backbone table to reflect new table versions and "
625  "group keys."
626  << __E__;
627 
628  { // start active backbone group handling
629 
630  cfgMgr->loadTableGroup(activeBackboneGroupName,
631  activeGroupKeys[activeBackboneGroupName].second,
632  true /*doActivate*/,
633  &memberMap,
634  0 /*progressBar*/,
635  &accumulateErrors,
636  &groupComment);
637 
638  // modify Group Aliases Table and Version Aliases Table to point
639  // at DEFAULT and flatVersion respectively
640 
641  const std::string groupAliasesName =
642  ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
643  const std::string versionAliasesName =
644  ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
645 
646  std::map<std::string, TableVersion> activeMap = cfgMgr->getActiveVersions();
647 
648  // modify Group Aliases Table
649  if(activeMap.find(groupAliasesName) != activeMap.end())
650  {
651  __COUT__ << "\n\nModifying " << groupAliasesName << __E__;
652 
653  // now save new group
654  __COUT__ << "Before member map: " << StringMacros::mapToString(memberMap)
655  << __E__;
656 
657  // save new Group Aliases table and Version Aliases table
658  // first save new group aliases table
659  __COUT__ << groupAliasesName << ":v" << memberMap[groupAliasesName] << __E__;
660 
661  // first copy to new column names
662  TableVersion temporaryVersion = cfgMgr->copyViewToCurrentColumns(
663  groupAliasesName /*table name*/,
664  memberMap[groupAliasesName] /*source version*/
665  );
666 
667  config = cfgMgr->getTableByName(groupAliasesName);
668  config->setActiveView(temporaryVersion);
669  cfgView = config->getViewP();
670 
671  unsigned int col1 = cfgView->findCol("GroupName");
672  unsigned int col2 = cfgView->findCol("GroupKey");
673 
674  cfgView->print();
675 
676  // change all key entries found to the new key and delete rows for groups not
677  // found
678  bool found;
679  for(unsigned int row = 0; row < cfgView->getNumberOfRows(); ++row)
680  {
681  found = false;
682  for(const auto& group : groupSet)
683  if(group.second.isInvalid())
684  continue;
685  else if(cfgView->getDataView()[row][col1] == group.first.first &&
686  cfgView->getDataView()[row][col2] ==
687  group.first.second.toString())
688  {
689  // found a matching group/key pair
690  __COUT__ << "Changing row " << row << " for "
691  << cfgView->getDataView()[row][col1]
692  << " key=" << cfgView->getDataView()[row][col2]
693  << " to NEW key=" << group.second << __E__;
694  cfgView->setValue(group.second.toString(), row, col2);
695  found = true;
696  break;
697  }
698 
699  if(!found) // delete row
700  cfgView->deleteRow(row--);
701  }
702 
703  cfgView->print();
704 
705  // then save temporary to persistent version
706  TableVersion persistentVersion =
707  cfgMgr->saveNewTable(groupAliasesName /*table name*/, temporaryVersion);
708 
709  // //change the version of the active view to flatVersion and save it
710  // config = cfgMgr->getTableByName(groupAliasesName);
711  // cfgView = config->getViewP();
712  // cfgView->setVersion(TableVersion(flatVersion));
713  // theInterface_->saveActiveVersion(config);
714 
715  memberMap[groupAliasesName] =
716  persistentVersion; // change version in the member map
717 
718  __COUT__ << "\t to...\t" << groupAliasesName << ":v"
719  << memberMap[groupAliasesName] << __E__;
720 
721  } // done modifying group aliases
722 
723  // modify Version Aliases Table
724  if(activeMap.find(versionAliasesName) != activeMap.end())
725  {
726  __COUT__ << "\n\nModifying " << versionAliasesName << __E__;
727 
728  // first save new version aliases table
729  __COUT__ << versionAliasesName << ":v" << memberMap[versionAliasesName]
730  << __E__;
731 
732  // first copy to new column names
733  TableVersion temporaryVersion = cfgMgr->copyViewToCurrentColumns(
734  versionAliasesName /*table name*/,
735  memberMap[versionAliasesName] /*source version*/
736  );
737 
738  config = cfgMgr->getTableByName(versionAliasesName);
739  config->setActiveView(temporaryVersion);
740  cfgView = config->getViewP();
741  unsigned int col1 = cfgView->findCol("TableName");
742  unsigned int col2 = cfgView->findCol("Version");
743 
744  // change all version entries to the new version and delete rows with no match
745  bool found;
746  for(unsigned int row = 0; row < cfgView->getNumberOfRows(); ++row)
747  {
748  found = false;
749  for(const auto& table : modifiedTables)
750  if(cfgView->getDataView()[row][col1] == table.first.first &&
751  cfgView->getDataView()[row][col2] == table.first.second.toString())
752  {
753  // found a matching group/key pair
754  __COUT__ << "Changing row " << row << " for "
755  << cfgView->getDataView()[row][col1]
756  << " version=" << cfgView->getDataView()[row][col2]
757  << " to NEW version=" << table.second << __E__;
758  cfgView->setValue(table.second.toString(), row, col2);
759  found = true;
760  break;
761  }
762 
763  if(!found) // delete row
764  cfgView->deleteRow(row--);
765  }
766 
767  // then save temporary to persistent version
768  TableVersion persistentVersion =
769  cfgMgr->saveNewTable(versionAliasesName /*table name*/, temporaryVersion);
770 
771  // //change the version of the active view to flatVersion and save it
772  // config = cfgMgr->getTableByName(versionAliasesName);
773  // cfgView = config->getViewP();
774  // cfgView->setVersion(TableVersion(flatVersion));
775  // theInterface_->saveActiveVersion(config);
776 
777  memberMap[versionAliasesName] =
778  persistentVersion; // change version in the member map
779 
780  __COUT__ << "\t to...\t" << versionAliasesName << ":v"
781  << memberMap[versionAliasesName] << __E__;
782 
783  } // done modifying version aliases
784 
785  // now save new group
786  __COUT__ << "After member map: " << StringMacros::mapToString(memberMap) << __E__;
787 
788  TableGroupKey newGroupKey = cfgMgr->saveNewTableGroup(
789  activeBackboneGroupName /*groupName*/,
790  memberMap,
791  groupComment,
792  0 /*groupAliases*/); // Do we need groupAliases for backbone here?
793 
794  // TableGroupKey cfgMgr->saveNewTableGroup
795  // theInterface_->saveTableGroup(memberMap,
796  // TableGroupKey::getFullGroupString(
797  // activeBackboneGroupName,
798  // TableGroupKey(flatVersion)));
799 
800  activeGroupKeys[activeBackboneGroupName].second = TableGroupKey(newGroupKey);
801 
802  __COUT__ << "New to-be-active backbone group " << activeBackboneGroupName << ":v"
803  << activeGroupKeys[activeBackboneGroupName].second << __E__;
804  } // end active backbone group handling
805 
806  // backup the file ConfigurationManager::ACTIVE_GROUPS_FILENAME with time
807  // and change the ConfigurationManager::ACTIVE_GROUPS_FILENAME
808  // to reflect new group names/keys
809 
810  {
811  __COUT__ << "Manipulating the Active Groups file..." << __E__;
812 
813  // check if original active file exists
814  FILE* fp = fopen(ConfigurationManager::ACTIVE_GROUPS_FILENAME.c_str(), "r");
815  if(!fp)
816  {
817  __SS__ << "Original active groups file '"
819  << __E__;
820  goto CLEAN_UP;
821  }
822 
823  __COUT__ << "Backing up file: " << ConfigurationManager::ACTIVE_GROUPS_FILENAME
824  << __E__;
825 
826  fclose(fp);
827 
828  std::string renameFile =
830  rename(ConfigurationManager::ACTIVE_GROUPS_FILENAME.c_str(), renameFile.c_str());
831 
832  __COUT__ << "Backup file name: " << renameFile << __E__;
833 
834  TableGroupKey *theConfigurationTableGroupKey_, *theContextTableGroupKey_,
835  *theBackboneTableGroupKey_, *theIterateTableGroupKey_;
836  std::string theConfigurationTableGroup_, theContextTableGroup_,
837  theBackboneTableGroup_, theIterateTableGroup_;
838 
839  theConfigurationTableGroup_ = activeConfigGroupName;
840  theConfigurationTableGroupKey_ = &(activeGroupKeys[activeConfigGroupName].second);
841 
842  theContextTableGroup_ = activeContextGroupName;
843  theContextTableGroupKey_ = &(activeGroupKeys[activeContextGroupName].second);
844 
845  theBackboneTableGroup_ = activeBackboneGroupName;
846  theBackboneTableGroupKey_ = &(activeGroupKeys[activeBackboneGroupName].second);
847 
848  theIterateTableGroup_ = activeIterateGroupName;
849  theIterateTableGroupKey_ = &(activeGroupKeys[activeIterateGroupName].second);
850 
851  // the following is copied from ConfigurationManagerRW::activateTableGroup
852  {
853  __COUT__ << "Updating persistent active groups to "
854  << ConfigurationManager::ACTIVE_GROUPS_FILENAME << " ..." << __E__;
855 
857  FILE* fp = fopen(fn.c_str(), "w");
858  if(!fp)
859  return;
860 
861  fprintf(fp, "%s\n", theContextTableGroup_.c_str());
862  fprintf(fp,
863  "%s\n",
864  theContextTableGroupKey_
865  ? theContextTableGroupKey_->toString().c_str()
866  : "-1");
867  fprintf(fp, "%s\n", theBackboneTableGroup_.c_str());
868  fprintf(fp,
869  "%s\n",
870  theBackboneTableGroupKey_
871  ? theBackboneTableGroupKey_->toString().c_str()
872  : "-1");
873  fprintf(fp, "%s\n", theConfigurationTableGroup_.c_str());
874  fprintf(fp,
875  "%s\n",
876  theConfigurationTableGroupKey_
877  ? theConfigurationTableGroupKey_->toString().c_str()
878  : "-1");
879  fprintf(fp, "%s\n", theIterateTableGroup_.c_str());
880  fprintf(fp,
881  "%s\n",
882  theIterateTableGroupKey_
883  ? theIterateTableGroupKey_->toString().c_str()
884  : "-1");
885  fclose(fp);
886  }
887  }
888 
889  // print resulting all groups
890 
891  __COUT__ << "Resulting Groups:" << __E__;
892  for(const auto& group : groupSet)
893  __COUT__ << "\t" << group.first.first << ": " << group.first.second << " => "
894  << group.second << __E__;
895  __COUT__ << "Resulting Groups end." << __E__;
896 
897  // print resulting active groups
898 
899  __COUT__ << "Resulting Active Groups:" << __E__;
900  for(const auto& activeGroup : activeGroupKeys)
901  __COUT__ << "\t" << activeGroup.first << ": " << activeGroup.second.first
902  << " => " << activeGroup.second.second << __E__;
903 
904  __COUT__ << activeBackboneGroupName << " is the "
905  << ConfigurationManager::GROUP_TYPE_NAME_BACKBONE << "." << __E__;
906  __COUT__ << "Resulting Active Groups end." << __E__;
907 
908 CLEAN_UP:
909  //==============================================================================
910  __COUT__ << "End of Flattening Active Table Groups!\n\n\n" << __E__;
911 
912  __COUT__ << "****************************" << __E__;
913  __COUT__ << "There were " << groupSet.size() << " groups considered, and there were "
914  << groupErrors.size() << " errors found handling those groups." << __E__;
915  __COUT__ << "The following errors were found handling the groups:" << __E__;
916  for(auto& groupErr : groupErrors)
917  __COUT__ << "\t" << groupErr.first.first << " " << groupErr.first.second << ": \t"
918  << groupErr.second << __E__;
919  __COUT__ << "End of errors.\n\n" << __E__;
920 
921  __COUT__ << "Run the following to return to your previous database structure:"
922  << __E__;
923  __COUT__ << "\t otsdaq_fix_new_table_fiels " << moveToDir << "\n\n" << __E__;
924 
925  return;
926 } // end FixNewTableFields()
927 
928 int main(int argc, char* argv[])
929 {
930  FixNewTableFields(argc, argv);
931  return 0;
932 }
933 // BOOST_AUTO_TEST_SUITE_END()
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 onlyLoadIfBackboneOrContext=ConfigurationManager::LoadGroupType::ALL_TYPES, bool ignoreVersionTracking=false)
void restoreActiveTableGroups(bool throwErrors=false, const std::string &pathToActiveGroupsFile="", ConfigurationManager::LoadGroupType onlyLoadIfBackboneOrContext=ConfigurationManager::LoadGroupType::ALL_TYPES, std::string *accumulatedWarnings=0)
std::map< std::string, std::pair< std::string, TableGroupKey > > getActiveTableGroups(void) const
std::map< std::string, TableVersion > getActiveVersions(void) const
getActiveVersions
ConfigurationTree getNode(const std::string &nodeString, bool doNotThrowOnBrokenUIDLinks=false) const
"root/parent/parent/"
static const std::string ACTIVE_GROUPS_FILENAME
added env check for otsdaq_flatten_active_to_version to function
TableVersion saveNewTable(const std::string &tableName, TableVersion temporaryVersion=TableVersion(), bool makeTemporary=false)
modifiers of generic TableBase
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"
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
std::string toString(void) const
toString
void deleteRow(int r)
Definition: TableView.cc:3424
unsigned int findCol(const std::string &name) const
Definition: TableView.cc:1935
void setValue(const T &value, unsigned int row, unsigned int col)
< in included .icc source
static std::string mapToString(const std::map< std::string, T > &mapToReturn, const std::string &primaryDelimeter=", ", const std::string &secondaryDelimeter=": ")