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