otsdaq  v2_04_02
TableViewColumnInfo.cc
1 #include "otsdaq/TableCore/TableViewColumnInfo.h"
2 
3 #include "otsdaq/Macros/CoutMacros.h"
4 #include "otsdaq/Macros/StringMacros.h"
5 
6 #include <iostream>
7 #include <sstream>
8 #include <stdexcept>
9 
10 #include "otsdaq/TableCore/TableView.h"
11 
12 using namespace ots;
13 
14 // NOTE: Do NOT put '-' in static const TYPEs because it will mess up javascript handling
15 // in the web gui
16 const std::string TableViewColumnInfo::TYPE_UID = "UID";
17 
18 const std::string TableViewColumnInfo::TYPE_DATA = "Data";
19 const std::string TableViewColumnInfo::TYPE_UNIQUE_DATA = "UniqueData";
20 const std::string TableViewColumnInfo::TYPE_UNIQUE_GROUP_DATA = "UniqueGroupData";
21 const std::string TableViewColumnInfo::TYPE_MULTILINE_DATA = "MultilineData";
22 const std::string TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA = "FixedChoiceData";
23 const std::string TableViewColumnInfo::TYPE_BITMAP_DATA = "BitMap";
24 
25 const std::string TableViewColumnInfo::TYPE_ON_OFF = "OnOff";
26 const std::string TableViewColumnInfo::TYPE_TRUE_FALSE = "TrueFalse";
27 const std::string TableViewColumnInfo::TYPE_YES_NO = "YesNo";
28 
29 const std::string TableViewColumnInfo::TYPE_START_CHILD_LINK = "ChildLink";
30 const std::string TableViewColumnInfo::TYPE_START_CHILD_LINK_UID = "ChildLinkUID";
31 const std::string TableViewColumnInfo::TYPE_START_CHILD_LINK_GROUP_ID =
32  "ChildLinkGroupID";
33 const std::string TableViewColumnInfo::TYPE_START_GROUP_ID = "GroupID";
34 const std::string TableViewColumnInfo::TYPE_COMMENT = "Comment";
35 const std::string TableViewColumnInfo::TYPE_AUTHOR = "Author";
36 const std::string TableViewColumnInfo::TYPE_TIMESTAMP = "Timestamp";
37 // NOTE: Do NOT put '-' in static const TYPEs because it will mess up javascript handling
38 // in the web gui
39 
40 const std::string TableViewColumnInfo::DATATYPE_NUMBER = "NUMBER";
41 const std::string TableViewColumnInfo::DATATYPE_STRING = "VARCHAR2";
42 const std::string TableViewColumnInfo::DATATYPE_TIME = "TIMESTAMP WITH TIMEZONE";
43 
44 const std::string TableViewColumnInfo::TYPE_VALUE_YES = "Yes";
45 const std::string TableViewColumnInfo::TYPE_VALUE_NO = "No";
46 const std::string TableViewColumnInfo::TYPE_VALUE_TRUE = "True";
47 const std::string TableViewColumnInfo::TYPE_VALUE_FALSE = "False";
48 const std::string TableViewColumnInfo::TYPE_VALUE_ON = "On";
49 const std::string TableViewColumnInfo::TYPE_VALUE_OFF = "Off";
50 
51 const std::string TableViewColumnInfo::DATATYPE_STRING_DEFAULT = "DEFAULT";
52 const std::string TableViewColumnInfo::DATATYPE_COMMENT_DEFAULT = "No Comment";
53 const std::string TableViewColumnInfo::DATATYPE_BOOL_DEFAULT = "0";
54 const std::string TableViewColumnInfo::DATATYPE_NUMBER_DEFAULT = "0";
55 const std::string TableViewColumnInfo::DATATYPE_TIME_DEFAULT = "0";
56 const std::string TableViewColumnInfo::DATATYPE_LINK_DEFAULT = "NO_LINK";
57 
58 const std::string TableViewColumnInfo::COL_NAME_STATUS = "Status";
59 const std::string TableViewColumnInfo::COL_NAME_ENABLED = "Enabled";
60 const std::string TableViewColumnInfo::COL_NAME_PRIORITY = "Priority";
61 const std::string TableViewColumnInfo::COL_NAME_COMMENT = "CommentDescription";
62 
63 //==============================================================================
64 // TableViewColumnInfo
65 // if(capturedExceptionString) *capturedExceptionString = ""; //indicates no error found
66 // if(!capturedExceptionString) then exception is thrown on error
67 TableViewColumnInfo::TableViewColumnInfo(const std::string& type,
68  const std::string& name,
69  const std::string& storageName,
70  const std::string& dataType,
71  const std::string& dataChoicesCSV,
72  std::string* capturedExceptionString)
73  : type_(type)
74  , name_(name)
75  , storageName_(storageName)
76  , dataType_(dataType)
77  , bitMapInfoP_(0)
78 {
79  // verify type
80  if((type_ != TYPE_UID) && (type_ != TYPE_DATA) && (type_ != TYPE_UNIQUE_DATA) &&
81  (type_ != TYPE_UNIQUE_GROUP_DATA) && (type_ != TYPE_MULTILINE_DATA) &&
82  (type_ != TYPE_FIXED_CHOICE_DATA) && (type_ != TYPE_BITMAP_DATA) &&
83  (type_ != TYPE_ON_OFF) && (type_ != TYPE_TRUE_FALSE) && (type_ != TYPE_YES_NO) &&
84  (type_ != TYPE_COMMENT) && (type_ != TYPE_AUTHOR) && (type_ != TYPE_TIMESTAMP) &&
85  !isChildLink() && !isChildLinkUID() && !isChildLinkGroupID() && !isGroupID())
86  {
87  __SS__ << "The type for column " << name_ << " is " << type_
88  << ", while the only accepted types are: " << TYPE_DATA << " "
89  << TYPE_UNIQUE_DATA << " " << TYPE_UNIQUE_GROUP_DATA << " "
90  << TYPE_MULTILINE_DATA << " " << TYPE_FIXED_CHOICE_DATA << " " << TYPE_UID
91  << " " << TYPE_ON_OFF << " " << TYPE_TRUE_FALSE << " " << TYPE_YES_NO
92  << " " << TYPE_START_CHILD_LINK << "-* " << TYPE_START_CHILD_LINK_UID
93  << "-* " << TYPE_START_CHILD_LINK_GROUP_ID << "-* " << TYPE_START_GROUP_ID
94  << "-* " << std::endl;
95  if(capturedExceptionString)
96  *capturedExceptionString = ss.str();
97  else
98  __SS_THROW__;
99  }
100  else if(capturedExceptionString)
101  *capturedExceptionString = ""; // indicates no error found
102 
103  // enforce that type only
104  // allows letters, numbers, dash, underscore
105  for(unsigned int i = 0; i < type_.size(); ++i)
106  if(!((type_[i] >= 'A' && type_[i] <= 'Z') ||
107  (type_[i] >= 'a' && type_[i] <= 'z') ||
108  (type_[i] >= '0' && type_[i] <= '9') ||
109  (type_[i] == '-' || type_[i] <= '_' || type_[i] <= '.')))
110  {
111  __SS__ << "The data type for column " << name_ << " is '" << type_
112  << "'. Data types must contain only letters, numbers,"
113  << "dashes, underscores, and periods." << std::endl;
114  if(capturedExceptionString)
115  *capturedExceptionString += ss.str();
116  else
117  __SS_THROW__;
118  }
119 
120  // verify data type
121  if((dataType_ != DATATYPE_NUMBER) && (dataType_ != DATATYPE_STRING) &&
122  (dataType_ != DATATYPE_TIME))
123  {
124  __SS__ << "The data type for column " << name_ << " is " << dataType_
125  << ", while the only accepted types are: " << DATATYPE_NUMBER << " "
126  << DATATYPE_STRING << " " << DATATYPE_TIME << std::endl;
127  if(capturedExceptionString)
128  *capturedExceptionString += ss.str();
129  else
130  __SS_THROW__;
131  }
132 
133  if(dataType_.size() == 0)
134  {
135  __SS__ << "The data type for column " << name_ << " is '" << dataType_
136  << "'. Data types must contain at least 1 character." << std::endl;
137  if(capturedExceptionString)
138  *capturedExceptionString += ss.str();
139  else
140  __SS_THROW__;
141  }
142 
143  // enforce that data type only
144  // allows letters, numbers, dash, underscore
145  for(unsigned int i = 0; i < dataType_.size(); ++i)
146  if(!((dataType_[i] >= 'A' && dataType_[i] <= 'Z') ||
147  (dataType_[i] >= 'a' && dataType_[i] <= 'z') ||
148  (dataType_[i] >= '0' && dataType_[i] <= '9') ||
149  (dataType_[i] == '-' || dataType_[i] <= '_')))
150  {
151  __SS__ << "The data type for column " << name_ << " is '" << dataType_
152  << "'. Data types must contain only letters, numbers,"
153  << "dashes, and underscores." << std::endl;
154  if(capturedExceptionString)
155  *capturedExceptionString += ss.str();
156  else
157  __SS_THROW__;
158  }
159 
160  if(name_.size() == 0)
161  {
162  __SS__ << "There is a column named " << name_
163  << "'. Column names must contain at least 1 character." << std::endl;
164  if(capturedExceptionString)
165  *capturedExceptionString += ss.str();
166  else
167  __SS_THROW__;
168  }
169 
170  // enforce that col name only
171  // allows letters, numbers, dash, underscore
172  for(unsigned int i = 0; i < name_.size(); ++i)
173  if(!((name_[i] >= 'A' && name_[i] <= 'Z') ||
174  (name_[i] >= 'a' && name_[i] <= 'z') ||
175  (name_[i] >= '0' && name_[i] <= '9') ||
176  (name_[i] == '-' || name_[i] <= '_')))
177  {
178  __SS__ << "There is a column named " << name_
179  << "'. Column names must contain only letters, numbers,"
180  << "dashes, and underscores." << std::endl;
181  if(capturedExceptionString)
182  *capturedExceptionString += ss.str();
183  else
184  __SS_THROW__;
185  }
186 
187  if(storageName_.size() == 0)
188  {
189  __SS__ << "The storage name for column " << name_ << " is '" << storageName_
190  << "'. Storage names must contain at least 1 character." << std::endl;
191  if(capturedExceptionString)
192  *capturedExceptionString += ss.str();
193  else
194  __SS_THROW__;
195  }
196 
197  // enforce that col storage name only
198  // allows capital letters, numbers, dash, underscore
199  for(unsigned int i = 0; i < storageName_.size(); ++i)
200  if(!((storageName_[i] >= 'A' && storageName_[i] <= 'Z') ||
201  (storageName_[i] >= '0' && storageName_[i] <= '9') ||
202  (storageName_[i] == '-' || storageName_[i] <= '_')))
203  {
204  __SS__ << "The storage name for column " << name_ << " is '" << storageName_
205  << "'. Storage names must contain only capital letters, numbers,"
206  << "dashes, and underscores." << std::endl;
207  if(capturedExceptionString)
208  *capturedExceptionString += ss.str();
209  else
210  __SS_THROW__;
211  }
212 
213  // build data choices vector from URI encoded data
214  //__COUT__ << "dataChoicesCSV " << dataChoicesCSV << std::endl;
215  {
216  std::istringstream f(dataChoicesCSV);
217  std::string s;
218  while(getline(f, s, ','))
219  dataChoices_.push_back(StringMacros::decodeURIComponent(s));
220  // for(const auto &dc: dataChoices_)
221  // __COUT__ << dc << std::endl;
222  }
223 
224  try
225  {
226  extractBitMapInfo();
227  }
228  catch(std::runtime_error& e)
229  {
230  if(capturedExceptionString)
231  *capturedExceptionString += e.what();
232  else
233  throw;
234  }
235 
236  //__COUT__ << "dataChoicesCSV " << dataChoicesCSV << std::endl;
237 }
238 
239 //==============================================================================
240 void TableViewColumnInfo::extractBitMapInfo()
241 {
242  // create BitMapInfo if this is a bitmap column
243  if(type_ == TYPE_BITMAP_DATA)
244  {
245  if(bitMapInfoP_)
246  delete bitMapInfoP_;
247  bitMapInfoP_ = new BitMapInfo();
248 
249  // extract bitMapInfo parameters:
250  // must match TableEditor js handling:
251 
252  // [ //types => 0:string, 1:bool (default no),
253  // //2:bool (default yes), 3:color
254  //
255  // 0 0,//"Number of Rows",
256  // 1 0,//"Number of Columns",
257  // 2 0,//"Cell Bit-field Size",
258  // 3 0,//"Min-value Allowed",
259  // 4 0,//"Max-value Allowed",
260  // 5 0,//"Value step-size Allowed",
261  // 6 0,//"Display Aspect H:W",
262  // 7 3,//"Min-value Cell Color",
263  // 8 3,//"Mid-value Cell Color",
264  // 9 3,//"Max-value Cell Color",
265  // 10 3,//"Absolute Min-value Cell Color",
266  // 11 3,//"Absolute Max-value Cell Color",
267  // 12 1,//"Display Rows in Ascending Order",
268  // 13 2,//"Display Columns in Ascending Order",
269  // 14 1,//"Snake Double Rows",
270  // 15 1];//"Snake Double Columns"];
271 
272  if(dataChoices_.size() < 16)
273  {
274  __SS__ << "The Bit-Map data parameters for column " << name_
275  << " should be size 16, but is size " << dataChoices_.size()
276  << ". Bit-Map parameters should be rows, cols, cellBitSize, and min, "
277  "mid, max color."
278  << std::endl;
279  __SS_THROW__;
280  }
281 
282  sscanf(dataChoices_[0].c_str(), "%u", &(bitMapInfoP_->numOfRows_));
283  sscanf(dataChoices_[1].c_str(), "%u", &(bitMapInfoP_->numOfColumns_));
284  sscanf(dataChoices_[2].c_str(), "%u", &(bitMapInfoP_->cellBitSize_));
285 
286  sscanf(dataChoices_[3].c_str(), "%lu", &(bitMapInfoP_->minValue_));
287  sscanf(dataChoices_[4].c_str(), "%lu", &(bitMapInfoP_->maxValue_));
288  sscanf(dataChoices_[5].c_str(), "%lu", &(bitMapInfoP_->stepValue_));
289 
290  bitMapInfoP_->aspectRatio_ = dataChoices_[6];
291  bitMapInfoP_->minColor_ = dataChoices_[7];
292  bitMapInfoP_->midColor_ = dataChoices_[8];
293  bitMapInfoP_->maxColor_ = dataChoices_[9];
294  bitMapInfoP_->absMinColor_ = dataChoices_[10];
295  bitMapInfoP_->absMaxColor_ = dataChoices_[11];
296 
297  bitMapInfoP_->rowsAscending_ = dataChoices_[12] == "Yes" ? 1 : 0;
298  bitMapInfoP_->colsAscending_ = dataChoices_[13] == "Yes" ? 1 : 0;
299  bitMapInfoP_->snakeRows_ = dataChoices_[14] == "Yes" ? 1 : 0;
300  bitMapInfoP_->snakeCols_ = dataChoices_[15] == "Yes" ? 1 : 0;
301  }
302 }
303 
304 //==============================================================================
305 // private empty default constructor. Only used by assignment operator.
306 TableViewColumnInfo::TableViewColumnInfo(void) {}
307 
308 //==============================================================================
309 TableViewColumnInfo::TableViewColumnInfo(
310  const TableViewColumnInfo& c) // copy constructor because of bitmap pointer
311  : type_(c.type_)
312  , name_(c.name_)
313  , storageName_(c.storageName_)
314  , dataType_(c.dataType_)
315  , dataChoices_(c.dataChoices_)
316  , bitMapInfoP_(0)
317 {
318  // extract bitmap info if necessary
319  extractBitMapInfo();
320 }
321 
322 //==============================================================================
323 TableViewColumnInfo& TableViewColumnInfo::operator=(
324  const TableViewColumnInfo& c) // assignment operator because of bitmap pointer
325 {
326  TableViewColumnInfo* retColInfo = new TableViewColumnInfo();
327  retColInfo->type_ = c.type_;
328  retColInfo->name_ = c.name_;
329  retColInfo->storageName_ = c.storageName_;
330  retColInfo->dataType_ = c.dataType_;
331  retColInfo->dataChoices_ = c.dataChoices_;
332  retColInfo->bitMapInfoP_ = 0;
333 
334  // extract bitmap info if necessary
335  retColInfo->extractBitMapInfo();
336 
337  return *retColInfo;
338 }
339 
340 //==============================================================================
341 TableViewColumnInfo::~TableViewColumnInfo(void)
342 {
343  if(bitMapInfoP_)
344  delete bitMapInfoP_;
345 }
346 
347 //==============================================================================
348 const std::string& TableViewColumnInfo::getType(void) const { return type_; }
349 
350 //==============================================================================
351 const std::string& TableViewColumnInfo::getDefaultValue(void) const
352 {
353  if(getDataType() == TableViewColumnInfo::DATATYPE_STRING)
354  {
355  if(getType() == TableViewColumnInfo::TYPE_ON_OFF ||
356  getType() == TableViewColumnInfo::TYPE_TRUE_FALSE ||
357  getType() == TableViewColumnInfo::TYPE_YES_NO)
358  return (
359  TableViewColumnInfo::DATATYPE_BOOL_DEFAULT); // default to OFF, NO, FALSE
360  else if(isChildLink())
361  return (TableViewColumnInfo::DATATYPE_LINK_DEFAULT);
362  else if(getType() == TableViewColumnInfo::TYPE_COMMENT)
363  return (TableViewColumnInfo::DATATYPE_COMMENT_DEFAULT);
364  else
365  return (TableViewColumnInfo::DATATYPE_STRING_DEFAULT);
366  }
367  else if(getDataType() == TableViewColumnInfo::DATATYPE_NUMBER)
368  return (TableViewColumnInfo::DATATYPE_NUMBER_DEFAULT);
369  else if(getDataType() == TableViewColumnInfo::DATATYPE_TIME)
370  return (TableViewColumnInfo::DATATYPE_TIME_DEFAULT);
371  else
372  {
373  __SS__ << "\tUnrecognized View data type: " << getDataType() << std::endl;
374  __COUT_ERR__ << "\n" << ss.str();
375  __SS_THROW__;
376  }
377 }
378 
379 //==============================================================================
380 std::vector<std::string> TableViewColumnInfo::getAllTypesForGUI(void)
381 {
382  std::vector<std::string> all;
383  all.push_back(TYPE_DATA);
384  all.push_back(TYPE_UNIQUE_DATA);
385  all.push_back(TYPE_UNIQUE_GROUP_DATA);
386  all.push_back(TYPE_FIXED_CHOICE_DATA);
387  all.push_back(TYPE_MULTILINE_DATA);
388  all.push_back(TYPE_BITMAP_DATA);
389  all.push_back(TYPE_ON_OFF);
390  all.push_back(TYPE_TRUE_FALSE);
391  all.push_back(TYPE_YES_NO);
392  all.push_back(TYPE_START_CHILD_LINK_UID);
393  all.push_back(TYPE_START_CHILD_LINK_GROUP_ID);
394  all.push_back(TYPE_START_CHILD_LINK);
395  all.push_back(TYPE_START_GROUP_ID);
396  return all;
397 }
398 
399 //==============================================================================
400 std::vector<std::string> TableViewColumnInfo::getAllDataTypesForGUI(void)
401 {
402  std::vector<std::string> all;
403  all.push_back(DATATYPE_STRING);
404  all.push_back(DATATYPE_NUMBER);
405  all.push_back(DATATYPE_TIME);
406  return all;
407 }
408 
409 //==============================================================================
410 // map of datatype,type to default value
411 std::map<std::pair<std::string, std::string>, std::string>
412 TableViewColumnInfo::getAllDefaultsForGUI(void)
413 {
414  std::map<std::pair<std::string, std::string>, std::string> all;
415  all[std::pair<std::string, std::string>(DATATYPE_NUMBER, "*")] =
416  DATATYPE_NUMBER_DEFAULT;
417  all[std::pair<std::string, std::string>(DATATYPE_TIME, "*")] = DATATYPE_TIME_DEFAULT;
418 
419  all[std::pair<std::string, std::string>(DATATYPE_STRING, TYPE_ON_OFF)] =
420  DATATYPE_BOOL_DEFAULT;
421  all[std::pair<std::string, std::string>(DATATYPE_STRING, TYPE_TRUE_FALSE)] =
422  DATATYPE_BOOL_DEFAULT;
423  all[std::pair<std::string, std::string>(DATATYPE_STRING, TYPE_YES_NO)] =
424  DATATYPE_BOOL_DEFAULT;
425 
426  all[std::pair<std::string, std::string>(DATATYPE_STRING, TYPE_START_CHILD_LINK)] =
427  DATATYPE_LINK_DEFAULT;
428  all[std::pair<std::string, std::string>(DATATYPE_STRING, "*")] =
429  DATATYPE_STRING_DEFAULT;
430  return all;
431 }
432 
433 //==============================================================================
434 // isBoolType
435 const bool TableViewColumnInfo::isBoolType(void) const
436 {
437  return (type_ == TYPE_ON_OFF || type_ == TYPE_TRUE_FALSE || type_ == TYPE_YES_NO);
438 } // end isBoolType()
439 
440 //==============================================================================
441 // isNumberDataType
442 const bool TableViewColumnInfo::isNumberDataType(void) const
443 {
444  return (dataType_ == DATATYPE_NUMBER);
445 } // end isBoolType()
446 
447 //==============================================================================
448 const std::string& TableViewColumnInfo::getName(void) const { return name_; }
449 
450 //==============================================================================
451 const std::string& TableViewColumnInfo::getStorageName(void) const
452 {
453  return storageName_;
454 }
455 
456 //==============================================================================
457 const std::string& TableViewColumnInfo::getDataType(void) const { return dataType_; }
458 
459 //==============================================================================
460 const std::vector<std::string>& TableViewColumnInfo::getDataChoices(void) const
461 {
462  return dataChoices_;
463 }
464 
465 //==============================================================================
466 // getBitMapInfo
467 // uses dataChoices CSV fields if type is TYPE_BITMAP_DATA
468 const TableViewColumnInfo::BitMapInfo& TableViewColumnInfo::getBitMapInfo(void) const
469 {
470  if(bitMapInfoP_)
471  return *bitMapInfoP_;
472 
473  // throw error at this point!
474  {
475  __SS__ << "getBitMapInfo request for non-BitMap column of type: " << getType()
476  << std::endl;
477  __COUT_ERR__ << "\n" << ss.str();
478  __SS_THROW__;
479  }
480 }
481 
482 //==============================================================================
483 // isChildLink
484 // note: TYPE_START_CHILD_LINK index may be a subset of UID and GROUP_ID
485 // so don't allow alpha character immediately after
486 const bool TableViewColumnInfo::isChildLink(void) const
487 {
488  return (type_.find(TYPE_START_CHILD_LINK) == 0 &&
489  type_.length() > TYPE_START_CHILD_LINK.length() &&
490  type_[TYPE_START_CHILD_LINK.length()] == '-');
491 }
492 
493 //==============================================================================
494 // isChildLinkUID
495 // note: TYPE_START_CHILD_LINK index may be a subset of UID and GROUP_ID
496 // so don't allow alpha character immediately after
497 const bool TableViewColumnInfo::isChildLinkUID(void) const
498 {
499  return (type_.find(TYPE_START_CHILD_LINK_UID) == 0 &&
500  type_.length() > TYPE_START_CHILD_LINK_UID.length() &&
501  type_[TYPE_START_CHILD_LINK_UID.length()] == '-');
502 }
503 
504 //==============================================================================
505 // isChildLinkGroupID
506 // note: TYPE_START_CHILD_LINK index may be a subset of UID and GROUP_ID
507 // so don't allow alpha character immediately after
508 const bool TableViewColumnInfo::isChildLinkGroupID(void) const
509 {
510  return (type_.find(TYPE_START_CHILD_LINK_GROUP_ID) == 0 &&
511  type_.length() > TYPE_START_CHILD_LINK_GROUP_ID.length() &&
512  type_[TYPE_START_CHILD_LINK_GROUP_ID.length()] == '-');
513 }
514 
515 //==============================================================================
516 // isGroupID
517 // note: TYPE_START_CHILD_LINK index may be a subset of UID and GROUP_ID
518 // so don't allow alpha character immediately after in group index
519 const bool TableViewColumnInfo::isGroupID(void) const
520 {
521  return (type_.find(TYPE_START_GROUP_ID) == 0 &&
522  type_.length() > TYPE_START_GROUP_ID.length() &&
523  type_[TYPE_START_GROUP_ID.length()] == '-');
524 }
525 
526 //==============================================================================
527 // isUID
528 const bool TableViewColumnInfo::isUID(void) const { return (type_ == TYPE_UID); }
529 
530 //==============================================================================
531 // getChildLinkIndex
532 std::string TableViewColumnInfo::getChildLinkIndex(void) const
533 {
534  // note: +1 to skip '-'
535  if(isChildLink())
536  return type_.substr(TYPE_START_CHILD_LINK.length() + 1);
537  else if(isChildLinkUID())
538  return type_.substr(TYPE_START_CHILD_LINK_UID.length() + 1);
539  else if(isChildLinkGroupID())
540  return type_.substr(TYPE_START_CHILD_LINK_GROUP_ID.length() + 1);
541  else if(isGroupID())
542  return type_.substr(TYPE_START_GROUP_ID.length() + 1);
543  else
544  {
545  __SS__
546  << ("Requesting a Link Index from a column that is not a child link member!")
547  << std::endl;
548  __COUT_ERR__ << ss.str();
549  __SS_THROW__;
550  }
551 }