REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestDataBase.cxx
1 #include "TRestDataBase.h"
2 
3 #include <errno.h>
4 #include <stdio.h>
5 #include <sys/stat.h>
6 #include <sys/types.h>
7 
8 #include "TClass.h"
9 #include "TRestStringHelper.h"
10 #include "TRestStringOutput.h"
11 #include "TRestTools.h"
12 #include "TSystem.h"
13 #include "TUrl.h"
14 
15 using namespace std;
16 
57 
58 DBEntry::DBEntry(vector<string> items) {
59  this->runNr = atoi(items[0].c_str());
60  this->type = items[1];
61  this->tag = items[2];
62  this->description = items[3];
63  this->version = items[4];
64 }
65 
67  fDataEntries.clear();
68  string metaFilename = REST_PATH + "/data/dataURL";
69  if (!TRestTools::fileExists(metaFilename)) {
70  return;
71  } else {
72  vector<int> result;
73  ifstream infile(metaFilename);
74  string s;
75  while (TRestTools::GetLine(infile, s)) {
76  DBEntry info;
77  vector<string> items = Split(s, "\t", true);
78  if (items.size() <= 2) continue;
79  for (auto item : items) {
80  vector<string> pair = Split(item, "=", true);
81  if (pair.size() == 2) {
82  if (pair[0] == "run")
83  info.runNr = atoi(pair[1].c_str());
84  else if (pair[0] == "type")
85  info.type = pair[1];
86  else if (pair[0] == "tag")
87  info.tag = pair[1];
88  else if (pair[0] == "description")
89  info.description = pair[1];
90  else if (pair[0] == "version")
91  info.version = pair[1];
92  else if (pair[0] == "value")
93  info.value = pair[1];
94  }
95  }
96 
97  fDataEntries.push_back(info);
98  }
99  }
100 }
101 
102 DBFile DBFile::ParseFile(string _filename) {
103  DBFile file;
104  file.filename = _filename;
105  auto _fullname = TRestTools::ToAbsoluteName(_filename);
106 
107  struct stat buf;
108  int result = stat(_fullname.c_str(), &buf);
109 
110  if (result != 0) {
111  RESTError << "DBFile::ParseFile: Failed to load file \"" << _fullname << "\"!" << RESTendl;
112  } else {
113  file.fileSize = buf.st_size;
114  file.evtRate = 0;
115  file.quality = true;
116  file.start = buf.st_ctime;
117  file.stop = buf.st_mtime;
118  string sha1result = TRestTools::Execute("sha1sum " + _fullname);
119  string sha1 = Split(sha1result, " ")[0];
120  if (sha1.size() == 40) {
121  for (int i = 0; i < 40; i++) {
122  file.sha1sum[i] = sha1[i];
123  }
124  file.sha1sum[40] = 0;
125  }
126  }
127  return file;
128 }
129 
130 void DBFile::Print() {
131  cout << "----DBFile struct----" << endl;
132  cout << "size: " << fileSize << endl;
133  cout << "event rate: " << evtRate << endl;
134  cout << "sha1sum: " << sha1sum << endl;
135  cout << "quality: " << quality << endl;
136  cout << "start time: " << ToDateTimeString(start) << endl;
137  cout << "stop time: " << ToDateTimeString(stop) << endl;
138 }
139 
141  auto url = getenv("REST_DBURL");
142  if (url != nullptr) {
143  fConnectionString = url;
144  }
145  Initialize();
146 }
147 
155  int runNr;
156  string runFilename = REST_USER_PATH + "/runNumber";
157  if (!TRestTools::fileExists(runFilename)) {
158  if (TRestTools::isPathWritable(REST_USER_PATH)) {
159  // we fix the "runNumber" file
160  TRestTools::Execute("echo 1 > " + runFilename);
161  runNr = 1;
162  }
163  } else {
164  ifstream ifs(runFilename);
165  ifs >> runNr;
166  }
167  // the number recorded in "runNumber" file is for the next run, we subtract 1 to get the latest run.
168  return runNr - 1;
169 }
170 
183 int TRestDataBase::set_run(DBEntry info, bool overwrite) {
184  int newRunNr;
185  if (info.runNr == 0) {
186  newRunNr = get_lastrun() + 1;
187  } else if (info.runNr > 0) {
188  newRunNr = info.runNr;
189  } else {
190  return -1;
191  }
192 
193  string runFilename = REST_USER_PATH + "/runNumber";
194  if (TRestTools::isPathWritable(REST_USER_PATH)) {
195  TRestTools::Execute("echo " + ToString(newRunNr + 1) + " > " + runFilename);
196  } else {
197  RESTWarning << "runNumber file not writable. auto run number "
198  "increment is disabled"
199  << RESTendl;
200  }
201 
202  return newRunNr;
203 }
204 
209 DBEntry TRestDataBase::query_data(DBEntry _info) {
210  vector<DBEntry> match;
211  if (_info.runNr <= 0 && _info.type == "" && _info.tag == "" && _info.description == "" &&
212  _info.version == "")
213  return DBEntry();
214 
215  for (unsigned int i = 0; i < fDataEntries.size(); i++) {
216  DBEntry info = fDataEntries[i];
217 
218  bool runmatch = (_info.runNr == 0 || info.runNr == 0 || info.runNr == _info.type);
219  bool typematch = (_info.type == "" || info.type == _info.type);
220  bool tagmatch = (_info.tag == "" || info.tag == _info.tag);
221  bool descriptionmatch = (_info.description == "" || info.description == _info.description);
222  bool versionmatch = (_info.version == "" || info.version == _info.version);
223  bool valuematch = (_info.value == "" || info.value == _info.value);
224 
225  if (runmatch && typematch && tagmatch && descriptionmatch && versionmatch && valuematch) {
226  match.push_back(info);
227  }
228  }
229 
230  if (match.size() == 1) {
231  return match[0];
232  } else if (match.size() > 1) {
233  RESTWarning << "multiple metadata found! returning the first!" << RESTendl;
234  return match[0];
235  } else {
236  return DBEntry();
237  }
238  return DBEntry();
239 }
240 
241 // int TRestDataBase::add_metadata(DBEntry info, string url, bool overwrite) {
242 // if (TRestTools::isPathWritable(REST_USER_PATH)) {
243 // cout << "error! path not writable" << endl;
244 // return -1;
245 // }
246 //
247 // string metaFilename = REST_USER_PATH + "/dataURL";
248 //
249 // if (info.runNr == 0) {
250 // info.runNr = get_lastmetadata();
251 // }
252 // fDataEntries.push_back({info, url});
253 //
254 // std::ofstream file(metaFilename, std::ios::app);
255 // file << "\"" << info.runNr << "\" ";
256 // file << "\"" << info.type << "\" ";
257 // file << "\"" << info.tag << "\" ";
258 // file << "\"" << info.description << "\" ";
259 // file << "\"" << info.version << "\" ";
260 // file << "\"" << url << "\" ";
261 // file << endl;
262 // file.close();
263 //
264 // return info.runNr;
265 //}
266 //
virtual void Initialize()
default: read the dataURL file
TRestDataBase()
default constructor, setting fConnectionString according to the env
virtual int get_lastrun()
get the latest run id in database
virtual DBEntry query_data(DBEntry info)
virtual int set_run(DBEntry info, bool overwrite=true)
add/update a run, with run info as struct DBEntry. returns the added run id
static std::string Execute(std::string cmd)
Executes a shell command and returns its output in a string.
static bool fileExists(const std::string &filename)
Returns true if the file (or directory) with path filename exists.
Definition: TRestTools.cxx:728
static bool isPathWritable(const std::string &path)
Returns true if the path given by argument is writable.
Definition: TRestTools.cxx:778
static std::istream & GetLine(std::istream &is, std::string &t)
It reads the next line from the incoming istream and puts it in the string argument t....
static std::string ToAbsoluteName(const std::string &filename)
It takes a path and returns its absolute path.
Definition: TRestTools.cxx:868
std::vector< std::string > Split(std::string in, std::string separator, bool allowBlankString=false, bool removeWhiteSpaces=false, int startPos=-1)
Split the input string according to the given separator. Returning a vector of fragments.
std::string ToDateTimeString(time_t time)
Format time_t into string.