//*-- AUTHOR : Ilse Koenig //*-- Created : 26/11/2004 ////////////////////////////////////////////////////////////////////////////// // CbmGenericParOraIo // // Interface class to database Oracle for input/output of generic parameter // containers ////////////////////////////////////////////////////////////////////////////// #include "CbmGenericParOraIo.h" #include "CbmParGenericSet.h" #include "CbmParamList.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(CbmGenericParOraIo) #define NMAX_PARAM 200 #define LOB_BUFSIZE 32512 CbmGenericParOraIo::CbmGenericParOraIo(CbmOraConn* pC) : CbmDetParOraIo(pC) { // constructor // sets the name of the I/O class "CbmGenericParIo" // gets the pointer to the connection class fName="CbmGenericParIo"; } Bool_t CbmGenericParOraIo::init(CbmParSet* pPar,Int_t* set) { // calls read(CbmParGenericSet*,Int_t*) if (pPar->InheritsFrom("CbmParGenericSet")) return read((CbmParGenericSet*)pPar); Error("CbmGenericParOraIo::init(CbmParSet*,Int_t*)", "%s does not inherit from CbmParGenericSet",pPar->GetName()); return kFALSE; } Int_t CbmGenericParOraIo::write(CbmParSet* pPar) { // calls write(CbmParGenericSet*) Int_t runStart=getRunStart(pPar); if (runStart<=0) return -1; if (pPar->InheritsFrom("CbmParGenericSet")) return writeSet((CbmParGenericSet*)pPar); Error("CbmGenericParOraIo::write(CbmParSet*)", "%s does not inherit from CbmParGenericSet",pPar->GetName()); return -1; } Bool_t CbmGenericParOraIo::read(CbmParGenericSet* pPar) { // reads the parameters and fills the container Int_t runStart=getRunStart(pPar); CbmParOraSet* 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; int id; struct { varchar p_name[NMAX_PARAM][81]; varchar p_value[NMAX_PARAM][4001]; varchar p_type[NMAX_PARAM][81]; int p_is_binary[NMAX_PARAM]; int p_is_basic[NMAX_PARAM]; int p_class_vers[NMAX_PARAM]; int p_num[NMAX_PARAM]; double p_since[NMAX_PARAM]; double p_until[NMAX_PARAM]; } ana; struct { short p_name_Ind[NMAX_PARAM]; short p_value_Ind[NMAX_PARAM]; short p_type_Ind[NMAX_PARAM]; short p_is_binary_Ind[NMAX_PARAM]; short p_is_basic_Ind[NMAX_PARAM]; short p_class_vers_Ind[NMAX_PARAM]; short p_num_Ind[NMAX_PARAM]; short p_since_Ind[NMAX_PARAM]; short p_until_Ind[NMAX_PARAM]; } ana_Ind; EXEC SQL END DECLARE SECTION; EXEC SQL WHENEVER SQLERROR DO showSqlError("read(CbmParGenericSet*)"); EXEC SQL WHENEVER NOT FOUND CONTINUE; id=pSet->contextId; EXEC SQL SELECT par_name, par_value, par_value_type, is_binary, is_basic_type, class_version, n_values, cbmdate.to_ansitime(valid_since), cbmdate.to_ansitime(valid_until) INTO :ana INDICATOR :ana_Ind FROM cbm_ana.param_values_at_histdate_ext WHERE param_context_id = :id ORDER BY par_value_id; CbmParamList* paramList = new CbmParamList; TList* blobList=new TList; for(Int_t i=0;ipSet->versDate[0]) pSet->versDate[0]=ana.p_since[i]; if (ana.p_until[i]versDate[1] || pSet->versDate[1]<0) pSet->versDate[1]=ana.p_until[i]; if (ana.p_is_binary[i]==0) paramList->add((char*)(ana.p_name[i].arr),(char*)(ana.p_value[i].arr), ana.p_type[i].arr[0],ana.p_num[i]); else { CbmParamBinObj* o=new CbmParamBinObj; o->SetName((char*)(ana.p_name[i].arr)); o->setParamType((char*)(ana.p_type[i].arr)); if (ana.p_is_basic[i]==0) o->setClassVersion(ana.p_class_vers[i]); paramList->getBinaryList()->Add(o); Int_t lobId; sscanf((char*)(ana.p_value[i].arr),"%i",&lobId); CbmParOraBlob* ob=new CbmParOraBlob(o,lobId); blobList->Add(ob); } } } TIter next(blobList); CbmParOraBlob* b; Bool_t rc; if (sqlca.sqlerrd[2]==0) rc=kFALSE; else rc=kTRUE; while ((b=(CbmParOraBlob*)next())!=0 && rc) { rc=readBlob(b->binaryParam,b->blobId); } if (rc) rc=pPar->getParams(paramList); else pPar->setInputVersion(-1,inputNumber); blobList->Delete(); delete blobList; delete paramList; if (rc==kTRUE) { setChanged(pPar); cout<GetName()<<" initialized from Oracle"<<'\n'; } return rc; } Bool_t CbmGenericParOraIo::readBlob(CbmParamBinObj* obj,Int_t lobId) { EXEC SQL BEGIN DECLARE SECTION; int id; unsigned int loblength; unsigned int amount; unsigned int offset; unsigned char buffer[LOB_BUFSIZE]; EXEC SQL VAR buffer IS RAW(LOB_BUFSIZE); EXEC SQL END DECLARE SECTION; id=lobId; amount=LOB_BUFSIZE; UChar_t* paramValue=0; UInt_t amountRead=0; EXEC SQL WHENEVER SQLERROR GOTO notfound; EXEC SQL WHENEVER NOT FOUND GOTO notfound; EXEC SQL EXECUTE BEGIN cbm_ana.param_lob_access.read_blob(:id,:amount,:loblength,:buffer); END; END-EXEC; obj->setLength(loblength); paramValue=obj->getParamValue(); amountRead=amount; memcpy((unsigned char*)paramValue,buffer,amount); while (amountReadLOB_BUFSIZE) ? LOB_BUFSIZE : loblength ; offset=amountRead+1; EXEC SQL EXECUTE BEGIN cbm_ana.param_lob_access.read_next_buffer(:amount,:offset,:buffer); END; END-EXEC; memcpy((unsigned char*)(¶mValue[amountRead]),buffer,amount); amountRead+=amount; } return kTRUE; notfound: showSqlError("readBlob"); Error("readBlob","Blob %i not read",lobId); return kFALSE; } Int_t CbmGenericParOraIo::createParamVers(CbmParGenericSet* 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; int vers=-1; int context_id=-1; EXEC SQL END DECLARE SECTION; p_class=(char*)(pPar->IsA()->GetName()); p_author=(char*)(pPar->getAuthor()); p_descript=(char*)(pPar->getDescription()); p_context=(char*)(pPar->getParamContext()); 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 := cbm_ana.param_query.get_context_id( :p_class,:p_context); IF :context_id > 0 THEN :vers := cbm_ana.param_query.next_param_vers_load(:p_class); IF :vers > 0 THEN INSERT INTO cbm_ana.param_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*)"); rollback(); return vers; }; Int_t CbmGenericParOraIo::writeSet(CbmParGenericSet* 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); CbmParamObj* po; TList* pBinList=paramList->getBinaryList(); TIter nextBin(pBinList); CbmParamBinObj* pbo; Int_t n=0, m=0; while ((po=(CbmParamObj*)next())) { vers[n]=version; strcpy(p_name[n],po->GetName()); strcpy(p_value[n],po->getParamValue()); p_type[n][0]=po->getParamType(); p_type[n][1]='\0'; p_is_binary[n]=0; p_is_basic[n]=1; p_nvalues[n]=po->getNumParams(); p_num[n]=n+1; n++; } EXEC SQL WHENEVER SQLERROR GOTO not_found; EXEC SQL WHENEVER NOT FOUND GOTO not_found; if (n>0) { rows_to_insert=n; EXEC SQL FOR :rows_to_insert INSERT INTO cbm_ana.param_value_load ( param_vers_load_id,param_name,param_value,param_value_type, is_binary,is_basic_type,nvalues,param_num) VALUES(:vers,:p_name,:p_value,:p_type,:p_is_binary,:p_is_basic, :p_nvalues,:p_num); cout<<"*** Number of parameters: "<GetName()); strcpy(p_type[n],pbo->getParamType()); p_is_binary[n]=1; if (pbo->isBasicType()) { p_is_basic[n]=1; class_vers_Ind[n]=-1; } else { p_is_basic[n]=0; p_class_vers[n]=pbo->getClassVersion(); class_vers_Ind[n]=0; p_nvalues[n]=0; } p_nvalues[n]=pbo->getNumParams(); sprintf(p_value[n],"%i",storeBlob(pbo->getParamValue(),pbo->getLength())); p_num[n]=m+n+1; n++; } if (n>0) { rows_to_insert=n; EXEC SQL FOR :rows_to_insert INSERT INTO cbm_ana.param_value_load (param_vers_load_id,param_name,param_value,param_value_type, is_binary,is_basic_type,nvalues,param_num,class_version) VALUES(:vers,:p_name,:p_value,:p_type,:p_is_binary,:p_is_basic, :p_nvalues,:p_num,:p_class_vers:class_vers_Ind); cout<<"*** Number of binary parameters: "<GetName()<<" written to Oracle"<setChanged(kFALSE); delete paramList; return version; not_found: showSqlError("writeSet(CbmParGenericSet*)"); rollback(); pPar->setChanged(kFALSE); delete paramList; return -1; } Int_t CbmGenericParOraIo::storeBlob(UChar_t* pValue, Int_t pLength) { EXEC SQL BEGIN DECLARE SECTION; unsigned char buffer[LOB_BUFSIZE]; int totlen; int amount; int offset; 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; EXEC SQL EXECUTE DECLARE BEGIN cbm_ana.param_lob_access.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 cbm_ana.param_lob_access.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."<add((char*)(cl.p_name[i].arr),(char*)(cl.p_value[i].arr), cl.p_type[i].arr[0],cl.p_num[i]); else { CbmParamBinObj* o=new CbmParamBinObj; o->SetName((char*)(cl.p_name[i].arr)); o->setParamType((char*)(cl.p_type[i].arr)); if (cl.p_is_basic[i]==0) o->setClassVersion(cl.p_class_vers[i]); paramList->getBinaryList()->Add(o); Int_t lobId; sscanf((char*)(cl.p_value[i].arr),"%i",&lobId); CbmParOraBlob* ob=new CbmParOraBlob(o,lobId); blobList->Add(ob); } } } TIter next(blobList); CbmParOraBlob* b; Bool_t rc=kTRUE; while ((b=(CbmParOraBlob*)next())!=0 && rc) { rc=readLoadBlob(b->binaryParam,b->blobId); } if (rc && sqlca.sqlerrd[2]>0) { rc=pPar->getParams(paramList); pPar->setInputVersion(version,inputNumber); } else pPar->setInputVersion(-1,inputNumber); blobList->Delete(); delete blobList; delete paramList; if (rc==kTRUE) { setChanged(pPar); cout<GetName()<<" initialized from Load Table"<<'\n'; } return rc; } Bool_t CbmGenericParOraIo::readLoadBlob(CbmParamBinObj* obj,Int_t lobId) { // 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]; EXEC SQL VAR buffer IS RAW(LOB_BUFSIZE); EXEC SQL END DECLARE SECTION; id=lobId; amount=LOB_BUFSIZE; UChar_t* paramValue=0; UInt_t amountRead=0; EXEC SQL WHENEVER SQLERROR GOTO notfound; EXEC SQL WHENEVER NOT FOUND GOTO notfound; EXEC SQL EXECUTE BEGIN cbm_ana.param_lob_access.read_load_blob(:id,:amount,:loblength,:buffer); END; END-EXEC; obj->setLength(loblength); paramValue=obj->getParamValue(); amountRead=amount; memcpy((unsigned char*)paramValue,buffer,amount); while (amountReadLOB_BUFSIZE) ? LOB_BUFSIZE : loblength ; offset=amountRead+1; EXEC SQL EXECUTE BEGIN cbm_ana.param_lob_access.read_next_buffer(:amount,:offset,:buffer); END; END-EXEC; memcpy((unsigned char*)(¶mValue[amountRead]),buffer,amount); amountRead+=amount; } return kTRUE; notfound: showSqlError("readBlob"); Error("readBlob","Blob %i not read",lobId); return kFALSE; }