00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #define DBCNV_DBCNVSVC_CPP
00019
00020
00021
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
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
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
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
00147
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& ) 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
00330 IOODataBase* DbCnvSvc::implementation() {
00331 return m_dbase;
00332 }
00333