Gaudi Framework, version v20r3

Generated: 24 Nov 2008

PoolDbCnvSvc.cpp

Go to the documentation of this file.
00001 // $Id: PoolDbCnvSvc.cpp,v 1.30 2008/10/27 16:41:33 marcocle Exp $
00002 //====================================================================
00003 //      PoolDbCnvSvc implementation
00004 //--------------------------------------------------------------------
00005 //
00006 //  Description: Implementation of the POOL data storage
00007 //
00008 //      Author     : M.Frank
00009 //
00010 //====================================================================
00011 
00012 // Framework include files
00013 #include "GaudiKernel/MsgStream.h"
00014 #include "GaudiKernel/strcasecmp.h"
00015 #include "GaudiKernel/SvcFactory.h"
00016 #include "GaudiKernel/CnvFactory.h"
00017 #include "GaudiKernel/IRegistry.h"
00018 #include "GaudiKernel/IDataManagerSvc.h"
00019 #include "GaudiKernel/IDataProviderSvc.h"
00020 
00021 #include "GaudiPoolDb/IPoolCacheSvc.h"
00022 #include "GaudiPoolDb/PoolDbCnvSvc.h"
00023 #include "GaudiPoolDb/PoolDbAddress.h"
00024 #include "GaudiPoolDb/PoolDbDataConnection.h"
00025 
00026 // POOL include files
00027 #include "POOLCore/Token.h"
00028 #include "StorageSvc/DbType.h"
00029 #include "StorageSvc/DbObject.h"
00030 #include "StorageSvc/DbSelect.h"
00031 #include "StorageSvc/DataCallBack.h"
00032 #include "StorageSvc/DbTypeInfo.h"
00033 #include "StorageSvc/DbInstanceCount.h"
00034 #include "StorageSvc/DbOptionCallback.h"
00035 #include "GaudiUtils/IFileCatalog.h"
00036 #include "GaudiUtils/IIODataManager.h"
00037 
00038 //ROOT include files
00039 #include "TInterpreter.h"
00040 
00041 #include <sstream>
00042 #include <set>
00043 #include <memory>
00044 
00045 using ROOT::Reflex::PluginService;
00046 
00047 static pool::DbInstanceCount::Counter* s_count = 
00048   pool::DbInstanceCount::getCounter(typeid(PoolDbCnvSvc));
00049 
00050 DECLARE_SERVICE_FACTORY(PoolDbCnvSvc);
00051 
00052 typedef std::vector<std::string> StringV;
00053 typedef const std::string& CSTR;
00054 
00055 #define S_OK   StatusCode::SUCCESS
00056 #define S_FAIL StatusCode::FAILURE
00057 using pool::DbType;
00058 using pool::DbContainer;
00059 using pool::DbDomain;
00060 using pool::DbDatabase;
00061 using pool::DbTypeInfo;
00062 using pool::DbTransaction;
00063 using pool::DbOptionCallback;
00064 using pool::DbAccessMode;
00065 using pool::Transaction;
00066 using namespace Gaudi;
00067 
00068 static void checkAccessMode(DbAccessMode mode, DbDatabase& dbH)  {
00069   DbAccessMode m = dbH.openMode();
00070   if ( m&mode || m&pool::UPDATE || m&pool::RECREATE )  {
00071     return;
00072   }
00073   std::string err = 
00074       "The dataset "+dbH.name()+" cannot be opened in mode "+
00075       +pool::accessMode(mode)+
00076       +"\nThe database was already open, but in mode " 
00077       +pool::accessMode(m);
00078   throw std::runtime_error(err);
00079 }
00080 
00082 PoolDbCnvSvc::PoolDbCnvSvc(CSTR nam, ISvcLocator* svc)
00083 : ConversionSvc( nam, svc, POOL_StorageType), 
00084   m_dataMgr(0), m_cacheSvc(0), m_current(0), 
00085   m_domH(pool::POOL_StorageType),
00086   m_catalog(0), m_ioMgr(0)
00087 {
00088   s_count->increment();
00089   declareProperty("Server",           m_serverConnect    = "");
00090   declareProperty("DbType",           m_implementation   = "Unknown");
00091   declareProperty("PoolCache",        m_cacheSvcName     = "PoolDbCacheSvc");
00092   declareProperty("ShareFiles",       m_shareFiles       = "NO");
00093   declareProperty("SafeTransactions", m_safeTransactions = false);
00094   declareProperty("CheckFIDs",        m_checkFIDs        = true);
00095 }
00096 
00098 PoolDbCnvSvc::~PoolDbCnvSvc()   {
00099   s_count->decrement();
00100 }
00101 
00103 StatusCode 
00104 PoolDbCnvSvc::queryInterface(const InterfaceID& riid, void** ppvInterface)   {
00105   if ( IID_IPoolDbMgr == riid )  {
00106     *ppvInterface = (IPoolDbMgr*)this;
00107     addRef();
00108     return S_OK;
00109   }
00110   // Interface is not directly availible: try out a base class
00111   return ConversionSvc::queryInterface(riid, ppvInterface);
00112 }
00113 
00115 StatusCode PoolDbCnvSvc::initialize()  {
00116   StatusCode status = ConversionSvc::initialize();
00117   MsgStream log(messageService(), name());
00118   if ( !status.isSuccess() ) {
00119     log << MSG::ERROR << "Failed to initialize ConversionSvc base class."
00120         << endmsg;
00121     return status;
00122   }
00123   status = accessStorageType(m_implementation, m_type);
00124   if ( !status.isSuccess() )  {
00125     log << MSG::ERROR << "Failed to connect to POOL implementation:"
00126         << m_implementation << endmsg;
00127     return status;
00128   }
00129   status = service(m_cacheSvcName, m_cacheSvc);
00130   if ( !status.isSuccess() )  {
00131     log << MSG::ERROR << "Failed to connect to POOL cache service:"
00132         << m_cacheSvcName << endmsg;
00133     return status;
00134   }
00135   status = service("IODataManager", m_ioMgr);
00136   if( !status.isSuccess() ) {
00137     log << MSG::ERROR 
00138         << "Unable to localize interface from service:IODataManager" << endreq;
00139     return status;
00140   }
00141   status = service("FileCatalog", m_catalog);
00142   if( !status.isSuccess() ) {
00143     log << MSG::ERROR 
00144         << "Unable to localize interface from service:FileCatalog" << endreq;
00145     return status;
00146   }
00147   DbOptionCallback cb(m_cacheSvc->callbackHandler());
00148   if ( m_domH.open(m_cacheSvc->session(),m_type,pool::UPDATE).isSuccess() )  {
00149     SmartIF<IProperty> prp(m_ioMgr);
00150     IntegerProperty ageLimit;
00151     ageLimit.assign(prp->getProperty("AgeLimit"));
00152     log << MSG::DEBUG << "POOL agelimit is set to " << ageLimit.value() << endmsg;
00153     m_domH.setAgeLimit(ageLimit.value());
00154     return S_OK;
00155   }
00156   return S_OK;
00157 }
00158 
00160 StatusCode PoolDbCnvSvc::finalize()    {
00161   MsgStream log(messageService(),name());
00162   DbOptionCallback cb(m_cacheSvc->callbackHandler());
00163   if ( m_ioMgr )  {
00164     if ( ::toupper(m_shareFiles[0]) != 'Y' )  {
00165       IIODataManager::Connections cons = m_ioMgr->connections(this);
00166       for(IIODataManager::Connections::iterator i=cons.begin(); i != cons.end(); ++i)  {
00167         if ( m_ioMgr->disconnect(*i).isSuccess() )  {
00168           log << MSG::INFO << "Disconnected data IO:" << (*i)->fid();
00169           log << "[" << (*i)->pfn() << "]";
00170           log << endmsg;
00171           delete (*i);
00172         }
00173       }
00174     }
00175     else  {
00176       log << MSG::INFO << "File sharing enabled. Do not retire files." << endmsg;
00177     }
00178     m_ioMgr->release();
00179     m_ioMgr = 0;
00180   }
00181   m_domH.close();
00182   m_domH = 0;
00183   if ( m_dataMgr ) m_dataMgr->clearStore().ignore();
00184   pool::releasePtr(m_dataMgr);
00185   pool::releasePtr(m_catalog);
00186   pool::releasePtr(m_cacheSvc);
00187   StatusCode status = ConversionSvc::finalize();
00188   log << MSG::DEBUG << "POOL conversion service finalized " << name() << " ";
00189   log << (const char*)(status.isSuccess() ? "successfully" : "with errors") << endmsg;
00190   return status;
00191 }
00192 
00194 StatusCode PoolDbCnvSvc::updateServiceState(IOpaqueAddress* /* pAddr */)  {
00195   return S_OK;
00196 }
00197 
00199 IConverter* 
00200 PoolDbCnvSvc::createConverter(long typ,const CLID& wanted,const ICnvFactory*)
00201 {
00202   IConverter* pConverter;
00203   ConverterID cnvid(POOL_StorageType, wanted);  
00204   pConverter = PluginService::CreateWithId<IConverter*>(cnvid, typ, wanted, serviceLocator());
00205   if ( 0 == pConverter )  {
00206     const CLID gen_clids[] = {  
00207     /* ObjectList               */ CLID_Any + CLID_ObjectList,
00208     /* ObjectVector             */ CLID_Any + CLID_ObjectVector, 
00209     /* Keyed Map                */ CLID_Any + CLID_ObjectVector+0x00030000,
00210     /* Keyed Hashmap            */ CLID_Any + CLID_ObjectVector+0x00040000,
00211     /* Keyed redirection array  */ CLID_Any + CLID_ObjectVector+0x00050000,
00212     /* Standard, non-container  */ CLID_Any
00213     };
00214     for ( unsigned int i = 0; i < sizeof(gen_clids)/sizeof(gen_clids[0]); i++ ) {
00215       if ( (wanted>>16) == (gen_clids[i]>>16) )  {
00216         ConverterID cnvid(POOL_StorageType, gen_clids[i]);  
00217         pConverter = PluginService::CreateWithId<IConverter*>(cnvid, typ, wanted, serviceLocator());
00218         if ( 0 != pConverter ) {
00219           return pConverter;
00220         }
00221       }
00222     }
00223     // Check if a converter using object update is needed
00224     if ( (wanted>>24) != 0 )  {
00225       ConverterID cnvid(POOL_StorageType, CLID_Any | 1<<31);  
00226       pConverter = PluginService::CreateWithId<IConverter*>(cnvid, typ, wanted, serviceLocator());
00227       if ( 0 != pConverter ) {
00228         return pConverter;
00229       }
00230     }
00231     // If we do not have found any suitable container after searching
00232     // for standard containers, we will use the "ANY" converter 
00233     // ... and pray for everything will go well.
00234     ConverterID cnvid(POOL_StorageType, CLID_Any);  
00235     pConverter = PluginService::CreateWithId<IConverter*>(cnvid, typ, wanted, serviceLocator());
00236     if ( 0 != pConverter ) {
00237       MsgStream log(msgSvc(), name());
00238       log << MSG::INFO << "Using \"Any\" converter "
00239           << "for objects of type " 
00240           << std::showbase << std::hex << wanted << endmsg;
00241     }
00242   }
00243   return pConverter;
00244 }
00245 
00246 void PoolDbCnvSvc::loadConverter(DataObject* pObject) {
00247   if (pObject) {
00248     MsgStream log(msgSvc(), name());
00249     std::string cname = System::typeinfoName(typeid(*pObject));
00250     log << MSG::DEBUG << "Trying to 'Autoload' dictionary for class " << cname << endmsg;
00251     gInterpreter->EnableAutoLoading();
00252     gInterpreter->AutoLoad(cname.c_str());
00253   }
00254 }  
00255 
00256 StatusCode PoolDbCnvSvc::setDataProvider(IDataProviderSvc* pDataSvc)  {
00257   IDataManagerSvc* tmp = m_dataMgr;
00258   if (pDataSvc)  {
00259     StatusCode status = 
00260       pDataSvc->queryInterface(IID_IDataManagerSvc, pp_cast<void>(&m_dataMgr));
00261     if ( !status.isSuccess() )    {
00262       return error("Cannot connect to \"IDataManagerSvc\" interface.");
00263     }
00264   }
00265   if ( tmp ) tmp->release();
00266   return ConversionSvc::setDataProvider(pDataSvc);
00267 }
00268 
00270 StatusCode PoolDbCnvSvc::accessStorageType(CSTR type_string, long& gaudi_type) {
00271   if ( ::strncasecmp(type_string.c_str(), "POOL_ROOTTREE", 10)==0 ) {
00272     gaudi_type  = POOL_ROOTTREE_StorageType;
00273     return S_OK;
00274   }
00275   else if ( ::strncasecmp(type_string.c_str(), "POOL_ROOTKEY", 10)==0 ) {
00276     gaudi_type  = POOL_ROOTKEY_StorageType;
00277     return S_OK;
00278   }
00279   else if ( ::strncasecmp(type_string.c_str(), "POOL_ROOT", 9)==0 ) {
00280     gaudi_type  = POOL_ROOT_StorageType;
00281     return S_OK;
00282   }
00283   gaudi_type = TEST_StorageType;
00284   return S_FAIL;
00285 }
00286 
00288 StatusCode PoolDbCnvSvc::connectOutput(CSTR dsn, CSTR openMode)   {
00289   StatusCode sc = StatusCode::FAILURE;
00290   DbAccessMode mode = pool::NOT_OPEN;
00291   m_current = 0;
00292   if ( ::strncasecmp(openMode.c_str(),"RECREATE",3)==0 )
00293     sc = connectDatabase(UNKNOWN, dsn, mode=pool::RECREATE, &m_current);
00294   else if ( ::strncasecmp(openMode.c_str(),"NEW",1)==0 )
00295     sc = connectDatabase(UNKNOWN, dsn, mode=pool::CREATE, &m_current);
00296   else if ( ::strncasecmp(openMode.c_str(),"CREATE",1)==0 )
00297     sc = connectDatabase(UNKNOWN, dsn, mode=pool::CREATE, &m_current);
00298   else if ( ::strncasecmp(openMode.c_str(),"UPDATE",1)==0 )
00299     sc = connectDatabase(UNKNOWN, dsn, mode=pool::UPDATE, &m_current);
00300   if ( sc.isSuccess() && m_current && m_current->isConnected() )  {
00301     return S_OK;
00302   }
00303   error("The dataset "+dsn+" cannot be opened in mode "+openMode+". [Invalid mode]");
00304   return sc;
00305 }
00306 
00307 // Conect output stream (valid until overwritten)
00308 StatusCode PoolDbCnvSvc::connectOutput(CSTR db_name)  {
00309   return connectOutput(db_name, "NEW");
00310 }
00311 
00312 // Commit pending output on open container
00313 StatusCode  PoolDbCnvSvc::commitOutput(CSTR dsn, bool doCommit) {
00314   if ( m_current )  {
00315     try  {
00316       if ( doCommit )
00317         m_current->transaction().set(m_safeTransactions ? Transaction::TRANSACT_FLUSH : Transaction::TRANSACT_COMMIT);
00318       else
00319         m_current->transaction().set(Transaction::TRANSACT_ROLLBACK);
00320       if ( m_current->database().transAct(m_current->transaction()).isSuccess() )  {
00321         return S_OK;
00322       }
00323       std::string action(doCommit ? "commit to" : "rollback");
00324       return error("commitOutput> Cannot "+action+" database:"+dsn);
00325     }
00326     catch (std::exception& e)  {
00327       error(std::string("commitOutput> Caught exception:")+e.what(), false);
00328     }
00329     catch (...)   {
00330       error("commitOutput> Unknown Fatal Exception on commit to "+dsn, false);
00331     }
00332   }
00333   return error("commitOutput> Cannot connect to database: "+dsn);
00334 }
00335 
00336 // Connect to a POOL container in read mode
00337 StatusCode PoolDbCnvSvc::connect(CSTR dsn, CSTR cntName, DbContainer& cntH)   {
00338   return connectContainer(UNKNOWN, dsn, cntName, pool::READ, 0, cntH);
00339 }
00340 
00342 StatusCode 
00343 PoolDbCnvSvc::connectDatabase(int typ, CSTR dataset, DbAccessMode mode, PoolDbDataConnection** con)  {
00344   try {
00345     DbOptionCallback cb(m_cacheSvc->callbackHandler());
00346     IDataConnection* c = m_ioMgr->connection(dataset);
00347     if ( !c )  {
00348       DbType dbType(DbType(m_type).majorType());
00349       std::auto_ptr<IDataConnection> connection(new PoolDbDataConnection(this,dataset,typ,mode,m_domH));
00350       StatusCode sc = (mode == pool::READ) 
00351         ? m_ioMgr->connectRead(false,connection.get())
00352         : m_ioMgr->connectWrite(connection.get(),IDataConnection::IoType(mode),dbType.storageName());
00353       c = sc.isSuccess() ? m_ioMgr->connection(dataset) : 0;
00354       if ( c ) connection.release();
00355       else     return sc;
00356     }
00357     PoolDbDataConnection* pc = dynamic_cast<PoolDbDataConnection*>(c);
00358     if ( pc )  {
00359       if ( !pc->isConnected() ) pc->connectRead();
00360       static int wr  = pool::RECREATE|pool::CREATE|pool::UPDATE;
00361       // Got a valid connection. Now rearm the transaction
00362       checkAccessMode(mode, pc->database());
00363       if ( (mode&wr) != 0 )  {
00364         pc->transaction().set(pool::Transaction::TRANSACT_START);
00365         if ( !pc->database().transAct(pc->transaction()).isSuccess() )
00366           return StatusCode::FAILURE;
00367       }
00368       *con = pc;
00369       pc->resetAge();
00370     }
00371     return *con ? StatusCode::SUCCESS : StatusCode::FAILURE;
00372   }
00373   catch (std::exception& e)  {
00374     return error(std::string("connectDatabase> Caught exception:")+e.what(), false);
00375   }
00376   catch (...)   {
00377     return error("connectDatabase> Unknown Fatal Exception for "+dataset, false);
00378   }
00379 }
00380 
00381 StatusCode 
00382 PoolDbCnvSvc::connectContainer(int type,
00383                                CSTR dbName,
00384                                CSTR cntName,
00385                                DbAccessMode mode,
00386                                const DbTypeInfo* info,
00387                                DbContainer& cntH)   
00388 {
00389   PoolDbDataConnection* c = 0;
00390   StatusCode sc = connectDatabase(type, dbName, mode, &c);
00391   if( sc.isSuccess() )  {
00392     return connectContainer(c->database(), cntName, mode, info, cntH);
00393   }
00394   return sc;
00395 }
00396 
00397 StatusCode
00398 PoolDbCnvSvc::connectContainer(DbDatabase& dbH, 
00399                                CSTR cntName,
00400                                DbAccessMode mode,
00401                                const DbTypeInfo* shapeH,
00402                                DbContainer& cntH)   
00403 {
00404   std::string pfn, fid;
00405   int all = pool::READ + pool::CREATE + pool::UPDATE;
00406   int wr  = pool::CREATE + pool::UPDATE;
00407   if ( dbH.isValid() )  {
00408     fid = dbH.token()->dbID();
00409     pfn = dbH.token()->contID();
00410     int m   = dbH.openMode();
00411     if ( (m&all) && mode == pool::READ )    {
00412     }
00413     else if ( m&wr && mode&pool::CREATE )   {
00414     }
00415     else if ( m&wr && mode&pool::UPDATE )   {
00416     }
00417     else  {
00418       dbH.reopen(pool::UPDATE);
00419     }
00420   }
00421   // No Else!
00422   if ( !dbH.isValid() )  {
00423     error("Cannot connect to Database: FID="+fid+" PFN="+pfn+
00424           " [Invalid database handle]",false);
00425     return StatusCode::FAILURE;
00426   }
00427   cntH = DbContainer(dbH.find(cntName));
00428   if ( cntH.isValid() )  {
00429     return StatusCode::SUCCESS;
00430   }
00431   if ( mode&pool::READ )  {
00432     shapeH = dbH.contShape(cntName);
00433   }
00434   if ( shapeH )  {
00435     if ( cntH.open(dbH, cntName, shapeH, m_type, mode).isSuccess() )  {
00436       return StatusCode::SUCCESS;
00437     }
00438     return error("connectContainer> Failed to open container:"+cntName+
00439       " in "+dbH.name(),false);
00440   }
00441   return error("connectContainer> No shape present for container:"+cntName+
00442     " in "+dbH.name(),false);
00443 }
00444 
00445 // Disconnect from an existing data stream.
00446 StatusCode PoolDbCnvSvc::disconnect(CSTR dataset)  {
00447   IDataConnection* c = m_ioMgr->connection(dataset);
00448   return c ? m_ioMgr->disconnect(c) : S_FAIL;
00449 }
00450 
00451 // Request an iterator over a container from the service
00452 pool::DbSelect* PoolDbCnvSvc::createSelect(CSTR criteria,CSTR db,CSTR cnt) {
00453   PoolDbDataConnection* c = 0;
00454   StatusCode sc = connectDatabase(UNKNOWN, db, pool::READ, &c);
00455   if ( sc.isSuccess() )  {
00456     // Now select according to criteria
00457     std::auto_ptr<pool::DbSelect> sel(new pool::DbSelect(criteria));
00458     if ( sel->start(c->database(), cnt).isSuccess() )  {
00459       return sel.release();          
00460     }
00461     return 0;
00462   }
00463   error("createSelect> Cannot open database:"+db, false);
00464   return 0;
00465 }
00466 
00468 StatusCode PoolDbCnvSvc::createAddress( long  typ,
00469                                         const CLID& clid,
00470                                         const std::string* par, 
00471                                         const unsigned long* ip,
00472                                         IOpaqueAddress*& refpAddress) 
00473 {
00474   PoolDbAddress* pA = 0;
00475   pool::Guid guid = pool::Guid::null();
00476   std::auto_ptr<pool::Token> tok(new pool::Token());
00477   guid.Data1 = clid;
00478   tok->setDb(par[0]);
00479   tok->setCont(par[1]);
00480   tok->setTechnology(typ);
00481   tok->setClassID(guid);
00482   tok->oid().first = ip[0];
00483   tok->oid().second = ip[1];
00484   if ( createAddress(tok.get(), &pA).isSuccess() )  {
00485     refpAddress = pA;
00486     tok->release();
00487     tok.release();
00488     return S_OK;
00489   }
00490   return error("createAddress> Failed to create opaque address.");
00491 }
00492 
00493 // Create an opaque address from a POOL token structure
00494 StatusCode PoolDbCnvSvc::createAddress(pool::Token* pTok,PoolDbAddress** ppAdd) {
00495   if ( pTok )  {
00496     *ppAdd = new PoolDbAddress(pTok);
00497     return S_OK;
00498   }
00499   return error("createAddress> Failed to create opaque address from POOL token.");
00500 }
00501 
00502 // Mark an object for write given an object reference
00503 StatusCode 
00504 PoolDbCnvSvc::markWrite(pool::DataCallBack* call,CSTR cntName,PoolDbAddress** ppAddr)
00505 {
00506   if ( m_current )  {
00507     DbOptionCallback call_back(m_cacheSvc->callbackHandler());
00508     const DbTypeInfo* shapeH = (const DbTypeInfo*)call->shape();
00509     DbDatabase& dbH = m_current->database();
00510     if ( dbH.transactionActive() )  {
00511       std::auto_ptr<pool::Token> token(new pool::Token());
00512       token->setDb(dbH.name()).setCont(cntName);
00513       token->setClassID(shapeH->shapeID());
00514       token->setTechnology(m_type);
00515       DbContainer cntH(POOL_StorageType);
00516       StatusCode sc = connectContainer(dbH,cntName,pool::UPDATE|pool::CREATE,shapeH,cntH);
00517       if ( sc.isSuccess() )  {
00518         call->setHandler(&m_handler);
00519         if ( cntH.allocate(call, token->oid()).isSuccess() )  {
00520           if ( dbH.makeLink(token.get(), token->oid()).isSuccess() )  {
00521             if ( ppAddr )  {
00522               if ( *ppAddr ) {
00523                 (*ppAddr)->token()->setData(token.get());
00524               }
00525               else {
00526                 *ppAddr = new PoolDbAddress(token.get());
00527                     }
00528             }
00529             long cnt = token->release();
00530             if ( cnt > 1 ) {
00531               MsgStream log(messageService(), name());
00532               log << MSG::ERROR << "markWrite> Token count wrong: " 
00533                   << cnt << " expect memory leak. " << endmsg
00534                   << "run again with environment POOLDB_TRACE=ON and"
00535                   << " check instance counts." << endmsg;
00536             }
00537             token.release();
00538             return S_OK;
00539           }
00540         }
00541       }
00542     }
00543     return error("markWrite> No active transaction present for "+dbH.name());
00544   }
00545   return error("markWrite> Current Database is invalid!");
00546 }
00547 
00548 // Mark an object for update
00549 StatusCode PoolDbCnvSvc::markUpdate(pool::DataCallBack* call, PoolDbAddress* pA)  {
00550   if ( pA && call )  {
00551     pool::Token* tok = pA->token();
00552     DbContainer cntH(POOL_StorageType);
00553     const DbTypeInfo* info = (const DbTypeInfo*)call->shape();
00554     StatusCode sc = connectContainer(FID,tok->dbID(),tok->contID(),pool::UPDATE,info,cntH);
00555     if ( sc.isSuccess() )  {
00556       call->setHandler(&m_handler);
00557       if ( cntH.update(call, tok->oid()).isSuccess() )  {
00558         return S_OK;
00559       }
00560       return error("markUpdate> Failed to update object:"+tok->toString());
00561     }
00562     MsgStream log(messageService(), name());
00563     log << MSG::ERROR << "markUpdate> The container " 
00564         << tok->dbID() << "::" << tok->contID()
00565         << " cannot be accessed." << endmsg
00566         << "Was this object really read from the container "
00567         << "the object token claims?"
00568         << endmsg;
00569     return S_FAIL;
00570   }
00571   return error("createRep> Invalid object address for update.");
00572 }
00573 
00575 StatusCode PoolDbCnvSvc::read(pool::DataCallBack* call, PoolDbAddress* pA)  {
00576   StatusCode sc = read(call, *pA->token());
00577   if ( sc.isSuccess() || sc == BAD_DATA_CONNECTION )  {
00578     return sc;
00579   }
00580   std::string err="read> Cannot read object:"+pA->registry()->identifier()+" ";
00581   return error(err, false);
00582 }
00583 
00585 StatusCode PoolDbCnvSvc::read(pool::DataCallBack* call, pool::Token& tok)  {
00586   try  {
00587     DbContainer cntH(tok.technology());
00588     const DbTypeInfo* info = (const DbTypeInfo*)call->shape();
00589     StatusCode sc = connectContainer(FID,tok.dbID(),tok.contID(),pool::READ,info,cntH);
00590     if ( sc.isSuccess() )  {
00591       typedef pool::DbObjectHandle<pool::DbObject> ObjH;
00592       call->setHandler(&m_handler);
00593       return ObjH::openEx(cntH, tok, call, pool::READ).isSuccess() ? S_OK : S_FAIL;
00594     }
00595     else if ( sc == BAD_DATA_CONNECTION )  {
00596       return sc;
00597     }
00598   }
00599   catch (std::exception& e)  {
00600     std::string err="read> Cannot read object:"+tok.toString()+" ";
00601     return error(err+e.what(), false);
00602   }
00603   catch (...)   {
00604     std::string err = "read> Cannot read object:"+tok.toString();
00605     return error(err+" [Unknown fatal exception]", false);
00606   }
00607   return error("read> Cannot read object:"+tok.toString(), false);
00608 }
00609 
00610 // Small routine to issue exceptions
00611 StatusCode PoolDbCnvSvc::error(CSTR msg, bool rethrow)  {
00612   if ( rethrow )  {
00613     pool::debugBreak("PoolDbCnvSvc", "Error:"+msg, rethrow);
00614   }
00615   else  {
00616     MsgStream log(messageService(),name());
00617     log << MSG::ERROR << "Error: " << msg << endmsg;
00618   }
00619   return S_FAIL;
00620 }

Generated at Mon Nov 24 14:38:47 2008 for Gaudi Framework, version v20r3 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004