//*-- AUTHOR : Ilse Koenig //*-- Created : 26/11/2004 ////////////////////////////////////////////////////////////////////////////// // FairGenericParOraIo // // Interface class to database Oracle for input/output of generic parameter // containers ////////////////////////////////////////////////////////////////////////////// #include "FairGenericParOraIo.h" #include "FairParGenericSet.h" #include "FairParamList.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(FairGenericParOraIo) #define LOB_BUFSIZE 32512 FairGenericParOraIo::FairGenericParOraIo(FairOraConn* pC) : FairDetParOraIo(pC) { // constructor // sets the name of the I/O class "FairGenericParIo" // gets the pointer to the connection class fName="FairGenericParIo"; } Bool_t FairGenericParOraIo::init(FairParSet* pPar,Int_t* set) { // calls read(FairParGenericSet*,Int_t*) if (pPar->InheritsFrom("FairParGenericSet")) return read((FairParGenericSet*)pPar); Error("FairGenericParOraIo::init(FairParSet*,Int_t*)", "%s does not inherit from FairParGenericSet",pPar->GetName()); return kFALSE; } Int_t FairGenericParOraIo::write(FairParSet* pPar) { // calls write(FairParGenericSet*) Int_t runStart=getRunStart(pPar); if (runStart<=0) return -1; if (pPar->InheritsFrom("FairParGenericSet")) return writeSet((FairParGenericSet*)pPar); Error("FairGenericParOraIo::write(FairParSet*)", "%s does not inherit from FairParGenericSet",pPar->GetName()); return -1; } Bool_t FairGenericParOraIo::read(FairParGenericSet* pPar) { // reads the analysis parameters and fill the container Int_t runStart=getRunStart(pPar); FairParOraSet* 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; FairParamList 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, hdate.to_ansitime(valid_since), hdate.to_ansitime(valid_until), param_value, param_blob, class_version, streamerinfo_id FROM hanal.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; FairParamObj* o=new FairParamObj((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("read(FairParGenericSet*, 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); } if (rc) { setChanged(pPar); cout<GetName()<<" initialized from Oracle"<<'\n'; } else { pPar->setInputVersion(-1,inputNumber); } return rc; errorfound: showSqlError("read(FairParGenericSet*, Int_t*)"); return kFALSE; } Bool_t FairGenericParOraIo::readBlob(FairParamObj* 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 hanal.hgenpar_ana.read_blob(:id,:amount,:loblength,:buffer); END; END-EXEC; pBlob=obj->setLength(loblength); } else { EXEC SQL EXECUTE BEGIN hanal.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 hanal.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 FairGenericParOraIo::createParamVers(FairParGenericSet* 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*)(pConn->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 := hanal.hgenpar_ana.get_context_id( :p_class,:p_context,:p_exp_loc); IF :context_id > 0 THEN :vers := hanal.hgenpar_ana.next_param_vers_load(:p_class); IF :vers > 0 THEN INSERT INTO hanal.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 FairGenericParOraIo::writeSet(FairParGenericSet* pPar) { // write analysis parameters to Oracle Int_t runStart=getRunStart(); if (runStart==-1) { pPar->setChanged(kFALSE); return -1; } 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); FairParamObj* 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=(FairParamObj*)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 hanal.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("writeSet(FairParGenericSet*)"); rollback(); pPar->setChanged(kFALSE); delete paramList; return -1; } Int_t FairGenericParOraIo::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 hanal.hgenpar_ana.add_streamerinfo(:totlen,:amount,:buffer,:rootversion,:id); END; END-EXEC; } else { EXEC SQL EXECUTE DECLARE BEGIN hanal.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 hanal.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(FairParGenericSet*,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 FairGenericParOraIo::readLoadBlob(FairParamObj* 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 hanal.hgenpar_ana.read_load_blob(:id,:amount,:loblength,:buffer); END; END-EXEC; pBlob=obj->setLength(loblength); } else { EXEC SQL EXECUTE BEGIN hanal.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 hanal.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; }