StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StDbConfigNode.cc
1 /***************************************************************************
2  *
3  * $Id: StDbConfigNode.cc,v 1.30 2021/02/08 15:13:11 dmitry Exp $
4  *
5  * Author: R. Jeff Porter
6  ***************************************************************************
7  *
8  * Description: Node (directory) to hold list of dbtables
9  *
10  ***************************************************************************
11  *
12  * $Log: StDbConfigNode.cc,v $
13  * Revision 1.30 2021/02/08 15:13:11 dmitry
14  * bugfix: override unknown db domain
15  *
16  * Revision 1.29 2012/03/16 19:36:18 dmitry
17  * converted dangled char pointers to std::string objects + fixed typo
18  *
19  * Revision 1.28 2012/03/16 17:36:46 dmitry
20  * added * symbol to global override indicators
21  *
22  * Revision 1.27 2012/03/14 18:12:45 dmitry
23  * Added protection against zero-sized strings and whitespaces sent as dbType. Null pointer was expected to indicate omitted dbType, but now StDbLib code receives \0 string instead (from upstream, checked St_db_Maker, StDbBroker, StDbConfigNode).
24  *
25  * Revision 1.26 2011/11/28 17:03:08 dmitry
26  * dbv override support in StDbLib,StDbBroker,St_db_Maker
27  *
28  * Revision 1.25 2004/01/15 00:02:25 fisyak
29  * Replace ostringstream => StString, add option for alpha
30  *
31  * Revision 1.24 2003/09/16 22:44:17 porter
32  * got rid of all ostrstream objects; replaced with StString+string.
33  * modified rules.make and added file stdb_streams.h for standalone compilation
34  *
35  * Revision 1.23 2003/09/02 17:57:49 perev
36  * gcc 3.2 updates + WarnOff
37  *
38  * Revision 1.22 2003/01/10 04:19:20 porter
39  * added feature of getting timestamp list (but no data) for a table.
40  * fixed 2 features sometimes used in online in query-by-whereclause.
41  * removed a stray 'cout' in a routine that is rarely accessed
42  *
43  * Revision 1.21 2001/10/26 16:35:28 porter
44  * improved directory search
45  *
46  * Revision 1.20 2001/01/22 18:37:52 porter
47  * Update of code needed in next year running. This update has little
48  * effect on the interface (only 1 method has been changed in the interface).
49  * Code also preserves backwards compatibility so that old versions of
50  * StDbLib can read new table structures.
51  * -Important features:
52  * a. more efficient low-level table structure (see StDbSql.cc)
53  * b. more flexible indexing for new systems (see StDbElememtIndex.cc)
54  * c. environment variable override KEYS for each database
55  * d. StMessage support & clock-time logging diagnostics
56  * -Cosmetic features
57  * e. hid stl behind interfaces (see new *Impl.* files) to again allow rootcint access
58  * f. removed codes that have been obsolete for awhile (e.g. db factories)
59  * & renamed some classes for clarity (e.g. tableQuery became StDataBaseI
60  * and mysqlAccessor became StDbSql)
61  *
62  * Revision 1.19 2000/06/30 01:57:01 porter
63  * fixed a delete bug & small memory leak found by Akio via Insure++ ,
64  * updated SetTable() method for containing idList, corrected enumeration
65  * map to rhic domain for Conditions_rhic database
66  *
67  * Revision 1.18 2000/04/25 18:26:02 porter
68  * added flavor & production time as settable query fields in
69  * table &/or node. Associated SQL updated in mysqlAccessor.
70  * Flavor key supports "+" as an OR symbol.
71  *
72  * Revision 1.17 2000/03/28 17:03:18 porter
73  * Several upgrades:
74  * 1. configuration by timestamp for Conditions
75  * 2. query by whereClause made more systematic
76  * 3. conflict between db-stored comments & number lists resolved
77  * 4. ensure endtime is correct for certain query falures
78  * 5. dbstl.h->handles ObjectSpace & RogueWave difference (Online vs Offline)
79  *
80  * Revision 1.16 2000/03/01 20:56:15 porter
81  * 3 items:
82  * 1. activated reConnect for server timeouts
83  * 2. activated connection sharing; better resource utilization but poorer
84  * logging
85  * 3. made rollback method in mysqlAccessor more robust (affects writes only)
86  *
87  * Revision 1.15 2000/02/15 20:27:44 porter
88  * Some updates to writing to the database(s) via an ensemble (should
89  * not affect read methods & haven't in my tests.
90  * - closeAllConnections(node) & closeConnection(table) method to mgr.
91  * - 'NullEntry' version to write, with setStoreMode in table;
92  * - updated both StDbTable's & StDbTableDescriptor's copy-constructor
93  *
94  * Revision 1.14 2000/01/27 05:54:33 porter
95  * Updated for compiling on CC5 + HPUX-aCC + KCC (when flags are reset)
96  * Fixed reConnect()+transaction model mismatch
97  * added some in-code comments
98  *
99  * Revision 1.13 2000/01/19 20:20:04 porter
100  * - finished transaction model needed by online
101  * - fixed CC5 compile problem in StDbNodeInfo.cc
102  * - replace TableIter class by StDbTableIter to prevent name problems
103  *
104  * Revision 1.12 2000/01/14 14:50:52 porter
105  * expanded use of verbose mode & fixed inconsistency in
106  * StDbNodeInfo::getElementID
107  *
108  * Revision 1.11 2000/01/10 20:37:53 porter
109  * expanded functionality based on planned additions or feedback from Online work.
110  * update includes:
111  * 1. basis for real transaction model with roll-back
112  * 2. limited SQL access via the manager for run-log & tagDb
113  * 3. balance obtained between enumerated & string access to databases
114  * 4. 3-levels of diagnostic output: Quiet, Normal, Verbose
115  * 5. restructured Node model for better XML support
116  *
117  * Revision 1.10 1999/12/28 21:31:41 porter
118  * added 'using std::vector' and 'using std::list' for Solaris CC5 compilation.
119  * Also fixed some warnings arising from the CC5 compiles
120  *
121  * Revision 1.9 1999/12/03 22:24:00 porter
122  * expanded functionality used by online, fixed bug in
123  * mysqlAccessor::getElementID(char*), & update StDbDataSet to
124  * conform to changes in Xml reader & writer
125  *
126  * Revision 1.8 1999/09/30 02:06:03 porter
127  * add StDbTime to better handle timestamps, modify SQL content (mysqlAccessor)
128  * allow multiple rows (StDbTable), & Added the comment sections at top of
129  * each header and src file
130  *
131  **************************************************************************/
132 
133 #include "stdb_streams.h"
134 #include <string.h>
135 
136 #include "StDbConfigNode.hh"
137 #include "StDbManager.hh"
138 #include "StDbTable.h"
139 
140 #ifdef __ROOT__
141 ClassImp(StDbConfigNode)
142 #endif
143 
144 #define __CLASS__ "StDbConfigNode"
145 
147 
148 StDbConfigNode::StDbConfigNode(StDbConfigNode* parent, const char* nodeName, const char* configName): StDbNode(nodeName,configName) {
149 
150  zeroNodes();
151  setParentNode(parent);
152  setDbName(parent->printDbName());
153  setDbType(parent->getDbType());
154  setDbDomain(parent->getDbDomain());
155 }
156 
158 StDbConfigNode::StDbConfigNode(StDbConfigNode* parent, StDbNode& node): StDbNode(node) {
159  zeroNodes();
160  setParentNode(parent);
161 }
162 
164 StDbConfigNode::StDbConfigNode(StDbType type, StDbDomain domain, const char* nodeName, const char* configName): StDbNode(nodeName,configName) {
165 
166  zeroNodes();
167  mdbType = type;
168  mdbDomain = domain;
169 }
170 
172 StDbConfigNode::~StDbConfigNode(){ deleteChildren();};
173 
175 void StDbConfigNode::zeroNodes() {
176  mfirstChildNode=0;
177  mnextNode=0;
178  mparentNode=0;
179  mhasData=false;
180  mbranchID=0;
181  misDbNode=false;
182 };
183 
184 
186 void
187 StDbConfigNode::setFlavor(const char* flavor){
188 
189  setTablesFlavor(flavor);
190  if(mfirstChildNode)mfirstChildNode->setFlavor(flavor);
191  if(mnextNode)mnextNode->setFlavor(flavor);
192 
193 }
194 
196 void
197 StDbConfigNode::setProdTime(unsigned int ptime){
198  setTablesProdTime(ptime);
199  if(mfirstChildNode)mfirstChildNode->setProdTime(ptime);
200  if(mnextNode)mnextNode->setProdTime(ptime);
201 }
202 
204 void
205 StDbConfigNode::setProdTimeOverride(unsigned int ptime, char* dbType, char* dbDomain) {
206  bool isAllTypesAccepted = false;
207 
208  // ***** get complete name for user-selected override *****
209  std::string completeName;
210  if (dbType && dbType[0] != '\0' && dbType[0] != ' ' && dbType[0] != '*') {
211  completeName.append(dbType);
212  } else {
213  isAllTypesAccepted = true;
214  }
215  completeName.append("_");
216  if (dbDomain && dbDomain[0] != '\0' && dbDomain[0] != ' ' && dbDomain[0] != '*') {
217  completeName.append(dbDomain);
218  }
219 
220  // ***** get current name for a node ******
221  std::string currentName;
222  if ( this->getDbDomain() <= dbDUser1 ) { // override only when domain is known to the library
223  if (!isAllTypesAccepted) {
224  // strict check, dbType is provided
225  currentName = StDbManager::Instance()->printDbName( this->getDbType(), this->getDbDomain() ) ;
226  } else {
227  // dbType is not provided, check domainName only
228  currentName.append("_");
229  currentName.append( StDbManager::Instance()->getDbDomainName( this->getDbDomain() ) ) ;
230  }
231  }
232 
233  // ***** compare names, override if needed *****
234  if (completeName == currentName) {
235  //std::cout << "complete = current = " << completeName <<", overriding\n";
236  setTablesProdTimeOverride(ptime, dbType, dbDomain);
237  }
238 
239  if (mfirstChildNode) {
240  //std::cout << "first child node: " << StDbManager::Instance()->printDbName( mfirstChildNode->getDbType(), mfirstChildNode->getDbDomain() ) << "\n";
241  mfirstChildNode->setProdTimeOverride(ptime, dbType, dbDomain);
242  }
243 
244  if (mnextNode) {
245  //std::cout << "next node: " << StDbManager::Instance()->printDbName( mnextNode->getDbType(), mnextNode->getDbDomain() ) << "\n";
246  mnextNode->setProdTimeOverride(ptime, dbType, dbDomain);
247  }
248 }
249 
251 
252 void
253 StDbConfigNode::deleteTree(){
254 
255  if(mfirstChildNode)delete mfirstChildNode;
256  if(mnextNode){
257  mnextNode->deleteTree();
258  delete mnextNode;
259  }
260 }
261 
263 void
264 StDbConfigNode::deleteChildren(){
265 
266  StDbConfigNode* nextChild = mfirstChildNode;
267  while(nextChild){
268  StDbConfigNode* node=nextChild->getNextNode();
269  delete nextChild;
270  nextChild=node;
271  }
272  mfirstChildNode=0;
273 }
274 
276 
278 StDbConfigNode::findConfigNode(StDbType type, StDbDomain domain, const char* subPath){
279 StDbConfigNode* node=findConfigNode(type,domain);
280 return node->findConfigNode(subPath);
281 }
282 
284 
286 StDbConfigNode::findConfigNode(StDbType type, StDbDomain domain){
287 
288  // Searches for the "highest" node of type & domain
289  // e.g. if request Calibrations , tpc & node is of that
290  // type & domain it checks parent 1st and if it is also
291  // that type & domain returns this call to the parent node
292  // .. else continue down the tree ...
293 
294 StDbConfigNode* node = 0;
295 
296 // search parent & this
297  if(isNode(type,domain)){
298  if(mparentNode && mparentNode->isNode(type,domain))
299  return mparentNode->findConfigNode(type,domain);
300  return this;
301  }
302 
303 // search children & sibs
304  if(hasChildren())node=mfirstChildNode->findConfigNode(type,domain);
305  if(!node && mnextNode)node = mnextNode->findConfigNode(type,domain);
306 
307 return node;
308 }
309 
311 
313 StDbConfigNode::findConfigNode(const char* subPath){
314 
315  // tries to find a node below (in the child sense)
316  // where nodeName/nodeName/nodeName/... = subPath
317  //
318  // returns null pointer if not found
319 
320  StDbConfigNode* node=0;
321  if(!subPath) return node;
322  char* path = mstrDup(subPath);
323 
324 if(path[0]=='/')path++;
325 char* id=strstr(path,"/");
326 if(id){ *id='\0'; id++; }
327 char* nextNodeName=mstrDup(path);
328 node=getFirstChildNode();
329 
330 if(node){
331  bool found = false;
332  while(!found){
333  if(!node->checkName(nextNodeName)){
334  node=node->getNextNode();
335  if(!node) found=true;
336  } else {
337  found=true;
338  }
339  }
340 
341 }
342 
343 if(node && id) {
344  node=node->findConfigNode(id);
345  *id='/'; // make path whole again
346 }
347 
348 delete [] path;
349 delete [] nextNodeName;
350 
351 return node;
352 }
353 
356 StDbConfigNode::findChildConfigNode(const char* name){
357 
358  StDbConfigNode* retVal=0;
359  if(!name) return retVal;
360  retVal=getFirstChildNode();
361  while(retVal){
362  if(retVal->checkName(name)) break;
363  retVal=retVal->getNextNode();
364  }
365  return retVal;
366 }
367 
369 void StDbConfigNode::setParentNode(StDbConfigNode* parent){
370 mparentNode = parent;
371 parent->setChildNode(this);
372 }
373 
375 void StDbConfigNode::appendNode(StDbConfigNode* node){
376  if(mnextNode){
377  mnextNode->appendNode(node);
378  } else {
379  mnextNode = node;
380  }
381 }
382 
384 void
385 StDbConfigNode::setChildNode(StDbConfigNode* node){
386  if(mfirstChildNode) {
387  mfirstChildNode->appendNode(node);
388  } else {
389  mfirstChildNode = node;
390  }
391 }
392 
394 void
395 StDbConfigNode::setFirstChildNode(StDbConfigNode* node){
396  if(mfirstChildNode)node->appendNode(mfirstChildNode);
397  mfirstChildNode = 0;
398  setChildNode(node);
399 }
400 
401 
403 
404 void
405 StDbConfigNode::printTree(int depth){
406 
407 if(!depth)cout<<endl<<"************* Node Structure ****************" <<endl<<endl;
408 
409  if(StDbManager::Instance()->IsVerbose()){
410  for(int k=0;k<depth;k++)cout<<" ";
411  cout<<"Node=" << mname <<" VersionKey = " << mversion <<endl;
412  if(mhasData) {
413  int depth2 = depth+4;
414  printTables(depth2);
415  }
416  }
417  int depth3=depth+4;
418  if(mfirstChildNode)mfirstChildNode->printTree(depth3);
419  if(mnextNode)mnextNode->printTree(depth);
420 
421  if(!depth)cout<<endl<<"*********************************************" << endl;
422 
423 }
424 #undef __CLASS__
static StDbManager * Instance()
strdup(..) is not ANSI
Definition: StDbManager.cc:155