1 #include "otsdaq/TableCore/TableView.h"
2 #include "otsdaq/TableCore/TableBase.h"
12 #define __MF_SUBJECT__ "TableView"
14 #define __COUT_HDR__ (tableName_ + "v" + version_.toString() + "\t<> ")
16 const unsigned int TableView::INVALID = -1;
20 : storageData_(tableName)
21 , tableName_(
TableBase::convertToCaps(storageData_))
25 , creationTime_(time(0))
29 , colPriority_(INVALID)
30 , fillWithLooseColumnMatching_(false)
31 , getSourceRawData_(false)
32 , sourceColumnMismatchCount_(0)
33 , sourceColumnMissingCount_(0)
39 __SS__ <<
"Do not allow anonymous table view construction!" << __E__;
47 TableView::~TableView(
void) {}
55 __SS__ <<
"Invalid use of operator=... Should not directly copy a TableView. Please "
56 "use TableView::copy(sourceView,author,comment)";
59 __COUT__ << ss.str() << __E__;
67 const std::string& author)
70 version_ = destinationVersion;
71 comment_ = src.comment_;
74 lastAccessTime_ = time(0);
79 for(
auto& c : src.columnsInfo_)
80 columnsInfo_.push_back(c);
82 theDataView_ = src.theDataView_;
83 sourceColumnNames_ = src.sourceColumnNames_;
89 std::string tmpCachePrepend = TableBase::GROUP_CACHE_PREPEND;
91 std::string tmpJsonDocPrepend = TableBase::JSON_DOC_PREPEND;
95 if(tableName_.substr(0, tmpCachePrepend.length()) == tmpCachePrepend ||
96 tableName_.substr(0, tmpJsonDocPrepend.length()) == tmpJsonDocPrepend)
98 __COUTT__ <<
"TableView copy for '" << tableName_ <<
"' done." << __E__;
127 unsigned int srcOffsetRow ,
128 unsigned int srcRowsToCopy ,
129 unsigned int destOffsetRow ,
130 unsigned char generateUniqueDataColumns ,
131 const std::string& baseNameAutoUID )
137 unsigned int retRow = (
unsigned int)-1;
140 if(src.getNumberOfColumns() != getNumberOfColumns())
142 __SS__ <<
"Error! Number of Columns of source view must match destination view."
143 <<
"Dimension of source is [" << src.getNumberOfColumns()
144 <<
"] and of destination is [" << getNumberOfColumns() <<
"]." << __E__;
148 unsigned int srcRows = src.getNumberOfRows();
150 for(
unsigned int r = 0; r < srcRowsToCopy; ++r)
152 if(r + srcOffsetRow >= srcRows)
155 destOffsetRow =
addRow(author,
156 generateUniqueDataColumns ,
160 if(retRow == (
unsigned int)-1)
161 retRow = destOffsetRow;
164 for(
unsigned int col = 0; col < getNumberOfColumns(); ++col)
165 if(generateUniqueDataColumns &&
167 columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_UNIQUE_DATA ||
168 columnsInfo_[col].getType() ==
169 TableViewColumnInfo::TYPE_UNIQUE_GROUP_DATA))
172 theDataView_[destOffsetRow][col] =
173 src.theDataView_[r + srcOffsetRow][col];
197 std::set<std::string> colNameSet;
198 std::string capsColName, colName;
199 for(
auto& colInfo : columnsInfo_)
201 colName = colInfo.getStorageName();
202 if(colName ==
"COMMENT_DESCRIPTION")
205 for(
unsigned int i = 0; i < colName.size(); ++i)
207 if(colName[i] ==
'_')
209 capsColName += colName[i];
212 colNameSet.emplace(capsColName);
215 if(colNameSet.size() != columnsInfo_.size())
217 __SS__ <<
"Table Error:\t"
218 <<
" Columns names must be unique! There are " << columnsInfo_.size()
219 <<
" columns and the unique name count is " << colNameSet.size()
241 if(sourceColumnNames_.size() == 0)
242 for(
unsigned int i = 0; i < getNumberOfColumns(); ++i)
243 sourceColumnNames_.emplace(getColumnsInfo()[i].getStorageName());
247 if((colPos =
findColByType(TableViewColumnInfo::TYPE_COMMENT)) != INVALID)
249 if(columnsInfo_[colPos].getName() != TableViewColumnInfo::COL_NAME_COMMENT)
251 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_COMMENT
252 <<
" data type column must have name="
253 << TableViewColumnInfo::COL_NAME_COMMENT << __E__;
257 if(
findColByType(TableViewColumnInfo::TYPE_COMMENT, colPos + 1) !=
260 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_COMMENT
261 <<
" data type in column " << columnsInfo_[colPos].getName()
262 <<
" is repeated. This is not allowed." << __E__;
266 if(colPos != getNumberOfColumns() - 3)
268 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_COMMENT
269 <<
" data type column must be 3rd to last (in column "
270 << getNumberOfColumns() - 3 <<
")." << __E__;
276 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_COMMENT
277 <<
" data type column "
278 <<
" is missing. This is not allowed." << __E__;
283 if((colPos =
findColByType(TableViewColumnInfo::TYPE_AUTHOR)) != INVALID)
285 if(
findColByType(TableViewColumnInfo::TYPE_AUTHOR, colPos + 1) !=
288 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_AUTHOR
289 <<
" data type in column " << columnsInfo_[colPos].getName()
290 <<
" is repeated. This is not allowed." << __E__;
294 if(colPos != getNumberOfColumns() - 2)
296 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_AUTHOR
297 <<
" data type column must be 2nd to last (in column "
298 << getNumberOfColumns() - 2 <<
")." << __E__;
304 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_AUTHOR
305 <<
" data type column "
306 <<
" is missing. This is not allowed." << __E__;
311 if((colPos =
findColByType(TableViewColumnInfo::TYPE_TIMESTAMP)) != INVALID)
313 if(
findColByType(TableViewColumnInfo::TYPE_TIMESTAMP, colPos + 1) !=
316 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_TIMESTAMP
317 <<
" data type in column " << columnsInfo_[colPos].getName()
318 <<
" is repeated. This is not allowed." << __E__;
322 if(colPos != getNumberOfColumns() - 1)
324 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_TIMESTAMP
325 <<
" data type column must be last (in column "
326 << getNumberOfColumns() - 1 <<
")." << __E__;
327 __COUT_ERR__ <<
"\n" << ss.str();
333 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_TIMESTAMP
334 <<
" data type column "
335 <<
" is missing. This is not allowed." << __E__;
342 std::set<std::string > uidSet;
343 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
345 if(uidSet.find(theDataView_[row][colUID_]) != uidSet.end())
347 __SS__ << (
"Entries in UID are not unique. Specifically at row=" +
348 std::to_string(row) +
" value=" + theDataView_[row][colUID_])
353 if(theDataView_[row][colUID_].size() == 0)
355 __SS__ <<
"An invalid UID '" << theDataView_[row][colUID_] <<
"' "
356 <<
" was identified. UIDs must contain at least 1 character."
361 for(
unsigned int i = 0; i < theDataView_[row][colUID_].size(); ++i)
362 if(!((theDataView_[row][colUID_][i] >=
'A' &&
363 theDataView_[row][colUID_][i] <=
'Z') ||
364 (theDataView_[row][colUID_][i] >=
'a' &&
365 theDataView_[row][colUID_][i] <=
'z') ||
366 (theDataView_[row][colUID_][i] >=
'0' &&
367 theDataView_[row][colUID_][i] <=
'9') ||
368 (theDataView_[row][colUID_][i] ==
'-' ||
369 theDataView_[row][colUID_][i] ==
'_')))
371 __SS__ <<
"An invalid UID '" << theDataView_[row][colUID_] <<
"' "
372 <<
" was identified. UIDs must contain only letters, numbers,"
373 <<
"dashes, and underscores." << __E__;
377 uidSet.insert(theDataView_[row][colUID_]);
379 if(uidSet.size() != getNumberOfRows())
381 __SS__ <<
"Entries in UID are not unique!"
382 <<
"There are " << getNumberOfRows()
383 <<
" records and the unique UID count is " << uidSet.size() << __E__;
388 colPos = (
unsigned int)-1;
389 while((colPos =
findColByType(TableViewColumnInfo::TYPE_UNIQUE_DATA,
390 colPos + 1)) != INVALID)
392 std::set<std::string > uDataSet;
393 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
395 if(uDataSet.find(theDataView_[row][colPos]) != uDataSet.end())
397 __SS__ <<
"Entries in Unique Data column "
398 << columnsInfo_[colPos].getName()
399 << (
" are not unique. Specifically at row=" +
400 std::to_string(row) +
401 " value=" + theDataView_[row][colPos])
405 uDataSet.insert(theDataView_[row][colPos]);
407 if(uDataSet.size() != getNumberOfRows())
409 __SS__ <<
"Entries in Unique Data column "
410 << columnsInfo_[colPos].getName() <<
" are not unique!"
411 <<
"There are " << getNumberOfRows()
412 <<
" records and the unique data count is " << uDataSet.size()
420 colPos = (
unsigned int)-1;
421 while((colPos =
findColByType(TableViewColumnInfo::TYPE_UNIQUE_GROUP_DATA,
422 colPos + 1)) != INVALID)
427 for(
unsigned int groupIdColPos = 0; groupIdColPos < columnsInfo_.size();
429 if(columnsInfo_[groupIdColPos].isGroupID())
431 std::map<std::string ,
432 std::pair<
unsigned int ,
433 std::set<std::string >>>
436 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
440 for(
const auto& groupId : groupIds)
442 uGroupDataSets[groupId].first++;
444 if(uGroupDataSets[groupId].second.find(
445 theDataView_[row][colPos]) !=
446 uGroupDataSets[groupId].second.end())
448 __SS__ <<
"Entries in Unique Group Data column " << colPos
449 <<
":" << columnsInfo_[colPos].getName()
450 <<
" are not unique for group ID '" << groupId
451 <<
".' Specifically at row=" << std::to_string(row)
452 <<
" value=" << theDataView_[row][colPos] << __E__;
455 uGroupDataSets[groupId].second.insert(
456 theDataView_[row][colPos]);
460 for(
const auto& groupPair : uGroupDataSets)
461 if(uGroupDataSets[groupPair.first].second.size() !=
462 uGroupDataSets[groupPair.first].first)
465 <<
"Entries in Unique Data column "
466 << columnsInfo_[colPos].getName()
467 <<
" are not unique for group '" << groupPair.first
469 <<
"There are " << uGroupDataSets[groupPair.first].first
470 <<
" records and the unique data count is "
471 << uGroupDataSets[groupPair.first].second.size() << __E__;
477 auto rowDefaults = initRowDefaults();
484 std::set<std::string> groupIdIndexes, childLinkIndexes, childLinkIdLabels;
485 unsigned int groupIdIndexesCount = 0, childLinkIndexesCount = 0,
486 childLinkIdLabelsCount = 0;
488 std::pair<
unsigned int ,
unsigned int > tmpLinkPair;
491 if(getNumberOfRows() != theDataView_.size())
493 __SS__ <<
"Impossible row mismatch " << getNumberOfRows() <<
" vs "
494 << theDataView_.size() <<
"! How did you get here?" << __E__;
497 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
498 if(getNumberOfColumns() != theDataView_[row].size())
500 __SS__ <<
"Impossible col mismatch " << getNumberOfColumns() <<
" vs ["
501 << row <<
"]" << theDataView_[row].size()
502 <<
"! How did you get here?" << __E__;
505 if(getNumberOfColumns() != columnsInfo_.size())
507 __SS__ <<
"Impossible col info mismatch " << getNumberOfColumns() <<
" vs "
508 << columnsInfo_.size() <<
"! How did you get here?" << __E__;
511 if(getNumberOfColumns() != rowDefaults.size())
513 __SS__ <<
"Impossible col default mismatch " << getNumberOfColumns() <<
" vs "
514 << rowDefaults.size() <<
"! How did you get here?" << __E__;
518 for(
unsigned int col = 0; col < getNumberOfColumns(); ++col)
520 if(columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA)
522 const std::vector<std::string>& theDataChoices =
523 columnsInfo_[col].getDataChoices();
526 if(theDataChoices.size() && theDataChoices[0] ==
"arbitraryBool=1")
530 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
534 if(theDataView_[row][col] == rowDefaults[col])
537 for(
const auto& choice : theDataChoices)
539 if(theDataView_[row][col] == choice)
547 __SS__ << getTableName() <<
" Error:\t'" << theDataView_[row][col]
548 <<
"' in column " << columnsInfo_[col].getName()
549 <<
" is not a valid Fixed Choice option. "
550 <<
"Possible values are as follows: ";
552 ss << columnsInfo_[col].getDefaultValue()
553 << (columnsInfo_[col].getDataChoices().size() ?
", " :
"");
554 for(
unsigned int i = 0;
555 i < columnsInfo_[col].getDataChoices().size();
558 if(columnsInfo_[col].getDataChoices()[i] ==
"arbitraryBool=0")
561 if(i && (i != 1 || columnsInfo_[col].getDataChoices()[0] !=
564 ss << columnsInfo_[col].getDataChoices()[i];
571 else if(columnsInfo_[col].isChildLink())
575 const std::vector<std::string>& theDataChoices =
576 columnsInfo_[col].getDataChoices();
579 if(!theDataChoices.size() || theDataChoices[0] ==
"arbitraryBool=1")
584 (theDataChoices.size() && theDataChoices[0] ==
"arbitraryBool=0");
588 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
593 for(
const auto& choice : theDataChoices)
595 if(skipOne && !hasSkipped)
601 if(theDataView_[row][col] == choice)
609 __SS__ << getTableName() <<
" Error:\t the value '"
610 << theDataView_[row][col] <<
"' in column "
611 << columnsInfo_[col].getName()
612 <<
" is not a valid Fixed Choice option. "
613 <<
"Possible values are as follows: ";
618 for(
unsigned int i = skipOne ? 1 : 0;
619 i < columnsInfo_[col].getDataChoices().size();
622 if(i > (skipOne ? 1 : 0))
624 ss << columnsInfo_[col].getDataChoices()[i];
631 else if(columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_ON_OFF)
632 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
634 if(theDataView_[row][col] ==
"1" || theDataView_[row][col] ==
"on" ||
635 theDataView_[row][col] ==
"On" || theDataView_[row][col] ==
"ON")
636 theDataView_[row][col] = TableViewColumnInfo::TYPE_VALUE_ON;
637 else if(theDataView_[row][col] ==
"0" ||
638 theDataView_[row][col] ==
"off" ||
639 theDataView_[row][col] ==
"Off" ||
640 theDataView_[row][col] ==
"OFF")
641 theDataView_[row][col] = TableViewColumnInfo::TYPE_VALUE_OFF;
644 __SS__ << getTableName() <<
" Error:\t the value '"
645 << theDataView_[row][col] <<
"' in column "
646 << columnsInfo_[col].getName()
647 <<
" is not a valid Type (On/Off) std::string. Possible "
648 "values are 1, on, On, ON, 0, off, Off, OFF."
653 else if(columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_TRUE_FALSE)
654 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
656 if(theDataView_[row][col] ==
"1" ||
657 theDataView_[row][col] ==
"true" ||
658 theDataView_[row][col] ==
"True" ||
659 theDataView_[row][col] ==
"TRUE")
660 theDataView_[row][col] = TableViewColumnInfo::TYPE_VALUE_TRUE;
661 else if(theDataView_[row][col] ==
"0" ||
662 theDataView_[row][col] ==
"false" ||
663 theDataView_[row][col] ==
"False" ||
664 theDataView_[row][col] ==
"FALSE")
665 theDataView_[row][col] = TableViewColumnInfo::TYPE_VALUE_FALSE;
668 __SS__ << getTableName() <<
" Error:\t the value '"
669 << theDataView_[row][col] <<
"' in column "
670 << columnsInfo_[col].getName()
671 <<
" is not a valid Type (True/False) std::string. "
672 "Possible values are 1, true, True, TRUE, 0, false, "
678 else if(columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_YES_NO)
679 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
681 if(theDataView_[row][col] ==
"1" || theDataView_[row][col] ==
"yes" ||
682 theDataView_[row][col] ==
"Yes" || theDataView_[row][col] ==
"YES")
683 theDataView_[row][col] = TableViewColumnInfo::TYPE_VALUE_YES;
684 else if(theDataView_[row][col] ==
"0" ||
685 theDataView_[row][col] ==
"no" ||
686 theDataView_[row][col] ==
"No" ||
687 theDataView_[row][col] ==
"NO")
688 theDataView_[row][col] = TableViewColumnInfo::TYPE_VALUE_NO;
691 __SS__ << getTableName() <<
" Error:\t the value '"
692 << theDataView_[row][col] <<
"' in column "
693 << columnsInfo_[col].getName()
694 <<
" is not a valid Type (Yes/No) std::string. Possible "
695 "values are 1, yes, Yes, YES, 0, no, No, NO."
700 else if(columnsInfo_[col].isGroupID())
702 colLinkGroupIDs_[columnsInfo_[col].getChildLinkIndex()] =
705 groupIdIndexes.emplace(columnsInfo_[col].getChildLinkIndex());
706 ++groupIdIndexesCount;
708 else if(columnsInfo_[col].isChildLink())
711 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
712 if(theDataView_[row][col] ==
"NoLink" ||
713 theDataView_[row][col] ==
"No_Link" ||
714 theDataView_[row][col] ==
"NOLINK" ||
715 theDataView_[row][col] ==
"NO_LINK" ||
716 theDataView_[row][col] ==
"Nolink" ||
717 theDataView_[row][col] ==
"nolink" ||
718 theDataView_[row][col] ==
"noLink")
719 theDataView_[row][col] =
720 TableViewColumnInfo::DATATYPE_LINK_DEFAULT;
723 childLinkIndexes.emplace(columnsInfo_[col].getChildLinkIndex());
724 ++childLinkIndexesCount;
727 if(columnsInfo_[col].getDataType() !=
728 TableViewColumnInfo::DATATYPE_STRING)
730 __SS__ << getTableName() <<
" Error:\t"
731 <<
"Column " << col <<
" with name '"
732 << columnsInfo_[col].getName()
733 <<
"' is a Child Link column and has an illegal data type of '"
734 << columnsInfo_[col].getDataType()
735 <<
"'. The data type for Child Link columns must be "
736 << TableViewColumnInfo::DATATYPE_STRING << __E__;
743 else if(columnsInfo_[col].isChildLinkUID() ||
744 columnsInfo_[col].isChildLinkGroupID())
747 childLinkIdLabels.emplace(columnsInfo_[col].getChildLinkIndex());
748 ++childLinkIdLabelsCount;
751 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
752 if(theDataView_[row][col] ==
"")
753 theDataView_[row][col] = rowDefaults[col];
760 if(columnsInfo_[col].isNumberDataType())
762 std::string minimumValueString = columnsInfo_[col].getMinValue();
763 std::string maximumValueString = columnsInfo_[col].getMaxValue();
764 double minimumValue, maximumValue, valueFromTable;
765 bool minExists =
false, maxExists =
false;
767 if(!minimumValueString.empty())
774 __SS__ <<
"Inavlid user spec'd min value '" << minimumValueString
775 <<
"' which is not a valid number. The minimum value must "
776 "be a number (environment variables and math "
777 "operations are allowed)."
783 if(!maximumValueString.empty())
790 __SS__ <<
"Inavlid user spec'd max value '" << maximumValueString
791 <<
"' which is not a valid number. The maximum value must "
792 "be a number (environment variables and math "
793 "operations are allowed)."
799 if(minExists && maxExists && minimumValue > maximumValue)
801 __SS__ <<
"Minimum value is greater than maximum, check table editor "
807 if(minExists || maxExists)
808 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
811 if(minExists && valueFromTable < minimumValue)
814 <<
"The value '" << valueFromTable <<
"'("
817 <<
") at [row,col]=[" << row <<
"," << col
818 <<
"] is outside the established limits: "
820 <<
" is lower than the specified minimum " << minimumValue
824 if(maxExists && valueFromTable > maximumValue)
827 <<
"This value '" << valueFromTable <<
"'("
830 <<
") at [row,col]=[" << row <<
"," << col
831 <<
"] is outside the established limits: "
833 <<
" is greater than the specified maximum "
834 << maximumValue <<
"." << __E__;
842 if(groupIdIndexes.size() != groupIdIndexesCount)
844 __SS__ << (
"GroupId Labels are not unique!") <<
"There are "
845 << groupIdIndexesCount <<
" GroupId Labels and the unique count is "
846 << groupIdIndexes.size() << __E__;
849 if(childLinkIndexes.size() != childLinkIndexesCount)
851 __SS__ << (
"Child Link Labels are not unique!") <<
"There are "
852 << childLinkIndexesCount
853 <<
" Child Link Labels and the unique count is "
854 << childLinkIndexes.size() << __E__;
857 if(childLinkIdLabels.size() != childLinkIdLabelsCount)
859 __SS__ << (
"Child Link ID Labels are not unique!") <<
"There are "
860 << childLinkIdLabelsCount
861 <<
" Child Link ID Labels and the unique count is "
862 << childLinkIdLabels.size() << __E__;
868 __COUT__ <<
"Error occured in TableView::init() for version=" << version_
882 bool doConvertEnvironmentVariables)
const
884 if(!(row < getNumberOfRows() && col < theDataView_[row].size()))
886 __SS__ <<
"Invalid row col requested " << row <<
"," << col <<
" vs "
887 << getNumberOfRows() <<
"," << columnsInfo_.size() <<
"/"
888 << theDataView_[row].size() << __E__;
893 theDataView_[row][col], col, doConvertEnvironmentVariables);
903 bool doConvertEnvironmentVariables)
const
905 if(col >= columnsInfo_.size())
907 __SS__ <<
"Invalid col requested" << __E__;
911 if(columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA &&
913 value == columnsInfo_[col].getDefaultDefaultValue(columnsInfo_[col].getType(),
914 columnsInfo_[col].getDataType()))
918 std::vector<std::string> choices = columnsInfo_[col].getDataChoices();
921 bool skipOne = (choices.size() && choices[0].find(
"arbitraryBool=") == 0);
922 size_t index = (skipOne ? 1 : 0);
923 if(choices.size() > index)
925 return doConvertEnvironmentVariables
931 if(columnsInfo_[col].getDataType() == TableViewColumnInfo::DATATYPE_STRING)
932 return doConvertEnvironmentVariables
935 else if(columnsInfo_[col].getDataType() == TableViewColumnInfo::DATATYPE_TIME)
938 doConvertEnvironmentVariables
953 __SS__ <<
"\tUnrecognized column data type: " << columnsInfo_[col].getDataType()
954 <<
" in configuration " << tableName_
955 <<
" at column=" << columnsInfo_[col].getName()
956 <<
" for getValue with type '"
971 bool doConvertEnvironmentVariables)
const
973 if(!(col < columnsInfo_.size() && row < getNumberOfRows()))
975 __SS__ << (
"Invalid row col requested") << __E__;
981 if(columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_ON_OFF)
983 if(theDataView_[row][col] ==
"1" || theDataView_[row][col] ==
"on" ||
984 theDataView_[row][col] ==
"On" || theDataView_[row][col] ==
"ON")
985 return TableViewColumnInfo::TYPE_VALUE_ON;
987 return TableViewColumnInfo::TYPE_VALUE_OFF;
989 else if(columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_TRUE_FALSE)
991 if(theDataView_[row][col] ==
"1" || theDataView_[row][col] ==
"true" ||
992 theDataView_[row][col] ==
"True" || theDataView_[row][col] ==
"TRUE")
993 return TableViewColumnInfo::TYPE_VALUE_TRUE;
995 return TableViewColumnInfo::TYPE_VALUE_FALSE;
997 else if(columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_YES_NO)
999 if(theDataView_[row][col] ==
"1" || theDataView_[row][col] ==
"yes" ||
1000 theDataView_[row][col] ==
"Yes" || theDataView_[row][col] ==
"YES")
1001 return TableViewColumnInfo::TYPE_VALUE_YES;
1003 return TableViewColumnInfo::TYPE_VALUE_NO;
1007 return doConvertEnvironmentVariables
1009 : theDataView_[row][col];
1020 bool doConvertEnvironmentVariables)
const
1022 std::string val =
getValueAsString(row, col, doConvertEnvironmentVariables);
1023 std::string retVal =
"";
1024 retVal.reserve(val.size());
1025 for(
unsigned int i = 0; i < val.size(); ++i)
1029 else if(val[i] ==
'\t')
1031 else if(val[i] ==
'\r')
1036 if(val[i] ==
'"' || val[i] ==
'\\')
1049 if(!(col < columnsInfo_.size() && row < getNumberOfRows()))
1051 __SS__ <<
"Invalid row (" << row <<
") col (" << col <<
") requested!" << __E__;
1055 if(columnsInfo_[col].getDataType() == TableViewColumnInfo::DATATYPE_STRING)
1056 theDataView_[row][col] = value;
1060 __SS__ <<
"\tUnrecognized column data type: " << columnsInfo_[col].getDataType()
1061 <<
" in configuration " << tableName_
1062 <<
" at column=" << columnsInfo_[col].getName()
1063 <<
" for setValue with type '"
1072 setValue(std::string(value), row, col);
1082 if(!(col < columnsInfo_.size() && row < getNumberOfRows()))
1084 __SS__ <<
"Invalid row (" << row <<
") col (" << col <<
") requested!" << __E__;
1088 theDataView_[row][col] = value;
1101 std::string baseValueAsString ,
1102 bool doMathAppendStrategy ,
1103 std::string childLinkIndex ,
1104 std::string groupId )
1106 if(!(col < columnsInfo_.size() && row < getNumberOfRows()))
1108 __SS__ <<
"Invalid row (" << row <<
") col (" << col <<
") requested!" << __E__;
1112 bool isUniqueGroupCol =
1113 (columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_UNIQUE_GROUP_DATA);
1114 unsigned int childLinkIndexCol = -1;
1115 if(isUniqueGroupCol)
1117 __COUTVS__(12, childLinkIndex);
1118 __COUTVS__(12, groupId);
1120 __COUTVS__(12, childLinkIndexCol);
1123 __COUT__ <<
"Current '" << columnsInfo_[col].getName() <<
"' "
1124 << (isUniqueGroupCol ?
"(Unique in Group) " :
"")
1125 <<
"unique data entry is data[" << row <<
"][" << col <<
"] = '"
1126 << theDataView_[row][col] <<
"' baseValueAsString = " << baseValueAsString
1127 <<
" doMathAppendStrategy = " << doMathAppendStrategy << __E__;
1129 bool firstConflict =
true;
1130 int maxUniqueData = -1;
1131 std::string tmpString =
"";
1134 std::string numString;
1135 std::string opString;
1141 for(
unsigned int r = 0; r < getNumberOfRows(); ++r)
1146 if(isUniqueGroupCol && !isEntryInGroupCol(r, childLinkIndexCol, groupId))
1152 tmpString = theDataView_[r][col];
1154 __COUTT__ <<
"row[" << r <<
"] tmpString " << tmpString << __E__;
1156 for(index = tmpString.length() - 1; index < tmpString.length(); --index)
1158 __COUTT__ << index <<
" tmpString[index] " << tmpString[index] << __E__;
1159 if(!(tmpString[index] >=
'0' && tmpString[index] <=
'9'))
1164 __COUTT__ <<
"index " << index <<
" foundAny " << foundAny << __E__;
1166 if(tmpString.length() && foundAny)
1169 numString = tmpString.substr(index + 1);
1172 tmpString = tmpString.substr(0, index + 1);
1174 if(doMathAppendStrategy && tmpString.size())
1178 for(index = tmpString.length() - 1; index < tmpString.length(); --index)
1182 if(!(tmpString[index] ==
'+' || tmpString[index] ==
' '))
1190 opString = tmpString.substr(index + 1);
1193 tmpString = tmpString.substr(0, index + 1);
1197 __COUTT__ << tmpString <<
" vs " << baseValueAsString << __E__;
1199 if(baseValueAsString !=
"" && tmpString != baseValueAsString)
1202 __COUTT__ <<
"Found unique data base string '" << tmpString
1203 <<
"' and number string '" << numString <<
"' in last record '"
1204 << theDataView_[r][col] <<
"'" << __E__;
1209 if(baseValueAsString.size() &&
1210 baseValueAsString[baseValueAsString.size() - 1] >=
'0' &&
1211 baseValueAsString[baseValueAsString.size() - 1] <=
'9')
1212 baseValueAsString +=
'_';
1214 firstConflict =
false;
1218 sscanf(numString.c_str(),
"%u", &index);
1220 if((
int)index > maxUniqueData)
1222 maxUniqueData = (int)index;
1224 if(baseValueAsString ==
"")
1225 baseValueAsString = tmpString;
1228 else if(maxUniqueData < 0 &&
1229 (baseValueAsString ==
"" || tmpString == baseValueAsString))
1234 if(baseValueAsString.size() &&
1235 baseValueAsString[baseValueAsString.size() - 1] >=
'0' &&
1236 baseValueAsString[baseValueAsString.size() - 1] <=
'9')
1237 baseValueAsString +=
'_';
1239 firstConflict =
false;
1246 __COUTVS__(12, maxUniqueData);
1247 __COUTVS__(12, baseValueAsString);
1249 if(maxUniqueData == -1)
1251 if(baseValueAsString !=
"")
1252 theDataView_[row][col] = baseValueAsString;
1254 theDataView_[row][col] = columnsInfo_[col].getDefaultValue();
1260 char indexString[1000];
1261 sprintf(indexString,
"%u", maxUniqueData);
1263 __COUTVS__(12, indexString);
1264 __COUTVS__(12, baseValueAsString);
1266 if(doMathAppendStrategy)
1267 theDataView_[row][col] = baseValueAsString +
" + " + indexString;
1269 theDataView_[row][col] = baseValueAsString + indexString;
1272 __COUT__ <<
"New unique data entry is data[" << row <<
"][" << col <<
"] = '"
1273 << theDataView_[row][col] <<
"'" << __E__;
1277 return theDataView_[row][col];
1283 unsigned int TableView::initColUID(
void)
1285 if(colUID_ != INVALID)
1290 if(colUID_ == INVALID)
1292 __COUT__ <<
"Column Types: " << __E__;
1293 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
1294 std::cout << columnsInfo_[col].getType() <<
"() "
1295 << columnsInfo_[col].getName() << __E__;
1296 __SS__ <<
"\tMissing UID Column in table named '" << tableName_ <<
"'" << __E__;
1307 if(colUID_ != INVALID)
1310 __COUT__ <<
"Column Types: " << __E__;
1311 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
1312 std::cout << columnsInfo_[col].getType() <<
"() " << columnsInfo_[col].getName()
1315 __SS__ << (
"Missing UID Column in config named " + tableName_ +
1316 ". (Possibly TableView was just not initialized?" +
1317 " This is the const call so can not alter class members)")
1328 unsigned int TableView::initColStatus(
void)
1330 if(colStatus_ != INVALID)
1334 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
1335 if(columnsInfo_[col].getName() == TableViewColumnInfo::COL_NAME_STATUS)
1340 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
1341 if(columnsInfo_[col].getName() == TableViewColumnInfo::COL_NAME_ENABLED)
1349 __SS__ <<
"\tMissing column named '" << TableViewColumnInfo::COL_NAME_STATUS
1350 <<
"' or '" << TableViewColumnInfo::COL_NAME_ENABLED <<
"' in table '"
1351 << tableName_ <<
".'" << __E__;
1352 ss <<
"\n\nTable '" << tableName_ <<
"' Columns: " << __E__;
1353 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
1354 ss << columnsInfo_[col].getType() <<
"() " << columnsInfo_[col].getName()
1364 unsigned int TableView::initColPriority(
void)
1366 if(colPriority_ != INVALID)
1367 return colPriority_;
1371 findCol(
"*" + TableViewColumnInfo::COL_NAME_PRIORITY);
1372 if(colPriority_ == INVALID)
1374 __SS__ <<
"\tMissing column named '" << TableViewColumnInfo::COL_NAME_PRIORITY
1375 <<
"' in table '" << tableName_ <<
".'" << __E__;
1376 ss <<
"\n\nTable '" << tableName_ <<
"' Columns: " << __E__;
1377 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
1378 ss << columnsInfo_[col].getType() <<
"() " << columnsInfo_[col].getName()
1383 return colPriority_;
1392 if(colStatus_ != INVALID)
1395 __SS__ <<
"\tMissing column named '" << TableViewColumnInfo::COL_NAME_STATUS
1396 <<
"' or '" << TableViewColumnInfo::COL_NAME_ENABLED <<
"' in table '"
1397 << tableName_ <<
".'"
1398 <<
" (The Status column is identified when the TableView is initialized)"
1401 ss <<
"\n\nTable '" << tableName_ <<
"' Columns: " << __E__;
1402 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
1403 ss <<
"\t" << columnsInfo_[col].getType() <<
"() " << columnsInfo_[col].getName()
1410 __COUT_WARN__ << ss.str();
1423 if(colPriority_ != INVALID)
1424 return colPriority_;
1426 __SS__ <<
"Priority column was not found... \nColumn Types: " << __E__;
1428 ss <<
"Missing " << TableViewColumnInfo::COL_NAME_PRIORITY
1429 <<
" Column in table named '" << tableName_
1430 <<
".' (The Priority column is identified when the TableView is initialized)"
1434 ss <<
"\n\nTable '" << tableName_ <<
"' Columns: " << __E__;
1435 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
1436 ss <<
"\t" << columnsInfo_[col].getType() <<
"() " << columnsInfo_[col].getName()
1449 const unsigned int& col,
1450 const std::string& groupID)
1453 if(isEntryInGroupCol(row, col, groupID))
1455 __SS__ <<
"GroupID (" << groupID <<
") added to row (" << row
1456 <<
" is already present!" << __E__;
1465 if(getDataView()[row][col] ==
"" ||
1466 getDataView()[row][col] == getDefaultRowValues()[col])
1469 setValue(groupID +
" | " + getDataView()[row][col], row, col);
1481 const unsigned int groupIdCol,
1482 const std::string& groupID,
1483 bool onlyStatusTrue ,
1484 bool orderedByPriority )
const
1486 std::vector<
unsigned int > retVector;
1487 std::vector<std::vector<
unsigned int >> groupRowVectors =
1488 getGroupRowsInVectors(groupIdCol, groupID, onlyStatusTrue, orderedByPriority);
1490 for(
const auto& groupRowVector : groupRowVectors)
1491 for(
const auto& groupRow : groupRowVector)
1492 retVector.push_back(groupRow);
1504 const unsigned int groupIdCol,
1505 const std::string& groupID,
1506 bool onlyStatusTrue )
const
1508 return getGroupRowsInVectors(
1509 groupIdCol, groupID, onlyStatusTrue,
true );
1520 std::vector<std::vector<
unsigned int >> TableView::getGroupRowsInVectors(
1521 const unsigned int groupIdCol,
1522 const std::string& groupID,
1523 bool onlyStatusTrue,
1524 bool orderedByPriority)
const
1526 std::map<uint64_t , std::vector<
unsigned int >>
1528 std::vector<std::vector<
unsigned int >> retVector;
1529 uint64_t tmpPriority;
1532 if(!(orderedByPriority &&
1533 colPriority_ != INVALID))
1534 retVector.push_back(std::vector<unsigned int /*group row*/>());
1536 for(
unsigned int r = 0; r < getNumberOfRows(); ++r)
1537 if(groupID ==
"" || groupID ==
"*" || groupIdCol == INVALID ||
1538 isEntryInGroupCol(r, groupIdCol, groupID))
1541 if(onlyStatusTrue && colStatus_ != INVALID)
1543 getValue(tmpStatus, r, colStatus_);
1549 if(orderedByPriority && colPriority_ != INVALID)
1551 getValue(tmpPriority, r, colPriority_);
1553 mapByPriority[tmpPriority ? tmpPriority : 100].push_back(r);
1556 retVector[0].push_back(r);
1559 if(orderedByPriority && colPriority_ != INVALID)
1563 for(
const auto& priorityChildRowVector : mapByPriority)
1565 retVector.push_back(std::vector<unsigned int /*group row*/>());
1566 for(
const auto& priorityChildRow : priorityChildRowVector.second)
1567 retVector[retVector.size() - 1].push_back(priorityChildRow);
1570 __COUT__ <<
"Returning priority children list." << __E__;
1583 const unsigned int& col,
1584 const std::string& groupNeedle,
1585 bool deleteRowIfNoGroupLeft)
1587 __COUT__ <<
"groupNeedle " << groupNeedle << __E__;
1588 std::set<std::string> groupIDList;
1589 if(!isEntryInGroupCol(row, col, groupNeedle, &groupIDList))
1591 __SS__ <<
"GroupID (" << groupNeedle <<
") removed from row (" << row
1592 <<
") was already removed!" << __E__;
1601 std::string newValue =
"";
1602 unsigned int cnt = 0;
1603 for(
const auto& groupID : groupIDList)
1606 if(groupID == groupNeedle)
1611 newValue += groupID;
1614 bool wasDeleted =
false;
1615 if(deleteRowIfNoGroupLeft && newValue ==
"")
1617 __COUT__ <<
"Delete row since it no longer part of any group." << __E__;
1636 const std::string& childLinkIndex,
1637 const std::string& groupNeedle)
const
1641 return isEntryInGroupCol(r, c, groupNeedle);
1653 bool TableView::isEntryInGroupCol(
const unsigned int& r,
1654 const unsigned int& c,
1655 const std::string& groupNeedle,
1656 std::set<std::string>* groupIDList)
const
1658 if(r >= getNumberOfRows() || c >= getNumberOfColumns())
1660 __SS__ <<
"Invalid row/col requested!" << __E__;
1672 for(; j < theDataView_[r][c].size(); ++j)
1673 if((theDataView_[r][c][j] ==
' ' ||
1674 theDataView_[r][c][j] ==
'|') &&
1677 else if((theDataView_[r][c][j] ==
1679 theDataView_[r][c][j] ==
'|') &&
1683 groupIDList->emplace(theDataView_[r][c].substr(i, j - i));
1687 if(groupNeedle == theDataView_[r][c].substr(i, j - i))
1700 groupIDList->emplace(theDataView_[r][c].substr(i, j - i));
1704 if(groupNeedle == theDataView_[r][c].substr(i, j - i))
1720 unsigned int r)
const
1725 unsigned int r)
const
1729 std::set<std::string> retSet;
1734 if(r != (
unsigned int)-1)
1736 if(r >= getNumberOfRows())
1738 __SS__ <<
"Invalid row requested!" << __E__;
1770 for(r = 0; r < getNumberOfRows(); ++r)
1822 if(!childLinkIndex.size())
1824 __SS__ <<
"Empty childLinkIndex string parameter!" << __E__;
1829 const char* needleChildLinkIndex = &childLinkIndex[0];
1833 size_t spacePos = childLinkIndex.find(
' ');
1834 if(spacePos != std::string::npos &&
1835 spacePos + 1 < childLinkIndex.size())
1838 needleChildLinkIndex = &childLinkIndex[spacePos + 1];
1841 std::map<std::string, unsigned int>::const_iterator it =
1842 colLinkGroupIDs_.find(needleChildLinkIndex);
1844 colLinkGroupIDs_.end())
1848 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
1851 if(columnsInfo_[col].isChildLink() || columnsInfo_[col].isChildLinkUID() ||
1852 columnsInfo_[col].isChildLinkGroupID() || columnsInfo_[col].isGroupID())
1854 if(needleChildLinkIndex == columnsInfo_[col].getChildLinkIndex())
1860 <<
"Error! Incompatible table for this group link! Table '" << tableName_
1861 <<
"' is missing a GroupID column with data type '"
1862 << TableViewColumnInfo::TYPE_START_GROUP_ID <<
"-" << needleChildLinkIndex
1864 <<
"Note: you can separate the child GroupID column data type from "
1865 <<
"the parent GroupLink column data type; this is accomplished by using a space "
1866 <<
"character at the parent level - the string after the space will be treated "
1868 <<
"child GroupID column data type." << __E__;
1869 ss <<
"Existing Column GroupIDs: " << __E__;
1870 for(
auto& groupIdColPair : colLinkGroupIDs_)
1871 ss <<
"\t" << groupIdColPair.first <<
" : col-" << groupIdColPair.second << __E__;
1873 ss <<
"Existing Column Types: " << __E__;
1874 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
1875 ss <<
"\t" << columnsInfo_[col].getType() <<
"() " << columnsInfo_[col].getName()
1885 const std::string& value,
1886 unsigned int offsetRow,
1887 bool doNotThrow )
const
1889 for(
unsigned int row = offsetRow; row < theDataView_.size(); ++row)
1891 if(theDataView_[row][col] == value)
1895 return TableView::INVALID;
1897 __SS__ <<
"\tIn view: " << tableName_ <<
", Can't find value=" << value
1898 <<
" in column named " << columnsInfo_[col].getName()
1899 <<
" with type=" << columnsInfo_[col].getType() << __E__ << __E__
1910 const std::string& value,
1911 const std::string& groupId,
1912 const std::string& childLinkIndex,
1913 unsigned int offsetRow)
const
1916 for(
unsigned int row = offsetRow; row < theDataView_.size(); ++row)
1918 if(theDataView_[row][col] == value && isEntryInGroupCol(row, groupIdCol, groupId))
1922 __SS__ <<
"\tIn view: " << tableName_ <<
", Can't find in group the value=" << value
1923 <<
" in column named '" << columnsInfo_[col].getName()
1924 <<
"' with type=" << columnsInfo_[col].getType() <<
" and GroupID: '"
1925 << groupId <<
"' in column '" << groupIdCol
1926 <<
"' with GroupID child link index '" << childLinkIndex <<
"'" << __E__;
1937 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
1939 columnsInfo_[col].getName() ))
1942 __SS__ <<
"\tIn view: " << tableName_ <<
", Can't find column named '" << wildCardName
1944 ss <<
"Existing columns:\n";
1945 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
1946 ss <<
"\t" << columnsInfo_[col].getName() <<
"\n";
1959 unsigned int startingCol)
const
1961 for(
unsigned int col = startingCol; col < columnsInfo_.size(); ++col)
1963 __COUT_TYPE__(TLVL_DEBUG + 40)
1964 << __COUT_HDR__ << columnsInfo_[col].getType() << __E__;
1965 if(columnsInfo_[col].getType() == type)
1979 if(!getNumberOfRows())
1980 return getNumberOfColumns();
1981 return theDataView_[0].size();
1985 std::set<std::string> TableView::getColumnNames(
void)
const
1987 std::set<std::string> retSet;
1988 for(
auto& colInfo : columnsInfo_)
1989 retSet.emplace(colInfo.getName());
1994 std::map<std::string,
unsigned int > TableView::getColumnNamesMap(
void)
const
1996 std::map<std::string,
unsigned int > retMap;
1998 for(
auto& colInfo : columnsInfo_)
1999 retMap.emplace(std::make_pair(colInfo.getName(), c++));
2004 std::set<std::string> TableView::getColumnStorageNames(
void)
const
2006 std::set<std::string> retSet;
2007 for(
auto& colInfo : columnsInfo_)
2008 retSet.emplace(colInfo.getStorageName());
2013 const std::vector<std::string>& TableView::initRowDefaults(
void)
2015 std::vector<std::string>& retVec = rowDefaultValues_;
2019 for(
unsigned int col = 0; col < getNumberOfColumns(); ++col)
2026 if(columnsInfo_[col].isChildLink())
2028 const std::vector<std::string>& theDataChoices =
2029 columnsInfo_[col].getDataChoices();
2032 if(!theDataChoices.size() ||
2033 theDataChoices[0] ==
"arbitraryBool=1")
2034 retVec.push_back(columnsInfo_[col].getDefaultValue());
2038 (theDataChoices.size() && theDataChoices[0] ==
"arbitraryBool=0");
2043 bool foundDefault =
false;
2045 for(
const auto& choice : theDataChoices)
2046 if(skipOne && !hasSkipped)
2051 else if(choice == columnsInfo_[col].getDefaultValue())
2053 foundDefault =
true;
2058 if(!foundDefault && theDataChoices.size() > (skipOne ? 1 : 0))
2059 retVec.push_back(theDataChoices[(skipOne ? 1 : 0)]);
2061 retVec.push_back(columnsInfo_[col].getDefaultValue());
2065 retVec.push_back(columnsInfo_[col].getDefaultValue());
2070 return rowDefaultValues_;
2076 if(column >= columnsInfo_.size())
2078 __SS__ <<
"\nCan't find column " << column
2079 <<
"\n\n\n\nThe column info is likely missing due to incomplete "
2080 "Configuration View filling.\n\n"
2085 return columnsInfo_[column];
2097 void TableView::setAuthor(
const std::string& author) { author_ = author; }
2100 void TableView::setCreationTime(time_t t) { creationTime_ = t; }
2103 void TableView::setLastAccessTime(time_t t) { lastAccessTime_ = t; }
2106 void TableView::setLooseColumnMatching(
bool setValue)
2108 fillWithLooseColumnMatching_ =
setValue;
2112 void TableView::doGetSourceRawData(
bool setValue) { getSourceRawData_ =
setValue; }
2115 void TableView::reset(
void)
2120 columnsInfo_.clear();
2121 theDataView_.clear();
2125 void TableView::print(std::ostream& out)
const
2127 out <<
"============================================================================="
2130 out <<
"Print: " << tableName_ <<
" Version: " << version_ <<
" Comment: " << comment_
2131 <<
" Author: " << author_ <<
" Creation Time: " << ctime(&creationTime_) << __E__;
2132 out <<
"\t\tNumber of Cols " << getNumberOfColumns() << __E__;
2133 out <<
"\t\tNumber of Rows " << getNumberOfRows() << __E__;
2135 out <<
"Columns:\t";
2136 for(
int i = 0; i < (int)columnsInfo_.size(); ++i)
2137 out << i <<
":" << columnsInfo_[i].getName() <<
":"
2138 << columnsInfo_[i].getStorageName() <<
":" << columnsInfo_[i].getType() <<
":"
2139 << columnsInfo_[i].getDataType() <<
"\t ";
2142 out <<
"Rows:" << __E__;
2145 for(
int r = 0; r < (int)getNumberOfRows(); ++r)
2147 out << (int)r <<
":\t";
2148 for(
int c = 0; c < (int)getNumberOfColumns(); ++c)
2150 out << (int)c <<
":";
2153 if(columnsInfo_[c].getType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA)
2155 int choiceIndex = -1;
2156 std::vector<std::string> choices = columnsInfo_[c].getDataChoices();
2159 if(val == columnsInfo_[c].getDefaultValue())
2163 for(
int i = 0; i < (int)choices.size(); ++i)
2164 if(val == choices[i])
2165 choiceIndex = i + 1;
2168 out <<
"ChoiceIndex=" << choiceIndex <<
":";
2171 out << theDataView_[r][c];
2191 void TableView::printJSON(std::ostream& out)
const
2194 std::string tmpCachePrepend = TableBase::GROUP_CACHE_PREPEND;
2196 std::string tmpJsonDocPrepend = TableBase::JSON_DOC_PREPEND;
2198 __COUT__ <<
" '" << tableName_ <<
"' vs " << tmpCachePrepend <<
" or "
2199 << tmpJsonDocPrepend << __E__;
2201 if(tableName_.substr(0, tmpCachePrepend.length()) == tmpCachePrepend ||
2202 tableName_.substr(0, tmpJsonDocPrepend.length()) == tmpJsonDocPrepend)
2210 out <<
"\"NAME\" : \"" << tableName_ <<
"\",\n";
2214 out <<
"\"COMMENT\" : ";
2220 for(
unsigned int i = 0; i < val.size(); ++i)
2224 else if(val[i] ==
'\t')
2226 else if(val[i] ==
'\r')
2231 if(val[i] ==
'"' || val[i] ==
'\\')
2238 out <<
"\"AUTHOR\" : \"" << author_ <<
"\",\n";
2239 out <<
"\"CREATION_TIME\" : " << creationTime_ <<
",\n";
2244 out <<
"\"COL_TYPES\" : {\n";
2245 for(
int c = 0; c < (int)getNumberOfColumns(); ++c)
2247 out <<
"\t\t\"" << columnsInfo_[c].getStorageName() <<
"\" : ";
2248 out <<
"\"" << columnsInfo_[c].getDataType() <<
"\"";
2249 if(c + 1 < (
int)getNumberOfColumns())
2255 out <<
"\"DATA_SET\" : [\n";
2257 for(
int r = 0; r < (int)getNumberOfRows(); ++r)
2260 for(
int c = 0; c < (int)getNumberOfColumns(); ++c)
2262 out <<
"\t\t\"" << columnsInfo_[c].getStorageName() <<
"\" : ";
2267 if(c + 1 < (
int)getNumberOfColumns())
2272 if(r + 1 < (
int)getNumberOfRows())
2284 std::string restoreJSONStringEntities(
const std::string& str)
2286 unsigned int sz = str.size();
2290 std::stringstream retStr;
2292 for(; i < sz - 1; ++i)
2324 retStr << str[sz - 1];
2326 return retStr.str();
2341 std::string tmpCachePrepend = TableBase::GROUP_CACHE_PREPEND;
2343 std::string tmpJsonDocPrepend = TableBase::JSON_DOC_PREPEND;
2347 if(tableName_.substr(0, tmpJsonDocPrepend.length()) == tmpJsonDocPrepend)
2349 __COUTT__ <<
"Special JSON doc: " << json << __E__;
2355 if(tableName_.substr(0, tmpCachePrepend.length()) == tmpCachePrepend)
2357 __COUT_TYPE__(TLVL_DEBUG + 20)
2358 << __COUT_HDR__ <<
"Group Cache JSON doc: " << json << __E__;
2361 std::string jsonClean =
"";
2363 if(c ==
'{' || c ==
'}' || c ==
'"' || c ==
' ')
2374 bool rawData = getSourceRawData_;
2375 if(getSourceRawData_)
2377 __COUTV__(getSourceRawData_);
2378 getSourceRawData_ =
false;
2379 sourceRawData_ =
"";
2382 std::map<std::string ,
unsigned int > keyEntryCountMap;
2383 std::vector<std::string> keys;
2384 keys.push_back(
"NAME");
2385 keys.push_back(
"COMMENT");
2386 keys.push_back(
"AUTHOR");
2387 keys.push_back(
"CREATION_TIME");
2389 keys.push_back(
"DATA_SET");
2393 CV_JSON_FILL_COMMENT,
2394 CV_JSON_FILL_AUTHOR,
2395 CV_JSON_FILL_CREATION_TIME,
2397 CV_JSON_FILL_DATA_SET
2401 __COUTV__(tableName_);
2405 sourceColumnMismatchCount_ = 0;
2406 sourceColumnMissingCount_ = 0;
2407 sourceColumnNames_.clear();
2408 unsigned int colFoundCount = 0;
2410 unsigned int row = -1;
2411 unsigned int colSpeedup = 0;
2412 unsigned int startString, startNumber = 0, endNumber = -1;
2413 unsigned int bracketCount = 0;
2414 unsigned int sqBracketCount = 0;
2419 bool keyIsMatch, keyIsComment;
2420 unsigned int keyIsMatchIndex, keyIsMatchStorageIndex, keyIsMatchCommentIndex;
2421 const std::string COMMENT_ALT_KEY =
"COMMENT";
2423 std::string extractedString =
"", currKey =
"", currVal =
"";
2424 unsigned int currDepth = 0;
2426 std::vector<std::string> jsonPath;
2427 std::vector<char> jsonPathType;
2428 char lastPopType =
'_';
2430 unsigned int matchedKey = -1;
2431 unsigned int lastCol = -1;
2434 for(; i < json.size(); ++i)
2439 if(i - 1 < json.size() &&
2440 json[i - 1] ==
'\\')
2443 inQuotes = !inQuotes;
2448 extractedString = restoreJSONStringEntities(
2449 json.substr(startString + 1, i - startString - 1));
2458 if(jsonPathType[jsonPathType.size() - 1] !=
'{' ||
2461 __COUT__ <<
"Invalid ':' position" << __E__;
2466 jsonPathType.push_back(
'K');
2467 jsonPath.push_back(extractedString);
2486 if(lastPopType ==
'{')
2489 if(jsonPathType[jsonPathType.size() - 1] ==
'K')
2492 jsonPath.pop_back();
2493 jsonPathType.pop_back();
2499 currVal = extractedString;
2502 if(endNumber == (
unsigned int)-1 ||
2503 endNumber <= startNumber)
2506 if(endNumber <= startNumber)
2509 currVal = json.substr(startNumber + 1, endNumber - startNumber - 1);
2512 currDepth = bracketCount;
2514 if(jsonPathType[jsonPathType.size() - 1] ==
'K')
2516 currKey = jsonPath[jsonPathType.size() - 1];
2521 jsonPath.pop_back();
2522 jsonPathType.pop_back();
2524 else if(jsonPathType[jsonPathType.size() - 1] ==
2528 for(
unsigned int k = jsonPathType.size() - 2; k < jsonPathType.size();
2530 if(jsonPathType[k] ==
'K')
2532 currKey = jsonPath[k];
2537 __COUT__ <<
"Invalid array position" << __E__;
2546 __COUT__ <<
"Invalid ',' position" << __E__;
2557 jsonPathType.push_back(
'{');
2558 jsonPath.push_back(
"{");
2571 if(lastPopType !=
'{' &&
2572 jsonPathType[jsonPathType.size() - 1] ==
'K')
2574 currDepth = bracketCount;
2575 currKey = jsonPath[jsonPathType.size() - 1];
2577 currVal = extractedString;
2580 if(endNumber == (
unsigned int)-1 ||
2581 endNumber <= startNumber)
2584 if(endNumber <= startNumber)
2588 json.substr(startNumber + 1, endNumber - startNumber - 1);
2592 jsonPath.pop_back();
2593 jsonPathType.pop_back();
2596 if(jsonPathType[jsonPathType.size() - 1] !=
'{')
2598 __COUT__ <<
"Invalid '}' position" << __E__;
2602 jsonPath.pop_back();
2603 jsonPathType.pop_back();
2609 jsonPathType.push_back(
'[');
2610 jsonPath.push_back(
"[");
2619 if(jsonPathType[jsonPathType.size() - 1] !=
'[')
2621 __COUT__ <<
"Invalid ']' position" << __E__;
2625 currDepth = bracketCount;
2629 currVal = extractedString;
2632 if(endNumber == (
unsigned int)-1 ||
2633 endNumber <= startNumber)
2636 if(endNumber <= startNumber)
2639 currVal = json.substr(startNumber + 1, endNumber - startNumber - 1);
2644 for(
unsigned int k = jsonPathType.size() - 2; k < jsonPathType.size(); --k)
2645 if(jsonPathType[k] ==
'K')
2647 currKey = jsonPath[k];
2652 __COUT__ <<
"Invalid array position" << __E__;
2657 if(jsonPathType[jsonPathType.size() - 1] !=
'[')
2659 __COUT__ <<
"Invalid ']' position" << __E__;
2663 jsonPath.pop_back();
2664 jsonPathType.pop_back();
2673 if(startNumber != (
unsigned int)-1 && endNumber == (
unsigned int)-1)
2685 if(0 && tableName_ ==
"ARTDAQ_DATALOGGER_TABLE")
2687 std::cout << i <<
":\t" << json[i] <<
" - ";
2697 std::cout <<
"ExtKey=";
2698 for(
unsigned int k = 0; k < jsonPath.size(); ++k)
2699 std::cout << jsonPath[k] <<
"/";
2701 std::cout << lastPopType <<
" ";
2702 std::cout << bracketCount <<
" ";
2703 std::cout << sqBracketCount <<
" ";
2704 std::cout << inQuotes <<
" ";
2705 std::cout << newValue <<
"-";
2706 std::cout << currKey <<
"-{" << currDepth <<
"}:";
2707 std::cout << currVal <<
" ";
2708 std::cout << startNumber <<
"-";
2709 std::cout << endNumber <<
" ";
2711 __COUTV__(fillWithLooseColumnMatching_);
2720 for(
unsigned int k = 0; k < keys.size(); ++k)
2721 if((currDepth == 1 && keys[k] == currKey) ||
2722 (currDepth > 1 && keys[k] == jsonPath[1]))
2731 if(matchedKey == CV_JSON_FILL_COMMENT)
2732 setComment(currVal);
2733 else if(matchedKey == CV_JSON_FILL_AUTHOR)
2735 else if(matchedKey == CV_JSON_FILL_CREATION_TIME)
2736 setCreationTime(strtol(currVal.c_str(), 0, 10));
2738 else if(currDepth == 2)
2741 sourceRawData_ += StringMacros::encodeURIComponent(currKey) +
"," +
2742 StringMacros::encodeURIComponent(currVal) +
",";
2743 sourceColumnNames_.emplace(currKey);
2746 else if(matchedKey != (
unsigned int)-1)
2753 case CV_JSON_FILL_NAME:
2759 if(currVal != getTableName() &&
2761 "TABLE_GROUP_METADATA")
2762 __COUT_WARN__ <<
"JSON-fill Table name mismatch: " << currVal
2763 <<
" vs " << getTableName() << __E__;
2766 case CV_JSON_FILL_COMMENT:
2768 setComment(currVal);
2770 case CV_JSON_FILL_AUTHOR:
2774 case CV_JSON_FILL_CREATION_TIME:
2776 setCreationTime(strtol(currVal.c_str(), 0, 10));
2781 case CV_JSON_FILL_DATA_SET:
2793 unsigned int col, ccnt = 0;
2794 unsigned int noc = getNumberOfColumns();
2795 for(; ccnt < noc; ++ccnt)
2801 if(fillWithLooseColumnMatching_)
2814 if(getNumberOfRows() == 1)
2815 sourceColumnNames_.emplace(currKey);
2819 if(row >= getNumberOfRows())
2821 __SS__ <<
"Invalid row"
2823 std::cout << ss.str();
2828 theDataView_[row][col] =
2836 col = (ccnt + colSpeedup) % noc;
2842 keyIsComment =
true;
2843 for(keyIsMatchIndex = 0,
2844 keyIsMatchStorageIndex = 0,
2845 keyIsMatchCommentIndex = 0;
2846 keyIsMatchIndex < currKey.size();
2849 if(columnsInfo_[col]
2850 .getStorageName()[keyIsMatchStorageIndex] ==
2852 ++keyIsMatchStorageIndex;
2854 if(currKey[keyIsMatchIndex] ==
'_')
2858 if(keyIsMatchStorageIndex >=
2859 columnsInfo_[col].getStorageName().size() ||
2860 currKey[keyIsMatchIndex] !=
2862 .getStorageName()[keyIsMatchStorageIndex])
2872 keyIsMatchCommentIndex < COMMENT_ALT_KEY.size())
2874 if(currKey[keyIsMatchIndex] !=
2875 COMMENT_ALT_KEY[keyIsMatchCommentIndex])
2878 keyIsComment =
false;
2882 ++keyIsMatchStorageIndex;
2885 if(keyIsMatch || keyIsComment)
2888 if(keyEntryCountMap.find(currKey) ==
2889 keyEntryCountMap.end())
2890 keyEntryCountMap[currKey] =
2893 ++keyEntryCountMap.at(currKey);
2896 if(keyEntryCountMap.size() == 1 ||
2897 (keyEntryCountMap.at(currKey) &&
2898 keyEntryCountMap.at(currKey) >
2901 if(getNumberOfRows())
2902 sourceColumnMissingCount_ +=
2903 getNumberOfColumns() - colFoundCount;
2911 if(getNumberOfRows() == 1)
2912 sourceColumnNames_.emplace(currKey);
2916 if(row >= getNumberOfRows())
2918 __SS__ <<
"Invalid row"
2920 __COUT__ <<
"\n" << ss.str();
2925 theDataView_[row][col] = currVal;
2931 if(ccnt >= getNumberOfColumns())
2934 <<
"Invalid column in JSON source data: " << currKey
2935 <<
" not found in column names of table named "
2936 << getTableName() <<
"."
2941 ++sourceColumnMismatchCount_;
2942 if(getNumberOfRows() ==
2944 sourceColumnNames_.emplace(currKey);
2947 __COUT_WARN__ <<
"Trying to ignore error, and not populating "
2952 colSpeedup = (colSpeedup + 1) % noc;
2974 if(!fillWithLooseColumnMatching_ && sourceColumnMissingCount_ > 0)
2976 __COUTV__(sourceColumnMissingCount_);
2977 __SS__ <<
"Can not ignore errors because not every column was found in the "
2979 <<
". Please see the details below:\n\n"
2990 std::string TableView::getMismatchColumnInfo(
void)
const
2992 const std::set<std::string>& srcColNames = getSourceColumnNames();
2993 std::set<std::string> destColNames = getColumnStorageNames();
2995 __SS__ <<
"The source column size was found to be " << srcColNames.size()
2996 <<
", and the current number of columns for this table is "
2997 << getNumberOfColumns() <<
". This resulted in a count of "
2998 << getSourceColumnMismatch() <<
" source column mismatches, and a count of "
2999 << getSourceColumnMissing() <<
" table entries missing in "
3000 << getNumberOfRows() <<
" row(s) of data." << __E__;
3003 << srcColNames.size()
3004 <<
" Source column names in ALPHABETICAL order were as follows:\n";
3006 std::string preIndexStr =
"";
3007 for(
auto& srcColName : srcColNames)
3009 if(destColNames.find(srcColName) == destColNames.end())
3010 ss <<
"\n\t*** " << preIndexStr << index <<
". " << srcColName <<
" ***";
3012 ss <<
"\n\t" << preIndexStr << index <<
". " << srcColName;
3025 << destColNames.size()
3026 <<
" Current table column names in ALPHABETICAL order are as follows:\n";
3029 for(
auto& destColName : destColNames)
3031 if(srcColNames.find(destColName) == srcColNames.end())
3032 ss <<
"\n\t*** " << preIndexStr << index <<
". " << destColName <<
" ***";
3034 ss <<
"\n\t" << preIndexStr << index <<
". " << destColName;
3049 bool TableView::isURIEncodedCommentTheSame(
const std::string& comment)
const
3052 return comment_ == compareStr;
3112 const int& dataOffset,
3113 const std::string& author)
3121 int j = data.find(
',', i);
3122 int k = data.find(
';', i);
3124 bool rowWasModified;
3125 unsigned int countRowsModified = 0;
3126 int authorCol =
findColByType(TableViewColumnInfo::TYPE_AUTHOR);
3127 int timestampCol =
findColByType(TableViewColumnInfo::TYPE_TIMESTAMP);
3130 while(k != (
int)(std::string::npos))
3132 rowWasModified =
false;
3133 if(r >= (
int)getNumberOfRows())
3137 rowWasModified =
true;
3140 while(j < k && j != (
int)(std::string::npos))
3145 if(c >= (
int)getNumberOfColumns() - 2)
3148 j = data.find(
',', i);
3154 rowWasModified =
true;
3157 j = data.find(
',', i);
3162 if(author !=
"" && rowWasModified)
3164 __COUTT__ <<
"Row=" << (int)r <<
" was modified!" << __E__;
3166 setValue(time(0), r, timestampCol);
3170 ++countRowsModified;
3176 j = data.find(
',', i);
3177 k = data.find(
';', i);
3181 while(r < (
int)getNumberOfRows())
3184 __COUT__ <<
"Row deleted: " << (int)r << __E__;
3185 ++countRowsModified;
3188 __COUT_INFO__ <<
"countRowsModified=" << countRowsModified << __E__;
3190 if(!countRowsModified)
3195 bool match = getColumnStorageNames().size() == getSourceColumnNames().size();
3198 for(
auto& destColName : getColumnStorageNames())
3199 if(getSourceColumnNames().find(destColName) ==
3200 getSourceColumnNames().end())
3202 __COUT__ <<
"Found column name mismach for '" << destColName
3203 <<
"'... So allowing same data!" << __E__;
3212 __SS__ <<
"No rows were modified! No reason to fill a view with same content."
3214 __COUT__ <<
"\n" << ss.str();
3224 sourceColumnNames_.clear();
3225 for(
unsigned int i = 0; i < getNumberOfColumns(); ++i)
3226 sourceColumnNames_.emplace(getColumnsInfo()[i].getStorageName());
3248 const unsigned int& r,
3249 const unsigned int& c,
3250 const std::string& author)
3252 if(!(c < columnsInfo_.size() && r < getNumberOfRows()))
3254 __SS__ <<
"Invalid row (" << (int)r <<
") col (" << (
int)c <<
") requested!"
3255 <<
"Number of Rows = " << getNumberOfRows()
3256 <<
"Number of Columns = " << columnsInfo_.size() << __E__;
3262 std::string originalValueStr =
3286 theDataView_[r][c] = valueStr;
3290 else if(columnsInfo_[c].getDataType() == TableViewColumnInfo::DATATYPE_TIME)
3302 setValue(time_t(strtol(valueStr.c_str(), 0, 10)), r, c);
3305 theDataView_[r][c] = valueStr;
3307 bool rowWasModified =
3308 (originalValueStr !=
3312 if(author !=
"" && rowWasModified)
3314 __COUT__ <<
"Row=" << (int)r <<
" was modified!" << __E__;
3315 int authorCol =
findColByType(TableViewColumnInfo::TYPE_AUTHOR);
3316 int timestampCol =
findColByType(TableViewColumnInfo::TYPE_TIMESTAMP);
3318 setValue(time(0), r, timestampCol);
3321 return rowWasModified;
3325 void TableView::resizeDataView(
unsigned int nRows,
unsigned int nCols)
3329 theDataView_.resize(nRows, std::vector<std::string>(nCols));
3340 const std::string& author,
3342 incrementUniqueData ,
3345 const std::string& baseNameAutoUID ,
3346 unsigned int rowToAdd ,
3347 std::string childLinkIndex ,
3348 std::string groupId )
3351 if(rowToAdd == (
unsigned int)-1)
3352 rowToAdd = getNumberOfRows();
3354 theDataView_.resize(getNumberOfRows() + 1,
3355 std::vector<std::string>(getNumberOfColumns()));
3358 for(
unsigned int r = getNumberOfRows() - 2; r >= rowToAdd; --r)
3360 if(r == (
unsigned int)-1)
3362 for(
unsigned int col = 0; col < getNumberOfColumns(); ++col)
3363 theDataView_[r + 1][col] = theDataView_[r][col];
3366 std::vector<std::string> defaultRowValues = getDefaultRowValues();
3369 std::string tmpString, baseString;
3373 std::string numString;
3378 for(
unsigned int col = 0; col < getNumberOfColumns(); ++col)
3386 if(incrementUniqueData &&
3387 (col ==
getColUID() || columnsInfo_[col].isChildLinkGroupID() ||
3388 (getNumberOfRows() > 1 &&
3389 (columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_UNIQUE_DATA ||
3390 columnsInfo_[col].getType() ==
3391 TableViewColumnInfo::TYPE_UNIQUE_GROUP_DATA))))
3393 if(col ==
getColUID() || columnsInfo_[col].isChildLinkGroupID())
3395 rowToAdd, col, baseNameAutoUID );
3405 theDataView_[rowToAdd][col] = defaultRowValues[col];
3410 __COUT__ <<
"Row=" << rowToAdd <<
" was created!" << __E__;
3412 int authorCol =
findColByType(TableViewColumnInfo::TYPE_AUTHOR);
3413 int timestampCol =
findColByType(TableViewColumnInfo::TYPE_TIMESTAMP);
3414 setValue(author, rowToAdd, authorCol);
3415 setValue(time(0), rowToAdd, timestampCol);
3426 if(r >= (
int)getNumberOfRows())
3429 __SS__ <<
"Row " << (int)r
3430 <<
" is out of bounds (Row Count = " << getNumberOfRows()
3431 <<
") and can not be deleted." << __E__;
3435 theDataView_.erase(theDataView_.begin() + r);
3455 const unsigned int& c,
3457 std::pair<unsigned int /*link col*/, unsigned int /*link id col*/>& linkPair)
const
3459 if(!(c < columnsInfo_.size()))
3461 __SS__ <<
"Invalid col (" << (int)c <<
") requested for child link!" << __E__;
3469 if((isGroup = columnsInfo_[c].isChildLinkGroupID()) ||
3470 columnsInfo_[c].isChildLinkUID())
3474 linkPair.second = c;
3475 std::string index = columnsInfo_[c].getChildLinkIndex();
3480 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
3486 else if(columnsInfo_[col].isChildLink() &&
3487 index == columnsInfo_[col].getChildLinkIndex())
3492 linkPair.first = col;
3498 __SS__ <<
"\tIn view: " << tableName_
3499 <<
", Can't find complete child link for column name "
3500 << columnsInfo_[c].getName() << __E__;
3504 if(!columnsInfo_[c].isChildLink())
3509 std::string index = columnsInfo_[c].getChildLinkIndex();
3514 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
3531 if(((columnsInfo_[col].isChildLinkUID() && !(isGroup =
false)) ||
3532 (columnsInfo_[col].isChildLinkGroupID() && (isGroup =
true))) &&
3533 index == columnsInfo_[col].getChildLinkIndex())
3538 linkPair.second = col;
3544 __SS__ <<
"\tIn view: " << tableName_
3545 <<
", Can't find complete child link id for column name "
3546 << columnsInfo_[c].getName() << __E__;
static std::string convertToCaps(std::string &str, bool isConfigName=false)
static const std::string DATATYPE_NUMBER
static const std::string TYPE_UID
NOTE: Do NOT put '-' in static const TYPEs because it will mess up javascript handling in the web gui...
unsigned int findRow(unsigned int col, const T &value, unsigned int offsetRow=0, bool doNotThrow=false) const
< in included .icc source
bool isEntryInGroup(const unsigned int &row, const std::string &childLinkIndex, const std::string &groupNeedle) const
void setValueAsString(const std::string &value, unsigned int row, unsigned int col)
std::vector< std::vector< unsigned int > > getGroupRowsByPriority(const unsigned int groupIdCol, const std::string &groupID, bool onlyStatusTrue=false) const
T validateValueForColumn(const std::string &value, unsigned int col, bool doConvertEnvironmentVariables=true) const
< in included .icc source
TableView(const std::string &tableName)
= "");
std::string getEscapedValueAsString(unsigned int row, unsigned int col, bool convertEnvironmentVariables=true) const
unsigned int getColStatus(void) const
unsigned int getLinkGroupIDColumn(const std::string &childLinkIndex) const
int fillFromCSV(const std::string &data, const int &dataOffset=0, const std::string &author="")
bool removeRowFromGroup(const unsigned int &row, const unsigned int &col, const std::string &groupID, bool deleteRowIfNoGroupLeft=false)
unsigned int findColByType(const std::string &type, unsigned int startingCol=0) const
bool getChildLink(const unsigned int &col, bool &isGroup, std::pair< unsigned int, unsigned int > &linkPair) const
void addRowToGroup(const unsigned int &row, const unsigned int &col, const std::string &groupID)
, const std::string& colDefault);
unsigned int copyRows(const std::string &author, const TableView &src, unsigned int srcOffsetRow=0, unsigned int srcRowsToCopy=(unsigned int) -1, unsigned int destOffsetRow=(unsigned int) -1, unsigned char generateUniqueDataColumns=false, const std::string &baseNameAutoUID="")
unsigned int getColPriority(void) const
const std::string & setUniqueColumnValue(unsigned int row, unsigned int col, std::string baseValueAsString="", bool doMathAppendStrategy=false, std::string childLinkIndex="", std::string groupId="")
std::string getValueAsString(unsigned int row, unsigned int col, bool convertEnvironmentVariables=true) const
std::vector< unsigned int > getGroupRows(const unsigned int groupIdCol, const std::string &groupID, bool onlyStatusTrue=false, bool orderedByPriority=false) const
const std::string & getCustomStorageData(void) const
Getters.
std::set< std::string > getSetOfGroupIDs(const std::string &childLinkIndex, unsigned int row=-1) const
void getValue(T &value, unsigned int row, unsigned int col, bool doConvertEnvironmentVariables=true) const
< in included .icc source
unsigned int getDataColumnSize(void) const
getDataColumnSize
int fillFromJSON(const std::string &json)
unsigned int getColUID(void) const
bool setURIEncodedValue(const std::string &value, const unsigned int &row, const unsigned int &col, const std::string &author="")
unsigned int findCol(const std::string &name) const
void setValue(const T &value, unsigned int row, unsigned int col)
< in included .icc source
void setURIEncodedComment(const std::string &uriComment)
unsigned int addRow(const std::string &author="", unsigned char incrementUniqueData=false, const std::string &baseNameAutoUID="", unsigned int rowToAdd=(unsigned int) -1, std::string childLinkIndex="", std::string groupId="")
unsigned int findRowInGroup(unsigned int col, const T &value, const std::string &groupId, const std::string &childLinkIndex, unsigned int offsetRow=0) const
< in included .icc source
void setCustomStorageData(const std::string &storageData)
static std::string getTimestampString(const std::string &linuxTimeInSeconds)
static void getSetFromString(const std::string &inputString, std::set< std::string > &setToReturn, const std::set< char > &delimiter={',', '|', '&'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'})
static std::string convertEnvironmentVariables(const std::string &data)
static std::string demangleTypeName(const char *name)
static bool wildCardMatch(const std::string &needle, const std::string &haystack, unsigned int *priorityIndex=0)
static std::string decodeURIComponent(const std::string &data)
static std::string stackTrace(void)
static bool getNumber(const std::string &s, T &retValue)