![]() |
|
|
Generated: 18 Jul 2008 |
00001 // $Id: PoolDbNTupleCnv.cpp,v 1.15 2008/01/17 13:20:52 marcocle Exp $ 00002 //------------------------------------------------------------------------------ 00003 // 00004 // Implementation of class : PoolDbNTupleCnv 00005 // 00006 // Author : Markus Frank 00007 // 00008 //------------------------------------------------------------------------------ 00009 00010 #define ALLOW_ALL_TYPES 00011 // Include files 00012 #include "GaudiPoolDb/IPoolDbMgr.h" 00013 #include "GaudiPoolDb/PoolDbAddress.h" 00014 #include "GaudiPoolDb/PoolDbNTupleCnv.h" 00015 #include "GaudiPoolDb/PoolDbLinkManager.h" 00016 #include "GaudiPoolDb/PoolDbNTupleDescriptor.h" 00017 #include "GaudiPoolDb/PoolDbTupleCallback.h" 00018 00019 #include "GaudiKernel/xtoa.h" 00020 #include "GaudiKernel/NTuple.h" 00021 #include "GaudiKernel/SmartIF.h" 00022 #include "GaudiKernel/SmartRef.h" 00023 #include "GaudiKernel/MsgStream.h" 00024 #include "GaudiKernel/INTupleSvc.h" 00025 #include "GaudiKernel/IRegistry.h" 00026 #include "GaudiKernel/ISelectStatement.h" 00027 #include "GaudiKernel/ContainedObject.h" 00028 #include "GaudiKernel/GenericAddress.h" 00029 #include "GaudiKernel/CnvFactory.h" 00030 00031 #include "StorageSvc/DbSelect.h" 00032 #include "StorageSvc/DbReflex.h" 00033 #include "StorageSvc/DbColumn.h" 00034 #include "StorageSvc/DbTypeInfo.h" 00035 #include "StorageSvc/DbObjectCallBack.h" 00036 00037 #define S_OK StatusCode::SUCCESS 00038 #define S_FAIL StatusCode::FAILURE 00039 #include "Reflex/Builder/ReflexBuilder.h" 00040 00041 namespace pool { 00042 const std::string typeName(const std::type_info& typ); 00043 } 00044 00045 void popCurrentDataObject(); 00046 void pushCurrentDataObject(DataObject** pobjAddr); 00047 00048 namespace pool { void genMD5(const std::string& s, void* code); } 00049 using pool::genMD5; 00050 00051 template <class T> static inline 00052 void* save(pool::DbBlob& s, const void* buffer, int len, bool save_len) { 00053 const T* buff = (const T*)buffer; 00054 if ( len > 1 ) { 00055 s << len; 00056 s.swapToBuffer(buff, len*sizeof(T)); 00057 return 0; 00058 } 00059 else if ( save_len ) { 00060 s << len; 00061 return 0; 00062 } 00063 return (void*)buff; 00064 } 00065 00066 static void* save(const void* b, PoolDbTokenWrap* lnk) { 00067 IOpaqueAddress* pA = (*(IOpaqueAddress**)b); 00068 pool::Token& tok = lnk->token; 00069 pool::Guid guid(pool::Guid::null()); 00070 if ( pA ) { 00071 const std::string* spar = pA->par(); 00072 const unsigned long* ipar = pA->ipar(); 00073 guid.Data1 = pA->clID(); 00074 tok.setTechnology(pA->svcType()); 00075 tok.setDb(spar[0]).setCont(spar[1]); 00076 tok.oid().first = ipar[0]; 00077 tok.oid().second = ipar[1]; 00078 } 00079 else { 00080 tok.setTechnology(0).setDb("").setCont(""); 00081 tok.oid().first = tok.oid().second = pool::INVALID; 00082 } 00083 tok.setClassID(guid); 00084 return lnk; 00085 } 00086 00087 // Helper to read 00088 template <class T> static inline int load(pool::DbBlob& s, void* buff) { 00089 int len; 00090 s >> len; 00091 s.swapFromBuffer(buff, len*sizeof(T)); 00092 return 0; 00093 } 00094 00095 // Helper to read specialized for strings 00096 template <> static inline int load<std::string>(pool::DbBlob& s, void* ptr) { 00097 std::string* str = (std::string*)ptr; 00098 s >> (*str); 00099 return 0; 00100 } 00101 00102 // Helper to read specialized for opaque addresses 00103 static inline int load(void* ptr,PoolDbTokenWrap* lnk) { 00104 IOpaqueAddress* pA = *(IOpaqueAddress**)ptr; 00105 GenericAddress* pAddr = (GenericAddress*)(pA); 00106 if ( 0 != pAddr ) { 00107 pool::Token& tok = lnk->token; 00108 std::string* spar = (std::string*)pAddr->par(); 00109 unsigned long* ipar = (unsigned long*)pAddr->ipar(); 00110 pAddr->setClID(tok.classID().Data1); 00111 pAddr->setSvcType(tok.technology()); 00112 ipar[0] = tok.oid().first; 00113 ipar[1] = tok.oid().second; 00114 spar[0] = tok.dbID(); 00115 spar[1] = tok.contID(); 00116 return 0; 00117 } 00118 else if ( pA ) { 00119 return 10; 00120 } 00121 return 11; 00122 } 00123 00124 // Instantiation of a static factory class used by clients to create 00125 // instances of this service 00126 PLUGINSVC_FACTORY_WITH_ID( PoolDbNTupleCnv, 00127 ConverterID(POOL_StorageType,CLID_RowWiseTuple), 00128 IConverter*(long, CLID, ISvcLocator*) ); 00129 00130 PLUGINSVC_FACTORY_WITH_ID( PoolDbNTupleCnv, 00131 ConverterID(POOL_StorageType,CLID_ColumnWiseTuple), 00132 IConverter*(long, CLID, ISvcLocator*) ); 00133 00134 static inline std::istream& loadLong(std::istream& is) { 00135 long i; 00136 is >> i; 00137 return is; 00138 } 00139 static inline std::istream& 00140 operator>>(std::istream& is, SmartRef<DataObject>& /*pObj*/) { 00141 return loadLong(is); 00142 } 00143 static inline std::istream& 00144 operator>>(std::istream& is, SmartRef<ContainedObject>& /*pObj*/) { 00145 return loadLong(is); 00146 } 00147 static inline std::istream& 00148 operator>>(std::istream& is, IOpaqueAddress*& /*pObj*/) { 00149 return loadLong(is); 00150 } 00151 static inline std::istream& 00152 operator>>(std::istream& is, std::string& /*pObj*/) 00153 { 00154 return loadLong(is); 00155 } 00156 00157 template<class TYP> static 00158 StatusCode createItem ( INTuple* tuple, std::istream& is, 00159 const std::string& name, 00160 const TYP& null) 00161 { 00162 std::string idxName; 00163 long len, ndim, dim[4], hasIdx, idxLow, idxLen; 00164 long dim1 = 1, dim2 = 1; 00165 INTupleItem* it = 0; 00166 char c; 00167 is >> len >> c 00168 >> ndim >> c 00169 >> hasIdx >> c; 00170 if ( hasIdx ) { 00171 std::getline(is, idxName, ';') >> idxLow >> c >> idxLen >> c; 00172 } 00173 for ( int i = 0; i < ndim; i++ ) 00174 is >> dim[i] >> c; 00175 00176 TYP low = null, high = null; 00177 is >> low >> c >> high >> c; 00178 is >> c; 00179 switch( ndim ) { 00180 case 0: 00181 it = NTuple::_Item<TYP>::create (tuple, name, typeid(TYP), low, high, null); 00182 break; 00183 case 1: 00184 dim1 = (hasIdx) ? idxLen : dim[0]; 00185 it = NTuple::_Array<TYP>::create (tuple, 00186 name, 00187 typeid(TYP), 00188 idxName, 00189 dim1, 00190 low, 00191 high, 00192 null); 00193 break; 00194 case 2: 00195 dim1 = (hasIdx) ? idxLen : dim[0]; 00196 dim2 = (hasIdx) ? dim[0] : dim[1]; 00197 it = NTuple::_Matrix<TYP>::create ( tuple, 00198 name, 00199 typeid(TYP), 00200 idxName, 00201 dim1, 00202 dim2, 00203 low, 00204 high, 00205 null); 00206 break; 00207 default: 00208 return S_FAIL; 00209 } 00210 return tuple->add(it); 00211 } 00212 00213 template <class T> static inline 00214 void putRange(std::ostream& os, NTuple::_Data<T>* it) 00215 { 00216 const NTuple::Range<T>& x = it->range(); 00217 os << x.lower() << ';' << x.upper() << ';'; 00218 } 00219 00221 PoolDbNTupleCnv::PoolDbNTupleCnv(long typ, const CLID& clid, ISvcLocator* svc) 00222 : PoolDbStatCnv(typ, clid, svc) 00223 { 00224 m_class = 0; 00225 } 00226 00227 PoolDbNTupleCnv::~PoolDbNTupleCnv() { 00228 } 00229 00230 // Converter overrides: Update the references of an updated transient object. 00231 StatusCode 00232 PoolDbNTupleCnv::createObj(IOpaqueAddress* pAddress, DataObject*& refpObject) 00233 { 00234 StatusCode status = S_FAIL; 00235 PoolDbAddress* pdbA = dynamic_cast<PoolDbAddress*>(pAddress); 00236 if ( 0 != pdbA ) { 00237 const pool::Token* tok = pdbA->token(); 00238 if ( tok ) { 00239 pool::DbContainer cntH(tok->technology()); 00240 status = m_dbMgr->connect(tok->dbID(),tok->contID(),cntH); 00241 if ( status.isSuccess() ) { 00242 std::string par_val, par_guid, par_typ; 00243 std::auto_ptr<pool::DbSelect> iter(m_dbMgr->createSelect("*", tok->dbID(), "GaudiStatisticsDescription")); 00244 if ( iter.get() ) { 00245 pool::Token* token; 00246 ROOT::Reflex::Type typ = pool::DbReflex::forTypeName("PoolDbNTupleDescriptor"); 00247 pool::DbObjectCallBack* call = new pool::DbObjectCallBack(typ); 00248 while( iter->next(token).isSuccess() ) { 00249 typedef pool::DbObjectHandle<pool::DbObject> ObjH; 00250 pool::DbContainer& cH = iter->container(); 00251 if ( ObjH::openEx(cH, *token, call, pool::READ).isSuccess() ) { 00252 PoolDbNTupleDescriptor* ref = (PoolDbNTupleDescriptor*)call->object(); 00253 if ( ref->container == tok->contID() ) { 00254 par_val = ref->description; 00255 par_typ = ref->optional; 00256 par_guid = ref->guid; 00257 token->release(); 00258 call->release(); 00259 call = 0; 00260 delete ref; 00261 break; 00262 } 00263 delete ref; 00264 } 00265 token->release(); 00266 } 00267 if ( call ) call->release(); 00268 } 00269 if ( !par_val.empty() && !par_guid.empty() && !par_typ.empty() ) 00270 { 00271 SmartIF<INTupleSvc> ntupleSvc(IID_INTupleSvc, dataProvider()); 00272 if ( ntupleSvc.isValid() ) { 00273 char c; 00274 CLID clid; 00275 int siz, typ; 00276 std::string title; 00277 NTuple::Tuple* nt = 0; 00278 std::istringstream is(par_val); 00279 std::getline(is, title, ';') >> clid >> c >> siz >> c; 00280 status = ntupleSvc->create(clid, title, nt); 00281 for ( int j = 0; j < siz && status.isSuccess(); j++ ) { 00282 is >> c; 00283 std::getline(is, title, ';') >> typ >> c; 00284 switch ( typ ) { 00285 case DataTypeInfo::UCHAR: 00286 status = createItem(nt, is, title, (unsigned char)0); 00287 break; 00288 case DataTypeInfo::USHORT: 00289 status = createItem(nt, is, title, (unsigned short)0); 00290 break; 00291 case DataTypeInfo::UINT: 00292 status = createItem(nt, is, title, (unsigned int)0); 00293 break; 00294 case DataTypeInfo::ULONG: 00295 status = createItem(nt, is, title, (unsigned long)0); 00296 break; 00297 case DataTypeInfo::CHAR: 00298 status = createItem(nt, is, title, char(0)); 00299 break; 00300 case DataTypeInfo::SHORT: 00301 status = createItem(nt, is, title, short(0)); 00302 break; 00303 case DataTypeInfo::INT: 00304 status = createItem(nt, is, title, int(0)); 00305 break; 00306 case DataTypeInfo::LONG: 00307 status = createItem(nt, is, title, long(0)); 00308 break; 00309 case DataTypeInfo::BOOL: 00310 status = createItem(nt, is, title, false); 00311 break; 00312 case DataTypeInfo::FLOAT: 00313 status = createItem(nt, is, title, float(0.0)); 00314 break; 00315 case DataTypeInfo::DOUBLE: 00316 status = createItem(nt, is, title, double(0.0)); 00317 break; 00318 /* 00319 case DataTypeInfo::NTCHAR: 00320 case DataTypeInfo::LONG_NTCHAR: 00321 status = 00322 createItem(nt, is, title, (char*)0); 00323 break; 00324 case DataTypeInfo::STRING: 00325 case DataTypeInfo::LONG_STRING: 00326 status = 00327 createItem(nt, is, title, std::string("")); 00328 break; 00329 */ 00330 case DataTypeInfo::OBJECT_ADDR: 00331 status = createItem(nt, is, title, (IOpaqueAddress*)0); 00332 break; 00333 case DataTypeInfo::POINTER: 00334 status = createItem(nt, is, title, (void*)0); 00335 break; 00336 case DataTypeInfo::UNKNOWN: 00337 default: 00338 status = S_FAIL; 00339 break; 00340 } 00341 if ( !status.isSuccess() ) { 00342 MsgStream err(msgSvc(),"NTupleCnv"); 00343 err << MSG::FATAL 00344 << "Error connecting (Unknown) column:" << j << endmsg 00345 << par_val << endmsg; 00346 return makeError("createObj[NTuple]> Cannot determine column!"); 00347 } 00348 } 00349 if ( status.isSuccess() ) { 00350 PoolDbTupleCallback* hdlr = new PoolDbTupleCallback(nt); 00351 const pool::DbTypeInfo* typ = pool::DbTypeInfo::fromString(par_typ); 00352 hdlr->configure(nt, typ, cntH); 00353 pdbA->setHandler(hdlr); 00354 refpObject = nt; 00355 } 00356 else { 00357 refpObject = 0; 00358 if ( nt ) nt->release(); 00359 } 00360 } 00361 } 00362 } 00363 } 00364 } 00365 return status; 00366 } 00367 00368 // Update the transient object: NTuples end here when reading records 00369 StatusCode 00370 PoolDbNTupleCnv::updateObj(IOpaqueAddress* pAddr, DataObject* pObj) { 00371 INTuple* tupl = dynamic_cast<INTuple*>(pObj); 00372 PoolDbAddress* pdbA = dynamic_cast<PoolDbAddress*>(pAddr); 00373 if ( 0 != tupl && 0 != pdbA ) { 00374 PoolDbTupleCallback* hdlr = dynamic_cast<PoolDbTupleCallback*>(pdbA->handler()); 00375 pool::DbSelect* it = hdlr->iterator(); 00376 if ( 0 == it ) { 00377 it = hdlr->select(tupl->selector()); 00378 } 00379 if ( it ) { 00380 pool::Token* t = 0; 00381 if ( hdlr->iterator()->next(t).isSuccess() ) { 00382 std::auto_ptr<pool::Token> next(t); 00383 // Now reload! 00384 if ( bindRead(tupl, hdlr).isSuccess() ) { 00385 // No support for SmartRefs<T> for N-tuples 00386 //pushCurrentDataObject((DataObject**)&pObj); 00387 if ( m_dbMgr->read(hdlr, *next.get()).isSuccess() ) { 00388 if ( readData(tupl, hdlr).isSuccess() ) { 00389 //popCurrentDataObject(); 00390 return S_OK; 00391 } 00392 //popCurrentDataObject(); 00393 return makeError("updateObj> Cannot interprete data."); 00394 } 00395 //popCurrentDataObject(); 00396 return makeError("updateObj> Cannot read data."); 00397 } 00398 return makeError("updateObj> Cannot bind data."); 00399 } 00400 return S_FAIL; 00401 } 00402 return makeError("updateObj> Token selection failed!"); 00403 } 00404 return makeError("updateObj> Invalid Tuple reference."); 00405 } 00406 00408 StatusCode 00409 PoolDbNTupleCnv::createRep(DataObject* pObj, IOpaqueAddress*& pAddr) { 00410 IRegistry* pRegistry = pObj->registry(); 00411 if ( 0 != pRegistry ) { 00412 pAddr = pRegistry->address(); 00413 PoolDbAddress* pdbA = dynamic_cast<PoolDbAddress*>(pAddr); 00414 if ( 0 == pdbA ) { 00415 const INTuple* nt = dynamic_cast<const INTuple*>(pObj); 00416 std::string loc = containerName(pObj->registry()); 00417 if ( 0 != nt ) { 00418 const INTuple::ItemContainer& items = nt->items(); 00419 std::vector<const pool::DbColumn*> cols; 00420 std::vector<int> item_map(items.size()+1,-1); 00421 std::ostringstream os; 00422 int pool_type = 0; 00423 size_t item_no; 00424 os << nt->title()<<';'<<pObj->clID()<<';'<<items.size()<< ';'; 00425 for(item_no = 0; item_no < items.size(); ++item_no ) { 00426 pool::DbColumn* col = 0; 00427 INTupleItem* it = items[item_no]; 00428 os << '{' 00429 << it->name() << ';' 00430 << it->type() << ';' 00431 << it->length() << ';' 00432 << it->ndim() << ';' 00433 << it->hasIndex() << ';'; 00434 if ( it->hasIndex() ) { 00435 os << it->index() << ';'; 00436 INTupleItem* itm = it->indexItem(); 00437 switch( itm->type() ) { 00438 case DataTypeInfo::UCHAR: 00439 putRange(os, dynamic_cast<NTuple::_Data<unsigned char>*>(itm)); 00440 break; 00441 case DataTypeInfo::USHORT: 00442 putRange(os, dynamic_cast<NTuple::_Data<unsigned short>*>(itm)); 00443 break; 00444 case DataTypeInfo::UINT: 00445 putRange(os, dynamic_cast<NTuple::_Data<unsigned int>*>(itm)); 00446 break; 00447 case DataTypeInfo::ULONG: 00448 putRange(os, dynamic_cast<NTuple::_Data<unsigned long>*>(itm)); 00449 break; 00450 case DataTypeInfo::CHAR: 00451 putRange(os, dynamic_cast<NTuple::_Data<char>*>(itm)); 00452 break; 00453 case DataTypeInfo::SHORT: 00454 putRange(os, dynamic_cast<NTuple::_Data<short>*>(itm)); 00455 break; 00456 case DataTypeInfo::INT: 00457 putRange(os, dynamic_cast<NTuple::_Data<int>*>(itm)); 00458 break; 00459 case DataTypeInfo::LONG: 00460 putRange(os, dynamic_cast<NTuple::_Data<long>*>(itm)); 00461 break; 00462 default: { 00463 MsgStream err(msgSvc(), "NTuple:"+pRegistry->name()); 00464 err << MSG::ERROR << "Column " << it->index() 00465 << " is not a valid index column!" << endreq; 00466 return S_FAIL; 00467 } 00468 } 00469 } 00470 for ( long k = 0; k < it->ndim(); k++ ) { 00471 os << it->dim(k) << ';'; 00472 } 00473 switch(it->type()) { 00474 case DataTypeInfo::STRING: 00475 pool_type = pool::DbColumn::STRING; 00476 os << 0 << ';' << 0 << ';'; 00477 break; 00478 case DataTypeInfo::NTCHAR: 00479 pool_type = pool::DbColumn::NTCHAR; 00480 os << 0 << ';' << 0 << ';'; 00481 break; 00482 case DataTypeInfo::OBJECT_ADDR: 00483 if ( it->length() == 1 ) { 00484 col = new pool::DbColumn(it->name(), 00485 pool::typeName(typeid(PoolDbTokenWrap)), 00486 pool::DbColumn::POINTER, 00487 0); 00488 item_map[item_no] = cols.size(); 00489 cols.push_back(col); 00490 } 00491 os << 0 << ';' << 0 << ';'; 00492 break; 00493 case DataTypeInfo::POINTER: 00494 if ( it->length() == 1 ) { 00495 ROOT::Reflex::Type typ = ROOT::Reflex::Type::ByName(it->typeName()); 00496 col = new pool::DbColumn(it->name(), 00497 typ.Name(ROOT::Reflex::SCOPED), 00498 pool::DbColumn::POINTER, 00499 0); 00500 item_map[item_no] = cols.size(); 00501 cols.push_back(col); 00502 os << 0 << ';' << 0 << ';'; 00503 } 00504 break; 00505 case DataTypeInfo::UCHAR: 00506 pool_type = pool::DbColumn::UCHAR; 00507 putRange(os, dynamic_cast<NTuple::_Data<unsigned char>*>(it)); 00508 goto MakeCol; 00509 case DataTypeInfo::USHORT: 00510 pool_type = pool::DbColumn::USHORT; 00511 putRange(os, dynamic_cast<NTuple::_Data<unsigned short>*>(it)); 00512 goto MakeCol; 00513 case DataTypeInfo::UINT: 00514 pool_type = pool::DbColumn::UINT; 00515 putRange(os, dynamic_cast<NTuple::_Data<unsigned int>*>(it)); 00516 goto MakeCol; 00517 case DataTypeInfo::ULONG: 00518 pool_type = pool::DbColumn::ULONG; 00519 putRange(os, dynamic_cast<NTuple::_Data<unsigned long>*>(it)); 00520 goto MakeCol; 00521 case DataTypeInfo::CHAR: 00522 pool_type = pool::DbColumn::CHAR; 00523 putRange(os, dynamic_cast<NTuple::_Data<char>*>(it)); 00524 goto MakeCol; 00525 case DataTypeInfo::SHORT: 00526 pool_type = pool::DbColumn::SHORT; 00527 putRange(os, dynamic_cast<NTuple::_Data<short>*>(it)); 00528 goto MakeCol; 00529 case DataTypeInfo::INT: 00530 pool_type = pool::DbColumn::INT; 00531 putRange(os, dynamic_cast<NTuple::_Data<int>*>(it)); 00532 goto MakeCol; 00533 case DataTypeInfo::LONG: 00534 pool_type = pool::DbColumn::LONG; 00535 putRange(os, dynamic_cast<NTuple::_Data<long>*>(it)); 00536 goto MakeCol; 00537 case DataTypeInfo::BOOL: 00538 pool_type = pool::DbColumn::BOOL; 00539 putRange(os, dynamic_cast<NTuple::_Data<bool>*>(it)); 00540 goto MakeCol; 00541 case DataTypeInfo::FLOAT: 00542 pool_type = pool::DbColumn::FLOAT; 00543 putRange(os, dynamic_cast<NTuple::_Data<float>*>(it)); 00544 goto MakeCol; 00545 case DataTypeInfo::DOUBLE: 00546 pool_type = pool::DbColumn::DOUBLE; 00547 putRange(os, dynamic_cast<NTuple::_Data<double>*>(it)); 00548 goto MakeCol; 00549 MakeCol: 00550 if ( it->length() == 1 ) { 00551 pool::DbColumn* col = new pool::DbColumn(it->name(), 00552 pool_type, 00553 0, 00554 DataTypeInfo::size(it->type())); 00555 item_map[item_no] = cols.size(); 00556 cols.push_back(col); 00557 } 00558 // Everything else CANNOT be identified using SQL 00559 break; 00560 case DataTypeInfo::UNKNOWN: 00561 default: 00562 std::cout << "Create item[FAIL]]: " << it->name() 00563 << " Typ:" << it->type() << std::endl; 00564 break; 00565 } 00566 os << '}'; 00567 } 00568 item_map[item_no] = cols.size(); 00569 pool::DbColumn* col = 00570 new pool::DbColumn("BlobData", 00571 pool::DbColumn::BLOB, 00572 0, 00573 DataTypeInfo::size(pool::DbColumn::BLOB)); 00574 cols.push_back(col); 00575 pool::Guid guid; 00576 std::string cntName = containerName(pRegistry); 00577 std::string path = fileName(pRegistry); 00578 genMD5(os.str(), &guid); 00579 const pool::DbTypeInfo* typH = pool::DbTypeInfo::createEx(guid, cols); 00580 StatusCode sc = saveDescription(path, 00581 cntName, 00582 os.str(), 00583 typH->toString(), 00584 guid, 00585 pObj->clID(), 00586 "UPDATE"); 00587 if ( sc.isSuccess() ) { 00588 // Check if the database container can be connected 00589 pool::DbContainer cntH(POOL_StorageType); 00590 StatusCode sc = 00591 m_dbMgr->connectContainer(IPoolDbMgr::UNKNOWN, 00592 path, 00593 cntName, 00594 pool::RECREATE|pool::UPDATE, 00595 typH, 00596 cntH); 00597 if ( sc.isSuccess() ) { 00598 PoolDbTupleCallback* hdlr = new PoolDbTupleCallback(pObj); 00599 pool::Token* tok = new pool::Token(cntH.token()); 00600 PoolDbAddress* add = new PoolDbAddress(tok); 00601 hdlr->configure(nt, typH, cntH); 00602 tok->oid().second = 0; 00603 tok->release(); 00604 pAddr = add; 00605 add->setHandler(hdlr); 00606 return m_dbMgr->commitOutput(path, true); 00607 } 00608 return S_FAIL; 00609 } 00610 return sc; 00611 } 00612 } 00613 else { 00614 return S_OK; 00615 } 00616 } 00617 return S_FAIL; 00618 } 00619 00621 StatusCode 00622 PoolDbNTupleCnv::fillRepRefs(IOpaqueAddress* pAddr, DataObject* pObj) 00623 { 00624 INTuple* pTuple = dynamic_cast<INTuple*>(pObj); 00625 if ( pTuple ) { 00626 IRegistry* pRegistry = pObj->registry(); 00627 if ( 0 != pRegistry ) { 00628 pAddr = pRegistry->address(); 00629 PoolDbAddress* pdbA = dynamic_cast<PoolDbAddress*>(pAddr); 00630 if ( 0 != pdbA ) { 00631 PoolDbTupleCallback* cb = dynamic_cast<PoolDbTupleCallback*>(pdbA->handler()); 00632 if ( cb ) { 00633 const pool::DbTypeInfo* typH = dynamic_cast<const pool::DbTypeInfo*>(cb->shape()); 00634 if ( typH ) { 00635 if ( bindWrite(pTuple, cb).isSuccess() ) { 00636 std::string path = fileName(pRegistry); 00637 std::string cntName = containerName(pRegistry); 00638 if ( !m_dbMgr->connectOutput(path, "UPDATE").isSuccess() ) { 00639 MsgStream log(msgSvc(), "PoolDbNTupleCnv"); 00640 log << MSG::ERROR << "Error: connectOutput(path, UPDATE)" << endmsg; 00641 return S_FAIL; 00642 } 00643 if ( m_dbMgr->markWrite(cb->clone(), cntName, &pdbA).isSuccess() ) { 00644 if ( m_dbMgr->commitOutput(path, true).isSuccess() ) { 00645 typedef INTuple::ItemContainer Cont; 00646 Cont& it = pTuple->items(); 00647 for(Cont::iterator i = it.begin(); i != it.end(); ++i) { 00648 (*i)->reset(); 00649 } 00650 return S_OK; 00651 } 00652 } 00653 } 00654 } 00655 } 00656 } 00657 } 00658 } 00659 return S_FAIL; 00660 } 00661 00662 StatusCode PoolDbNTupleCnv::bindRead(INTuple* nt, 00663 PoolDbTupleCallback* cb) 00664 { 00665 typedef INTuple::ItemContainer Cont; 00666 int cnt = 0; 00667 //pool::DbBlob& s = cb->stream(); 00668 std::vector<void*>& addr = cb->addresses(); 00669 std::vector<PoolDbTokenWrap*>& links = cb->links(); 00670 const std::vector<int>& mapping = cb->mapping(); 00671 Cont& items = nt->items(); 00672 for (Cont::iterator i = items.begin(); i != items.end(); ++i, ++cnt ) { 00673 int count = mapping[cnt]; 00674 if ( count >= 0 ) { 00675 char* buf = (char*)(*i)->buffer(); 00676 switch( (*i)->type() ) { 00677 case DataTypeInfo::OBJECT_ADDR: 00678 addr[count] = &links[cnt]; 00679 break; 00680 default: 00681 addr[count] = buf; 00682 break; 00683 } 00684 } 00685 } 00686 return S_OK; 00687 } 00688 00689 StatusCode PoolDbNTupleCnv::readData(INTuple* nt, 00690 PoolDbTupleCallback* cb) 00691 { 00692 typedef INTuple::ItemContainer Cont; 00693 int cnt = 0; 00694 pool::DbBlob& s = cb->stream(); 00695 std::vector<PoolDbTokenWrap*>& links = cb->links(); 00696 const std::vector<int>& mapping = cb->mapping(); 00697 INTuple::ItemContainer& items = nt->items(); 00698 for (Cont::iterator i = items.begin(); i != items.end(); ++i, ++cnt ) { 00699 int count = mapping[cnt]; 00700 int typ = (*i)->type(); 00701 if(count < 0 || typ == DataTypeInfo::OBJECT_ADDR || typ == DataTypeInfo::POINTER) { 00702 char* buf = (char*)(*i)->buffer(); 00703 int sc = 11; 00704 switch( (*i)->type() ) { 00705 case DataTypeInfo::UCHAR: sc=load<unsigned char> (s,buf); break; 00706 case DataTypeInfo::USHORT: sc=load<unsigned short>(s,buf); break; 00707 case DataTypeInfo::UINT: sc=load<unsigned int> (s,buf); break; 00708 case DataTypeInfo::ULONG: sc=load<unsigned long> (s,buf); break; 00709 case DataTypeInfo::CHAR: sc=load<char> (s,buf); break; 00710 case DataTypeInfo::SHORT: sc=load<short> (s,buf); break; 00711 case DataTypeInfo::INT: sc=load<int> (s,buf); break; 00712 case DataTypeInfo::LONG: sc=load<long> (s,buf); break; 00713 case DataTypeInfo::BOOL: sc=load<bool> (s,buf); break; 00714 case DataTypeInfo::FLOAT: sc=load<float> (s,buf); break; 00715 case DataTypeInfo::DOUBLE: sc=load<double> (s,buf); break; 00716 case DataTypeInfo::STRING: sc=load<std::string> (s,buf); break; 00717 case DataTypeInfo::NTCHAR: sc=load<char*> (s,buf); break; 00718 case DataTypeInfo::OBJECT_ADDR: sc=load(buf,links[count]); break; 00719 case DataTypeInfo::POINTER: break; 00720 case DataTypeInfo::UNKNOWN: break; 00721 default: break; 00722 } 00723 if ( 0 != sc ) { 00724 MsgStream log(msgSvc(), "PoolDbNTupleCnv"); 00725 log << MSG::DEBUG; 00726 switch (sc) { 00727 case 10: 00728 log << "CANNOT Set Ntuple token: dynamic_cast<GenericAddress*> is NULL"; 00729 break; 00730 case 11: 00731 log << "CANNOT Set Ntuple token: invalid address buffer"; 00732 break; 00733 } 00734 log << endmsg; 00735 } 00736 } 00737 } 00738 return S_OK; 00739 } 00740 00742 StatusCode PoolDbNTupleCnv::bindWrite(INTuple* nt, PoolDbTupleCallback* cb) 00743 { 00744 int cnt = 0; 00745 pool::DbBlob& s = cb->stream(); 00746 std::vector<void*>& addr = cb->addresses(); 00747 std::vector<PoolDbTokenWrap*>& links = cb->links(); 00748 const std::vector<int>& mapping = cb->mapping(); 00749 const INTuple::ItemContainer& items = nt->items(); 00750 INTuple::ItemContainer::const_iterator i; 00751 00752 s.setMode(pool::DbBlob::WRITING); 00753 for(i = items.begin(); i != items.end(); ++i, ++cnt ) { 00754 char* b = (char*)(*i)->buffer(); 00755 int len = (*i)->filled(); 00756 long ndim = (*i)->ndim(); 00757 int count = mapping[cnt]; 00758 void* ptr = 0; 00759 switch( (*i)->type() ) { 00760 case DataTypeInfo::UCHAR: ptr=save<unsigned char >(s,b,len,ndim>0); break; 00761 case DataTypeInfo::USHORT: ptr=save<unsigned short>(s,b,len,ndim>0); break; 00762 case DataTypeInfo::UINT: ptr=save<unsigned int >(s,b,len,ndim>0); break; 00763 case DataTypeInfo::ULONG: ptr=save<unsigned long >(s,b,len,ndim>0); break; 00764 case DataTypeInfo::CHAR: ptr=save<char >(s,b,len,ndim>0); break; 00765 case DataTypeInfo::SHORT: ptr=save<short >(s,b,len,ndim>0); break; 00766 case DataTypeInfo::INT: ptr=save<int >(s,b,len,ndim>0); break; 00767 case DataTypeInfo::LONG: ptr=save<long >(s,b,len,ndim>0); break; 00768 case DataTypeInfo::BOOL: ptr=save<bool >(s,b,len,ndim>0); break; 00769 case DataTypeInfo::FLOAT: ptr=save<float >(s,b,len,ndim>0); break; 00770 case DataTypeInfo::DOUBLE: ptr=save<double >(s,b,len,ndim>0); break; 00771 case DataTypeInfo::STRING: ptr=save<std::string >(s,b,len,ndim>0); break; 00772 case DataTypeInfo::NTCHAR: ptr=save<char* >(s,b,len,ndim>0); break; 00773 case DataTypeInfo::POINTER: ptr=*(void**)b; break; 00774 case DataTypeInfo::OBJECT_ADDR: ptr=save(b,links[count]); break; 00775 case DataTypeInfo::UNKNOWN: break; 00776 default: /* Do we have to take some action here ? */ break; 00777 } 00778 if ( count >= 0 ) { 00779 addr[count] = ptr; 00780 } 00781 } 00782 return S_OK; 00783 }