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