DBDataset.cxx
Go to the documentation of this file.
1 //=================================================================================
2 //
3 // Name: DBDataset.cpp
4 //
5 // Purpose: Implementation for class DBDataset.
6 //
7 // Created: 26-Oct-2020 - H. Greenlee
8 //
9 //=================================================================================
10 
11 #include <cstring>
12 #include "WebDBIConstants.h"
13 #include "DBDataset.h"
14 #include "wda.h"
15 #include "cetlib_except/exception.h"
17 
18 // Default constructor.
19 
21  fBeginTime(0, 0),
22  fEndTime(0, 0)
23 {}
24 
25 
26 // Libwda initializing constructor.
27 
28 lariov::DBDataset::DBDataset(void* dataset, bool release) :
29  fBeginTime(0, 0),
30  fEndTime(0, 0)
31 {
32  // Parse dataset and get number of rows.
33 
34  size_t nrows = getNtuples(dataset) - kNUMBER_HEADER_ROWS;
35  //mf::LogInfo("DBDataset") << "DBDataset: Number of rows = " << nrows << "\n";
36  fChannels.reserve(nrows);
37 
38  // Process header rows.
39 
40  int err = 0;
41  char buf[kBUFFER_SIZE];
42  Tuple tup;
43 
44  // Extract IOV begin time.
45 
46  tup = getTuple(dataset, 0);
47  getStringValue(tup, 0, buf, kBUFFER_SIZE, &err);
49  //mf::LogInfo log("DBDataset");
50  //log << "DBDataset: Begin time stamp input = " << buf << "\n";
51  //log << "DBDataset: Begin time stamp = " << fBeginTime.DBStamp() << "\n";
52  releaseTuple(tup);
53 
54  // Extract IOV end time.
55 
56  tup = getTuple(dataset, 1);
57  getStringValue(tup, 0, buf, kBUFFER_SIZE, &err);
58  if ( 0 == strcmp(buf,"-") )
60  else
62  //mf::LogInfo log("DBDataset");
63  //log << "DBDataset: End time stamp input = " << buf << "\n";
64  //log << "DBDataset: End time stamp = " << fEndTime.DBStamp() << "\n";
65  releaseTuple(tup);
66 
67  // Extract column names.
68 
69  tup = getTuple(dataset, 2);
70  size_t ncols = getNfields(tup);
71  //mf::LogInfo("DBDataset") << "DBDataset: Number of columns = " << ncols << "\n";
72  fColNames.reserve(ncols);
73  for (size_t col=0; col<ncols; ++col) {
74  getStringValue(tup, col, buf, kBUFFER_SIZE, &err);
75  //mf::LogInfo("DBDataset") << "DBDataset: Column name = " << buf << "\n";
76  fColNames.push_back(std::string(buf));
77  }
78  releaseTuple(tup);
79 
80  // Extract column types.
81 
82  tup = getTuple(dataset, 3);
83  fColTypes.reserve(ncols);
84  for (size_t col=0; col < ncols; ++col) {
85  getStringValue(tup, col, buf, kBUFFER_SIZE, &err);
86  //mf::LogInfo("DBDataset") << "DBDataset: Column type = " << buf << "\n";
87  fColTypes.push_back(std::string(buf));
88  }
89  releaseTuple(tup);
90 
91  // Extract data. Loop over rows.
92 
93  fData.reserve(nrows * ncols);
94  for(size_t row = 0; row < nrows; ++row) {
95  //mf::LogInfo("DBDataset") << "\nRow " << row << "\n";
96  tup = getTuple(dataset, row + kNUMBER_HEADER_ROWS);
97 
98  // Loop over columns.
99 
100  for(size_t col = 0; col < ncols; ++col) {
101  getStringValue(tup, col, buf, kBUFFER_SIZE, &err);
102 
103  // Convert string value to DBDataset::value_type (std::variant).
104 
105  if(fColTypes[col] == "integer" || fColTypes[col] == "bigint") {
106  long value = strtol(buf, 0, 10);
107  fData.push_back(value_type(value));
108  //mf::LogInfo("DBDataset") << "DBDataset: row=" << row << ", column=" << col << ", value=" << fData.back()
109  // << "\n";
110  if(col == 0) {
111  fChannels.push_back(value);
112  //mf::LogInfo("DBDataset") << "DBDataset: channel=" << fChannels.back() << "\n";
113  }
114  }
115  else if(fColTypes[col] == "real") {
116  double value = strtod(buf, 0);
117  fData.push_back(value_type(value));
118  //mf::LogInfo("DBDataset") << "DBDataset: row=" << row << ", column=" << col << ", value=" << fData.back()
119  // << "\n";
120  if(col == 0) {
121  mf::LogError("DBDataset") << "First column has wrong type real." << "\n";
122  throw cet::exception("DBDataset") << "First column has wrong type real.";
123  }
124  }
125  else if(fColTypes[col] == "text") {
126  fData.emplace_back(std::make_unique<std::string>(buf));
127  //mf::LogInfo("DBDataset") << "DBDataset: row=" << row << ", column=" << col << ", value=" << fData.back()
128  // << "\n";
129  if(col == 0) {
130  mf::LogError("DBDataset") << "First column has wrong type text." << "\n";
131  throw cet::exception("DBDataset") << "First column has wrong type text.";
132  }
133  }
134  else if(fColTypes[col] == "boolean") {
135  long value = 0;
136  std::string s = std::string(buf);
137  if(s == "true" || s == "True" || s == "TRUE" || s == "1")
138  value = 1;
139  else if(s == "false" || s == "False" || s == "FALSE" || s == "0")
140  value = 0;
141  else {
142  mf::LogError("DBDataset") << "Unknown string representation of boolean " << s << "\n";
143  throw cet::exception("DBDataset") << "Unknown string representation of boolean " << s
144  << "\n";
145  }
146  fData.push_back(value_type(value));
147  //mf::LogInfo("DBDataset") << "DBDataset: row=" << row << ", column=" << col << ", value=" << fData.back()
148  // << "\n";
149  if(col == 0) {
150  mf::LogError("DBDataset") << "First column has wrong type boolean." << "\n";
151  throw cet::exception("DBDataset") << "First column has wrong type boolean.";
152  }
153  }
154  else {
155  mf::LogError("DBDataset") << "Unknown datatype = " << fColTypes[col] << "\n";
156  throw cet::exception("DBDataset") << "Unknown datatype = " << fColTypes[col]
157  << ": " << buf << "\n";
158  }
159  }
160  releaseTuple(tup);
161  }
162 
163  // Maybe release dataset memory.
164 
165  if(release)
166  releaseDataset(dataset);
167 }
168 
169 // SQLite initializing move constructor.
170 
171 lariov::DBDataset::DBDataset(const IOVTimeStamp& begin_time, // IOV begin time.
172  const IOVTimeStamp& end_time, // IOV end time.
173  std::vector<std::string>&& col_names, // Column names.
174  std::vector<std::string>&& col_types, // Column types.
175  std::vector<DBChannelID_t>&& channels, // Channels.
176  std::vector<value_type>&& data) : // Calibration data.
177  fBeginTime(begin_time),
178  fEndTime(end_time),
179  fColNames(std::move(col_names)),
180  fColTypes(std::move(col_types)),
182  fData(std::move(data))
183 {}
184 
185 // Get row number by channel number.
186 // Return -1 if not found.
187 
189 {
190  int result = -1;
191 
192  // Do a binary search on channel numbers.
193 
194  int low = 0;
195  int high = fChannels.size() - 1;
196  while(high-low > 1) {
197  int mid = (low + high) / 2;
198  if(fChannels[mid] < ch)
199  low = mid;
200  else if(fChannels[mid] > ch)
201  high = mid;
202  else {
203 
204  // Found an exact match. Break out of loop.
205 
206  result = mid;
207  break;
208  }
209  }
210 
211  // If we fell out of loop without finding a match...
212 
213  if(result < 0) {
214  if(fChannels[low] == ch)
215  result = low;
216  else if(fChannels[high] == ch)
217  result = high;
218  }
219 
220  // Done.
221 
222  return result;
223 }
224 
225 // Get column number by column name.
226 // Return -1 if not found.
227 
229 {
230  int result = -1;
231 
232  // Scan column names.
233 
234  for(size_t i=0; i<fColNames.size(); ++i) {
235  if(fColNames[i] == name) {
236  result = i;
237  break;
238  }
239  }
240 
241  return result;
242 }
static QCString name
Definition: declinfo.cpp:673
const unsigned int kNUMBER_HEADER_ROWS
std::variant< long, double, std::unique_ptr< std::string > > value_type
Definition: DBDataset.h:67
static QCString result
std::string string
Definition: nybbler.cc:12
std::uint32_t DBChannelID_t
size_t nrows() const
Definition: DBDataset.h:123
STL namespace.
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
std::vector< std::string > fColNames
Definition: DBDataset.h:145
void * Tuple
Definition: DBFolder.h:13
int getRowNumber(DBChannelID_t ch) const
Definition: DBDataset.cxx:188
const std::vector< value_type > & data() const
Definition: DBDataset.h:128
std::vector< std::string > fColTypes
Definition: DBDataset.h:146
IOVTimeStamp fBeginTime
Definition: DBDataset.h:143
def move(depos, offset)
Definition: depos.py:107
std::vector< value_type > fData
Definition: DBDataset.h:148
void err(const char *fmt,...)
Definition: message.cpp:226
const unsigned int kBUFFER_SIZE
std::vector< DBChannelID_t > fChannels
Definition: DBDataset.h:147
const std::vector< DBChannelID_t > & channels() const
Definition: DBDataset.h:127
string release
Definition: conf.py:24
int strcmp(const String &s1, const String &s2)
Definition: relates.cpp:14
IOVTimeStamp fEndTime
Definition: DBDataset.h:144
size_t ncols() const
Definition: DBDataset.h:124
int getColNumber(const std::string &name) const
Definition: DBDataset.cxx:228
static IOVTimeStamp GetFromString(const std::string &ts)
static IOVTimeStamp MaxTimeStamp()
static QCString * s
Definition: config.cpp:1042
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33