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