1 #include "otsdaq/ConfigurationInterface/ConfigurationTree.h"
5 #include "otsdaq/ConfigurationInterface/ConfigurationManager.h"
6 #include "otsdaq/Macros/StringMacros.h"
7 #include "otsdaq/TableCore/TableBase.h"
12 #define __MF_SUBJECT__ "ConfigurationTree"
14 const std::string ConfigurationTree::DISCONNECTED_VALUE =
"X";
15 const std::string ConfigurationTree::VALUE_TYPE_DISCONNECTED =
"Disconnected";
16 const std::string ConfigurationTree::VALUE_TYPE_NODE =
"Node";
17 const std::string ConfigurationTree::ROOT_NAME =
"/";
29 , disconnectedTargetName_(
"")
30 , disconnectedLinkID_(
"")
66 const std::string& groupId,
68 const std::string& linkColName,
69 const std::string& linkColValue,
70 const unsigned int linkBackRow,
71 const unsigned int linkBackCol,
72 const std::string& disconnectedTargetName,
73 const std::string& disconnectedLinkID,
74 const std::string& childLinkIndex,
75 const unsigned int row,
76 const unsigned int col)
77 : configMgr_(configMgr)
80 , linkParentTable_(linkParentConfig)
81 , linkColName_(linkColName)
82 , linkColValue_(linkColValue)
83 , linkBackRow_(linkBackRow)
84 , linkBackCol_(linkBackCol)
85 , disconnectedTargetName_(disconnectedTargetName)
86 , disconnectedLinkID_(disconnectedLinkID)
87 , childLinkIndex_(childLinkIndex)
94 __SS__ <<
"Invalid empty pointer given to tree!\n"
95 <<
"\n\tconfigMgr_=" << configMgr_ <<
"\n\tconfiguration_=" << table_
96 <<
"\n\tconfigView_=" << tableView_ << __E__;
103 tableView_ = &(table_->getView());
106 if(tableView_ && tableView_->getColumnInfo(tableView_->
getColUID()).getType() !=
109 __SS__ <<
"Missing UID column (must column of type "
111 <<
") in config view : " << tableView_->getTableName() << __E__;
133 recursivePrint(*
this, depth, out,
"\t");
166 out << space <<
"{" << __E__;
168 recursivePrint(c.second, depth - 1, out, space +
" ");
170 out << space <<
"}" << __E__;
176 std::string ConfigurationTree::handleValidateValueForColumn(
184 __SS__ <<
"Null configView" << __E__;
189 __COUT__ <<
"handleValidateValueForColumn<string>" << __E__;
202 if(row_ != TableView::INVALID &&
203 col_ != TableView::INVALID)
210 __COUT__ <<
"Success following path to tree node!" << __E__;
221 __COUT__ <<
"Successful value!" << __E__;
235 tableView_->
getValue(value, row_, col_);
237 else if(row_ == TableView::INVALID &&
238 col_ == TableView::INVALID)
245 value = (groupId_ ==
"") ? table_->
getTableName() : groupId_;
247 else if(row_ == TableView::INVALID)
249 __SS__ <<
"Malformed ConfigurationTree" << __E__;
252 else if(col_ == TableView::INVALID)
256 __SS__ <<
"Impossible." << __E__;
310 if(row_ != TableView::INVALID &&
311 col_ != TableView::INVALID)
313 std::string bitmapString;
314 tableView_->
getValue(bitmapString, row_, col_);
316 __COUTV__(bitmapString);
317 if(bitmapString == TableViewColumnInfo::DATATYPE_STRING_DEFAULT)
319 bitmap.isDefault_ =
true;
323 bitmap.isDefault_ =
false;
327 bitmap.bitmap_.clear();
329 bool openRow =
false;
330 unsigned int startInt = -1;
331 for(
unsigned int i = 0; i < bitmapString.length(); i++)
333 __COUTV__(bitmapString[i]);
341 if(bitmapString[i] ==
'[')
345 bitmap.bitmap_.push_back(std::vector<uint64_t>());
347 else if(bitmapString[i] ==
']')
351 else if(bitmapString[i] ==
',')
355 <<
"Too many ']' or ',' characters in bit map configuration"
362 else if(startInt == (
unsigned int)-1)
364 if(bitmapString[i] ==
']')
369 else if(bitmapString[i] >=
'0' &&
370 bitmapString[i] <=
'9')
374 else if(bitmapString[i] ==
',')
376 __SS__ <<
"Too many ',' characters in bit map configuration"
387 if(bitmapString[i] ==
391 bitmap.bitmap_[row].push_back(strtoul(
392 bitmapString.substr(startInt, i - startInt).c_str(), 0, 0));
395 else if(bitmapString[i] ==
',')
397 bitmap.bitmap_[row].push_back(strtoul(
398 bitmapString.substr(startInt, i - startInt).c_str(), 0, 0));
404 for(
unsigned int r = 0; r < bitmap.bitmap_.size(); ++r)
406 for(
unsigned int c = 0; c < bitmap.bitmap_[r].size(); ++c)
408 __COUT__ << r <<
"," << c <<
" = " << bitmap.bitmap_[r][c] << __E__;
410 __COUT__ <<
"================" << __E__;
416 __SS__ <<
"Requesting getValue must be on a value node." << __E__;
439 if(row_ != TableView::INVALID &&
440 col_ != TableView::INVALID)
443 __SS__ <<
"Can not get escaped value except from a value node!"
444 <<
" This node is type '" << getNodeType() <<
"." << __E__;
456 __SS__ <<
"Can not get configuration name of node with no configuration pointer! "
457 <<
"Is there a broken link? " << __E__;
460 ss <<
"Error occurred traversing from " << linkParentTable_->
getTableName()
463 linkBackRow_, linkParentTable_->getView().
getColUID())
464 <<
"' at row " << linkBackRow_ <<
" col '"
465 << linkParentTable_->getView().getColumnInfo(linkBackCol_).getName()
483 __SS__ <<
"Can not get parent table name of node with no parent table pointer! "
484 <<
"Was this node initialized correctly? " << __E__;
495 __SS__ <<
"Can only get row from a UID or value node!" << __E__;
498 ss <<
"Error occurred traversing from " << linkParentTable_->
getTableName()
501 linkBackRow_, linkParentTable_->getView().
getColUID())
502 <<
"' at row " << linkBackRow_ <<
" col '"
503 << linkParentTable_->getView().getColumnInfo(linkBackCol_).getName() <<
".'"
523 if(!linkParentTable_)
525 __SS__ <<
"Can not get configuration name of link node field with no parent "
526 "configuration pointer!"
542 return disconnectedTargetName_;
544 __SS__ <<
"Can not get disconnected target name of node unless it is a disconnected "
557 return disconnectedLinkID_;
559 __SS__ <<
"Can not get disconnected target name of node unless it is a disconnected "
573 __SS__ <<
"Can not get configuration version of node with no config view pointer!"
579 return tableView_->getVersion();
588 __SS__ <<
"Can not get configuration creation time of node with no config view "
595 return tableView_->getCreationTime();
605 __SS__ <<
"Can not get set of group IDs of node with value type of '"
606 << getNodeType() <<
".' Node must be a GroupID node." << __E__;
622 if(
getValueType() != TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA &&
625 __SS__ <<
"Can not get fixed choices of node with value type of '"
626 <<
getValueType() <<
".' Node must be a link or a value node with type '"
627 << TableViewColumnInfo::TYPE_BITMAP_DATA <<
"' or '"
628 << TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA <<
".'" << __E__;
634 std::vector<std::string> retVec;
638 if(!linkParentTable_)
641 <<
"Can not get fixed choices of node with no parent config view pointer!"
654 const TableView* parentView = &(linkParentTable_->getView());
655 int c = parentView->
findCol(linkColName_);
657 std::pair<
unsigned int ,
unsigned int > linkPair;
662 std::vector<std::string> choices = parentView->getColumnInfo(c).getDataChoices();
663 for(
const auto& choice : choices)
664 retVec.push_back(choice);
671 __SS__ <<
"Can not get fixed choices of node with no config view pointer!"
679 retVec.push_back(tableView_->getColumnInfo(col_).getDefaultValue());
680 std::vector<std::string> choices = tableView_->getColumnInfo(col_).getDataChoices();
681 for(
const auto& choice : choices)
682 retVec.push_back(choice);
692 ? TableViewColumnInfo::DATATYPE_COMMENT_DEFAULT
717 if(returnLinkTableValue)
718 return linkColValue_;
720 return ConfigurationTree::DISCONNECTED_VALUE;
721 else if(row_ == TableView::INVALID &&
722 col_ == TableView::INVALID)
723 return (groupId_ ==
"") ? table_->
getTableName() : groupId_;
724 else if(col_ == TableView::INVALID)
725 return tableView_->getDataView()[row_][tableView_->
getColUID()];
728 __SS__ <<
"Impossible Link." << __E__;
734 else if(row_ != TableView::INVALID &&
735 col_ != TableView::INVALID)
736 return tableView_->getDataView()[row_][col_];
737 else if(row_ == TableView::INVALID &&
738 col_ == TableView::INVALID)
742 return ConfigurationTree::ROOT_NAME;
744 return (groupId_ ==
"") ? table_->
getTableName() : groupId_;
746 else if(row_ == TableView::INVALID)
748 __SS__ <<
"Malformed ConfigurationTree" << __E__;
753 else if(col_ == TableView::INVALID)
754 return tableView_->getDataView()[row_][tableView_->
getColUID()];
757 __SS__ <<
"Impossible." << __E__;
771 return tableView_->getDataView()[row_][tableView_->
getColUID()];
774 __SS__ <<
"Can not get UID of node with type '" << getNodeType()
775 <<
".' Node type must be '" << ConfigurationTree::NODE_TYPE_VALUE
776 <<
"' or '" << ConfigurationTree::NODE_TYPE_UID_LINK <<
".'" << __E__;
789 return tableView_->getColumnInfo(col_).getDataType();
791 return TableViewColumnInfo::DATATYPE_STRING;
804 if(
getValueType() == TableViewColumnInfo::TYPE_ON_OFF ||
805 getValueType() == TableViewColumnInfo::TYPE_TRUE_FALSE ||
808 TableViewColumnInfo::DATATYPE_BOOL_DEFAULT;
810 else if(
getValueType() == TableViewColumnInfo::TYPE_COMMENT)
811 return getValueAsString() == TableViewColumnInfo::DATATYPE_COMMENT_DEFAULT ||
833 __SS__ <<
"Can only get default value from a value node! "
834 <<
"The node type is " << getNodeType() << __E__;
842 if(
getValueType() == TableViewColumnInfo::TYPE_ON_OFF ||
843 getValueType() == TableViewColumnInfo::TYPE_TRUE_FALSE ||
845 return TableViewColumnInfo::DATATYPE_BOOL_DEFAULT;
847 else if(
getValueType() == TableViewColumnInfo::TYPE_COMMENT)
848 return TableViewColumnInfo::
849 DATATYPE_COMMENT_DEFAULT;
851 return TableViewColumnInfo::DATATYPE_STRING_DEFAULT;
854 return TableViewColumnInfo::DATATYPE_NUMBER_DEFAULT;
856 return TableViewColumnInfo::DATATYPE_TIME_DEFAULT;
859 __SS__ <<
"Can only get default value from a value node! "
860 <<
"The node type is " << getNodeType() << __E__;
873 return tableView_->getColumnInfo(col_).getType();
875 return ConfigurationTree::VALUE_TYPE_DISCONNECTED;
877 return ConfigurationTree::VALUE_TYPE_NODE;
886 return tableView_->getColumnInfo(col_);
889 __SS__ <<
"Can only get column info from a value node! "
890 <<
"The node type is " << getNodeType() << __E__;
939 __SS__ <<
"Can only get link ID from a link! "
940 <<
"The node type is " << getNodeType() << __E__;
945 return childLinkIndex_;
954 return tableView_->getColumnInfo(col_).getName();
959 __SS__ <<
"Can only get value name of a value node!" << __E__;
970 const std::string& childPath,
971 bool doNotThrowOnBrokenUIDLinks,
972 const std::string& originalNodeString)
974 __COUT_TYPE__(TLVL_DEBUG + 50)
975 << __COUT_HDR__ << tree.row_ <<
" " << tree.col_ << __E__;
976 __COUT_TYPE__(TLVL_DEBUG + 51) << __COUT_HDR__ <<
"childPath=" << childPath <<
" "
977 << childPath.length() << __E__;
978 if(childPath.length() <= 1)
980 return tree.recursiveGetNode(
981 childPath, doNotThrowOnBrokenUIDLinks, originalNodeString);
995 bool doNotThrowOnBrokenUIDLinks)
const
998 return recursiveGetNode(
999 nodeString, doNotThrowOnBrokenUIDLinks,
"" );
1002 const std::string& nodeString,
1003 bool doNotThrowOnBrokenUIDLinks,
1004 const std::string& originalNodeString)
const
1006 __COUT_TYPE__(TLVL_DEBUG + 51) << __COUT_HDR__ <<
"nodeString=" << nodeString
1007 <<
" len=" << nodeString.length() << __E__;
1008 __COUT_TYPE__(TLVL_DEBUG + 52)
1009 << __COUT_HDR__ <<
"doNotThrowOnBrokenUIDLinks=" << doNotThrowOnBrokenUIDLinks
1013 if(nodeString.length() < 1)
1015 __SS__ <<
"Invalid empty node name! Looking for child node '" << nodeString
1016 <<
"' from node '" <<
getValue() <<
"'..." << __E__;
1023 size_t startingIndex = 0;
1024 while(startingIndex < nodeString.length() && nodeString[startingIndex] ==
'/')
1026 size_t endingIndex = nodeString.find(
'/', startingIndex);
1027 if(endingIndex == std::string::npos)
1028 endingIndex = nodeString.length();
1030 std::string nodeName = nodeString.substr(startingIndex, endingIndex - startingIndex);
1031 __COUT_TYPE__(TLVL_DEBUG + 51) << __COUT_HDR__ <<
"nodeName=" << nodeName
1032 <<
" len=" << nodeName.length() << __E__;
1035 std::string childPath =
1036 (endingIndex >= nodeString.length() ?
"" : nodeString.substr(endingIndex));
1037 __COUT_TYPE__(TLVL_DEBUG + 51)
1038 << __COUT_HDR__ <<
"childPath=" << childPath <<
" len=" << childPath.length()
1039 <<
" endingIndex=" << endingIndex
1040 <<
" nodeString.length()=" << nodeString.length() << __E__;
1046 __COUT_TYPE__(TLVL_DEBUG + 50) << __COUT_HDR__ << row_ <<
" " << col_ <<
" "
1047 << groupId_ <<
" " << tableView_ << __E__;
1052 return recurse(configMgr_->
getNode(nodeName),
1054 doNotThrowOnBrokenUIDLinks,
1055 originalNodeString);
1057 else if(row_ == TableView::INVALID && col_ == TableView::INVALID)
1063 __SS__ <<
"Missing configView pointer! Likely attempting to access a "
1064 "child node through a disconnected link node."
1080 TableView::INVALID ,
1081 TableView::INVALID ,
1093 doNotThrowOnBrokenUIDLinks,
1094 originalNodeString);
1096 else if(row_ == TableView::INVALID)
1098 __SS__ <<
"Malformed ConfigurationTree" << __E__;
1103 else if(col_ == TableView::INVALID)
1108 __COUT_TYPE__(TLVL_DEBUG + 51) << __COUT_HDR__ <<
"nodeName=" << nodeName
1109 <<
" " << nodeName.length() << __E__;
1119 __SS__ <<
"Missing configView pointer! Likely attempting to access a "
1120 "child node through a disconnected link node."
1127 unsigned int c = tableView_->
findCol(nodeName);
1128 std::pair<
unsigned int ,
unsigned int > linkPair;
1129 bool isGroupLink, isLink;
1130 if((isLink = tableView_->
getChildLink(c, isGroupLink, linkPair)) &&
1133 __COUT_TYPE__(TLVL_DEBUG + 50) << __COUT_HDR__ <<
"nodeName=" << nodeName
1134 <<
" " << nodeName.length() << __E__;
1143 tableView_->getDataView()[row_][linkPair.first]);
1144 childConfig->getView();
1146 if(doNotThrowOnBrokenUIDLinks)
1148 childConfig->getView().
findRow(
1150 tableView_->getDataView()[row_][linkPair.second]);
1155 __COUT_TYPE__(TLVL_DEBUG + 50)
1156 << __COUT_HDR__ <<
"Found disconnected node! (" << nodeName <<
":"
1157 << tableView_->getDataView()[row_][linkPair.first] <<
")"
1158 <<
" at entry with UID "
1159 << tableView_->getDataView()[row_][tableView_->
getColUID()]
1168 tableView_->getDataView()[row_][c],
1173 tableView_->getDataView()[row_][linkPair.first],
1176 tableView_->getDataView()[row_][linkPair.second],
1189 tableView_->getDataView()[row_][c],
1197 childConfig->getView().
findRow(
1199 tableView_->getDataView()[row_][linkPair.second])),
1201 doNotThrowOnBrokenUIDLinks,
1202 originalNodeString);
1206 __COUT_TYPE__(TLVL_DEBUG + 50) << __COUT_HDR__ <<
"nodeName=" << nodeName
1207 <<
" " << nodeName.length() << __E__;
1216 tableView_->getDataView()[row_][linkPair.first]);
1217 childConfig->getView();
1221 if(tableView_->getDataView()[row_][linkPair.first] !=
1222 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
1224 <<
"Found disconnected node! Failed link target "
1226 << nodeName <<
" to table:id="
1227 << tableView_->getDataView()[row_][linkPair.first] <<
":"
1228 << tableView_->getDataView()[row_][linkPair.second] << __E__;
1234 tableView_->getDataView()[row_][linkPair.second],
1237 tableView_->getDataView()[row_][c],
1242 tableView_->getDataView()[row_][linkPair.first],
1245 tableView_->getDataView()[row_][linkPair.second],
1256 ->getDataView()[row_][linkPair.second],
1259 tableView_->getDataView()[row_][c],
1268 doNotThrowOnBrokenUIDLinks,
1269 originalNodeString);
1273 __COUT_TYPE__(TLVL_DEBUG + 50) << __COUT_HDR__ <<
"nodeName=" << nodeName
1274 <<
" " << nodeName.length() << __E__;
1282 TableView::INVALID ,
1283 TableView::INVALID ,
1292 catch(std::runtime_error& e)
1294 __SS__ <<
"\n\nError occurred descending from node '" <<
getValue()
1295 <<
"' in table '" <<
getTableName() <<
"' looking for child '" << nodeName
1298 ss <<
"The original node search string was '" << originalNodeString <<
".'"
1300 ss <<
"--- Additional error detail: \n\n" << e.what() << __E__;
1307 __SS__ <<
"\n\nError occurred descending from node '" <<
getValue()
1308 <<
"' in table '" <<
getTableName() <<
"' looking for child '" << nodeName
1311 ss <<
"The original node search string was '" << originalNodeString <<
".'"
1317 catch(
const std::exception& e)
1319 ss <<
"Exception message: " << e.what();
1330 <<
"\n\nError occurred descending from node '" <<
getValue() <<
"' in table '"
1331 <<
getTableName() <<
"' looking for child '" << nodeName <<
"'\n\n"
1332 <<
"Invalid depth! getNode() called from a value point in the Configuration Tree."
1334 ss <<
"The original node search string was '" << originalNodeString <<
".'" << __E__;
1343 const std::string& nodeString)
const
1345 if(nodeString.length() < 1)
1357 __SS__ << __E__ << __E__;
1359 ss <<
"Row=" << (int)row_ <<
", Col=" << (
int)col_ <<
", TablePointer=" << table_
1371 ss <<
"ConfigurationTree::nodeDump() "
1372 "=====================================\nConfigurationTree::nodeDump():"
1379 <<
"Node dump initiated from node '" <<
getValueAsString() <<
"'..." << __E__;
1387 <<
"Node dump initiated from node '" <<
getValue() <<
"' in table '"
1401 <<
"Here is the list of possible children (count = " << children.size()
1403 for(
auto& child : children)
1404 ss <<
"\t\t" << child << __E__;
1407 ss <<
"\n\nHere is the culprit table printout:\n\n";
1408 tableView_->print(ss);
1416 ss <<
"\n\nend ConfigurationTree::nodeDump() ====================================="
1424 unsigned int backSteps)
const
1426 for(
unsigned int i = 0; i < backSteps; i++)
1427 nodeName = nodeName.substr(0, nodeName.find_last_of(
'/'));
1434 unsigned int forwardSteps)
const
1439 while(s < nodeName.length() && nodeName[s] ==
'/')
1442 for(
unsigned int i = 0; i < forwardSteps; i++)
1443 s = nodeName.find(
'/', s) + 1;
1445 return getNode(nodeName.substr(0, s));
1453 return (row_ != TableView::INVALID && col_ != TableView::INVALID);
1481 __SS__ <<
"\n\nError occurred testing link connection at node with value '"
1484 ss <<
"This is not a Link node! It is node type '" << getNodeType()
1485 <<
".' Only a Link node can be disconnected." << __E__;
1491 return !table_ || !tableView_;
1503 const std::string ConfigurationTree::NODE_TYPE_TABLE =
"TableNode";
1504 const std::string ConfigurationTree::NODE_TYPE_GROUP_LINK =
"GroupLinkNode";
1505 const std::string ConfigurationTree::NODE_TYPE_UID_LINK =
"UIDLinkNode";
1506 const std::string ConfigurationTree::NODE_TYPE_VALUE =
"ValueNode";
1507 const std::string ConfigurationTree::NODE_TYPE_UID =
"UIDNode";
1508 const std::string ConfigurationTree::NODE_TYPE_ROOT =
"RootNode";
1510 std::string ConfigurationTree::getNodeType(
void)
const
1513 return ConfigurationTree::NODE_TYPE_ROOT;
1514 if(isTableNode() && groupId_ !=
"")
1517 return ConfigurationTree::NODE_TYPE_TABLE;
1519 return ConfigurationTree::NODE_TYPE_GROUP_LINK;
1521 return ConfigurationTree::NODE_TYPE_UID_LINK;
1523 return ConfigurationTree::NODE_TYPE_VALUE;
1524 return ConfigurationTree::NODE_TYPE_UID;
1556 return (row_ != TableView::INVALID && col_ == TableView::INVALID);
1576 const std::vector<std::string /*uid*/>& recordList,
1577 const std::vector<std::string /*relative-path*/>& fieldAcceptList,
1578 const std::vector<std::string /*relative-path*/>& fieldRejectList,
1580 bool autoSelectFilterFields)
const
1583 if(!isRootNode() && !isTableNode())
1585 __SS__ <<
"Can only get getCommonFields from a root or table node! "
1586 <<
"The node type is " << getNodeType() << __E__;
1592 std::vector<ConfigurationTree::RecordField> fieldCandidateList;
1593 std::vector<int> fieldCount;
1637 if(!recordList.size() && tableView_)
1639 const std::vector<TableViewColumnInfo>& colInfo = tableView_->getColumnsInfo();
1641 for(
unsigned int col = 0; col < colInfo.size(); ++col)
1643 __COUT_TYPE__(TLVL_DEBUG + 11) << __COUT_HDR__ <<
"Considering field "
1644 << colInfo[col].getName() << __E__;
1647 found = fieldAcceptList.size() ? false :
true;
1649 for(
const auto& fieldFilter : fieldAcceptList)
1661 for(
const auto& fieldFilter : fieldRejectList)
1672 __COUT_TYPE__(TLVL_DEBUG + 11)
1673 << __COUT_HDR__ <<
"FOUND field " << colInfo[col].getName() << __E__;
1675 if(colInfo[col].isChildLink())
1677 __COUT_TYPE__(TLVL_DEBUG + 11) << __COUT_HDR__ <<
"isGroupLinkNode "
1678 << colInfo[col].getName() << __E__;
1682 std::pair<
unsigned int ,
unsigned int >
1692 tableView_->getColumnInfo(linkPair.first).getName(),
1694 &tableView_->getColumnInfo(linkPair.first)));
1695 fieldCount.push_back(-1);
1700 tableView_->getColumnInfo(linkPair.second).getName(),
1702 &tableView_->getColumnInfo(linkPair.second)));
1703 fieldCount.push_back(-1);
1710 colInfo[col].getName(),
1713 fieldCount.push_back(1);
1719 for(
unsigned int i = 0; i < recordList.size(); ++i)
1721 __COUT_TYPE__(TLVL_DEBUG + 11)
1722 << __COUT_HDR__ <<
"Checking " << recordList[i] << __E__;
1725 node.recursiveGetCommonFields(fieldCandidateList,
1736 __COUT__ <<
"======================= check for count = " << (int)recordList.size()
1741 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1743 __COUT_TYPE__(TLVL_DEBUG + 11)
1744 << __COUT_HDR__ <<
"Checking " << fieldCandidateList[i].relativePath_
1745 << fieldCandidateList[i].columnName_ <<
" = " << fieldCount[i] << __E__;
1746 if(recordList.size() != 0 && fieldCount[i] != -1 &&
1747 fieldCount[i] != (
int)recordList.size())
1749 __COUT_TYPE__(TLVL_DEBUG + 11)
1750 << __COUT_HDR__ <<
"Erasing " << fieldCandidateList[i].relativePath_
1751 << fieldCandidateList[i].columnName_ << __E__;
1753 fieldCount.erase(fieldCount.begin() + i);
1754 fieldCandidateList.erase(fieldCandidateList.begin() + i);
1759 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1760 __COUT_TYPE__(TLVL_DEBUG + 11)
1761 << __COUT_HDR__ <<
"Pre-Final " << fieldCandidateList[i].relativePath_
1762 << fieldCandidateList[i].columnName_ << __E__;
1764 if(autoSelectFilterFields)
1768 std::set<std::pair<
unsigned int ,
unsigned int >>
1771 unsigned int priorityPenalty;
1772 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1774 __COUT_TYPE__(TLVL_DEBUG + 11)
1775 << __COUT_HDR__ <<
"Option [" << i <<
"] "
1776 << fieldCandidateList[i].relativePath_
1777 << fieldCandidateList[i].columnName_ <<
" : "
1778 << fieldCandidateList[i].columnInfo_->getType() <<
":"
1779 << fieldCandidateList[i].columnInfo_->getDataType() << __E__;
1781 priorityPenalty = std::count(fieldCandidateList[i].relativePath_.begin(),
1782 fieldCandidateList[i].relativePath_.end(),
1786 if(fieldCandidateList[i].columnInfo_->isBoolType() &&
1787 (fieldCandidateList[i].columnName_ ==
1788 TableViewColumnInfo::COL_NAME_STATUS ||
1789 fieldCandidateList[i].columnName_ ==
1790 TableViewColumnInfo::COL_NAME_ENABLED))
1792 priorityPenalty += 0;
1794 else if(fieldCandidateList[i].columnInfo_->isGroupID())
1796 priorityPenalty += 1;
1798 else if(fieldCandidateList[i].columnInfo_->isBoolType())
1800 priorityPenalty += 3;
1802 else if(fieldCandidateList[i].columnInfo_->getType() ==
1803 TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA)
1805 priorityPenalty += 3;
1807 else if(fieldCandidateList[i].columnInfo_->getType() ==
1808 TableViewColumnInfo::TYPE_DATA)
1810 priorityPenalty += 10;
1814 fieldCandidateList[i].tableName_ =
1818 prioritySet.emplace(
1819 std::make_pair(priorityPenalty , i ));
1820 __COUT_TYPE__(TLVL_DEBUG + 11)
1821 << __COUT_HDR__ <<
"Option [" << i <<
"] "
1822 << fieldCandidateList[i].relativePath_
1823 << fieldCandidateList[i].columnName_ <<
" : "
1824 << fieldCandidateList[i].columnInfo_->getType() <<
":"
1825 << fieldCandidateList[i].columnInfo_->getDataType()
1826 <<
"... priority = " << priorityPenalty << __E__;
1835 unsigned int cnt = 0;
1836 for(
const auto& priorityFieldIndex : prioritySet)
1839 __COUT_TYPE__(TLVL_DEBUG + 11)
1840 << __COUT_HDR__ << cnt <<
" marking "
1841 << fieldCandidateList[priorityFieldIndex.second].relativePath_
1842 << fieldCandidateList[priorityFieldIndex.second].columnName_
1844 fieldCandidateList[priorityFieldIndex.second].tableName_ =
1849 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1851 if(fieldCandidateList[i].tableName_ ==
"")
1853 __COUT_TYPE__(TLVL_DEBUG + 11)
1854 << __COUT_HDR__ <<
"Erasing " << fieldCandidateList[i].relativePath_
1855 << fieldCandidateList[i].columnName_ << __E__;
1856 fieldCandidateList.erase(fieldCandidateList.begin() + i);
1862 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1863 __COUT__ <<
"Final " << fieldCandidateList[i].relativePath_
1864 << fieldCandidateList[i].columnName_ << __E__;
1866 return fieldCandidateList;
1876 const std::vector<std::string /*relative-path*/>& recordList,
1877 const std::string& fieldName,
1878 std::string* fieldGroupIDChildLinkIndex )
const
1880 if(fieldGroupIDChildLinkIndex)
1881 *fieldGroupIDChildLinkIndex =
"";
1886 __SS__ <<
"Can only get getCommonFields from a table node! "
1887 <<
"The node type is " << getNodeType() << __E__;
1893 std::set<std::string > uniqueValues;
1901 if(!recordList.size() && tableView_ && fieldGroupIDChildLinkIndex)
1904 tableView_->getColumnInfo(tableView_->
findCol(fieldName));
1911 for(
unsigned int i = 0; i < recordList.size(); ++i)
1931 if(i == 0 && fieldGroupIDChildLinkIndex)
1937 for(
auto& groupID : setOfGroupIDs)
1938 uniqueValues.emplace(groupID);
1945 return uniqueValues;
1951 void ConfigurationTree::recursiveGetCommonFields(
1952 std::vector<ConfigurationTree::RecordField>& fieldCandidateList,
1953 std::vector<int>& fieldCount,
1954 const std::vector<std::string /*relative-path*/>& fieldAcceptList,
1955 const std::vector<std::string /*relative-path*/>& fieldRejectList,
1957 const std::string& relativePathBase,
1958 bool inFirstRecord)
const
1991 for(
const auto& fieldNode : recordChildren)
1997 if(fieldNode.second.isValueNode() || fieldNode.second.isGroupLinkNode())
2000 if(fieldNode.second.isValueNode())
2002 if(fieldNode.second.getColumnInfo().getType() ==
2003 TableViewColumnInfo::TYPE_AUTHOR ||
2004 fieldNode.second.getColumnInfo().getType() ==
2005 TableViewColumnInfo::TYPE_TIMESTAMP)
2018 found = fieldAcceptList.size() ? false :
true;
2020 for(
const auto& fieldFilter : fieldAcceptList)
2021 if(fieldFilter.find(
'/') != std::string::npos)
2025 fieldFilter, relativePathBase + fieldNode.first))
2042 for(
const auto& fieldFilter : fieldRejectList)
2043 if(fieldFilter.find(
'/') != std::string::npos)
2047 fieldFilter, relativePathBase + fieldNode.first))
2066 if(fieldNode.second.isGroupLinkNode())
2072 std::pair<
unsigned int ,
unsigned int >
2076 tableView_->
findCol(fieldNode.first), isGroupLink, linkPair);
2083 tableView_->getColumnInfo(linkPair.first).getName(),
2085 &tableView_->getColumnInfo(linkPair.first)));
2086 fieldCount.push_back(1);
2091 tableView_->getColumnInfo(linkPair.second).getName(),
2093 &tableView_->getColumnInfo(linkPair.second)));
2094 fieldCount.push_back(1);
2103 &fieldNode.second.getColumnInfo()));
2104 fieldCount.push_back(1);
2112 for(j = 0; j < fieldCandidateList.size(); ++j)
2114 if((relativePathBase + fieldNode.first) ==
2115 (fieldCandidateList[j].relativePath_ +
2116 fieldCandidateList[j].columnName_))
2122 if(fieldNode.second.isGroupLinkNode() &&
2123 j + 1 < fieldCandidateList.size())
2124 ++fieldCount[j + 1];
2130 else if(fieldNode.second.isUIDLinkNode())
2139 fieldAcceptList.size() ? false :
true;
2140 for(
const auto& fieldFilter : fieldAcceptList)
2141 if(fieldFilter.find(
'/') != std::string::npos)
2145 fieldFilter, relativePathBase + fieldNode.first))
2162 for(
const auto& fieldFilter : fieldRejectList)
2163 if(fieldFilter.find(
'/') != std::string::npos)
2167 fieldFilter, relativePathBase + fieldNode.first))
2185 std::pair<
unsigned int ,
unsigned int >
2191 tableView_->
findCol(fieldNode.first), isGroupLink, linkPair);
2198 tableView_->getColumnInfo(linkPair.first).getName(),
2200 &tableView_->getColumnInfo(linkPair.first)));
2201 fieldCount.push_back(1);
2206 tableView_->getColumnInfo(linkPair.second).getName(),
2208 &tableView_->getColumnInfo(linkPair.second)));
2209 fieldCount.push_back(1);
2216 for(j = 0; j < fieldCandidateList.size() - 1; ++j)
2218 if((relativePathBase + fieldNode.first) ==
2219 (fieldCandidateList[j].relativePath_ +
2220 fieldCandidateList[j].columnName_))
2226 ++fieldCount[j + 1];
2233 if(depth > 0 && !fieldNode.second.isDisconnected())
2234 fieldNode.second.recursiveGetCommonFields(
2240 (relativePathBase + fieldNode.first) +
"/",
2253 std::vector<std::vector<std::pair<std::string, ConfigurationTree>>>
2255 std::map<std::string /*relative-path*/, std::string /*value*/> filterMap,
2256 bool onlyStatusTrue)
const
2258 std::vector<std::vector<std::pair<std::string, ConfigurationTree>>> retVector;
2262 bool filtering = filterMap.size();
2263 std::string fieldValue;
2265 bool createContainer;
2267 std::vector<std::vector<std::string>> childrenNamesByPriority =
2270 for(
auto& childNamesAtPriority : childrenNamesByPriority)
2272 createContainer =
true;
2274 for(
auto& childName : childNamesAtPriority)
2284 retVector.push_back(
2285 std::vector<std::pair<std::string, ConfigurationTree>>());
2286 createContainer =
false;
2289 retVector[retVector.size() - 1].push_back(
2290 std::pair<std::string, ConfigurationTree>(
2291 childName, this->
getNode(childName,
true)));
2303 const std::string& childName,
2304 std::map<std::string /*relative-path*/, std::string /*value*/> filterMap)
const
2310 for(
const auto& filterPair : filterMap)
2312 std::string filterPath = childName +
"/" + filterPair.first;
2313 __COUTV__(filterPath);
2319 std::vector<std::string> fieldValues;
2321 filterPair.second, fieldValues, std::set<char>({
','}) );
2323 __COUTV__(fieldValues.size());
2327 for(
const auto& fieldValue : fieldValues)
2341 bool groupIdFound =
false;
2344 for(
auto& groupID : setOfGroupIDs)
2346 __COUT__ <<
"\t\tGroupID Check: " << filterPair.first
2347 <<
" == " << fieldValue <<
" => "
2349 <<
" ??? " << groupID << __E__;
2355 __COUT__ <<
"Found match" << __E__;
2356 groupIdFound =
true;
2364 __COUT__ <<
"Found break match" << __E__;
2371 __COUT__ <<
"\t\tCheck: " << filterPair.first <<
" == " << fieldValue
2388 __SS__ <<
"Failed to access filter path '" << filterPath <<
"' - aborting."
2412 std::map<std::string /*relative-path*/, std::string /*value*/> filterMap,
2414 bool onlyStatusTrue)
const
2416 std::vector<std::pair<std::string, ConfigurationTree>> retVector;
2420 bool filtering = filterMap.size();
2422 std::string fieldValue;
2424 std::vector<std::string> childrenNames =
getChildrenNames(byPriority, onlyStatusTrue);
2425 for(
auto& childName : childrenNames)
2431 retVector.push_back(std::pair<std::string, ConfigurationTree>(
2432 childName, this->
getNode(childName,
true)));
2444 std::map<std::string /*relative-path*/, std::string /*value*/> filterMap,
2445 bool onlyStatusTrue)
const
2447 std::map<std::string, ConfigurationTree> retMap;
2449 bool filtering = filterMap.size();
2452 std::vector<std::string> childrenNames =
2454 for(
auto& childName : childrenNames)
2462 retMap.insert(std::pair<std::string, ConfigurationTree>(
2463 childName, this->
getNode(childName)));
2477 <<
".' Can only check the status of a UID/Record node!" << __E__;
2482 bool tmpStatus =
true;
2487 catch(
const std::runtime_error& e)
2496 bool ConfigurationTree::isStatusNode(
void)
const
2508 bool onlyStatusTrue)
const
2510 std::vector<std::vector<std::string >> retVector;
2515 <<
"' with null configuration view pointer!" << __E__;
2524 if(row_ == TableView::INVALID && col_ == TableView::INVALID)
2531 std::vector<std::vector<
unsigned int >> groupRowsByPriority =
2534 ? TableView::INVALID
2541 for(
const auto& priorityChildRowVector : groupRowsByPriority)
2543 retVector.push_back(std::vector<std::string /*child name*/>());
2544 for(
const auto& priorityChildRow : priorityChildRowVector)
2545 retVector[retVector.size() - 1].push_back(
2546 tableView_->getDataView()[priorityChildRow][tableView_->
getColUID()]);
2549 else if(row_ == TableView::INVALID)
2551 __SS__ <<
"Malformed ConfigurationTree" << __E__;
2556 else if(col_ == TableView::INVALID)
2561 for(
unsigned int c = 0; c < tableView_->getNumberOfColumns(); ++c)
2569 retVector.push_back(std::vector<std::string /*child name*/>());
2570 retVector[retVector.size() - 1].push_back(
2571 tableView_->getColumnInfo(c).getName());
2577 __SS__ <<
"\n\nError occurred looking for children of nodeName=" <<
getValueName()
2579 <<
"Invalid depth! getChildrenValues() called from a value point in the "
2580 "Configuration Tree."
2594 bool onlyStatusTrue)
const
2596 std::vector<std::string > retVector;
2604 retVector.push_back(configPair.first);
2611 __SS__ <<
"Can not get children names of '" <<
getFieldName() <<
":"
2620 if(row_ == TableView::INVALID && col_ == TableView::INVALID)
2624 std::vector<
unsigned int > groupRows = tableView_->
getGroupRows(
2626 ? TableView::INVALID
2634 for(
const auto& groupRow : groupRows)
2635 retVector.push_back(
2636 tableView_->getDataView()[groupRow][tableView_->
getColUID()]);
2703 else if(row_ == TableView::INVALID)
2705 __SS__ <<
"Malformed ConfigurationTree" << __E__;
2710 else if(col_ == TableView::INVALID)
2715 for(
unsigned int c = 0; c < tableView_->getNumberOfColumns(); ++c)
2722 retVector.push_back(tableView_->getColumnInfo(c).getName());
2727 __SS__ <<
"\n\nError occurred looking for children of nodeName=" <<
getValueName()
2729 <<
"Invalid depth! getChildrenValues() called from a value point in the "
2730 "Configuration Tree."
2751 __SS__ <<
"Invalid node for get value." << __E__;
2755 std::string valueString =
2758 if(valueString.size() && valueString[0] ==
'/')
2765 __COUT__ <<
"Found a valid tree path in value!" << __E__;
2770 __SS__ <<
"Invalid tree path." << __E__;
2776 __SS__ <<
"Invalid value string '" << valueString
2777 <<
"' - must start with a '/' character." << __E__;
std::map< std::string, TableVersion > getActiveVersions(void) const
getActiveVersions
ConfigurationTree getNode(const std::string &nodeString, bool doNotThrowOnBrokenUIDLinks=false) const
"root/parent/parent/"
const TableBase * getTableByName(const std::string &configurationName) const
const unsigned int & getRow(void) const
getRow
const std::string & getValueDataType(void) const
bool isUIDNode(void) const
std::map< std::string, ConfigurationTree > getNodes(const std::string &nodeString) const
getNodes
const TableVersion & getTableVersion(void) const
getTableVersion
bool isDisconnected(void) const
const std::string & getAuthor(void) const
getAuthor
ConfigurationTree::BitMap getValueAsBitMap(void) const
const std::string & getComment(void) const
getComment
std::vector< std::string > getChildrenNames(bool byPriority=false, bool onlyStatusTrue=false) const
bool isEnabled(void) const
same as status()
static const std::string NODE_TYPE_GROUP_TABLE
bool isValueNumberDataType(void) const
ConfigurationTree getNode(const std::string &nodeName, bool doNotThrowOnBrokenUIDLinks=false) const
navigating between nodes
const std::string & getTableName(void) const
getTableName
T getValueWithDefault(const T &defaultValue) const
const unsigned int & getFieldRow(void) const
std::map< std::string, ConfigurationTree > getChildrenMap(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool onlyStatusTrue=false) const
const std::string & getValueName(void) const
const std::string & getValueAsString(bool returnLinkTableValue=false) const
const std::string & getChildLinkIndex(void) const
getChildLinkIndex
void print(const unsigned int &depth=-1, std::ostream &out=std::cout) const
bool isGroupIDNode(void) const
const std::string & getDisconnectedTableName(void) const
getDisconnectedTableName
bool isValueBoolType(void) const
std::vector< std::pair< std::string, ConfigurationTree > > getChildren(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool byPriority=false, bool onlyStatusTrue=false) const
std::vector< std::string > getFixedChoices(void) const
bool isLinkNode(void) const
const std::string & getDefaultValue(void) const
const time_t & getTableCreationTime(void) const
getTableCreationTime
const std::string & getUIDAsString(void) const
std::vector< ConfigurationTree::RecordField > getCommonFields(const std::vector< std::string > &recordList, const std::vector< std::string > &fieldAcceptList, const std::vector< std::string > &fieldRejectList, unsigned int depth=-1, bool autoSelectFilterFields=false) const
const unsigned int & getNodeRow(void) const
getNodeRow
std::set< std::string > getSetOfGroupIDs(void) const
bool isValueNode(void) const
const std::string & getFieldName(void) const
alias for getValueName
std::vector< std::vector< std::string > > getChildrenNamesByPriority(bool onlyStatusTrue=false) const
std::set< std::string > getUniqueValuesForField(const std::vector< std::string > &recordList, const std::string &fieldName, std::string *fieldGroupIDChildLinkIndex=0) const
const std::string & getValueType(void) const
bool passFilterMap(const std::string &childName, std::map< std::string, std::string > filterMap) const
std::string nodeDump(void) const
used for debugging (when throwing exception)
~ConfigurationTree(void)
destructor
bool isGroupLinkNode(void) const
const std::string & getFieldTableName(void) const
const unsigned int & getColumn(void) const
getColumn
const std::string & getDisconnectedLinkID(void) const
getDisconnectedLinkID
const std::string & getParentTableName(void) const
getParentTableName
bool isUIDLinkNode(void) const
std::string getEscapedValue(void) const
const TableViewColumnInfo & getColumnInfo(void) const
bool isDefaultValue(void) const
boolean info
std::vector< std::vector< std::pair< std::string, ConfigurationTree > > > getChildrenByPriority(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool onlyStatusTrue=false) const
T getValue(void) const
defined in included .icc source
const unsigned int & getFieldColumn(void) const
const std::string & getTableName(void) const
Getters.
bool isChildLinkUID(void) const
static const std::string DATATYPE_NUMBER
std::string getChildLinkIndex(void) const
getChildLinkIndex
bool isGroupID(void) const
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...
bool isBoolType(void) const
TODO check if min and max values need a function called getallminmaxforgui or something like that for...
bool isNumberDataType(void) const
isNumberDataType
bool isChildLinkGroupID(void) const
unsigned int findRow(unsigned int col, const T &value, unsigned int offsetRow=0, bool doNotThrow=false) const
< in included .icc source
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
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
bool getChildLink(const unsigned int &col, bool &isGroup, std::pair< unsigned int, unsigned int > &linkPair) const
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
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 getColUID(void) const
unsigned int findCol(const std::string &name) const
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
extracting information from a list of records
static void getVectorFromString(const std::string &inputString, std::vector< std::string > &listToReturn, const std::set< char > &delimiter={',', '|', '&'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'}, std::vector< char > *listOfDelimiters=0, bool decodeURIComponents=false)
static std::string setToString(const std::set< T > &setToReturn, const std::string &delimeter=", ")
setToString ~
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)