//*-- AUTHOR : Ilse Koenig //*-- Created : 21/01/2010 by Ilse Koenig //_HADES_CLASS_DESCRIPTION ////////////////////////////////////////////////////////////////////////////// // HCondParOra2Io // // Interface class to database Oracle for input/output of parameters derived // from HParCond // ////////////////////////////////////////////////////////////////////////////// #include "hcondparora2io.h" #include "hparcond.h" #include "hparamlist.h" #include "hmagnetpar.h" #include "hora2conn.h" #include "hparora2set.h" #include "TROOT.h" #include "TClass.h" #define SQLCA_STORAGE_CLASS extern #define ORACA_STORAGE_CLASS extern // Oracle communication area #include // Include the SQL Communications Area #include ClassImp(HCondParOra2Io) #define LOB_BUFSIZE 32512 HCondParOra2Io::HCondParOra2Io(HOra2Conn* pC) : HDetParOra2Io(pC) { // constructor // sets the name of the I/O class "HCondParIo" // gets the pointer to the connection class fName="HCondParIo"; } Bool_t HCondParOra2Io::init(HParSet* pPar,Int_t* set) { // calls read-function if (getRunStart(pPar)<=0) { pPar->setInputVersion(-1,inputNumber); return kFALSE; } const Text_t* name=pPar->IsA()->GetName(); if (strcmp(name,"HMagnetPar")==0) return read((HMagnetPar*)pPar); if (pPar->InheritsFrom("HParCond")) return readCond((HParCond*)pPar); Error("HCondParOra2Io::init(HParSet*,Int_t*)", "%s does not inherit from HParCond",name); return kFALSE; } Int_t HCondParOra2Io::write(HParSet* pPar) { // calls write-function if (getRunStart(pPar)<=0) return -1; const Text_t* name=pPar->IsA()->GetName(); if (strcmp(name,"HMagnetPar")==0) { if (strcmp(pPar->getParamContext(),"MagnetCurrentSetValues")==0) { return writeCond((HParCond*)pPar); } else { Error("HCondParOra2Io::write(HParSet*)", "No write interface for HMagnetPar with context %s",pPar->getParamContext()); } } if (pPar->InheritsFrom("HParCond")) return writeCond((HParCond*)pPar); Error("HCondParOra2Io::write(HParSet*)", "%s does not inherit from HParCond",name); return -1; } Bool_t HCondParOra2Io::read(HMagnetPar* pPar) { // Reads the magnet current if (strcmp(pPar->getParamContext(),"MagnetCurrentSetValues")==0 &&strcmp(getExpLocation(),"VIRTUAL")!=0) { return readCond((HParCond*)pPar); } Int_t actualCurrent=pPar->getCurrent(); EXEC SQL BEGIN DECLARE SECTION; int curr; short curr_Ind; EXEC SQL END DECLARE SECTION; EXEC SQL WHENEVER SQLERROR GOTO errorfound; EXEC SQL WHENEVER NOT FOUND GOTO notfound; if (strcmp(getExpLocation(),"VIRTUAL")==0) { EXEC SQL SELECT ROUND(field_factor*3465,0) INTO :curr:curr_Ind FROM hanal2.simul_project WHERE hades_oper.run_query_2.get_date BETWEEN project_begin and project_end; } else { EXEC SQL SELECT mean_current INTO :curr:curr_Ind FROM cryo.runs_magnet_current WHERE run_id = hades_oper.run_query_2.get_run_id; } if (curr_Ind!=-1) { if (curr>=-4&&curr<=4) curr=0; if (curr!=actualCurrent|| (pPar->getInputVersion(1)==-1&&pPar->getInputVersion(2)==-1)) { pPar->setCurrent(curr); setChanged(pPar); cout<GetName()<<" initialized from Oracle"<<'\n'; } return kTRUE; } return kFALSE; errorfound: showSqlError("read(HMagnetPar*)"); notfound: pPar->setInputVersion(-1,inputNumber); return kFALSE; } Bool_t HCondParOra2Io::readCond(HParCond* pPar) { // reads the analysis parameters and fill the container HParOra2Set* pSet=getOraSet(pPar); if (pSet->contextId==-1 || runStart==-1) { pPar->setInputVersion(-1,inputNumber); return kFALSE; } Int_t contVers=pPar->getInputVersion(inputNumber); if (contVers!=-1 && runStart>=pSet->versDate[0] && runStart<=pSet->versDate[1]) return contVers; pSet->clearVersDate(); EXEC SQL BEGIN DECLARE SECTION; typedef struct { unsigned short len; unsigned char arr[2000]; } vraw; EXEC SQL TYPE vraw IS VARRAW(2002); int id; varchar p_name[83]; varchar p_type[85]; vraw p_value; int p_blob; int p_class_vers; int p_streamer; double p_since; double p_until; short p_value_Ind; short p_blob_Ind; short p_class_vers_Ind; short p_streamer_Ind; EXEC SQL END DECLARE SECTION; id=pSet->contextId; HParamList paramList; Bool_t rc=kTRUE; Int_t n=0; EXEC SQL WHENEVER SQLERROR GOTO errorfound; EXEC SQL DECLARE gplana_cursor CURSOR FOR SELECT param_name, param_value_type, hanadate.date_to_number(valid_since), hanadate.date_to_number(valid_until), param_value, param_blob, class_version, streamerinfo_id FROM hanal2.genparam_values_at_histdate WHERE param_context_id = :id; EXEC SQL OPEN gplana_cursor; EXEC SQL WHENEVER NOT FOUND DO break; for (;rc;) { EXEC SQL FETCH gplana_cursor INTO :p_name, :p_type, :p_since, :p_until, :p_value:p_value_Ind, :p_blob:p_blob_Ind, :p_class_vers:p_class_vers_Ind, :p_streamer:p_streamer_Ind; p_name.arr[p_name.len]='\0'; p_type.arr[p_type.len]='\0'; if (p_since>pSet->versDate[0]) pSet->versDate[0]=p_since; if (p_untilversDate[1] || pSet->versDate[1]<0) pSet->versDate[1]=p_until; HParamObj* o=new HParamObj((Char_t*)(p_name.arr)); o->setParamType((Char_t*)(p_type.arr)); if (p_blob_Ind!=-1) { rc=readBlob(o,p_blob,kFALSE); if (rc&&p_streamer_Ind!=-1) { rc=readBlob(o,p_streamer,kTRUE); } if (p_class_vers_Ind!=-1) { o->setClassVersion(p_class_vers); } } else if (p_value_Ind!=-1) { UChar_t* v=new UChar_t[p_value.len]; memcpy(v,p_value.arr,p_value.len); o->setParamValue(v,p_value.len); } else { Error("readCond(HParCond*, Int_t*)", "Data undefined for parameter %s",o->GetName()); rc=kFALSE; } if (rc) { paramList.getList()->Add(o); n++; } } EXEC SQL CLOSE gplana_cursor; if (rc&&n>0) { rc=pPar->getParams(¶mList); } else { rc=kFALSE; } if (rc) { setChanged(pPar); cout<GetName()<<" initialized from Oracle"<<'\n'; } else { pPar->setInputVersion(-1,inputNumber); } return rc; errorfound: showSqlError("readCond(HParCond*, Int_t*)"); return kFALSE; } Bool_t HCondParOra2Io::readBlob(HParamObj* obj,Int_t lobId,Bool_t isStreamerInfo) { EXEC SQL BEGIN DECLARE SECTION; int id; unsigned int loblength; unsigned int amount; unsigned int offset; unsigned char buffer[LOB_BUFSIZE]; varchar root_vers[83]; EXEC SQL VAR buffer IS RAW(LOB_BUFSIZE); EXEC SQL END DECLARE SECTION; id=lobId; amount=LOB_BUFSIZE; UChar_t* pBlob=0; UInt_t amountRead=0; root_vers.len=83; EXEC SQL WHENEVER SQLERROR GOTO notfound; EXEC SQL WHENEVER NOT FOUND GOTO notfound; if (!isStreamerInfo) { EXEC SQL EXECUTE BEGIN hanal2.hgenpar_ana.read_blob(:id,:amount,:loblength,:buffer); END; END-EXEC; pBlob=obj->setLength(loblength); } else { EXEC SQL EXECUTE BEGIN hanal2.hgenpar_ana.read_streamerinfo(:id,:amount,:loblength,:buffer,:root_vers); END; END-EXEC; pBlob=obj->setStreamerInfoSize(loblength); root_vers.arr[root_vers.len]='\0'; if (strcmp(gROOT->GetVersion(),(char*)root_vers.arr)!=0) { Warning("readBlob", "Parameter %s\n ROOT version of streamer info = %s, current ROOT version = %s \n", obj->GetName(),root_vers.arr,gROOT->GetVersion()); } } amountRead=amount; memcpy((UChar_t*)pBlob,buffer,amount); while (amountReadLOB_BUFSIZE) ? LOB_BUFSIZE : loblength ; offset=amountRead+1; EXEC SQL EXECUTE BEGIN hanal2.hgenpar_ana.read_next_buffer(:amount,:offset,:buffer); END; END-EXEC; memcpy((UChar_t*)(&pBlob[amountRead]),buffer,amount); amountRead+=amount; } return kTRUE; notfound: showSqlError("readBlob"); if (isStreamerInfo) Error("readBlob","StreamerInfo Blob %i not read",lobId); else Error("readBlob","Value Blob %i not read",lobId); return kFALSE; } Int_t HCondParOra2Io::createParamVers(HParCond* pPar) { // create analysis parameter version in Oracle // returns version number or -1 if error occurred EXEC SQL BEGIN DECLARE SECTION; char* p_class; char* p_author; char* p_descript; char* p_context; char* p_exp_loc; int vers=-1; int context_id=-1; EXEC SQL END DECLARE SECTION; p_class=(Char_t*)(pPar->IsA()->GetName()); p_author=(Char_t*)(pPar->getAuthor()); p_descript=(Char_t*)(pPar->getDescription()); p_context=(Char_t*)(pPar->getParamContext()); p_exp_loc=(Char_t*)(getExpLocation()); if (strlen(p_author)==0) { Error("createParamVers(...)", "author of parameters not defined"); return -1; } if (strlen(p_descript)==0) { Error("createParamVers(...)", "description of parameters not defined"); return -1; } if (strlen(p_context)==0) { Error("createParamVers(...)", "Purpose of parameters not defined"); return -1; } EXEC SQL WHENEVER SQLERROR GOTO not_found; EXEC SQL WHENEVER NOT FOUND GOTO not_found; EXEC SQL EXECUTE DECLARE BEGIN :context_id := hanal2.hgenpar_ana.get_context_id( :p_class,:p_context,:p_exp_loc); IF :context_id > 0 THEN :vers := hanal2.hgenpar_ana.next_param_vers_load(:p_class); IF :vers > 0 THEN INSERT INTO hanal2.genparam_vers_load (param_vers_load_id,param_context_id,author,description) VALUES (:vers,:context_id,:p_author,:p_descript); END IF; END IF; END; END-EXEC; return vers; not_found: showSqlError("createParamVers(const Char_t*)"); rollback(); return vers; return -1; }; Int_t HCondParOra2Io::writeCond(HParCond* pPar) { // write analysis parameters to Oracle cout<<"--------------- Storage of "<GetName()<<" ---------------\n"; Int_t version=createParamVers(pPar); if (version==-1) return -1; cout<<"****************************************************************\n"; cout<<"*** Version: "<putParams(paramList); TList* pList=paramList->getList(); TIter next(pList); HParamObj* po; Int_t n=0, olen=0; EXEC SQL WHENEVER SQLERROR GOTO not_found; EXEC SQL WHENEVER NOT FOUND GOTO not_found; vers=version; while ((po=(HParamObj*)next())) { strcpy(p_name,po->GetName()); strcpy(p_type,po->getParamType()); p_nvalues=po->getNumParams(); olen=po->getLength(); if (po->isBasicType()) { p_is_basic=1; if (olen<=2000) { p_value.len=olen; memcpy(p_value.val,po->getParamValue(),olen); value_Ind=0; blob_Ind=-1; } else { value_Ind=-1; p_blob=storeBlob(po->getParamValue(),olen,kFALSE); blob_Ind=0; } class_vers_Ind=-1; streamerinfo_Ind=-1; } else { p_is_basic=0; value_Ind=-1; p_blob=storeBlob(po->getParamValue(),po->getLength(),kFALSE); blob_Ind=0; p_class_vers=po->getClassVersion(); class_vers_Ind=0; if (po->getStreamerInfoSize()>0&&po->getStreamerInfo()!=0) { p_streamerinfo=storeBlob(po->getStreamerInfo(),po->getStreamerInfoSize(),kTRUE); streamerinfo_Ind=0; } else { streamerinfo_Ind=-1; } } p_num=++n; EXEC SQL INSERT INTO hanal2.genparam_value_load ( param_vers_load_id,param_name,param_value_type,param_value,blob_id, nvalues,param_num,is_basic_type,class_version,streamerinfo_id ) VALUES ( :vers,:p_name,:p_type,:p_value:value_Ind,:p_blob:blob_Ind, :p_nvalues,:p_num,:p_is_basic,:p_class_vers:class_vers_Ind, :p_streamerinfo:streamerinfo_Ind ); } cout<<"*** Number of parameters: "<GetName()<<" written to Oracle"<setChanged(kFALSE); delete paramList; return version; not_found: showSqlError("writeCond(HParCond*)"); rollback(); pPar->setChanged(kFALSE); delete paramList; return -1; } Int_t HCondParOra2Io::storeBlob(UChar_t* pValue, Int_t pLength,Bool_t isStreamerInfo) { EXEC SQL BEGIN DECLARE SECTION; unsigned char buffer[LOB_BUFSIZE]; int totlen; int amount; int offset; char* rootversion; int id; EXEC SQL VAR buffer IS RAW(LOB_BUFSIZE); EXEC SQL END DECLARE SECTION; offset=1; totlen=pLength; amount= (totlen>LOB_BUFSIZE) ? LOB_BUFSIZE : totlen; memcpy(buffer,pValue,amount); id=-1; Int_t restlen=totlen-amount; EXEC SQL WHENEVER SQLERROR GOTO errorfound; EXEC SQL WHENEVER NOT FOUND GOTO errorfound; if (isStreamerInfo) { rootversion=(char*)(gROOT->GetVersion()); EXEC SQL EXECUTE DECLARE BEGIN hanal2.hgenpar_ana.add_streamerinfo(:totlen,:amount,:buffer,:rootversion,:id); END; END-EXEC; } else { EXEC SQL EXECUTE DECLARE BEGIN hanal2.hgenpar_ana.add_blob(:totlen,:amount,:buffer,:id); END; END-EXEC; } while (restlen>0) { offset+=LOB_BUFSIZE; amount= (restlen>LOB_BUFSIZE) ? LOB_BUFSIZE : restlen; memcpy(buffer,&pValue[offset-1],amount); EXEC SQL EXECUTE DECLARE BEGIN hanal2.hgenpar_ana.append_to_blob(:id,:amount,:offset,:buffer); END; END-EXEC; restlen-=amount; } return id; errorfound: showSqlError("storeBlob"); EXEC SQL ROLLBACK WORK; cout<<"Blob not stored."<setParamType((Char_t*)(p_type.arr)); if (p_blob_Ind!=-1) { rc=readLoadBlob(o,p_blob,kFALSE); if (rc&&p_streamer_Ind!=-1) { rc=readLoadBlob(o,p_streamer,kTRUE); } if (p_class_vers_Ind!=-1) { o->setClassVersion(p_class_vers); } } else if (p_value_Ind!=-1) { UChar_t* v=new UChar_t[p_value.len]; memcpy(v,p_value.arr,p_value.len); o->setParamValue(v,p_value.len); } else { Error("readFromLoadingTable(HParCond*,Int_t*)", "Data undefined for parameter %s",o->GetName()); rc=kFALSE; } if (rc) { paramList.getList()->Add(o); n++; } } EXEC SQL CLOSE gplraw_cursor; if (rc&&n>0) { rc=pPar->getParams(¶mList); } if (rc) { pPar->setInputVersion(version,inputNumber); setChanged(pPar); cout<GetName()<<" initialized from Load Table"<<'\n'; } else { pPar->setInputVersion(-1,inputNumber); } return rc; errorfound: showSqlError("readFromLoadingTable"); return kFALSE; } Bool_t HCondParOra2Io::readLoadBlob(HParamObj* obj,Int_t lobId,Bool_t isStreamerInfo) { // reads the BLOB from the LOAD table EXEC SQL BEGIN DECLARE SECTION; int id; unsigned int loblength; unsigned int amount; unsigned int offset; unsigned char buffer[LOB_BUFSIZE]; varchar root_vers[83]; EXEC SQL VAR buffer IS RAW(LOB_BUFSIZE); EXEC SQL END DECLARE SECTION; id=lobId; amount=LOB_BUFSIZE; UChar_t* pBlob=0; UInt_t amountRead=0; root_vers.len=83; EXEC SQL WHENEVER SQLERROR GOTO notfound; EXEC SQL WHENEVER NOT FOUND GOTO notfound; if (!isStreamerInfo) { EXEC SQL EXECUTE BEGIN hanal2.hgenpar_ana.read_load_blob(:id,:amount,:loblength,:buffer); END; END-EXEC; pBlob=obj->setLength(loblength); } else { EXEC SQL EXECUTE BEGIN hanal2.hgenpar_ana.read_load_streamerinfo(:id,:amount,:loblength,:buffer,:root_vers); END; END-EXEC; pBlob=obj->setStreamerInfoSize(loblength); root_vers.arr[root_vers.len]='\0'; if (strcmp(gROOT->GetVersion(),(char*)root_vers.arr)!=0) { Warning("readLoadBlob", "Parameter %s\n ROOT version of streamer info = %s, current ROOT version = %s \n", obj->GetName(),root_vers.arr,gROOT->GetVersion()); } } amountRead=amount; memcpy((UChar_t*)pBlob,buffer,amount); while (amountReadLOB_BUFSIZE) ? LOB_BUFSIZE : loblength ; offset=amountRead+1; EXEC SQL EXECUTE BEGIN hanal2.hgenpar_ana.read_next_buffer(:amount,:offset,:buffer); END; END-EXEC; memcpy((UChar_t*)(&pBlob[amountRead]),buffer,amount); amountRead+=amount; } return kTRUE; notfound: showSqlError("readLoadBlob"); Error("readLoadBlob","Blob %i not read",lobId); return kFALSE; }