Class Reference for E1039 Core & Analysis Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DbSvc.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <iomanip>
3 #include <sstream>
4 #include <cstdlib>
5 #include <fstream>
6 #include <wordexp.h> //to expand environmentals
7 #include <TMySQLServer.h>
8 #include <TSQLiteServer.h>
9 #include <TSQLStatement.h>
10 #include <TSQLResult.h>
11 #include <TSQLRow.h>
12 #include "DbSvc.h"
13 
14 #define LogInfo(message) std::cout << "DEBUG: " << __FILE__ << " " << __LINE__ << " " << __FUNCTION__ << " ::: " << message << std::endl
15 
16 using namespace std;
17 
18 bool FileExist(const std::string fileName)
19 {
20  std::ifstream infile(fileName.c_str());
21  return infile.good();
22 }
23 
24 std::string ExpandEnvironmentals( const std::string& input )
25 {
26  // expand any environment variables in the file name
27  wordexp_t exp_result;
28  if(wordexp(input.c_str(), &exp_result, 0) != 0)
29  {
30  std::cout << "ExpandEnvironmentals - ERROR - Your string '" << input << "' cannot be understood!" << endl;
31  return "";
32  }
33 
34  const string output( exp_result.we_wordv[0]);
35 
36  return output;
37 }
38 
39 DbSvc::DbSvc(const SvrId_t svr_id, const UsrId_t usr_id, const std::string my_cnf)
40 {
41  m_svr_id = svr_id;
42  m_usr_id = usr_id;
43  if (my_cnf.length() > 0) {
44  m_my_cnf = my_cnf;
45  } else {
46  if (usr_id == Guest) {
47  m_my_cnf = ExpandEnvironmentals("$E1039_RESOURCE/db_conf/guest.cnf");
48  //LogInfo("Using "<< m_my_cnf);
49  if (!FileExist(m_my_cnf)) {
50  LogInfo("DB Conf. "<< m_my_cnf << " doesn't exist");
51  }
52  }
53  else /* == Prod */ m_my_cnf = "my.cnf"; // not supported yet.
54  }
55  SelectServer();
56  ConnectServer();
57 }
58 
59 DbSvc::DbSvc(const SvrId_t svr_id, const std::string dbfile)
60 {
61  m_svr_id = svr_id;
62  if (m_svr_id != LITE) {
63  LogInfo("DbSvc::DbSvc(const SvrId_t, const std::string) is for sqlite db only.");
64  return;
65  }
66 
67  std::string m_dbfile = ExpandEnvironmentals(dbfile);
68  if (!FileExist(m_dbfile)) {
69  LogInfo("SQLITE DB file " << m_dbfile << " does not exist");
70  return;
71  }
72 
73  m_svr = Form("sqlite://%s", m_dbfile.c_str());
74  m_con = new TSQLiteServer(m_svr.c_str());
75 }
76 
78 {
79  if (m_con) delete m_con;
80 }
81 
82 void DbSvc::UseSchema(const char* name, const bool do_create, const bool do_drop)
83 {
84  bool found = false;
85  TSQLResult* res = m_con->GetDataBases(name);
86  TSQLRow* row = 0;
87  while ( (row = res->Next()) != 0 ) {
88  string val = row->GetField(0);
89  delete row;
90  if (val == name) found = true;
91  }
92  delete res;
93 
94  int ret = -1; // non-zero
95  if (found) {
96  if (do_drop) {
97  ret = m_con->DropDataBase(name);
98  if (ret == 0) ret = m_con->CreateDataBase(name);
99  } else {
100  ret = 0; // OK just as found.
101  }
102  } else {
103  if (do_create) ret = m_con->CreateDataBase(name);
104  }
105  if (ret == 0) ret = m_con->SelectDataBase(name);
106  if (ret != 0) {
107  cerr << "!!ERROR!! DbSvc::UseSchema: Failed to select '" << name << "'. Abort." << endl;
108  exit(1);
109  }
110 }
111 
112 void DbSvc::DropTable(const char* name)
113 {
114  string query = "drop table if exists ";
115  query += name;
116  if (! m_con->Exec(query.c_str())) {
117  cerr << "!!ERROR!! DbSvc::DropTable(): Failed on " << name << ". Abort." << endl;
118  exit(1);
119  }
120 }
121 
122 bool DbSvc::HasTable(const char* name, const bool exit_on_false)
123 {
124  if (m_con->HasTable(name)) return true;
125  if (exit_on_false) {
126  cerr << "!!ERROR!! DbSvc: The table '" << name << "' does not exist. Abort." << endl;
127  exit(1);
128  }
129  return false;
130 }
131 
132 void DbSvc::CreateTable(const std::string name, const std::vector<std::string> list_var, const std::vector<std::string> list_type, const std::vector<std::string> list_key)
133 {
134  if (HasTable(name)) {
135  cerr << "!!ERROR!! DbSvc::CreateTable(): Table '" << name << "' already exists. To avoid an unintended creation, please check and drop the table in your code. Abort." << endl;
136  exit(1);
137  }
138  if (list_var.size() != list_type.size()) {
139  cerr << "!!ERROR!! DbSvc::CreateTable(): The sizes of the var and type lists don't match. Abort." << endl;
140  exit(1);
141  }
142 
143  ostringstream oss;
144  oss << "create table " << name << "(";
145  for (unsigned int ii = 0; ii < list_var.size(); ii++) {
146  oss << list_var[ii] << " " << list_type[ii] << ", ";
147  }
148  if (list_key.size() == 0) {
149  oss << "primary_id INT not null auto_increment, PRIMARY KEY (primary_id)";
150  } else {
151  oss << "PRIMARY KEY (";
152  for (unsigned int ii = 0; ii < list_key.size(); ii++) {
153  if (ii != 0) oss << ", ";
154  oss << list_key[ii];
155  }
156  oss << ")";
157  }
158  oss << ")";
159  if (! m_con->Exec(oss.str().c_str())) {
160  cerr << "!!ERROR!! DbSvc::CreateTable(): The creation query failed. Abort." << endl;
161  exit(1);
162  }
163 }
164 
165 void DbSvc::CreateTable(const std::string name, const int n_var, const char** list_var, const char** list_type, const int n_key, const char** list_key)
166 {
167  vector<string> vec_var;
168  vector<string> vec_type;
169  for (int ii = 0; ii < n_var; ii++) {
170  vec_var .push_back(list_var [ii]);
171  vec_type.push_back(list_type[ii]);
172  }
173  vector<string> vec_key;
174  for (int ii = 0; ii < n_key; ii++) {
175  vec_key.push_back(list_key[ii]);
176  }
177  CreateTable(name, vec_var, vec_type, vec_key);
178 }
179 
180 void DbSvc::CreateTable(const std::string name, const VarList list)
181 {
182  vector<string> vec_var;
183  vector<string> vec_type;
184  vector<string> vec_key;
185  for (unsigned int ii = 0; ii < list.Size(); ii++) {
186  string name, type;
187  bool is_key;
188  list.Get(ii, name, type, is_key);
189  vec_var .push_back(name);
190  vec_type.push_back(type);
191  if (is_key) vec_key.push_back(name);
192  }
193  CreateTable(name, vec_var, vec_type, vec_key);
194 }
195 
206 TSQLStatement* DbSvc::Process(const char* query)
207 {
208  TSQLStatement* stmt = m_con->Statement(query);
209  if ((! stmt->Process()) && m_svr_id != LITE) { //sqlite returns false if the query returns no data - this should be accepted
210  cerr << "!!ERROR!! DbSvc::Process(): Failed to execute a statement: " << stmt << ".\n"
211  << "Abort." << endl;
212  exit(1);
213  }
214  stmt->StoreResult();
215  return stmt;
216 }
217 
218 void DbSvc::SelectServer()
219 {
220  if (m_svr_id == DB1 ) m_svr = "e906-db1.fnal.gov";
221  else if (m_svr_id == DB2 ) m_svr = "e906-db2.fnal.gov";
222  else if (m_svr_id == DB3 ) m_svr = "e906-db3.fnal.gov";
223  else if (m_svr_id == DB01) m_svr = "seaquestdb01.fnal.gov:3310";
224  else if (m_svr_id == UIUC) m_svr = "seaquel.physics.illinois.edu:3283";
225  else if (m_svr_id == LOCAL) m_svr = "localhost";
226  else {
227  cerr << "!!ERROR!! DbSvc(): Unsupported server ID. Abort.\n";
228  exit(1);
229  }
230 }
231 
232 void DbSvc::ConnectServer()
233 {
234  ostringstream oss;
235  oss << "mysql://" << m_svr << "/?reconnect=1&cnf_file=" << m_my_cnf;
236 
238  m_con = TMySQLServer::Connect(oss.str().c_str(), 0, 0);
239  if (! (m_con && m_con->IsConnected())) {
240  cerr << "!!ERROR!! DbSvc::ConnectServer(): Failed. Abort." << endl;
241  exit(1);
242  }
243 }
244 
245 void DbSvc::VarList::Add(const std::string name, const std::string type, const bool is_key)
246 {
247  m_name .push_back(name);
248  m_type .push_back(type);
249  m_is_key.push_back(is_key);
250 }
251 
252 void DbSvc::VarList::Get(const int idx, std::string& name, std::string& type, bool& is_key) const
253 {
254  name = m_name [idx];
255  type = m_type [idx];
256  is_key = m_is_key[idx];
257 }
void Get(const int idx, std::string &name, std::string &type, bool &is_key) const
Definition: DbSvc.cc:252
UsrId_t
Definition: DbSvc.h:12
void UseSchema(const char *name, const bool do_create=false, const bool do_drop=false)
Definition: DbSvc.cc:82
DbSvc(const SvrId_t svr_id=DB1, const UsrId_t usr_id=Guest, const std::string my_cnf="")
Definition: DbSvc.cc:39
SvrId_t
Definition: DbSvc.h:11
TSQLStatement * Process(const char *query)
Definition: DbSvc.cc:206
std::string ExpandEnvironmentals(const std::string &input)
Definition: DbSvc.cc:24
void Add(const std::string name, const std::string type, const bool is_key=false)
Definition: DbSvc.cc:245
bool FileExist(const std::string fileName)
Definition: DbSvc.cc:18
void CreateTable(const std::string name, const std::vector< std::string > list_var, const std::vector< std::string > list_type, const std::vector< std::string > list_key)
Definition: DbSvc.cc:132
unsigned int Size() const
Definition: DbSvc.h:18
bool HasTable(const char *name, const bool exit_on_false=false)
Definition: DbSvc.cc:122
~DbSvc()
Definition: DbSvc.cc:77
void DropTable(const char *name)
Definition: DbSvc.cc:112
#define LogInfo(message)
Definition: DbSvc.cc:14