NCBI C++ ToolKit
bed_autosql_custom.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /*
2  * $Id: bed_autosql_custom.cpp 99919 2023-05-22 11:51:29Z foleyjp $
3  *
4  * ===========================================================================
5  *
6  * PUBLIC DOMAIN NOTICE
7  * National Center for Biotechnology Information
8  *
9  * This software/database is a "United States Government Work" under the
10  * terms of the United States Copyright Act. It was written as part of
11  * the author's official duties as a United States Government employee and
12  * thus cannot be copyrighted. This software/database is freely available
13  * to the public for use. The National Library of Medicine and the U.S.
14  * Government have not placed any restriction on its use or reproduction.
15  *
16  * Although all reasonable efforts have been taken to ensure the accuracy
17  * and reliability of the software and data, the NLM and the U.S.
18  * Government do not and cannot warrant the performance or results that
19  * may be obtained by using this software or data. The NLM and the U.S.
20  * Government disclaim all warranties, express or implied, including
21  * warranties of performance, merchantability or fitness for any particular
22  * purpose.
23  *
24  * Please cite the author in any work or product based on this material.
25  *
26  * ===========================================================================
27  *
28  * Authors: Frank Ludwig
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 #include <corelib/ncbistr.hpp>
41 #include "bed_autosql.hpp"
42 
43 #include <functional>
44 
47 
48 // ============================================================================
50 // ============================================================================
55  {"lstring", CAutoSqlCustomField::AddString},
59 };
60 
61 // ============================================================================
63  size_t colIndex, string format, string name, string description):
64 // ============================================================================
65  mColIndex(colIndex),
66  mFormat(format),
67  mName(name),
68  mDescription(description)
69 {
70  if (NStr::EndsWith(format, "]")) {
71  auto openBracket = format.find('[');
72  if (openBracket != string::npos) {
73  mFormat = format.substr(0, openBracket + 1) + "]";
74  }
75  }
76  auto handlerIt = mFormatHandlers.find(mFormat);
77  if (handlerIt != mFormatHandlers.end()) {
78  mHandler = handlerIt->second;
79  }
80  else {
82  }
83 }
84 
85 // ============================================================================
87  const string& key,
88  const string& value,
89  unsigned int lineNo,
90  int bedFlags,
91  CUser_object& uo,
92  CReaderMessageHandler& messageHandler)
93 // ============================================================================
94 {
95  double floatVal = 0;
96  try {
97  floatVal = NStr::StringToDouble(value);
98  } catch (const CStringException&) {
99  CReaderMessage warning(
101  lineNo,
102  string("BED: Unable to convert \"") + key + "\" value \"" + value +
103  "\" to float. Defaulting to 0.0");
104  messageHandler.Report(warning);
105  }
106  uo.AddField(key, floatVal);
107  return true;
108 }
109 
110 
111 // ============================================================================
113  const string& key,
114  const string& value,
115  unsigned int lineNo,
116  int bedFlags,
117  CUser_object& uo,
118  CReaderMessageHandler& messageHandler)
119 // ============================================================================
120 {
121  int intVal = 0;
122  try {
123  intVal = NStr::StringToInt(value);
124  } catch (const CStringException&) {
125  CReaderMessage warning(
127  lineNo,
128  string("BED: Unable to convert \"") + key + "\" value \"" + value +
129  "\" to int. Defaulting to 0");
130  messageHandler.Report(warning);
131  }
132  uo.AddField(key, intVal);
133  return true;
134 }
135 
136 // ============================================================================
138  const string& key,
139  const string& value,
140  unsigned int lineNo,
141  int bedFlags,
142  CUser_object& uo,
143  CReaderMessageHandler& messageHandler)
144 // ============================================================================
145 {
146  vector<string> intStrs;
147  NStr::Split(value, ",", intStrs);
148  vector<int> realInts;
149  try {
151  intStrs.begin(), intStrs.end(),
152  std::back_inserter(realInts),
153  [] (const string& str) -> int { return NStr::StringToInt(str);} );
154  } catch (const CStringException&) {
155  CReaderMessage warning(
157  lineNo,
158  string("BED: Unable to convert \"") + key + "\" value \"" + value +
159  "\" to int list. Defaulting to empty list");
160  messageHandler.Report(warning);
161  realInts.clear();
162  }
163  uo.AddField(key, realInts);
164  return true;
165 }
166 
167 // ============================================================================
169  const string& key,
170  const string& value,
171  unsigned int lineNo,
172  int bedFlags,
173  CUser_object& uo,
174  CReaderMessageHandler& messageHandler)
175 // ============================================================================
176 {
177  uo.AddField(key, value);
178  return true;
179 }
180 
181 // ============================================================================
183  const string& key,
184  const string& value,
185  unsigned int lineNo,
186  int bedFlags,
187  CUser_object& uo,
188  CReaderMessageHandler& messageHandler)
189 // ============================================================================
190 {
191  unsigned uintVal = 0;
192  try {
193  uintVal = NStr::StringToUInt(value);
194  } catch (const CStringException&) {
195  CReaderMessage warning(
197  lineNo,
198  string("BED: Unable to convert \"") + key + "\" value \"" + value +
199  "\" to uint. Defaulting to 0");
200  messageHandler.Report(warning);
201  }
202  uo.AddField(key, static_cast<Int8>(uintVal));
203  return true;
204 }
205 
206 // ============================================================================
208  const string& key,
209  const string& value,
210  unsigned int lineNo,
211  int bedFlags,
212  CUser_object& uo,
213  CReaderMessageHandler& messageHandler)
214 // ============================================================================
215 {
216  return AddIntArray(key, value, lineNo, bedFlags, uo, messageHandler);
217 }
218 
219 // ============================================================================
220 bool
222  const CBedColumnData& columnData,
223  int bedFlags,
224  CUser_object& uo,
225  CReaderMessageHandler& messageHandler) const
226 // ============================================================================
227 {
228  return xHandleSpecialCaseRgb(columnData, bedFlags, uo, messageHandler);
229 }
230 
231 // ============================================================================
232 bool
234  const CBedColumnData& columnData,
235  int bedFlags,
236  CUser_object& uo,
237  CReaderMessageHandler& messageHandler) const
238 // ============================================================================
239 {
240  //if it's column 9 or the key and format suggests it's an RGB value then accept
241  // (r,g,b) or #RRGGBB and convert to int.
242  //
243  if (mFormat != "int" && mFormat != "uint") {
244  return false;
245  }
246 
247  vector<string> knownRgbKeys = {"itemrgb", "color", "colour"};
248  string lowerName(mName);
249  NStr::ToLower(lowerName);
250  bool isRgbKey = (find(knownRgbKeys.begin(), knownRgbKeys.end(), lowerName) !=
251  knownRgbKeys.end());
252  if (mColIndex != 8 && !isRgbKey) {
253  return false;
254  }
255  string valueStr = columnData[mColIndex];
256 
257  if (NStr::StartsWith(valueStr, "#")) {
258  int intVal = 0;
259  try {
260  intVal = NStr::StringToInt(valueStr.substr(1), 0, 16);
261  } catch (const CStringException&) {
262  CReaderMessage warning(
264  columnData.LineNo(),
265  string("BED: Unable to convert \"") + mName + "\" value \"" +
266  valueStr + "\" to int. Defaulting to 0");
267  messageHandler.Report(warning);
268  }
269  uo.AddField(mName, intVal);
270  return true;
271  }
272 
273  vector<string> rgb;
274  NStr::Split(valueStr, ",", rgb);
275  int rgbInt(0);
276  if (rgb.size() == 3) {
277  try {
278  rgbInt = 256*256*NStr::StringToInt(rgb[0]) +
279  256*NStr::StringToInt(rgb[1]) + NStr::StringToInt(rgb[2]);
280  } catch (const CStringException&) {
281  CReaderMessage warning(
283  columnData.LineNo(),
284  string("BED: Unable to convert \"") + mName + "\" value \"" +
285  valueStr + "\" to int. Defaulting to 0");
286  messageHandler.Report(warning);
287  }
288  uo.AddField(mName, rgbInt);
289  return true;
290  }
291  // no special case after all, use regular processing
292  return false;
293 }
294 
295 
296 // ============================================================================
297 bool
299  const CBedColumnData& columnData,
300  int bedFlags,
301  CUser_object& uo,
302  CReaderMessageHandler& messageHandler) const
303 // ============================================================================
304 {
305  if (xHandleSpecialCases(columnData, bedFlags, uo, messageHandler)) {
306  return true;
307  }
308  string valueStr = columnData[mColIndex];
309  if (NStr::EndsWith(mFormat, "[]")) {
310  // deal with trailing comma in list
311  NStr::TrimSuffixInPlace(valueStr, ",");
312  }
313 
314  //note:
315  // we need some extra policy decisions on error handling in custom field.
316  // until then: avoid throwing at all costs,
317  // return false like never.
318  return mHandler(
319  mName, valueStr, columnData.LineNo(), bedFlags, uo, messageHandler);
320 }
321 
322 // ============================================================================
323 bool
325  CReaderMessageHandler& messageHandler) const
326 // ============================================================================
327 {
328  if (mFormatHandlers.find(mFormat) == mFormatHandlers.end()) {
329  CReaderMessage warning(
331  0,
332  string("AutoSql: Format \"") + mFormat +
333  "\" for \"" + mName +
334  "\" not recognized, processing as string");
335  messageHandler.Report(warning);
336  }
337  return true;
338 }
339 
340 // ============================================================================
341 void
343  const CAutoSqlCustomField& columnInfo)
344 // ============================================================================
345 {
346  mFields.push_back(columnInfo);
347 }
348 
349 // ============================================================================
350 bool
352  const CBedColumnData& columnData,
353  int bedFlags,
354  CSeq_feat& feat,
355  CReaderMessageHandler& messageHandler) const
356 // ============================================================================
357 {
358  bool newUserObject {false};
359 
360  auto pDisplayData = feat.FindExt("DisplaySettings");
361  if (!pDisplayData) {
362  pDisplayData = Ref(new CUser_object());
363  pDisplayData->SetType().SetStr("DisplaySettings");
364  newUserObject = true;
365  }
366 
367  CRef<CUser_field> pDummy(new CUser_field);
368  for (const auto& fieldInfo: mFields) {
369  if (! fieldInfo.SetUserField(
370  columnData, bedFlags, *pDisplayData, messageHandler)) {
371  return false;
372  }
373  }
374 
375  if (newUserObject) {
376  feat.SetExts().push_back(pDisplayData);
377  }
378  return true;
379 }
380 
381 // ============================================================================
382 bool
384  CReaderMessageHandler& messageHandler) const
385 // ============================================================================
386 {
387  for (const auto& field: mFields) {
388  if (!field.Validate(messageHandler)) {
389  return false;
390  }
391  }
392  return true;
393 }
394 
void transform(Container &c, UnaryFunction *op)
Definition: chainer.hpp:86
bool Validate(CReaderMessageHandler &) const
static bool AddUint(const string &, const string &, unsigned int, int, CUser_object &, CReaderMessageHandler &)
static FormatHandlers mFormatHandlers
bool SetUserField(const CBedColumnData &, int bedFlags, CUser_object &, CReaderMessageHandler &) const
static bool AddUintArray(const string &, const string &, unsigned int, int, CUser_object &, CReaderMessageHandler &)
bool xHandleSpecialCases(const CBedColumnData &, int bedFlags, CUser_object &, CReaderMessageHandler &) const
static bool AddString(const string &, const string &, unsigned int, int, CUser_object &, CReaderMessageHandler &)
static bool AddDouble(const string &, const string &, unsigned int, int, CUser_object &, CReaderMessageHandler &)
static bool AddInt(const string &, const string &, unsigned int, int, CUser_object &, CReaderMessageHandler &)
static bool AddIntArray(const string &, const string &, unsigned int, int, CUser_object &, CReaderMessageHandler &)
CAutoSqlCustomField(size_t colIndex, string format, string name, string description)
bool xHandleSpecialCaseRgb(const CBedColumnData &, int bedFlags, CUser_object &, CReaderMessageHandler &) const
vector< CAutoSqlCustomField > mFields
bool Validate(CReaderMessageHandler &) const
bool SetUserObject(const CBedColumnData &, int bedFlags, CSeq_feat &, CReaderMessageHandler &) const
void Append(const CAutoSqlCustomField &)
void Report(const CReaderMessage &)
namespace ncbi::objects::
Definition: Seq_feat.hpp:58
CStringException –.
Definition: ncbistr.hpp:4506
CUser_object & AddField(const string &label, const string &value, EParseField parse=eParse_String)
add a data field to the user object that holds a given value
const_iterator end() const
Definition: map.hpp:152
const_iterator find(const key_type &key) const
Definition: map.hpp:153
Definition: map.hpp:338
The NCBI C++ standard methods for dealing with std::string.
static const char * str(char *buf, int n)
Definition: stats.c:84
@ eDiag_Warning
Warning message.
Definition: ncbidiag.hpp:652
CRef< C > Ref(C *object)
Helper functions to get CRef<> and CConstRef<> objects.
Definition: ncbiobj.hpp:2015
int64_t Int8
8-byte (64-bit) signed integer
Definition: ncbitype.h:104
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define END_SCOPE(ns)
End the previously defined scope.
Definition: ncbistl.hpp:75
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define BEGIN_SCOPE(ns)
Define a new scope.
Definition: ncbistl.hpp:72
static int StringToInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to int.
Definition: ncbistr.cpp:630
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
Definition: ncbistr.cpp:3461
static bool EndsWith(const CTempString str, const CTempString end, ECase use_case=eCase)
Check if a string ends with a specified suffix value.
Definition: ncbistr.hpp:5430
static double StringToDouble(const CTempStringEx str, TStringToNumFlags flags=0)
Convert string to double.
Definition: ncbistr.cpp:1387
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
Definition: ncbistr.hpp:5412
static void TrimSuffixInPlace(string &str, const CTempString suffix, ECase use_case=eCase)
Trim suffix from a string (in-place)
Definition: ncbistr.cpp:3278
static unsigned int StringToUInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to unsigned int.
Definition: ncbistr.cpp:642
static string & ToLower(string &str)
Convert string to lower case – string& version.
Definition: ncbistr.cpp:405
const struct ncbi::grid::netcache::search::fields::KEY key
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
static Format format
Definition: njn_ioutil.cpp:53
Modified on Wed May 29 18:44:20 2024 by modify_doxy.py rev. 669887