1 #include "otsdaq-core/TableCore/TableView.h"
11 #define __MF_SUBJECT__ "TableView-" + tableName_
13 #define __COUT_HDR__ "v" << version_ << ":" << __COUT_HDR_FL__
15 const unsigned int TableView::INVALID = -1;
18 TableView::TableView(
const std::string& name)
19 : uniqueStorageIdentifier_(
"")
24 , creationTime_(time(0))
28 , colPriority_(INVALID)
29 , fillWithLooseColumnMatching_(false)
30 , sourceColumnMismatchCount_(0)
31 , sourceColumnMissingCount_(0)
36 TableView::~TableView(
void) {}
44 __SS__ <<
"Invalid use of operator=... Should not directly copy a TableView. Please "
45 "use TableView::copy(sourceView,author,comment)";
52 const std::string& author)
54 tableName_ = src.tableName_;
55 version_ = destinationVersion;
56 comment_ = src.comment_;
59 lastAccessTime_ = time(0);
60 columnsInfo_ = src.columnsInfo_;
61 theDataView_ = src.theDataView_;
62 sourceColumnNames_ = src.sourceColumnNames_;
70 unsigned int TableView::copyRows(
const std::string& author,
72 unsigned int srcOffsetRow,
73 unsigned int srcRowsToCopy,
74 unsigned int destOffsetRow,
75 bool generateUniqueDataColumns)
81 unsigned int retRow = (
unsigned int)-1;
84 if(src.getNumberOfColumns() != getNumberOfColumns())
86 __SS__ <<
"Error! Number of Columns of source view must match destination view."
87 <<
"Dimension of source is [" << src.getNumberOfColumns()
88 <<
"] and of destination is [" << getNumberOfColumns() <<
"]." << __E__;
92 unsigned int srcRows = src.getNumberOfRows();
94 for(
unsigned int r = 0; r < srcRowsToCopy; ++r)
96 if(r + srcOffsetRow >= srcRows)
99 destOffsetRow = addRow(author,
100 generateUniqueDataColumns ,
104 if(retRow == (
unsigned int)-1)
105 retRow = destOffsetRow;
108 for(
unsigned int col = 0; col < getNumberOfColumns(); ++col)
109 if(generateUniqueDataColumns &&
110 (columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_UNIQUE_DATA ||
111 columnsInfo_[col].getType() ==
112 TableViewColumnInfo::TYPE_UNIQUE_GROUP_DATA))
115 theDataView_[destOffsetRow][col] =
116 src.theDataView_[r + srcOffsetRow][col];
132 void TableView::init(
void)
138 std::set<std::string> colNameSet;
139 std::string capsColName, colName;
140 for(
auto& colInfo : columnsInfo_)
142 colName = colInfo.getStorageName();
143 if(colName ==
"COMMENT_DESCRIPTION")
146 for(
unsigned int i = 0; i < colName.size(); ++i)
148 if(colName[i] ==
'_')
150 capsColName += colName[i];
153 colNameSet.emplace(capsColName);
156 if(colNameSet.size() != columnsInfo_.size())
158 __SS__ <<
"Table Error:\t"
159 <<
" Columns names must be unique! There are " << columnsInfo_.size()
160 <<
" columns and the unique name count is " << colNameSet.size()
168 getOrInitColStatus();
175 getOrInitColPriority();
183 if((colPos = findColByType(TableViewColumnInfo::TYPE_COMMENT)) != INVALID)
185 if(columnsInfo_[colPos].getName() !=
"CommentDescription")
187 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_COMMENT
188 <<
" data type column must have name="
189 <<
"CommentDescription" << __E__;
193 if(findColByType(TableViewColumnInfo::TYPE_COMMENT, colPos + 1) !=
196 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_COMMENT
197 <<
" data type in column " << columnsInfo_[colPos].getName()
198 <<
" is repeated. This is not allowed." << __E__;
202 if(colPos != getNumberOfColumns() - 3)
204 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_COMMENT
205 <<
" data type column must be 3rd to last (in column "
206 << getNumberOfColumns() - 3 <<
")." << __E__;
212 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_COMMENT
213 <<
" data type column "
214 <<
" is missing. This is not allowed." << __E__;
219 if((colPos = findColByType(TableViewColumnInfo::TYPE_AUTHOR)) != INVALID)
221 if(findColByType(TableViewColumnInfo::TYPE_AUTHOR, colPos + 1) !=
224 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_AUTHOR
225 <<
" data type in column " << columnsInfo_[colPos].getName()
226 <<
" is repeated. This is not allowed." << __E__;
230 if(colPos != getNumberOfColumns() - 2)
232 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_AUTHOR
233 <<
" data type column must be 2nd to last (in column "
234 << getNumberOfColumns() - 2 <<
")." << __E__;
240 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_AUTHOR
241 <<
" data type column "
242 <<
" is missing. This is not allowed." << __E__;
247 if((colPos = findColByType(TableViewColumnInfo::TYPE_TIMESTAMP)) != INVALID)
249 if(findColByType(TableViewColumnInfo::TYPE_TIMESTAMP, colPos + 1) !=
252 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_TIMESTAMP
253 <<
" data type in column " << columnsInfo_[colPos].getName()
254 <<
" is repeated. This is not allowed." << __E__;
258 if(colPos != getNumberOfColumns() - 1)
260 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_TIMESTAMP
261 <<
" data type column must be last (in column "
262 << getNumberOfColumns() - 1 <<
")." << __E__;
263 __COUT_ERR__ <<
"\n" << ss.str();
269 __SS__ <<
"Table Error:\t" << TableViewColumnInfo::TYPE_TIMESTAMP
270 <<
" data type column "
271 <<
" is missing. This is not allowed." << __E__;
278 std::set<std::string > uidSet;
279 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
281 if(uidSet.find(theDataView_[row][colUID_]) != uidSet.end())
283 __SS__ << (
"Entries in UID are not unique. Specifically at row=" +
284 std::to_string(row) +
" value=" + theDataView_[row][colUID_])
289 if(theDataView_[row][colUID_].size() == 0)
291 __SS__ <<
"An invalid UID '" << theDataView_[row][colUID_] <<
"' "
292 <<
" was identified. UIDs must contain at least 1 character."
297 for(
unsigned int i = 0; i < theDataView_[row][colUID_].size(); ++i)
298 if(!((theDataView_[row][colUID_][i] >=
'A' &&
299 theDataView_[row][colUID_][i] <=
'Z') ||
300 (theDataView_[row][colUID_][i] >=
'a' &&
301 theDataView_[row][colUID_][i] <=
'z') ||
302 (theDataView_[row][colUID_][i] >=
'0' &&
303 theDataView_[row][colUID_][i] <=
'9') ||
304 (theDataView_[row][colUID_][i] ==
'-' ||
305 theDataView_[row][colUID_][i] <=
'_')))
307 __SS__ <<
"An invalid UID '" << theDataView_[row][colUID_] <<
"' "
308 <<
" was identified. UIDs must contain only letters, numbers,"
309 <<
"dashes, and underscores." << __E__;
313 uidSet.insert(theDataView_[row][colUID_]);
315 if(uidSet.size() != getNumberOfRows())
317 __SS__ <<
"Entries in UID are not unique!"
318 <<
"There are " << getNumberOfRows()
319 <<
" records and the unique UID count is " << uidSet.size() << __E__;
324 colPos = (
unsigned int)-1;
325 while((colPos = findColByType(TableViewColumnInfo::TYPE_UNIQUE_DATA,
326 colPos + 1)) != INVALID)
328 std::set<std::string > uDataSet;
329 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
331 if(uDataSet.find(theDataView_[row][colPos]) != uDataSet.end())
333 __SS__ <<
"Entries in Unique Data column "
334 << columnsInfo_[colPos].getName()
335 << (
" are not unique. Specifically at row=" +
336 std::to_string(row) +
337 " value=" + theDataView_[row][colPos])
341 uDataSet.insert(theDataView_[row][colPos]);
343 if(uDataSet.size() != getNumberOfRows())
345 __SS__ <<
"Entries in Unique Data column "
346 << columnsInfo_[colPos].getName() <<
" are not unique!"
347 <<
"There are " << getNumberOfRows()
348 <<
" records and the unique data count is " << uDataSet.size()
356 colPos = (
unsigned int)-1;
357 while((colPos = findColByType(TableViewColumnInfo::TYPE_UNIQUE_GROUP_DATA,
358 colPos + 1)) != INVALID)
363 for(
unsigned int groupIdColPos = 0; groupIdColPos < columnsInfo_.size();
365 if(columnsInfo_[groupIdColPos].isGroupID())
367 std::map<std::string ,
368 std::pair<
unsigned int ,
369 std::set<std::string > > >
372 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
374 auto groupIds = getSetOfGroupIDs(groupIdColPos, row);
376 for(
const auto& groupId : groupIds)
378 uGroupDataSets[groupId].first++;
380 if(uGroupDataSets[groupId].second.find(
381 theDataView_[row][colPos]) !=
382 uGroupDataSets[groupId].second.end())
384 __SS__ <<
"Entries in Unique Group Data column " << colPos
385 <<
":" << columnsInfo_[colPos].getName()
386 <<
" are not unique for group ID '" << groupId
387 <<
".' Specifically at row=" << std::to_string(row)
388 <<
" value=" << theDataView_[row][colPos] << __E__;
391 uGroupDataSets[groupId].second.insert(
392 theDataView_[row][colPos]);
396 for(
const auto& groupPair : uGroupDataSets)
397 if(uGroupDataSets[groupPair.first].second.size() !=
398 uGroupDataSets[groupPair.first].first)
401 <<
"Entries in Unique Data column "
402 << columnsInfo_[colPos].getName()
403 <<
" are not unique for group '" << groupPair.first
405 <<
"There are " << uGroupDataSets[groupPair.first].first
406 <<
" records and the unique data count is "
407 << uGroupDataSets[groupPair.first].second.size() << __E__;
413 auto rowDefaults = getDefaultRowValues();
420 std::set<std::string> groupIdIndexes, childLinkIndexes, childLinkIdLabels;
421 unsigned int groupIdIndexesCount = 0, childLinkIndexesCount = 0,
422 childLinkIdLabelsCount = 0;
424 std::pair<
unsigned int ,
unsigned int > tmpLinkPair;
426 for(
unsigned int col = 0; col < getNumberOfColumns(); ++col)
428 if(columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA)
430 const std::vector<std::string>& theDataChoices =
431 columnsInfo_[col].getDataChoices();
434 if(theDataChoices.size() && theDataChoices[0] ==
"arbitraryBool=1")
438 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
442 if(theDataView_[row][col] == rowDefaults[col])
445 for(
const auto& choice : theDataChoices)
447 if(theDataView_[row][col] == choice)
455 __SS__ <<
"Table Error:\t'" << theDataView_[row][col]
456 <<
"' in column " << columnsInfo_[col].getName()
457 <<
" is not a valid Fixed Choice option. "
458 <<
"Possible values are as follows: ";
460 for(
unsigned int i = 0;
461 i < columnsInfo_[col].getDataChoices().size();
466 ss << columnsInfo_[col].getDataChoices()[i];
473 else if(columnsInfo_[col].isChildLink())
477 const std::vector<std::string>& theDataChoices =
478 columnsInfo_[col].getDataChoices();
481 if(!theDataChoices.size() || theDataChoices[0] ==
"arbitraryBool=1")
486 (theDataChoices.size() && theDataChoices[0] ==
"arbitraryBool=0");
490 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
495 for(
const auto& choice : theDataChoices)
497 if(skipOne && !hasSkipped)
503 if(theDataView_[row][col] == choice)
511 __SS__ <<
"Table Error:\t'" << theDataView_[row][col]
512 <<
"' in column " << columnsInfo_[col].getName()
513 <<
" is not a valid Fixed Choice option. "
514 <<
"Possible values are as follows: ";
519 for(
unsigned int i = skipOne ? 1 : 0;
520 i < columnsInfo_[col].getDataChoices().size();
523 if(i > (skipOne ? 1 : 0))
525 ss << columnsInfo_[col].getDataChoices()[i];
532 else if(columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_ON_OFF)
533 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
535 if(theDataView_[row][col] ==
"1" || theDataView_[row][col] ==
"on" ||
536 theDataView_[row][col] ==
"On" || theDataView_[row][col] ==
"ON")
537 theDataView_[row][col] = TableViewColumnInfo::TYPE_VALUE_ON;
538 else if(theDataView_[row][col] ==
"0" ||
539 theDataView_[row][col] ==
"off" ||
540 theDataView_[row][col] ==
"Off" ||
541 theDataView_[row][col] ==
"OFF")
542 theDataView_[row][col] = TableViewColumnInfo::TYPE_VALUE_OFF;
545 __SS__ <<
"Table Error:\t" << theDataView_[row][col]
546 <<
" in column " << columnsInfo_[col].getName()
547 <<
" is not a valid Type (On/Off) std::string. Possible "
548 "values are 1, on, On, ON, 0, off, Off, OFF."
553 else if(columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_TRUE_FALSE)
554 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
556 if(theDataView_[row][col] ==
"1" ||
557 theDataView_[row][col] ==
"true" ||
558 theDataView_[row][col] ==
"True" ||
559 theDataView_[row][col] ==
"TRUE")
560 theDataView_[row][col] = TableViewColumnInfo::TYPE_VALUE_TRUE;
561 else if(theDataView_[row][col] ==
"0" ||
562 theDataView_[row][col] ==
"false" ||
563 theDataView_[row][col] ==
"False" ||
564 theDataView_[row][col] ==
"FALSE")
565 theDataView_[row][col] = TableViewColumnInfo::TYPE_VALUE_FALSE;
568 __SS__ <<
"Table Error:\t" << theDataView_[row][col]
569 <<
" in column " << columnsInfo_[col].getName()
570 <<
" is not a valid Type (True/False) std::string. "
571 "Possible values are 1, true, True, TRUE, 0, false, "
577 else if(columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_YES_NO)
578 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
580 if(theDataView_[row][col] ==
"1" || theDataView_[row][col] ==
"yes" ||
581 theDataView_[row][col] ==
"Yes" || theDataView_[row][col] ==
"YES")
582 theDataView_[row][col] = TableViewColumnInfo::TYPE_VALUE_YES;
583 else if(theDataView_[row][col] ==
"0" ||
584 theDataView_[row][col] ==
"no" ||
585 theDataView_[row][col] ==
"No" ||
586 theDataView_[row][col] ==
"NO")
587 theDataView_[row][col] = TableViewColumnInfo::TYPE_VALUE_NO;
590 __SS__ <<
"Table Error:\t" << theDataView_[row][col]
591 <<
" in column " << columnsInfo_[col].getName()
592 <<
" is not a valid Type (Yes/No) std::string. Possible "
593 "values are 1, yes, Yes, YES, 0, no, No, NO."
598 else if(columnsInfo_[col].isGroupID())
600 colLinkGroupIDs_[columnsInfo_[col].getChildLinkIndex()] =
603 groupIdIndexes.emplace(columnsInfo_[col].getChildLinkIndex());
604 ++groupIdIndexesCount;
606 else if(columnsInfo_[col].isChildLink())
609 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
610 if(theDataView_[row][col] ==
"NoLink" ||
611 theDataView_[row][col] ==
"No_Link" ||
612 theDataView_[row][col] ==
"NOLINK" ||
613 theDataView_[row][col] ==
"NO_LINK" ||
614 theDataView_[row][col] ==
"Nolink" ||
615 theDataView_[row][col] ==
"nolink" ||
616 theDataView_[row][col] ==
"noLink")
617 theDataView_[row][col] =
618 TableViewColumnInfo::DATATYPE_LINK_DEFAULT;
621 childLinkIndexes.emplace(columnsInfo_[col].getChildLinkIndex());
622 ++childLinkIndexesCount;
625 if(columnsInfo_[col].getDataType() !=
626 TableViewColumnInfo::DATATYPE_STRING)
628 __SS__ <<
"Table Error:\t"
629 <<
"Column " << col <<
" with name "
630 << columnsInfo_[col].getName()
631 <<
" is a Child Link column and has an illegal data type of '"
632 << columnsInfo_[col].getDataType()
633 <<
"'. The data type for Child Link columns must be "
634 << TableViewColumnInfo::DATATYPE_STRING << __E__;
639 getChildLink(col, tmpIsGroup, tmpLinkPair);
641 else if(columnsInfo_[col].isChildLinkUID() ||
642 columnsInfo_[col].isChildLinkGroupID())
645 childLinkIdLabels.emplace(columnsInfo_[col].getChildLinkIndex());
646 ++childLinkIdLabelsCount;
649 for(
unsigned int row = 0; row < getNumberOfRows(); ++row)
650 if(theDataView_[row][col] ==
"")
651 theDataView_[row][col] = rowDefaults[col];
654 getChildLink(col, tmpIsGroup, tmpLinkPair);
659 if(groupIdIndexes.size() != groupIdIndexesCount)
661 __SS__ << (
"GroupId Labels are not unique!") <<
"There are "
662 << groupIdIndexesCount <<
" GroupId Labels and the unique count is "
663 << groupIdIndexes.size() << __E__;
666 if(childLinkIndexes.size() != childLinkIndexesCount)
668 __SS__ << (
"Child Link Labels are not unique!") <<
"There are "
669 << childLinkIndexesCount
670 <<
" Child Link Labels and the unique count is "
671 << childLinkIndexes.size() << __E__;
674 if(childLinkIdLabels.size() != childLinkIdLabelsCount)
676 __SS__ << (
"Child Link ID Labels are not unique!") <<
"There are "
677 << childLinkIdLabelsCount
678 <<
" Child Link ID Labels and the unique count is "
679 << childLinkIdLabels.size() << __E__;
685 __COUT__ <<
"Error occured in TableView::init() for version=" << version_
696 void TableView::getValue(std::string& value,
699 bool doConvertEnvironmentVariables)
const
701 if(!(col < columnsInfo_.size() && row < getNumberOfRows()))
703 __SS__ <<
"Invalid row col requested" << __E__;
707 value = validateValueForColumn(
708 theDataView_[row][col], col, doConvertEnvironmentVariables);
716 std::string TableView::validateValueForColumn(
const std::string& value,
718 bool doConvertEnvironmentVariables)
const
720 if(col >= columnsInfo_.size())
722 __SS__ <<
"Invalid col requested" << __E__;
726 if(columnsInfo_[col].getDataType() == TableViewColumnInfo::DATATYPE_STRING)
727 return doConvertEnvironmentVariables
728 ? StringMacros::convertEnvironmentVariables(value)
730 else if(columnsInfo_[col].getDataType() == TableViewColumnInfo::DATATYPE_TIME)
732 return StringMacros::getTimestampString(
733 doConvertEnvironmentVariables
734 ? StringMacros::convertEnvironmentVariables(value)
748 __SS__ <<
"\tUnrecognized column data type: " << columnsInfo_[col].getDataType()
749 <<
" in configuration " << tableName_
750 <<
" at column=" << columnsInfo_[col].getName()
751 <<
" for getValue with type '"
752 << StringMacros::demangleTypeName(
typeid(std::string).name()) <<
"'"
764 std::string TableView::getValueAsString(
unsigned int row,
766 bool doConvertEnvironmentVariables)
const
768 if(!(col < columnsInfo_.size() && row < getNumberOfRows()))
770 __SS__ << (
"Invalid row col requested") << __E__;
776 if(columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_ON_OFF)
778 if(theDataView_[row][col] ==
"1" || theDataView_[row][col] ==
"on" ||
779 theDataView_[row][col] ==
"On" || theDataView_[row][col] ==
"ON")
780 return TableViewColumnInfo::TYPE_VALUE_ON;
782 return TableViewColumnInfo::TYPE_VALUE_OFF;
784 else if(columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_TRUE_FALSE)
786 if(theDataView_[row][col] ==
"1" || theDataView_[row][col] ==
"true" ||
787 theDataView_[row][col] ==
"True" || theDataView_[row][col] ==
"TRUE")
788 return TableViewColumnInfo::TYPE_VALUE_TRUE;
790 return TableViewColumnInfo::TYPE_VALUE_FALSE;
792 else if(columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_YES_NO)
794 if(theDataView_[row][col] ==
"1" || theDataView_[row][col] ==
"yes" ||
795 theDataView_[row][col] ==
"Yes" || theDataView_[row][col] ==
"YES")
796 return TableViewColumnInfo::TYPE_VALUE_YES;
798 return TableViewColumnInfo::TYPE_VALUE_NO;
802 return doConvertEnvironmentVariables
803 ? StringMacros::convertEnvironmentVariables(theDataView_[row][col])
804 : theDataView_[row][col];
813 std::string TableView::getEscapedValueAsString(
unsigned int row,
815 bool doConvertEnvironmentVariables)
const
817 std::string val = getValueAsString(row, col, doConvertEnvironmentVariables);
818 std::string retVal =
"";
819 retVal.reserve(val.size());
820 for(
unsigned int i = 0; i < val.size(); ++i)
824 else if(val[i] ==
'\t')
826 else if(val[i] ==
'\r')
831 if(val[i] ==
'"' || val[i] ==
'\\')
842 void TableView::setValue(
const std::string& value,
unsigned int row,
unsigned int col)
844 if(!(col < columnsInfo_.size() && row < getNumberOfRows()))
846 __SS__ <<
"Invalid row (" << row <<
") col (" << col <<
") requested!" << __E__;
850 if(columnsInfo_[col].getDataType() == TableViewColumnInfo::DATATYPE_STRING)
851 theDataView_[row][col] = value;
855 __SS__ <<
"\tUnrecognized column data type: " << columnsInfo_[col].getDataType()
856 <<
" in configuration " << tableName_
857 <<
" at column=" << columnsInfo_[col].getName()
858 <<
" for setValue with type '"
859 << StringMacros::demangleTypeName(
typeid(value).name()) <<
"'" << __E__;
863 void TableView::setValue(
const char* value,
unsigned int row,
unsigned int col)
865 setValue(std::string(value), row, col);
871 void TableView::setValueAsString(
const std::string& value,
875 if(!(col < columnsInfo_.size() && row < getNumberOfRows()))
877 __SS__ <<
"Invalid row (" << row <<
") col (" << col <<
") requested!" << __E__;
881 theDataView_[row][col] = value;
887 const unsigned int TableView::getOrInitColUID(
void)
889 if(colUID_ != INVALID)
893 colUID_ = findColByType(TableViewColumnInfo::TYPE_UID);
894 if(colUID_ == INVALID)
896 __COUT__ <<
"Column Types: " << __E__;
897 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
898 std::cout << columnsInfo_[col].getType() <<
"() "
899 << columnsInfo_[col].getName() << __E__;
900 __SS__ <<
"\tMissing UID Column in table named '" << tableName_ <<
"'" << __E__;
909 const unsigned int TableView::getColUID(
void)
const
911 if(colUID_ != INVALID)
914 __COUT__ <<
"Column Types: " << __E__;
915 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
916 std::cout << columnsInfo_[col].getType() <<
"() " << columnsInfo_[col].getName()
919 __SS__ << (
"Missing UID Column in config named " + tableName_ +
920 ". (Possibly TableView was just not initialized?" +
921 "This is the const call so can not alter class members)")
929 const unsigned int TableView::getOrInitColStatus(
void)
931 if(colStatus_ != INVALID)
935 colStatus_ = findCol(TableViewColumnInfo::COL_NAME_STATUS);
936 if(colStatus_ == INVALID)
938 __SS__ <<
"\tMissing " << TableViewColumnInfo::COL_NAME_STATUS
939 <<
" Column in table named '" << tableName_ <<
"'" << __E__;
940 ss <<
"Column Types: " << __E__;
941 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
942 ss << columnsInfo_[col].getType() <<
"() " << columnsInfo_[col].getName()
953 const unsigned int TableView::getOrInitColPriority(
void)
955 if(colPriority_ != INVALID)
960 findCol(
"*" + TableViewColumnInfo::COL_NAME_PRIORITY);
961 if(colPriority_ == INVALID)
963 __SS__ <<
"\tMissing " << TableViewColumnInfo::COL_NAME_PRIORITY
964 <<
" Column in table named '" << tableName_ <<
"'" << __E__;
965 ss <<
"Column Types: " << __E__;
966 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
967 ss << columnsInfo_[col].getType() <<
"() " << columnsInfo_[col].getName()
979 const unsigned int TableView::getColStatus(
void)
const
981 if(colStatus_ != INVALID)
984 __COUT__ <<
"\n\nTable '" << tableName_ <<
"' Columns: " << __E__;
985 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
986 std::cout <<
"\t" << columnsInfo_[col].getType() <<
"() "
987 << columnsInfo_[col].getName() << __E__;
991 __SS__ <<
"Missing " << TableViewColumnInfo::COL_NAME_STATUS
992 <<
" Column in config named " << tableName_
993 <<
". (Possibly TableView was just not initialized?"
994 <<
"This is the const call so can not alter class members)" << __E__;
1002 const unsigned int TableView::getColPriority(
void)
const
1004 if(colPriority_ != INVALID)
1005 return colPriority_;
1007 __COUT__ <<
"Priority column was not found... \nColumn Types: " << __E__;
1008 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
1009 std::cout <<
"\t" << columnsInfo_[col].getType() <<
"() "
1010 << columnsInfo_[col].getName() << __E__;
1013 __SS__ <<
"Missing " << TableViewColumnInfo::COL_NAME_PRIORITY
1014 <<
" Column in config named " << tableName_
1015 <<
". (The Priority column is identified when TableView is initialized)"
1024 void TableView::addRowToGroup(
1025 const unsigned int& row,
1026 const unsigned int& col,
1027 const std::string& groupID)
1030 if(isEntryInGroupCol(row, col, groupID))
1032 __SS__ <<
"GroupID (" << groupID <<
") added to row (" << row
1033 <<
" is already present!" << __E__;
1042 if(getDataView()[row][col] ==
"" ||
1043 getDataView()[row][col] == getDefaultRowValues()[col])
1044 setValue(groupID, row, col);
1046 setValue(groupID +
" | " + getDataView()[row][col], row, col);
1056 bool TableView::removeRowFromGroup(
const unsigned int& row,
1057 const unsigned int& col,
1058 const std::string& groupNeedle,
1059 bool deleteRowIfNoGroupLeft)
1061 __COUT__ <<
"groupNeedle " << groupNeedle << __E__;
1062 std::set<std::string> groupIDList;
1063 if(!isEntryInGroupCol(row, col, groupNeedle, &groupIDList))
1065 __SS__ <<
"GroupID (" << groupNeedle <<
") removed from row (" << row
1066 <<
") was already removed!" << __E__;
1074 std::string newValue =
"";
1075 unsigned int cnt = 0;
1076 for(
const auto& groupID : groupIDList)
1079 if(groupID == groupNeedle)
1084 newValue += groupID;
1087 bool wasDeleted =
false;
1088 if(deleteRowIfNoGroupLeft && newValue ==
"")
1090 __COUT__ <<
"Delete row since it no longer part of any group." << __E__;
1095 setValue(newValue, row, col);
1108 bool TableView::isEntryInGroup(
const unsigned int& r,
1109 const std::string& childLinkIndex,
1110 const std::string& groupNeedle)
const
1112 unsigned int c = getColLinkGroupID(childLinkIndex);
1114 return isEntryInGroupCol(r, c, groupNeedle);
1126 bool TableView::isEntryInGroupCol(
const unsigned int& r,
1127 const unsigned int& c,
1128 const std::string& groupNeedle,
1129 std::set<std::string>* groupIDList)
const
1138 for(; j < theDataView_[r][c].size(); ++j)
1139 if((theDataView_[r][c][j] ==
' ' ||
1140 theDataView_[r][c][j] ==
'|') &&
1143 else if((theDataView_[r][c][j] ==
1145 theDataView_[r][c][j] ==
'|') &&
1149 groupIDList->emplace(theDataView_[r][c].substr(i, j - i));
1153 if(groupNeedle == theDataView_[r][c].substr(i, j - i))
1166 groupIDList->emplace(theDataView_[r][c].substr(i, j - i));
1170 if(groupNeedle == theDataView_[r][c].substr(i, j - i))
1185 std::set<std::string> TableView::getSetOfGroupIDs(
const std::string& childLinkIndex,
1186 unsigned int r)
const
1188 return getSetOfGroupIDs(getColLinkGroupID(childLinkIndex), r);
1190 std::set<std::string> TableView::getSetOfGroupIDs(
const unsigned int& c,
1191 unsigned int r)
const
1195 std::set<std::string> retSet;
1200 if(r != (
unsigned int)-1)
1202 if(r >= getNumberOfRows())
1204 __SS__ <<
"Invalid row requested!" << __E__;
1208 StringMacros::getSetFromString(theDataView_[r][c], retSet);
1236 for(r = 0; r < getNumberOfRows(); ++r)
1238 StringMacros::getSetFromString(theDataView_[r][c], retSet);
1286 const unsigned int TableView::getColLinkGroupID(
const std::string& childLinkIndex)
const
1288 if(!childLinkIndex.size())
1290 __SS__ <<
"Empty childLinkIndex string parameter!" << __E__;
1294 const char* needleChildLinkIndex = &childLinkIndex[0];
1298 size_t spacePos = childLinkIndex.find(
' ');
1299 if(spacePos != std::string::npos &&
1300 spacePos + 1 < childLinkIndex.size())
1303 needleChildLinkIndex = &childLinkIndex[spacePos + 1];
1306 std::map<std::string, unsigned int>::const_iterator it =
1307 colLinkGroupIDs_.find(needleChildLinkIndex);
1309 colLinkGroupIDs_.end())
1313 <<
"Incompatible table for this group link. Table '" << tableName_
1314 <<
"' is missing a GroupID column with data type '"
1315 << TableViewColumnInfo::TYPE_START_GROUP_ID <<
"-" << needleChildLinkIndex
1317 <<
"Note: you can separate the child GroupID column data type from "
1318 <<
"the parent GroupLink column data type; this is accomplished by using a space "
1319 <<
"character at the parent level - the string after the space will be treated "
1321 <<
"child GroupID column data type." << __E__;
1322 ss <<
"Existing Column GroupIDs: " << __E__;
1323 for(
auto& groupIdColPair : colLinkGroupIDs_)
1324 ss <<
"\t" << groupIdColPair.first <<
" : col-" << groupIdColPair.second << __E__;
1326 ss <<
"Existing Column Types: " << __E__;
1327 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
1328 ss <<
"\t" << columnsInfo_[col].getType() <<
"() " << columnsInfo_[col].getName()
1335 unsigned int TableView::findRow(
unsigned int col,
1336 const std::string& value,
1337 unsigned int offsetRow)
const
1339 for(
unsigned int row = offsetRow; row < theDataView_.size(); ++row)
1341 if(theDataView_[row][col] == value)
1345 __SS__ <<
"\tIn view: " << tableName_ <<
", Can't find value=" << value
1346 <<
" in column named " << columnsInfo_[col].getName()
1347 <<
" with type=" << columnsInfo_[col].getType() << __E__;
1355 unsigned int TableView::findRowInGroup(
unsigned int col,
1356 const std::string& value,
1357 const std::string& groupId,
1358 const std::string& childLinkIndex,
1359 unsigned int offsetRow)
const
1361 unsigned int groupIdCol = getColLinkGroupID(childLinkIndex);
1362 for(
unsigned int row = offsetRow; row < theDataView_.size(); ++row)
1364 if(theDataView_[row][col] == value && isEntryInGroupCol(row, groupIdCol, groupId))
1368 __SS__ <<
"\tIn view: " << tableName_ <<
", Can't find in group the value=" << value
1369 <<
" in column named '" << columnsInfo_[col].getName()
1370 <<
"' with type=" << columnsInfo_[col].getType() <<
" and GroupID: '"
1371 << groupId <<
"' in column '" << groupIdCol
1372 <<
"' with GroupID child link index '" << childLinkIndex <<
"'" << __E__;
1381 unsigned int TableView::findCol(
const std::string& wildCardName)
const
1383 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
1384 if(StringMacros::wildCardMatch(wildCardName ,
1385 columnsInfo_[col].getName() ))
1388 __SS__ <<
"\tIn view: " << tableName_ <<
", Can't find column named '" << wildCardName
1390 ss <<
"Existing columns:\n";
1391 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
1392 ss <<
"\t" << columnsInfo_[col].getName() <<
"\n";
1401 unsigned int TableView::findColByType(
const std::string& type,
int startingCol)
const
1403 for(
unsigned int col = startingCol; col < columnsInfo_.size(); ++col)
1404 if(columnsInfo_[col].getType() == type)
1412 const std::string& TableView::getUniqueStorageIdentifier(
void)
const
1414 return uniqueStorageIdentifier_;
1418 const std::string& TableView::getTableName(
void)
const {
return tableName_; }
1421 const TableVersion& TableView::getVersion(
void)
const {
return version_; }
1424 const std::string& TableView::getComment(
void)
const {
return comment_; }
1427 const std::string& TableView::getAuthor(
void)
const {
return author_; }
1430 const time_t& TableView::getCreationTime(
void)
const {
return creationTime_; }
1433 const time_t& TableView::getLastAccessTime(
void)
const {
return lastAccessTime_; }
1436 const bool& TableView::getLooseColumnMatching(
void)
const
1438 return fillWithLooseColumnMatching_;
1443 const unsigned int TableView::getDataColumnSize(
void)
const
1446 if(!getNumberOfRows())
1447 return getNumberOfColumns();
1448 return theDataView_[0].size();
1454 const unsigned int& TableView::getSourceColumnMismatch(
void)
const
1456 return sourceColumnMismatchCount_;
1462 const unsigned int& TableView::getSourceColumnMissing(
void)
const
1464 return sourceColumnMissingCount_;
1470 const std::set<std::string>& TableView::getSourceColumnNames(
void)
const
1472 return sourceColumnNames_;
1476 std::set<std::string> TableView::getColumnNames(
void)
const
1478 std::set<std::string> retSet;
1479 for(
auto& colInfo : columnsInfo_)
1480 retSet.emplace(colInfo.getName());
1485 std::map<std::string,
unsigned int > TableView::getColumnNamesMap(
void)
const
1487 std::map<std::string,
unsigned int > retMap;
1489 for(
auto& colInfo : columnsInfo_)
1490 retMap.emplace(std::make_pair(colInfo.getName(), c++));
1495 std::set<std::string> TableView::getColumnStorageNames(
void)
const
1497 std::set<std::string> retSet;
1498 for(
auto& colInfo : columnsInfo_)
1499 retSet.emplace(colInfo.getStorageName());
1504 std::vector<std::string> TableView::getDefaultRowValues(
void)
const
1506 std::vector<std::string> retVec;
1509 for(
unsigned int col = 0; col < getNumberOfColumns(); ++col)
1516 if(columnsInfo_[col].isChildLink())
1518 const std::vector<std::string>& theDataChoices =
1519 columnsInfo_[col].getDataChoices();
1522 if(!theDataChoices.size() ||
1523 theDataChoices[0] ==
"arbitraryBool=1")
1524 retVec.push_back(columnsInfo_[col].getDefaultValue());
1528 (theDataChoices.size() && theDataChoices[0] ==
"arbitraryBool=0");
1533 bool foundDefault =
false;
1535 for(
const auto& choice : theDataChoices)
1536 if(skipOne && !hasSkipped)
1541 else if(choice == columnsInfo_[col].getDefaultValue())
1543 foundDefault =
true;
1548 if(!foundDefault && theDataChoices.size() > (skipOne ? 1 : 0))
1549 retVec.push_back(theDataChoices[(skipOne ? 1 : 0)]);
1551 retVec.push_back(columnsInfo_[col].getDefaultValue());
1555 retVec.push_back(columnsInfo_[col].getDefaultValue());
1562 unsigned int TableView::getNumberOfRows(
void)
const {
return theDataView_.size(); }
1565 unsigned int TableView::getNumberOfColumns(
void)
const {
return columnsInfo_.size(); }
1568 const TableView::DataView& TableView::getDataView(
void)
const {
return theDataView_; }
1577 const std::vector<TableViewColumnInfo>& TableView::getColumnsInfo(
void)
const
1579 return columnsInfo_;
1583 std::vector<TableViewColumnInfo>* TableView::getColumnsInfoP(
void)
1585 return &columnsInfo_;
1590 if(column >= columnsInfo_.size())
1592 std::stringstream errMsg;
1593 errMsg << __COUT_HDR_FL__ <<
"\nCan't find column " << column
1594 <<
"\n\n\n\nThe column info is likely missing due to incomplete "
1595 "Configuration View filling.\n\n"
1597 __THROW__(errMsg.str().c_str());
1599 return columnsInfo_[column];
1604 void TableView::setUniqueStorageIdentifier(
const std::string& storageUID)
1606 uniqueStorageIdentifier_ = storageUID;
1610 void TableView::setTableName(
const std::string& name) { tableName_ = name; }
1613 void TableView::setComment(
const std::string& comment) { comment_ = comment; }
1616 void TableView::setURIEncodedComment(
const std::string& uriComment)
1618 comment_ = StringMacros::decodeURIComponent(uriComment);
1622 void TableView::setAuthor(
const std::string& author) { author_ = author; }
1625 void TableView::setCreationTime(time_t t) { creationTime_ = t; }
1628 void TableView::setLastAccessTime(time_t t) { lastAccessTime_ = t; }
1631 void TableView::setLooseColumnMatching(
bool setValue)
1633 fillWithLooseColumnMatching_ = setValue;
1637 void TableView::reset(
void)
1642 columnsInfo_.clear();
1643 theDataView_.clear();
1647 void TableView::print(std::ostream& out)
const
1649 out <<
"============================================================================="
1652 out <<
"Print: " << tableName_ <<
" Version: " << version_ <<
" Comment: " << comment_
1653 <<
" Author: " << author_ <<
" Creation Time: " << ctime(&creationTime_) << __E__;
1654 out <<
"\t\tNumber of Cols " << getNumberOfColumns() << __E__;
1655 out <<
"\t\tNumber of Rows " << getNumberOfRows() << __E__;
1657 out <<
"Columns:\t";
1658 for(
int i = 0; i < (int)columnsInfo_.size(); ++i)
1659 out << i <<
":" << columnsInfo_[i].getName() <<
":"
1660 << columnsInfo_[i].getStorageName() <<
":" << columnsInfo_[i].getType() <<
":"
1661 << columnsInfo_[i].getDataType() <<
"\t ";
1664 out <<
"Rows:" << __E__;
1667 for(
int r = 0; r < (int)getNumberOfRows(); ++r)
1669 out << (int)r <<
":\t";
1670 for(
int c = 0; c < (int)getNumberOfColumns(); ++c)
1672 out << (int)c <<
":";
1675 if(columnsInfo_[c].getType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA)
1677 int choiceIndex = -1;
1678 std::vector<std::string> choices = columnsInfo_[c].getDataChoices();
1679 val = StringMacros::convertEnvironmentVariables(theDataView_[r][c]);
1681 if(val == columnsInfo_[c].getDefaultValue())
1685 for(
int i = 0; i < (int)choices.size(); ++i)
1686 if(val == choices[i])
1687 choiceIndex = i + 1;
1690 out <<
"ChoiceIndex=" << choiceIndex <<
":";
1693 out << theDataView_[r][c];
1713 void TableView::printJSON(std::ostream& out)
const
1716 out <<
"\"NAME\" : \"" << tableName_ <<
"\",\n";
1720 out <<
"\"COMMENT\" : ";
1726 for(
unsigned int i = 0; i < val.size(); ++i)
1730 else if(val[i] ==
'\t')
1732 else if(val[i] ==
'\r')
1737 if(val[i] ==
'"' || val[i] ==
'\\')
1744 out <<
"\"AUTHOR\" : \"" << author_ <<
"\",\n";
1745 out <<
"\"CREATION_TIME\" : " << creationTime_ <<
",\n";
1750 out <<
"\"COL_TYPES\" : {\n";
1751 for(
int c = 0; c < (int)getNumberOfColumns(); ++c)
1753 out <<
"\t\t\"" << columnsInfo_[c].getStorageName() <<
"\" : ";
1754 out <<
"\"" << columnsInfo_[c].getDataType() <<
"\"";
1755 if(c + 1 < (
int)getNumberOfColumns())
1761 out <<
"\"DATA_SET\" : [\n";
1763 for(
int r = 0; r < (int)getNumberOfRows(); ++r)
1766 for(
int c = 0; c < (int)getNumberOfColumns(); ++c)
1768 out <<
"\t\t\"" << columnsInfo_[c].getStorageName() <<
"\" : ";
1770 out <<
"\"" << getEscapedValueAsString(r, c,
false)
1773 if(c + 1 < (
int)getNumberOfColumns())
1778 if(r + 1 < (
int)getNumberOfRows())
1790 std::string restoreJSONStringEntities(
const std::string& str)
1792 unsigned int sz = str.size();
1796 std::stringstream retStr;
1798 for(; i < sz - 1; ++i)
1830 retStr << str[sz - 1];
1832 return retStr.str();
1843 int TableView::fillFromJSON(
const std::string& json)
1845 std::vector<std::string> keys;
1846 keys.push_back(
"NAME");
1847 keys.push_back(
"COMMENT");
1848 keys.push_back(
"AUTHOR");
1849 keys.push_back(
"CREATION_TIME");
1851 keys.push_back(
"DATA_SET");
1855 CV_JSON_FILL_COMMENT,
1856 CV_JSON_FILL_AUTHOR,
1857 CV_JSON_FILL_CREATION_TIME,
1859 CV_JSON_FILL_DATA_SET
1864 sourceColumnMismatchCount_ = 0;
1865 sourceColumnMissingCount_ = 0;
1866 sourceColumnNames_.clear();
1867 unsigned int colFoundCount = 0;
1869 unsigned int row = -1;
1870 unsigned int colSpeedup = 0;
1871 unsigned int startString, startNumber, endNumber = -1;
1872 unsigned int bracketCount = 0;
1873 unsigned int sqBracketCount = 0;
1877 bool isDataArray = 0;
1878 bool keyIsMatch, keyIsComment;
1879 unsigned int keyIsMatchIndex, keyIsMatchStorageIndex, keyIsMatchCommentIndex;
1880 const std::string COMMENT_ALT_KEY =
"COMMENT";
1882 std::string extractedString =
"", currKey =
"", currVal =
"";
1883 unsigned int currDepth;
1885 std::vector<std::string> jsonPath;
1886 std::vector<char> jsonPathType;
1887 char lastPopType =
'_';
1889 unsigned int matchedKey = -1;
1890 unsigned int lastCol = -1;
1893 for(; i < json.size(); ++i)
1898 if(i - 1 < json.size() &&
1899 json[i - 1] ==
'\\')
1902 inQuotes = !inQuotes;
1907 extractedString = restoreJSONStringEntities(
1908 json.substr(startString + 1, i - startString - 1));
1917 if(jsonPathType[jsonPathType.size() - 1] !=
'{' ||
1920 __COUT__ <<
"Invalid ':' position" << __E__;
1925 jsonPathType.push_back(
'K');
1926 jsonPath.push_back(extractedString);
1945 if(lastPopType ==
'{')
1948 if(jsonPathType[jsonPathType.size() - 1] ==
'K')
1951 jsonPath.pop_back();
1952 jsonPathType.pop_back();
1958 currVal = extractedString;
1961 if(endNumber == (
unsigned int)-1 ||
1962 endNumber <= startNumber)
1965 if(endNumber <= startNumber)
1968 currVal = json.substr(startNumber + 1, endNumber - startNumber - 1);
1971 currDepth = bracketCount;
1973 if(jsonPathType[jsonPathType.size() - 1] ==
'K')
1975 currKey = jsonPath[jsonPathType.size() - 1];
1980 jsonPath.pop_back();
1981 jsonPathType.pop_back();
1983 else if(jsonPathType[jsonPathType.size() - 1] ==
1987 for(
unsigned int k = jsonPathType.size() - 2; k < jsonPathType.size();
1989 if(jsonPathType[k] ==
'K')
1991 currKey = jsonPath[k];
1996 __COUT__ <<
"Invalid array position" << __E__;
2005 __COUT__ <<
"Invalid ',' position" << __E__;
2016 jsonPathType.push_back(
'{');
2017 jsonPath.push_back(
"{");
2030 if(lastPopType !=
'{' &&
2031 jsonPathType[jsonPathType.size() - 1] ==
'K')
2033 currDepth = bracketCount;
2034 currKey = jsonPath[jsonPathType.size() - 1];
2036 currVal = extractedString;
2039 if(endNumber == (
unsigned int)-1 ||
2040 endNumber <= startNumber)
2043 if(endNumber <= startNumber)
2047 json.substr(startNumber + 1, endNumber - startNumber - 1);
2051 jsonPath.pop_back();
2052 jsonPathType.pop_back();
2055 if(jsonPathType[jsonPathType.size() - 1] !=
'{')
2057 __COUT__ <<
"Invalid '}' position" << __E__;
2061 jsonPath.pop_back();
2062 jsonPathType.pop_back();
2068 jsonPathType.push_back(
'[');
2069 jsonPath.push_back(
"[");
2078 if(jsonPathType[jsonPathType.size() - 1] !=
'[')
2080 __COUT__ <<
"Invalid ']' position" << __E__;
2084 currDepth = bracketCount;
2088 currVal = extractedString;
2091 if(endNumber == (
unsigned int)-1 ||
2092 endNumber <= startNumber)
2095 if(endNumber <= startNumber)
2098 currVal = json.substr(startNumber + 1, endNumber - startNumber - 1);
2103 for(
unsigned int k = jsonPathType.size() - 2; k < jsonPathType.size(); --k)
2104 if(jsonPathType[k] ==
'K')
2106 currKey = jsonPath[k];
2111 __COUT__ <<
"Invalid array position" << __E__;
2116 if(jsonPathType[jsonPathType.size() - 1] !=
'[')
2118 __COUT__ <<
"Invalid ']' position" << __E__;
2122 jsonPath.pop_back();
2123 jsonPathType.pop_back();
2132 if(startNumber != (
unsigned int)-1 && endNumber == (
unsigned int)-1)
2141 std::cout << i <<
":\t" << json[i] <<
" - ";
2143 std::cout <<
"ExtKey=";
2144 for(
unsigned int k = 0; k < jsonPath.size(); ++k)
2145 std::cout << jsonPath[k] <<
"/";
2147 std::cout << lastPopType <<
" ";
2148 std::cout << bracketCount <<
" ";
2149 std::cout << sqBracketCount <<
" ";
2150 std::cout << inQuotes <<
" ";
2151 std::cout << newValue <<
"-";
2152 std::cout << currKey <<
"-{" << currDepth <<
"}:";
2153 std::cout << currVal <<
" ";
2154 std::cout << startNumber <<
"-";
2155 std::cout << endNumber <<
" ";
2185 for(
unsigned int k = 0; k < keys.size(); ++k)
2186 if((currDepth == 1 && keys[k] == currKey) ||
2187 (currDepth > 1 && keys[k] == jsonPath[1]))
2190 if(matchedKey != (
unsigned int)-1)
2197 case CV_JSON_FILL_NAME:
2199 setTableName(currVal);
2201 case CV_JSON_FILL_COMMENT:
2203 setComment(currVal);
2205 case CV_JSON_FILL_AUTHOR:
2209 case CV_JSON_FILL_CREATION_TIME:
2211 setCreationTime(strtol(currVal.c_str(), 0, 10));
2216 case CV_JSON_FILL_DATA_SET:
2228 unsigned int col, ccnt = 0;
2229 unsigned int noc = getNumberOfColumns();
2230 for(; ccnt < noc; ++ccnt)
2236 if(fillWithLooseColumnMatching_)
2249 if(getNumberOfRows() == 1)
2250 sourceColumnNames_.emplace(currKey);
2254 if(row >= getNumberOfRows())
2256 __SS__ <<
"Invalid row"
2258 std::cout << ss.str();
2263 theDataView_[row][col] =
2271 col = (ccnt + colSpeedup) % noc;
2277 keyIsComment =
true;
2278 for(keyIsMatchIndex = 0,
2279 keyIsMatchStorageIndex = 0,
2280 keyIsMatchCommentIndex = 0;
2281 keyIsMatchIndex < currKey.size();
2284 if(columnsInfo_[col]
2285 .getStorageName()[keyIsMatchStorageIndex] ==
2287 ++keyIsMatchStorageIndex;
2289 if(currKey[keyIsMatchIndex] ==
'_')
2293 if(keyIsMatchStorageIndex >=
2294 columnsInfo_[col].getStorageName().size() ||
2295 currKey[keyIsMatchIndex] !=
2297 .getStorageName()[keyIsMatchStorageIndex])
2307 keyIsMatchCommentIndex < COMMENT_ALT_KEY.size())
2309 if(currKey[keyIsMatchIndex] !=
2310 COMMENT_ALT_KEY[keyIsMatchCommentIndex])
2313 keyIsComment =
false;
2317 ++keyIsMatchStorageIndex;
2328 if(getNumberOfRows())
2329 sourceColumnMissingCount_ +=
2330 getNumberOfColumns() - colFoundCount;
2338 if(getNumberOfRows() == 1)
2339 sourceColumnNames_.emplace(currKey);
2343 if(row >= getNumberOfRows())
2345 __SS__ <<
"Invalid row"
2347 __COUT__ <<
"\n" << ss.str();
2352 theDataView_[row][col] = currVal;
2362 if(ccnt >= getNumberOfColumns())
2365 <<
"\n\nInvalid column in JSON source data: " << currKey
2366 <<
" not found in column names of table named "
2367 << getTableName() <<
"."
2369 __COUT__ <<
"\n" << ss.str();
2372 ++sourceColumnMismatchCount_;
2373 if(getNumberOfRows() == 1)
2374 sourceColumnNames_.emplace(currKey);
2378 <<
"Ignoring error, and not populating missing column."
2406 bool TableView::isURIEncodedCommentTheSame(
const std::string& comment)
const
2408 std::string compareStr = StringMacros::decodeURIComponent(comment);
2409 return comment_ == compareStr;
2468 int TableView::fillFromCSV(
const std::string& data,
2469 const int& dataOffset,
2470 const std::string& author)
2478 int j = data.find(
',', i);
2479 int k = data.find(
';', i);
2481 bool rowWasModified;
2482 unsigned int countRowsModified = 0;
2483 int authorCol = findColByType(TableViewColumnInfo::TYPE_AUTHOR);
2484 int timestampCol = findColByType(TableViewColumnInfo::TYPE_TIMESTAMP);
2487 while(k != (
int)(std::string::npos))
2489 rowWasModified =
false;
2490 if(r >= (
int)getNumberOfRows())
2494 rowWasModified =
true;
2497 while(j < k && j != (
int)(std::string::npos))
2502 if(c >= (
int)getNumberOfColumns() - 2)
2505 j = data.find(
',', i);
2510 if(setURIEncodedValue(data.substr(i, j - i), r, c))
2511 rowWasModified =
true;
2514 j = data.find(
',', i);
2519 if(author !=
"" && rowWasModified)
2521 __COUT__ <<
"Row=" << (int)r <<
" was modified!" << __E__;
2522 setValue(author, r, authorCol);
2523 setValue(time(0), r, timestampCol);
2527 ++countRowsModified;
2533 j = data.find(
',', i);
2534 k = data.find(
';', i);
2538 while(r < (
int)getNumberOfRows())
2541 __COUT__ <<
"Row deleted: " << (int)r << __E__;
2542 ++countRowsModified;
2545 __COUT_INFO__ <<
"countRowsModified=" << countRowsModified << __E__;
2547 if(!countRowsModified)
2552 bool match = getColumnStorageNames().size() == getSourceColumnNames().size();
2555 for(
auto& destColName : getColumnStorageNames())
2556 if(getSourceColumnNames().find(destColName) ==
2557 getSourceColumnNames().end())
2559 __COUT__ <<
"Found column name mismach for '" << destColName
2560 <<
"'... So allowing same data!" << __E__;
2569 __SS__ <<
"No rows were modified! No reason to fill a view with same content."
2571 __COUT__ <<
"\n" << ss.str();
2581 sourceColumnNames_.clear();
2582 for(
unsigned int i = 0; i < getNumberOfColumns(); ++i)
2583 sourceColumnNames_.emplace(getColumnsInfo()[i].getStorageName());
2604 bool TableView::setURIEncodedValue(
const std::string& value,
2605 const unsigned int& r,
2606 const unsigned int& c,
2607 const std::string& author)
2609 if(!(c < columnsInfo_.size() && r < getNumberOfRows()))
2611 __SS__ <<
"Invalid row (" << (int)r <<
") col (" << (
int)c << ") requested!"
2612 << "Number of Rows = " << getNumberOfRows()
2613 << "Number of Columns = " << columnsInfo_.size() << __E__;
2618 std::
string valueStr =
StringMacros::decodeURIComponent(value);
2619 std::
string originalValueStr =
2620 getValueAsString(r, c, false);
2628 std::string convertedString = StringMacros::convertEnvironmentVariables(valueStr);
2643 theDataView_[r][c] = valueStr;
2645 else if(columnsInfo_[c].getDataType() == TableViewColumnInfo::DATATYPE_TIME)
2657 setValue(time_t(strtol(valueStr.c_str(), 0, 10)), r, c);
2660 theDataView_[r][c] = valueStr;
2662 bool rowWasModified =
2663 (originalValueStr !=
2664 getValueAsString(r, c,
false));
2667 if(author !=
"" && rowWasModified)
2669 __COUT__ <<
"Row=" << (int)r <<
" was modified!" << __E__;
2670 int authorCol = findColByType(TableViewColumnInfo::TYPE_AUTHOR);
2671 int timestampCol = findColByType(TableViewColumnInfo::TYPE_TIMESTAMP);
2672 setValue(author, r, authorCol);
2673 setValue(time(0), r, timestampCol);
2676 return rowWasModified;
2680 void TableView::resizeDataView(
unsigned int nRows,
unsigned int nCols)
2684 theDataView_.resize(nRows, std::vector<std::string>(nCols));
2694 unsigned int TableView::addRow(
const std::string& author,
2695 bool incrementUniqueData,
2696 std::string baseNameAutoUID,
2697 unsigned int rowToAdd)
2700 if(rowToAdd == (
unsigned int)-1)
2701 rowToAdd = getNumberOfRows();
2703 theDataView_.resize(getNumberOfRows() + 1,
2704 std::vector<std::string>(getNumberOfColumns()));
2707 for(
unsigned int r = getNumberOfRows() - 2; r >= rowToAdd; --r)
2709 if(r == (
unsigned int)-1)
2711 for(
unsigned int col = 0; col < getNumberOfColumns(); ++col)
2712 theDataView_[r + 1][col] = theDataView_[r][col];
2715 std::vector<std::string> defaultRowValues = getDefaultRowValues();
2717 char indexString[1000];
2718 std::string tmpString, baseString;
2721 unsigned int maxUniqueData;
2722 std::string numString;
2727 for(
unsigned int col = 0; col < getNumberOfColumns(); ++col)
2734 if(incrementUniqueData &&
2735 (col == getColUID() ||
2736 (getNumberOfRows() > 1 &&
2737 (columnsInfo_[col].getType() == TableViewColumnInfo::TYPE_UNIQUE_DATA ||
2738 columnsInfo_[col].getType() ==
2739 TableViewColumnInfo::TYPE_UNIQUE_GROUP_DATA))))
2755 for(
unsigned int r = 0; r < getNumberOfRows(); ++r)
2763 tmpString = theDataView_[r][col];
2767 for(index = tmpString.length() - 1; index < tmpString.length(); --index)
2771 if(!(tmpString[index] >=
'0' && tmpString[index] <=
'9'))
2778 if(tmpString.length() && foundAny)
2781 numString = tmpString.substr(index + 1);
2782 tmpString = tmpString.substr(0, index + 1);
2789 sscanf(numString.c_str(),
"%u", &index);
2791 if(index > maxUniqueData)
2793 maxUniqueData = index;
2794 baseString = tmpString;
2801 sprintf(indexString,
"%u", maxUniqueData);
2805 if(col == getColUID())
2808 if(baseNameAutoUID !=
"")
2809 theDataView_[rowToAdd][col] = baseNameAutoUID + indexString;
2811 theDataView_[rowToAdd][col] = baseString + indexString;
2814 theDataView_[rowToAdd][col] = baseString + indexString;
2816 __COUT__ <<
"New unique data entry is data[" << rowToAdd <<
"][" << col
2817 <<
"] = '" << theDataView_[rowToAdd][col] <<
"'" << __E__;
2822 theDataView_[rowToAdd][col] = defaultRowValues[col];
2827 __COUT__ <<
"Row=" << rowToAdd <<
" was created!" << __E__;
2828 int authorCol = findColByType(TableViewColumnInfo::TYPE_AUTHOR);
2829 int timestampCol = findColByType(TableViewColumnInfo::TYPE_TIMESTAMP);
2830 setValue(author, rowToAdd, authorCol);
2831 setValue(time(0), rowToAdd, timestampCol);
2840 void TableView::deleteRow(
int r)
2842 if(r >= (
int)getNumberOfRows())
2845 __SS__ <<
"Row " << (int)r
2846 <<
" is out of bounds (Row Count = " << getNumberOfRows()
2847 <<
") and can not be deleted." << __E__;
2851 theDataView_.erase(theDataView_.begin() + r);
2870 const bool TableView::getChildLink(
2871 const unsigned int& c,
2873 std::pair<unsigned int /*link col*/, unsigned int /*link id col*/>& linkPair)
const
2875 if(!(c < columnsInfo_.size()))
2877 __SS__ <<
"Invalid col (" << (int)c <<
") requested!" << __E__;
2885 if((isGroup = columnsInfo_[c].isChildLinkGroupID()) ||
2886 columnsInfo_[c].isChildLinkUID())
2890 linkPair.second = c;
2891 std::string index = columnsInfo_[c].getChildLinkIndex();
2896 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
2902 else if(columnsInfo_[col].isChildLink() &&
2903 index == columnsInfo_[col].getChildLinkIndex())
2908 linkPair.first = col;
2914 __SS__ <<
"\tIn view: " << tableName_
2915 <<
", Can't find complete child link for column name "
2916 << columnsInfo_[c].getName() << __E__;
2920 if(!columnsInfo_[c].isChildLink())
2925 std::string index = columnsInfo_[c].getChildLinkIndex();
2930 for(
unsigned int col = 0; col < columnsInfo_.size(); ++col)
2947 if(((columnsInfo_[col].isChildLinkUID() && !(isGroup =
false)) ||
2948 (columnsInfo_[col].isChildLinkGroupID() && (isGroup =
true))) &&
2949 index == columnsInfo_[col].getChildLinkIndex())
2954 linkPair.second = col;
2960 __SS__ <<
"\tIn view: " << tableName_
2961 <<
", Can't find complete child link id for column name "
2962 << columnsInfo_[c].getName() << __E__;