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