CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
LMFUnique.cc
Go to the documentation of this file.
2 #include <iomanip>
3 
4 using namespace std;
5 using namespace oracle::occi;
6 
8 }
9 
11  std::string ts = t.str();
12  return ts.substr(2, 2);
13 }
14 
15 LMFUnique& LMFUnique::setString(std::string key, std::string value) {
16  // check if this key exists
17  std::map<std::string, std::string>::const_iterator i =
18  m_stringFields.find(key);
19  if (i != m_stringFields.end()) {
20  // the key exist: check if it changed: reset the ID of the object
21  if (i->second != value) {
22  m_stringFields[key] = value;
23  m_ID = 0;
24  }
25  } else {
26  // create this key and reset the ID of the object
27  m_stringFields[key] = value;
28  m_ID = 0;
29  }
30  return *this;
31 }
32 
33 LMFUnique& LMFUnique::setInt(std::string key, int value) {
34  // check if this key exists
35  std::map<std::string, int>::const_iterator i = m_intFields.find(key);
36  if (i != m_intFields.end()) {
37  // the key exist: check if it changed: reset the ID of the object
38  if (i->second != value) {
39  m_intFields[key] = value;
40  m_ID = 0;
41  }
42  } else {
43  // create this key and reset the ID of the object
44  m_intFields[key] = value;
45  m_ID = 0;
46  }
47  return *this;
48 }
49 
50 void LMFUnique::attach(std::string name, LMFUnique *u) {
51  std::map<std::string, LMFUnique *>::const_iterator i =
52  m_foreignKeys.find(name);
53  if (i != m_foreignKeys.end()) {
54  if (i->second != u) {
55  m_foreignKeys[name] = u;
56  m_ID = 0;
57  }
58  } else {
59  m_foreignKeys[name] = u;
60  m_ID = 0;
61  }
62 }
63 
64 boost::ptr_list<LMFUnique> LMFUnique::fetchAll() const
65  throw(std::runtime_error)
66 {
67  /*
68  Returns a list of pointers to DB objects
69  */
70  boost::ptr_list<LMFUnique> l;
71  this->checkConnection();
72 
73  try {
74  Statement* stmt = m_conn->createStatement();
75  std::string sql = fetchAllSql(stmt);
76  if (sql != "") {
77  if (m_debug) {
78  cout << m_className + ": Query " + sql << endl;
79  }
80  ResultSet* rset = stmt->executeQuery();
81  while (rset->next() != 0) {
82  LMFUnique *o = createObject();
83  if (m_debug) {
84  o->debug();
85  }
86  if (o != NULL) {
87  o->setByID(rset->getInt(1));
88  if (m_debug) {
89  o->dump();
90  }
91  try {
92  l.push_back(o);
93  }
94  catch (boost::bad_pointer &e) {
95  throw(std::runtime_error(m_className + "::fetchAll: " +
96  e.what()));
97  }
98  }
99  }
100  }
101  m_conn->terminateStatement(stmt);
102  }
103  catch (SQLException &e) {
104  throw(std::runtime_error(m_className + "::fetchAll: "+e.getMessage()));
105  }
106  if (m_debug) {
107  cout << m_className << ": list size = " << l.size() << endl;
108  }
109  return l;
110 }
111 
112 void LMFUnique::dump() const {
113  dump(0);
114 }
115 
116 void LMFUnique::dump(int n) const {
117  /*
118  This method is used to dump the content of an object
119  Indent data if the object is contained inside another object
120  */
121  std::string m_indent = "";
122  std::string m_trail = "";
123  m_trail.resize(70 - 31 - n * 2, '#');
124  m_indent.resize(n*2, ' ');
125  m_indent += "|";
126  // start of object
127  cout << m_indent << "#################" << setw(15) << m_className
128  << " " << m_trail << endl;
129  cout << m_indent << "Address: " << this << endl;
130  cout << m_indent << "Connection params : " << m_env << ", " << m_conn << endl;
131  // object ID in the DB
132  cout << m_indent << "ID" << setw(18) << ": " << m_ID;
133  if (m_ID == 0) {
134  cout << " *** NULL ID ***";
135  }
136  if (!isValid()) {
137  cout << " INVALID ***";
138  }
139  cout << endl;
140  // iterate over string fields
141  std::map<std::string, std::string>::const_iterator is =
142  m_stringFields.begin();
143  std::map<std::string, std::string>::const_iterator es =
144  m_stringFields.end();
145  while (is != es) {
146  std::string key = is->first;
147  cout << m_indent << key << setw(20 - key.length()) << ": " << is->second
148  << endl;
149  is++;
150  }
151  // iterate over integer fields
152  std::map<std::string, int>::const_iterator ii = m_intFields.begin();
153  std::map<std::string, int>::const_iterator ei = m_intFields.end();
154  while (ii != ei) {
155  std::string key = ii->first;
156  cout << m_indent << key << setw(20 - key.length()) << ": " << ii->second
157  << endl;
158  ii++;
159  }
160  cout << m_indent << "#################" << setw(15) << m_className
161  << " " << m_trail << endl;
162  // iterate over foreign keys
163  std::map<std::string, LMFUnique*>::const_iterator ik = m_foreignKeys.begin();
164  std::map<std::string, LMFUnique*>::const_iterator ek = m_foreignKeys.end();
165  m_indent.clear();
166  m_indent.resize((n + 1) * 2, ' ');
167  while (ik != ek) {
168  cout << m_indent << "Foreign Key: " << ik->first << endl;
169  ik->second->dump(n + 1);
170  ik++;
171  }
172 }
173 
175  fetchID();
176  bool ret = false;
177  if (m_ID > 0) {
178  ret = true;
179  }
180  return ret;
181 }
182 
183 std::string LMFUnique::fetchAllSql(Statement *stmt) const {
184  /* this method should setup a Statement to select the unique IDs of the
185  objects to return */
186  return "";
187 }
188 
190  /* this method should return a pointer to a newly created object */
191  return NULL;
192 }
193 
194 std::string LMFUnique::getString(std::string s) const {
195  std::string rs = "";
196  std::map<std::string, std::string>::const_iterator i = m_stringFields.find(s);
197  if (i != m_stringFields.end()) {
198  rs = i->second;
199  }
200  return rs;
201 }
202 
203 int LMFUnique::getInt(std::string s) const {
204  // this should be better defined
205  int ret = 0;
206  std::map<std::string, int>::const_iterator i = m_intFields.find(s);
207  if (i != m_intFields.end()) {
208  ret = i->second;
209  }
210  return ret;
211 }
212 
214  throw(std::runtime_error)
215 {
216  /*
217  This method fetch the ID of the object from the database according
218  to the given specifications.
219 
220  It is assumed that there is only one object in the database with the
221  given specifications. In case more than one object can be retrieved
222  this method throws an exception.
223 
224  Since not all the specifications can define completely the object
225  itself, at the end, we setup the object based on its ID.
226  */
227  // Return tag from memory if available
228  if (m_ID) {
229  return m_ID;
230  }
231 
232  this->checkConnection();
233 
234  // fetch this ID
235  try {
236  Statement* stmt = m_conn->createStatement();
237  // prepare the sql query
238  std::string sql = fetchIdSql(stmt);
239  if (sql != "") {
240  if (m_debug) {
241  cout << m_className + ": Query " + sql << endl;
242  }
243 
244  ResultSet* rset = stmt->executeQuery();
245  if (rset->next() != 0) {
246  m_ID = rset->getInt(1);
247  } else {
248  m_ID = 0;
249  }
250  if (m_debug) {
251  cout << m_className + ": ID set to " << m_ID << endl;
252  }
253  int n = rset->getNumArrayRows();
254  if (m_debug) {
255  cout << m_className + ": Returned " << n << " rows" << endl;
256  }
257  if (n > 1) {
258  throw(std::runtime_error(m_className + "::fetchID: too many rows returned " +
259  "executing query " + sql));
260  m_ID = 0;
261  }
262  }
263  m_conn->terminateStatement(stmt);
264  } catch (SQLException &e) {
265  throw(std::runtime_error(m_className + "::fetchID: "+e.getMessage()));
266  }
267  // given the ID of this object setup it completely
268  if (m_ID > 0) {
269  setByID(m_ID);
270  }
271  // if foreignKeys are there, set these objects too
272  map<string, LMFUnique*>::iterator i = m_foreignKeys.begin();
273  map<string, LMFUnique*>::iterator e = m_foreignKeys.end();
274  while (i != e) {
275  if (i->second->getID() == 0) {
276  i->second->fetchID();
277  }
278  i++;
279  }
280  if (m_debug) {
281  cout << m_className << ": fetchID:: returning " << m_ID << endl;
282  }
283  return m_ID;
284 }
285 
286 void LMFUnique::setByID(int id)
287  throw(std::runtime_error)
288 {
289  /*
290  Given the ID of an object setup it
291  */
292  if (m_debug) {
293  cout << m_className << ": Setting this object as ID = " << id << endl;
294  }
295  this->checkConnection();
296  try {
297  Statement* stmt = m_conn->createStatement();
298  std::string sql = setByIDSql(stmt, id);
299  if (sql == "") {
300  throw(std::runtime_error(m_className + "::setByID: [empty sql])"));
301  }
302  if (m_debug) {
303  cout << m_className + ": " + sql << endl;
304  }
305 
306  ResultSet* rset = stmt->executeQuery();
307  if (rset->next() != 0) {
308  // setup the concrete object
309  getParameters(rset);
310  m_ID = id;
311  if (m_debug) {
312  cout << m_className + ": Setting done. ID set to " << m_ID << endl;
313  }
314  } else {
315  throw(std::runtime_error(m_className + "::setByID: Given id is not in the database"));
316  }
317  m_conn->terminateStatement(stmt);
318  } catch (SQLException &e) {
319  throw(std::runtime_error(m_className + "::setByID: "+e.getMessage()));
320  }
321 }
322 
324  throw(std::runtime_error)
325 {
326  std::map<std::string, LMFUnique*>::const_iterator i = m_foreignKeys.begin();
327  std::map<std::string, LMFUnique*>::const_iterator e = m_foreignKeys.end();
328  int count = 0;
329  while (i != e) {
330  if (i->second->getID() == 0) {
331  i->second->writeDB();
332  count++;
333  }
334  i++;
335  }
336  return count;
337 }
338 
340  throw(std::runtime_error)
341 {
342  clock_t start = 0;
343  clock_t end = 0;
344  if (_profiling) {
345  start = clock();
346  }
347  // write the associated objects first (foreign keys must exist before use)
348  writeForeignKeys();
349  // see if this data is already in the DB
350  if (!(this->fetchID())) {
351  // check the connectioin
352  this->checkConnection();
353 
354  // write new tag to the DB
355  std::string sql = "";
356  try {
357  Statement* stmt = m_conn->createStatement();
358 
359  sql = writeDBSql(stmt);
360  if (sql != "") {
361  if (m_debug) {
362  cout << m_className + ": " + sql << endl;
363  }
364  stmt->executeUpdate();
365  }
366  m_conn->commit();
367  m_conn->terminateStatement(stmt);
368  } catch (SQLException &e) {
369  debug();
370  dump();
371  throw(std::runtime_error(m_className + "::writeDB: " + e.getMessage() +
372  " while executing query " + sql));
373  }
374  // now get the id
375  if (this->fetchID() == 0) {
376  throw(std::runtime_error(m_className + "::writeDB: Failed to write"));
377  }
378  }
379  if (_profiling) {
380  end = clock();
381  if (m_debug) {
382  std::cout << m_className << ":: Spent time in writeDB:" <<
383  ((double) (end - start)) / CLOCKS_PER_SEC << " s" << endl;
384  }
385  }
386  return m_ID;
387 }
388 
int i
Definition: DBlmapReader.cc:9
LMFUnique & setInt(std::string key, int value)
Definition: LMFUnique.cc:33
oracle::occi::ResultSet ResultSet
Definition: LMFUnique.h:19
#define NULL
Definition: scimark2.h:8
virtual LMFUnique * createObject() const
Definition: LMFUnique.cc:189
virtual void dump() const
Definition: LMFUnique.cc:112
virtual int writeDB()
Definition: LMFUnique.cc:339
virtual bool exists()
Definition: LMFUnique.cc:174
oracle::occi::SQLException SQLException
Definition: HcalDbOmds.cc:22
virtual int writeForeignKeys()
Definition: LMFUnique.cc:323
int getInt(std::string fieldname) const
Definition: LMFUnique.cc:203
void setByID(int id)
Definition: LMFUnique.cc:286
std::string sequencePostfix(Tm t)
Definition: LMFUnique.cc:10
int fetchID()
Definition: LMFUnique.cc:213
oracle::occi::Statement Statement
Definition: LMFUnique.h:20
#define end
Definition: vmac.h:38
LMFUnique & setString(std::string key, std::string value)
Definition: LMFUnique.cc:15
virtual boost::ptr_list< LMFUnique > fetchAll() const
Definition: LMFUnique.cc:64
std::string str() const
Definition: Tm.cc:89
virtual ~LMFUnique()
Definition: LMFUnique.cc:7
list key
Definition: combine.py:13
virtual std::string fetchAllSql(Statement *stmt) const
Definition: LMFUnique.cc:183
tuple cout
Definition: gather_cfg.py:121
std::string getString(std::string fieldname) const
Definition: LMFUnique.cc:194
#define debug
Definition: MEtoEDMFormat.h:34
void attach(std::string name, LMFUnique *u)
Definition: LMFUnique.cc:50
void debug()
Definition: LMFUnique.h:68
Definition: Tm.h:14