$treeview $search $mathjax $extrastylesheet
otsdaq
v2_03_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #ifndef _ots_ConfigurationInterface_h_ 00002 #define _ots_ConfigurationInterface_h_ 00003 00004 #include <memory> 00005 #include <set> 00006 #include <sstream> 00007 #include "otsdaq-core/Macros/CoutMacros.h" 00008 00009 #include "otsdaq-core/PluginMakers/MakeTable.h" 00010 #include "otsdaq-core/TableCore/TableBase.h" 00011 #include "otsdaq-core/TableCore/TableGroupKey.h" 00012 #include "otsdaq-core/TableCore/TableVersion.h" 00013 00014 namespace ots 00015 { 00016 class ConfigurationHandlerBase; 00017 00018 class ConfigurationInterface 00019 { 00020 friend class ConfigurationManagerRW; // because need access to latestVersion() call 00021 // for group metadata 00022 friend class ConfigurationManager; // because need access to fill() call for group 00023 // metadata 00024 00025 public: 00026 virtual ~ConfigurationInterface() { ; } 00027 00028 static ConfigurationInterface* getInstance(bool mode); 00029 static bool isVersionTrackingEnabled(); 00030 static void setVersionTrackingEnabled(bool setValue); 00031 00032 static const std::string GROUP_METADATA_TABLE_NAME; 00033 //============================================================================== 00034 // get 00035 // Note: If filling, assume, new view becomes active view. 00036 // 00037 // Loose column matching can be used to ignore column names when filling. 00038 // 00039 void get(TableBase*& table, 00040 const std::string tableName, 00041 std::shared_ptr<const TableGroupKey> groupKey = 0, 00042 const std::string* groupName = 0, 00043 bool dontFill = false, 00044 TableVersion version = TableVersion(), 00045 bool resetConfiguration = true, 00046 bool looseColumnMatching = false) 00047 { 00048 if(table == 0) 00049 { 00050 // try making table table plugin, if fails use TableBase 00051 try 00052 { 00053 table = makeTable(tableName); 00054 } 00055 catch(...) 00056 { 00057 } 00058 00059 if(table == 0) 00060 { 00061 //__COUT__ << "Using TableBase object with table name " << 00062 // tableName << std::endl; 00063 00064 // try making table base.. 00065 // if it fails, then probably something wrong with Info file 00066 try 00067 { 00068 table = new TableBase(tableName); 00069 } 00070 catch(...) // failure so cleanup any halfway complete table work 00071 { 00072 __COUT_WARN__ << "Failed to even use TableBase!" << std::endl; 00073 if(table) 00074 delete table; 00075 table = 0; 00076 throw; 00077 } 00078 } 00079 //__COUT__ << "Table constructed!" << std::endl; 00080 } 00081 00082 if(groupKey != 0 && groupName != 0) 00083 { // FIXME -- new TableGroup and TableGroupKey should be used! 00084 // version = configurations->getConditionVersion(*groupKey, 00085 // table->getTableName()); 00086 __SS__ << "FATAL ERROR: new TableGroup and TableGroupKey should be used!" 00087 << std::endl; 00088 __SS_THROW__; 00089 } 00090 else if(!dontFill) 00091 { 00092 // check version choice 00093 if(version == TableVersion::INVALID && 00094 (version = findLatestVersion(table)) == TableVersion::INVALID) 00095 { 00096 __COUT__ << "FATAL ERROR: Can't ask to fill a table object with " 00097 "a negative version! " 00098 << tableName << std::endl; 00099 __SS__ << "FATAL ERROR: Invalid latest version." << std::endl 00100 << std::endl 00101 << std::endl 00102 << "*******************" << std::endl 00103 << "Suggestion: If you expect a version to exist for this " 00104 "table, perhaps this is your first time running with " 00105 "the artdaq database. (and your old configurations have not " 00106 "been transferred?) " 00107 << std::endl 00108 << "Try running this once:\n\n\totsdaq_database_migrate" 00109 << std::endl 00110 << std::endl 00111 << "This will migrate the old ots file system table to " 00112 "the artdaq database approach." 00113 << std::endl 00114 << std::endl 00115 << std::endl; 00116 __SS_THROW__; 00117 } 00118 } 00119 00120 if(resetConfiguration) // reset to empty table views and no active view 00121 { // EXCEPT, keep temporary views! (call TableBase::reset to really reset all) 00122 table->deactivate(); 00123 std::set<TableVersion> versions = table->getStoredVersions(); 00124 for(auto& version : versions) 00125 if(!version.isTemporaryVersion()) // if not temporary 00126 table->eraseView(version); 00127 } 00128 00129 if(dontFill) 00130 return; 00131 00132 // Note: assume new view becomes active view 00133 00134 // take advantage of version possibly being cached 00135 if(table->isStored(version)) 00136 { 00137 //__COUT__ << "Using archived version: " << version << std::endl; 00138 00139 // Make sure this version is not already active 00140 if(!table->isActive() || version != table->getViewVersion()) 00141 table->setActiveView(version); 00142 00143 table->getViewP()->setLastAccessTime(); 00144 return; 00145 } 00146 00147 try // to fill 00148 { 00149 if(version.isTemporaryVersion()) 00150 { 00151 __SS__ << "FATAL ERROR: Can not use interface to fill a " 00152 "table object with a temporary version!" 00153 << std::endl; 00154 ss << "FATAL ERROR: Invalid temporary version v" << version << std::endl; 00155 __SS_THROW__; 00156 } 00157 00158 table->setupMockupView(version); 00159 table->setActiveView(version); 00160 00161 // loose column matching can be used to ignore column names 00162 table->getViewP()->setLooseColumnMatching(looseColumnMatching); 00163 fill(table, version); 00164 if(looseColumnMatching) 00165 table->getViewP()->setLooseColumnMatching(false); 00166 table->getViewP()->setLastAccessTime(); 00167 00169 // verify the new view 00170 if(table->getViewP()->getVersion() != version) 00171 { 00172 __COUT__ << "Version mismatch!! " << table->getViewP()->getVersion() 00173 << " vs " << version << std::endl; 00174 throw; 00175 } 00176 00177 // match key by ignoring '_' 00178 bool nameIsMatch = true; 00179 unsigned int nameIsMatchIndex, nameIsMatchStorageIndex; 00180 for(nameIsMatchIndex = 0, nameIsMatchStorageIndex = 0; 00181 nameIsMatchIndex < table->getViewP()->getTableName().size(); 00182 ++nameIsMatchIndex) 00183 { 00184 if(table->getMockupViewP()->getTableName()[nameIsMatchStorageIndex] == 00185 '_') 00186 ++nameIsMatchStorageIndex; // skip to next storage character 00187 if(table->getViewP()->getTableName()[nameIsMatchIndex] == '_') 00188 continue; // skip to next character 00189 00190 // match to storage name 00191 if(nameIsMatchStorageIndex >= 00192 table->getMockupViewP()->getTableName().size() || 00193 table->getViewP()->getTableName()[nameIsMatchIndex] != 00194 table->getMockupViewP()->getTableName()[nameIsMatchStorageIndex]) 00195 { 00196 // size mismatch or character mismatch 00197 nameIsMatch = false; 00198 break; 00199 } 00200 ++nameIsMatchStorageIndex; 00201 } 00202 00203 if(nameIsMatch) // if name is considered match by above rule, then force 00204 // matchup 00205 table->getViewP()->setTableName(table->getMockupViewP()->getTableName()); 00206 else // table->getViewP()->getTableName() != 00207 // table->getMockupViewP()->getTableName()) 00208 { 00209 __COUT__ << "View Table Name mismatch!! " 00210 << table->getViewP()->getTableName() << " vs " 00211 << table->getMockupViewP()->getTableName() << std::endl; 00212 throw; 00213 } 00214 table->getViewP() 00215 ->init(); // sanitize for column info (and possibly on dataType soon?) 00216 00217 // at this point, view has been verified! 00219 } 00220 catch(...) 00221 { 00222 __COUT__ << "Error occurred while getting and filling Table \"" << tableName 00223 << "\" version:" << version << std::endl; 00224 __COUT__ << "\t-Configuration interface mode=" << theMode_ << std::endl; 00225 throw; 00226 } 00227 00228 } // end get() 00229 00230 // table handling 00231 virtual std::set<std::string /*name*/> getAllTableNames() const 00232 throw(std::runtime_error) 00233 { 00234 __SS__; 00235 __THROW__(ss.str() + 00236 "ConfigurationInterface::... Must only call " 00237 "getAllTableNames in a mode with this functionality " 00238 "implemented (e.g. DatabaseConfigurationInterface)."); 00239 } 00240 virtual std::set<TableVersion> getVersions(const TableBase* configuration) const = 0; 00241 const bool& getMode() const { return theMode_; } 00242 TableVersion saveNewVersion(TableBase* configuration, 00243 TableVersion temporaryVersion, 00244 TableVersion newVersion = TableVersion()); 00245 00246 // group handling 00247 virtual std::set<std::string /*name*/> getAllTableGroupNames( 00248 const std::string& filterString = "") const throw(std::runtime_error) 00249 { 00250 __SS__; 00251 __THROW__(ss.str() + 00252 "ConfigurationInterface::... Must only call " 00253 "getAllTableGroupNames in a mode with this functionality " 00254 "implemented (e.g. DatabaseConfigurationInterface)."); 00255 } 00256 virtual std::set<TableGroupKey> getKeys(const std::string& groupName) const 00257 { 00258 __SS__; 00259 __THROW__(ss.str() + 00260 "ConfigurationInterface::... Must only call " 00261 "getKeys in a mode with this functionality " 00262 "implemented (e.g. DatabaseConfigurationInterface)."); 00263 } 00264 00265 // Caution: getTableGroupMembers must be carefully used.. the table versions 00266 // are as initially defined for table versions aliases, i.e. not converted according 00267 // to the metadata groupAliases! 00268 virtual std::map<std::string /*name*/, TableVersion /*version*/> getTableGroupMembers( 00269 std::string const& /*groupName*/, bool includeMetaDataTable = false) const 00270 throw(std::runtime_error) 00271 { 00272 __SS__; 00273 __THROW__(ss.str() + 00274 "ConfigurationInterface::... Must only call " 00275 "getTableGroupMembers in a mode with this functionality " 00276 "implemented (e.g. DatabaseConfigurationInterface)."); 00277 } 00278 00279 virtual void saveTableGroup( 00280 std::map<std::string /*name*/, 00281 TableVersion /*version*/> const& /*tableToVersionMap*/, 00282 std::string const& /*groupName*/) const throw(std::runtime_error) 00283 { 00284 __SS__; 00285 __THROW__(ss.str() + 00286 "ConfigurationInterface::... Must only call " 00287 "saveTableGroup in a mode with this functionality " 00288 "implemented (e.g. DatabaseConfigurationInterface)."); 00289 }; 00290 00291 protected: 00292 ConfigurationInterface(void); // Protected constructor 00293 00294 virtual void fill(TableBase* configuration, TableVersion version) const = 0; 00295 00296 public: // was protected,.. unfortunately, must be public to allow 00297 // otsdaq_database_migrate and otsdaq_import_system_aliases to compile 00298 virtual TableGroupKey findLatestGroupKey( 00299 const std::string& groupName) const /* return INVALID if no existing versions */ 00300 { 00301 __SS__; 00302 __THROW__(ss.str() + 00303 "ConfigurationInterface::... Must only call findLatestGroupKey in a " 00304 "mode with this functionality implemented (e.g. " 00305 "DatabaseConfigurationInterface)."); 00306 } 00307 virtual TableVersion findLatestVersion(const TableBase* configuration) 00308 const = 0; // return INVALID if no existing versions 00309 virtual void saveActiveVersion(const TableBase* configuration, 00310 bool overwrite = false) const = 0; 00311 00312 protected: 00313 ConfigurationHandlerBase* theConfigurationHandler_; 00314 00315 private: 00316 static ConfigurationInterface* theInstance_; 00317 static bool theMode_; // 1 is FILE, 0 is artdaq-DB 00318 static bool 00319 theVersionTrackingEnabled_; // tracking versions 1 is enabled, 0 is disabled 00320 }; 00321 00322 } // namespace ots 00323 #endif