StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StDbBuffer.cc
1 /***************************************************************************
2  *
3  * $Id: StDbBuffer.cc,v 1.25 2012/06/11 14:33:47 fisyak Exp $
4  *
5  * Author: Laurent Conin
6  ***************************************************************************
7  *
8  * Description: Buffer for DB I/O
9  *
10  ***************************************************************************
11  *
12  * $Log: StDbBuffer.cc,v $
13  * Revision 1.25 2012/06/11 14:33:47 fisyak
14  * std namespace
15  *
16  * Revision 1.24 2007/08/20 18:21:28 deph
17  * New Version of Load Balancer
18  *
19  * Revision 1.23 2007/06/17 16:05:34 deph
20  * Bug fix for unsigned datatypes: max int was being returned changed atoi to strtol.
21  *
22  * Revision 1.22 2007/05/16 22:48:10 deph
23  * Replaced cerr with LOG_ERROR <<endm; for logger
24  *
25  * Revision 1.21 2004/01/15 00:02:24 fisyak
26  * Replace ostringstream => StString, add option for alpha
27  *
28  * Revision 1.20 2003/09/16 22:44:17 porter
29  * got rid of all ostrstream objects; replaced with StString+string.
30  * modified rules.make and added file stdb_streams.h for standalone compilation
31  *
32  * Revision 1.19 2003/09/02 17:57:49 perev
33  * gcc 3.2 updates + WarnOff
34  *
35  * Revision 1.18 2003/04/11 22:47:35 porter
36  * Added a fast multi-row write model specifically needed by the daqEventTag
37  * writer. Speed increased from about 100Hz to ~3000Hz. It is only invoked if
38  * the table is marked as Non-Indexed (daqTags & scalers). For non-indexed tables
39  * which include binary stored data (we don't have any yet), the fast writer has
40  * to invoke a slower buffer so that the rates are a bit slower (~500Hz at 50 rows/insert).
41  *
42  * Revision 1.17 2002/11/13 15:24:09 porter
43  * updated strstream formatting
44  *
45  * Revision 1.16 2001/12/21 04:54:45 porter
46  * sped up table definition for emc and changed some ostrstream usage for
47  * insure tests
48  *
49  * Revision 1.15 2001/10/24 04:05:19 porter
50  * added long long type to I/O and got rid of obsolete dataIndex table
51  *
52  * Revision 1.14 2001/04/25 17:18:10 perev
53  * HPcorrs
54  *
55  * Revision 1.13 2001/03/30 18:48:26 porter
56  * modified code to keep Insure from wigging-out on ostrstream functions.
57  * moved some messaging into a StDbSql method.
58  *
59  * Revision 1.12 2001/01/22 18:37:50 porter
60  * Update of code needed in next year running. This update has little
61  * effect on the interface (only 1 method has been changed in the interface).
62  * Code also preserves backwards compatibility so that old versions of
63  * StDbLib can read new table structures.
64  * -Important features:
65  * a. more efficient low-level table structure (see StDbSql.cc)
66  * b. more flexible indexing for new systems (see StDbElememtIndex.cc)
67  * c. environment variable override KEYS for each database
68  * d. StMessage support & clock-time logging diagnostics
69  * -Cosmetic features
70  * e. hid stl behind interfaces (see new *Impl.* files) to again allow rootcint access
71  * f. removed codes that have been obsolete for awhile (e.g. db factories)
72  * & renamed some classes for clarity (e.g. tableQuery became StDataBaseI
73  * and mysqlAccessor became StDbSql)
74  *
75  * Revision 1.11 2000/06/30 01:57:00 porter
76  * fixed a delete bug & small memory leak found by Akio via Insure++ ,
77  * updated SetTable() method for containing idList, corrected enumeration
78  * map to rhic domain for Conditions_rhic database
79  *
80  * Revision 1.10 2000/06/02 15:58:26 porter
81  * removed "\" character in a "//" comment - it gives a warning on linux
82  *
83  * Revision 1.9 2000/06/02 13:37:36 porter
84  * built up list of minor changes:
85  * - made buffer more robust for certain null inputs
86  * - fixed small leak in StDbTables & restructure call to createMemory
87  * - added dbRhic as a database domain in StDbDefs
88  * - added setUser() in StDbManager
89  * - added more diagnostic printouts in mysqlAccessor.cc
90  *
91  * Revision 1.8 2000/05/10 21:39:01 porter
92  * fixed delete[] bug in reading from table where input schema includes fields that
93  * are not in the database by checking buffer status for reads
94  *
95  * Revision 1.7 2000/02/18 22:11:58 porter
96  * modified buffer read of unsigned char array
97  *
98  * Revision 1.6 2000/02/15 20:27:44 porter
99  * Some updates to writing to the database(s) via an ensemble (should
100  * not affect read methods & haven't in my tests.
101  * - closeAllConnections(node) & closeConnection(table) method to mgr.
102  * - 'NullEntry' version to write, with setStoreMode in table;
103  * - updated both StDbTable's & StDbTableDescriptor's copy-constructor
104  *
105  * Revision 1.5 2000/01/27 05:54:32 porter
106  * Updated for compiling on CC5 + HPUX-aCC + KCC (when flags are reset)
107  * Fixed reConnect()+transaction model mismatch
108  * added some in-code comments
109  *
110  * Revision 1.4 1999/12/07 21:39:27 porter
111  * *** empty log message ***
112  *
113  * Revision 1.3 1999/12/07 21:25:25 porter
114  * some fixes for linux warnings
115  *
116  * Revision 1.2 1999/09/30 02:06:01 porter
117  * add StDbTime to better handle timestamps, modify SQL content (mysqlAccessor)
118  * allow multiple rows (StDbTable), & Added the comment sections at top of
119  * each header and src file
120  *
121  **************************************************************************/
122 #include "StDbBuffer.h"
123 #include <stdlib.h>
124 #include <string.h>
125 #include "stdb_streams.h"
126 
127 #ifndef __STDB_STANDALONE__
128 #include "StMessMgr.h"
129 #else
130 #define LOG_DEBUG cout
131 #define LOG_INFO cout
132 #define LOG_WARN cout
133 #define LOG_ERROR cerr
134 #define LOG_FATAL cerr
135 #define LOG_QA cout
136 #define endm "\n"
137 #endif
138 
139 #ifdef HPUX
140 #define freeze(i) str()
141 #endif
142 using namespace std;
144 
145 void StDbBuffer::Print(){
146  if (mCol) {
147  int i;
148  for (i=0; i<=mLast;i++) {
149  if (mCol[i].type==_char) {
150  char* tVal;int len;
151  ReadArray(tVal,len,mCol[i].name);
152  cout << mCol[i].name <<"=" << "#BIN (" << len << ") bytes" <<endl;
153  }else {
154  char** tVal; int len;
155  ReadArray(tVal,len,mCol[i].name);
156  int j;
157  for (j=0;j<len;j++)
158  {cout << mCol[i].name <<"["<< j << "]=" << tVal[j] <<endl;}
159  };
160  };
161  };
162 };
163 
165 void StDbBuffer::zeroColumn(int istart, int iend) {
166  for(int i=istart;i<iend+1;i++){
167  mCol[i].name = 0;
168  mCol[i].val = 0;
169  }
170 }
171 
172 
174 void StDbBuffer::Raz(){
175 
176  int i;
177  for (i=0;i<=mLast;i++) {
178  if (mCol[i].val) {
179  if (mCol[i].type>=_ascii){
180  char ** tTextVal= (char**)mCol[i].val;
181  int j;
182  for(j=0;j<(int)mCol[i].length;j++) {
183 
184  if (tTextVal[j]) delete [] tTextVal[j];
185  };
186  delete [] tTextVal;
187  } else {
188  delete [] mCol[i].val ;
189  };
190  };
191  if (mCol[i].name) delete [] mCol[i].name;
192  mCol[i].val=0;
193  mCol[i].name=0;
194  mCol[i].type=_char;
195  mCol[i].length=0;
196  };
197  mCur=0;
198  mLast=-1;
199 }
200 
202 char **StDbBuffer::WhatsIn(){
203  char **tIn;
204  tIn=new char*[mLast+2];
205  int i;
206  for (i=0;i<=mLast;i++){
207  tIn[i]=mCol[i].name;
208  };
209  tIn[mLast+1]=0;
210  return tIn;
211 }
212 
214 bool StDbBuffer::Find_Col (const char *aName){
215  // int tCount=0;
216 
217  if (mLast==-1) return false;
218 
219  for (int tCount=0;tCount<mLast+1;tCount++){
220  mCur++;
221  if (mCur>mLast) mCur=0;
222 
223  if (!strcmp(mCol[mCur].name,aName)) return true;
224  };
225 
226  return false;
227 }
228 
229 
231 void StDbBuffer::AddField(const char *aName, const myctype aTpe,const void* aVal,const int aLen) {
232  /* when the field aName doesn't exist int the buffer, this function is call
233  to initialise a new field. if needed, it increase the array mCol.
234  it store the name, and then call ChangeField to store the value */
235 
236  if (mLast+1>mMax) {
237  column *tCol=new column[mMax*2+1];
238  memcpy(tCol,mCol,(mMax+1)*sizeof(column));
239  if (mCol) delete [] mCol;
240  mCol=tCol;
241  zeroColumn(mMax+1,2*mMax);
242  mMax=mMax*2;
243  }
244  mLast++;
245  mCur=mLast;
246  if(mCol[mCur].name) delete [] mCol[mCur].name;
247  mCol[mCur].name=new char[strlen(aName)+1];
248  strcpy(mCol[mCur].name,aName);
249  mCol[mCur].val=0;
250  ChangeField(aTpe,aVal,aLen);
251 };
252 
254 void StDbBuffer::ChangeField(const myctype aTpe,const void* aVal,const int aLen) {
255  if (mCol[mCur].val){
256  if(mCol[mCur].type>=_ascii){
257  char ** tTextVal= (char**)mCol[mCur].val;
258  int j;
259  for(j=0;j<(int)mCol[mCur].length;j++) {
260  if (tTextVal[j]) delete [] tTextVal[j];
261  };
262  delete [] tTextVal ; mCol[mCur].val=0;
263  }
264  }
265  mCol[mCur].type=aTpe;
266  mCol[mCur].length=aLen;
267  if (aTpe<_ascii) {
268  mCol[mCur].val=new char[aLen*mycsize[aTpe]];
269  MemSwapCpy(mCol[mCur].val,(char*)aVal,aLen*mycsize[aTpe],mycswapl[aTpe],Auto);
270  } else {
271  mCol[mCur].val=(char*) new char*[aLen];
272  char** tVal=(char**)aVal;
273  char** tStoreVal=(char**)mCol[mCur].val;
274  int i;
275  for (i=0;i<aLen;i++) {
276  if (tVal[i]==0) {
277  (tStoreVal)[i]=0;
278  } else {
279  tStoreVal[i]=new char[strlen(tVal[i])+1];
280  strcpy(tStoreVal[i],tVal[i]);
281  };
282  };
283  };
284 
285 
286 };
287 
289 void StDbBuffer::MemSwapCpy(char* where,char* from,int len,int swaplen,BuffMode mode) {
290  if (mode==Auto) mode=mMode;
291  if (swaplen<=1||mode==Storage) {
292  memcpy(where,from,len);
293  } else {
294  if (len%swaplen!=0) {
295  LOG_ERROR << "memswapcy: len not in agreement with swapping - binary truncate " << endm;
296  };
297  int tNbCpy=len/swaplen;
298  int i;
299  for (i=0;i<tNbCpy;i++){
300  where+=swaplen;
301  int j;
302  for (j=0;j<swaplen;j++){
303  where--;
304  *where=*from;
305  from++;
306  }
307  where+=swaplen;
308  };
309  };
310 };
311 
312 
314 void StDbBuffer::StrConv(char* aVal,char &s){s=aVal[0];};
315 void StDbBuffer::StrConv(char* aVal,unsigned char &s){s=(unsigned char)atoi(aVal);};
316 void StDbBuffer::StrConv(char* aVal,short &s){s=(short)atoi(aVal);};
317 void StDbBuffer::StrConv(char* aVal,unsigned short &s){s=(unsigned short) atoi(aVal);};
318 void StDbBuffer::StrConv(char* aVal,int &s){s=atoi(aVal);};
319 void StDbBuffer::StrConv(char* aVal,unsigned int &s){s=strtoul(aVal,0,10);};
320 void StDbBuffer::StrConv(char* aVal,long &s){s=atoi(aVal);};
321 void StDbBuffer::StrConv(char* aVal,unsigned long &s){s=strtoul(aVal,0,10);};
322 #ifndef __osf__
323 void StDbBuffer::StrConv(char* aVal,long long &s){s=atoll(aVal);};
324 #else
325 void StDbBuffer::StrConv(char* aVal,long long &s){s=atol(aVal);};
326 #endif
327 void StDbBuffer::StrConv(char* aVal,float &s){s=(float) atof(aVal);};
328 void StDbBuffer::StrConv(char* aVal,double &s){s=atof(aVal);};
329 void StDbBuffer::StrConv(char* aVal,char* &s){s=new char[strlen(aVal)+1];strcpy(s,aVal);};
330 
331 #define castcase(typelist,casttype,tpe) case typelist: {casttype *tVal=(casttype*)aVal;casttype tValSwap;MemSwapCpy((char*)&tValSwap,(char*)tVal,mycsize[typelist],mycswapl[typelist],Client);*s=(tpe)tValSwap;};break;
332 
333 #define genwritemem(tpe) \
334 bool StDbBuffer::WriteMem( tpe *s,void* aVal, myctype type)\
335 {bool tRetVal=true;\
336  switch (type) {\
337  castcase(_char,char,tpe);\
338  castcase(_uchar,unsigned char,tpe);\
339  castcase(_short,short,tpe);\
340  castcase(_ushort,unsigned short,tpe);\
341  castcase(_int,int,tpe);\
342  castcase(_uint,unsigned int,tpe);\
343  castcase(_long,long,tpe);\
344  castcase(_ulong,unsigned long,tpe);\
345  castcase(_longlong,long long,tpe);\
346  castcase(_float,float,tpe);\
347  castcase(_double,double,tpe);\
348  case _string: {char** tVal=(char**)aVal;StrConv(*tVal,*s);};break;\
349  default: cout <<"wrong type" << endl;tRetVal=false;\
350  };\
351  return tRetVal;\
352 }
353 genwritemem(char);
354 genwritemem(unsigned char);
355 genwritemem(short);
356 genwritemem(unsigned short);
357 genwritemem(int);
358 genwritemem(unsigned int);
359 genwritemem(long);
360 genwritemem(unsigned long);
361 genwritemem(long long);
362 genwritemem(float);
363 genwritemem(double);
364 
365 #define castcasest(typelist,casttype) case typelist: {casttype tVal; MemSwapCpy((char*)&tVal,(char*)aVal,mycsize[typelist],mycswapl[typelist],Client);StString sStream;sStream.precision(10); sStream << tVal; string s2=sStream.str();char *tStr=new char[s2.length()+1];strcpy(tStr,s2.c_str());s[0]=tStr; };break
366 
367 bool StDbBuffer::WriteMem( char **s,void* aVal, myctype type) {
368  bool tRetVal=true;
369 
370  switch (type) {
371  castcasest(_char,char);
372  castcasest(_uchar,unsigned char);
373  castcasest(_short,short);
374  castcasest(_ushort,unsigned short);
375  castcasest(_int,int);
376  castcasest(_uint,unsigned int);
377  castcasest(_long,long);
378  castcasest(_ulong,unsigned long);
379  castcasest(_longlong,long long);
380  castcasest(_float,float);
381  castcasest(_double,double);
382  case _string: {char** tVal=(char**)aVal;
383  *s=new char[strlen(*(char**)aVal)+1];
384  strcpy(*s,*tVal);
385  }
386  break;
387  default: cout <<"wrong type" << endl;tRetVal=false;\
388  };\
389  return tRetVal;\
390 }
391 
392 #define Rscal(tpe) \
393 bool StDbBuffer::ReadScalar(tpe s,const char *aName) \
394 {bool tRetVal=false; \
395  if(Find_Col(aName) && WriteMem(&s,mCol[mCur].val,mCol[mCur].type)) \
396  tRetVal=true;\
397  return tRetVal;}
398 
399 // --> old
400 // if (Find_Col(aName))
401 // { char* tSwapVal=new char[mycsize[mCol[mCur].type]];
402 // if(WriteMem(&s,mCol[mCur].val,mCol[mCur].type)) tRetVal=true;}
403 // return tRetVal;}
404 
405 Rscal(char&);
406 Rscal(unsigned char&);
407 Rscal( short& );
408 Rscal(unsigned short& );
409 Rscal(int&);
410 Rscal(unsigned int&);
411 Rscal(long&);
412 Rscal(unsigned long& );
413 Rscal(long long& );
414 Rscal(float& );
415 Rscal(double&);
416 Rscal(char*&);
417 
418 
419 #define Wscal(tpe,tpelist,len) \
420 bool StDbBuffer::WriteScalar(const tpe s,const char *aName) \
421 { if (Find_Col(aName))\
422  {ChangeField(tpelist,(void*)&s,len);}\
423  else\
424  {AddField(aName,tpelist,(void*)&s,len);};\
425 return true;\
426 }
427 
428 Wscal(char,_char,1);
429 Wscal(unsigned char,_uchar,1);
430 Wscal(short,_short ,1);
431 Wscal(unsigned short,_ushort,1);
432 Wscal(int ,_int ,1);
433 Wscal(unsigned int ,_uint ,1);
434 Wscal(long ,_long ,1);
435 Wscal(unsigned long ,_ulong,1);
436 Wscal(long long ,_longlong,1);
437 Wscal(float ,_float,1);
438 Wscal(double,_double,1);
439 //Wscal(char*,_string,1);
440 
442 bool StDbBuffer::WriteScalar(const char* s,const char *aName)
443 {
444  if(!s) return false;
445 // cout<< "Createin pointerstring "<<endl;
446  //** char** tVal=new char*[1];
447  char* aVal=new char[strlen(s)+1];
448  strcpy(aVal,s);
449  char** tVal=&aVal;
450 // cout<< "Creatin storag string "<<endl;
451  //** tVal[0]=new char[strlen(s)+1];
452 // cout<< "Copy storag string "<<endl;
453  //** strcpy(tVal[0],s);
454  /* if (Find_Col(aName))
455  // { ChangeField(_string,(void*)&tVal,1);}
456  { ChangeField(_string,(void*)tVal,1); delete [] tVal[0]; delete [] tVal;}
457  else
458  { AddField(aName,_string,(void*)tVal,1); delete [] tVal[0]; delete [] tVal;}
459  */
460  if (Find_Col(aName))
461  { ChangeField(_string,(void*)tVal,1); delete [] aVal;}
462  else
463  { AddField(aName,_string,(void*)tVal,1); delete [] aVal;};
464 return true;
465 }
466 
468 #define Rarray(tpe,tpelist) \
469 bool StDbBuffer::ReadArray(tpe* &s, int &len,const char *aName)\
470 { bool tRetVal=false; \
471  bool newCheck=false;\
472  if (Find_Col(aName)) \
473  {int i;\
474  if (mCol[mCur].type==_char ) {\
475  len=mCol[mCur].length/sizeof(tpe);\
476  s=new tpe[len];\
477  newCheck=true;\
478  MemSwapCpy((char*)s,(char*)mCol[mCur].val,len*sizeof(tpe),mycswapl[tpelist],Auto);\
479  tRetVal=true;\
480  } else {\
481  len=mCol[mCur].length;\
482  s=new tpe[len];\
483  newCheck=true;\
484  for (i=0;i<len;i++)\
485  { if (!(WriteMem(&s[i],(void*)(((char*)mCol[mCur].val)+i*mycsize[mCol[mCur].type]),mCol[mCur].type))) break;}\
486  if (i==(int)mCol[mCur].length) tRetVal=true;}}\
487  return tRetVal;\
488 }
489 
490 
491 //Rarray(char,_char);
492 Rarray(unsigned char,_uchar);
493 Rarray(short,_short );
494 Rarray(unsigned short,_ushort);
495 Rarray(int,_int );
496 Rarray(unsigned int,_uint );
497 Rarray(long,_long );
498 Rarray(unsigned long,_ulong );
499 Rarray(long long,_longlong );
500 Rarray(float,_float );
501 Rarray(double,_double);
502 Rarray(char*,_string);
503 
504 
505 bool StDbBuffer::ReadArray(char* &s, int &len,const char *aName)
506 { bool tRetVal=false;
507  if (Find_Col(aName)) {
508  len=mCol[mCur].length*mycsize[mCol[mCur].type];
509  s=new char[len];
510  MemSwapCpy((char*)s,(char*)mCol[mCur].val,len,mycswapl[mCol[mCur].type],Auto);
511  tRetVal=true;
512  } else {
513  s=0;
514  // cerr << "WARNING:: field " << aName << " doesnt exist in this Buffer" << endl;
515  };
516  return tRetVal;\
517 };
518 
519 #define Warray(tpe,tpelist) \
520 bool StDbBuffer::WriteArray(tpe* s,int len,const char *aName) \
521 { if (Find_Col(aName))\
522  {ChangeField(tpelist,(void*)s,len);}\
523  else\
524  {AddField(aName,tpelist,(void*)s,len);};\
525 return true;\
526 }
527 
528 Warray(char,_char);
529 Warray(unsigned char,_uchar);
530 Warray(short,_short );
531 Warray(unsigned short,_ushort);
532 Warray(int,_int );
533 Warray(unsigned int,_uint );
534 Warray(long,_long );
535 Warray(unsigned long,_ulong );
536 Warray(long long,_longlong );
537 Warray(float,_float );
538 Warray(double,_double);
539 Warray(char*,_string);
540 
541 
542 
543 
544 
545 
546 
547 
548 
549 
550 
551 
552