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

DbCnvSvc.cpp

Go to the documentation of this file.
00001 //====================================================================
00002 //      DbCnvSvc implementation
00003 //--------------------------------------------------------------------
00004 //
00005 //      Package    : System ( The LHCb Offline System)
00006 //
00007 //  Description: Implementation of the Db data service
00008 //
00009 //      Author     : M.Frank
00010 //  History    :
00011 // +---------+----------------------------------------------+---------
00012 // |    Date |                 Comment                      | Who     
00013 // +---------+----------------------------------------------+---------
00014 // | 29/10/98| Initial version                              | MF
00015 // +---------+----------------------------------------------+---------
00016 //
00017 //====================================================================
00018 #define DBCNV_DBCNVSVC_CPP
00019 // $Header: /nfs/slac/g/glast/ground/cvs/GaudiDb/src/Services/DbCnvSvc.cpp,v 1.1.1.1 2001/04/18 21:13:35 tlindner Exp $
00020 
00021 // Framework include files
00022 #include "GaudiKernel/SmartIF.h"
00023 #include "GaudiKernel/SvcFactory.h"
00024 #include "GaudiKernel/DataObject.h"
00025 #include "GaudiKernel/IFactory.h"
00026 #include "GaudiKernel/IObjManager.h"
00027 #include "GaudiKernel/ICnvManager.h"
00028 #include "GaudiKernel/ISvcLocator.h"
00029 #include "GaudiKernel/IMessageSvc.h"
00030 #include "GaudiKernel/IOpaqueAddress.h"
00031 #include "GaudiKernel/IDataDirectory.h"
00032 #include "GaudiKernel/IDataProviderSvc.h"
00033 #include "GaudiKernel/IDataManagerSvc.h"
00034 #include "GaudiKernel/PropertyMgr.h"
00035 #include "GaudiKernel/MsgStream.h"
00036 
00037 // Db data service include files
00038 #include "GaudiDb/IOODataBase.h"
00039 #include "GaudiDb/DbBaseConverter.h"
00040 #include "GaudiDb/DbCnvFactory.h"
00041 #include "GaudiDb/DbIter.h"
00042 #include "GaudiDb/DbAddress.h"
00043 #include "DbCnvSvc.h"
00044 
00045 #ifdef WIN32
00046 #  define strncasecmp _strnicmp
00047 #else
00048 #  include <strings.h>
00049 #endif
00050 
00051 static const SvcFactory<DbCnvSvc> s_DbCnvSvcFactory;
00052 const ISvcFactory& DbCnvSvcFactory = s_DbCnvSvcFactory;
00053 
00055 DbCnvSvc::DbCnvSvc(const std::string& nam, ISvcLocator* svc)
00056 : ConversionSvc( nam, svc, DBOOMS_StorageType), 
00057   m_dbase(0),
00058   m_session(DBOOMS_StorageType), 
00059   m_federation(DBOOMS_StorageType),
00060   m_output(DBOOMS_StorageType)
00061 {
00062   // Set address factory for my type
00063   setAddressFactory(this);
00064         declareProperty("Server",   m_serverConnect  = "");
00065         declareProperty("FddbName", m_fddbName       = "");
00066         declareProperty("DbType",   m_implementation = "Unknown");
00067 }
00068 
00070 DbCnvSvc::~DbCnvSvc()    {
00071 }
00072 
00074 StatusCode DbCnvSvc::queryInterface(const IID& riid, void** ppvInterface)  {
00075   if ( IID_IDataBaseMgr == riid )  {
00076     *ppvInterface = (IDataBaseMgr*)this;
00077   }
00078   else  {
00079     // Interface is not directly availible: try out a base class
00080     return ConversionSvc::queryInterface(riid, ppvInterface);
00081   }
00082   addRef();
00083   return StatusCode::SUCCESS;
00084 }
00085 
00087 const ICnvFactory* DbCnvSvc::findCnvFactory(const CLID& wanted)  {
00088   ICnvManager* manager = cnvManager();
00089   if ( 0 != manager )   {
00090     const ICnvFactory* fac = manager->factory(DBOOMS_StorageType, wanted);
00091     return fac;
00092   }
00093   return 0;
00094 }
00095 
00097 IConverter* DbCnvSvc::createConverter(const ICnvFactory& fac)   {
00098   IConverter* cnv = 0;
00099   if ( m_dbase )    {
00100     IDbCnvFactory* pFac = 0;
00101     ICnvFactory* p = const_cast<ICnvFactory*>(&fac);
00102     StatusCode status = p->queryInterface(IID_IDbCnvFactory, (void**)&pFac);
00103     if ( status.isSuccess() )   {
00104       cnv = pFac->instantiate(m_dbase, serviceLocator());
00105       pFac->release();
00106     }
00107   }
00108   return cnv;
00109 }
00110 
00111 StatusCode DbCnvSvc::requestImplementation(IOODataBase*& implementation)    {
00112   SmartIF<IObjManager> objManager(IID_IObjManager,serviceLocator());
00113   implementation = 0;
00114   if ( objManager.isValid() )   {
00115     IObjManager::ObjIterator i, stop;
00116     std::string needed_impl = m_implementation;
00117     const char* imp = m_implementation.c_str();
00118     long len = strlen(imp);
00119     if ( ::strncasecmp(imp,"MS Access", len) == 0 )
00120       needed_impl = "OdbcDb::OODataBase";
00121     else if ( ::strncasecmp(imp,"Microsoft Access", strlen("Microsoft Access")) == 0 )
00122       needed_impl = "OdbcDb::OODataBase";
00123     else if ( ::strncasecmp(imp,"SQL Server", len) == 0 )
00124       needed_impl = "OdbcDb::OODataBase";
00125     else if ( ::strncasecmp(imp,"Microsoft ODBC for Oracle", len) == 0 )
00126       needed_impl = "OdbcDb::OODataBase";
00127     else if ( ::strncasecmp(imp,"Oracle ODBC", strlen("Oracle ODBC")) == 0 )
00128       needed_impl = "OdbcDb::OODataBase";
00129     else if ( ::strncasecmp(imp,"Oracle OCI", strlen("Oracle OCI")) == 0 )
00130       needed_impl = "OdbcDb::OODataBase";
00131     else if ( ::strncasecmp(imp,"MySQL", len) == 0 )
00132       needed_impl = "OdbcDb::OODataBase";
00133     else if ( ::strncasecmp(imp,"ROOT", len) == 0 )
00134       needed_impl = "RootDb::OODataBase";
00135     else if ( ::strncasecmp(imp,"OBJY", len) == 0 )
00136       needed_impl = "ObjyDb::OODataBase";
00137     else if ( ::strncasecmp(imp,"OBJECTI", 7) == 0 )
00138       needed_impl = "ObjyDb::OODataBase";
00139 
00140     for ( i = objManager->objBegin(), stop = objManager->objEnd(); i != stop; i++ )    {
00141       IFactory* f = const_cast<IFactory*>(*i);
00142       if ( f->ident() == needed_impl )    {
00143         IInterface *iface = f->instantiate(serviceLocator());
00144         SmartIF<IOODataBase> db(IID_IOODataBase, iface);
00145         if ( db.isValid() )    {
00146           // Set default properties for known implementations
00147           // These properties can be over written by the joboptions.
00148           SmartIF<IProperty> iprop(IID_IProperty,db);
00149           if ( iprop.isValid() )   {
00150             iprop->setProperty(StringProperty("Driver",m_implementation));
00151             iprop->setProperty(StringProperty("Server",m_serverConnect));
00152             if ( ::strncasecmp(imp,"MS Access", len) == 0 )    {
00153               iprop->setProperty(StringProperty("Driver","Microsoft Access Driver (*.mdb)"));
00154               iprop->setProperty(StringProperty("Server",""));
00155             }
00156             else if ( ::strncasecmp(imp,"Microsoft Access", strlen("Microsoft Access")) == 0 )    {
00157               iprop->setProperty(StringProperty("Driver","Microsoft Access Driver (*.mdb)"));
00158               iprop->setProperty(StringProperty("Server",""));
00159             }
00160             else if ( ::strncasecmp(imp,"SQL Server", len) == 0 )    {
00161               iprop->setProperty(StringProperty("Server","SERVER=(local)"));
00162             }
00163             else if ( ::strncasecmp(imp,"Microsoft ODBC for Oracle", len) == 0 )   {
00164             }
00165             else if ( ::strncasecmp(imp,"Oracle ODBC", strlen("Oracle ODBC")) == 0 )    {
00166               iprop->setProperty(StringProperty("Driver","Oracle ODBC Driver"));
00167             }
00168             else if ( ::strncasecmp(imp,"Oracle OCI", strlen("Oracle OCI")) == 0 )    {
00169               iprop->setProperty(StringProperty("Driver","Oracle OCI Driver"));
00170               iprop->setProperty(StringProperty("SqlDll","OCI"));
00171             }
00172             else if ( ::strncasecmp(imp,"MySQL", len) == 0 )   {
00173               iprop->setProperty(StringProperty("Server","SERVER=localhost"));
00174               iprop->setProperty(StringProperty("SqlDll","myodbc"));
00175             }
00176             else if ( ::strncasecmp(imp,"ROOT", len) == 0 )    {
00177             }
00178             else if ( ::strncasecmp(imp,"OBJY", len) == 0 )    {
00179             }
00180             else if ( ::strncasecmp(imp,"OBJECTI", 7) == 0 )    {
00181             }
00182             implementation = db.pRef();
00183             implementation->addRef();
00184             return StatusCode::SUCCESS;
00185           }
00186         }
00187       }
00188     }
00189   }
00190   return StatusCode::FAILURE;
00191 }
00192 
00194 StatusCode DbCnvSvc::initialize()    {
00195   StatusCode status = ConversionSvc::initialize();
00196   MsgStream log(messageService(), name());
00197   if ( status.isSuccess() )   {
00198     status = setProperties();
00199     if ( status.isSuccess() )   {
00200       if ( 0 == m_dbase )   {
00201         status = requestImplementation(m_dbase);
00202         if ( status.isSuccess() )   {
00203           status = m_dbase->initialize(name());
00204           if ( status.isSuccess() )   {
00205             m_type       = m_dbase->type();
00206             m_session    = dbHandle<DbSession>   (repSvcType());
00207             m_federation = dbHandle<DbFederation>(repSvcType());
00208             m_output     = dbHandle<DbDataBase>  (repSvcType());
00209             if ( m_fddbName.length() == 0 ) m_fddbName = m_dbase->driver();
00210             if ( m_session.open(m_dbase, messageService(), DbOOMs::UPDATE) )    {
00211               if ( m_federation.open(m_session, m_fddbName, DbOOMs::READ) )   {
00212                 return StatusCode::SUCCESS;
00213               }
00214               else    {
00215                 log << MSG::ERROR << "Cannot open Federation " << m_fddbName << endreq;
00216               }
00217             }
00218             else    {
00219               log << MSG::ERROR << "Cannot initialize DB implementation." << endreq;
00220             }
00221           }
00222           else    {
00223             log << MSG::ERROR << "Cannot open DB session " << endreq;
00224           }
00225         }
00226         else  {
00227           log << MSG::ERROR << "DB implementation '" << m_implementation << "' is not accessible " << endreq;
00228         }
00229       }
00230       else    {
00231         log << MSG::ERROR << "Cannot initialize DB implementation" << endreq;
00232       }
00233       status = StatusCode::FAILURE;
00234     }
00235   }
00236   return status;
00237 }
00238 
00240 StatusCode DbCnvSvc::finalize()    {
00241   MsgStream log(messageService(), name());
00242   m_output.close();
00243   m_federation.close();
00244   m_session.close();
00245   if ( m_dbase )    {
00246     m_dbase->release();
00247     m_dbase = 0;
00248   }
00249   log << MSG::DEBUG << "Number of remaining DbObject instances:" << DbObject::numInstances() << endreq;
00250   return ConversionSvc::finalize();
00251 }
00252 
00254 StatusCode DbCnvSvc::connectOutput(const std::string& fname)   {
00255   if ( !m_output.isValid() || fname != m_output.name() )   {
00256     if ( m_federation.isValid() )   {
00257       if ( !(m_federation.openMode()&DbOOMs::CREATE) &&
00258            !(m_federation.openMode()&DbOOMs::UPDATE) )    {
00259         m_federation.close();
00260         if ( !m_federation.open(m_session, m_fddbName, DbOOMs::UPDATE) )   {
00261           return StatusCode::FAILURE;
00262         }
00263       }
00264       if ( !m_federation.existsDbase(fname) )    {
00265         m_output.open(m_federation, fname, DbOOMs::CREATE);
00266       }
00267       else    {
00268         m_output.open(m_federation, fname, DbOOMs::UPDATE);
00269       }
00270     }
00271     else    {
00272       dbHandle<DbDataBase> hdl(repSvcType());
00273       m_output = hdl;
00274     }
00275   }
00276   return m_output.isValid() ? StatusCode::SUCCESS : StatusCode::FAILURE;
00277 }
00278 
00280 dbIter<DbObject>* DbCnvSvc::createIterator(const std::string& dbName, const std::string& cntName, DbAccessMode mode)   {
00281   unsigned char dbType = repSvcType();
00282   dbHandle<DbDataBase> dbH(dbType);
00283   if ( m_federation.isValid() )   {
00284     if ( dbH.open(m_federation, dbName, mode) )   {
00285       dbHandle<DbContainer> cntH(dbType);
00286       DbResult result = DbOOMs::DbError;
00287       if ( mode == DbOOMs::READ )   {
00288         result = cntH.open(dbH, cntName);
00289       }
00290       else  {
00291         const DbTypeInfo* typ = dbH.objType(cntName);
00292         if ( 0 != typ )   {
00293           result = cntH.open(dbH, cntName, *typ, mode);
00294         }
00295       }
00296       if ( result )   {
00297         dbIter<DbObject>* iter = new dbIter<DbObject>();
00298         iter->scan(cntH);
00299         iter->next();
00300         return iter;
00301       }
00302     }
00303   }
00304   return 0;
00305 }
00306 
00308 IOpaqueAddress* DbCnvSvc::instantiate(const GenericLinkBase& link,
00309                                       const std::string& dbName, 
00310                                       const std::string& containerName,
00311                                       const std::string& /* objectName */ ) const    {
00312   dbHandle<DbDataBase> dbH(repSvcType());
00313   if ( dbH.open(m_federation, dbName) )   {
00314     dbHandle<DbContainer> cntH(repSvcType());
00315     const DbTypeInfo* info = dbH.objType(containerName);
00316     if ( 0 != info )    {
00317       if ( cntH.open(dbH, containerName, *info, dbH.openMode() ) )   {
00318         if ( link.svcType() == repSvcType() )    {
00319           dbHandle<DbLink> linkH(link);
00320           DbAddress* pAdd = new DbAddress(cntH, linkH);
00321           return pAdd;
00322         }
00323       }
00324     }
00325   }
00326   return 0;
00327 }
00328 
00329 // Get access to the underlying database implementation
00330 IOODataBase* DbCnvSvc::implementation()   {
00331   return m_dbase;
00332 }
00333 

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