1 #ifndef _ots_ConfigurationView_h_
2 #define _ots_ConfigurationView_h_
4 #include "otsdaq-core/ConfigurationDataFormats/ViewColumnInfo.h"
5 #include "otsdaq-core/MessageFacility/MessageFacility.h"
6 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
7 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationVersion.h"
20 std::string ots_demangle(
const char* name);
30 static const unsigned int INVALID;
31 typedef std::vector<std::vector<std::string> > DataView;
32 typedef DataView::iterator iterator;
33 typedef DataView::const_iterator const_iterator;
46 unsigned int findRow(
unsigned int col,
const T& value,
47 unsigned int offsetRow=0)
const
49 std::istringstream s(value);
50 return findRow(col,s.str(),offsetRow);
52 unsigned int findRow (
unsigned int col,
const std::string& value,
unsigned int offsetRow=0)
const;
55 unsigned int findRowInGroup(
unsigned int col,
const T& value,
56 const std::string &groupId,
const std::string &childLinkIndex,
unsigned int offsetRow=0)
const
58 std::istringstream s(value);
59 return findRowInGroup(col,s.str(),groupId,childLinkIndex,offsetRow);
61 unsigned int findRowInGroup (
unsigned int col,
const std::string &value,
const std::string &groupId,
const std::string &childLinkIndex,
unsigned int offsetRow=0)
const;
62 unsigned int findCol (
const std::string &name)
const;
63 unsigned int findColByType (
const std::string &type,
int startingCol = 0)
const;
66 const std::string& getUniqueStorageIdentifier (
void)
const;
67 const std::string& getTableName (
void)
const;
69 const std::string& getComment (
void)
const;
70 const std::string& getAuthor (
void)
const;
71 const time_t& getCreationTime (
void)
const;
72 const time_t& getLastAccessTime (
void)
const;
73 const bool& getLooseColumnMatching (
void)
const;
74 const unsigned int getDataColumnSize (
void)
const;
75 const unsigned int& getSourceColumnMismatch (
void)
const;
76 const unsigned int& getSourceColumnMissing (
void)
const;
77 const std::set<std::string>& getSourceColumnNames (
void)
const;
78 std::set<std::string> getColumnNames (
void)
const;
79 std::set<std::string> getColumnStorageNames (
void)
const;
80 std::vector<std::string> getDefaultRowValues (
void)
const;
82 unsigned int getNumberOfRows (
void)
const;
83 unsigned int getNumberOfColumns (
void)
const;
84 const unsigned int getColUID (
void)
const;
85 const unsigned int getColStatus (
void)
const;
91 bool isEntryInGroupCol (
const unsigned int& row,
const unsigned int& groupCol,
const std::string& groupNeedle, std::set<std::string>* groupIDList = 0)
const;
94 std::set<std::string> getSetOfGroupIDs (
const std::string& childLinkIndex,
unsigned int row = -1)
const;
95 bool isEntryInGroup (
const unsigned int& row,
const std::string& childLinkIndex,
const std::string& groupNeedle)
const;
96 const bool getChildLink (
const unsigned int& col,
bool& isGroup, std::pair<unsigned int /*link col*/, unsigned int /*link id col*/>& linkPair)
const;
97 const unsigned int getColLinkGroupID (
const std::string& childLinkIndex)
const;
98 void addRowToGroup (
const unsigned int& row,
const unsigned int& col,
const std::string& groupID);
99 bool removeRowFromGroup (
const unsigned int& row,
const unsigned int& col,
const std::string& groupID,
bool deleteRowIfNoGroupLeft=
false);
106 void getValue(T& value,
unsigned int row,
unsigned int col,
bool convertEnvironmentVariables=
true)
const
108 if(!(col < columnsInfo_.size() && row < getNumberOfRows()))
110 __SS__ <<
"Invalid row col requested" << std::endl;
111 __COUT_ERR__ <<
"\n" << ss.str();
112 throw std::runtime_error(ss.str());
115 value = validateValueForColumn<T>(theDataView_[row][col],col,convertEnvironmentVariables);
119 void getValue(std::string& value,
unsigned int row,
unsigned int col,
bool convertEnvironmentVariables=
true)
const;
128 T validateValueForColumn(
const std::string& value,
unsigned int col,
129 bool convertEnvironmentVariables=
true)
const
131 if(col >= columnsInfo_.size())
133 __SS__ <<
"Invalid col requested" << std::endl;
134 __COUT_ERR__ <<
"\n" << ss.str();
135 throw std::runtime_error(ss.str());
142 if(columnsInfo_[col].getDataType() == ViewColumnInfo::DATATYPE_NUMBER)
144 std::string data = convertEnvironmentVariables?convertEnvVariables(value):
149 __SS__ << (data +
" is not a number!") << std::endl;
150 __COUT__ <<
"\n" << ss.str();
151 throw std::runtime_error(ss.str());
154 if(
typeid(
double) ==
typeid(retValue))
155 retValue = strtod(data.c_str(),0);
156 else if(
typeid(
float) ==
typeid(retValue))
157 retValue = strtof(data.c_str(),0);
158 else if(data.size() > 2 && data[1] ==
'x')
159 retValue = strtol(data.c_str(),0,16);
160 else if(data.size() > 1 && data[0] ==
'b')
161 retValue = strtol(data.substr(1).c_str(),0,2);
163 retValue = strtol(data.c_str(),0,10);
167 else if(columnsInfo_[col].getType() == ViewColumnInfo::TYPE_FIXED_CHOICE_DATA &&
168 columnsInfo_[col].getDataType() == ViewColumnInfo::DATATYPE_STRING &&
169 (
typeid(int) ==
typeid(retValue) ||
170 typeid(
unsigned int) ==
typeid(retValue)))
177 if(value == ViewColumnInfo::DATATYPE_STRING_DEFAULT)
181 std::vector<std::string> choices = columnsInfo_[col].getDataChoices();
187 bool skipOne = (choices.size() &&
188 choices[0].find(
"arbitraryBool=") == 0);
190 for(retValue=1 + (skipOne?1:0);retValue-1<(T)choices.size();++retValue)
191 if(value == choices[retValue-1])
192 return retValue - (skipOne?1:0);
194 __SS__ <<
"\tInvalid value for column data type: " << columnsInfo_[col].getDataType()
195 <<
" in configuration " << tableName_
196 <<
" at column=" << columnsInfo_[col].getName()
197 <<
" for getValue with type '" << ots_demangle(
typeid(retValue).name())
199 <<
"Attempting to get index of '" << value
200 <<
" in fixed choice array, but was not found in array. "
201 <<
"Here are the valid choices:\n";
202 ss <<
"\t" << ViewColumnInfo::DATATYPE_STRING_DEFAULT <<
"\n";
203 for(
const auto &choice:choices)
204 ss <<
"\t" << choice <<
"\n";
205 __COUT__ <<
"\n" << ss.str();
206 throw std::runtime_error(ss.str());
211 else if(columnsInfo_[col].getDataType() == ViewColumnInfo::DATATYPE_STRING &&
212 typeid(bool) ==
typeid(retValue))
214 if(columnsInfo_[col].getType() == ViewColumnInfo::TYPE_ON_OFF)
215 retValue = (value == ViewColumnInfo::TYPE_VALUE_ON) ?
true:
false;
216 else if(columnsInfo_[col].getType() == ViewColumnInfo::TYPE_TRUE_FALSE)
217 retValue = (value == ViewColumnInfo::TYPE_VALUE_TRUE) ?
true:
false;
218 else if(columnsInfo_[col].getType() == ViewColumnInfo::TYPE_YES_NO)
219 retValue = (value == ViewColumnInfo::TYPE_VALUE_YES) ?
true:
false;
220 else if(value.length() && value[0] ==
'1')
222 else if(value.length() && value[0] ==
'0')
226 __SS__ <<
"Invalid boolean value encountered: " << value << __E__;
232 else if(columnsInfo_[col].getDataType() == ViewColumnInfo::DATATYPE_STRING &&
233 typeid(std::string) !=
typeid(retValue))
235 std::string data = convertEnvironmentVariables?convertEnvVariables(value):
242 if(
typeid(
double) ==
typeid(retValue))
243 retValue = strtod(data.c_str(),0);
244 else if(
typeid(
float) ==
typeid(retValue))
245 retValue = strtof(data.c_str(),0);
246 else if(
typeid(
unsigned int) ==
typeid(retValue) ||
247 typeid(
int) ==
typeid(retValue) ||
248 typeid(
unsigned long long) ==
typeid(retValue) ||
249 typeid(
long long) ==
typeid(retValue) ||
250 typeid(
unsigned long) ==
typeid(retValue) ||
251 typeid(
long) ==
typeid(retValue) ||
252 typeid(
unsigned short) ==
typeid(retValue) ||
253 typeid(
short) ==
typeid(retValue) ||
254 typeid(uint8_t) ==
typeid(retValue))
256 if(data.size() > 2 && data[1] ==
'x')
257 retValue = (T)strtol(data.c_str(),0,16);
258 else if(data.size() > 1 && data[0] ==
'b')
259 retValue = (T)strtol(data.substr(1).c_str(),0,2);
261 retValue = (T)strtol(data.c_str(),0,10);
265 __SS__ <<
"Invalid type requested for a numeric string." << __E__;
273 __SS__ <<
"Invalid type requested for a non-numeric string (must request std::string)." << __E__;
279 throw std::runtime_error(
"Error.");
281 catch(
const std::runtime_error& e)
283 __SS__ <<
"\tUnrecognized column data type: " << columnsInfo_[col].getDataType()
284 <<
" and column type: " << columnsInfo_[col].getType()
285 <<
", in configuration " << tableName_
286 <<
" at column=" << columnsInfo_[col].getName()
287 <<
" for getValue with type '" << ots_demangle(
typeid(retValue).name())
290 if(columnsInfo_[col].getType() == ViewColumnInfo::TYPE_FIXED_CHOICE_DATA)
291 ss <<
"For column type " << ViewColumnInfo::TYPE_FIXED_CHOICE_DATA
292 <<
" the only valid numeric types are 'int' and 'unsigned int.'" << __E__;
294 ss << e.what() << __E__;
295 throw std::runtime_error(ss.str());
300 std::string validateValueForColumn(
const std::string& value,
unsigned int col,
bool convertEnvironmentVariables=
true)
const;
302 std::string getValueAsString(
unsigned int row,
unsigned int col,
bool convertEnvironmentVariables=
true)
const;
303 std::string getEscapedValueAsString(
unsigned int row,
unsigned int col,
bool convertEnvironmentVariables=
true)
const;
304 bool isURIEncodedCommentTheSame(
const std::string &comment)
const;
306 const DataView& getDataView (
void)
const;
307 const std::vector<ViewColumnInfo>& getColumnsInfo (
void)
const;
308 std::vector<ViewColumnInfo>* getColumnsInfoP(
void);
313 void setUniqueStorageIdentifier (
const std::string &storageUID);
314 void setTableName (
const std::string &name );
315 void setComment (
const std::string &comment );
316 void setURIEncodedComment (
const std::string &uriComment );
317 void setAuthor (
const std::string &author );
318 void setCreationTime (time_t t );
319 void setLastAccessTime (time_t t = time(0) );
320 void setLooseColumnMatching (
bool setValue );
324 void setVersion (
const T &version)
333 void setValue(
const T &value,
unsigned int row,
unsigned int col)
335 if(!(col < columnsInfo_.size() && row < getNumberOfRows()))
337 __SS__ <<
"Invalid row (" << row <<
") col (" << col <<
") requested!" << std::endl;
338 throw std::runtime_error(ss.str());
341 if(columnsInfo_[col].getDataType() == ViewColumnInfo::DATATYPE_NUMBER)
343 std::stringstream ss;
345 theDataView_[row][col] = ss.str();
347 else if(columnsInfo_[col].getDataType() == ViewColumnInfo::DATATYPE_TIME &&
348 typeid(time_t) ==
typeid(value))
351 std::stringstream ss;
353 theDataView_[row][col] = ss.str();
357 __SS__ <<
"\tUnrecognized view data type: " << columnsInfo_[col].getDataType()
358 <<
" in configuration " << tableName_
359 <<
" at column=" << columnsInfo_[col].getName()
360 <<
" for setValue with type '" << ots_demangle(
typeid(value).name())
362 throw std::runtime_error(ss.str());
365 void setValue (
const std::string &value,
unsigned int row,
unsigned int col);
366 void setValue (
const char *value,
unsigned int row,
unsigned int col);
369 void setValueAsString (
const std::string &value,
unsigned int row,
unsigned int col);
372 void resizeDataView (
unsigned int nRows,
unsigned int nCols);
373 int addRow (
const std::string &author =
"",
bool incrementUniqueData =
false, std::string baseNameAutoUID =
"");
374 void deleteRow (
int r);
379 iterator begin (
void) {
return theDataView_.begin();}
380 iterator end (
void) {
return theDataView_.end();}
381 const_iterator begin (
void)
const {
return theDataView_.begin();}
382 const_iterator end (
void)
const {
return theDataView_.end();}
384 void print (std::ostream &out = std::cout)
const;
385 void printJSON (std::ostream &out = std::cout)
const;
386 int fillFromJSON (
const std::string &json);
387 int fillFromCSV (
const std::string &data,
const int &dataOffset = 0,
const std::string &author =
"")
throw(std::runtime_error);
388 bool setURIEncodedValue (
const std::string &value,
const unsigned int &row,
const unsigned int &col,
const std::string &author =
"");
390 static std::string decodeURIComponent (
const std::string& data);
393 const unsigned int getOrInitColUID (
void);
394 const unsigned int getOrInitColStatus (
void);
400 std::string convertEnvVariables (
const std::string& data)
const;
401 bool isNumber (
const std::string& s)
const;
403 std::string uniqueStorageIdentifier_;
404 std::string tableName_ ;
406 std::string comment_ ;
407 std::string author_ ;
408 time_t creationTime_ ;
409 time_t lastAccessTime_ ;
410 unsigned int colUID_, colStatus_;
411 std::map<std::string, unsigned int> colLinkGroupIDs_;
413 bool fillWithLooseColumnMatching_;
414 unsigned int sourceColumnMismatchCount_, sourceColumnMissingCount_;
415 std::set<std::string> sourceColumnNames_;
417 std::vector<ViewColumnInfo> columnsInfo_ ;
418 DataView theDataView_ ;