StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StDbTableDescriptor.cc
1 /***************************************************************************
2  *
3  * $Id: StDbTableDescriptor.cc,v 1.28 2009/09/28 19:14:10 dmitry Exp $
4  *
5  * Author: R. Jeff Porter
6  ***************************************************************************
7  *
8  * Description: Class implement table-descriptor (memory/name of data-elements)
9  * this descriptor is loaded from database
10  *
11  ***************************************************************************
12  *
13  * $Log: StDbTableDescriptor.cc,v $
14  * Revision 1.28 2009/09/28 19:14:10 dmitry
15  * row size is not *static* anymore, tables have different row sizes
16  *
17  * Revision 1.27 2009/09/10 20:01:30 dmitry
18  * removed redundant output
19  *
20  * Revision 1.26 2009/09/10 18:06:08 dmitry
21  * struct alignment fix, does not rely on fixed 4 byte cap anymore - runtime align calculation is now in use
22  *
23  * Revision 1.25 2005/09/07 22:04:02 deph
24  * update to correct padding issue for packed tables
25  *
26  * Revision 1.24 2004/01/15 00:02:25 fisyak
27  * Replace ostringstream => StString, add option for alpha
28  *
29  * Revision 1.23 2003/10/28 20:58:31 perev
30  * Linux ==> __linux__
31  *
32  * Revision 1.22 2003/09/16 22:44:18 porter
33  * got rid of all ostrstream objects; replaced with StString+string.
34  * modified rules.make and added file stdb_streams.h for standalone compilation
35  *
36  * Revision 1.21 2003/09/02 17:57:50 perev
37  * gcc 3.2 updates + WarnOff
38  *
39  * Revision 1.20 2002/01/30 15:40:48 porter
40  * changed limits on flavor tag & made defaults retrieving more readable
41  *
42  * Revision 1.19 2001/12/05 17:16:35 porter
43  * stand-alone make file no longer had "D__linux__" in compile but this is still needed
44  * and returned. Also retrieve elementID list in query by whereClause for plotting
45  * many row instances.
46  *
47  * Revision 1.18 2001/10/24 04:05:20 porter
48  * added long long type to I/O and got rid of obsolete dataIndex table
49  *
50  * Revision 1.17 2001/02/08 23:23:56 porter
51  * fixed initialization of schemaID in table & fixed some warnings when
52  * compiled with NODEBUG
53  *
54  * Revision 1.16 2001/01/22 18:38:00 porter
55  * Update of code needed in next year running. This update has little
56  * effect on the interface (only 1 method has been changed in the interface).
57  * Code also preserves backwards compatibility so that old versions of
58  * StDbLib can read new table structures.
59  * -Important features:
60  * a. more efficient low-level table structure (see StDbSql.cc)
61  * b. more flexible indexing for new systems (see StDbElememtIndex.cc)
62  * c. environment variable override KEYS for each database
63  * d. StMessage support & clock-time logging diagnostics
64  * -Cosmetic features
65  * e. hid stl behind interfaces (see new *Impl.* files) to again allow rootcint access
66  * f. removed codes that have been obsolete for awhile (e.g. db factories)
67  * & renamed some classes for clarity (e.g. tableQuery became StDataBaseI
68  * and mysqlAccessor became StDbSql)
69  *
70  * Revision 1.15 2000/03/28 17:03:19 porter
71  * Several upgrades:
72  * 1. configuration by timestamp for Conditions
73  * 2. query by whereClause made more systematic
74  * 3. conflict between db-stored comments & number lists resolved
75  * 4. ensure endtime is correct for certain query falures
76  * 5. dbstl.h->handles ObjectSpace & RogueWave difference (Online vs Offline)
77  *
78  * Revision 1.14 2000/03/06 17:11:49 porter
79  * - WriteDb(table) returns true if no data is in table
80  * - fixed memory leak introduced in 2/18/00 update.
81  * - modified descriptor algorythm for OnlRunDescriptor.
82  *
83  * Revision 1.13 2000/03/01 20:56:16 porter
84  * 3 items:
85  * 1. activated reConnect for server timeouts
86  * 2. activated connection sharing; better resource utilization but poorer
87  * logging
88  * 3. made rollback method in mysqlAccessor more robust (affects writes only)
89  *
90  * Revision 1.12 2000/02/24 20:30:47 porter
91  * fixed padding for uchar; beginTime in mysqlAccessor;
92  * added rollback safety checkes in StDbManger
93  *
94  * Revision 1.11 2000/02/15 20:27:45 porter
95  * Some updates to writing to the database(s) via an ensemble (should
96  * not affect read methods & haven't in my tests.
97  * - closeAllConnections(node) & closeConnection(table) method to mgr.
98  * - 'NullEntry' version to write, with setStoreMode in table;
99  * - updated both StDbTable's & StDbTableDescriptor's copy-constructor
100  *
101  * Revision 1.10 2000/01/27 05:54:35 porter
102  * Updated for compiling on CC5 + HPUX-aCC + KCC (when flags are reset)
103  * Fixed reConnect()+transaction model mismatch
104  * added some in-code comments
105  *
106  * Revision 1.9 2000/01/19 20:20:07 porter
107  * - finished transaction model needed by online
108  * - fixed CC5 compile problem in StDbNodeInfo.cc
109  * - replace TableIter class by StDbTableIter to prevent name problems
110  *
111  * Revision 1.8 2000/01/10 20:37:55 porter
112  * expanded functionality based on planned additions or feedback from Online work.
113  * update includes:
114  * 1. basis for real transaction model with roll-back
115  * 2. limited SQL access via the manager for run-log & tagDb
116  * 3. balance obtained between enumerated & string access to databases
117  * 4. 3-levels of diagnostic output: Quiet, Normal, Verbose
118  * 5. restructured Node model for better XML support
119  *
120  * Revision 1.7 1999/12/07 21:25:25 porter
121  * some fixes for __linux__ warnings
122  *
123  * Revision 1.6 1999/12/03 19:02:01 porter
124  * modified descriptor to accept tableDescriptor once this St_base object
125  * has been updated to have longer name lengths.
126  *
127  * Revision 1.5 1999/10/19 14:30:40 porter
128  * modifications relevant to use with StDbBroker and future merging with
129  * "params" database structure + some docs + suppressing diagnostics messages
130  *
131  * Revision 1.4 1999/09/30 02:06:10 porter
132  * add StDbTime to better handle timestamps, modify SQL content (mysqlAccessor)
133  * allow multiple rows (StDbTable), & Added the comment sections at top of
134  * each header and src file
135  *
136  **************************************************************************/
137 #include "StDbTableDescriptor.h"
138 #include <stdlib.h>
139 #include <math.h>
140 #include "stdb_streams.h"
141 #include <iostream>
142 
143 // Alignment test struct
144 template <typename T>
146  char m0;
147  T m1;
148 };
149 
150 #define st_alignof(TYPE) (size_t)&(((StCompilerAlignTest<TYPE>*)0)->m1)
151 
153 
154 StDbTableDescriptor::StDbTableDescriptor(){ init(); }
155 
157 
158 StDbTableDescriptor::StDbTableDescriptor(int structID, int schemaID){
159 
160  init();
161  mstructID=structID;
162  mschemaID=schemaID;
163 
164 };
165 
167 
168 void
169 StDbTableDescriptor::init(){
170 
171 mtableSize=0;
172 mCur = 0;
173 mMax = 100;
174 offsetToNextEmptyByte = 0;
175 offsetToLast4Bytes = -4;
176 mnumElements = 0;
177 lastType=Stdouble;
178 padsize = 0;
179 mcols = new tableDescriptor[mMax];
180 memset(mcols,0,mMax*sizeof(tableDescriptor));
181 mschemaID=mstructID=0;
182 misValid=false;
183 mhasDouble=false;
184 rowSizeTT = 0;
185 
186 mAlign[Stchar] = st_alignof(char);
187 mAlign[Stuchar] = st_alignof(unsigned char);
188 mAlign[Stshort] = st_alignof(short);
189 mAlign[Stushort] = st_alignof(unsigned short);
190 mAlign[Stint] = st_alignof(int);
191 mAlign[Stuint] = st_alignof(unsigned int);
192 mAlign[Stlong] = st_alignof(long);
193 mAlign[Stulong] = st_alignof(unsigned long);
194 mAlign[Stlonglong] = st_alignof(long long);
195 mAlign[Stfloat] = st_alignof(float);
196 mAlign[Stdouble] = st_alignof(double);
197 
198 maxAlign = mAlign[Stchar];
199 
200 }
201 
203 
204 StDbTableDescriptor::StDbTableDescriptor(StDbTableDescriptor& d){
205 
206 mCur = (int)d.getNumElements()-1;
207 mMax = d.getCurrentInternalSize();
208 offsetToNextEmptyByte = 0;
209 offsetToLast4Bytes = 0;
210 mcols = d.getTableDescriptor();
211 mnumElements=d.getNumElements();
212 mtableSize = d.getTotalSizeInBytes();
213 mschemaID=d.getSchemaID();
214 mstructID=d.getStructID();
215 misValid=d.IsValid();
216 mhasDouble=d.mhasDouble;
217 maxAlign=d.maxAlign;
218 rowSizeTT = d.rowSizeTT;
219 
220 mAlign[Stchar] = st_alignof(char);
221 mAlign[Stuchar] = st_alignof(unsigned char);
222 mAlign[Stshort] = st_alignof(short);
223 mAlign[Stushort] = st_alignof(unsigned short);
224 mAlign[Stint] = st_alignof(int);
225 mAlign[Stuint] = st_alignof(unsigned int);
226 mAlign[Stlong] = st_alignof(long);
227 mAlign[Stulong] = st_alignof(unsigned long);
228 mAlign[Stlonglong] = st_alignof(long long);
229 mAlign[Stfloat] = st_alignof(float);
230 mAlign[Stdouble] = st_alignof(double);
231 
232 }
233 
235 
237 StDbTableDescriptor::getTableDescriptor() const {
238 
239  tableDescriptor* dScr = new tableDescriptor[mMax];
240  memset(dScr,0,(mMax)*sizeof(tableDescriptor));
241  memcpy(dScr,mcols,(mMax)*sizeof(tableDescriptor));
242 
243 return dScr;
244 }
246 
248 StDbTableDescriptor::getCpy(){
249 
250 StTableDescriptorI* dScr = new StDbTableDescriptor(*this);
251 return dScr;
252 
253 }
255 
256 void
257 StDbTableDescriptor::fillElement(StDbBuffer* buff, int tableID){
258 
259  //bool ClientMode;
260 // if(!(ClientMode=buff->IsClientMode()))buff->SetClientMode();
261  int schemaID;
262  if(tableID){ // mask off elements if tableID is non-zero
263  if(!(buff->ReadScalar(schemaID,"schemaID") && (schemaID==tableID)) ){
264  // skip this one
265  return;
266  }
267  }
268 
269  reSize(); // increase array if needed
270  int i = mCur;
271  char* mtype = 0;
272  char* mname = 0;
273  buff->ReadScalar(mname,"name");
274  if(mname)strcpy(mcols[i].name,mname);
275  if(mname) delete [] mname;
276  if(buff->ReadScalar(mtype,"type")){
277  mcols[i].type = getType(mtype);
278  if(mtype)delete [] mtype;
279  char* length=0;
280  if(buff->ReadScalar(length,"length"))fillSizeAndOffset(length,i);
281  if(length) delete [] length;
282  }
283 
284  if (mcols[i].type==Stlonglong || mcols[i].type==Stdouble ) mhasDouble=true;
285  if (getAlign(mcols[i].type) > maxAlign) { maxAlign = getAlign(mcols[i].type); }
286 
287  mCur++;
288  mnumElements++;
289 
290  // for multiple rows, add padding as needed at end of structure (tableSize)
291 
292  int rowpad;
293  if ( ( rowpad = offsetToNextEmptyByte%2 ) ) { rowpad = 2 - rowpad; }
294 
295  //mtableSize = offsetToNextEmptyByte + rowpad;
296 
297  // correct padding should be based on max align:
298  mtableSize = int(ceil(float(offsetToNextEmptyByte) / float(maxAlign)) * maxAlign);
299 
300  //if(!ClientMode)buff->SetStorageMode(); // reset to StorageMode
301 
302  misValid=true;
303 
304 }
305 
307 
308 
309 void
310 StDbTableDescriptor::reSize(){
311 
312  // simply add 10 elements
313 
314  if(mCur<mMax) return;
315 
316  int newMax = mMax+10;
317  tableDescriptor* dScr = new tableDescriptor[newMax];
318  memcpy(dScr,mcols,(mMax)*sizeof(tableDescriptor));
319  if(mcols)delete [] mcols;
320  mcols=dScr;
321  mMax=newMax;
322 
323 }
324 
326 
327 void
328 StDbTableDescriptor::fillLengths(char* length, int elementNum){
329 
330 int ip = 0;
331 int i=elementNum;
332 char* id= strstr(length,",");
333 
334 // preset lengths to 1;
335 
336  int k= (int)(sizeof(mcols[i].dimensionlen)/sizeof(ip));
337  for(int j=0;j<k;j++)mcols[i].dimensionlen[j]=1;
338 
339  while (id && ip<3) {
340  id[0]='\0';
341  mcols[i].dimensionlen[ip] = atoi(length);
342  ip++;
343  id++;
344  length=id;
345  id= strstr(length,",");
346  }
347  mcols[i].dimensionlen[ip]=atoi(length);
348 
349 }
350 
352 
353 void
354 StDbTableDescriptor::fillSizeAndOffset(char* length, int elementNum){
355 
356  fillLengths(length,elementNum);
357  StTypeE type = mcols[elementNum].type;
358 
359  int j = 0;
360  mcols[elementNum].size = getSize(mcols[elementNum].type);
361 
362  int k= (int)(sizeof(mcols[elementNum].dimensionlen)/sizeof(j));
363  for (j=0; j<k; j++) mcols[elementNum].size *= mcols[elementNum].dimensionlen[j];
364 
365  int offp = int(ceil(float(offsetToNextEmptyByte) / float(getAlign(type))) * getAlign(type));
366  mcols[elementNum].offset = offp;
367  offsetToNextEmptyByte = mcols[elementNum].offset + mcols[elementNum].size;
368 
369 }
370 
372 
373 StTypeE
374 StDbTableDescriptor::getType(char* type) {
375 
376 StTypeE retVal=Stchar;
377 
378 //char* typenames[] = {"Stchar","Stuchar","Stshort","Stushort","Stint","Stuint","Stlong","Stulong","Stfloat","Stdouble","Stascii","Ststring"};
379 const char* typenames[] = {"char","uchar","short","ushort","int","uint","long","ulong","longlong","float","double","ascii","string"};
380 
381  for(int i=0; i<12;i++){
382  if(strcmp(type,typenames[i])==0){
383  retVal=(StTypeE)i;
384  break;
385  }
386  }
387 
388 return retVal;
389 }
390 
392 void StDbTableDescriptor::endRowPadding(){
393 
394  //simple item for solaris & use of doubles & longlong.
395  // if the struct contains such an entity, it's size must
396  // be divisable by 8.
397 
398 #ifndef __linux__
399  if(mhasDouble){
400  int checkPadding=mtableSize%8;
401  if(checkPadding>0 && checkPadding<5)mtableSize+=4;
402  }
403 #endif
404 
405 };
406 
407 
408 
409 
410 
411 
412 
413 
414 
415 
416 
417 
418 
419 
420 
421 
422 
423 
424