Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

StDbBuffer.cc

Go to the documentation of this file.
00001 /*************************************************************************** 00002 * 00003 * $Id: StDbBuffer.cc,v 1.21 2004/01/15 00:02:24 fisyak Exp $ 00004 * 00005 * Author: Laurent Conin 00006 *************************************************************************** 00007 * 00008 * Description: Buffer for DB I/O 00009 * 00010 *************************************************************************** 00011 * 00012 * $Log: StDbBuffer.cc,v $ 00013 * Revision 1.21 2004/01/15 00:02:24 fisyak 00014 * Replace ostringstream => StString, add option for alpha 00015 * 00016 * Revision 1.20 2003/09/16 22:44:17 porter 00017 * got rid of all ostrstream objects; replaced with StString+string. 00018 * modified rules.make and added file stdb_streams.h for standalone compilation 00019 * 00020 * Revision 1.19 2003/09/02 17:57:49 perev 00021 * gcc 3.2 updates + WarnOff 00022 * 00023 * Revision 1.18 2003/04/11 22:47:35 porter 00024 * Added a fast multi-row write model specifically needed by the daqEventTag 00025 * writer. Speed increased from about 100Hz to ~3000Hz. It is only invoked if 00026 * the table is marked as Non-Indexed (daqTags & scalers). For non-indexed tables 00027 * which include binary stored data (we don't have any yet), the fast writer has 00028 * to invoke a slower buffer so that the rates are a bit slower (~500Hz at 50 rows/insert). 00029 * 00030 * Revision 1.17 2002/11/13 15:24:09 porter 00031 * updated strstream formatting 00032 * 00033 * Revision 1.16 2001/12/21 04:54:45 porter 00034 * sped up table definition for emc and changed some ostrstream usage for 00035 * insure tests 00036 * 00037 * Revision 1.15 2001/10/24 04:05:19 porter 00038 * added long long type to I/O and got rid of obsolete dataIndex table 00039 * 00040 * Revision 1.14 2001/04/25 17:18:10 perev 00041 * HPcorrs 00042 * 00043 * Revision 1.13 2001/03/30 18:48:26 porter 00044 * modified code to keep Insure from wigging-out on ostrstream functions. 00045 * moved some messaging into a StDbSql method. 00046 * 00047 * Revision 1.12 2001/01/22 18:37:50 porter 00048 * Update of code needed in next year running. This update has little 00049 * effect on the interface (only 1 method has been changed in the interface). 00050 * Code also preserves backwards compatibility so that old versions of 00051 * StDbLib can read new table structures. 00052 * -Important features: 00053 * a. more efficient low-level table structure (see StDbSql.cc) 00054 * b. more flexible indexing for new systems (see StDbElememtIndex.cc) 00055 * c. environment variable override KEYS for each database 00056 * d. StMessage support & clock-time logging diagnostics 00057 * -Cosmetic features 00058 * e. hid stl behind interfaces (see new *Impl.* files) to again allow rootcint access 00059 * f. removed codes that have been obsolete for awhile (e.g. db factories) 00060 * & renamed some classes for clarity (e.g. tableQuery became StDataBaseI 00061 * and mysqlAccessor became StDbSql) 00062 * 00063 * Revision 1.11 2000/06/30 01:57:00 porter 00064 * fixed a delete bug & small memory leak found by Akio via Insure++ , 00065 * updated SetTable() method for containing idList, corrected enumeration 00066 * map to rhic domain for Conditions_rhic database 00067 * 00068 * Revision 1.10 2000/06/02 15:58:26 porter 00069 * removed "\" character in a "//" comment - it gives a warning on linux 00070 * 00071 * Revision 1.9 2000/06/02 13:37:36 porter 00072 * built up list of minor changes: 00073 * - made buffer more robust for certain null inputs 00074 * - fixed small leak in StDbTables & restructure call to createMemory 00075 * - added dbRhic as a database domain in StDbDefs 00076 * - added setUser() in StDbManager 00077 * - added more diagnostic printouts in mysqlAccessor.cc 00078 * 00079 * Revision 1.8 2000/05/10 21:39:01 porter 00080 * fixed delete[] bug in reading from table where input schema includes fields that 00081 * are not in the database by checking buffer status for reads 00082 * 00083 * Revision 1.7 2000/02/18 22:11:58 porter 00084 * modified buffer read of unsigned char array 00085 * 00086 * Revision 1.6 2000/02/15 20:27:44 porter 00087 * Some updates to writing to the database(s) via an ensemble (should 00088 * not affect read methods & haven't in my tests. 00089 * - closeAllConnections(node) & closeConnection(table) method to mgr. 00090 * - 'NullEntry' version to write, with setStoreMode in table; 00091 * - updated both StDbTable's & StDbTableDescriptor's copy-constructor 00092 * 00093 * Revision 1.5 2000/01/27 05:54:32 porter 00094 * Updated for compiling on CC5 + HPUX-aCC + KCC (when flags are reset) 00095 * Fixed reConnect()+transaction model mismatch 00096 * added some in-code comments 00097 * 00098 * Revision 1.4 1999/12/07 21:39:27 porter 00099 * *** empty log message *** 00100 * 00101 * Revision 1.3 1999/12/07 21:25:25 porter 00102 * some fixes for linux warnings 00103 * 00104 * Revision 1.2 1999/09/30 02:06:01 porter 00105 * add StDbTime to better handle timestamps, modify SQL content (mysqlAccessor) 00106 * allow multiple rows (StDbTable), & Added the comment sections at top of 00107 * each header and src file 00108 * 00109 **************************************************************************/ 00110 #include "StDbBuffer.h" 00111 #include <stdlib.h> 00112 #include <string.h> 00113 #include "stdb_streams.h" 00114 00115 00116 #ifdef HPUX 00117 #define freeze(i) str() 00118 #endif 00119 00121 00122 void StDbBuffer::Print(){ 00123 if (mCol) { 00124 int i; 00125 for (i=0; i<=mLast;i++) { 00126 if (mCol[i].type==_char) { 00127 char* tVal;int len; 00128 ReadArray(tVal,len,mCol[i].name); 00129 cout << mCol[i].name <<"=" << "#BIN (" << len << ") bytes" <<endl; 00130 }else { 00131 char** tVal; int len; 00132 ReadArray(tVal,len,mCol[i].name); 00133 int j; 00134 for (j=0;j<len;j++) 00135 {cout << mCol[i].name <<"["<< j << "]=" << tVal[j] <<endl;} 00136 }; 00137 }; 00138 }; 00139 }; 00140 00142 void StDbBuffer::zeroColumn(int istart, int iend) { 00143 for(int i=istart;i<iend+1;i++){ 00144 mCol[i].name = 0; 00145 mCol[i].val = 0; 00146 } 00147 } 00148 00149 00151 void StDbBuffer::Raz(){ 00152 00153 int i; 00154 for (i=0;i<=mLast;i++) { 00155 if (mCol[i].val) { 00156 if (mCol[i].type>=_ascii){ 00157 char ** tTextVal= (char**)mCol[i].val; 00158 int j; 00159 for(j=0;j<(int)mCol[i].length;j++) { 00160 00161 if (tTextVal[j]) delete [] tTextVal[j]; 00162 }; 00163 delete [] tTextVal; 00164 } else { 00165 delete [] mCol[i].val ; 00166 }; 00167 }; 00168 if (mCol[i].name) delete [] mCol[i].name; 00169 mCol[i].val=0; 00170 mCol[i].name=0; 00171 mCol[i].type=_char; 00172 mCol[i].length=0; 00173 }; 00174 mCur=0; 00175 mLast=-1; 00176 } 00177 00179 char **StDbBuffer::WhatsIn(){ 00180 char **tIn; 00181 tIn=new char*[mLast+2]; 00182 int i; 00183 for (i=0;i<=mLast;i++){ 00184 tIn[i]=mCol[i].name; 00185 }; 00186 tIn[mLast+1]=0; 00187 return tIn; 00188 } 00189 00191 bool StDbBuffer::Find_Col (const char *aName){ 00192 // int tCount=0; 00193 00194 if (mLast==-1) return false; 00195 00196 for (int tCount=0;tCount<mLast+1;tCount++){ 00197 mCur++; 00198 if (mCur>mLast) mCur=0; 00199 00200 if (!strcmp(mCol[mCur].name,aName)) return true; 00201 }; 00202 00203 return false; 00204 } 00205 00206 00208 void StDbBuffer::AddField(const char *aName, const myctype aTpe,const void* aVal,const int aLen) { 00209 /* when the field aName doesn't exist int the buffer, this function is call 00210 to initialise a new field. if needed, it increase the array mCol. 00211 it store the name, and then call ChangeField to store the value */ 00212 00213 if (mLast+1>mMax) { 00214 column *tCol=new column[mMax*2+1]; 00215 memcpy(tCol,mCol,(mMax+1)*sizeof(column)); 00216 if (mCol) delete [] mCol; 00217 mCol=tCol; 00218 zeroColumn(mMax+1,2*mMax); 00219 mMax=mMax*2; 00220 } 00221 mLast++; 00222 mCur=mLast; 00223 if(mCol[mCur].name) delete [] mCol[mCur].name; 00224 mCol[mCur].name=new char[strlen(aName)+1]; 00225 strcpy(mCol[mCur].name,aName); 00226 mCol[mCur].val=0; 00227 ChangeField(aTpe,aVal,aLen); 00228 }; 00229 00231 void StDbBuffer::ChangeField(const myctype aTpe,const void* aVal,const int aLen) { 00232 if (mCol[mCur].val){ 00233 if(mCol[mCur].type>=_ascii){ 00234 char ** tTextVal= (char**)mCol[mCur].val; 00235 int j; 00236 for(j=0;j<(int)mCol[mCur].length;j++) { 00237 if (tTextVal[j]) delete [] tTextVal[j]; 00238 }; 00239 delete [] tTextVal ; mCol[mCur].val=0; 00240 } 00241 } 00242 mCol[mCur].type=aTpe; 00243 mCol[mCur].length=aLen; 00244 if (aTpe<_ascii) { 00245 mCol[mCur].val=new char[aLen*mycsize[aTpe]]; 00246 MemSwapCpy(mCol[mCur].val,(char*)aVal,aLen*mycsize[aTpe],mycswapl[aTpe],Auto); 00247 } else { 00248 mCol[mCur].val=(char*) new char*[aLen]; 00249 char** tVal=(char**)aVal; 00250 char** tStoreVal=(char**)mCol[mCur].val; 00251 int i; 00252 for (i=0;i<aLen;i++) { 00253 if (tVal[i]==0) { 00254 (tStoreVal)[i]=0; 00255 } else { 00256 tStoreVal[i]=new char[strlen(tVal[i])+1]; 00257 strcpy(tStoreVal[i],tVal[i]); 00258 }; 00259 }; 00260 }; 00261 00262 00263 }; 00264 00266 void StDbBuffer::MemSwapCpy(char* where,char* from,int len,int swaplen,BuffMode mode) { 00267 if (mode==Auto) mode=mMode; 00268 if (swaplen<=1||mode==Storage) { 00269 memcpy(where,from,len); 00270 } else { 00271 if (len%swaplen!=0) { 00272 cerr << "memswapcy: len not in agreement with swapping - binary truncate " << endl; 00273 }; 00274 int tNbCpy=len/swaplen; 00275 int i; 00276 for (i=0;i<tNbCpy;i++){ 00277 where+=swaplen; 00278 int j; 00279 for (j=0;j<swaplen;j++){ 00280 where--; 00281 *where=*from; 00282 from++; 00283 } 00284 where+=swaplen; 00285 }; 00286 }; 00287 }; 00288 00289 00291 void StDbBuffer::StrConv(char* aVal,char &s){s=aVal[0];}; 00292 void StDbBuffer::StrConv(char* aVal,unsigned char &s){s=(unsigned char)atoi(aVal);}; 00293 void StDbBuffer::StrConv(char* aVal,short &s){s=(short)atoi(aVal);}; 00294 void StDbBuffer::StrConv(char* aVal,unsigned short &s){s=(unsigned short) atoi(aVal);}; 00295 void StDbBuffer::StrConv(char* aVal,int &s){s=atoi(aVal);}; 00296 void StDbBuffer::StrConv(char* aVal,unsigned int &s){s=atol(aVal);}; 00297 void StDbBuffer::StrConv(char* aVal,long &s){s=atoi(aVal);}; 00298 void StDbBuffer::StrConv(char* aVal,unsigned long &s){s=atol(aVal);}; 00299 #ifndef __osf__ 00300 void StDbBuffer::StrConv(char* aVal,long long &s){s=atoll(aVal);}; 00301 #else 00302 void StDbBuffer::StrConv(char* aVal,long long &s){s=atol(aVal);}; 00303 #endif 00304 void StDbBuffer::StrConv(char* aVal,float &s){s=(float) atof(aVal);}; 00305 void StDbBuffer::StrConv(char* aVal,double &s){s=atof(aVal);}; 00306 void StDbBuffer::StrConv(char* aVal,char* &s){s=new char[strlen(aVal)+1];strcpy(s,aVal);}; 00307 00308 #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; 00309 00310 #define genwritemem(tpe) \ 00311 bool StDbBuffer::WriteMem( tpe *s,void* aVal, myctype type)\ 00312 {bool tRetVal=true;\ 00313 switch (type) {\ 00314 castcase(_char,char,tpe);\ 00315 castcase(_uchar,unsigned char,tpe);\ 00316 castcase(_short,short,tpe);\ 00317 castcase(_ushort,unsigned short,tpe);\ 00318 castcase(_int,int,tpe);\ 00319 castcase(_uint,unsigned int,tpe);\ 00320 castcase(_long,long,tpe);\ 00321 castcase(_ulong,unsigned long,tpe);\ 00322 castcase(_longlong,long long,tpe);\ 00323 castcase(_float,float,tpe);\ 00324 castcase(_double,double,tpe);\ 00325 case _string: {char** tVal=(char**)aVal;StrConv(*tVal,*s);};break;\ 00326 default: cout <<"wrong type" << endl;tRetVal=false;\ 00327 };\ 00328 return tRetVal;\ 00329 } 00330 genwritemem(char); 00331 genwritemem(unsigned char); 00332 genwritemem(short); 00333 genwritemem(unsigned short); 00334 genwritemem(int); 00335 genwritemem(unsigned int); 00336 genwritemem(long); 00337 genwritemem(unsigned long); 00338 genwritemem(long long); 00339 genwritemem(float); 00340 genwritemem(double); 00341 00342 #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 00343 00344 bool StDbBuffer::WriteMem( char **s,void* aVal, myctype type) { 00345 bool tRetVal=true; 00346 00347 switch (type) { 00348 castcasest(_char,char); 00349 castcasest(_uchar,unsigned char); 00350 castcasest(_short,short); 00351 castcasest(_ushort,unsigned short); 00352 castcasest(_int,int); 00353 castcasest(_uint,unsigned int); 00354 castcasest(_long,long); 00355 castcasest(_ulong,unsigned long); 00356 castcasest(_longlong,long long); 00357 castcasest(_float,float); 00358 castcasest(_double,double); 00359 case _string: {char** tVal=(char**)aVal; 00360 *s=new char[strlen(*(char**)aVal)+1]; 00361 strcpy(*s,*tVal); 00362 } 00363 break; 00364 default: cout <<"wrong type" << endl;tRetVal=false;\ 00365 };\ 00366 return tRetVal;\ 00367 } 00368 00369 #define Rscal(tpe) \ 00370 bool StDbBuffer::ReadScalar(tpe s,const char *aName) \ 00371 {bool tRetVal=false; \ 00372 if(Find_Col(aName) && WriteMem(&s,mCol[mCur].val,mCol[mCur].type)) \ 00373 tRetVal=true;\ 00374 return tRetVal;} 00375 00376 // --> old 00377 // if (Find_Col(aName)) 00378 // { char* tSwapVal=new char[mycsize[mCol[mCur].type]]; 00379 // if(WriteMem(&s,mCol[mCur].val,mCol[mCur].type)) tRetVal=true;} 00380 // return tRetVal;} 00381 00382 Rscal(char&); 00383 Rscal(unsigned char&); 00384 Rscal( short& ); 00385 Rscal(unsigned short& ); 00386 Rscal(int&); 00387 Rscal(unsigned int&); 00388 Rscal(long&); 00389 Rscal(unsigned long& ); 00390 Rscal(long long& ); 00391 Rscal(float& ); 00392 Rscal(double&); 00393 Rscal(char*&); 00394 00395 00396 #define Wscal(tpe,tpelist,len) \ 00397 bool StDbBuffer::WriteScalar(const tpe s,const char *aName) \ 00398 { if (Find_Col(aName))\ 00399 {ChangeField(tpelist,(void*)&s,len);}\ 00400 else\ 00401 {AddField(aName,tpelist,(void*)&s,len);};\ 00402 return true;\ 00403 } 00404 00405 Wscal(char,_char,1); 00406 Wscal(unsigned char,_uchar,1); 00407 Wscal(short,_short ,1); 00408 Wscal(unsigned short,_ushort,1); 00409 Wscal(int ,_int ,1); 00410 Wscal(unsigned int ,_uint ,1); 00411 Wscal(long ,_long ,1); 00412 Wscal(unsigned long ,_ulong,1); 00413 Wscal(long long ,_longlong,1); 00414 Wscal(float ,_float,1); 00415 Wscal(double,_double,1); 00416 //Wscal(char*,_string,1); 00417 00419 bool StDbBuffer::WriteScalar(const char* s,const char *aName) 00420 { 00421 if(!s) return false; 00422 // cout<< "Createin pointerstring "<<endl; 00423 //** char** tVal=new char*[1]; 00424 char* aVal=new char[strlen(s)+1]; 00425 strcpy(aVal,s); 00426 char** tVal=&aVal; 00427 // cout<< "Creatin storag string "<<endl; 00428 //** tVal[0]=new char[strlen(s)+1]; 00429 // cout<< "Copy storag string "<<endl; 00430 //** strcpy(tVal[0],s); 00431 /* if (Find_Col(aName)) 00432 // { ChangeField(_string,(void*)&tVal,1);} 00433 { ChangeField(_string,(void*)tVal,1); delete [] tVal[0]; delete [] tVal;} 00434 else 00435 { AddField(aName,_string,(void*)tVal,1); delete [] tVal[0]; delete [] tVal;} 00436 */ 00437 if (Find_Col(aName)) 00438 { ChangeField(_string,(void*)tVal,1); delete [] aVal;} 00439 else 00440 { AddField(aName,_string,(void*)tVal,1); delete [] aVal;}; 00441 return true; 00442 } 00443 00445 #define Rarray(tpe,tpelist) \ 00446 bool StDbBuffer::ReadArray(tpe* &s, int &len,const char *aName)\ 00447 { bool tRetVal=false; \ 00448 bool newCheck=false;\ 00449 if (Find_Col(aName)) \ 00450 {int i;\ 00451 if (mCol[mCur].type==_char ) {\ 00452 len=mCol[mCur].length/sizeof(tpe);\ 00453 s=new tpe[len];\ 00454 newCheck=true;\ 00455 MemSwapCpy((char*)s,(char*)mCol[mCur].val,len*sizeof(tpe),mycswapl[tpelist],Auto);\ 00456 tRetVal=true;\ 00457 } else {\ 00458 len=mCol[mCur].length;\ 00459 s=new tpe[len];\ 00460 newCheck=true;\ 00461 for (i=0;i<len;i++)\ 00462 { if (!(WriteMem(&s[i],(void*)(((char*)mCol[mCur].val)+i*mycsize[mCol[mCur].type]),mCol[mCur].type))) break;}\ 00463 if (i==(int)mCol[mCur].length) tRetVal=true;}}\ 00464 return tRetVal;\ 00465 } 00466 00467 00468 //Rarray(char,_char); 00469 Rarray(unsigned char,_uchar); 00470 Rarray(short,_short ); 00471 Rarray(unsigned short,_ushort); 00472 Rarray(int,_int ); 00473 Rarray(unsigned int,_uint ); 00474 Rarray(long,_long ); 00475 Rarray(unsigned long,_ulong ); 00476 Rarray(long long,_longlong ); 00477 Rarray(float,_float ); 00478 Rarray(double,_double); 00479 Rarray(char*,_string); 00480 00481 00482 bool StDbBuffer::ReadArray(char* &s, int &len,const char *aName) 00483 { bool tRetVal=false; 00484 if (Find_Col(aName)) { 00485 len=mCol[mCur].length*mycsize[mCol[mCur].type]; 00486 s=new char[len]; 00487 MemSwapCpy((char*)s,(char*)mCol[mCur].val,len,mycswapl[mCol[mCur].type],Auto); 00488 tRetVal=true; 00489 } else { 00490 s=0; 00491 // cerr << "WARNING:: field " << aName << " doesnt exist in this Buffer" << endl; 00492 }; 00493 return tRetVal;\ 00494 }; 00495 00496 #define Warray(tpe,tpelist) \ 00497 bool StDbBuffer::WriteArray(tpe* s,int len,const char *aName) \ 00498 { if (Find_Col(aName))\ 00499 {ChangeField(tpelist,(void*)s,len);}\ 00500 else\ 00501 {AddField(aName,tpelist,(void*)s,len);};\ 00502 return true;\ 00503 } 00504 00505 Warray(char,_char); 00506 Warray(unsigned char,_uchar); 00507 Warray(short,_short ); 00508 Warray(unsigned short,_ushort); 00509 Warray(int,_int ); 00510 Warray(unsigned int,_uint ); 00511 Warray(long,_long ); 00512 Warray(unsigned long,_ulong ); 00513 Warray(long long,_longlong ); 00514 Warray(float,_float ); 00515 Warray(double,_double); 00516 Warray(char*,_string); 00517 00518 00519 00520 00521 00522 00523 00524 00525 00526 00527 00528 00529

Generated on Thu Aug 24 14:45:25 2006 for Doxygen by doxygen 1.3.7