//*-- AUTHOR : Ilse Koenig //*-- Created : 10/06/2010 by Ilse Koenig //_HADES_CLASS_DESCRIPTION ///////////////////////////////////////////////////////////// // HGeomOra2Conn // // Connection class to database Oracle for geometry // (uses the Oracle C/C++ precompiler) // ///////////////////////////////////////////////////////////// using namespace std; #include "hgeomora2conn.h" #include "TRandom.h" #include #include #include #include #include #include #include #include #include #include #include // Oracle communication area #include // SQL Communications Area #include ClassImp(HGeomOra2Conn) HGeomOra2Conn::HGeomOra2Conn() { // default constructor // defines default values for user ("hades_ana") and the database // ("db-hades", the HADES Oracle database at GSI) // User "hades" has Read-only access to the Oracle tables. // The connection to Oracle is not opened! strcpy(dbName,"db-hades"); strcpy(userName,"hades_ana"); isConnected=kFALSE; actRunId=-1; runStart=-1; expLocation[0]='\0'; historyDate[0]='\0'; needsServerCheck=kTRUE; writable=kFALSE; } HGeomOra2Conn::~HGeomOra2Conn() { // default destructor (closes connection) close(); } Bool_t HGeomOra2Conn::open() { // opens default connection with readonly access Char_t* password = new Char_t[20]; strcpy(password,"hades"); Bool_t rc=openConnection(password); writable=kFALSE; if (!rc) close(); return rc; } Bool_t HGeomOra2Conn::open(const Char_t *uName) { // opens connection to database Hades for user given by name // asks for password strcpy(userName,uName); Char_t* password=getPassword(); Bool_t rc=openConnection(password); writable=kTRUE; if (!rc) close(); return rc; } Bool_t HGeomOra2Conn::open(const Char_t *dbN,const Char_t *uN) { // opens connection to database with name dbName for user given by name // asks for password strcpy(dbName,dbN); strcpy(userName,uN); Char_t* password=getPassword(); Bool_t rc=openConnection(password); writable=kTRUE; if (!rc) close(); return rc; } void HGeomOra2Conn::close() { // disconnects from ORACLE // A transaction will be automatically rolled back, // that means changes in the database are not stored // without an explicit COMMIT actRunId=-1; runStart=-1; expLocation[0]='\0'; historyDate[0]='\0'; EXEC SQL WHENEVER SQLERROR DO showSqlError("ORACLE error in HGeomOra2Conn::close():"); if (isConnected) { EXEC SQL ROLLBACK RELEASE; isConnected=kFALSE; cout<<"connection to Oracle closed"< "; Int_t n=scanf("%[^\n]%*c",passwd); if(n==0)cout<<"no password found!"< "; Bool_t res=fgets(buf, 20, stdin); if(!res)cout<<"could not retrieve next buffer!"<0) return kTRUE; else return kFALSE; errorfound: showSqlError("setSimulRefRun(const Char_t*"); return kFALSE; notfound: Error("setSimulRefRun(const Char_t*)", "No such simulation reference run %s",runName); return kFALSE; } Bool_t HGeomOra2Conn::setRunId(Int_t id) { // Sets the run id and the run start if (!isConnected) return kFALSE; simulRefRun=""; getRunStart(id); if (runStart==-1) return kFALSE; else return kTRUE; } Int_t HGeomOra2Conn::checkServerLoad() { EXEC SQL BEGIN DECLARE SECTION; int retval; EXEC SQL END DECLARE SECTION; EXEC SQL WHENEVER SQLERROR GOTO notfound; EXEC SQL EXECUTE BEGIN :retval := hanal.check_analysis_sessions; END; END-EXEC; return retval; notfound: showSqlError("checkServerLoad"); return -1; } Int_t HGeomOra2Conn::getRunStart(Int_t id) { // Compares the run id with the last used actRunId for fetching data. // If they are different, the run start time (converted to ansi C time) is // read from Oracle and stored together with the run id in the data members // run_id and runStart if (id==actRunId && runStart>0) return runStart; if (needsServerCheck) { Int_t l=0; UInt_t nTotWait=0; l=checkServerLoad(); while (l==0&&nTotWait<86400000) { UInt_t nWait=10000+gRandom->Integer(20000); nTotWait+=nWait; cout<<"Oracle server busy, retry in "<0) needsServerCheck=kFALSE; else return -1; } if (strlen(historyDate)==0) setParamRelease(id); actRunId=id; runStart=-1; EXEC SQL BEGIN DECLARE SECTION; int ri; int rs; varchar exp_loc[30]; EXEC SQL END DECLARE SECTION; EXEC SQL WHENEVER SQLERROR GOTO notfound; ri = actRunId; exp_loc.len=30; EXEC SQL EXECUTE BEGIN hades_oper.run_query_2.get_run_start(:ri,:rs,:exp_loc); END; END-EXEC; if (ri==actRunId) { runStart=rs; exp_loc.arr[exp_loc.len]='\0'; if (strlen(expLocation)==0) strcpy(expLocation,(Char_t*)exp_loc.arr); else { if (strcmp(expLocation,(Char_t*)exp_loc.arr)!=0) { Error("getRunStart(Int_t)", "\nA switch from beamtime runs to simulations runs and vice versa is not " "possible\nwithout the close and reopen of the Oracle connection!\n\n"); runStart=-1; } } return runStart; } notfound: Error("getRunStart(Int_t)","Run not found!\n\n"); return -1; } Bool_t HGeomOra2Conn::setHistoryDate(const Char_t* dateString) { // Sets the date to retrieve historic data // Returns kFALSE when the date string cannot be converted to a valid date. if (!isConnected) return kFALSE; if (strstr(dateString,"_")!=NULL) { return setParamRelease(dateString); } EXEC SQL BEGIN DECLARE SECTION; char* d; char rd[21]; EXEC SQL END DECLARE SECTION; EXEC SQL WHENEVER SQLERROR GOTO notfound; d=(Char_t*)dateString; rd[0]='\0'; EXEC SQL EXECUTE BEGIN hades_oper.run_query_2.set_history_date(:d); :rd := to_char(hades_oper.run_query_2.get_history_date,hwww.c_datemask); END; END-EXEC; rd[20]='\0'; strcpy(historyDate,rd); cout<<"*************************************************************\n"; cout<<" Oracle history date: "<