otsdaq  v2_03_00
ConfigurationInterface.cc
1 #include "otsdaq-core/ConfigurationInterface/ConfigurationInterface.h"
2 #include "otsdaq-core/ConfigurationInterface/DatabaseConfigurationInterface.h"
3 #include "otsdaq-core/ConfigurationInterface/FileConfigurationInterface.h"
4 
5 #include "otsdaq-core/Macros/CoutMacros.h"
6 #include "otsdaq-core/MessageFacility/MessageFacility.h"
7 
8 #include <dirent.h>
9 #include <cassert>
10 #include <iostream>
11 #include <typeinfo>
12 
13 using namespace ots;
14 
15 #define DEBUG_CONFIGURATION true
16 
17 //==============================================================================
18 ConfigurationInterface* ConfigurationInterface::theInstance_ = 0;
19 bool ConfigurationInterface::theMode_ = true;
20 bool ConfigurationInterface::theVersionTrackingEnabled_ = true;
21 
22 const std::string ConfigurationInterface::GROUP_METADATA_TABLE_NAME =
23  "TableGroupMetadata";
24 
25 //==============================================================================
26 ConfigurationInterface::ConfigurationInterface() {}
27 
28 //==============================================================================
29 ConfigurationInterface* ConfigurationInterface::getInstance(bool mode)
30 {
31  if(mode == true)
32  {
33  if(theInstance_ != 0 &&
34  dynamic_cast<FileConfigurationInterface*>(theInstance_) == 0)
35  {
36  delete theInstance_;
37  theInstance_ = 0;
38  }
39  if(theInstance_ == 0) // && typeid(theInstance_) !=
40  // static_cast<DatabaseConfigurationInterface*> )
41  theInstance_ = new FileConfigurationInterface();
42  }
43  else
44  {
45  if(theInstance_ != 0 &&
46  dynamic_cast<DatabaseConfigurationInterface*>(theInstance_) == 0)
47  {
48  delete theInstance_;
49  theInstance_ = 0;
50  }
51  if(theInstance_ == 0) // && typeid(theInstance_) !=
52  // static_cast<DatabaseConfigurationInterface*> )
53  {
54  theInstance_ = new DatabaseConfigurationInterface();
55  }
56  }
57  theMode_ = mode;
58  return theInstance_;
59 }
60 
61 //==============================================================================
62 bool ConfigurationInterface::isVersionTrackingEnabled()
63 {
64  return ConfigurationInterface::theVersionTrackingEnabled_;
65 }
66 
67 //==============================================================================
68 void ConfigurationInterface::setVersionTrackingEnabled(bool setValue)
69 {
70  ConfigurationInterface::theVersionTrackingEnabled_ = setValue;
71 }
72 
73 //==============================================================================
74 // saveNewVersion
75 // If newVersion is 0, then save the temporaryVersion as the next positive version
76 // number,
77 // save using the interface, and return the new version number
78 // If newVersion is non 0, attempt to save as given newVersion number, else throw
79 // exception. return TableVersion::INVALID on failure
80 TableVersion ConfigurationInterface::saveNewVersion(TableBase* configuration,
81  TableVersion temporaryVersion,
82  TableVersion newVersion)
83 {
84  if(!temporaryVersion.isTemporaryVersion() ||
85  !configuration->isStored(temporaryVersion))
86  {
87  std::cout << __COUT_HDR_FL__
88  << "Invalid temporary version number: " << temporaryVersion
89  << std::endl;
90  return TableVersion(); // return INVALID
91  }
92 
93  if(!ConfigurationInterface::isVersionTrackingEnabled()) // tracking is OFF, so always
94  // save to same version
95  newVersion = TableVersion::SCRATCH;
96 
97  bool rewriteableExists = false;
98 
99  std::set<TableVersion> versions = getVersions(configuration);
100  if(newVersion == TableVersion::INVALID)
101  {
102  if(versions
103  .size() && // 1 more than last version, if any non-scratch versions exist
104  *(versions.rbegin()) != TableVersion(TableVersion::SCRATCH))
105  newVersion = TableVersion::getNextVersion(*(versions.rbegin()));
106  else if(versions.size() >
107  1) // if scratch exists, take 1 more than second to last version
108  newVersion = TableVersion::getNextVersion(*(--(versions.rbegin())));
109  else
110  newVersion = TableVersion::DEFAULT;
111  std::cout << __COUT_HDR_FL__ << "Next available version number is " << newVersion
112  << std::endl;
113  //
114  // //for sanity check, compare with config's idea of next version
115  // TableVersion baseNextVersion = configuration->getNextVersion();
116  // if(newVersion <= baseNextVersion)
117  // newVersion = TableVersion::getNextVersion(baseNextVersion);
118  //
119  // std::cout << __COUT_HDR_FL__ << "After considering baseNextVersion, " <<
120  // baseNextVersion <<
121  // ", next available version number is " << newVersion << std::endl;
122  }
123  else if(versions.find(newVersion) != versions.end())
124  {
125  std::cout << __COUT_HDR_FL__ << "newVersion(" << newVersion << ") already exists!"
126  << std::endl;
127  rewriteableExists = newVersion == TableVersion::SCRATCH;
128 
129  // throw error if version already exists and this is not the rewriteable version
130  if(!rewriteableExists || ConfigurationInterface::isVersionTrackingEnabled())
131  {
132  __SS__ << ("New version already exists!") << std::endl;
133  std::cout << __COUT_HDR_FL__ << ss.str();
134  __SS_THROW__;
135  }
136  }
137 
138  std::cout << __COUT_HDR_FL__ << "Version number to save is " << newVersion
139  << std::endl;
140 
141  // copy to new version
142  configuration->changeVersionAndActivateView(temporaryVersion, newVersion);
143 
144  // save to disk
145  // only allow overwrite if version tracking is disabled AND the rewriteable version
146  // already exists.
147  saveActiveVersion(
148  configuration,
149  !ConfigurationInterface::isVersionTrackingEnabled() && rewriteableExists);
150 
151  return newVersion;
152 }