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