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

StDbTable.cc

Go to the documentation of this file.
00001 /*************************************************************************** 00002 * 00003 * $Id: StDbTable.cc,v 1.38 2005/09/07 22:03:04 deph Exp $ 00004 * 00005 * Author: R. Jeff Porter 00006 *************************************************************************** 00007 * 00008 * Description: Class that holds data, descriptor, & db-address 00009 * & performs streamer of db-data into data-memory 00010 * 00011 *************************************************************************** 00012 * 00013 * $Log: StDbTable.cc,v $ 00014 * Revision 1.38 2005/09/07 22:03:04 deph 00015 * update to correct padding issue for pacted tables 00016 * 00017 * Revision 1.37 2004/01/15 00:02:25 fisyak 00018 * Replace ostringstream => StString, add option for alpha 00019 * 00020 * Revision 1.36 2003/09/16 22:44:17 porter 00021 * got rid of all ostrstream objects; replaced with StString+string. 00022 * modified rules.make and added file stdb_streams.h for standalone compilation 00023 * 00024 * Revision 1.35 2003/09/02 17:57:49 perev 00025 * gcc 3.2 updates + WarnOff 00026 * 00027 * Revision 1.34 2003/04/11 22:47:36 porter 00028 * Added a fast multi-row write model specifically needed by the daqEventTag 00029 * writer. Speed increased from about 100Hz to ~3000Hz. It is only invoked if 00030 * the table is marked as Non-Indexed (daqTags & scalers). For non-indexed tables 00031 * which include binary stored data (we don't have any yet), the fast writer has 00032 * to invoke a slower buffer so that the rates are a bit slower (~500Hz at 50 rows/insert). 00033 * 00034 * Revision 1.33 2003/02/12 22:12:45 porter 00035 * moved warning message about null columns (checked in 2 days ago) from the 00036 * depths of the mysql coding into the StDbTable code. This suppresses confusing 00037 * warnings from tables that have had elements removed but their storage columns 00038 * still exist in the database. 00039 * 00040 * Revision 1.32 2003/01/10 04:19:20 porter 00041 * added feature of getting timestamp list (but no data) for a table. 00042 * fixed 2 features sometimes used in online in query-by-whereclause. 00043 * removed a stray 'cout' in a routine that is rarely accessed 00044 * 00045 * Revision 1.31 2002/01/30 15:40:48 porter 00046 * changed limits on flavor tag & made defaults retrieving more readable 00047 * 00048 * Revision 1.30 2001/12/21 04:54:46 porter 00049 * sped up table definition for emc and changed some ostrstream usage for 00050 * insure tests 00051 * 00052 * Revision 1.29 2001/10/26 20:59:46 porter 00053 * fixed new endtime flag from previous checkin. made StDataBaseI available 00054 * at root-cli. 00055 * 00056 * Revision 1.28 2001/10/24 04:05:20 porter 00057 * added long long type to I/O and got rid of obsolete dataIndex table 00058 * 00059 * Revision 1.27 2001/08/02 17:37:20 porter 00060 * fixed problem in fetch by where-clause used in online in StDbSql.cc. 00061 * also got rid of warning comparing unsigned int to int. 00062 * 00063 * Revision 1.26 2001/07/13 22:53:26 porter 00064 * last night's schema-fix was in a switch-case ... I missed one & put it in today 00065 * 00066 * Revision 1.25 2001/07/13 02:28:15 porter 00067 * fix problem in schema evolution for array size changes 00068 * 00069 * Revision 1.24 2001/04/23 19:24:32 porter 00070 * fixed row limit & initial buffer contents for query by where clause 00071 * 00072 * Revision 1.23 2001/02/09 23:06:25 porter 00073 * replaced ostrstream into a buffer with ostrstream creating the 00074 * buffer. The former somehow clashed on Solaris with CC5 iostream (current .dev) 00075 * 00076 * Revision 1.22 2001/02/08 23:23:56 porter 00077 * fixed initialization of schemaID in table & fixed some warnings when 00078 * compiled with NODEBUG 00079 * 00080 * Revision 1.21 2001/01/22 18:38:00 porter 00081 * Update of code needed in next year running. This update has little 00082 * effect on the interface (only 1 method has been changed in the interface). 00083 * Code also preserves backwards compatibility so that old versions of 00084 * StDbLib can read new table structures. 00085 * -Important features: 00086 * a. more efficient low-level table structure (see StDbSql.cc) 00087 * b. more flexible indexing for new systems (see StDbElememtIndex.cc) 00088 * c. environment variable override KEYS for each database 00089 * d. StMessage support & clock-time logging diagnostics 00090 * -Cosmetic features 00091 * e. hid stl behind interfaces (see new *Impl.* files) to again allow rootcint access 00092 * f. removed codes that have been obsolete for awhile (e.g. db factories) 00093 * & renamed some classes for clarity (e.g. tableQuery became StDataBaseI 00094 * and mysqlAccessor became StDbSql) 00095 * 00096 * Revision 1.20 2000/08/15 22:51:52 porter 00097 * Added Root2DB class from Masashi Kaneta 00098 * + made code more robust against requesting data from non-existent databases 00099 * 00100 * Revision 1.19 2000/06/30 01:57:02 porter 00101 * fixed a delete bug & small memory leak found by Akio via Insure++ , 00102 * updated SetTable() method for containing idList, corrected enumeration 00103 * map to rhic domain for Conditions_rhic database 00104 * 00105 * Revision 1.18 2000/06/02 13:37:37 porter 00106 * built up list of minor changes: 00107 * - made buffer more robust for certain null inputs 00108 * - fixed small leak in StDbTables & restructure call to createMemory 00109 * - added dbRhic as a database domain in StDbDefs 00110 * - added setUser() in StDbManager 00111 * - added more diagnostic printouts in mysqlAccessor.cc 00112 * 00113 * Revision 1.17 2000/05/10 21:39:02 porter 00114 * fixed delete[] bug in reading from table where input schema includes fields that 00115 * are not in the database by checking buffer status for reads 00116 * 00117 * Revision 1.16 2000/04/25 18:26:03 porter 00118 * added flavor & production time as settable query fields in 00119 * table &/or node. Associated SQL updated in mysqlAccessor. 00120 * Flavor key supports "+" as an OR symbol. 00121 * 00122 * Revision 1.15 2000/03/28 17:03:19 porter 00123 * Several upgrades: 00124 * 1. configuration by timestamp for Conditions 00125 * 2. query by whereClause made more systematic 00126 * 3. conflict between db-stored comments & number lists resolved 00127 * 4. ensure endtime is correct for certain query falures 00128 * 5. dbstl.h->handles ObjectSpace & RogueWave difference (Online vs Offline) 00129 * 00130 * Revision 1.14 2000/02/15 20:27:44 porter 00131 * Some updates to writing to the database(s) via an ensemble (should 00132 * not affect read methods & haven't in my tests. 00133 * - closeAllConnections(node) & closeConnection(table) method to mgr. 00134 * - 'NullEntry' version to write, with setStoreMode in table; 00135 * - updated both StDbTable's & StDbTableDescriptor's copy-constructor 00136 * 00137 * Revision 1.13 2000/01/27 05:54:34 porter 00138 * Updated for compiling on CC5 + HPUX-aCC + KCC (when flags are reset) 00139 * Fixed reConnect()+transaction model mismatch 00140 * added some in-code comments 00141 * 00142 * Revision 1.12 2000/01/19 20:20:07 porter 00143 * - finished transaction model needed by online 00144 * - fixed CC5 compile problem in StDbNodeInfo.cc 00145 * - replace TableIter class by StDbTableIter to prevent name problems 00146 * 00147 * Revision 1.11 2000/01/10 20:37:54 porter 00148 * expanded functionality based on planned additions or feedback from Online work. 00149 * update includes: 00150 * 1. basis for real transaction model with roll-back 00151 * 2. limited SQL access via the manager for run-log & tagDb 00152 * 3. balance obtained between enumerated & string access to databases 00153 * 4. 3-levels of diagnostic output: Quiet, Normal, Verbose 00154 * 5. restructured Node model for better XML support 00155 * 00156 * Revision 1.10 1999/12/07 21:25:25 porter 00157 * some fixes for linux warnings 00158 * 00159 * Revision 1.9 1999/12/03 19:01:59 porter 00160 * modified descriptor to accept tableDescriptor once this St_base object 00161 * has been updated to have longer name lengths. 00162 * 00163 * Revision 1.8 1999/11/29 21:40:08 fisyak 00164 * Add cast to HP 00165 * 00166 * Revision 1.7 1999/11/19 21:58:06 porter 00167 * added method to return "malloc'd" version of table instead of new 00168 * so that delete of St_Table class i done correctly 00169 * 00170 * $Log: StDbTable.cc,v $ 00171 * Revision 1.38 2005/09/07 22:03:04 deph 00172 * update to correct padding issue for pacted tables 00173 * 00174 * Revision 1.37 2004/01/15 00:02:25 fisyak 00175 * Replace ostringstream => StString, add option for alpha 00176 * 00177 * Revision 1.36 2003/09/16 22:44:17 porter 00178 * got rid of all ostrstream objects; replaced with StString+string. 00179 * modified rules.make and added file stdb_streams.h for standalone compilation 00180 * 00181 * Revision 1.35 2003/09/02 17:57:49 perev 00182 * gcc 3.2 updates + WarnOff 00183 * 00184 * Revision 1.34 2003/04/11 22:47:36 porter 00185 * Added a fast multi-row write model specifically needed by the daqEventTag 00186 * writer. Speed increased from about 100Hz to ~3000Hz. It is only invoked if 00187 * the table is marked as Non-Indexed (daqTags & scalers). For non-indexed tables 00188 * which include binary stored data (we don't have any yet), the fast writer has 00189 * to invoke a slower buffer so that the rates are a bit slower (~500Hz at 50 rows/insert). 00190 * 00191 * Revision 1.33 2003/02/12 22:12:45 porter 00192 * moved warning message about null columns (checked in 2 days ago) from the 00193 * depths of the mysql coding into the StDbTable code. This suppresses confusing 00194 * warnings from tables that have had elements removed but their storage columns 00195 * still exist in the database. 00196 * 00197 * Revision 1.32 2003/01/10 04:19:20 porter 00198 * added feature of getting timestamp list (but no data) for a table. 00199 * fixed 2 features sometimes used in online in query-by-whereclause. 00200 * removed a stray 'cout' in a routine that is rarely accessed 00201 * 00202 * Revision 1.31 2002/01/30 15:40:48 porter 00203 * changed limits on flavor tag & made defaults retrieving more readable 00204 * 00205 * Revision 1.30 2001/12/21 04:54:46 porter 00206 * sped up table definition for emc and changed some ostrstream usage for 00207 * insure tests 00208 * 00209 * Revision 1.29 2001/10/26 20:59:46 porter 00210 * fixed new endtime flag from previous checkin. made StDataBaseI available 00211 * at root-cli. 00212 * 00213 * Revision 1.28 2001/10/24 04:05:20 porter 00214 * added long long type to I/O and got rid of obsolete dataIndex table 00215 * 00216 * Revision 1.27 2001/08/02 17:37:20 porter 00217 * fixed problem in fetch by where-clause used in online in StDbSql.cc. 00218 * also got rid of warning comparing unsigned int to int. 00219 * 00220 * Revision 1.26 2001/07/13 22:53:26 porter 00221 * last night's schema-fix was in a switch-case ... I missed one & put it in today 00222 * 00223 * Revision 1.25 2001/07/13 02:28:15 porter 00224 * fix problem in schema evolution for array size changes 00225 * 00226 * Revision 1.24 2001/04/23 19:24:32 porter 00227 * fixed row limit & initial buffer contents for query by where clause 00228 * 00229 * Revision 1.23 2001/02/09 23:06:25 porter 00230 * replaced ostrstream into a buffer with ostrstream creating the 00231 * buffer. The former somehow clashed on Solaris with CC5 iostream (current .dev) 00232 * 00233 * Revision 1.22 2001/02/08 23:23:56 porter 00234 * fixed initialization of schemaID in table & fixed some warnings when 00235 * compiled with NODEBUG 00236 * 00237 * Revision 1.21 2001/01/22 18:38:00 porter 00238 * Update of code needed in next year running. This update has little 00239 * effect on the interface (only 1 method has been changed in the interface). 00240 * Code also preserves backwards compatibility so that old versions of 00241 * StDbLib can read new table structures. 00242 * -Important features: 00243 * a. more efficient low-level table structure (see StDbSql.cc) 00244 * b. more flexible indexing for new systems (see StDbElememtIndex.cc) 00245 * c. environment variable override KEYS for each database 00246 * d. StMessage support & clock-time logging diagnostics 00247 * -Cosmetic features 00248 * e. hid stl behind interfaces (see new *Impl.* files) to again allow rootcint access 00249 * f. removed codes that have been obsolete for awhile (e.g. db factories) 00250 * & renamed some classes for clarity (e.g. tableQuery became StDataBaseI 00251 * and mysqlAccessor became StDbSql) 00252 * 00253 * Revision 1.20 2000/08/15 22:51:52 porter 00254 * Added Root2DB class from Masashi Kaneta 00255 * + made code more robust against requesting data from non-existent databases 00256 * 00257 * Revision 1.19 2000/06/30 01:57:02 porter 00258 * fixed a delete bug & small memory leak found by Akio via Insure++ , 00259 * updated SetTable() method for containing idList, corrected enumeration 00260 * map to rhic domain for Conditions_rhic database 00261 * 00262 * Revision 1.18 2000/06/02 13:37:37 porter 00263 * built up list of minor changes: 00264 * - made buffer more robust for certain null inputs 00265 * - fixed small leak in StDbTables & restructure call to createMemory 00266 * - added dbRhic as a database domain in StDbDefs 00267 * - added setUser() in StDbManager 00268 * - added more diagnostic printouts in mysqlAccessor.cc 00269 * 00270 * Revision 1.17 2000/05/10 21:39:02 porter 00271 * fixed delete[] bug in reading from table where input schema includes fields that 00272 * are not in the database by checking buffer status for reads 00273 * 00274 * Revision 1.16 2000/04/25 18:26:03 porter 00275 * added flavor & production time as settable query fields in 00276 * table &/or node. Associated SQL updated in mysqlAccessor. 00277 * Flavor key supports "+" as an OR symbol. 00278 * 00279 * Revision 1.15 2000/03/28 17:03:19 porter 00280 * Several upgrades: 00281 * 1. configuration by timestamp for Conditions 00282 * 2. query by whereClause made more systematic 00283 * 3. conflict between db-stored comments & number lists resolved 00284 * 4. ensure endtime is correct for certain query falures 00285 * 5. dbstl.h->handles ObjectSpace & RogueWave difference (Online vs Offline) 00286 * 00287 * Revision 1.14 2000/02/15 20:27:44 porter 00288 * Some updates to writing to the database(s) via an ensemble (should 00289 * not affect read methods & haven't in my tests. 00290 * - closeAllConnections(node) & closeConnection(table) method to mgr. 00291 * - 'NullEntry' version to write, with setStoreMode in table; 00292 * - updated both StDbTable's & StDbTableDescriptor's copy-constructor 00293 * 00294 * Revision 1.13 2000/01/27 05:54:34 porter 00295 * Updated for compiling on CC5 + HPUX-aCC + KCC (when flags are reset) 00296 * Fixed reConnect()+transaction model mismatch 00297 * added some in-code comments 00298 * 00299 * Revision 1.12 2000/01/19 20:20:07 porter 00300 * - finished transaction model needed by online 00301 * - fixed CC5 compile problem in StDbNodeInfo.cc 00302 * - replace TableIter class by StDbTableIter to prevent name problems 00303 * 00304 * Revision 1.11 2000/01/10 20:37:54 porter 00305 * expanded functionality based on planned additions or feedback from Online work. 00306 * update includes: 00307 * 1. basis for real transaction model with roll-back 00308 * 2. limited SQL access via the manager for run-log & tagDb 00309 * 3. balance obtained between enumerated & string access to databases 00310 * 4. 3-levels of diagnostic output: Quiet, Normal, Verbose 00311 * 5. restructured Node model for better XML support 00312 * 00313 * Revision 1.10 1999/12/07 21:25:25 porter 00314 * some fixes for linux warnings 00315 * 00316 * Revision 1.9 1999/12/03 19:01:59 porter 00317 * modified descriptor to accept tableDescriptor once this St_base object 00318 * has been updated to have longer name lengths. 00319 * 00320 * Revision 1.6 1999/10/19 14:30:39 porter 00321 * modifications relevant to use with StDbBroker and future merging with 00322 * "params" database structure + some docs + suppressing diagnostics messages 00323 * 00324 * Revision 1.5 1999/09/30 02:06:10 porter 00325 * add StDbTime to better handle timestamps, modify SQL content (mysqlAccessor) 00326 * allow multiple rows (StDbTable), & Added the comment sections at top of 00327 * each header and src file 00328 * 00329 **************************************************************************/ 00330 #include "StDbTable.h" 00331 #include "StDbBuffer.h" 00332 #include "typeAcceptor.hh" 00333 #include "StTableDescriptorI.h" 00334 #include "StDbDefaults.hh" 00335 #include "StDbManager.hh" 00336 #include <string.h> 00337 #include "stdb_streams.h" 00338 #include <malloc.h> 00339 #ifdef __ROOT__ 00340 ClassImp(StDbTable) 00341 #endif 00342 00343 #define __CLASS__ "StDbTable" 00344 00346 StDbTable::StDbTable(const char* tableName): StDbNode(tableName) { init();}; 00347 00348 StDbTable::StDbTable(const char* tableName, int schemaID): StDbNode(tableName) { init(); mschemaID=schemaID; } 00349 00350 00351 StDbTable::StDbTable(StDbTable& table): StDbNode(table) { 00352 00353 init(); 00354 mflavor=table.getFlavor(); 00355 mdefaultFlavor = table.defaultFlavor(); 00356 mprodTime = table.getProdTime(); 00357 00358 mschemaID = table.getSchemaID(); 00359 mrows = table.GetNRows(); 00360 mhasDescriptor=table.hasDescriptor(); 00361 mdescriptor=table.getDescriptorCpy(); 00362 00363 mbeginTime.setDateTime(table.getBeginDateTime()); 00364 mbeginTime.setUnixTime(table.getBeginTime()); 00365 mendTime.setDateTime(table.getEndDateTime()); 00366 mendTime.setUnixTime(table.getEndTime()); 00367 00368 char* tmp = table.GetTable(); 00369 if(mrows==0) mrows = 1; 00370 if(tmp) { 00371 unsigned int size = mrows*table.getTableSize(); 00372 mdata = new char[size]; 00373 memcpy(mdata,tmp,size); 00374 mhasData = true; 00375 } 00376 00377 setCstructName(table.printCstructName()); 00378 setDataTable(table.printDataTable()); 00379 00380 } 00381 00382 void StDbTable::init() { 00383 mflavor = 0; 00384 mstructName = 0; 00385 melementName = 0; 00386 mdataTable = 0; 00387 melementID = 0; 00388 mhasDescriptor = false; 00389 mdescriptor = 0; 00390 mdata = 0; 00391 mhasData = false; 00392 mrowsRequested = 0; 00393 mtimeVals = 0; 00394 mendTime.munixTime = 0; 00395 mrows = 0; 00396 mrowNumber = 0; 00397 mprodTime = StDbDefaults::Instance()->getProdTime(); 00398 setDefaultFlavor(); 00399 mschemaID = 0; 00400 00401 } 00402 00404 void StDbTable::setNodeInfo(StDbNode* node){ 00405 00406 mdbType=node->getDbType(); 00407 mdbDomain=node->getDbDomain(); 00408 setDbName(node->printDbName()); 00409 setVersion(node->printVersion()); 00410 setNodeType(node->printNodeType()); 00411 mnodeID=node->getNodeID(); 00412 }; 00413 00415 void StDbTable::setCstructName(const char* name){ mstructName=mstrDup(name); } 00416 00418 char* StDbTable::getCstructName() { return mstrDup(mstructName); } 00419 00421 void StDbTable::setDataTable(const char* name){ mdataTable=mstrDup(name); } 00422 00424 char* StDbTable::getDataTable() { return mstrDup(mdataTable); } 00425 00427 void 00428 StDbTable::setDefaultFlavor(){ setFlavor(StDbDefaults::Instance()->printFlavor()); 00429 } 00430 00432 void StDbTable::setFlavor(const char* flavor) { 00433 if(!flavor) return; 00434 if(mflavor) delete [] mflavor; 00435 mflavor=new char[strlen(flavor)+1]; 00436 strcpy(mflavor,flavor); 00437 mdefaultFlavor = StDbDefaults::Instance()->IsDefaultFlavor(mflavor); 00438 } 00439 00440 char* StDbTable::getFlavor() { return mstrDup(mflavor); } 00441 00442 00444 void 00445 StDbTable::addWrittenRows(int* dataID, int numRows, bool canRollBack){ 00446 00447 for(int i=0; i<numRows; i++) mstoredData.addWrittenRow(dataID[i]); 00448 if(canRollBack)mcanRollBack=true; 00449 00450 } 00451 00452 int* 00453 StDbTable::getWrittenRows(int& nRows){ 00454 return mstoredData.getDataIDs(nRows); 00455 } 00456 void StDbTable::commitData() { mstoredData.commit(); } 00457 void StDbTable::clearStoreInfo() { mstoredData.resetStoreInfo(); } 00458 00460 StTableDescriptorI* 00461 StDbTable::getDescriptorCpy() const { return mdescriptor->getCpy(); } 00462 00464 void 00465 StDbTable::setDescriptor(StTableDescriptorI* descriptor){ 00466 00467 if(mdescriptor) delete mdescriptor; 00468 mdescriptor=descriptor; 00469 mhasDescriptor=true; 00470 00471 //checkDescriptor(); 00472 00473 }; 00474 00476 char* StDbTable::GetTable() { if(!mdata)createMemory(); return mdata;}; 00477 00479 void* 00480 StDbTable::GetTableCpy() { 00481 00482 if(!mdata)return (void*)GetTable(); 00483 00484 int len = mrows*getTableSize(); 00485 char* c = (char*)calloc(mrows,getTableSize()); 00486 memcpy(c,mdata,len); 00487 00488 return (void*)c; 00489 }; 00490 00492 void 00493 StDbTable::SetTable(char* c, int nrows, int* idList) { 00494 00495 if(mdata){ 00496 delete [] mdata; 00497 mdata = 0; 00498 } 00499 if(!idList){ 00500 createMemory(nrows); 00501 } else { 00502 setElementID(idList,nrows); // createMemory is called here 00503 } 00504 int len = nrows*getTableSize(); 00505 memcpy(mdata,c,len); 00506 mhasData=true; 00507 00508 } 00509 00511 void 00512 StDbTable::AddRows(char* c, int nrows) { 00513 00514 char* tmpData = duplicateData(); 00515 int len1 = mrows*getTableSize(); 00516 int len2 = nrows*getTableSize(); 00517 00518 int newRows = nrows+mrows; 00519 if(mdata){ 00520 delete [] mdata; 00521 mdata = 0; 00522 } 00523 00524 createMemory(newRows); 00525 00526 char* ptr= &mdata[0]; 00527 memcpy(mdata,tmpData,len1); 00528 ptr+=len1; 00529 memcpy(ptr,c,len2); 00530 00531 delete [] tmpData; 00532 mhasData=true; 00533 00534 } 00535 00537 void* 00538 StDbTable::getDataValue(const char* name, int rowNumber){ 00539 00540 void* retVal=0; 00541 int saveRowNum=mrowNumber; 00542 mrowNumber=rowNumber; 00543 int max = mdescriptor->getNumElements(); 00544 char* ename=0; 00545 StTypeE type; 00546 unsigned int length; 00547 char * ptr; 00548 00549 for(int i=0;i<max;i++){ 00550 getElementSpecs(i,ptr,ename,length,type); 00551 if(strcmp(name,ename)==0)break; 00552 if(ename) delete [] ename; 00553 ename=0; 00554 } 00555 00556 mrowNumber=saveRowNum; 00557 if(!ename) return retVal; 00558 00559 delete [] ename; 00560 return (void*)ptr; 00561 } 00562 00564 char* 00565 StDbTable::duplicateData() { 00566 00567 char* dup=0; 00568 int len1 = mrows*getTableSize(); 00569 if(len1 !=0){ 00570 dup=new char[len1]; 00571 memcpy(dup,mdata,len1); 00572 } 00573 return dup; 00574 } 00575 00577 00578 bool 00579 StDbTable::createMemory(int nrows) { 00580 mrows = nrows; 00581 bool retVal = true; 00582 if(mrows==0) { 00583 if(mdata)delete [] mdata; 00584 mdata=0; 00585 return retVal; 00586 } 00587 00588 // mdescriptor->getNumElements(); 00589 //if (mdescriptor) { 00590 //cout <<"**************CHECKIT************"<<endl; 00591 //} 00592 if(mdescriptor && mdescriptor->getNumElements()>0){ 00593 // if(mrows==0) mrows = 1; 00594 //int len = mrows*mdescriptor->getTotalSizeInBytes(); 00595 int len; 00596 if (!mdescriptor->getTrowSize()){ 00597 len = mrows*mdescriptor->getTotalSizeInBytes(); 00598 }else{ 00599 len = mrows*mdescriptor->getTrowSize(); 00600 } 00601 if(len>0){ 00602 if(mdata)delete [] mdata; 00603 mdata=new char[len]; 00604 memset(mdata,0,len); 00605 int max = mdescriptor->getNumElements(); 00606 char* name; 00607 StTypeE type; 00608 unsigned int length; 00609 char * ptr; 00610 for(int i=0; i<max;i++){ 00611 getElementSpecs(i,ptr,name,length,type); 00612 if(type==Stchar)ptr='\0'; 00613 delete [] name; 00614 } 00615 } 00616 } else { 00617 if(!mname){mname=mstrDup("Unknown");} 00618 retVal = false; 00619 } 00620 00621 return retVal; 00622 } 00623 00625 bool 00626 StDbTable::createMemory() { 00627 if(mdata)return true; 00628 if(mrows==0) mrows=1; 00629 return createMemory(mrows); 00630 } 00631 00633 00634 char* 00635 StDbTable::getElementName() { return mstrDup(melementName); }; 00636 00637 void 00638 StDbTable::setElementName(const char* name) { melementName=mstrDup(name);}; 00639 00640 void 00641 StDbTable::setElementID(int* elements, int nrows) { 00642 00643 createMemory(nrows); 00644 // set up & fill char* will element list 00645 if(melementID) delete [] melementID; 00646 if(nrows==0){ 00647 melementID=0; 00648 return; 00649 } 00650 melementID = new int[nrows]; 00651 memcpy(melementID, elements, nrows*sizeof(int)); 00652 } 00653 00655 void StDbTable::resizeNumRows(int nrows){ 00656 // if only some rows are returned, this is called to 00657 // compress memory 00658 00659 //unsigned int rowsize=mdescriptor->getTotalSizeInBytes(); 00660 unsigned int rowsize; 00661 if (!mdescriptor->getTrowSize()) { 00662 rowsize=mdescriptor->getTotalSizeInBytes(); 00663 }else{ 00664 rowsize=mdescriptor->getTrowSize(); 00665 } 00666 unsigned int len = mrows*rowsize; 00667 unsigned int newlen = nrows*rowsize; 00668 00669 if(mdata){ 00670 char* oldData=new char[len]; 00671 memcpy(oldData,mdata,len); 00672 delete [] mdata; 00673 mdata = new char[newlen]; 00674 if(newlen<=len){ 00675 memcpy(mdata,oldData,newlen); 00676 } else { 00677 memcpy(mdata,oldData,len); 00678 } 00679 delete [] oldData; 00680 } 00681 00682 mrows=nrows; 00683 return; 00684 } 00685 00686 00688 void 00689 StDbTable::addNRows(int numRows){ 00690 00691 if(!mdescriptor) return; 00692 00693 int newRows = numRows+mrows; 00694 //unsigned int rowsize=mdescriptor->getTotalSizeInBytes(); 00695 unsigned int rowsize; 00696 if(!mdescriptor->getTrowSize()) { 00697 rowsize=mdescriptor->getTotalSizeInBytes(); 00698 }else{ 00699 rowsize=mdescriptor->getTrowSize(); 00700 } 00701 unsigned int len = newRows*rowsize; 00702 char* newData = new char[len]; 00703 memset(newData,0,len); 00704 if(mdata)memcpy(newData,mdata,mrows*rowsize); 00705 char* p1 = newData; 00706 p1+=mrows*rowsize; 00707 memset(p1,0,numRows*rowsize); 00708 if(mdata)delete [] mdata; 00709 mdata=newData; 00710 00711 resizeElementID(newRows); 00712 }; 00713 00715 void 00716 StDbTable::resizeElementID(int numRows){ 00717 00718 int * newElements=new int[numRows]; 00719 if(melementID) { 00720 memcpy(newElements,melementID,mrows*sizeof(int)); 00721 delete [] melementID; 00722 } 00723 melementID=newElements; 00724 mrows = numRows; 00725 00726 }; 00727 00729 void 00730 StDbTable::addNElements(int* elements, int newRows){ 00731 00732 00733 if(!melementID) return; 00734 00735 int i,j,k; 00736 k=mrows-newRows; 00737 if(k<0)return; 00738 j=0; 00739 for(i=k;i<mrows;i++){ 00740 melementID[i]=elements[j]; 00741 j++; 00742 } 00743 00744 } 00745 00747 void 00748 StDbTable::StreamAccessor(typeAcceptor* accept, bool isReading){ 00749 00750 int len = 1; 00751 accept->pass((char*)"schemaID",mschemaID,len); 00752 00753 if(isReading){ 00754 if(mbeginTime.mdateTime) delete [] mbeginTime.mdateTime; 00755 if(mversion)delete [] mversion; 00756 if(melementID)delete [] melementID; 00757 } else { 00758 if(!melementID){ 00759 melementID = new int[mrows]; 00760 for(int i=0;i<mrows;i++)melementID[i]=i; 00761 } 00762 } 00763 accept->pass((char*)"beginTime",mbeginTime.mdateTime,len); 00764 accept->pass((char*)"version",mversion,len); 00765 accept->pass((char*)"elementID",melementID, mrows); 00766 } 00767 00769 void 00770 StDbTable::StreamAccessor(StDbBufferI* buff, bool isReading){ 00771 00772 bool ClientMode; 00773 if(!(ClientMode=buff->IsClientMode()))buff->SetClientMode(); 00774 00775 int rowID; 00776 if(!melementID){ 00777 melementID = new int[mrows]; 00778 for(int i=0;i<mrows;i++)melementID[i]=i; 00779 } 00780 00781 if(isReading){ 00782 buff->ReadScalar(rowID,"elementID"); 00783 melementID[mrowNumber]=rowID; 00784 00785 if(mrowNumber==0){ 00786 buff->ReadScalar(mschemaID,"schemaID"); 00787 if(mversion) delete [] mversion; 00788 buff->ReadScalar(mversion,"version"); 00789 } else { 00790 unsigned int bTime;// , eTime; 00791 buff->ReadScalar(bTime,"beginTime"); 00792 if(bTime>mbeginTime.munixTime)mbeginTime.munixTime=bTime; 00793 } 00794 00795 } else { 00796 00797 buff->WriteScalar(mschemaID,"schemaID"); 00798 buff->WriteScalar(mbeginTime.munixTime,"beginTime"); 00799 if(mversion)buff->WriteScalar(mversion,"version"); 00800 rowID = melementID[mrowNumber]; 00801 buff->WriteScalar(rowID,"elementID"); 00802 } 00803 00804 if(!ClientMode)buff->SetStorageMode(); // reset to StorageMode 00805 00806 } 00807 00809 void 00810 StDbTable::getElementSpecs(int elementNum, char*& c, char*& name, unsigned int& length,StTypeE& type){ 00811 00812 int tRow = mdescriptor->getTrowSize(); 00813 unsigned int tSize=mdescriptor->getTotalSizeInBytes(); 00814 unsigned int rowIndex; 00815 if (!tRow) { 00816 rowIndex = ((unsigned int)mrowNumber)*tSize; 00817 }else{ 00818 rowIndex = ((unsigned int)mrowNumber)*tRow; 00819 } 00820 int i = elementNum; 00821 c = &mdata[rowIndex]; 00822 int current = mdescriptor->getElementOffset(i); 00823 c += current; // for(int k=0;k<current;k++)c++; 00824 name = mdescriptor->getElementName(i); 00825 length = mdescriptor->getElementLength(i);; 00826 type = mdescriptor->getElementType(i); 00827 00828 return; 00829 } 00830 00832 void 00833 StDbTable::dbStreamer(StDbBufferI* buff, bool isReading){ 00834 00835 int max = mdescriptor->getNumElements(); 00836 char* name; 00837 StTypeE type; 00838 unsigned int length; 00839 char* ptr; 00840 00841 bool ClientMode; 00842 if(!(ClientMode=buff->IsClientMode()))buff->SetClientMode(); 00843 00844 if(createMemory() && mrowNumber < mrows){ 00845 00846 for(int i=0; i<max; i++){ 00847 getElementSpecs(i,ptr,name,length,type); 00848 if(isReading){ 00849 ReadElement(ptr,name,length,type,(StDbBuffer*)buff); 00850 } else { 00851 WriteElement(ptr,name,length,type,(StDbBuffer*)buff); 00852 } 00853 delete [] name; 00854 } 00855 00856 mrowNumber++; 00857 if(isReading)mhasData=true; 00858 00859 } else { 00860 cerr << "dbStreamer:: more rows delivered than allocated " << endl; 00861 } 00862 if(!ClientMode)buff->SetStorageMode(); // reset to StorageMode 00863 } 00864 00865 00867 void 00868 StDbTable::dbStreamerWrite(StDbBufferI* buff){ 00869 00870 int max = mdescriptor->getNumElements(); 00871 char* name; 00872 StTypeE type; 00873 unsigned int length; 00874 char* ptr; 00875 00876 // bool ClientMode; 00877 // if(!(ClientMode=buff->IsClientMode()))buff->SetClientMode(); 00878 00879 // if(createMemory() && mrowNumber < mrows){ 00880 00881 if(mrowNumber<mrows){ 00882 for(int i=0; i<max; i++){ 00883 getElementSpecs(i,ptr,name,length,type); 00884 WriteElement(ptr,name,length,type,(StDbBuffer*)buff); 00885 delete [] name; 00886 } 00887 mrowNumber++; 00888 } 00889 } 00890 00892 00893 void 00894 StDbTable::dbTableStreamer(StDbBufferI* buff, const char* name, bool isReading){ 00895 00896 int max = mdescriptor->getNumElements(); 00897 //int size = mdescriptor->getTotalSizeInBytes(); 00898 StTypeE type = mdescriptor->getElementType(0); 00899 unsigned int length = (unsigned int) mrows*max; 00900 00901 char* ptr; 00902 00903 bool ClientMode; 00904 if(!(ClientMode=buff->IsClientMode()))buff->SetClientMode(); 00905 00906 if(createMemory() && mrowNumber < mrows){ 00907 00908 ptr = &mdata[0]; 00909 // getElementSpecs(i,ptr,name,length,type); 00910 if(isReading){ 00911 ReadElement(ptr,(char *) name,length,type,(StDbBuffer*)buff); 00912 } else { 00913 WriteElement(ptr,(char *) name,length,type,(StDbBuffer*)buff); 00914 } 00915 mrowNumber=mrows; 00916 if(isReading) mhasData=true; 00917 } 00918 00919 if(!ClientMode)buff->SetStorageMode(); // reset to StorageMode 00920 } 00921 00922 00924 00925 void 00926 StDbTable::dbStreamer(typeAcceptor* accept, bool isReading){ 00927 00928 int max = mdescriptor->getNumElements(); 00929 char* name; 00930 StTypeE type; 00931 unsigned int length; 00932 char* ptr; 00933 00934 if(createMemory() && mrowNumber < mrows){ 00935 00936 if(isReading){ 00937 for(int i=0; i<max; i++){ 00938 getElementSpecs(i,ptr,name,length,type); 00939 PassInElement(ptr,name,length,type,accept); 00940 delete [] name; 00941 } 00942 mhasData=true; 00943 } else { 00944 for(int i=0; i<max; i++){ 00945 getElementSpecs(i,ptr,name,length,type); 00946 PassOutElement(ptr,name,length,type,accept); 00947 delete [] name; 00948 } 00949 } 00950 00951 mrowNumber++; 00952 } 00953 00954 } 00955 00957 00958 void 00959 StDbTable::ReadElement(char*& ptr, char* name, int len, StTypeE type, StDbBuffer* buff){ 00960 00961 char* mchar; unsigned char* muchar; short* mshort; unsigned short* mushort; 00962 int* mint; unsigned int* muint; long* mlong; unsigned long* mulong; 00963 long long* mlonglong; 00964 float* mfloat; double* mdouble; 00965 00966 int blen; // length returned from db ### use lesser of len & blen 00967 00968 switch (type) { 00969 case Stchar: 00970 { 00971 StString cn; 00972 cn<<name<<".text"; const char* commentName = (cn.str()).c_str(); 00973 mchar = 0; 00974 if(!buff->ReadScalar(mchar,commentName))buff->ReadScalar(mchar,name); 00975 if(mchar){ 00976 int len1=strlen(mchar); 00977 if(len>len1) len=len1; 00978 strncpy(ptr,mchar,len); 00979 delete [] mchar; 00980 } else { 00981 *ptr='\0'; 00982 printNoDataReturned(name); 00983 } 00984 break; 00985 } 00986 case Stuchar: 00987 { 00988 if(buff->ReadArray(muchar,blen,name)){ 00989 if(len>blen)len=blen; 00990 memcpy(ptr,muchar,len*sizeof(unsigned char)); 00991 delete [] muchar; 00992 } else { printNoDataReturned(name); } 00993 break; 00994 } 00995 case Stshort: 00996 { 00997 if(buff->ReadArray(mshort,blen,name)){ 00998 if(len>blen)len=blen; 00999 memcpy(ptr,mshort,len*sizeof(short)); 01000 delete [] mshort; 01001 } else { printNoDataReturned(name); } 01002 break; 01003 } 01004 case Stushort: 01005 { 01006 if(buff->ReadArray(mushort,blen,name)){ 01007 if(len>blen)len=blen; 01008 memcpy(ptr,mushort,len*sizeof(unsigned short)); 01009 delete [] mushort; 01010 } else { printNoDataReturned(name); } 01011 break; 01012 } 01013 case Stint: 01014 { 01015 if(buff->ReadArray(mint,blen,name)){ 01016 if(len>blen)len=blen; 01017 memcpy(ptr,mint,len*sizeof(int)); 01018 delete [] mint; 01019 } else { printNoDataReturned(name); } 01020 break; 01021 } 01022 case Stuint: 01023 { 01024 if(buff->ReadArray(muint,blen,name)){ 01025 if(len>blen)len=blen; 01026 memcpy(ptr,muint,len*sizeof(unsigned int)); 01027 delete [] muint; 01028 } else { printNoDataReturned(name); } 01029 break; 01030 } 01031 case Stlong: 01032 { 01033 if(buff->ReadArray(mlong,blen,name)){ 01034 if(len>blen)len=blen; 01035 memcpy(ptr,mlong,len*sizeof(long)); 01036 delete [] mlong; 01037 } else { printNoDataReturned(name); } 01038 break; 01039 } 01040 case Stulong: 01041 { 01042 if(buff->ReadArray(mulong,blen,name)){ 01043 if(len>blen)len=blen; 01044 memcpy(ptr,mulong,len*sizeof(unsigned long)); 01045 delete [] mulong; 01046 } else { printNoDataReturned(name); } 01047 break; 01048 } 01049 case Stlonglong: 01050 { 01051 if(buff->ReadArray(mlonglong,blen,name)){ 01052 if(len>blen)len=blen; 01053 memcpy(ptr,mlonglong,len*sizeof(long long)); 01054 delete [] mlonglong; 01055 } else { printNoDataReturned(name); } 01056 break; 01057 } 01058 case Stfloat: 01059 { 01060 if(buff->ReadArray(mfloat,blen,name)){ 01061 if(len>blen)len=blen; 01062 memcpy(ptr,mfloat,len*sizeof(float)); 01063 delete [] mfloat; 01064 } else { printNoDataReturned(name); } 01065 break; 01066 } 01067 case Stdouble: 01068 { 01069 if(buff->ReadArray(mdouble,blen,name)){ 01070 if(len>blen)len=blen; 01071 memcpy(ptr,mdouble,len*sizeof(double)); 01072 delete [] mdouble; 01073 } else { printNoDataReturned(name); } 01074 break; 01075 } 01076 } 01077 01078 } 01079 01081 01082 void 01083 StDbTable::WriteElement(char* ptr, char* name, int len, StTypeE type, StDbBuffer* buff){ 01084 01085 switch (type) { 01086 case Stchar: 01087 { 01088 char* mchar = ptr; 01089 buff->WriteScalar(mchar,name); 01090 break; 01091 } 01092 case Stuchar: 01093 { 01094 unsigned char* muchar = (unsigned char*)ptr; 01095 buff->WriteArray(muchar,len,name); 01096 break; 01097 } 01098 case Stshort: 01099 { 01100 short* mshort = (short*) ptr; 01101 buff->WriteArray(mshort ,len,name); 01102 break; 01103 } 01104 case Stushort: 01105 { 01106 unsigned short* mushort = (unsigned short*) ptr; 01107 buff->WriteArray(mushort,len,name); 01108 break; 01109 } 01110 case Stint: 01111 { 01112 int* mint = (int*)ptr; 01113 buff->WriteArray(mint,len,name); 01114 break; 01115 } 01116 case Stuint: 01117 { 01118 unsigned int* muint = (unsigned int*) ptr; 01119 buff->WriteArray(muint,len,name); 01120 break; 01121 } 01122 case Stlong: 01123 { 01124 long* mlong = (long*) ptr; 01125 //if(len==1) cout << name << " = "<< *mlong << endl; 01126 buff->WriteArray(mlong,len,name); 01127 break; 01128 } 01129 case Stulong: 01130 { 01131 unsigned long* mulong = (unsigned long*) ptr; 01132 buff->WriteArray(mulong,len,name); 01133 break; 01134 } 01135 case Stlonglong: 01136 { 01137 long long* mlonglong = (long long*) ptr; 01138 buff->WriteArray(mlonglong,len,name); 01139 break; 01140 } 01141 case Stfloat: 01142 { 01143 float* mfloat = (float*) ptr; 01144 //if(len==1) cout << name << " = "<< *mfloat << endl; 01145 buff->WriteArray(mfloat,len,name); 01146 break; 01147 } 01148 case Stdouble: 01149 { 01150 double* mdouble = (double*) ptr; 01151 buff->WriteArray(mdouble,len,name); 01152 break; 01153 } 01154 } 01155 01156 } 01157 01159 void 01160 StDbTable::PassInElement(char* ptr, char* name, int len, StTypeE type, typeAcceptor* accept){ 01161 01162 01163 switch (type) { 01164 case Stchar: 01165 { 01166 char* data; 01167 accept->pass(name,data,len); 01168 memcpy(ptr,data,len); 01169 delete [] data; 01170 break; 01171 } 01172 case Stuchar: 01173 { 01174 unsigned char* data; 01175 accept->pass(name,data,len); 01176 memcpy(ptr,data,len); 01177 delete [] data; 01178 break; 01179 } 01180 case Stshort: 01181 { 01182 short* data; 01183 accept->pass(name,data,len); 01184 memcpy(ptr,data,len*sizeof(short)); 01185 delete [] data; 01186 break; 01187 } 01188 case Stushort: 01189 { 01190 unsigned short* data; 01191 accept->pass(name,data,len); 01192 memcpy(ptr,data,len*sizeof(short)); 01193 delete [] data; 01194 break; 01195 } 01196 case Stint: 01197 { 01198 int* data; 01199 accept->pass(name,data,len); 01200 memcpy(ptr,data,len*sizeof(int)); 01201 delete [] data; 01202 break; 01203 } 01204 case Stuint: 01205 { 01206 unsigned int* data; 01207 accept->pass(name,data,len); 01208 memcpy(ptr,data,len*sizeof(int)); 01209 delete [] data; 01210 break; 01211 } 01212 case Stlong: 01213 { 01214 long* data; 01215 accept->pass(name,data,len); 01216 memcpy(ptr,data,len*sizeof(long)); 01217 delete [] data; 01218 break; 01219 } 01220 case Stulong: 01221 { 01222 unsigned long* data; 01223 accept->pass(name,data,len); 01224 memcpy(ptr,data,len*sizeof(long)); 01225 delete [] data; 01226 break; 01227 } 01228 case Stlonglong: 01229 { 01230 long long* data; 01231 accept->pass(name,data,len); 01232 memcpy(ptr,data,len*sizeof(long long)); 01233 delete [] data; 01234 break; 01235 } 01236 case Stfloat: 01237 { 01238 float* data; 01239 accept->pass(name,data,len); 01240 memcpy(ptr,data,len*sizeof(float)); 01241 delete [] data; 01242 break; 01243 } 01244 case Stdouble: 01245 { 01246 double* data; 01247 accept->pass(name,data,len); 01248 memcpy(ptr,data,len*sizeof(double)); 01249 delete [] data; 01250 break; 01251 } 01252 } 01253 } 01254 01256 01257 void 01258 StDbTable::PassOutElement(char* ptr, char* name, int len, StTypeE type, typeAcceptor* accept){ 01259 01260 switch (type) { 01261 case Stchar: 01262 { 01263 accept->pass(name,ptr,len); 01264 break; 01265 } 01266 case Stuchar: 01267 { 01268 unsigned char* muchar = (unsigned char*)ptr; 01269 accept->pass(name, muchar,len); 01270 break; 01271 } 01272 case Stshort: 01273 { 01274 short* mshort = (short*)ptr; 01275 if(len==1){ 01276 accept->pass(name, *mshort ,len); 01277 } else { 01278 accept->pass(name,mshort,len); 01279 } 01280 break; 01281 } 01282 case Stushort: 01283 { 01284 unsigned short* mushort = (unsigned short*)ptr; 01285 if(len==1){ 01286 accept->pass(name, *mushort ,len); 01287 } else { 01288 accept->pass(name,mushort,len); 01289 } 01290 break; 01291 } 01292 case Stint: 01293 { 01294 int* mint = (int*)ptr; 01295 if(len==1){ 01296 accept->pass(name, *mint ,len); 01297 } else { 01298 accept->pass(name,mint,len); 01299 } 01300 break; 01301 } 01302 case Stuint: 01303 { 01304 unsigned int* muint = (unsigned int*)ptr; 01305 if(len==1){ 01306 accept->pass(name, *muint ,len); 01307 } else { 01308 accept->pass(name,muint,len); 01309 } 01310 break; 01311 } 01312 case Stlong: 01313 { 01314 long* mlong = (long*)ptr; 01315 if(len==1){ 01316 accept->pass(name, *mlong ,len); 01317 } else { 01318 accept->pass(name,mlong,len); 01319 } 01320 break; 01321 } 01322 case Stulong: 01323 { 01324 unsigned long* mulong = (unsigned long*)ptr; 01325 if(len==1){ 01326 accept->pass(name, *mulong ,len); 01327 } else { 01328 accept->pass(name,mulong,len); 01329 } 01330 break; 01331 } 01332 case Stlonglong: 01333 { 01334 long long* mlonglong = (long long*)ptr; 01335 if(len==1){ 01336 accept->pass(name, *mlonglong ,len); 01337 } else { 01338 accept->pass(name,mlonglong,len); 01339 } 01340 break; 01341 } 01342 case Stfloat: 01343 { 01344 float* mfloat = (float*)ptr; 01345 if(len==1){ 01346 accept->pass(name, *mfloat ,len); 01347 } else { 01348 accept->pass(name,mfloat,len); 01349 } 01350 break; 01351 } 01352 case Stdouble: 01353 { 01354 double* mdouble = (double*)ptr; 01355 if(len==1){ 01356 accept->pass(name, *mdouble ,len); 01357 } else { 01358 accept->pass(name,mdouble,len); 01359 } 01360 break; 01361 } 01362 } 01363 } 01364 01366 void 01367 StDbTable::checkDescriptor(){ 01368 01369 int i = mdescriptor->getNumElements(); 01370 unsigned int size = mdescriptor->getTotalSizeInBytes(); 01371 cout <<"Descriptor for Table = " << mname<<endl; 01372 cout <<" number of elements = "<<i<< " with size = " << size << endl; 01373 for(int k=0; k<i;k++){ 01374 cout <<"Name = " << mdescriptor->getElementName(k); 01375 cout <<" size = " << mdescriptor->getElementSize(k); 01376 cout <<" offset = " <<mdescriptor->getElementOffset(k); 01377 cout <<" type = " <<(int)mdescriptor->getElementType(k)<<endl; 01378 } 01379 } 01380 01381 01382 void StDbTable::printNoDataReturned(const char* elementName){ 01383 01384 StString emess; 01385 emess<<" No data return from table="<<printName()<<" column="<<elementName; 01386 StDbManager::Instance()->printInfo((emess.str()).c_str(),dbMWarn,__LINE__,__CLASS__,"ReadElement(ptr,name,len,type,buffer)"); 01387 } 01388 01389 #undef __CLASS__ 01390 01391 01392 01393 01394 01395 01396 01397 01398 01399 01400 01401

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