![]() |
|
|
Generated: 8 Jan 2009 |
00001 //==================================================================== 00002 // NTupleSvc.cpp 00003 //-------------------------------------------------------------------- 00004 // 00005 // Package : GaudiSvc/NTupleSvc ( The LHCb Offline System) 00006 // 00007 // Description: implementation of the NTuple service 00008 // 00009 // Author : M.Frank 00010 // History : 00011 // +---------+----------------------------------------------+--------- 00012 // | Date | Comment | Who 00013 // +---------+----------------------------------------------+--------- 00014 // | 29/10/98| Initial version | MF 00015 // | 29/09/99| Added access to ICnvManager for missing | 00016 // | | converters | MF 00017 // | 20/09/00| Connect dynamically to conversion service | 00018 // | | for N-tuple persistency | MF 00019 // +---------+----------------------------------------------+--------- 00020 // 00021 //==================================================================== 00022 #define GAUDISVC_NTUPLESVC_CPP 00023 00024 // Framework include files 00025 #include "GaudiKernel/xtoa.h" 00026 #include "GaudiKernel/SmartIF.h" 00027 #include "GaudiKernel/Tokenizer.h" 00028 #include "GaudiKernel/SvcFactory.h" 00029 #include "GaudiKernel/DataObject.h" 00030 #include "GaudiKernel/ObjectFactory.h" 00031 #include "GaudiKernel/GenericAddress.h" 00032 00033 #include "GaudiKernel/IProperty.h" 00034 #include "GaudiKernel/ISvcLocator.h" 00035 #include "GaudiKernel/IDataSelector.h" 00036 00037 #include "GaudiKernel/Property.h" 00038 #include "GaudiKernel/Selector.h" 00039 #include "GaudiKernel/MsgStream.h" 00040 #include "GaudiKernel/ConversionSvc.h" 00041 #include "GaudiKernel/DataSelectionAgent.h" 00042 #include "GaudiKernel/NTupleImplementation.h" 00043 00044 #include "NTupleSvc.h" 00045 00046 // Instantiation of a static factory class used by clients to create 00047 // instances of this service 00048 DECLARE_SERVICE_FACTORY(NTupleSvc) 00049 00050 00051 DECLARE_NAMESPACE_OBJECT_FACTORY(NTuple,Selector) 00052 00054 NTupleSvc::NTupleSvc(const std::string& name, ISvcLocator* svc) 00055 : DataSvc(name, svc) 00056 { 00057 declareProperty("Input", m_input); 00058 declareProperty("Output", m_output); 00059 m_rootName = "/NTUPLES"; 00060 m_rootCLID = CLID_DataObject; 00061 } 00062 00064 NTupleSvc::~NTupleSvc() { 00065 } 00066 00068 StatusCode NTupleSvc::initialize() { 00069 StatusCode status = DataSvc::initialize(); 00070 if ( status.isSuccess() ) { 00071 status = setProperties(); 00072 if ( status.isSuccess() ) { 00073 StatusCode iret(StatusCode::SUCCESS,true); 00074 DataObject* root = new NTuple::Directory(); 00075 status = setRoot(m_rootName, root); 00076 for ( DBaseEntries::iterator i = m_output.begin(); i != m_output.end(); ++i ) { 00077 iret = connect(*i); 00078 if ( !iret.isSuccess() ) { 00079 status = iret; 00080 } 00081 } 00082 for ( DBaseEntries::iterator j = m_input.begin(); j != m_input.end(); ++j ) { 00083 iret = connect(*j); 00084 if ( !iret.isSuccess() ) { 00085 status = iret; 00086 } 00087 } 00088 } 00089 } 00090 return status; 00091 } 00092 00094 StatusCode NTupleSvc::reinitialize() { 00095 return StatusCode::SUCCESS; 00096 } 00097 00098 // Check if a datasource is connected 00099 bool NTupleSvc::isConnected(const std::string& identifier) const { 00100 Connections::const_iterator i = m_connections.find(identifier); 00101 return !(i==m_connections.end()); 00102 } 00103 00105 IConversionSvc* NTupleSvc::getDataLoader(IRegistry* pRegistry) { 00106 if ( 0 != pRegistry ) { 00107 std::string full = pRegistry->identifier(); 00108 size_t len = m_rootName.length(); 00109 size_t idx = full.find(SEPARATOR,len+1); 00110 std::string path = (idx==std::string::npos) ? full : full.substr(0, idx); 00111 Connections::iterator i = m_connections.find(path); 00112 if ( i != m_connections.end() ) { 00113 return (*i).second.service; 00114 } 00115 } 00116 return 0; 00117 } 00118 00119 StatusCode NTupleSvc::updateDirectories() { 00120 typedef std::vector<IRegistry*> Leaves; 00121 long need_update = 0; 00122 DataObject* pO = 0; 00123 StatusCode iret = findObject(m_rootName, pO); 00124 MsgStream log ( msgSvc(), name() ); 00125 // log << MSG::DEBUG << "in finalize()" << endmsg; 00126 if ( iret.isSuccess() ) { 00127 Leaves leaves; 00128 iret = objectLeaves(pO, leaves); 00129 if ( iret.isSuccess() ) { 00130 // Only traverse the tree below the files 00131 for ( Leaves::iterator d = leaves.begin(); d != leaves.end(); d++ ) { 00132 if ( (*d)->object() ) { 00133 IOpaqueAddress* pA = (*d)->address(); 00134 if ( pA ) { 00135 unsigned long typ = pA->ipar()[1]; 00136 if ( typ == 'R' || typ == 'N' || typ == 'U' ) { 00137 // ...starting from the file entries: first save the directories/ntuples 00138 IConversionSvc* svc = getDataLoader(*d); 00139 if ( 0 != svc ) { 00140 StatusCode status; 00141 DataSelectionAgent agent; 00142 IDataSelector* sel = agent.selectedObjects(); 00143 traverseSubTree ( (*d)->object(), &agent ).ignore(); 00144 for(int i = sel->size()-1; i >= 0; i-- ) { 00145 DataObject* o = (*sel)[i]; 00146 IRegistry* r = o->registry(); 00147 status = svc->updateRep(r->address(), o); 00148 if ( !status.isSuccess() ) { 00149 iret = status; 00150 } 00151 } 00152 for(int j = sel->size()-1; j >= 0; j-- ) { 00153 DataObject* o = (*sel)[j]; 00154 IRegistry* r = o->registry(); 00155 status = svc->updateRepRefs(r->address(), o); 00156 if ( !status.isSuccess() ) { 00157 iret = status; 00158 } 00159 } 00160 if ( iret.isSuccess() ) need_update += sel->size(); 00161 } 00162 } 00163 } 00164 } 00165 } 00166 } 00167 } 00168 if ( !iret.isSuccess() ) { 00169 log << MSG::ERROR << "ERROR while saving NTuples" << endmsg; 00170 return iret; 00171 } 00172 else if ( need_update > 0 ) { 00173 log << MSG::INFO << "NTuples saved successfully" << endmsg; 00174 } 00175 return iret; 00176 } 00177 00178 // Finalize single service 00179 void NTupleSvc::releaseConnection(Connection& c) { 00180 SmartIF<IService> isvc(IID_IService, c.service ); 00181 if ( isvc.isValid( ) ) { 00182 isvc->finalize().ignore(); 00183 } 00184 c.service->release(); 00185 c.service = 0; 00186 } 00187 00188 // Close all open connections 00189 StatusCode NTupleSvc::disconnect(const std::string& nam) { 00190 Connections::iterator i = m_connections.find(nam); 00191 if ( i != m_connections.end() ) { 00192 releaseConnection((*i).second); 00193 m_connections.erase(i); 00194 return StatusCode::SUCCESS; 00195 } 00196 return StatusCode::FAILURE; 00197 } 00198 00199 // Close all open connections 00200 StatusCode NTupleSvc::disconnectAll() { 00201 for(Connections::iterator i = m_connections.begin(); i != m_connections.end(); ++i) { 00202 releaseConnection((*i).second); 00203 } 00204 m_connections.erase(m_connections.begin(), m_connections.end()); 00205 return StatusCode::SUCCESS; 00206 } 00207 00209 StatusCode NTupleSvc::finalize() { 00210 StatusCode status = updateDirectories(); 00211 status = clearStore(); 00212 status = DataSvc::finalize(); 00213 status = disconnectAll(); 00214 return status; 00215 } 00216 00218 StatusCode NTupleSvc::queryInterface(const InterfaceID& riid, void** ppvInterface) { 00219 if ( IID_INTupleSvc == riid ) 00220 *ppvInterface = (INTupleSvc*)this; 00221 else if ( IID_IDataSourceMgr == riid ) 00222 *ppvInterface = (IDataSourceMgr*)this; 00223 else // Interface is not directly availible: try out a base class 00224 return DataSvc::queryInterface(riid, ppvInterface); 00225 addRef(); 00226 return StatusCode::SUCCESS; 00227 } 00228 00229 StatusCode NTupleSvc::connect(const std::string& ident) { 00230 std::string logName; 00231 return connect(ident, logName); 00232 } 00233 00234 StatusCode NTupleSvc::connect(const std::string& ident, std::string& logname) { 00235 MsgStream log ( msgSvc(), name() ); 00236 DataObject* pO = 0; 00237 StatusCode status = findObject(m_rootName, pO); 00238 if ( status.isSuccess() ) { 00239 char typ=0; 00240 Tokenizer tok(true); 00241 std::vector<Prop> props; 00242 long loc = ident.find(" "); 00243 std::string filename, auth, svc = "", db_typ = ""; 00244 logname = ident.substr(0,loc); 00245 tok.analyse(ident.substr(loc+1,ident.length()), " ", "", "", "=", "'", "'"); 00246 for ( Tokenizer::Items::iterator i = tok.items().begin(); i != tok.items().end(); ++i) { 00247 const std::string& tag = (*i).tag(); 00248 switch( ::toupper(tag[0]) ) { 00249 case 'A': 00250 break; 00251 case 'F': // FILE='<file name>' 00252 case 'D': // DATAFILE='<file name>' 00253 filename = (*i).value(); 00254 break; 00255 case 'O': // OPT='<NEW<CREATE,WRITE>, UPDATE, READ>' 00256 switch( ::toupper((*i).value()[0]) ) { 00257 case 'C': 00258 case 'N': 00259 case 'W': 00260 typ = 'N'; 00261 break; 00262 case 'U': 00263 typ = 'U'; 00264 break; 00265 case 'O': 00266 case 'R': 00267 typ = 'O'; 00268 break; 00269 default: 00270 typ = 0; 00271 break; 00272 } 00273 break; 00274 case 'T': // TYP='<HBOOK,ROOT,OBJY,...>' 00275 db_typ = (*i).value(); 00276 break; 00277 default: 00278 props.push_back( Prop((*i).tag(), (*i).value())); 00279 break; 00280 } 00281 } 00282 if ( 0 != typ ) { 00283 IConversionSvc* pSvc = 0; 00284 status = createService(name()+'.'+logname, db_typ, props, pSvc); 00285 if ( status.isSuccess() ) { 00286 status = attachTuple(filename, logname, typ, pSvc->repSvcType()); 00287 if ( status.isSuccess() ) { 00288 m_connections.insert(Connections::value_type(m_rootName+'/'+logname,Connection(pSvc))); 00289 return StatusCode::SUCCESS; 00290 } 00291 } 00292 } 00293 } 00294 log << MSG::ERROR << "Cannot add " << ident << " invalid filename!" << endmsg; 00295 return StatusCode::FAILURE; 00296 } 00297 00298 StatusCode NTupleSvc::createService(const std::string& /* nam */, 00299 const std::string& typ, 00300 const std::vector<Prop>& /* props */, 00301 IConversionSvc*& pSvc) 00302 { 00303 MsgStream log ( msgSvc(), name() ); 00305 // Get the value of the Stat persistancy mechanism from the AppMgr 00306 IProperty* appPropMgr = 0; 00307 StatusCode sts = serviceLocator()->queryInterface(IID_IProperty, pp_cast<void>(&appPropMgr) ); 00308 if( !sts.isSuccess() ) { 00309 // Report an error and return the FAILURE status code 00310 log << MSG::ERROR << "Could not get PropMgr" << endmsg; 00311 return sts; 00312 } 00313 00314 StringProperty sp("HistogramPersistency",""); 00315 sts = appPropMgr->getProperty( &sp ); 00316 if ( !sts.isSuccess() ) { 00317 log << MSG::ERROR << "Could not get NTuple Persistency format" 00318 << " from ApplicationMgr properties" << endmsg; 00319 return sts; 00320 } 00321 00322 long storage_typ = TEST_StorageType; 00323 if ( sp.value() == "HBOOK" ) { 00324 storage_typ = HBOOK_StorageType; 00325 } 00326 else if ( sp.value() == "ROOT" ) { 00327 storage_typ = ROOT_StorageType; 00328 } 00329 else { 00330 appPropMgr->release(); 00331 log << MSG::ERROR << "Unknown NTuple Persistency format: " << sp.value() << endmsg; 00332 return StatusCode::FAILURE; 00333 } 00334 // Clean up 00335 appPropMgr->release(); 00336 00337 if ( typ.length() > 0 && typ != sp.value() ) { 00338 log << MSG::WARNING << "NTuple persistency type is " 00339 << sp.value() << "." << endmsg 00340 << "Type given by job option " 00341 << "NTupleSvc.Input/Output ignored!" << endmsg; 00342 } 00343 00344 // log << MSG::DEBUG << "storage type: " << m_storageType << endmsg; 00345 00346 // FIXME: (MCl) why NTupleSvc has to directly create a ConversionSvc? 00347 IService* pService = 0; 00348 IInterface* iface = new ConversionSvc(name()+"Conversions", serviceLocator(), storage_typ); 00349 StatusCode status = iface->queryInterface(IID_IService, pp_cast<void>(&pService)); 00350 if ( status.isSuccess() ) { 00351 status = iface->queryInterface(IID_IConversionSvc, pp_cast<void>(&pSvc)); 00352 if ( !status.isSuccess() ) { 00353 pService->release(); 00354 return status; 00355 } 00356 } 00357 status = pService->sysInitialize(); 00358 if ( !status.isSuccess() ) { 00359 return status; 00360 } 00361 pService->release(); 00362 status = pSvc->setDataProvider(this); 00363 if ( !status.isSuccess() ) { 00364 return status; 00365 } 00366 return status; 00367 } 00368 00370 StatusCode NTupleSvc::create(const CLID& typ, const std::string& title, NTuple::Tuple*& refpTuple) { 00371 NTuple::TupleImp* pTuple = 0; 00372 StatusCode status = StatusCode::FAILURE; 00373 if ( typ == CLID_ColumnWiseTuple ) { 00374 pTuple = new NTuple::ColumnWiseTuple( title ); 00375 } 00376 else if ( typ == CLID_RowWiseTuple ) { 00377 pTuple = new NTuple::RowWiseTuple( title ); 00378 } 00379 else { 00381 } 00382 if ( 0 != pTuple ) { 00383 pTuple->setTupleService(this); 00384 status = StatusCode::SUCCESS; 00385 } 00386 refpTuple = pTuple; 00387 return status; 00388 } 00389 00391 NTuple::Tuple* NTupleSvc::book (const std::string& fullPath, const CLID& type, const std::string& title) { 00392 DataObject* pObj = 0; 00393 std::string path = fullPath; 00394 MsgStream log(msgSvc(), name()); 00395 if ( path[0] != SEPARATOR ) { 00396 path = m_rootName; 00397 path += SEPARATOR; 00398 path += fullPath; 00399 } 00400 StatusCode status = retrieveObject(path, pObj); 00401 if ( !status.isSuccess() ) { 00402 int sep = path.rfind(SEPARATOR); 00403 if ( sep > 0 ) { 00404 std::string p_path (path, 0, sep); 00405 std::string o_path (path, sep, path.length()); 00406 DataObject* dir = createDirectory(p_path); 00407 if ( 0 != dir ) { 00408 NTuple::Tuple* tup = book( dir, o_path, type, title); 00409 if ( 0 == tup ) { 00410 log << MSG::ERROR << "Cannot book N-tuple " << path << " (Unknown reason)" << endmsg; 00411 } 00412 return tup; 00413 } 00414 log << MSG::ERROR << "Cannot book N-tuple " << path << " (Invalid parent directory)" << endmsg; 00415 return 0; 00416 } 00417 log << MSG::ERROR << "Cannot book N-tuple " << path << " (Invalid path)" << endmsg; 00418 return 0; 00419 } 00420 log << MSG::ERROR << "Cannot book N-tuple " << path << " (Exists already)" << endmsg; 00421 return 0; 00422 } 00423 00425 NTuple::Tuple* NTupleSvc::book (const std::string& dirPath, const std::string& relPath, const CLID& type, const std::string& title) { 00426 std::string full = dirPath; 00427 if (relPath[0] != SEPARATOR) full += SEPARATOR; 00428 full += relPath; 00429 return book(full, type, title); 00430 } 00431 00433 NTuple::Tuple* NTupleSvc::book (const std::string& dirPath, long id, const CLID& type, const std::string& title) { 00434 char txt[32]; 00435 return book( dirPath, _itoa(id, txt, 10), type, title); 00436 } 00437 00439 NTuple::Tuple* NTupleSvc::book (DataObject* pParent, const std::string& relPath, const CLID& type, const std::string& title) { 00440 NTuple::Tuple* pObj = 0; 00441 // Check if object is already present 00442 StatusCode status = findObject(pParent, relPath, *pp_cast<DataObject>(&pObj)); 00443 // No ? Then create it! 00444 if ( !status.isSuccess() ) { 00445 status = create( type, title, pObj); 00446 if ( status.isSuccess() ) { 00447 // Finally register the created N tuple with the store 00448 status = registerObject(pParent, relPath, pObj); 00449 if ( status.isSuccess() ) { 00450 return pObj; 00451 } 00452 pObj->release(); 00453 } 00454 } 00455 return 0; 00456 } 00457 00459 NTuple::Tuple* NTupleSvc::book (DataObject* pParent, 00460 long id, 00461 const CLID& type, 00462 const std::string& title) { 00463 char txt[32]; 00464 return book( pParent, ::_itoa(id, txt,10), type, title); 00465 } 00466 00468 NTuple::Directory* NTupleSvc::createDirectory (DataObject* pParent, 00469 const std::string& relPath) { 00470 if ( 0 != pParent ) { 00471 IRegistry* pDir = pParent->registry(); 00472 if ( 0 != pDir ) { 00473 std::string full = pDir->identifier(); 00474 full += (relPath[0]=='/') ? "" : "/"; 00475 full += relPath; 00476 return createDirectory(full); 00477 } 00478 } 00479 return 0; 00480 } 00481 00483 NTuple::Directory* NTupleSvc::createDirectory (DataObject* pParent, long id) { 00484 char txt[32]; 00485 return createDirectory( pParent, ::_itoa(id, txt,10) ); 00486 } 00487 00489 NTuple::Directory* NTupleSvc::createDirectory (const std::string& dirPath, long id) { 00490 char txt[32]; 00491 return createDirectory( dirPath, ::_itoa(id, txt,10) ); 00492 } 00493 00495 NTuple::Directory* NTupleSvc::createDirectory (const std::string& dirPath, const std::string& relPath ) { 00496 std::string full = dirPath; 00497 full += (relPath[0]=='/') ? "" : "/"; 00498 full += relPath; 00499 return createDirectory(full); 00500 } 00501 00502 StatusCode NTupleSvc::attachTuple(const std::string& filename, const std::string& logname, const char typ, const long t) { 00503 MsgStream log(msgSvc(), name()); 00504 DataObject* p; 00505 // First get the root object 00506 StatusCode status = retrieveObject(m_rootName, p); 00507 if ( status.isSuccess() ) { 00508 // Now add the registry entry to the store 00509 std::string entryname = m_rootName; 00510 entryname += '/'; 00511 entryname += logname; 00512 GenericAddress* pA = 00513 new GenericAddress(t, CLID_NTupleFile, filename, entryname, 0, typ); 00514 status = registerAddress(p, logname, pA); 00515 if ( status.isSuccess() ) { 00516 log << MSG::INFO << "Added stream file:" << filename << " as " << logname << endmsg; 00517 return status; 00518 } 00519 pA->release(); 00520 } 00521 log << MSG::ERROR << "Cannot add file:" << filename << " as " << logname << endmsg; 00522 return status; 00523 } 00524 00526 NTuple::Directory* NTupleSvc::createDirectory (const std::string& fullPath) { 00527 NTuple::Directory* p = 0; 00528 StatusCode status = findObject(fullPath, *pp_cast<DataObject>(&p)); 00529 if ( !status.isSuccess() ) { 00530 int sep2 = fullPath.rfind(SEPARATOR); 00531 if ( sep2 > 0 ) { 00532 std::string relPath = fullPath.substr(0, sep2); 00533 p = createDirectory(relPath); 00534 if ( 0 != p ) { 00535 p = new NTuple::Directory(); 00536 // Finally register the created N tuple with the store 00537 status = registerObject(fullPath, p); 00538 if ( status.isSuccess() ) { 00539 // ...starting from the file entries 00540 IConversionSvc* svc = getDataLoader(p->registry()); 00541 if ( 0 != svc ) { 00542 IOpaqueAddress* pAddr = 0; 00543 status = svc->createRep (p, pAddr); 00544 if ( status.isSuccess() ) { 00545 p->registry()->setAddress(pAddr); 00546 status = svc->fillRepRefs (pAddr, p); 00547 if ( status.isSuccess() ) { 00548 return p; 00549 } 00550 } 00551 } 00552 unregisterObject(p); 00553 } 00554 p->release(); 00555 p = 0; 00556 } 00557 } 00558 } 00559 try { 00560 p = dynamic_cast<NTuple::Directory*>(p); 00561 return p; 00562 } 00563 catch (...) { 00564 } 00565 return 0; 00566 } 00567 00569 NTuple::Tuple* NTupleSvc::access(const std::string&, const std::string&) { 00570 MsgStream log ( msgSvc(), name() ); 00571 return 0; 00572 } 00573 00575 StatusCode NTupleSvc::save(const std::string& fullPath) { 00576 MsgStream log ( msgSvc(), name() ); 00577 NTuple::Tuple* pObj = 0; 00578 StatusCode status = findObject(fullPath, *pp_cast<DataObject>(&pObj)); // Check if object is present 00579 if ( status.isSuccess() ) { 00580 return save ( pObj ); 00581 } 00582 return INVALID_OBJ_PATH; 00583 } 00584 00586 StatusCode NTupleSvc::save(NTuple::Tuple* n_tuple) { 00587 NTuple::TupleImp* tuple = (NTuple::TupleImp*)n_tuple; 00588 if ( 0 != tuple ) { 00589 try { 00590 IConversionSvc* pSvc = tuple->conversionService(); 00591 IRegistry* pReg = tuple->registry(); 00592 if ( 0 != pSvc && 0 != pReg ) { 00593 IOpaqueAddress* pAddr = pReg->address(); 00594 StatusCode status = pSvc->updateRep(pAddr, n_tuple); 00595 if ( status.isSuccess() ) { 00596 status = pSvc->updateRepRefs(pAddr, n_tuple); 00597 } 00598 return status; 00599 } 00600 return IDataProviderSvc::NO_DATA_LOADER; 00601 } 00602 catch(...) { 00603 } 00604 } 00605 return INVALID_OBJECT; 00606 } 00607 00609 StatusCode NTupleSvc::save(DataObject* pParent, const std::string& relPath) { 00610 NTuple::Tuple* pObj = 0; 00611 StatusCode status = findObject(pParent, relPath, *pp_cast<DataObject>(&pObj)); // Check if object is present 00612 if ( status.isSuccess() ) { 00613 return save ( pObj ); 00614 } 00615 return INVALID_OBJ_PATH; 00616 } 00617 00619 StatusCode NTupleSvc::writeRecord( NTuple::Tuple* n_tuple ) { 00620 NTuple::TupleImp* tuple = (NTuple::TupleImp*)n_tuple; 00621 if ( 0 != tuple ) { 00622 try { 00623 IConversionSvc* pSvc = tuple->conversionService(); 00624 if ( 0 == pSvc ) { 00625 pSvc = getDataLoader(n_tuple->registry()); 00626 tuple->setConversionService(pSvc); 00627 } 00628 if ( 0 != pSvc ) { 00629 IRegistry* pReg = n_tuple->registry(); 00630 IOpaqueAddress* pAddr = pReg->address(); 00631 StatusCode status = pSvc->createRep(n_tuple, pAddr); 00632 if ( status.isSuccess() ) { 00633 pReg->setAddress(pAddr); 00634 status = pSvc->fillRepRefs(pAddr, n_tuple); 00635 } 00636 return status; 00637 } 00638 return IDataProviderSvc::NO_DATA_LOADER; 00639 } 00640 catch(...) { 00641 } 00642 } 00643 return INVALID_OBJECT; 00644 } 00645 00647 StatusCode NTupleSvc::writeRecord(const std::string& fullPath ) { 00648 NTuple::Tuple* pObj = 0; 00649 StatusCode status = findObject(fullPath, *pp_cast<DataObject>(&pObj)); // Check if object is present 00650 if ( status.isSuccess() ) { 00651 return writeRecord ( pObj ); 00652 } 00653 return INVALID_OBJ_PATH; 00654 } 00655 00657 StatusCode NTupleSvc::writeRecord( DataObject* pParent, const std::string& relPath) { 00658 NTuple::Tuple* pObj = 0; 00659 StatusCode status = findObject(pParent, relPath, *pp_cast<DataObject>(&pObj)); // Check if object is present 00660 if ( status.isSuccess() ) { 00661 return writeRecord ( pObj ); 00662 } 00663 return INVALID_OBJ_PATH; 00664 } 00665 00667 StatusCode NTupleSvc::readRecord( NTuple::Tuple* n_tuple ) { 00668 StatusCode status = INVALID_OBJECT; 00669 NTuple::TupleImp* tuple = (NTuple::TupleImp*)n_tuple; 00670 if ( 0 != tuple ) { 00671 try { 00672 IConversionSvc* pSvc = tuple->conversionService(); 00673 if ( 0 == pSvc ) { 00674 pSvc = getDataLoader(n_tuple->registry()); 00675 tuple->setConversionService(pSvc); 00676 } 00677 if ( 0 != pSvc ) { 00678 IRegistry* pReg = n_tuple->registry(); 00679 IOpaqueAddress* pAddr = pReg->address(); 00680 status = pSvc->updateObj(pAddr, n_tuple); 00681 if ( status.isSuccess() ) { 00682 status = pSvc->updateObjRefs(pAddr, n_tuple); 00683 } 00684 return status; 00685 } 00686 status = IDataProviderSvc::NO_DATA_LOADER; 00687 } 00688 catch(...) { 00689 status = INVALID_OBJECT; 00690 } 00691 } 00692 return status; 00693 } 00694 00696 StatusCode NTupleSvc::readRecord(const std::string& fullPath) { 00697 NTuple::Tuple* pObj = 0; 00698 StatusCode status = findObject(fullPath, *pp_cast<DataObject>(&pObj)); // Check if object is present 00699 if ( status.isSuccess() ) { 00700 return readRecord ( pObj ); 00701 } 00702 return INVALID_OBJ_PATH; 00703 } 00704 00706 StatusCode NTupleSvc::readRecord(DataObject* pParent, const std::string& relPath) { 00707 NTuple::Tuple* pObj = 0; 00708 StatusCode status = findObject(pParent, relPath, *pp_cast<DataObject>(&pObj)); // Check if object is present 00709 if ( status.isSuccess() ) { 00710 return readRecord ( pObj ); 00711 } 00712 return INVALID_OBJ_PATH; 00713 } 00714