00001 #include "DatabaseSvc.h"
00002
00003
00004 #include "GaudiKernel/MsgStream.h"
00005 #include "GaudiKernel/Service.h"
00006 #include <string>
00007
00008 #include "TROOT.h"
00009 #include "TPython.h"
00010
00011
00012 DatabaseSvc::DatabaseSvc( const std::string& name, ISvcLocator* sl ) : Service( name, sl )
00013 {
00014
00015 declareProperty("dbHost",m_dbHost="dyb1.ihep.ac.cn",
00016 "The host of offline database");
00017 declareProperty("dbName",m_dbName="offline_db");
00018 declareProperty("dbUser",m_dbUser="");
00019 declareProperty("dbPswd",m_dbPswd="");
00020
00021 }
00022
00023 DatabaseSvc::~DatabaseSvc()
00024 {
00025 if (m_conn)
00026 {
00027 mysql_close(m_conn);
00028 delete m_conn;
00029 m_conn = NULL;
00030 }
00031 }
00032
00033 StatusCode
00034 DatabaseSvc::queryInterface( const InterfaceID& riid, void** ppvInterface )
00035 {
00036 if ( IID_IDatabaseSvc == riid ) {
00037 *ppvInterface = static_cast< IDatabaseSvc* >( this );
00038 return StatusCode::SUCCESS;
00039 } else {
00040 return Service::queryInterface( riid, ppvInterface );
00041 }
00042 }
00043
00044
00045
00046 StatusCode
00047 DatabaseSvc::initialize()
00048 {
00049
00050
00051 StatusCode status = this->Service::initialize();
00052 if ( !status.isSuccess() ) return status;
00053
00054
00055 MsgStream log( msgSvc(), name() );
00056 log << MSG::INFO
00057 << "DatabaseSvc specific initialization starting" << endreq;
00058
00059
00060 status = setProperties();
00061 if ( !status.isSuccess() ) {
00062 log << MSG::ERROR << "Could not set jobOptions properties" << endreq;
00063 return status;
00064 }
00065 log << MSG::DEBUG << "Properties were read from jobOptions" << endreq;
00066
00067
00068 const char* dbconf = getenv("DBCONF");
00069 if( dbconf ){
00070 log << MSG::INFO << "Using DybPython.DBConf.Export to setup envvars for DBCONF : \"" << dbconf << "\"" << endreq ;
00071 TPython::Exec( "from DybPython import DBConf ; DBConf.Export() " );
00072 }
00073
00074
00075 char* host = getenv("DYB_DB_HOST");
00076 if (host){
00077 m_dbHost = std::string(host);
00078 }
00079 else{
00080 log << MSG::WARNING << "Enviroment variable ${DYB_DB_HOST} is not set."<<endreq;
00081 log << MSG::WARNING << "Use the default database host: "<< m_dbHost << endreq;
00082 }
00083 log << MSG::DEBUG << "Environment variable ${DYB_DB_HOST}: "<<m_dbHost << endreq;
00084
00085 char* name = getenv("DYB_DB_NAME");
00086 if (name){
00087 m_dbName = std::string(name);
00088 }
00089 else{
00090 log << MSG::WARNING << "Enviroment variable ${DYB_DB_NAME} is not set."<<endreq;
00091 log << MSG::WARNING << "Use the default database name: "<< m_dbName << endreq;
00092 }
00093 log << MSG::DEBUG << "Environment variable ${DYB_DB_HOST}: "<<m_dbName << endreq;
00094
00095 char* user = getenv("DYB_DB_USER");
00096 if (user){
00097 m_dbUser = std::string(user);
00098 }
00099 else{
00100 log << MSG::ERROR << "Enviroment variable ${DYB_DB_USER} is not set."<<endreq;
00101 }
00102
00103 char* pswd = getenv("DYB_DB_PSWD");
00104 if (pswd){
00105 m_dbPswd = std::string(pswd);
00106 }
00107 else{
00108 log << MSG::ERROR << "Enviroment variable ${DYB_DB_PSWD} is not set."<<endreq;
00109 }
00110
00111
00112 if( dbconf ){
00113 setenv("DYB_DB_PSWD","dbconf_censored",1);
00114 }
00115
00116
00117
00118 try {
00119 m_conn = new MYSQL;
00120 mysql_init(m_conn);
00121 MYSQL* ret = mysql_real_connect(m_conn, m_dbHost.c_str(), m_dbUser.c_str(), m_dbPswd.c_str(),m_dbName.c_str(),3306,NULL,0);
00122 if (ret != 0) {
00123 log << MSG::INFO << "Connected to MySQL database: " << m_dbHost
00124 <<"/"<<m_dbName<<endreq;
00125 }
00126 else {
00127 throw (char*)mysql_error(m_conn);
00128 }
00129
00130 } catch ( std::exception &e ) {
00131
00132 log << MSG::FATAL << "Error in MySQL session initialization!" << endreq;
00133 log << MSG::FATAL << "*** std::exception caught:" << endreq;
00134 log << MSG::FATAL << "*** error message:" << e.what() << endreq;
00135 return StatusCode::FAILURE;
00136
00137 } catch (char* mess) {
00138
00139 log << MSG::FATAL << "Exception in MySQL session initialization caught: " << mess << endreq;
00140 log << MSG::FATAL << "Check jobOptions properties dbHost, dbUser, dbPswd" << endreq;
00141
00142 return StatusCode::FAILURE;
00143 }
00144 catch (...) {
00145 log << MSG::FATAL << "UNKNOWN exception in MySQL session initialization caught" << endreq;
00146 return StatusCode::FAILURE;
00147 }
00148
00149
00150 log << MSG::INFO << "DatabaseSvc initialized successfully" << endreq;
00151 return StatusCode::SUCCESS;
00152 }
00153
00154
00155
00156 StatusCode
00157 DatabaseSvc::finalize()
00158 {
00159 MsgStream log( msgSvc(), name() );
00160
00161
00162 StatusCode status = Service::finalize();
00163 if ( ! status.isSuccess() ) {
00164 log << MSG::ERROR << "Unable to finalize the Service" << endreq;
00165 return status;
00166 }
00167
00168 mysql_close(m_conn);
00169 delete m_conn;
00170 m_conn = NULL;
00171
00172
00173 log << MSG::INFO << "DatabaseSvc finalized successfully" << endreq;
00174 return StatusCode::SUCCESS;
00175 }
00176
00177
00178 int DatabaseSvc::query(const std::string& dbName, const std::string& sql, DatabaseRecordVector& res)
00179 {
00180 MsgStream log( msgSvc(), name() );
00181
00182 log << MSG::DEBUG << "Query database " << dbName << " SQL: " << sql << endreq;
00183
00184
00185 res.clear();
00186
00187 try{
00188
00189 if(m_dbName != dbName)
00190 {
00191 m_dbName = dbName;
00192 int ret = mysql_select_db(m_conn, m_dbName.c_str());
00193 if ( ret != 0 )
00194 throw std::exception();
00195 }
00196
00197 int status = mysql_real_query(m_conn, sql.c_str(), sql.length());
00198 if (status)
00199 {
00200 log << MSG::ERROR << "Query " << sql << " failed: " << mysql_error(m_conn) << endreq;
00201 }
00202
00203 MYSQL_RES* result = mysql_store_result(m_conn);
00204
00205 if(result)
00206 {
00207 int num_fields = mysql_num_fields(result);
00208
00209 if(num_fields>0)
00210 {
00211 MYSQL_FIELD *fields;
00212 fields = mysql_fetch_fields(result);
00213
00214 MYSQL_ROW row;
00215 while ((row = mysql_fetch_row(result)))
00216 {
00217 DatabaseRecord dbrec;
00218 int field;
00219 for(field = 0; field<num_fields; field++)
00220 {
00221 if(row[field]!=0)
00222 {
00223 dbrec[fields[field].name]=row[field];
00224 }
00225 else
00226 {
00227 dbrec[fields[field].name]="NULL";
00228 }
00229 }
00230 res.push_back(dbrec);
00231 }
00232 }
00233 mysql_free_result(result);
00234 return res.size();
00235 }
00236 }
00237 catch(...)
00238 {
00239 log << MSG::ERROR << "Could not execute query: " << mysql_error(m_conn) << endreq;
00240 return 0;
00241 }
00242
00243 return 0;
00244 }
00245