1 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationView.h"
12 #define __MF_SUBJECT__ "ConfigurationView"
14 #define __MF_HDR__ tableName_ << ":v" << version_ << ":" << __COUT_HDR_FL__
16 const unsigned int ConfigurationView::INVALID = -1;
19 ConfigurationView::ConfigurationView(
const std::string &name)
20 : uniqueStorageIdentifier_ (
""),
25 creationTime_ (time(0)),
28 fillWithLooseColumnMatching_(false),
29 sourceColumnMismatchCount_ (0),
30 sourceColumnMissingCount_ (0)
34 ConfigurationView::~ConfigurationView(
void)
43 __SS__ <<
"Invalid use of operator=... Should not directly copy a ConfigurationView. Please use ConfigurationView::copy(sourceView,author,comment)";
44 throw std::runtime_error(ss.str());
50 const std::string &author)
52 tableName_ = src.tableName_;
53 version_ = destinationVersion;
54 comment_ = src.comment_;
57 lastAccessTime_ = time(0);
58 columnsInfo_ = src.columnsInfo_;
59 theDataView_ = src.theDataView_;
60 sourceColumnNames_ = src.sourceColumnNames_;
72 void ConfigurationView::init(
void)
78 std::set<std::string> colNameSet;
79 std::string capsColName, colName;
80 for(
auto &colInfo: columnsInfo_)
82 colName = colInfo.getStorageName();
83 if(colName ==
"COMMENT_DESCRIPTION")
86 for(
unsigned int i=0;i<colName.size(); ++i)
88 if(colName[i] ==
'_')
continue;
89 capsColName += colName[i];
92 colNameSet.emplace(capsColName);
95 if(colNameSet.size() != columnsInfo_.size())
97 __SS__ <<
"Configuration Error:\t" <<
98 " Columns names must be unique! There are " << columnsInfo_.size() <<
99 " columns and the unique name count is " << colNameSet.size() << std::endl;
100 __MOUT_ERR__ << ss.str();
102 throw std::runtime_error(ss.str());
109 if((colPos = findColByType(ViewColumnInfo::TYPE_COMMENT)) != INVALID)
111 if(columnsInfo_[colPos].getName() !=
"CommentDescription")
113 __SS__ <<
"Configuration Error:\t" << ViewColumnInfo::TYPE_COMMENT <<
114 " data type column must have name=" <<
115 "CommentDescription" << std::endl;
116 __MOUT_ERR__ << ss.str();
117 throw std::runtime_error(ss.str());
120 if(findColByType(ViewColumnInfo::TYPE_COMMENT,colPos+1) != INVALID)
122 __SS__ <<
"Configuration Error:\t" << ViewColumnInfo::TYPE_COMMENT <<
123 " data type in column " <<
124 columnsInfo_[colPos].getName() <<
125 " is repeated. This is not allowed." << std::endl;
126 __MOUT_ERR__ << ss.str();
127 throw std::runtime_error(ss.str());
130 if(colPos != getNumberOfColumns()-3)
132 __SS__ <<
"Configuration Error:\t" << ViewColumnInfo::TYPE_COMMENT <<
133 " data type column must be 3rd to last (in column " <<
134 getNumberOfColumns()-3 <<
")." << std::endl;
135 __MOUT_ERR__ << ss.str();
136 throw std::runtime_error(ss.str());
141 __SS__ <<
"Configuration Error:\t" << ViewColumnInfo::TYPE_COMMENT <<
142 " data type column " <<
" is missing. This is not allowed." << std::endl;
143 __MOUT_ERR__ << ss.str();
144 throw std::runtime_error(ss.str());
148 if((colPos = findColByType(ViewColumnInfo::TYPE_AUTHOR)) != INVALID)
150 if(findColByType(ViewColumnInfo::TYPE_AUTHOR,colPos+1) != INVALID)
152 __SS__ <<
"Configuration Error:\t" << ViewColumnInfo::TYPE_AUTHOR <<
153 " data type in column " <<
154 columnsInfo_[colPos].getName() <<
155 " is repeated. This is not allowed." << std::endl;
156 __MOUT_ERR__ << ss.str();
157 throw std::runtime_error(ss.str());
160 if(colPos != getNumberOfColumns()-2)
162 __SS__ <<
"Configuration Error:\t" << ViewColumnInfo::TYPE_AUTHOR <<
163 " data type column must be 2nd to last (in column " <<
164 getNumberOfColumns()-2 <<
")." << std::endl;
165 __MOUT_ERR__ << ss.str();
166 throw std::runtime_error(ss.str());
171 __SS__ <<
"Configuration Error:\t" << ViewColumnInfo::TYPE_AUTHOR <<
172 " data type column " <<
" is missing. This is not allowed." << std::endl;
173 __MOUT_ERR__ << ss.str();
174 throw std::runtime_error(ss.str());
178 if((colPos = findColByType(ViewColumnInfo::TYPE_TIMESTAMP)) != INVALID)
180 if(findColByType(ViewColumnInfo::TYPE_TIMESTAMP,colPos+1) != INVALID)
182 __SS__ <<
"Configuration Error:\t" << ViewColumnInfo::TYPE_TIMESTAMP <<
183 " data type in column " <<
184 columnsInfo_[colPos].getName() <<
" is repeated. This is not allowed." <<
186 __MOUT_ERR__ << ss.str();
187 throw std::runtime_error(ss.str());
190 if(colPos != getNumberOfColumns()-1)
192 __SS__ <<
"Configuration Error:\t" << ViewColumnInfo::TYPE_TIMESTAMP <<
193 " data type column must be last (in column " <<
194 getNumberOfColumns()-1 <<
")." << std::endl;
195 __MOUT_ERR__ << ss.str();
196 throw std::runtime_error(ss.str());
201 __SS__ <<
"Configuration Error:\t" << ViewColumnInfo::TYPE_TIMESTAMP <<
202 " data type column " <<
" is missing. This is not allowed." << std::endl;
203 __MOUT_ERR__ << ss.str();
204 throw std::runtime_error(ss.str());
210 std::set<std::string > uidSet;
211 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
213 if(uidSet.find(theDataView_[row][colUID_]) != uidSet.end())
215 __SS__ << (
"Entries in UID are not unique. Specifically at row=" +
216 std::to_string(row) +
" value=" + theDataView_[row][colUID_])<< std::endl;
217 __MOUT_ERR__ << ss.str();
218 throw std::runtime_error(ss.str());
221 if(theDataView_[row][colUID_].size() == 0)
223 __SS__ <<
"An invalid UID '" << theDataView_[row][colUID_] <<
"' " <<
224 " was identified. UIDs must contain at least 1 character." <<
226 throw std::runtime_error(ss.str());
229 for(
unsigned int i=0;i<theDataView_[row][colUID_].size();++i)
231 (theDataView_[row][colUID_][i] >=
'A' && theDataView_[row][colUID_][i] <=
'Z') ||
232 (theDataView_[row][colUID_][i] >=
'a' && theDataView_[row][colUID_][i] <=
'z') ||
233 (theDataView_[row][colUID_][i] >=
'0' && theDataView_[row][colUID_][i] <=
'9') ||
234 (theDataView_[row][colUID_][i] ==
'-' || theDataView_[row][colUID_][i] <=
'_')
237 __SS__ <<
"An invalid UID '" << theDataView_[row][colUID_] <<
"' " <<
238 " was identified. UIDs must contain only letters, numbers," <<
239 "dashes, and underscores." << std::endl;
240 throw std::runtime_error(ss.str());
243 uidSet.insert(theDataView_[row][colUID_]);
245 if(uidSet.size() != getNumberOfRows())
247 __SS__ <<
"Entries in UID are not unique!" <<
248 "There are " << getNumberOfRows() <<
249 " rows and the unique UID count is " << uidSet.size() << std::endl;
250 __MOUT_ERR__ << ss.str();
251 throw std::runtime_error(ss.str());
255 colPos = (
unsigned int)-1;
256 while((colPos = findColByType(ViewColumnInfo::TYPE_UNIQUE_DATA,colPos+1)) != INVALID)
258 std::set<std::string > uDataSet;
259 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
261 if(uDataSet.find(theDataView_[row][colPos]) != uDataSet.end())
263 __SS__ <<
"Entries in Unique Data column " <<
264 columnsInfo_[colPos].getName() <<
265 (
" are not unique. Specifically at row=" +
266 std::to_string(row) +
" value=" + theDataView_[row][colPos]) <<
268 __MOUT_ERR__ << ss.str();
269 throw std::runtime_error(ss.str());
271 uDataSet.insert(theDataView_[row][colPos]);
273 if(uDataSet.size() != getNumberOfRows())
275 __SS__ <<
"Entries in Unique Data column " <<
276 columnsInfo_[colPos].getName() <<
" are not unique!" <<
277 "There are " << getNumberOfRows() <<
278 " rows and the unique data count is " << uDataSet.size() << std::endl;
279 __MOUT_ERR__ << ss.str();
280 throw std::runtime_error(ss.str());
284 auto rowDefaults = getDefaultRowValues();
291 std::set<std::string> groupIdIndexes, childLinkIndexes, childLinkIdLabels;
292 unsigned int groupIdIndexesCount = 0, childLinkIndexesCount = 0, childLinkIdLabelsCount = 0;
293 for(
unsigned int col = 0; col < getNumberOfColumns(); ++col)
295 if(columnsInfo_[col].getType() == ViewColumnInfo::TYPE_FIXED_CHOICE_DATA)
298 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
302 if(theDataView_[row][col] == rowDefaults[col])
305 const std::vector<std::string>& theDataChoices =
306 columnsInfo_[col].getDataChoices();
309 if(theDataChoices.size() && theDataChoices[0] ==
313 for(
const auto &choice:theDataChoices)
315 if(theDataView_[row][col] == choice)
323 __SS__ <<
"Configuration Error:\t'" << theDataView_[row][col] <<
"' in column " <<
324 columnsInfo_[col].getName() <<
" is not a valid Fixed Choice option. " <<
325 "Possible values are as follows: ";
327 for(
unsigned int i = 0; i < columnsInfo_[col].getDataChoices().size(); ++i)
330 ss << columnsInfo_[col].getDataChoices()[i];
332 ss <<
"." << std::endl;
333 __MOUT_ERR__ << ss.str();
334 throw std::runtime_error(ss.str());
338 else if(columnsInfo_[col].getType() == ViewColumnInfo::TYPE_ON_OFF)
339 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
341 if (theDataView_[row][col] ==
"1" || theDataView_[row][col] ==
"on" || theDataView_[row][col] ==
"On" || theDataView_[row][col] ==
"ON")
342 theDataView_[row][col] = ViewColumnInfo::TYPE_VALUE_ON;
343 else if (theDataView_[row][col] ==
"0" || theDataView_[row][col] ==
"off" || theDataView_[row][col] ==
"Off" || theDataView_[row][col] ==
"OFF")
344 theDataView_[row][col] = ViewColumnInfo::TYPE_VALUE_OFF;
347 __SS__ <<
"Configuration Error:\t" << theDataView_[row][col] <<
" in column " <<
348 columnsInfo_[col].getName() <<
" is not a valid Type (On/Off) std::string. Possible values are 1, on, On, ON, 0, off, Off, OFF." << std::endl;
349 __MOUT_ERR__ << ss.str();
350 throw std::runtime_error(ss.str());
353 else if(columnsInfo_[col].getType() == ViewColumnInfo::TYPE_TRUE_FALSE)
354 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
356 if (theDataView_[row][col] ==
"1" || theDataView_[row][col] ==
"true" || theDataView_[row][col] ==
"True" || theDataView_[row][col] ==
"TRUE")
357 theDataView_[row][col] = ViewColumnInfo::TYPE_VALUE_TRUE;
358 else if (theDataView_[row][col] ==
"0" || theDataView_[row][col] ==
"false" || theDataView_[row][col] ==
"False" || theDataView_[row][col] ==
"FALSE")
359 theDataView_[row][col] = ViewColumnInfo::TYPE_VALUE_FALSE;
362 __SS__ <<
"Configuration Error:\t" << theDataView_[row][col] <<
" in column " <<
363 columnsInfo_[col].getName() <<
" is not a valid Type (True/False) std::string. Possible values are 1, true, True, TRUE, 0, false, False, FALSE." << std::endl;
364 __MOUT_ERR__ << ss.str();
365 throw std::runtime_error(
"Invalid true/false usage");
368 else if(columnsInfo_[col].getType() == ViewColumnInfo::TYPE_YES_NO)
369 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
371 if (theDataView_[row][col] ==
"1" || theDataView_[row][col] ==
"yes" || theDataView_[row][col] ==
"Yes" || theDataView_[row][col] ==
"YES")
372 theDataView_[row][col] = ViewColumnInfo::TYPE_VALUE_YES;
373 else if (theDataView_[row][col] ==
"0" || theDataView_[row][col] ==
"no" || theDataView_[row][col] ==
"No" || theDataView_[row][col] ==
"NO")
374 theDataView_[row][col] = ViewColumnInfo::TYPE_VALUE_NO;
377 __SS__ <<
"Configuration Error:\t" << theDataView_[row][col] <<
" in column " <<
378 columnsInfo_[col].getName() <<
" is not a valid Type (Yes/No) std::string. Possible values are 1, yes, Yes, YES, 0, no, No, NO." << std::endl;
379 __MOUT_ERR__ << ss.str();
380 throw std::runtime_error(ss.str());
383 else if(columnsInfo_[col].isGroupID())
385 colLinkGroupIDs_[columnsInfo_[col].getChildLinkIndex()] = col;
387 groupIdIndexes.emplace(columnsInfo_[col].getChildLinkIndex());
388 ++groupIdIndexesCount;
390 else if(columnsInfo_[col].isChildLink())
393 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
394 if(theDataView_[row][col] ==
"NoLink" ||
395 theDataView_[row][col] ==
"No_Link" ||
396 theDataView_[row][col] ==
"NOLINK" ||
397 theDataView_[row][col] ==
"NO_LINK" ||
398 theDataView_[row][col] ==
"Nolink" ||
399 theDataView_[row][col] ==
"nolink" ||
400 theDataView_[row][col] ==
"noLink")
401 theDataView_[row][col] = ViewColumnInfo::DATATYPE_LINK_DEFAULT;
404 childLinkIndexes.emplace(columnsInfo_[col].getChildLinkIndex());
405 ++childLinkIndexesCount;
408 if(columnsInfo_[col].getDataType() != ViewColumnInfo::DATATYPE_STRING)
410 __SS__ <<
"Configuration Error:\t" <<
"Column " << col <<
411 " with name " << columnsInfo_[col].getName() <<
412 " is a Child Link column and has an illegal data type of '" <<
413 columnsInfo_[col].getDataType() <<
414 "'. The data type for Child Link columns must be " <<
415 ViewColumnInfo::DATATYPE_STRING << std::endl;
416 __MOUT_ERR__ << ss.str();
417 throw std::runtime_error(ss.str());
421 else if(columnsInfo_[col].isChildLinkUID() ||
422 columnsInfo_[col].isChildLinkGroupID())
425 childLinkIdLabels.emplace(columnsInfo_[col].getChildLinkIndex());
426 ++childLinkIdLabelsCount;
429 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
430 if(theDataView_[row][col] ==
"")
431 theDataView_[row][col] = rowDefaults[col];
437 if(groupIdIndexes.size() != groupIdIndexesCount)
439 __SS__ << (
"GroupId Labels are not unique!") <<
440 "There are " << groupIdIndexesCount <<
441 " GroupId Labels and the unique count is " << groupIdIndexes.size() << std::endl;
442 __MOUT_ERR__ << ss.str();
443 throw std::runtime_error(ss.str());
445 if(childLinkIndexes.size() != childLinkIndexesCount)
447 __SS__ << (
"Child Link Labels are not unique!") <<
448 "There are " << childLinkIndexesCount <<
449 " Child Link Labels and the unique count is " << childLinkIndexes.size() << std::endl;
450 __MOUT_ERR__ << ss.str();
451 throw std::runtime_error(ss.str());
453 if(childLinkIdLabels.size() != childLinkIdLabelsCount)
455 __SS__ << (
"Child Link ID Labels are not unique!") <<
456 "There are " << childLinkIdLabelsCount <<
457 " Child Link ID Labels and the unique count is " << childLinkIdLabels.size() << std::endl;
458 __MOUT_ERR__ << ss.str();
459 throw std::runtime_error(ss.str());
465 __MOUT__ <<
"Error occured in ConfigurationView::init() for version=" << version_ << std::endl;
473 void ConfigurationView::getValue(std::string& value,
unsigned int row,
unsigned int col,
bool convertEnvironmentVariables)
const
475 if(!(col < columnsInfo_.size() && row < getNumberOfRows()))
476 throw std::runtime_error(
"Invalid row col requested");
478 if(columnsInfo_[col].getDataType() == ViewColumnInfo::DATATYPE_STRING)
480 value = theDataView_[row][col];
481 if(convertEnvironmentVariables)
482 value = convertEnvVariables(value);
484 else if(columnsInfo_[col].getDataType() == ViewColumnInfo::DATATYPE_TIME)
487 time_t timestamp(strtol(theDataView_[row][col].c_str(),0,10));
489 ::localtime_r(×tamp, &tmstruct);
490 ::strftime(&value[0], 30,
"%c %Z", &tmstruct);
491 value.resize(strlen(value.c_str()));
495 __SS__ <<
"\tUnrecognized column data type: " << columnsInfo_[col].getDataType()
496 <<
" in configuration " << tableName_
497 <<
" at column=" << columnsInfo_[col].getName()
498 <<
" for getValue with type '" << ots_demangle(
typeid(value).name())
500 throw std::runtime_error(ss.str());
511 std::string ConfigurationView::getValueAsString(
unsigned int row,
unsigned int col,
512 bool convertEnvironmentVariables)
const
514 if(!(col < columnsInfo_.size() && row < getNumberOfRows()))
515 throw std::runtime_error(
"Invalid row col requested");
518 if(columnsInfo_[col].getType() == ViewColumnInfo::TYPE_ON_OFF)
520 if (theDataView_[row][col] ==
"1" || theDataView_[row][col] ==
"on" || theDataView_[row][col] ==
"On" || theDataView_[row][col] ==
"ON")
521 return ViewColumnInfo::TYPE_VALUE_ON;
523 return ViewColumnInfo::TYPE_VALUE_OFF;
525 else if(columnsInfo_[col].getType() == ViewColumnInfo::TYPE_TRUE_FALSE)
527 if (theDataView_[row][col] ==
"1" || theDataView_[row][col] ==
"true" || theDataView_[row][col] ==
"True" || theDataView_[row][col] ==
"TRUE")
528 return ViewColumnInfo::TYPE_VALUE_TRUE;
530 return ViewColumnInfo::TYPE_VALUE_FALSE;
532 else if(columnsInfo_[col].getType() == ViewColumnInfo::TYPE_YES_NO)
534 if (theDataView_[row][col] ==
"1" || theDataView_[row][col] ==
"yes" || theDataView_[row][col] ==
"Yes" || theDataView_[row][col] ==
"YES")
535 return ViewColumnInfo::TYPE_VALUE_YES;
537 return ViewColumnInfo::TYPE_VALUE_NO;
540 return convertEnvironmentVariables?convertEnvVariables(theDataView_[row][col]):
541 theDataView_[row][col];
551 std::string ConfigurationView::getEscapedValueAsString(
unsigned int row,
unsigned int col,
552 bool convertEnvironmentVariables)
const
554 std::string val = getValueAsString(row,col,convertEnvironmentVariables);
555 std::string retVal =
"";
556 retVal.reserve(val.size());
557 for(
unsigned int i=0;i<val.size();++i)
561 else if(val[i] ==
'\t')
563 else if(val[i] ==
'\r')
578 std::string ConfigurationView::convertEnvVariables(
const std::string& data)
const
580 std::string converted = data;
581 if(data.find(
"${") != std::string::npos)
583 unsigned int begin = data.find(
"${");
584 unsigned int end = data.find(
"}");
585 std::string envVariable = data.substr(begin+2, end-begin-2);
587 if(getenv(envVariable.c_str()) !=
nullptr)
589 return convertEnvVariables(converted.replace(begin,end-begin+1,getenv(envVariable.c_str())));
592 throw std::runtime_error(
"In configuration " + tableName_ +
" the environmental variable: " + envVariable +
" is not set! Please make sure you set it before continuing!");
600 void ConfigurationView::setValue(
const std::string &value,
unsigned int row,
unsigned int col)
602 if(!(col < columnsInfo_.size() && row < getNumberOfRows()))
604 __SS__ <<
"Invalid row (" << row <<
") col (" << col <<
") requested!" << std::endl;
605 throw std::runtime_error(ss.str());
608 if(columnsInfo_[col].getDataType() == ViewColumnInfo::DATATYPE_STRING)
609 theDataView_[row][col] = value;
613 __SS__ <<
"\tUnrecognized column data type: " << columnsInfo_[col].getDataType()
614 <<
" in configuration " << tableName_
615 <<
" at column=" << columnsInfo_[col].getName()
616 <<
" for setValue with type '" << ots_demangle(
typeid(value).name())
618 throw std::runtime_error(ss.str());
621 void ConfigurationView::setValue(
const char *value,
unsigned int row,
unsigned int col)
622 { setValue(std::string(value),row,col); }
627 void ConfigurationView::setValueAsString(
const std::string &value,
unsigned int row,
unsigned int col)
629 if(!(col < columnsInfo_.size() && row < getNumberOfRows()))
631 __SS__ <<
"Invalid row (" << row <<
") col (" << col <<
") requested!" << std::endl;
632 throw std::runtime_error(ss.str());
635 theDataView_[row][col] = value;
641 const unsigned int ConfigurationView::getOrInitColUID (
void)
643 if(colUID_ != INVALID)
return colUID_;
646 colUID_ = findColByType(ViewColumnInfo::TYPE_UID);
647 if(colUID_ == INVALID)
649 __MOUT__ <<
"Column Types: " << std::endl;
650 for(
unsigned int col=0; col<columnsInfo_.size(); ++col)
651 std::cout << columnsInfo_[col].getType() <<
"() " << columnsInfo_[col].getName() << std::endl;
652 __SS__ <<
"\tMissing UID Column in table named '" << tableName_ <<
"'" << std::endl;
653 __MOUT_ERR__ <<
"\n" << ss.str() << std::endl;
654 throw std::runtime_error(ss.str());
662 const unsigned int ConfigurationView::getColUID (
void)
const
664 if(colUID_ != INVALID)
return colUID_;
666 __MOUT__ <<
"Column Types: " << std::endl;
667 for(
unsigned int col=0; col<columnsInfo_.size(); ++col)
668 std::cout << columnsInfo_[col].getType() <<
"() " << columnsInfo_[col].getName() << std::endl;
670 __SS__ << (
"Missing UID Column in config named " + tableName_ +
671 ". (Possibly ConfigurationView was just not initialized?" +
672 "This is the const call so can not alter class members)") << std::endl;
673 __MOUT_ERR__ <<
"\n" << ss.str() << std::endl;
674 throw std::runtime_error(ss.str());
680 void ConfigurationView::addRowToGroup(
const unsigned int &row,
681 const unsigned int &col,
682 const std::string &groupID,
683 const std::string &colDefault)
685 if(isEntryInGroupCol(row,col,groupID))
687 __SS__ <<
"GroupID (" << groupID <<
688 ") added to row (" << row
689 <<
" is already present!" << std::endl;
690 throw std::runtime_error(ss.str());
698 if(getDataView()[row][col] ==
"" ||
699 getDataView()[row][col] == colDefault)
705 groupID +
" | " + getDataView()[row][col],
714 void ConfigurationView::removeRowFromGroup(
const unsigned int &row,
715 const unsigned int &col,
716 const std::string &groupNeedle)
718 __MOUT__ <<
"groupNeedle " << groupNeedle << std::endl;
719 std::set<std::string> groupIDList;
720 if(!isEntryInGroupCol(row,col,groupNeedle,&groupIDList))
722 __SS__ <<
"GroupID (" << groupNeedle <<
723 ") removed from row (" << row
724 <<
") was already removed!" << std::endl;
725 throw std::runtime_error(ss.str());
732 std::string newValue =
"";
733 unsigned int cnt = 0;
734 for(
const auto & groupID : groupIDList)
737 if(groupID == groupNeedle)
continue;
739 if(cnt) newValue +=
" | ";
742 setValue(newValue,row,col);
753 bool ConfigurationView::isEntryInGroup(
const unsigned int &r,
754 const std::string &childLinkIndex,
755 const std::string &groupNeedle)
const
757 unsigned int c = getColLinkGroupID(childLinkIndex);
759 return isEntryInGroupCol(r,c,groupNeedle);
772 bool ConfigurationView::isEntryInGroupCol(
const unsigned int &r,
773 const unsigned int &c,
const std::string &groupNeedle,
774 std::set<std::string> *groupIDList)
const
783 for(;j<theDataView_[r][c].size();++j)
784 if((theDataView_[r][c][j] ==
' ' ||
785 theDataView_[r][c][j] ==
'|')
788 else if((theDataView_[r][c][j] ==
' ' ||
789 theDataView_[r][c][j] ==
'|')
792 if(groupIDList) groupIDList->emplace(theDataView_[r][c].substr(i,j-i));
796 if(groupNeedle == theDataView_[r][c].substr(i,j-i))
808 if(groupIDList) groupIDList->emplace(theDataView_[r][c].substr(i,j-i));
812 if(groupNeedle == theDataView_[r][c].substr(i,j-i))
827 std::set<std::string> ConfigurationView::getSetOfGroupIDs(
const std::string &childLinkIndex,
828 unsigned int r)
const
830 unsigned int c = getColLinkGroupID(childLinkIndex);
834 std::set<std::string> retSet;
839 if(r != (
unsigned int)-1)
841 if(r >= getNumberOfRows())
843 __SS__ <<
"Invalid row requested!" << std::endl;
844 throw std::runtime_error(ss.str());
849 for(;j<theDataView_[r][c].size();++j)
850 if((theDataView_[r][c][j] ==
' ' ||
851 theDataView_[r][c][j] ==
'|')
854 else if((theDataView_[r][c][j] ==
' ' ||
855 theDataView_[r][c][j] ==
'|')
862 retSet.emplace(theDataView_[r][c].substr(i,j-i));
869 retSet.emplace(theDataView_[r][c].substr(i,j-i));
874 for(r=0;r<getNumberOfRows();++r)
883 for(;j<theDataView_[r][c].size();++j)
887 if((theDataView_[r][c][j] ==
' ' ||
888 theDataView_[r][c][j] ==
'|')
891 else if((theDataView_[r][c][j] ==
' ' ||
892 theDataView_[r][c][j] ==
'|')
898 retSet.emplace(theDataView_[r][c].substr(i,j-i));
909 retSet.emplace(theDataView_[r][c].substr(i,j-i));
920 const unsigned int ConfigurationView::getColLinkGroupID(
const std::string &childLinkIndex)
const
922 std::map<std::string, unsigned int>::const_iterator it = colLinkGroupIDs_.find(childLinkIndex);
924 colLinkGroupIDs_.end())
927 __MOUT__ <<
"Existing Column Types: " << std::endl;
928 for(
unsigned int col=0; col<columnsInfo_.size(); ++col)
929 std::cout << columnsInfo_[col].getType() <<
"() " << columnsInfo_[col].getName() << std::endl;
931 __SS__ << (
"Missing column with data type " +
932 (ViewColumnInfo::TYPE_START_GROUP_ID +
"-" + childLinkIndex) +
933 " in config named " + tableName_) << std::endl;
934 __MOUT_ERR__ <<
"\n" << ss.str();
935 throw std::runtime_error(ss.str());
939 unsigned int ConfigurationView::findRow(
unsigned int col,
const std::string& value,
unsigned int offsetRow)
const
941 for(
unsigned int row=offsetRow; row<theDataView_.size(); ++row)
943 if(theDataView_[row][col] == value)
947 __SS__ <<
"\tIn view: " << tableName_
948 <<
", Can't find value=" << value
949 <<
" in column named " << columnsInfo_[col].getName()
950 <<
" with type=" << columnsInfo_[col].getType()
955 throw std::runtime_error(ss.str());
959 unsigned int ConfigurationView::findRowInGroup(
unsigned int col,
const std::string& value,
960 const std::string &groupId,
const std::string &childLinkIndex,
unsigned int offsetRow)
const
962 unsigned int groupIdCol = getColLinkGroupID(childLinkIndex);
963 for(
unsigned int row=offsetRow; row<theDataView_.size(); ++row)
965 if(theDataView_[row][col] == value &&
966 isEntryInGroupCol(row,groupIdCol,groupId))
970 __SS__ <<
"\tIn view: " << tableName_ <<
", Can't find in group the value=" <<
971 value <<
" in column named " <<
972 columnsInfo_[col].getName() <<
" with type=" <<
973 columnsInfo_[col].getType() <<
" and GroupID: " <<
974 groupId <<
" in column " << groupIdCol <<
975 " with GroupID child link index " << childLinkIndex << std::endl;
976 __MOUT__ << ss.str();
977 throw std::runtime_error(ss.str());
983 unsigned int ConfigurationView::findCol(
const std::string& name)
const
985 for(
unsigned int col=0; col<columnsInfo_.size(); ++col)
986 if(columnsInfo_[col].getName() == name)
989 __SS__ <<
"\tIn view: " << tableName_ <<
990 ", Can't find column named " << name << std::endl;
991 throw std::runtime_error(ss.str());
997 unsigned int ConfigurationView::findColByType(
const std::string& type,
int startingCol)
const
999 for(
unsigned int col=startingCol; col<columnsInfo_.size(); ++col)
1000 if(columnsInfo_[col].getType() == type)
1008 const std::string& ConfigurationView::getUniqueStorageIdentifier(
void)
const
1010 return uniqueStorageIdentifier_;
1014 const std::string& ConfigurationView::getTableName(
void)
const
1026 const std::string& ConfigurationView::getComment(
void)
const
1032 const std::string& ConfigurationView::getAuthor(
void)
const
1038 const time_t& ConfigurationView::getCreationTime(
void)
const
1040 return creationTime_;
1044 const time_t& ConfigurationView::getLastAccessTime(
void)
const
1046 return lastAccessTime_;
1050 const bool& ConfigurationView::getLooseColumnMatching(
void)
const
1052 return fillWithLooseColumnMatching_;
1056 const unsigned int ConfigurationView::getSourceColumnSize(
void)
const
1060 if(!getNumberOfRows())
return getNumberOfColumns();
1061 return sourceColumnNames_.size();
1065 const unsigned int& ConfigurationView::getSourceColumnMismatch(
void)
const
1067 return sourceColumnMismatchCount_;
1071 const unsigned int& ConfigurationView::getSourceColumnMissing(
void)
const
1073 return sourceColumnMissingCount_;
1077 const std::set<std::string>& ConfigurationView::getSourceColumnNames(
void)
const
1080 return sourceColumnNames_;
1084 std::set<std::string> ConfigurationView::getColumnNames(
void)
const
1086 std::set<std::string> retSet;
1087 for(
auto &colInfo: columnsInfo_)
1088 retSet.emplace(colInfo.getName());
1093 std::set<std::string> ConfigurationView::getColumnStorageNames(
void)
const
1095 std::set<std::string> retSet;
1096 for(
auto &colInfo: columnsInfo_)
1097 retSet.emplace(colInfo.getStorageName());
1102 std::vector<std::string> ConfigurationView::getDefaultRowValues(
void)
const
1104 std::vector<std::string> retVec;
1107 for(
unsigned int col=0;col<getNumberOfColumns();++col)
1108 retVec.push_back(columnsInfo_[col].getDefaultValue());
1114 unsigned int ConfigurationView::getNumberOfRows(
void)
const
1116 return theDataView_.size();
1120 unsigned int ConfigurationView::getNumberOfColumns(
void)
const
1122 return columnsInfo_.size();
1126 const ConfigurationView::DataView& ConfigurationView::getDataView(
void)
const
1128 return theDataView_;
1138 const std::vector<ViewColumnInfo>& ConfigurationView::getColumnsInfo (
void)
const
1140 return columnsInfo_;
1144 std::vector<ViewColumnInfo>* ConfigurationView::getColumnsInfoP(
void)
1146 return &columnsInfo_;
1149 const ViewColumnInfo& ConfigurationView::getColumnInfo(
unsigned int column)
const
1151 if(column >= columnsInfo_.size())
1153 std::stringstream errMsg;
1154 errMsg << __COUT_HDR_FL__ <<
"\nCan't find column " << column <<
1155 "\n\n\n\nThe column info is likely missing due to incomplete Configuration View filling.\n\n"
1157 throw std::runtime_error(errMsg.str().c_str());
1159 return columnsInfo_[column];
1164 void ConfigurationView::setUniqueStorageIdentifier(
const std::string &storageUID)
1166 uniqueStorageIdentifier_ = storageUID;
1170 void ConfigurationView::setTableName(
const std::string &name)
1176 void ConfigurationView::setComment(
const std::string &comment)
1182 void ConfigurationView::setURIEncodedComment(
const std::string &uriComment)
1184 comment_ = decodeURIComponent(uriComment);
1188 void ConfigurationView::setAuthor(
const std::string &author)
1194 void ConfigurationView::setCreationTime(time_t t)
1200 void ConfigurationView::setLastAccessTime(time_t t)
1202 lastAccessTime_ = t;
1206 void ConfigurationView::setLooseColumnMatching(
bool setValue)
1208 fillWithLooseColumnMatching_ = setValue;
1212 void ConfigurationView::reset (
void)
1217 columnsInfo_.clear();
1218 theDataView_.clear();
1222 void ConfigurationView::print (std::ostream &out)
const
1224 out <<
"==============================================================================" << std::endl;
1225 out <<
"Print: " << tableName_ <<
" Version: " << version_ <<
" Comment: " << comment_ <<
1226 " Author: " << author_ <<
" Creation Time: " << ctime(&creationTime_) << std::endl;
1227 out <<
"\t\tNumber of Cols " << getNumberOfColumns() << std::endl;
1228 out <<
"\t\tNumber of Rows " << getNumberOfRows() << std::endl;
1230 out <<
"Columns:\t";
1231 for(
int i=0;i<(int)columnsInfo_.size();++i)
1232 out << i <<
":" << columnsInfo_[i].getName() <<
":" << columnsInfo_[i].getStorageName() <<
":" << columnsInfo_[i].getDataType() <<
"\t ";
1235 out <<
"Rows:" << std::endl;
1238 for(
int r=0;r<(int)getNumberOfRows();++r)
1241 for(
int c=0;c<(int)getNumberOfColumns();++c)
1244 out << theDataView_[r][c];
1265 void ConfigurationView::printJSON (std::ostream &out)
const
1268 out <<
"\"NAME\" : \"" << tableName_ <<
"\",\n";
1272 out <<
"\"COMMENT\" : ";
1278 for(
unsigned int i=0;i<val.size();++i)
1283 else if(val[i] ==
'\t')
1285 else if(val[i] ==
'\r')
1298 out <<
"\"AUTHOR\" : \"" << author_ <<
"\",\n";
1299 out <<
"\"CREATION_TIME\" : " << creationTime_ <<
",\n";
1306 out <<
"\"COL_TYPES\" : {\n";
1307 for(
int c=0;c<(int)getNumberOfColumns();++c)
1309 out <<
"\t\t\"" << columnsInfo_[c].getStorageName() <<
"\" : ";
1310 out <<
"\"" << columnsInfo_[c].getDataType() <<
"\"";
1311 if(c+1 < (
int)getNumberOfColumns())
1317 out <<
"\"DATA_SET\" : [\n";
1319 for(
int r=0;r<(int)getNumberOfRows();++r)
1322 for(
int c=0;c<(int)getNumberOfColumns();++c)
1324 out <<
"\t\t\"" << columnsInfo_[c].getStorageName() <<
"\" : ";
1326 out <<
"\"" << getEscapedValueAsString(r,c,
false) <<
"\"";
1328 if(c+1 < (
int)getNumberOfColumns())
1333 if(r+1 < (
int)getNumberOfRows())
1345 std::string restoreJSONStringEntities(
const std::string &str)
1347 unsigned int sz = str.size();
1350 std::stringstream retStr;
1358 retStr <<
'\n'; ++i;
break;
1360 retStr <<
'"'; ++i;
break;
1362 retStr <<
'\t'; ++i;
break;
1364 retStr <<
'\r'; ++i;
break;
1366 retStr <<
'\\'; ++i;
break;
1374 retStr << str[sz-1];
1376 return retStr.str();
1388 int ConfigurationView::fillFromJSON(
const std::string &json)
1390 std::vector<std::string> keys;
1391 keys.push_back (
"NAME");
1392 keys.push_back (
"COMMENT");
1393 keys.push_back (
"AUTHOR");
1394 keys.push_back (
"CREATION_TIME");
1396 keys.push_back (
"DATA_SET");
1399 CV_JSON_FILL_COMMENT,
1400 CV_JSON_FILL_AUTHOR,
1401 CV_JSON_FILL_CREATION_TIME,
1403 CV_JSON_FILL_DATA_SET
1408 sourceColumnMismatchCount_ = 0;
1409 sourceColumnMissingCount_ = 0;
1410 sourceColumnNames_.clear();
1411 unsigned int colFoundCount = 0;
1413 unsigned int row = -1;
1414 unsigned int colSpeedup = 0;
1415 unsigned int startString, startNumber, endNumber = -1;
1416 unsigned int bracketCount = 0;
1417 unsigned int sqBracketCount = 0;
1421 bool isDataArray = 0;
1422 bool keyIsMatch, keyIsComment;
1423 unsigned int keyIsMatchIndex, keyIsMatchStorageIndex, keyIsMatchCommentIndex;
1424 const std::string COMMENT_ALT_KEY =
"COMMENT";
1426 std::string extractedString =
"", currKey =
"", currVal =
"";
1427 unsigned int currDepth;
1429 std::vector<std::string> jsonPath;
1430 std::vector<char> jsonPathType;
1431 char lastPopType =
'_';
1433 unsigned int matchedKey = -1;
1434 unsigned int lastCol = -1;
1438 for(;i<json.size();++i)
1443 if(i-1 < json.size() &&
1444 json[i-1] ==
'\\')
break;
1446 inQuotes = !inQuotes;
1451 extractedString = restoreJSONStringEntities(
1452 json.substr(startString+1,i-startString-1));
1460 if(jsonPathType[jsonPathType.size()-1] !=
'{'
1463 __MOUT__ <<
"Invalid ':' position" << std::endl;
1468 jsonPathType.push_back(
'K');
1469 jsonPath.push_back(extractedString);
1487 if(lastPopType ==
'{')
1490 if(jsonPathType[jsonPathType.size()-1] ==
'K')
1493 jsonPath.pop_back();
1494 jsonPathType.pop_back();
1500 currVal = extractedString;
1503 if(endNumber == (
unsigned int)-1 ||
1504 endNumber <= startNumber)
1507 if(endNumber <= startNumber)
1510 currVal = json.substr(startNumber+1,endNumber-startNumber-1);
1513 currDepth = bracketCount;
1515 if(jsonPathType[jsonPathType.size()-1] ==
'K')
1517 currKey = jsonPath[jsonPathType.size()-1];
1522 jsonPath.pop_back();
1523 jsonPathType.pop_back();
1525 else if(jsonPathType[jsonPathType.size()-1] ==
'[')
1528 for(
unsigned int k=jsonPathType.size()-2; k<jsonPathType.size(); --k)
1529 if(jsonPathType[k] ==
'K')
1531 currKey = jsonPath[k];
1536 __MOUT__ <<
"Invalid array position" << std::endl;
1545 __MOUT__ <<
"Invalid ',' position" << std::endl;
1555 jsonPathType.push_back(
'{');
1556 jsonPath.push_back(
"{");
1568 if(lastPopType !=
'{' &&
1569 jsonPathType[jsonPathType.size()-1] ==
'K')
1571 currDepth = bracketCount;
1572 currKey = jsonPath[jsonPathType.size()-1];
1574 currVal = extractedString;
1577 if(endNumber == (
unsigned int)-1 ||
1578 endNumber <= startNumber)
1581 if(endNumber <= startNumber)
1584 currVal = json.substr(startNumber+1,endNumber-startNumber-1);
1588 jsonPath.pop_back();
1589 jsonPathType.pop_back();
1592 if(jsonPathType[jsonPathType.size()-1] !=
'{')
1594 __MOUT__ <<
"Invalid '}' position" << std::endl;
1598 jsonPath.pop_back();
1599 jsonPathType.pop_back();
1604 jsonPathType.push_back(
'[');
1605 jsonPath.push_back(
"[");
1613 if(jsonPathType[jsonPathType.size()-1] !=
'[')
1615 __MOUT__ <<
"Invalid ']' position" << std::endl;
1619 currDepth = bracketCount;
1623 currVal = extractedString;
1626 if(endNumber == (
unsigned int)-1 ||
1627 endNumber <= startNumber)
1630 if(endNumber <= startNumber)
1633 currVal = json.substr(startNumber+1,endNumber-startNumber-1);
1638 for(
unsigned int k=jsonPathType.size()-2; k<jsonPathType.size(); --k)
1639 if(jsonPathType[k] ==
'K')
1641 currKey = jsonPath[k];
1646 __MOUT__ <<
"Invalid array position" << std::endl;
1651 if(jsonPathType[jsonPathType.size()-1] !=
'[')
1653 __MOUT__ <<
"Invalid ']' position" << std::endl;
1657 jsonPath.pop_back();
1658 jsonPathType.pop_back();
1666 if(startNumber != (
unsigned int)-1 &&
1667 endNumber == (
unsigned int)-1)
1676 std::cout << i <<
":\t" << json[i] <<
" - ";
1678 std::cout <<
"ExtKey=";
1679 for(
unsigned int k=0;k<jsonPath.size();++k)
1680 std::cout << jsonPath[k] <<
"/";
1682 std::cout << lastPopType <<
" ";
1683 std::cout << bracketCount <<
" ";
1684 std::cout << sqBracketCount <<
" ";
1685 std::cout << inQuotes <<
" ";
1686 std::cout << newValue <<
"-";
1687 std::cout << currKey <<
"-{" << currDepth <<
"}:" ;
1688 std::cout << currVal <<
" ";
1689 std::cout << startNumber <<
"-";
1690 std::cout << endNumber <<
" ";
1722 for(
unsigned int k=0;k<keys.size();++k)
1723 if((currDepth == 1 && keys[k] == currKey) ||
1724 (currDepth > 1 && keys[k] == jsonPath[1]))
1727 if(matchedKey != (
unsigned int)-1)
1734 case CV_JSON_FILL_NAME:
1735 if(currDepth == 1) setTableName(currVal);
1737 case CV_JSON_FILL_COMMENT:
1738 if(currDepth == 1) setComment(currVal);
1740 case CV_JSON_FILL_AUTHOR:
1741 if(currDepth == 1) setAuthor(currVal);
1743 case CV_JSON_FILL_CREATION_TIME:
1744 if(currDepth == 1) setCreationTime(strtol(currVal.c_str(),0,10));
1749 case CV_JSON_FILL_DATA_SET:
1758 unsigned int col, ccnt = 0;
1759 unsigned int noc = getNumberOfColumns();
1760 for(;ccnt<noc;++ccnt)
1766 if(fillWithLooseColumnMatching_)
1778 if(getNumberOfRows() == 1)
1779 sourceColumnNames_.emplace(currKey);
1783 if(row >= getNumberOfRows())
1785 __SS__ <<
"Invalid row" << std::endl;
1786 std::cout << ss.str();
1787 throw std::runtime_error(ss.str());
1791 theDataView_[row][col] = currVal;
1796 col = (ccnt + colSpeedup) % noc;
1802 keyIsComment =
true;
1803 for(keyIsMatchIndex=0, keyIsMatchStorageIndex=0, keyIsMatchCommentIndex=0;
1804 keyIsMatchIndex<currKey.size();++keyIsMatchIndex)
1806 if(columnsInfo_[col].getStorageName()[keyIsMatchStorageIndex] ==
'_')
1807 ++keyIsMatchStorageIndex;
1808 if(currKey[keyIsMatchIndex] ==
'_')
1812 if(keyIsMatchStorageIndex >= columnsInfo_[col].getStorageName().size() ||
1813 currKey[keyIsMatchIndex] !=
1814 columnsInfo_[col].getStorageName()[keyIsMatchStorageIndex])
1823 if(keyIsComment && keyIsMatchCommentIndex < COMMENT_ALT_KEY.size())
1825 if(currKey[keyIsMatchIndex] != COMMENT_ALT_KEY[keyIsMatchCommentIndex])
1828 keyIsComment =
false;
1832 ++keyIsMatchStorageIndex;
1835 if(keyIsMatch || keyIsComment)
1840 if(getNumberOfRows())
1841 sourceColumnMissingCount_ += getNumberOfColumns() - colFoundCount;
1849 if(getNumberOfRows() == 1)
1850 sourceColumnNames_.emplace(currKey);
1854 if(row >= getNumberOfRows())
1856 __SS__ <<
"Invalid row" << std::endl;
1857 __MOUT__ <<
"\n" << ss.str();
1858 throw std::runtime_error(ss.str());
1862 theDataView_[row][col] = currVal;
1868 colSpeedup = (colSpeedup + 1) % noc;
1870 if(ccnt >= getNumberOfColumns())
1872 __SS__ <<
"\n\nInvalid column in JSON source data: " <<
1873 currKey <<
" not found in column names of table named " <<
1874 getTableName() <<
"." <<
1876 __MOUT__ <<
"\n" << ss.str();
1879 ++sourceColumnMismatchCount_;
1880 if(getNumberOfRows() == 1)
1881 sourceColumnNames_.emplace(currKey);
1915 bool ConfigurationView::isURIEncodedCommentTheSame(
const std::string &comment)
const
1917 std::string compareStr = decodeURIComponent(comment);
1918 return comment_ == compareStr;
1973 int ConfigurationView::fillFromCSV(
const std::string &data,
const int &dataOffset,
1974 const std::string &author)
1975 throw(std::runtime_error)
1981 int j = data.find(
',',i);
1982 int k = data.find(
';',i);
1984 bool rowWasModified;
1985 unsigned int countRowsModified = 0;
1986 int authorCol = findColByType(ViewColumnInfo::TYPE_AUTHOR);
1987 int timestampCol = findColByType(ViewColumnInfo::TYPE_TIMESTAMP);
1990 while(k != (
int)(std::string::npos))
1992 rowWasModified =
false;
1993 if(r >= (
int)getNumberOfRows())
1997 rowWasModified =
true;
2000 while(j < k && j != (
int)(std::string::npos))
2005 if(c >= (
int)getNumberOfColumns()-2)
2008 j = data.find(
',',i);
2013 if(setURIEncodedValue(data.substr(i,j-i),r,c))
2014 rowWasModified =
true;
2017 j = data.find(
',',i);
2022 if(author !=
"" && rowWasModified)
2024 __MOUT__ <<
"Row=" << r <<
" was modified!" << std::endl;
2025 setValue(author,r,authorCol);
2026 setValue(time(0),r,timestampCol);
2029 if(rowWasModified) ++countRowsModified;
2036 j = data.find(
',',i);
2037 k = data.find(
';',i);
2041 while(r < (
int)getNumberOfRows())
2044 __MOUT__ <<
"Row deleted: " << r << std::endl;
2045 ++countRowsModified;
2048 __MOUT_INFO__ <<
"countRowsModified=" <<
2049 countRowsModified << std::endl;
2051 if(!countRowsModified)
2053 __SS__ <<
"No rows were modified! No reason to fill a view with same content." << std::endl;
2054 __MOUT__ << ss.str();
2061 sourceColumnNames_.clear();
2062 for(
unsigned int i=0;i<getNumberOfColumns();++i)
2063 sourceColumnNames_.emplace(getColumnsInfo()[i].getStorageName());
2079 bool ConfigurationView::setURIEncodedValue(
const std::string &value,
const unsigned int &r,
const unsigned int &c)
2081 if(!(c < columnsInfo_.size() && r < getNumberOfRows()))
2083 __SS__ <<
"Invalid row (" << r <<
") col (" << c <<
") requested!" << std::endl;
2084 throw std::runtime_error(ss.str());
2087 std::string valueStr = decodeURIComponent(value);
2088 std::string originalValueStr = getValueAsString(r,c,
false);
2092 if(columnsInfo_[c].getDataType() == ViewColumnInfo::DATATYPE_NUMBER)
2095 std::string convertedString = convertEnvVariables(valueStr);
2096 if(!isNumber(convertedString))
2098 __SS__ <<
"\tIn configuration " << tableName_
2099 <<
" at column=" << columnsInfo_[c].getName()
2100 <<
" the value set (" << convertedString <<
")"
2101 <<
" is not a number! Please fix it or change the column type..." << std::endl;
2102 throw std::runtime_error(ss.str());
2104 theDataView_[r][c] = valueStr;
2106 else if(columnsInfo_[c].getDataType() == ViewColumnInfo::DATATYPE_TIME)
2118 setValue(time_t(strtol(valueStr.c_str(),0,10)),
2122 theDataView_[r][c] = valueStr;
2125 return(originalValueStr != getValueAsString(r,c,
false));
2131 std::string ConfigurationView::decodeURIComponent(
const std::string &data)
2133 std::string decodeURIString(data.size(),0);
2135 for(
unsigned int i=0;i<data.size();++i,++j)
2141 decodeURIString[j] += (data[i+1]-55)*16;
2143 decodeURIString[j] += (data[i+1]-48)*16;
2147 decodeURIString[j] += (data[i+2]-55);
2149 decodeURIString[j] += (data[i+2]-48);
2154 decodeURIString[j] = data[i];
2156 decodeURIString.resize(j);
2157 return decodeURIString;
2161 void ConfigurationView::resizeDataView(
unsigned int nRows,
unsigned int nCols)
2164 theDataView_.resize(nRows, std::vector<std::string>(nCols));
2171 int ConfigurationView::addRow (
void)
2173 int row = getNumberOfRows();
2174 theDataView_.resize(getNumberOfRows()+1,std::vector<std::string>(getNumberOfColumns()));
2176 std::vector<std::string> defaultRowValues =
2177 getDefaultRowValues();
2180 for(
unsigned int col=0;col<getNumberOfColumns();++col)
2181 theDataView_[row][col] = defaultRowValues[col];
2189 void ConfigurationView::deleteRow(
int r)
2191 if(r >= (
int)getNumberOfRows())
2194 __SS__ <<
"Row " << r <<
" is out of bounds (Row Count = " <<
2195 getNumberOfRows() <<
") and can not be deleted." <<
2197 throw std::runtime_error(ss.str());
2200 theDataView_.erase(theDataView_.begin()+r);
2217 const bool ConfigurationView::getChildLink(
const unsigned int &c,
bool *isGroup,
2218 std::pair<unsigned int /*link col*/, unsigned int /*link id col*/> *linkPair)
const
2224 if((*isGroup = columnsInfo_[c].isChildLinkGroupID()) ||
2225 columnsInfo_[c].isChildLinkUID())
2229 linkPair->second = c;
2230 std::string index = columnsInfo_[c].getChildLinkIndex();
2235 for(
unsigned int col=0; col<columnsInfo_.size(); ++col)
2238 if(col == c)
continue;
2239 else if(columnsInfo_[col].isChildLink() &&
2240 index == columnsInfo_[col].getChildLinkIndex())
2243 __MOUT__ <<
"getChildLink Found match for col: " << c <<
" at " << col << std::endl;
2244 linkPair->first = col;
2250 __SS__ <<
"\tIn view: " << tableName_ <<
2251 ", Can't find complete child link for column name " << columnsInfo_[c].getName() << std::endl;
2252 throw std::runtime_error(ss.str());
2255 if(!columnsInfo_[c].isChildLink())
2259 linkPair->first = c;
2260 std::string index = columnsInfo_[c].getChildLinkIndex();
2265 for(
unsigned int col=0; col<columnsInfo_.size(); ++col)
2268 if(col == c)
continue;
2280 if(((columnsInfo_[col].isChildLinkUID() && !(*isGroup =
false)) ||
2281 (columnsInfo_[col].isChildLinkGroupID() && (*isGroup =
true)))
2282 && index == columnsInfo_[col].getChildLinkIndex())
2286 linkPair->second = col;
2292 __SS__ <<
"\tIn view: " << tableName_ <<
2293 ", Can't find complete child link id for column name " << columnsInfo_[c].getName() << std::endl;
2294 throw std::runtime_error(ss.str());
2300 bool ConfigurationView::isNumber(
const std::string& s)
const
2303 if(s.find(
"0x") == 0)
2306 for(
unsigned int i=2;i<s.size();++i)
2308 if(!((s[i] >=
'0' && s[i] <=
'9') ||
2309 (s[i] >=
'A' && s[i] <=
'F') ||
2310 (s[i] >=
'a' && s[i] <=
'f')
2319 else if(s[0] ==
'b')
2323 for(
unsigned int i=1;i<s.size();++i)
2325 if(!((s[i] >=
'0' && s[i] <=
'1')
2336 for(
unsigned int i=0;i<s.size();++i)
2337 if(!((s[i] >=
'0' && s[i] <=
'9') ||
2357 std::string ots_demangle(
const char* name) {
2362 std::unique_ptr<char, void(*)(void*)> res {
2363 abi::__cxa_demangle(name, NULL, NULL, &status),
2367 return (status==0) ? res.get() : name ;
2373 std::string ots_demangle(
const char* name) {