Jpp  master_rocky-43-ge265d140c
the software that should make you happy
JDB.hh
Go to the documentation of this file.
1 #ifndef __JDB_JDB__
2 #define __JDB_JDB__
3 
4 #include <string>
5 #include <istream>
6 #include <ostream>
7 #include <fstream>
8 #include <stdlib.h>
9 #include <vector>
10 #include <map>
11 #include <algorithm>
12 #include <memory>
13 
14 #include "dbclient/KM3NeTDBClient.h"
15 
16 #include "JSystem/JStat.hh"
17 #include "JLang/JManip.hh"
18 #include "JSon/JSon.hh"
19 #include "Jeep/JVersion.hh"
20 #include "Jeep/JPrint.hh"
21 
22 #include "JDB/JDBReader.hh"
23 
24 
25 /**
26  * \author mdejong
27  */
28 namespace JDATABASE {}
29 namespace JPP { using namespace JDATABASE; }
30 
31 namespace JDATABASE {
32 
33  using KM3NeT::DB::DBException;
34  using KM3NeT::DB::Server;
35  using KM3NeT::DB::Client;
36  using KM3NeT::DB::ResultSet;
37  using KM3NeT::DB::Selector;
39  using JSON::json;
40  using JEEP::JVersion;
41 
42 
43  static const JVersion APIV2_VERSION(2,1,0); // APIv2 version
44 
45 
46  /**
47  * Wrapper class for server name.
48  *
49  * By reading the name of the server, this class will automatically set the server in class JDB.
50  */
51  struct JServer :
52  public std::string
53  {
54  /**
55  * Default constructor.
56  */
58  {}
59 
60 
61  /**
62  * Constructor.
63  *
64  * \param server server name
65  */
66  JServer(const char* server) :
67  std::string(server)
68  {}
69  };
70 
71 
72  /**
73  * Named list of available database servers.
74  */
76  { "Default", Server::Default },
77  { "Test", Server::Test },
78  { "Lyon", Server::Lyon },
79  { "Lyon2", Server::Lyon2 },
80  { "Napoli", Server::Napoli }
81  };
82 
83 
84  /**
85  * Get server by name.
86  *
87  * \param server server name
88  * \return server
89  */
90  inline const Server& getServer(const std::string& server)
91  {
92  for (const auto& element : LIST_OF_SERVERS) {
93  if (element.first == server) {
94  return element.second;
95  }
96  }
97 
98  THROW(JDatabaseException, "Invalid server name " << server);
99  }
100 
101 
102  /**
103  * Get list of names of available database servers.
104  *
105  * \return server names
106  */
108  {
109  std::vector<JServer> buffer;
110 
111  const char* const server = getenv("DATABASE_SERVER");
112 
113  if (server != NULL) {
114  buffer.push_back(server);
115  }
116 
117  for (const auto& element : LIST_OF_SERVERS) {
118  if (std::find(buffer.begin(), buffer.end(), element.first) == buffer.end()) {
119  buffer.push_back(element.first);
120  }
121  }
122 
123  return buffer;
124  }
125 
126 
127  /**
128  * Get default server.
129  *
130  * The default server is defined by:
131  * -# named server from environment variable DATABASE_SERVER; else
132  * -# first server in LIST_OF_SERVERS if not empty; else
133  * -# default server Server::Default;
134  *
135  * \return server
136  */
137  inline const Server& getServer()
138  {
139  const char* const server = getenv("DATABASE_SERVER");
140 
141  if (server != NULL)
142  return getServer(server);
143  else if (!LIST_OF_SERVERS.empty())
144  return LIST_OF_SERVERS[0].second;
145  else
146  return Server::Default;
147  }
148 
149 
150  /**
151  * Get private cookie.
152  *
153  * \return cookie
154  */
155  inline const char* getPrivateCookie()
156  {
157  const char* home = getenv("HOME");
158 
159  return MAKE_CSTRING((home != NULL ? home : ".") << "/" << ".km3netdb_cookie");
160  }
161 
162 
163  /**
164  * Get public cookie.
165  *
166  * \return cookie
167  */
168  inline const char* getPublicCookie()
169  {
170  return getenv("DBCOOKIE");
171  }
172 
173 
174  /**
175  * Cookie prefix.
176  */
177  static const char PREFIX_COOKIE = '_';
178 
179 
180  /**
181  * This string is prepended to every parameter in the database output for the corresponding process.
182  */
183  static const std::string PREFIX_DATAFILTER = "DAQ_triggerParameters";
184  static const std::string PREFIX_ADF = "DAQ_ADF";
185 
186 
187  /**
188  * Auxiliary class for connection to data base.
189  */
190  class JDB :
191  public std::shared_ptr<Client>
192  {
193  private:
194  /**
195  * Get server.
196  *
197  * \return server
198  */
199  static inline Server& get_server()
200  {
201  static Server server = JDATABASE::getServer();
202 
203  return server;
204  }
205 
206  public:
207  /**
208  * Get server.
209  *
210  * \return server
211  */
212  static inline const Server& getServer()
213  {
214  return get_server();
215  }
216 
217 
218  /**
219  * Set server.
220  *
221  * \param server server
222  */
223  static inline void setServer(const Server& server)
224  {
225  get_server() = server;
226  }
227 
228 
229  /**
230  * Get connection to database.
231  *
232  * \return database connection
233  */
234  static JDB& get()
235  {
236  static JDB db;
237 
238  return db;
239  }
240 
241 
242  /**
243  * Reset connection to database.
244  */
245  static void reset()
246  {
247  JDB& db = JDB::get();
248 
249  if (db.get() != NULL) {
250  db->Close();
251  static_cast<std::shared_ptr<Client>&>(db).reset();
252  }
253  }
254 
255 
256  /**
257  * Reset connection to database.
258  *
259  * \param usr user name
260  * \param pwd pass word
261  */
262  static void reset(const std::string& usr,
263  const std::string& pwd)
264  {
265  static_cast<std::shared_ptr<Client>&>(JDB::get()) = Client::Create(getServer(), usr.c_str(), pwd.c_str());
266  }
267 
268 
269  /**
270  * Reset connection to database.
271  *
272  * \param cookie persistent cookie
273  */
274  static void reset(const std::string& cookie)
275  {
276  using namespace std;
277  using namespace JPP;
278 
279  string buffer = cookie;
280 
281  if (getFileStatus(cookie.c_str())) {
282 
283  ifstream in(cookie.c_str());
284 
285  getline(in, buffer);
286 
287  in.close();
288  }
289 
290  const string::size_type pos = buffer.find(PREFIX_COOKIE);
291 
292  if (pos != string::npos) {
293  buffer.erase(0, pos);
294  }
295 
296  static_cast<std::shared_ptr<Client>&>(JDB::get()) = Client::Create(getServer(), buffer.c_str());
297  }
298 
299 
300  /**
301  * Reset connection to database.
302  *
303  * An attempt to make a connection to the database is made in the following order,
304  * using:
305  * -# user name and password, if neither empty;
306  * -# given cookie, if not empty;
307  * -# private cookie file (created with JCookie.sh);
308  * -# public cookie (defined by environment variable DBCOOKIE);
309  *
310  * \param usr user name
311  * \param pwd password
312  * \param cookie persistent cookie
313  */
314  static void reset(const std::string& usr,
315  const std::string& pwd,
316  const std::string& cookie)
317  {
318  using namespace std;
319  using namespace JPP;
320 
321  if (usr != "" && pwd != "")
322  JDB::reset(usr, pwd);
323  else if (cookie != "")
324  JDB::reset(cookie);
325  else if (getFileStatus(getPrivateCookie()))
327  else if (getPublicCookie() != NULL)
329  else
330  THROW(JDatabaseException, "Missing user name / password or cookie file.");
331  }
332 
333 
334  private:
335  /**
336  * Default constructor.
337  */
338  JDB()
339  {}
340 
341 
342  JDB(const JDB&);
343  JDB& operator=(const JDB&);
344  };
345 
346 
347  /**
348  * Read server name from input stream.
349  *
350  * This operation will accordingly set the database server, if possible.
351  *
352  * \param in input stream
353  * \param server server
354  * \return input stream
355  */
356  inline std::istream& operator>>(std::istream& in, JServer& server)
357  {
358  if (in >> static_cast<std::string&>(server)) {
359  JDB::setServer(getServer(server));
360  }
361 
362  return in;
363  }
364 
365 
366  /**
367  * Get table name.
368  *
369  * \return table name
370  */
371  template<class JTable_t>
372  inline const char* getTable()
373  {
374  return JTable_t::getName();
375  }
376 
377 
378  /**
379  * Get column name.
380  *
381  * \param data_member data member
382  * \return column name
383  */
384  template<class JTable_t, class JType_t>
385  inline const char* getColumn(JType_t JTable_t::*data_member)
386  {
387  JTable_t* pc = NULL;
388  TClass* rc = dynamic_cast<TClass*>(TDictionary::GetDictionary(typeid(JTable_t)));
389 
390  if (rc != NULL) {
391 
392  for( std::unique_ptr<TIterator> i(rc->GetListOfDataMembers()->MakeIterator()); const TDataMember* p = (const TDataMember*) i->Next(); ) {
393 
394  if (p->GetOffset() == (char*) &(pc->*data_member) - (char*) pc) {
395  return p->GetName();
396  }
397  }
398  }
399 
400  return NULL;
401  }
402 
403 
404  /**
405  * Get column names.
406  *
407  * \return column names
408  */
409  template<class JTable_t>
411  {
412  using namespace JPP;
413 
415 
416  TClass* rc = dynamic_cast<TClass*>(TDictionary::GetDictionary(typeid(JTable_t)));
417 
418  if (rc != NULL) {
419 
420  for (std::unique_ptr<TIterator> i(rc->GetListOfDataMembers()->MakeIterator()); const TDataMember* p = (const TDataMember*) i->Next(); ) {
421  if (JRootClass::is_class(*p)) {
422  buffer.push_back(p->GetName());
423  }
424  }
425  }
426 
427  return buffer;
428  }
429 
430 
431  /**
432  * Get result set.
433  *
434  * \param query query / table name
435  * \return result set
436  */
437  inline ResultSet& getResultSet(const std::string& query)
438  {
439  return JDB::get()->StreamDS(query.c_str(), std::vector<Selector>());
440  }
441 
442 
443  /**
444  * Get result set.
445  *
446  * \param query query / table name
447  * \param selection selection
448  * \return result set
449  */
450  inline ResultSet& getResultSet(const std::string& query, const std::vector<Selector>& selection)
451  {
452  return JDB::get()->StreamDS(query.c_str(), selection);
453  }
454 
455 
456  /**
457  * Get json.
458  *
459  * \param js json
460  * \param query query / table name
461  */
462  inline void get_json(json& js, const std::string& query)
463  {
464  *(JDB::get()->APIv2Select(APIV2_VERSION.toString().c_str(), query.c_str(), std::vector<Selector>())) >> js;
465  }
466 
467 
468  /**
469  * Get json.
470  *
471  * \param js json
472  * \param query query / table name
473  * \param selection selection
474  */
475  inline void get_json(json& js, const std::string& query, const std::vector<Selector>& selection)
476  {
477  *(JDB::get()->APIv2Select(APIV2_VERSION.toString().c_str(), query.c_str(), selection)) >> js;
478  }
479 }
480 
481 #endif
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:712
I/O manipulators.
I/O formatting auxiliaries.
#define MAKE_CSTRING(A)
Make C-string.
Definition: JPrint.hh:72
File status.
nlohmann::json json
static Server & get_server()
Get server.
Definition: JDB.hh:199
static JDB & get()
Get connection to database.
Definition: JDB.hh:234
static void reset(const std::string &cookie)
Reset connection to database.
Definition: JDB.hh:274
static void reset(const std::string &usr, const std::string &pwd)
Reset connection to database.
Definition: JDB.hh:262
static void reset()
Reset connection to database.
Definition: JDB.hh:245
static const Server & getServer()
Get server.
Definition: JDB.hh:212
static void setServer(const Server &server)
Set server.
Definition: JDB.hh:223
JDB(const JDB &)
JDB & operator=(const JDB &)
JDB()
Default constructor.
Definition: JDB.hh:338
static void reset(const std::string &usr, const std::string &pwd, const std::string &cookie)
Reset connection to database.
Definition: JDB.hh:314
Database exception.
Definition: JException.hh:684
Auxiliary classes and methods for database I/O.
Definition: JAHRS.hh:14
const Server & getServer()
Get default server.
Definition: JDB.hh:137
const char * getPrivateCookie()
Get private cookie.
Definition: JDB.hh:155
static const std::string PREFIX_ADF
Definition: JDB.hh:184
const char * getPublicCookie()
Get public cookie.
Definition: JDB.hh:168
const char * getTable()
Get table name.
Definition: JDB.hh:372
std::vector< std::string > getColumns()
Get column names.
Definition: JDB.hh:410
static std::vector< std::pair< JServer, Server > > LIST_OF_SERVERS
Named list of available database servers.
Definition: JDB.hh:75
ResultSet & getResultSet(const std::string &query, const std::vector< Selector > &selection)
Get result set.
Definition: JDB.hh:450
static const std::string PREFIX_DATAFILTER
This string is prepended to every parameter in the database output for the corresponding process.
Definition: JDB.hh:183
std::istream & operator>>(std::istream &in, JServer &server)
Read server name from input stream.
Definition: JDB.hh:356
void get_json(json &js, const std::string &query, const std::vector< Selector > &selection)
Get json.
Definition: JDB.hh:475
static const char PREFIX_COOKIE
Cookie prefix.
Definition: JDB.hh:177
const char * getColumn(JType_t JTable_t::*data_member)
Get column name.
Definition: JDB.hh:385
const Server & getServer(const std::string &server)
Get server by name.
Definition: JDB.hh:90
static const JVersion APIV2_VERSION(2, 1, 0)
std::vector< JServer > getServernames()
Get list of names of available database servers.
Definition: JDB.hh:107
std::istream & getline(std::istream &in, JString &object)
Read string from input stream until end of line.
Definition: JString.hh:478
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
const char * getName()
Get ROOT name of given data type.
Definition: JRootToolkit.hh:62
static JStat getFileStatus
Function object for file status.
Definition: JStat.hh:173
Definition: JSTDTypes.hh:14
Wrapper class for server name.
Definition: JDB.hh:53
JServer(const char *server)
Constructor.
Definition: JDB.hh:66
JServer()
Default constructor.
Definition: JDB.hh:57
Auxiliary data structure for general purpose version number.
std::string toString() const
Convert version to string.
static bool is_class(const char *const name)
Check name of class against ROOT classes.
Definition: JRootClass.hh:50