StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StDbConfigNodeImpl.cc
1 /***************************************************************************
2  *
3  * $Id: StDbConfigNodeImpl.cc,v 1.11 2016/05/25 20:40:01 dmitry Exp $
4  *
5  * Author: R. Jeff Porter
6  ***************************************************************************
7  *
8  * Description: Payload Implementatoin of pure virtual Node (directory) class
9  * StDbConfigNode --> to hold list of dbtables
10  *
11  ***************************************************************************
12  *
13  * $Log: StDbConfigNodeImpl.cc,v $
14  * Revision 1.11 2016/05/25 20:40:01 dmitry
15  * coverity - reverse_inull
16  *
17  * Revision 1.10 2016/05/24 20:26:48 dmitry
18  * coverity - unreachable delete loop suppression
19  *
20  * Revision 1.9 2011/11/28 17:03:08 dmitry
21  * dbv override support in StDbLib,StDbBroker,St_db_Maker
22  *
23  * Revision 1.8 2007/03/08 22:07:22 deph
24  * Fixed small memory leak in removeTable
25  *
26  * Revision 1.7 2004/01/15 00:02:25 fisyak
27  * Replace ostringstream => StString, add option for alpha
28  *
29  * Revision 1.6 2003/09/16 22:44:17 porter
30  * got rid of all ostrstream objects; replaced with StString+string.
31  * modified rules.make and added file stdb_streams.h for standalone compilation
32  *
33  * Revision 1.5 2003/09/02 17:57:49 perev
34  * gcc 3.2 updates + WarnOff
35  *
36  * Revision 1.4 2003/01/10 04:19:20 porter
37  * added feature of getting timestamp list (but no data) for a table.
38  * fixed 2 features sometimes used in online in query-by-whereclause.
39  * removed a stray 'cout' in a routine that is rarely accessed
40  *
41  * Revision 1.3 2001/10/26 16:35:28 porter
42  * improved directory search
43  *
44  * Revision 1.2 2001/02/09 23:06:24 porter
45  * replaced ostrstream into a buffer with ostrstream creating the
46  * buffer. The former somehow clashed on Solaris with CC5 iostream (current .dev)
47  *
48  * Revision 1.1 2001/01/22 18:37:52 porter
49  * Update of code needed in next year running. This update has little
50  * effect on the interface (only 1 method has been changed in the interface).
51  * Code also preserves backwards compatibility so that old versions of
52  * StDbLib can read new table structures.
53  * -Important features:
54  * a. more efficient low-level table structure (see StDbSql.cc)
55  * b. more flexible indexing for new systems (see StDbElememtIndex.cc)
56  * c. environment variable override KEYS for each database
57  * d. StMessage support & clock-time logging diagnostics
58  * -Cosmetic features
59  * e. hid stl behind interfaces (see new *Impl.* files) to again allow rootcint access
60  * f. removed codes that have been obsolete for awhile (e.g. db factories)
61  * & renamed some classes for clarity (e.g. tableQuery became StDataBaseI
62  * and mysqlAccessor became StDbSql)
63  *
64  *
65  **************************************************************************/
66 #include "stdb_streams.h"
67 #include <string.h>
68 #include "StDbConfigNodeImpl.hh"
69 #include "StDbManagerImpl.hh" // could be StDbManager.hh but for dbEnvList def
70 #include "StDbTableIterImpl.hh"
71 #include "StDbElementIndex.hh"
72 
73 #define __CLASS__ "StDbConfigNodeImpl"
74 
76 
77 StDbConfigNodeImpl::StDbConfigNodeImpl(StDbConfigNode* parent, const char* nodeName, const char* configName): StDbConfigNode(parent,nodeName,configName), mindexRef(-1) {
78  melementIndex = new StDbElementIndex();
79  setConfigured(false);
80  mcanRollBack=false;
81  updateDbInfo();
82 }
83 
85 
86 StDbConfigNodeImpl::StDbConfigNodeImpl(StDbConfigNode* parent, StDbNode& node): StDbConfigNode(parent,node), mindexRef(-1) {
87  melementIndex = new StDbElementIndex();
88  updateDbInfo();
89 }
90 
92 
93 StDbConfigNodeImpl::StDbConfigNodeImpl(StDbType type, StDbDomain domain, const char* nodeName, const char* configName): StDbConfigNode(type,domain,nodeName,configName), mindexRef(-1) {
94  melementIndex = new StDbElementIndex();
95  updateDbInfo();
96 }
97 
99 
100 StDbConfigNodeImpl::~StDbConfigNodeImpl(){
101 deleteTables();
102 delete melementIndex;
103 };
104 
106 void
107 StDbConfigNodeImpl::updateDbInfo(){
108 #define __METHOD__ "updateDbInfo()"
109 
110  if(mparentNode)melementIndex->addElementIndex(mparentNode->getElementIndex());
111 
112  // If StarDb Type, then name holds map to real Db type
113  // while the domain may still be StarDb
114  // Else if StarDb domain, then name holds map to real domain type
115  // Else both type & domain are that of parent (which maybe User defined)
116 
117  misConfigured = false;
118  if(mparentNode){ //top level node will have type&domain set by the manager.
119  if(mdbType==dbStDb){
120  mdbType=StDbManager::Instance()->getDbType(mname);
121  } else if(mdbDomain==dbStar) {
122  mdbDomain=StDbManager::Instance()->getDbDomain(mname);
123  }
124  }
125 
126  if(!mnodeType) mnodeType=mstrDup("DB");
127  // replace nodetype of DB to Config moving from 1 db to another
128  // & allow overwriting of versionkey with environment variable
129  if(strcmp(mnodeType,"DB")==0){
130  setIsDbNode(true);
131  delete [] mnodeType;
132  mnodeType=mstrDup("Config");
133  setBranchID(0);
134  char* version=StDbManager::Instance()->getExternalVersion(mdbType,mdbDomain);
135  if(version && strcmp(version,mversion)){
136  StString nm;
137  nm<<" Overriding Key="<<mversion<<" with Environment Var Key="<<version;
138  nm<<" for DataBase=";
139  nm<<StDbManager::Instance()->printDbName(mdbType,mdbDomain);
140  StDbManager::Instance()->printInfo((nm.str()).c_str(),dbMWarn,__LINE__,__CLASS__,__METHOD__);
141  setVersion(version);
142  }
143  }
144 
145 #undef __METHOD__
146 }
147 
149 int
150 StDbConfigNodeImpl::buildTree(int opt){
151 #define __METHOD__ "buildTree(int opt)"
152 
153  StDataBaseI *db = StDbManager::Instance()->findDb(mdbType, mdbDomain);
154 
155  if(!db)
156  return StDbManager::Instance()->printInfo(" No DB found for Node=",mname,dbMErr,__LINE__,__CLASS__,__METHOD__);
157 
158  if(db->QueryDb(this)){
159  // check if we should connect via environment variables
160  if(isDbNode() && mdbDomain==dbStar){
161  dbEnvList* elist = StDbManager::Instance()->getEnvList(mname);
162  if(elist){
163  addChildren(elist);
164  delete elist;
165  }
166  }
167  // load descriptors & element structure as needed
168  updateDbTables(opt);
169  if(mfirstChildNode)mfirstChildNode->buildTree(opt);
170  }
171 
172  if(mnextNode)mnextNode->buildTree(opt);
173 
174  return 1;
175 #undef __METHOD__
176 }
177 
179 void StDbConfigNodeImpl::updateDbTables(int opt){
180 
181  if(!mhasData)return;
182  StDataBaseI* db=StDbManager::Instance()->findDb(mdbType, mdbDomain);
183  if(!db) return;
184 
185  StDbTableIter* itr = getStDbTableIter();
186  StDbTable* table;
187  while((itr) && !(itr->done())){
188  table=itr->next();
189  updateDbTable(table,opt);
190  }
191  if(itr)delete itr;
192 
193 }
195 void StDbConfigNodeImpl::updateDbTable(StDbTable* table, int opt){
196 
197  if(!table) return;
198  StDataBaseI* db=StDbManager::Instance()->findDb(mdbType, mdbDomain);
199  if(!db)return;
200 
201  int nRows;
202  char* elements=table->printElementName();
203  if(elements){
204  int* eList=db->selectElements(elements,melementIndex,nRows);
205  if(eList){
206  table->setElementID(eList,nRows);
207  delete [] eList;
208  }
209  }
210  if(!opt) db->QueryDescriptor(table);
211 }
212 
214 
215 StDbTable*
216 StDbConfigNodeImpl::addDbTable(const char* tableName, const char* version){
217 
218  // just like addTable but also loads the descriptor from the database
219  StDbTable* table = addTable(tableName,version);
220  updateDbTable(table);
221  return table;
222 }
223 
225 
226 StDbTable*
227 StDbConfigNodeImpl::addTable(const char* tableName, const char* version){
228 
229  StDbTable* table = 0;
230  table = StDbManager::Instance()->newDbTable(mdbName,tableName);
231  if (table) {
232  mTables.push_back(table);
233  table->setVersion((char*)version);
234  table->setNodeType("table");
235  }
236  StDataBaseI* db = StDbManager::Instance()->findDb(mdbType, mdbDomain);
237  if(db && table && db->QueryDb((StDbNode*)table)) { mhasData = true; }
238  return table;
239 }
240 
242 StDbTable*
243 StDbConfigNodeImpl::addTable(StDbNode* node){
244 
245  StDbTable* table = StDbManager::Instance()->newDbTable(node);
246  if(table){
247  mTables.push_back(table);
248  mhasData=true;
249  }
250 
251 return table;
252 }
253 
255 StDbTable*
256 StDbConfigNodeImpl::findTable(const char* name, const char* subPath){
257 
258 if(subPath && (strcmp(subPath,"/")==0))return findLocalTable(name);
259 
260 StDbConfigNode* node = findConfigNode(subPath);
261 if(node)return node->findLocalTable(name);
262 
263 // if we got here then we can't find it
264  StDbTable* table=0;
265 return table;
266 }
267 
269 
270 StDbTable*
271 StDbConfigNodeImpl::findLocalTable(const char* name){
272 
273  TableList::iterator itr;
274  StDbTable* table=0;
275  for(itr = mTables.begin(); itr!=mTables.end(); ++itr){
276  if((*itr)->checkName(name)){
277  table=*itr;
278  break;
279  }
280  }
281 return table;
282 }
283 
285 void
286 StDbConfigNodeImpl::removeTable(StDbTable* table){
287 
288  if(!table)return;
289  TableList::iterator itr;
290  StDbTable* myTable=0;
291 
292  for(itr = mTables.begin(); itr!=mTables.end(); ++itr){
293  myTable=*itr;
294  if(myTable && compareTables(myTable,table)){
295  delete *itr;
296  mTables.erase(itr); break;
297  }
298  myTable=0;
299  }
300 }
301 
303 void
304 StDbConfigNodeImpl::setTablesFlavor(const char* flavor){
305 
306  TableList::iterator itr;
307  for(itr = mTables.begin(); itr!=mTables.end(); ++itr){
308  if((*itr))(*itr)->setFlavor(flavor);
309  }
310 }
311 
313 void
314 StDbConfigNodeImpl::setTablesProdTime(unsigned int ptime){
315 
316  TableList::iterator itr;
317  for(itr = mTables.begin(); itr!=mTables.end(); ++itr){
318  if((*itr))(*itr)->setProdTime(ptime);
319  }
320 }
321 
323 void
324 StDbConfigNodeImpl::setTablesProdTimeOverride(unsigned int ptime, char* dbType, char* dbDomain) {
325  TableList::iterator itr;
326  for(itr = mTables.begin(); itr!=mTables.end(); ++itr) {
327  if((*itr))(*itr)->setProdTime(ptime);
328  }
329 }
330 
332 bool
333 StDbConfigNodeImpl::compareTables(StDbTable* tab1, StDbTable* tab2){
334 
335 bool retVal=false;
336 // compare name & version
337  if((strcmp(tab1->printName(),tab2->printName())!=0)) return retVal;
338  if((strcmp(tab1->printVersion(),tab2->printVersion())!=0)) return retVal;
339 // compare each row identifier
340  int nRows1; int nRows2;
341  int* elements1 = tab1->getElementID(nRows1);
342  int* elements2 = tab2->getElementID(nRows2);
343  if(nRows1 != nRows2) return retVal;
344  int i;
345  for(i=0;i<nRows1;i++)if(elements1[i] != elements2[i])break;
346  if(i==nRows1)retVal=true;
347 return retVal;
348 }
349 
351 StDbElementIndex* StDbConfigNodeImpl::getElementIndex(){return melementIndex; }
352 
354 void
355 StDbConfigNodeImpl::setElementIndexInfo(const char* indexName, int indexID){
356  mindexRef=melementIndex->addNameValuePair(indexName,indexID);
357 }
358 
360 void
361 StDbConfigNodeImpl::getElementIndexInfo(char*& indexName, int& indexID){
362 
363  if(mindexRef < 0){ indexName=0; return; }
364  indexName=melementIndex->getIndexName(mindexRef);
365  indexID =melementIndex->getIndexVal(mindexRef);
366 }
367 
369 int
370 StDbConfigNodeImpl::getNumIndeces() const { return melementIndex->getNumIndeces();}
371 
374 StDbConfigNodeImpl::getStDbTableIter(){
375  StDbTableIter* itr = new StDbTableIterImpl(this);
376  return itr;
377 }
378 
379 
381 void
382 StDbConfigNodeImpl::resetConfig(const char* configName, int opt){
383 
384 if(mfirstChildNode)mfirstChildNode->deleteTree();
385 if(mhasData)deleteTables();
386 setVersion(configName);
387 buildTree(opt);
388 }
389 
390 
392 void
393 StDbConfigNodeImpl::deleteTables(){
394  for( auto &it : mTables ) delete it;
395  mTables.clear();
396  mhasData=false;
397 }
398 
400 void
401 StDbConfigNodeImpl::addChildren(dbEnvList* elist){
402 #define __METHOD__ "addChildren(dbEnvList*)"
403 
404  for(int i=0; i<elist->num; i++){
405  char* id=strstr(elist->envVar[i],"_");
406  if(id){
407  id++;
408  if(strcmp(id,mname) && !findChildConfigNode(id)){
409  StString nm;
410  nm<<" Adding DataBase="<<elist->envVar[i]<<" with KEY=";
411  nm<<elist->envDef[i]<<" from Environment variable definition";
412  StDbManager::Instance()->printInfo((nm.str()).c_str(),dbMWarn,__LINE__,__CLASS__,__METHOD__);
413 //VP delete [] nMes;
414  new StDbConfigNodeImpl(this,id,elist->envDef[i]);
415  }
416  }
417  }
418 #undef __METHOD__
419 }
420 
422 void
423 StDbConfigNodeImpl::printTables(int depth){
424 
425  if(StDbManager::Instance()->IsVerbose()){
426  StString os;
427  for(int k=0;k<depth;k++)os<<" ";
428 
429  string pdepth=os.str();
430  TableList::iterator itr;
431  for(itr = mTables.begin(); itr!=mTables.end(); ++itr){
432  cout<<pdepth<<"Table="<<(*itr)->printName()<<", Version="<<(*itr)->printVersion();
433  int nRows;
434  int* eIDs=(*itr)->getElementID(nRows);
435  cout <<", numRows="<<nRows;
436  if(nRows==1)cout<<", elementID="<<eIDs[0];
437  cout<<endl;
438  }
439 //VP delete [] pdepth;
440  }
441 }
442 
443 void
444 StDbConfigNodeImpl::printNumberStats() {
445 #define __METHOD__ "printNumberStats()"
446 
447 unsigned int numNodes, numTables, numBytes;
448  numNodes=numTables=numBytes=0;
449  getNumberStats(numNodes,numTables, numBytes);
450  double kbs = ((double)numBytes)/1000.0;
451  StString cos;
452  cos<<"******************** Number Stats ******************** "<<stendl;
453  cos<<"Total Number of Nodes = "<<numNodes <<stendl;
454  cos<<"Total Number of Tables = "<<numTables <<stendl;
455  cos<<"Total Size of Data in Tables = "<<kbs<<" kBytes" <<stendl;
456  cos<<"******************************************************" <<stendl;
457 
458  StDbManager::Instance()->printInfo((cos.str()).c_str(),dbMConnect,__LINE__,__CLASS__,__METHOD__);
459 //VP delete [] nstats;
460 
461 #undef __METHOD__
462 }
463 
465 void
466 StDbConfigNodeImpl::getNumberStats(unsigned int& numNodes, unsigned int& numTables, unsigned int& numBytes){
467 
468  numNodes++;
469  StDbTableIter* itr = getStDbTableIter();
470  StDbTable* table;
471  while((itr) && !(itr->done())){
472  table=itr->next();
473  numTables++;
474  numBytes+=(table->getTableSize()*table->GetNRows());
475  }
476  if(itr)delete itr;
477  if(mfirstChildNode)mfirstChildNode->getNumberStats(numNodes,numTables,numBytes);
478  if(mnextNode)mnextNode->getNumberStats(numNodes,numTables,numBytes);
479 }
480 #undef __CLASS__
481 
void version(std::ostream &os=std::cout)
print HepMC version
Definition: Version.h:27
static StDbManager * Instance()
strdup(..) is not ANSI
Definition: StDbManager.cc:155