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