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