Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

DbDataBaseObj.cpp

Go to the documentation of this file.
00001 //====================================================================
00002 //      DbDataBase object implementation
00003 //--------------------------------------------------------------------
00004 //
00005 //      Package    : System ( The LHCb Offline System)
00006 //
00007 //  Description: Generic data persistency
00008 //
00009 //      Author     : M.Frank
00010 //  History    :
00011 // +---------+----------------------------------------------+---------
00012 // |    Date |                 Comment                      | Who     
00013 // +---------+----------------------------------------------+---------
00014 // | 11/07/99| Initial version                              | MF
00015 // +---------+----------------------------------------------+---------
00016 //====================================================================
00017 #define GAUDIDB_DBSESSION_CPP
00018 
00019 // GaudiDb include files
00020 #include "GaudiDb/DbOOMs.h"
00021 #include "GaudiDb/DbObject.h"
00022 #include "GaudiDb/DbIter.h"
00023 #include "DbDataBaseObj.h"
00024 #include "DbContainerObj.h"
00025 
00026 // Gaudi include files
00027 #include "GaudiKernel/StreamBuffer.h"
00028 #include "GaudiKernel/System.h"
00029 #include "GaudiKernel/MsgStream.h"
00030 
00031 // Standard Constructor
00032 DbDataBase::DbDataBase(const dbHandle<DbFederation>& fed, const std::string& name, DbAccessMode mode) {
00033   m_fed     = fed;
00034   m_name    = name;
00035   m_mode    = mode;
00036   m_info    = 0;
00037   m_type    = m_fed.type();
00038   m_dbOOMs  = m_fed.db();
00039   m_msgSvc  = m_fed.msgSvc();
00040   MsgStream log(m_msgSvc, m_fed.name());
00041   if ( 0 == m_dbOOMs )    {
00042     log << MSG::ERROR
00043         << "--> Access   DbDataBase   "
00044         << " Mode:" << DbOOMs::accessMode(m_mode) 
00045         << "  " << m_name
00046         << " impossible. Cannot link to implementation."
00047         << endreq;
00048     return;
00049   }
00050   DbResult p = m_fed.add( m_name, this );
00051   if ( DbOOMs::DbSuccess != p )    {
00052     log << MSG::ERROR
00053         << "--> Access   DbDataBase   "
00054         << " Type:" << m_dbOOMs->name() 
00055         << " Mode:" << DbOOMs::accessMode(m_mode) 
00056         << "  " << m_name
00057         << " impossible. Error inserting DbDataBase into federation!"
00058         << endreq;
00059   }
00060   m_fed.addRef();
00061   /*
00062   log << MSG::INFO
00063       << "--> Access   DbDataBase   "
00064       << " Type:" << m_dbOOMs->name() 
00065       << " Mode:" << DbOOMs::accessMode(m_mode) 
00066       << "  " << m_name
00067       << endreq;
00068   */
00069   log << MSG::INFO
00070       << "--> Access   DbDataBase   " << DbOOMs::accessMode(m_mode) << " " << m_name
00071       << endreq;
00072 }
00073 
00074 // Standard Destructor
00075 DbDataBase::~DbDataBase()  {
00076   MsgStream log(m_msgSvc, m_fed.name());
00077   clearEntries();
00078   for (LinkVector::iterator i = m_linkVector.begin(); i != m_linkVector.end(); i++ )    {
00079     delete (*i);
00080   }
00081   for (TypeVector::iterator j = m_typeVector.begin(); j != m_typeVector.end(); j++ )    {
00082     delete (*j);
00083   }
00084   m_linkMap.erase(m_linkMap.begin(), m_linkMap.end());
00085   m_linkVector.erase(m_linkVector.begin(), m_linkVector.end());
00086   m_typeMap.erase(m_typeMap.begin(), m_typeMap.end());
00087   m_typeVector.erase(m_typeVector.begin(), m_typeVector.end());
00088   DbDataBase* p = m_fed.find(m_name);
00089   if ( p )   {
00090     m_fed.remove ( p );
00091   }
00092   m_fed.release();
00093   /*
00094   std::string dbtyp((m_dbOOMs) ? m_dbOOMs->name() : "UNKNOWN");
00095   log << MSG::INFO
00096       << "--> Deaccess DbDataBase   "
00097       << " Type:" << dbtyp
00098       << " Mode:" << DbOOMs::accessMode(m_mode) 
00099       << "  " << m_name
00100       << endreq;
00101   */
00102   log << MSG::INFO
00103       << "--> Deaccess DbDataBase   " << DbOOMs::accessMode(m_mode) << " " << m_name
00104       << endreq;
00105 }
00106 
00107 // Add association entry
00108 DbResult DbDataBase::addAssocEntry(const std::string& db, const std::string& cnt, const std::string& obj, dbHandle<DbLink>& to)     {
00109   std::string key = db;
00110   key += ":";
00111   key += cnt;
00112   key += "#";
00113   key += obj;
00114   LinkMap::iterator i = m_linkMap.find(key);
00115   if ( i != m_linkMap.end() )   {
00116     return (*i).second->set(to);
00117   }
00118   else if ( m_mode != DbOOMs::READ ) {
00119     Link* link;
00120     const Link* cpLink = link = new Link(db==m_name ? "<localDB>" : db, cnt, obj, to, m_linkVector.size());
00121     // Add the persistent entry to the links container
00122     std::string typName = System::typeinfoName(typeid(DbObject));
00123     const DbTypeInfo* typ = m_dbOOMs->typeInfo(typName);
00124     if ( 0 != typ )   {
00125       dbHandle<DbObject> persH = new(m_links, *typ) DbObject();
00126       StreamBuffer& buffer = persH->streamBuffer();
00127       buffer.setMode(StreamBuffer::WRITING);
00128       cpLink->serialize(buffer);
00129       cpLink->print(m_msgSvc,m_name,"-->  Adding Assoc.Entry:");
00130       if ( !m_links.addEntry(persH) )    {
00131         delete link;
00132         return DbOOMs::DbError;
00133       }
00134       // Update the transient list of links
00135       m_linkMap.insert( LinkMap::value_type(key, link) );
00136       m_linkVector.push_back( link );
00137       return link->set(to);
00138     }
00139   }
00140   return DbOOMs::DbError;
00141 }
00142 
00143 // Retrieve the number of all contained object types
00144 long DbDataBase::numObjTypes()  const   {
00145   return m_typeVector.size();
00146 }
00147 
00148 // Retrieve type information for a specified container by squence number
00149 const DbTypeInfo* DbDataBase::objType(long id)  const {
00150   if ( id >= 0 && id < long(m_typeVector.size()) )   {
00151     return m_dbOOMs->typeInfo(m_typeVector[id]->objType);;
00152   }
00153   return 0;
00154 }
00155 
00156 // Retrieve type information for a specified container by name
00157 const DbTypeInfo* DbDataBase::objType(const std::string& contName)  const {
00158   TypeMap::iterator i = m_typeMap.find(contName);
00159   if ( i == m_typeMap.end() ) {
00160     /*
00161     MsgStream log(m_msgSvc, "availible types");
00162     for ( i = m_typeMap.begin(); i != m_typeMap.end(); i++ )    {
00163       log << MSG::ERROR << contName << " cnt:" << (*i).second->contName << " typ:" << (*i).second->objType;
00164     }
00165     */
00166     return 0;
00167   }
00168   return m_dbOOMs->typeInfo((*i).second->objType);
00169 }
00170 
00171 // Add persistent type to the database
00172 DbResult DbDataBase::addType (const std::string& cntName, const DbTypeInfo& refType)   {
00173   TypeMap::iterator i = m_typeMap.find(cntName);
00174   if ( i != m_typeMap.end() )   {
00175     return DbOOMs::DbSuccess;
00176   }
00177   else if ( m_mode != DbOOMs::READ ) {
00178     Type* type;
00179     refType.makeDescription();
00180     const std::string& typName = refType.name();
00181     const std::string& description = refType.description();
00182     const Type* cpType = type = new Type(cntName, typName, description);
00183     // Add the persistent entry to the links container
00184     std::string typN = System::typeinfoName(typeid(DbObject));
00185     const DbTypeInfo* typ = m_dbOOMs->typeInfo(typN);
00186     if ( 0 != typ )   {
00187       dbHandle<DbObject> persH = new(m_types, *typ) DbObject();
00188       StreamBuffer& buffer = persH->streamBuffer();
00189       buffer.setMode(StreamBuffer::WRITING);
00190       cpType->serialize(buffer);
00191       cpType->print(m_msgSvc, m_name, "-->  Adding Type.Entry:");
00192       // Update the transient list of links
00193       // This must be done BEFORE the entry is inserted into the container!
00194       // Otherwise addEntry will add the type again and again ending in an 
00195       // infinite recusrsion
00196       m_typeMap.insert( TypeMap::value_type(cntName, type) );
00197       m_typeVector.push_back( type );
00198       if ( !m_types.addEntry(persH) )    {
00199         i = m_typeMap.find(cntName);
00200         if ( i != m_typeMap.end() ) m_typeMap.erase(i);
00201         m_typeVector.pop_back();
00202         delete type;
00203         return DbOOMs::DbError;
00204       }
00205       return DbOOMs::DbSuccess;
00206     }
00207   }
00208   return DbOOMs::DbError;
00209 }
00210 
00211 // Open database object
00212 DbResult DbDataBase::open()     const   {
00213   if ( !m_info && m_fed.isValid() )    {
00214     if ( 0 != m_dbOOMs )    {
00215       m_info = m_dbOOMs->createDataBase();
00216       if ( m_info->open(m_fed, m_name, m_mode) )    {
00217         DbDataBase* db = const_cast<DbDataBase*>(this);
00218         dbHandle<DbDataBase> dbH(db);
00219         std::string typName = System::typeinfoName(typeid(DbObject));
00220         const DbTypeInfo* typ = m_dbOOMs->typeInfo(typName);
00221         if ( 0 != typ )   {
00222           if ( m_types.open(dbH, "##Types", *typ, m_mode) )    {
00223             dbIter<DbObject> it;
00224             for ( it.scan(m_types); it.next(); )   {
00225               StreamBuffer& buffer = it->streamBuffer();
00226               buffer.setMode(StreamBuffer::READING);
00227               buffer.reserve(it->objSize());
00228               buffer.setBuffPointer(0);
00229               Type* pType = new Type();
00230               pType->serialize(buffer);
00231               pType->print(m_msgSvc, m_name, "-->  Reading Type.Entry:");
00232               m_dbOOMs->addTypeInfo(pType);
00233               // Update the transient list of links
00234               m_typeMap.insert( TypeMap::value_type(pType->contName, pType) );
00235               m_typeVector.push_back( pType );
00236             }
00237           }
00238           if ( m_links.open(dbH, "##Links", *typ, m_mode) )    {
00239             dbIter<DbObject> it;
00240             for ( it.scan(m_links); it.next(); )   {
00241               StreamBuffer& buffer = it->streamBuffer();
00242               buffer.setMode(StreamBuffer::READING);
00243               buffer.reserve(it->objSize());
00244               buffer.setBuffPointer(0);
00245               Link* pLink = new Link();
00246               pLink->serialize(buffer);
00247               pLink->print(m_msgSvc,m_name, "-->  Reading Assoc.Entry:");
00248               // Update the transient list of links
00249               if ( "<localDB>" == pLink->dbase ) pLink->dbase = m_name;
00250               std::string key = pLink->dbase;
00251               key += ":";
00252               key += pLink->container;
00253               key += "#";
00254               key += pLink->object;
00255               m_linkMap.insert( LinkMap::value_type(key, pLink) );
00256               m_linkVector.push_back( pLink );
00257             }
00258           }
00259           return DbOOMs::DbSuccess;
00260         }
00261       }
00262     }
00263     return DbOOMs::DbError;
00264   }
00265   return DbOOMs::DbSuccess;
00266 }
00267 
00268 DbResult DbDataBase::closeContainers()  const  {
00269   iterator i;
00270   DbDataBase* db = const_cast<DbDataBase*>(this);
00271   m_links.close();
00272   m_types.close();
00273   while ( (i=db->begin()) != db->end() )    {
00274     (*i)->close();
00275   }
00276   if ( m_info )    {
00277     m_info->close(m_mode);
00278     m_info = 0;
00279   }
00280   return DbOOMs::DbSuccess;
00281 }
00282 
00283 // Close database object
00284 DbResult DbDataBase::close()    const  {
00285   closeContainers();
00286   DbDataBase* p = m_fed.find(m_name);
00287   if ( p )   {
00288     m_fed.remove ( p );
00289   }
00290   return DbOOMs::DbSuccess;
00291 }
00292 
00293 // Retrieve the number of all contained object types
00294 long DbDataBase::numAssocEntries()  const   {
00295   return m_linkVector.size();
00296 }
00297 
00298 // Retrieve association link from link container identified by its sequence number
00299 DbResult DbDataBase::assocEntry(long id, dbHandle<DbLink>& lnk, std::string& db, std::string& cnt, std::string& obj)  const   {
00300   if ( id >= 0 && id < long(m_linkVector.size()) && 0 != m_info )   {
00301     Link* link = m_linkVector[id];
00302     db  = ("<localDB>" == link->dbase) ? m_name : link->dbase;
00303     cnt = link->container;
00304     obj = link->object;
00305     lnk = *link;
00306     return DbOOMs::DbSuccess;
00307   }
00308   return DbOOMs::DbError;
00309 }
00310 
00311 //#include <iostream>
00312 // Retrieve association link from link container
00313 DbResult DbDataBase::assocEntry(const dbHandle<DbLink>& which, std::string& db, std::string& cnt, std::string& obj)  const   {
00314   if ( 0 != m_info )    {
00315     if ( m_info->assocEntry(m_linkVector, which, db, cnt, obj) )    {
00316       if ( "<localDB>" == db ) db = m_name;
00317       return DbOOMs::DbSuccess;
00318     }
00319   }
00320   //  const unsigned long* info      = which.genericInfo()->m_info;
00321   //  std::cout << "Error resolving Assoc:" << (void*)info[0] << " " << (void*)info[1] << std::endl;
00322   return DbOOMs::DbError;
00323 }
00324 

Generated at Wed Nov 21 12:22:19 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000