00001
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 #define MYSQLON 1999
00261
00262 #include <Stiostream.h>
00263 #include "Stiostream.h"
00264 #include <stdlib.h>
00265 #include <string.h>
00266 #include <time.h>
00267 #include "TError.h"
00268 #include "TBrowser.h"
00269 #include "TDatime.h"
00270 #include "TRegexp.h"
00271 #include "TInterpreter.h"
00272 #include "TFile.h"
00273 #include "TSystem.h"
00274 #include "St_db_Maker.h"
00275 #include "TDataSetIter.h"
00276 #include "TFileSet.h"
00277
00278 #include "StTree.h"
00279 #include "TTableDescriptor.h"
00280 #include "TTable.h"
00281 #include "TUnixTime.h"
00282 #include "StDbBroker/StDbBroker.h"
00283 #include "TAttr.h"
00284 #include "StValiSet.h"
00285
00286
00287 enum eDBMAKER {kUNIXOBJ = 0x2000};
00288
00290
00291
00292
00293
00295
00296 TString FullFileName(const TDataSet* ds)
00297 {
00298 TString dbfile(ds->GetTitle()+5);
00299 TString dbDir(gSystem->BaseName(dbfile.Data()));
00300 dbDir.Append("/");
00301 TString full(ds->Path());
00302
00303 do {
00304 int idx = full.Index(dbDir);if (idx<0) break;
00305 full.Remove(0,idx+dbDir.Length()-1);
00306 } while(1);
00307
00308 TString name(ds->GetName());
00309 int idx = name.Index("."); if (idx>=0) name.Remove(idx,999);
00310 name.Insert(0,"/.");
00311 full.ReplaceAll(name,"");
00312 full.Insert(0,dbfile);
00313 gSystem->ExpandPathName(full);
00314 return full;
00315 }
00316
00317 TableClassImpl(St_dbConfig,dbConfig_st)
00318
00319
00320 ClassImp(St_db_Maker)
00321
00322 St_db_Maker::St_db_Maker(const char *name
00323 , const char *dir0
00324 , const char *dir1
00325 , const char *dir2
00326 , const char *dir3
00327 )
00328 :StMaker(name)
00329 {
00330 for (int i=0;i<5;i++) {fTimer[i].Stop();}
00331 fTimer[5].Start(0);
00332
00333 memset(fEvents,0,sizeof(fEvents)+sizeof(fDataSize));
00334
00335 fDirs[0] = dir0;
00336 fDirs[1] = dir1;
00337 fDirs[2] = dir2;
00338 fDirs[3] = dir3;
00339 fDirs[4] = "";
00340
00341 fDBBroker = 0;
00342
00343 fHierarchy = 0;
00344 fIsDBTime = 0;
00345
00346 fDataBase = 0;
00347 fUpdateMode = 0;
00348 TUnixTime ut;
00349 fMaxEntryTime = ut.GetUTime();
00350 }
00351
00352 St_db_Maker::~St_db_Maker()
00353 {
00354 delete fDBBroker; fDBBroker =0;
00355 fDataBase =0;
00356 delete fHierarchy;fHierarchy=0;
00357 }
00358
00359 Int_t St_db_Maker::InitRun(int runumber)
00360 {
00361 if (!fDBBroker || !runumber) return 0;
00362 fTimer[3].Start(0);
00363 fDBBroker->SetRunNumber(runumber);
00364 fTimer[3].Stop();
00365 return 0;
00366 }
00367
00368 Int_t St_db_Maker::Init()
00369 {
00370 TDataSet *fileset;
00371 TString dir;
00372 fTimer[0].Start(0);
00373 SetBIT(kInitBeg);
00374 fDataBase=0;
00375 Snapshot(0);
00376 int snap = fDataBase!=0;
00377 for (int idir=0; !fDirs[idir].IsNull() && !snap; idir++) {
00378
00379 dir = fDirs[idir];
00380 gSystem->ExpandPathName(dir);
00381 if (strncmp("MySQL:", (const char*)dir,6)==0){
00382 fileset = OpenMySQL(((const char*)dir)+6);
00383 if (!fileset) return kStErr;
00384 fileset->Pass(PrepareDB,0);
00385 } else {
00386
00387
00388 fileset = new TFileSet(dir,gSystem->BaseName(dir));
00389 if (!fileset->First()) {delete fileset; fileset = 0; continue;}
00390 fileset->Purge();
00391 fileset->Sort();
00392 fileset->Pass(PrepareDB,&dir);
00393 fileset->Purge();
00394 }
00395 if (fDataBase) {
00396 assert(strcmp(fDataBase->GetName(),fileset->GetName())==0);
00397 fDataBase->Update(fileset); delete fileset;
00398 } else {fDataBase = fileset; }
00399 }
00400
00401 if (fDataBase) {
00402 AddConst(fDataBase);
00403 SetOutputAll(fDataBase,1);
00404
00405 if (Debug()>1) fDataBase->ls("*");
00406 }
00407 OnOff();
00408 SetFlavor(0,0);
00409 ResetBIT(kInitBeg); SetBIT(kInitEnd);
00410 fTimer[0].Stop ();
00411 return StMaker::Init();
00412 }
00413
00414 Int_t St_db_Maker::Finish()
00415 {
00416 Snapshot(1);
00417 for (int i=0;i<6;i++) fTimer[i].Stop();
00418 Printf("St_db_Maker::Init ");fTimer[0].Print();
00419 Printf(" MySQL::Init ");fTimer[2].Print();
00420 Printf("St_db_Maker::Make ");fTimer[1].Print();
00421 Printf(" MySQL::Make ");fTimer[3].Print();
00422 Printf(" MySQL::Data ");fTimer[4].Print();
00423
00424 if (fEvents[1]<=0) return 0;
00425 double estiTime = fTimer[4].RealTime()*fTimer[5].CpuTime()/fTimer[5].RealTime();
00426 double eachEvt = double(fEvents[0]) /(fEvents[1]+3e-33);
00427 double MperTim = (fDataSize[1]*1e-6)/(estiTime+3e-33);
00428 double timPerE = estiTime/(fEvents[1]+3e-33);
00429 double cpuPerE = fTimer[4].CpuTime() /(fEvents[1]+3e-33);
00430 double timPct = fTimer[4].RealTime()/fTimer[5].RealTime() *100;
00431 double cpuPct = fTimer[4].CpuTime() /fTimer[5].CpuTime() *100;
00432
00433 Info("dbStat","Evts = %d dbEvts=%d Evts/dbEvts = %4.1f\n"
00434 ,fEvents[0], fEvents[1],eachEvt);
00435
00436 Info("dbStat","dbData =%10.1f dbTime=%g dbData/dbTime=%g\n"
00437 ,fDataSize[1]*1e-6,estiTime,MperTim);
00438
00439 Info("dbStat","dbTime =%10.1f dbEvts=%d dbTime/dbEvts =%g\n"
00440 ,estiTime,fEvents[1],timPerE);
00441
00442 Info("dbStat","dbCpu =%10.1f dbEvts=%d dbCpu/dbEvts =%g\n"
00443 ,fTimer[4].CpuTime() ,fEvents[1],cpuPerE);
00444
00445 Info("dbStat","dbTime/tot =%10.2f dbCpu/tot=%10.2f \n"
00446 ,timPct,cpuPct);
00447
00448 return 0;
00449 }
00450
00451
00452
00453 Int_t St_db_Maker::Make()
00454 {
00455
00456 fTimer[1].Start(0);
00457 TDatime td = GetDateTime();
00458 if (td.GetDate() >= 20330101) {
00459 Error("Make", "TimeStamp not set. Can not make request to DB");
00460 return kStFatal;
00461 }
00462 fUpdateMode = 1;
00463 UpdateDB(fDataBase);
00464 fUpdateMode = 0;
00465 fTimer[1].Stop();
00466 return kStOK;
00467 }
00468
00469 void St_db_Maker::Clear(const char *)
00470 {
00471 if (!fDBBroker) return;
00472 fEvents[0]++;
00473 if (fDataSize[0]) fEvents[1]++;
00474 fDataSize[1]+=fDataSize[0];
00475 fDataSize[0]=0;
00476
00477 fDBBroker->Release();
00478 }
00479
00480 TDatime St_db_Maker::Time(const char *filename)
00481 {
00482 int lfilename,lname,idate,itime;
00483
00484 TDatime time; time.Set(kMaxTime,0);
00485
00486 lfilename = strlen(filename);
00487 lname = strcspn(filename,".");
00488 if (lname+2>lfilename) return time;
00489 idate = AliasDate(filename+lname+1);
00490 itime = AliasTime(filename+lname+1);
00491
00492 if (idate) { time.Set(idate,itime);return time;}
00493
00494 if (lname+18 <= lfilename &&
00495 filename[lname+0 ]=='.' &&
00496 filename[lname+9 ]=='.' &&
00497 filename[lname+16]=='.' ) {
00498 idate = atoi(filename+lname+ 1);
00499 itime = atoi(filename+lname+10);
00500 } else {
00501 idate = kMinTime;
00502 itime = 0;
00503 }
00504 time.Set(idate,itime); return time;
00505
00506 }
00507
00508 int St_db_Maker::Kind(const char *filename)
00509 {
00510 int lfilename;
00511
00512 lfilename = strlen(filename);
00513 if (!strcmp(filename+lfilename-4,".xdf" )) return 1;
00514 if (!strcmp(filename+lfilename-2,".C" )) return 2;
00515 if (!strcmp(filename+lfilename-2,".c" )) return 2;
00516 if (!strcmp(filename+lfilename-5,".root")) return 3;
00517 return 0;
00518 }
00519
00520 TDataSet *St_db_Maker::OpenMySQL(const char *dbname)
00521 {
00522 int nrows,irow,jrow;
00523 dbConfig_st *thy,*ihy,*jhy;
00524 TDataSet *top,*node,*ds;
00525
00526 fTimer[0].Stop(); fTimer[2].Start(0);
00527 fDBBroker = new StDbBroker();
00528 if (Debug() > 1) fDBBroker->setVerbose(1);
00529 if (fMaxEntryTime) {
00530 fDBBroker->SetProdTime(fMaxEntryTime);
00531 for (std::map<std::pair<std::string,std::string>,UInt_t>::iterator it = fMaxEntryTimeOverride.begin(); it != fMaxEntryTimeOverride.end(); it++ ) {
00532 fDBBroker->AddProdTimeOverride((*it).second, (char*)((*it).first.first).c_str(), (char*)((*it).first.second).c_str());
00533 }
00534 }
00535 const TAttr *attl = GetAttr();
00536 if (attl) {
00537 TIter next(attl);
00538 TObject *obj;
00539 while ((obj = next())) {
00540 if (strcmp("blacklist",obj->GetName())!=0) continue;
00541 fDBBroker->addBlacklistedDomain(obj->GetTitle());
00542 Info("OpenMySQL","Block domain %s",obj->GetTitle());
00543 }
00544 }
00545 TString ts(dbname); ts+="_hierarchy";
00546 fHierarchy = new St_dbConfig((char*)ts.Data());
00547 thy = fDBBroker->InitConfig(dbname,nrows);
00548 fTimer[0].Start(0); fTimer[2].Stop();
00549 if (!thy || !nrows){
00550 Warning("OpenMySQL","***Can not open MySQL DB %s ***",dbname);
00551 return 0;}
00552
00553 fHierarchy->Adopt(nrows,thy);
00554 if (GetDebug()>1) fHierarchy->Print(0,nrows);
00555
00556 top = new TDataSet(thy->parname);
00557 top->SetTitle("directory");
00558
00559 TDataSet **dss = new TDataSet*[nrows];
00560 memset(dss,0,nrows*sizeof(void*));
00561
00562
00563 for (irow=0,ihy=thy; irow <nrows ; irow++,ihy++)
00564 {
00565 if (strcmp(ihy->tabtype,".node")==0) {
00566 ds = new TDataSet(ihy->tabname);
00567 ds->SetTitle("directory");
00568 } else {
00569 const char *ty = ihy->tabtype;
00570 if (ty[0]=='.') ty++;
00571 ds = TTable::New(ihy->tabname,ty,0,0);
00572 if (!ds) {
00573 Warning("OpenMySQL","Unknown table %s/%s.%s",ihy->parname,ihy->tabname,ihy->tabtype); continue;}
00574 }
00575 if (ds) ds->SetUniqueID(ihy->tabID);
00576 dss[irow] = ds;
00577 }
00578
00579
00580 for (irow=0,ihy=thy; irow <nrows ; irow++,ihy++)
00581 {
00582 ds = dss[irow]; if (!ds) continue;
00583 if (strcmp(ihy->parname,top->GetName())==0) top->Add(ds);
00584 if(ds->GetParent()) continue;
00585 for (jrow=0,jhy=thy; jrow <nrows ; jrow++,jhy++)
00586 {
00587 if (jrow==irow) continue;
00588 if (ihy->parID != jhy->tabID) continue;
00589 if (strcmp(".node" ,jhy->tabtype)) continue;
00590 if (strcmp(ihy->parname,jhy->tabname)) continue;
00591 node = dss[jrow]; if (!node) continue;
00592 node->Add(ds); break;
00593 }
00594 if (ds->GetParent()) continue;
00595 delete ds; dss[irow]=0;
00596 Error("OpenMySQL","WRONG parent %s/%s\n",ihy->parname,ihy->tabname);
00597 }
00598
00599
00600 delete [] dss;
00601
00602 return top;
00603 }
00604
00605
00606
00607 TDataSet *St_db_Maker::UpdateDB(TDataSet* ds)
00608 {
00609 if(!ds) return 0;
00610 ds->Pass(&UpdateDB,this);
00611 return ds;
00612 }
00613
00614 int St_db_Maker::UpdateTable(UInt_t parId, TTable* dat
00615 ,const TDatime &req,TDatime val[2] )
00616 {
00617
00618 assert(fDBBroker);assert(dat);
00619
00620 fDBBroker->SetDateTime(req.GetDate(),req.GetTime());
00621 TTableDescriptor *rowTL = ((TTable*)dat)->GetRowDescriptors();
00622 fTimer[1].Stop();
00623 fTimer[3].Start(0);
00624 fTimer[4].Start(0);
00625 fDBBroker->SetDictionary(rowTL);
00626 fDBBroker->SetTableName (dat->GetName());
00627 fDBBroker->SetStructName(dat->GetTitle());
00628 fDBBroker->SetStructSize(dat->GetRowSize());
00629
00630
00631 void *dbstruct = fDBBroker->Use(dat->GetUniqueID(),parId);
00632
00633 Int_t d1 = fDBBroker->GetBeginDate();
00634 Int_t t1 = fDBBroker->GetBeginTime();
00635 if (d1 < 19950101) {
00636 Warning("UpdateTable","Table %s.%s Unacceptable Begin Date/Time %d/%d reset to 19950101/000001",
00637 dat->GetName(),dat->GetTitle(),d1,t1);
00638 d1 = 19950101; t1 = 1;
00639 }
00640 Int_t d2 = fDBBroker->GetEndDate ();
00641 Int_t t2 = fDBBroker->GetEndTime ();
00642 if (d2 < 19950101) {
00643 Warning("UpdateTable","Table %s.%s Unacceptable End Date/Time %d/%d reset to 19950101/000001",
00644 dat->GetName(),dat->GetTitle(),d2,t2);
00645 d2 = 19950101; t2 = 1;
00646 }
00647 val[0].Set(d1,t1);
00648 val[1].Set(d2,t2);
00649
00650
00651 if ( val[0].Get() >= val[1].Get()) {
00652 Error("UpdateTable","val[0].Get() = %u >= val[1].Get() = %u\n",val[0].Get(),val[1].Get());
00653 Error("UpdateTable:","Table %s.%s Suspicious Ranges Date/Time %d/%d->%d/%d\n",
00654 dat->GetName(),dat->GetTitle(),d1,t1,d2,t2);
00655 Error("UpdateTable","Table %s.%s Suspicious Ranges Date/Time %d/%d->%d/%d",
00656 dat->GetName(),dat->GetTitle(),d1,t1,d2,t2);
00657 assert(! ( val[0].Get() >= val[1].Get()));
00658 }
00659
00660 fTimer[1].Start(0); fTimer[3].Stop();fTimer[4].Stop();
00661
00662 if (!dbstruct) {
00663 dat->SetNRows(0);
00664 if(Debug()>1) Warning("UpdateTable","Table %s.%s Not FOUND in DB",dat->GetName(),dat->GetTitle());
00665 return 1;
00666 }
00667
00668 int nRows = fDBBroker->GetNRows();
00669
00670 dat->Adopt(nRows,dbstruct);
00671
00672 fDataSize[0]+=nRows*dat->GetRowSize();
00673 if (!nRows || ((char*)dbstruct)[dat->GetRowSize()*nRows-1]) {}
00674
00675
00676
00677
00678
00679 return 0;
00680
00681 }
00682
00683 EDataSetPass St_db_Maker::UpdateDB(TDataSet* ds,void *user )
00684 {
00685 StValiSet *val;
00686 if (strcmp("directory",ds->GetTitle())==0) return kContinue;
00687 if (strcmp(".Val" ,ds->GetTitle())!=0) return kPrune;
00688
00689
00690 val = (StValiSet*)ds;
00691 St_db_Maker *mk = (St_db_Maker*)user;
00692 if (mk->fUpdateMode && !val->IsModified()) return kPrune;
00693
00694 TDatime currenTime = mk->GetDateTime();
00695 UInt_t uevent = currenTime.Get();
00696
00697
00698 if (val->fTimeMin.Get() <= uevent
00699 && val->fTimeMax.Get() > uevent) return kPrune;
00700
00701 TObjectSet set("dbSnapshot",0);
00702 const char *fname = mk->SAttr("dbSnapshot");
00703 if (!fname || !*fname) {
00704
00705 } else {
00706 if (!mk->fDBBroker) {
00707 mk->Error("UpdateDB","DbSnapshot mode: wrong validity for %s ignored( ???? )"
00708 ,val->GetName());
00709 return kPrune;
00710 }
00711 }
00712 TDataSet *par = val->GetParent();
00713 par->Remove(val->fDat);
00714 mk->UpdateValiSet(val,currenTime);
00715 if (val->fGood) par->AddFirst(val->fDat);
00716 return kPrune;
00717 }
00718
00719 int St_db_Maker::UpdateValiSet(StValiSet *val,const TDatime ¤Timep)
00720 {
00721 static int nCall=0; nCall++;
00722 TDatime currenTime(currenTimep);
00723 if (currenTime.GetDate() >=kMaxTime) currenTime.Set(kMaxTime-1,0);
00724 TDataSet *left;
00725 TDatime valsCINT[2],valsSQL[2];
00726 UInt_t uevent = currenTime.Get();
00727
00728
00729 val->fTimeMin.Set(kMaxTime,0);
00730 val->fTimeMax.Set(kMinTime,0);
00731 val->fGood=0;
00732 int kase = 0;
00733 valsSQL[0].Set(kMinTime,0);
00734 valsSQL[1].Set(kMaxTime,0);
00735 if (fDBBroker && val->fTabId ) {
00736 assert(val->fTabId==val->fDat->GetUniqueID());
00737 int ierr = UpdateTable(val->fParId,(TTable*)val->fDat,currenTime,valsSQL );
00738 if (!ierr) kase = 1;
00739 }
00740
00741 left = FindLeft(val,valsCINT,currenTime);
00742 if (left) kase+=2;
00743 TDataSet *newGuy=0;
00744 SWITCH: switch (kase) {
00745
00746 case 0:
00747 val->fTimeMin = valsSQL[0]; val->fTimeMax = valsSQL[1];
00748 kase=4; goto SWITCH;
00749
00750 case 1:
00751 val->fTimeMin = valsSQL[0]; val->fTimeMax = valsSQL[1];
00752 val->fGood=1; kase=4; goto SWITCH;
00753
00754 case 2:
00755 newGuy = LoadTable(left);
00756 if (!val->fDat) { val->fDat = newGuy; val->AddFirst(newGuy);}
00757 else if(val->fDat->InheritsFrom(TTable::Class()))
00758 { val->fDat->Update(newGuy); delete newGuy ;}
00759 else { delete val->fDat; val->fDat = newGuy ;}
00760 val->fTimeMin = valsCINT[0]; val->fTimeMax = valsCINT[1];
00761 val->fGood=1; kase=4; goto SWITCH;
00762
00763 case 3:
00764 if (valsCINT[0].Get()>=valsSQL[0].Get()) {
00765 kase = 2;
00766 if (valsCINT[1].Get()>valsSQL[1].Get()) valsCINT[1] = valsSQL[1];
00767 } else {
00768 kase = 1;
00769 if (valsSQL[1].Get()>valsCINT[1].Get()) valsSQL[1] = valsCINT[1];
00770 }
00771 goto SWITCH;
00772
00773 case 4:
00774 if( ! ((val->fTimeMin.Get()<= uevent) && (uevent<val->fTimeMax.Get()) )){
00775
00776 if (val->Path().Contains("RunLog/onl")) break;
00777 (void) printf("CheckFail:: Assert will fail for Table %s TimeMin=%d TimeMax=%d uevent=%d\n",
00778 val->GetName(),val->fTimeMin.Get(),val->fTimeMax.Get(),uevent);
00779 (void) printf("\tTimeMin "); val->fTimeMin.Print();
00780 (void) printf("\tuevent "); currenTime.Print();
00781 (void) printf("\tTimeMax "); val->fTimeMax.Print();
00782 }
00783 assert((val->fTimeMin.Get()<= uevent) && (val->fTimeMax.Get()>uevent));
00784
00785 break;
00786
00787 default: assert(0);
00788 }
00789 val->fVers++;
00790 val->Modified(1);
00791 if (val->fTimeMin.Get() == val->fTimeMax.Get()) {
00792 Warning("UpdateDB","Zero size validity for %s",val->GetName());
00793 printf("\tTimeMin "); val->fTimeMin.Print();
00794 printf("\tuevent "); currenTime.Print();
00795 printf("\tTimeMax "); val->fTimeMax.Print();
00796 Warning("UpdateDB","Ask Mike DeFillips WHY!!!!!");
00797 }
00798 return val->fGood;
00799 }
00800
00801
00802 TDataSet *St_db_Maker::FindLeft(StValiSet *val, TDatime vals[2], const TDatime ¤Time)
00803 {
00804
00805
00806
00807 UInt_t uevent = currenTime.Get();
00808
00809 vals[0].Set(kMinTime,0);
00810 vals[1].Set(kMaxTime,0);
00811 UInt_t utmp,udifleft=(UInt_t)(-1),udifrite=(UInt_t)(-1);
00812 TDataSet *left=0,*rite=0,*set=0;
00813 TListIter next(val->GetList());
00814 while ((set = (TDataSet*)next())) {
00815 if (set == val->fDat) continue;
00816 const char *filename = set->GetName();
00817 UInt_t ucur = St_db_Maker::Time(filename).Get();
00818 if (!ucur) {
00819 Warning("FindLeft","*** Unrecognozed file %s ***",filename);
00820 continue;
00821 } else if (uevent < ucur) {
00822 utmp = ucur - uevent;
00823 if (utmp <= udifrite) { udifrite=utmp; rite=set;}
00824 }else{
00825 utmp = uevent - ucur;
00826 if (utmp <= udifleft) { udifleft=utmp; left=set;}
00827 }
00828 }
00829
00830
00831 if (left) vals[0] = St_db_Maker::Time(left->GetName());
00832 if (rite) vals[1] = St_db_Maker::Time(rite->GetName());
00833 return left;
00834 }
00835
00836
00837
00838 TDataSet *St_db_Maker::LoadTable(TDataSet* left)
00839 {
00840 TFile *tf =0;
00841 TObject *to =0;
00842 TString command;
00843 TDataSet *newdat = 0;
00844 TString dbfile(FullFileName(left));
00845 assert(dbfile.Length()>0);
00846
00847 int kind = Kind(left->GetName());
00848 switch (kind) {
00849
00850 case 1:
00851 assert(0);
00852
00853 if (GetDebug()) printf("Load XdfFile: %s\n",(const char*)dbfile);
00854 break;
00855
00856 case 2:
00857
00858 command = ".L "; command += dbfile;
00859 if (GetDebug()) printf("LoadTable: %s\n",(const char*)command);
00860 TInterpreter::EErrorCode ee;
00861 gInterpreter->ProcessLine(command,&ee);
00862 assert(!ee);
00863 newdat = (TDataSet *) gInterpreter->Calc("CreateTable()",&ee);
00864 assert(!ee);
00865 command.ReplaceAll(".L ",".U ");
00866 gInterpreter->ProcessLine(command,&ee);
00867 assert(!ee);
00868
00869 break;
00870
00871 case 3:
00872
00873 tf = new TFile(dbfile);
00874 to = StIO::Read (tf, "*");
00875 delete tf;
00876 if (!to) break;
00877 if (GetDebug()) printf("Load TFile: %s\n",(const char*)dbfile);
00878 if (strcmp(to->ClassName(),"StIOEvent")==0) to = ((StIOEvent*)to)->fObj;
00879 if (!to) break;
00880 if (to->InheritsFrom(TDataSet::Class())) {
00881 newdat = (TDataSet*)to;
00882 } else {
00883 newdat = new TObjectSet(to->GetName());
00884 newdat->SetObject(to);
00885 }
00886 break;
00887
00888 default: assert(0);
00889 }
00890 if (newdat) newdat->SetUniqueID(kUNIXOBJ+kind);
00891
00892 return newdat;
00893 }
00894
00895
00896 EDataSetPass St_db_Maker::PrepareDB(TDataSet* ds, void *user)
00897 {
00898 TDataSet *set;
00899 StValiSet *pseudo;
00900 const char *dsname,*filename,*dot;
00901 char psname[100];
00902
00903 int lpsname;
00904
00905 TList *list = ds->GetList();
00906 if (!list) return kContinue;
00907 if (strcmp("directory",ds->GetTitle())!=0) return kPrune;
00908 dsname = ds->GetName(); ;
00909 if (!strcmp("CVS",dsname)) { delete ds; return kPrune;}
00910
00911 TString newTitle = "file ";
00912 if (user) newTitle += *((TString*)user);
00913
00914
00915 pseudo = 0; psname[0]='.'; psname[1]=0;
00916 TListIter next(list);
00917 while ((set = (TDataSet*)next())) {
00918 filename = set->GetName();
00919 int isSql =(set->InheritsFrom(TTable::Class())!=0);
00920 if (isSql) {
00921 lpsname = strlen(filename);
00922 } else {
00923 if (strncmp("file",set->GetTitle(),4)!=0) continue;
00924 if (!(dot = strchr(filename,'.'))) continue;
00925 int k = Kind(filename);
00926 if (k==2) {
00927 }
00928 if (!k){ delete set; continue;}
00929 set->SetTitle(newTitle);
00930
00931
00932
00933
00934
00935
00936
00937 lpsname = dot - filename;
00938 }
00939 if (strncmp(filename,psname+1,lpsname)) {
00940 psname[1]=0; strncat(psname,filename,lpsname);
00941 pseudo = new StValiSet(psname,ds);
00942 pseudo->fParId = ds->GetUniqueID();
00943 }
00944
00945 set->Shunt(pseudo);
00946 if (isSql) {
00947 pseudo->fTabId = set->GetUniqueID();
00948 pseudo->fDat=set;
00949
00950 }
00951 }
00952 return kContinue;
00953 }
00954
00955 TDataSet *St_db_Maker::GetDataBase(const char* logInput,const TDatime *td)
00956 {
00957 fTimer[1].Start(0);
00958 TString ts;
00959 TDataSet *ds=0;
00960 int idir = 1,lst;
00961 ds = GetDataSet(logInput);
00962 if (!ds || strncmp(ds->GetTitle(),"directory",9)!=0)
00963 {
00964
00965 idir = 0;
00966 lst =-1;
00967 for (int i=0;logInput[i];i++) if (logInput[i]=='/') lst=i;
00968 if (lst<0) { ds=0; goto RETN;}
00969
00970 ts = logInput;
00971 ts.Insert(lst+1,".");
00972 ds = GetDataSet(ts.Data());
00973 if (!ds) goto RETN;
00974 }
00975
00976 if (td) {
00977 if (idir) {
00978 Error("GetDataBase","Request for directory %s with user time is FORBIDDEN"
00979 ,ds->GetName());
00980 assert(!idir);
00981 }
00982 assert(!strcmp(".Val",ds->GetTitle()));
00983 StValiSet *vs = (StValiSet*)ds;
00984 StValiSet *myVS = new StValiSet(vs->GetName(),0);
00985 myVS->fTabId = vs->fTabId;
00986 myVS->fParId = vs->fParId;
00987 myVS->Modified(1);
00988 if (vs->fParId) {
00989 TTable *tb = (TTable *)vs->fDat;
00990 TString ty(tb->GetType());
00991 if (ty.EndsWith("_st")) ty.Remove(ty.Length()-3,99);
00992 myVS->fDat = TTable::New(tb->GetName(),ty,0,0);
00993 myVS->fDat->SetUniqueID(myVS->fTabId);
00994 }
00995 TDataSetIter next(vs);
00996 TDataSet *to=0;
00997 while ((to=(TDataSet*)next())){ myVS->Add(to);}
00998
00999 UpdateValiSet(myVS,*td);
01000 myVS->GetList()->Clear("nodelete");
01001 if (myVS->fGood) {
01002 myVS->fDat->Add(myVS);
01003 return myVS->fDat;
01004 }
01005 delete myVS->fDat;
01006 delete myVS;
01007 return 0;
01008 }
01009
01010
01011 UpdateDB(ds);
01012 if (idir) goto RETN;
01013 ds = GetDataSet(logInput);
01014 RETN: fTimer[1].Stop(); return ds;
01015 }
01016
01017 const TDatime &St_db_Maker::GetDateTime() const
01018 {
01019 if (!fIsDBTime) return StMaker::GetDateTime();
01020
01021 return fDBTime;
01022 }
01023
01024 void St_db_Maker::SetDateTime(Int_t idat,Int_t itim)
01025 {
01026 fIsDBTime=0; if (idat==0) return;
01027 fIsDBTime=1; fDBTime.Set(idat,itim);
01028 Info("SetDateTime","Setting Startup Date=%d Time=%d",idat,itim);
01029 StMaker::SetDateTime(idat,itim);
01030 }
01031
01032 void St_db_Maker::SetDateTime(const char *alias)
01033 {
01034 fIsDBTime=1;
01035 int idat = AliasDate(alias);
01036 int itim = AliasTime(alias);
01037 assert(idat);
01038 Info("SetDateTime","(\"%s\") == Startup Date=%d Time=%d",alias,idat,itim);
01039 fDBTime.Set(idat,itim);
01040 StMaker::SetDateTime(idat,itim);
01041 }
01042
01043 void St_db_Maker::SetOn(const char *path)
01044 { AddAlias("On" ,path,".onoff"); OnOff();}
01045
01046 Int_t St_db_Maker::Save(const char *path,const TDatime *newtime)
01047 {
01048 ofstream out;
01049 int nakt=0,i,l;
01050 TDataSet *top,*ds;
01051 TTable *tb;
01052 TString ts,dir;
01053 TDatime val[2];
01054 char cbuf[20];
01055 top = GetDataBase(path);
01056 if (!top) return 1;
01057 TDataSetIter nextDS(top,999);
01058 TDataSet::EDataSetPass mode = TDataSet::kContinue;
01059 while((ds = nextDS(mode))) {
01060 mode = TDataSet::kContinue;
01061 if (ds->GetName()[0]=='.') { mode = TDataSet::kPrune; continue; }
01062 if (!ds->InheritsFrom(TTable::Class()))continue;
01063 ts = ds->Path();
01064 i = ts.Index(".const/"); assert(i>0); ts.Replace(0 ,i+7,"");
01065 int jdot = ts.Index(".",(Ssiz_t)1,(Ssiz_t)0 ,TString::kExact);
01066 assert(jdot>0);
01067 int jsla = ts.Index("/",(Ssiz_t)1,(Ssiz_t)jdot,TString::kExact);
01068 assert(jsla>0);
01069 ts.Remove(jdot,jsla-jdot+1);
01070 l = ts.Length();
01071 for (i=0;i<l;i++) {
01072 if (ts[i]!='/') continue;
01073 dir.Replace(0,999,ts,i);
01074 gSystem->MakeDirectory(dir);
01075 }
01076 tb = (TTable*)ds;
01077 if (newtime) { val[0] = *newtime;}
01078 else {i = GetValidity(tb,val); assert(i>=0);}
01079 sprintf(cbuf,".%08d.%06d.C",val[0].GetDate(),val[0].GetTime());
01080 ts += cbuf;
01081 out.open((const char*)ts);
01082 tb->SavePrimitive(out,"");
01083 out.close();
01084 nakt++;
01085 }
01086 return (!nakt);
01087 }
01088
01089 Int_t St_db_Maker::SaveDataSet(TDataSet* ds, int type, bool savenext) {
01090 if (!ds || !ds->InheritsFrom(TTable::Class())) {
01091
01092 return 0;
01093 }
01094 int i = 0;
01095 int jdot = 0, jsla = 0;
01096 TString ts;
01097 TString dir;
01098 ts = ds->Path();
01099 i = 0; i = ts.Index(".const/"); assert(i>0); ts.Replace(0,i+7,"");
01100 jdot = 0; jdot = ts.Index(".",(Ssiz_t)1,(Ssiz_t)0 ,TString::kExact); assert(jdot>0);
01101 jsla = 0; jsla = ts.Index("/",(Ssiz_t)1,(Ssiz_t)jdot,TString::kExact); assert(jsla>0);
01102 ts.Remove(jdot, jsla-jdot + 1);
01103 int l = ts.Length();
01104
01105 for (i = 0; i < l; i++) {
01106 if (ts[i]!='/') continue;
01107 dir.Replace(0,999,ts,i);
01108 gSystem->MakeDirectory(dir);
01109 }
01110 switch(type) {
01111 case 0:
01112 return SaveDataSetAsRootFile((TTable*)ds, ts, savenext);
01113 break;
01114 case 1:
01115 return SaveDataSetAsCMacro((TTable*)ds, ts, savenext);
01116 break;
01117 default:
01118
01119 break;
01120 }
01121 return 1;
01122 }
01123
01124
01125 Int_t St_db_Maker::SaveDataSetAsCMacro(TTable* tb, TString ts, bool savenext) {
01126 TDatime val[2];
01127 std::ofstream out;
01128 int i = 0; i = GetValidity(tb,val); assert(i>=0);
01129 std::stringstream ostr;
01130 ostr << ts << "." << std::setw(6) << std::setfill('0') <<val[0].GetDate() << "." << std::setw(6) << std::setfill('0')
01131 << val[0].GetTime() << ".C";
01132 out.open( ostr.str().c_str() );
01133 tb->SavePrimitive(out,"");
01134 out.close();
01135
01136 if (savenext == true) {
01137 std::string tbname( std::string(ts.Data()).substr(7) );
01138 if (val[1].GetDate() < 20330101 ) {
01139 TDataSet* ds_r = 0;
01140 ds_r = GetDataBase(tbname.c_str(), &val[1]);
01141 if (ds_r) {
01142 SaveDataSetAsCMacro((TTable*)ds_r, ts, false);
01143 delete ds_r;
01144 }
01145 }
01146 }
01147 return 0;
01148 }
01149
01150 Int_t St_db_Maker::SaveDataSetAsRootFile(TTable* tb, TString ts, bool savenext) {
01151 TDatime val[2];
01152 int i = 0; i = GetValidity(tb,val); assert(i>=0);
01153 std::stringstream ostr;
01154 ostr << ts << "." << std::setw(6) << std::setfill('0') <<val[0].GetDate() << "." << std::setw(6) << std::setfill('0')
01155 << val[0].GetTime() << ".root";
01156 TFile ofile(ostr.str().c_str(),"RECREATE" );
01157 tb->Write();
01158 ofile.Close();
01159
01160 if (savenext == true) {
01161 std::string tbname( std::string(ts.Data()).substr(7) );
01162 if (val[1].GetDate() < 20330101 ) {
01163 TDataSet* ds_r = 0;
01164 ds_r = GetDataBase(tbname.c_str(), &val[1]);
01165 if (ds_r) {
01166 SaveDataSetAsRootFile((TTable*)ds_r, ts, false);
01167 delete ds_r;
01168 }
01169 }
01170 }
01171
01172 return 0;
01173 }
01174
01175
01176 Int_t St_db_Maker::SaveSnapshotPlus(char* path, int type)
01177 {
01178 TDataSet *top = 0, *ds = 0;
01179 TString ts;
01180 TDataSet::EDataSetPass mode = TDataSet::kContinue;
01181 TDatime maxDbTime;
01182 maxDbTime.Set(kMaxTime,0);
01183
01184
01185 top = GetDataBase(path);
01186 if (!top) {
01187
01188 return 1;
01189 }
01190 TDataSetIter nextDS(top,999);
01191 ds = nextDS(mode);
01192 if (!ds) {
01193
01194 SaveDataSet(top, type, true);
01195 return 0;
01196 }
01197
01198 while ((ds = nextDS(mode))) {
01199 mode = TDataSet::kContinue;
01200 if (ds->GetName()[0]=='.') { mode = TDataSet::kPrune; continue; }
01201 SaveDataSet(ds, type, true);
01202 }
01203 return 0;
01204 }
01205
01206
01207 void St_db_Maker::SetFlavor(const char *flav,const char *tabname)
01208 {
01209 TDataSet *fl=0;
01210 TDataSet *flaDir =0;
01211 if (flav) {
01212 fl = 0;
01213 flaDir = Find(".flavor");
01214 if (flaDir) fl = flaDir->Find(tabname);
01215 if (fl && strcmp(fl->GetTitle(),flav)==0) return;
01216 if (fl) delete fl;
01217 fl = new TDataSet(tabname);
01218 fl->SetTitle(flav);
01219 AddData(fl,".flavor");
01220 }
01221 if (!fDBBroker) return;
01222 int nAkt = 0;
01223 flaDir = Find(".flavor");
01224 if (!flaDir) return;
01225 StValiSet *val;
01226 TDataSetIter valNext(m_ConstSet,999);
01227 while ((val = (StValiSet*)valNext())) {
01228 const char *tabName = val->GetName();
01229 if (tabName[0] != '.') continue;
01230 if (strcmp(val->GetTitle(),".Val")!=0) continue;
01231 tabName++;
01232 if (val->fDat==0) continue;
01233 if (val->fDat->GetUniqueID() >= kUNIXOBJ) continue;
01234
01235 TDataSetIter flaNext(flaDir);
01236 while((fl = flaNext())) {
01237 const char *flaName = fl->GetName();
01238 if (strcmp(flaName,".all" )!=0
01239 && strcmp(flaName,tabName)!=0) continue;
01240 const char *flaType = fl->GetTitle();
01241 if (val->fFla == flaType) continue;
01242
01243 TDataSet *par = val->GetParent();
01244 val->fFla = flaType;
01245 nAkt++;
01246 val->fTimeMin.Set(kMaxTime,0);
01247 val->fTimeMax.Set(kMinTime,0);
01248 int tabID = (int)val->fDat->GetUniqueID();
01249 int parID = (int)par->GetUniqueID();
01250
01251 fTimer[1].Stop(); fTimer[3].Start(0);
01252 fDBBroker->SetTableFlavor(flaType,tabID, parID);
01253 fTimer[1].Start(0); fTimer[3].Stop();
01254 fl->SetUniqueID(fl->GetUniqueID()+1);
01255
01256 if (Debug()<2) continue;
01257 if (strcmp("ofl",flaType)==0) continue;
01258 printf("<St_db_Maker::SetFlavor> Set flavor %s to %s\n",flaType,tabName);
01259
01260 }
01261
01262 }
01263
01264 TDataSetIter flaNext(flaDir);
01265 while((fl = flaNext())) {
01266 if (fl->GetUniqueID()) continue;
01267 if (strcmp(fl->GetName(),".all" )==0) continue;
01268 Warning("SetFlavor","Flavor %s for table %s was NOT USED",
01269 fl->GetTitle(),fl->GetName());
01270 }
01271
01272 delete flaDir;
01273 if (GetDateTime().GetDate() >= 20330101) return;
01274 if(nAkt) Make();
01275
01276 }
01277
01278 Int_t St_db_Maker::GetValidity(const TTable *tb, TDatime *const val)
01279 {
01280 if (!tb) return -1;
01281 TString ts("."); ts+=tb->GetName();
01282 TDataSet *pa = tb->GetParent();
01283 const StValiSet *vs =0;
01284 if (pa) { vs = (StValiSet*)pa->Find(ts);}
01285 else { vs = (StValiSet*)tb->Find(ts);}
01286 if (!vs) return -2;
01287 if (val) {
01288 val[0] = vs->fTimeMin;
01289 val[1] = vs->fTimeMax;
01290 }
01291 return vs->fVers;
01292 }
01293
01294 Int_t St_db_Maker::Drop(TDataSet *ds)
01295 {
01296 if (!ds) return -1;
01297 TString ts("."); ts+=ds->GetName();
01298 TDataSet *pa = ds->GetParent();
01299 assert(pa);
01300 assert(ts == pa->GetName());
01301 StValiSet *vs = (StValiSet*)pa;
01302 assert(ds == vs->fDat);
01303 TDataSet *ppa = pa->GetParent();
01304 ppa->Remove(ds);
01305 pa->Remove(ds);
01306 vs->fDat=0;
01307 delete ds;
01308 return 0;
01309 }
01310
01311 void St_db_Maker::SetOff(const char *path)
01312 { AddAlias("Off",path,".onoff"); OnOff();}
01313
01314 void St_db_Maker::OnOff()
01315 {
01316 int Off,len;
01317 if (!fDataBase) return;
01318 TDataSet *onoff = Find(".onoff");
01319 if (!onoff) return;
01320
01321 TString tsBase,tsDir,tsTit;
01322 TDataSet *ono;
01323 TDataSetIter onoffNext(onoff);
01324 while((ono=onoffNext())) {
01325 Off = (strcmp("Off",ono->GetName())==0);
01326 tsDir = gSystem->DirName(ono->GetTitle());
01327 tsBase = gSystem->BaseName(ono->GetTitle());
01328 TRegexp rex(tsBase,1);
01329 TDataSet *dsDir = GetDataSet(tsDir);
01330 if (!dsDir) continue;
01331 if (GetMaker(dsDir) != this) continue;
01332 TDataSetIter nextVal(dsDir);
01333 TDataSet *val;
01334 while ((val=nextVal())) {
01335 const char *name = val->GetName();
01336 if(name[0]!='.') continue;
01337 tsTit = val->GetTitle();
01338 int ival = tsTit.Index(".Val");
01339 if (ival<0) continue;
01340 if (Off != (ival==0)) continue;
01341 if (rex.Index(name+1,&len)!=0) continue;
01342 if ( Off) tsTit.Replace(0,0,".Off");
01343 if (!Off) tsTit.Replace(0,4,"" );
01344 val->SetTitle(tsTit);
01345 printf("<%s::Set%s> %s/%s\n"
01346 ,ClassName(),ono->GetName(),(const char*)tsDir,val->GetName()+1);
01347 }
01348 }
01349 }
01350
01351 void St_db_Maker::SetMaxEntryTime(Int_t idate,Int_t itime)
01352 {
01353 TUnixTime ut;
01354 ut.SetGTime(idate,itime);
01355 fMaxEntryTime = ut.GetUTime();
01356 }
01357
01358
01359 void St_db_Maker::AddMaxEntryTimeOverride(Int_t idate,Int_t itime, char* dbType, char* dbDomain) {
01360
01361 std::string mDbType = "";
01362 std::string mDbDomain = "";
01363
01364 if (dbType) {
01365 for (char* p = dbType; *p != '\0'; p++) {
01366 *p = (char)std::tolower(*p);
01367 }
01368 dbType[0] = std::toupper(dbType[0]);
01369 mDbType = dbType;
01370 }
01371
01372 if (dbDomain) {
01373 for (char* p = dbDomain; *p != '\0'; p++) {
01374 *p = (char)std::tolower(*p);
01375 }
01376 mDbDomain = dbDomain;
01377 }
01378
01379 TUnixTime ut;
01380 ut.SetGTime(idate,itime);
01381 fMaxEntryTimeOverride.insert( std::make_pair<std::pair<std::string,std::string>,UInt_t>( std::make_pair<std::string,std::string>(mDbType,mDbDomain), ut.GetUTime() ) );
01382 }
01383
01384
01385 #define private public
01386 #include "TGeoManager.h"
01387
01388 int St_db_Maker::Snapshot (int flag)
01389 {
01390 int ians=0;
01391 TFile *tfSnap = 0;
01392 TObjectSet set("dbSnapshot",0);
01393 const char *fname = SAttr("dbSnapshot");
01394 if (!fname || !*fname) return 0;
01395 switch (flag) {
01396 case 0:
01397 if (gSystem->AccessPathName(fname, kFileExists)) return 0;
01398 if (gSystem->AccessPathName(fname, kReadPermission)) return 0;
01399 tfSnap = TFile::Open(fname,"READ");
01400 if (!tfSnap) return 0;
01401 if (tfSnap->IsZombie()) {delete tfSnap; return 0;}
01402
01403 Info("Snapshot","Use DB from file %s\n",fname);
01404 ians = set.Read("dbSnapshot");
01405 fDataBase = (TDataSet*)set.GetObject();
01406 set.DoOwner(0);
01407 assert(fDataBase);
01408
01409
01410
01411
01412
01413
01414
01415
01416 break;
01417
01418 case 1:
01419 if (!gSystem->AccessPathName(fname, kFileExists)) return 0;
01421 tfSnap = TFile::Open(fname,"NEW");
01422 if (!tfSnap || tfSnap->IsZombie()) {
01423 Error("Snapshot","Can not open file for write");
01424 return 0;
01425 }
01426
01427
01428
01429
01430
01431
01432 TDataSet *parent = fDataBase->GetParent();
01433 fDataBase->Shunt(0);
01434 set.SetObject(fDataBase);
01435 Info("Snapshot","Save DB to file %s\n",fname);
01436 ians = set.Write("dbSnapshot",TObject::kOverwrite);
01437 fDataBase->Shunt(parent);
01438 tfSnap->Close();
01439 break;
01440 }
01441 delete tfSnap;
01442 return ians;
01443 }
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01566
01567
01568
01569
01570