Correct cleaning of valid ids in QueryCDB
[u/mrichter/AliRoot.git] / STEER / CDB / AliCDBStorage.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 #include <TKey.h>
17 #include <TH1.h>
18 #include <TTree.h>
19 #include <TNtuple.h>
20 #include <TFile.h>
21 #include "AliCDBStorage.h"
22 #include "AliCDBGrid.h"
23
24 #include "AliCDBEntry.h"
25 #include "AliLog.h"
26
27 ClassImp(AliCDBStorage)
28
29 //_____________________________________________________________________________
30 AliCDBStorage::AliCDBStorage():
31   fValidFileIds(),
32   fRun(-1),
33   fPathFilter(),
34   fVersion(-1),
35   fMetaDataFilter(0),
36   fSelections(),
37   fURI(),
38   fType(),
39   fBaseFolder(),
40   fNretry(0),
41   fInitRetrySeconds(0)
42 {
43   // constructor
44
45   fValidFileIds.SetOwner(1);
46   fSelections.SetOwner(1);
47 }
48
49 //_____________________________________________________________________________
50 AliCDBStorage::~AliCDBStorage() {
51 // destructor
52
53   RemoveAllSelections();
54   fValidFileIds.Clear();
55   delete fMetaDataFilter;
56
57 }
58
59 //_____________________________________________________________________________
60 void AliCDBStorage::GetSelection(/*const*/ AliCDBId* id) {
61 // return required version and subversion from the list of selection criteria
62
63   TIter iter(&fSelections);
64   AliCDBId* aSelection;
65
66   // loop on the list of selection criteria
67   while ((aSelection = (AliCDBId*) iter.Next())) {
68     // check if selection element contains id's path and run (range) 
69     if (aSelection->Comprises(*id)) {
70       AliDebug(2,Form("Using selection criterion: %s ", aSelection->ToString().Data()));
71       // return required version and subversion
72
73       id->SetVersion(aSelection->GetVersion());
74       id->SetSubVersion(aSelection->GetSubVersion());
75       return;  
76     }
77   }
78
79   // no valid element is found in the list of selection criteria -> return
80   AliDebug(2,"Looking for objects with most recent version");
81   return;
82 }
83
84 //_____________________________________________________________________________
85 void AliCDBStorage::ReadSelectionFromFile(const char *fileName){
86 // read selection criteria list from file
87
88   RemoveAllSelections();
89
90   TList *list = GetIdListFromFile(fileName);
91   if(!list) return;
92
93   list->SetOwner();     
94   Int_t nId = list->GetEntries();
95   AliCDBId *id;
96   TKey *key;
97
98   for(int i=nId-1;i>=0;i--){
99     key = (TKey*) list->At(i);
100     id = (AliCDBId*) key->ReadObj();
101     if(id) AddSelection(*id);
102   }
103   delete list;
104   AliInfo(Form("Selection criteria list filled with %d entries",fSelections.GetEntries()));
105   PrintSelectionList();
106
107 }
108
109 //_____________________________________________________________________________
110 void AliCDBStorage::AddSelection(const AliCDBId& selection) {
111 // add a selection criterion
112
113   AliCDBPath path = selection.GetPath();
114   if(!path.IsValid()) return;
115
116   TIter iter(&fSelections);
117   const AliCDBId *anId;
118   while((anId = (AliCDBId*) iter.Next())){
119     if(selection.Comprises(*anId)){
120       AliWarning("This selection is more general than a previous one and will hide it!");
121       AliWarning(Form("%s", (anId->ToString()).Data()));
122       fSelections.AddBefore(anId, new AliCDBId(selection));
123       return;
124     }
125
126   }
127   fSelections.AddFirst(new AliCDBId(selection));
128 }
129
130 //_____________________________________________________________________________
131 void AliCDBStorage::AddSelection(const AliCDBPath& path,
132     const AliCDBRunRange& runRange, Int_t version, Int_t subVersion){
133   // add a selection criterion
134
135   AddSelection(AliCDBId(path, runRange, version, subVersion));
136 }
137
138 //_____________________________________________________________________________
139 void AliCDBStorage::AddSelection(const AliCDBPath& path,
140     Int_t firstRun, Int_t lastRun, Int_t version, Int_t subVersion){
141   // add a selection criterion
142
143   AddSelection(AliCDBId(path, firstRun, lastRun, version, subVersion));
144 }
145
146 //_____________________________________________________________________________
147 void AliCDBStorage::RemoveSelection(const AliCDBId& selection) {
148 // remove a selection criterion
149
150   TIter iter(&fSelections);
151   AliCDBId* aSelection;
152
153   while ((aSelection = (AliCDBId*) iter.Next())) {
154     if (selection.Comprises(*aSelection)) {
155       fSelections.Remove(aSelection);
156     }
157   }
158 }
159
160 //_____________________________________________________________________________
161 void AliCDBStorage::RemoveSelection(const AliCDBPath& path, 
162     const AliCDBRunRange& runRange){
163   // remove a selection criterion
164
165   RemoveSelection(AliCDBId(path, runRange, -1, -1));
166 }
167
168 //_____________________________________________________________________________
169 void AliCDBStorage::RemoveSelection(const AliCDBPath& path,
170     Int_t firstRun, Int_t lastRun){
171   // remove a selection criterion
172
173   RemoveSelection(AliCDBId(path, firstRun, lastRun, -1, -1));
174 }
175
176 //_____________________________________________________________________________
177 void AliCDBStorage::RemoveSelection(int position){
178 // remove a selection criterion from its position in the list
179
180   delete fSelections.RemoveAt(position);
181 }
182
183 //_____________________________________________________________________________
184 void AliCDBStorage::RemoveAllSelections(){
185 // remove all selection criteria
186
187   fSelections.Clear();
188 }
189
190 //_____________________________________________________________________________
191 void AliCDBStorage::PrintSelectionList(){
192 // prints the list of selection criteria
193
194   TIter iter(&fSelections);
195   AliCDBId* aSelection;
196
197   // loop on the list of selection criteria
198   int index=0;
199   while ((aSelection = (AliCDBId*) iter.Next())) {
200     AliInfo(Form("index %d -> selection: %s",index++, aSelection->ToString().Data()));
201   }
202
203 }
204
205 //_____________________________________________________________________________
206 AliCDBEntry* AliCDBStorage::Get(const AliCDBId& query) {
207 // get an AliCDBEntry object from the database
208
209   // check if query's path and runRange are valid
210   // query is invalid also if version is not specified and subversion is!
211   if (!query.IsValid()) {
212     AliError(Form("Invalid query: %s", query.ToString().Data()));
213     return NULL;
214   }
215
216   // query is not specified if path contains wildcard or runrange = [-1,-1]
217   if (!query.IsSpecified()) {
218     AliError(Form("Unspecified query: %s",
219           query.ToString().Data()));
220     return NULL;
221   }
222
223   // This is needed otherwise TH1  objects (histos, TTree's) are lost when file is closed!
224   Bool_t oldStatus = TH1::AddDirectoryStatus();
225   TH1::AddDirectory(kFALSE);
226
227   AliCDBEntry* entry = GetEntry(query);
228
229   if (oldStatus != kFALSE)
230     TH1::AddDirectory(kTRUE);
231
232   // if drain storage is set, drain entry into drain storage
233   if(entry && (AliCDBManager::Instance())->IsDrainSet())
234     AliCDBManager::Instance()->Drain(entry);
235
236   return entry;
237 }
238
239 //_____________________________________________________________________________
240 AliCDBEntry* AliCDBStorage::Get(const AliCDBPath& path, Int_t runNumber,
241     Int_t version, Int_t subVersion) {
242   // get an AliCDBEntry object from the database
243
244   return Get(AliCDBId(path, runNumber, runNumber, version, subVersion));
245 }
246
247 //_____________________________________________________________________________
248 AliCDBEntry* AliCDBStorage::Get(const AliCDBPath& path,
249     const AliCDBRunRange& runRange, Int_t version,
250     Int_t subVersion) {
251   // get an AliCDBEntry object from the database
252
253   return Get(AliCDBId(path, runRange, version, subVersion));
254 }
255
256 //_____________________________________________________________________________
257 TList* AliCDBStorage::GetAll(const AliCDBId& query) {
258 // get multiple AliCDBEntry objects from the database
259
260
261   if (!query.IsValid()) {
262     AliError(Form("Invalid query: %s", query.ToString().Data()));
263     return NULL;
264   }
265
266   if (query.IsAnyRange()) {
267     AliError(Form("Unspecified run or runrange: %s",
268           query.ToString().Data()));    
269     return NULL;
270   }     
271
272   // This is needed otherwise TH1  objects (histos, TTree's) are lost when file is closed!
273   Bool_t oldStatus = TH1::AddDirectoryStatus();
274   TH1::AddDirectory(kFALSE);
275
276   TList *result = GetEntries(query);
277
278   if (oldStatus != kFALSE)
279     TH1::AddDirectory(kTRUE);
280
281   Int_t nEntries = result->GetEntries();
282
283   AliInfo(Form("%d objects retrieved. Request was: %s",
284         nEntries, query.ToString().Data()));
285   for(int i=0; i<nEntries;i++){
286     AliCDBEntry *entry = (AliCDBEntry*) result->At(i);
287     AliInfo(Form("%s",entry->GetId().ToString().Data()));
288   }
289
290
291   // if drain storage is set, drain entries into drain storage
292   if((AliCDBManager::Instance())->IsDrainSet()){
293     for(int i = 0; i<result->GetEntries(); i++){
294       AliCDBEntry* entry = (AliCDBEntry*) result->At(i);
295       AliCDBManager::Instance()->Drain(entry);
296     }
297   }
298
299
300   return result;
301 }
302
303 //_____________________________________________________________________________
304 TList* AliCDBStorage::GetAll(const AliCDBPath& path, Int_t runNumber, 
305     Int_t version, Int_t subVersion) {
306   // get multiple AliCDBEntry objects from the database
307
308   return GetAll(AliCDBId(path, runNumber, runNumber, version,   
309         subVersion));
310 }
311
312 //_____________________________________________________________________________
313 TList* AliCDBStorage::GetAll(const AliCDBPath& path, 
314     const AliCDBRunRange& runRange, Int_t version, Int_t subVersion) {
315   // get multiple AliCDBEntry objects from the database
316
317   return GetAll(AliCDBId(path, runRange, version, subVersion));
318 }
319
320 //_____________________________________________________________________________
321 AliCDBId* AliCDBStorage::GetId(const AliCDBId& query) {
322 // get the Id of the valid object from the database (does not open the file)
323
324   // check if query's path and runRange are valid
325   // query is invalid also if version is not specified and subversion is!
326   if (!query.IsValid()) {
327     AliError(Form("Invalid query: %s", query.ToString().Data()));
328     return NULL;
329   }
330
331   // query is not specified if path contains wildcard or runrange = [-1,-1]
332   if (!query.IsSpecified()) {
333     AliError(Form("Unspecified query: %s",
334           query.ToString().Data()));
335     return NULL;
336   }
337
338   AliCDBId* id = GetEntryId(query);
339
340   return id;
341 }
342
343 //_____________________________________________________________________________
344 AliCDBId* AliCDBStorage::GetId(const AliCDBPath& path, Int_t runNumber,
345     Int_t version, Int_t subVersion) {
346   // get the Id of the valid object from the database (does not open the file)
347
348   return GetId(AliCDBId(path, runNumber, runNumber, version, subVersion));
349 }
350
351 //_____________________________________________________________________________
352 AliCDBId* AliCDBStorage::GetId(const AliCDBPath& path,
353     const AliCDBRunRange& runRange, Int_t version,
354     Int_t subVersion) {
355   // get the Id of the valid object from the database (does not open the file)
356
357   return GetId(AliCDBId(path, runRange, version, subVersion));
358 }
359
360 //_____________________________________________________________________________
361 Bool_t AliCDBStorage::Put(TObject* object, AliCDBId& id, AliCDBMetaData* metaData, const char* mirrors, AliCDBManager::DataType type) {
362 // store an AliCDBEntry object into the database
363
364   if (object==0x0) {
365     AliError("Null Entry! No storage will be done!");
366     return kFALSE;
367   } 
368
369   AliCDBEntry anEntry(object, id, metaData);
370
371   return Put(&anEntry, mirrors, type);
372 }
373
374 //_____________________________________________________________________________
375 Bool_t AliCDBStorage::Put(AliCDBEntry* entry, const char* mirrors, AliCDBManager::DataType type) {
376 // store an AliCDBEntry object into the database
377
378   if (!entry){
379     AliError("No entry!");
380     return kFALSE;
381   }
382
383   if (entry->GetObject()==0x0){
384     AliError("No valid object in CDB entry!");
385     return kFALSE;
386   }
387
388   if (!entry->GetId().IsValid()) {
389     AliError(Form("Invalid entry ID: %s",
390           entry->GetId().ToString().Data()));
391     return kFALSE;
392   }     
393
394   if (!entry->GetId().IsSpecified()) {
395     AliError(Form("Unspecified entry ID: %s",
396           entry->GetId().ToString().Data()));
397     return kFALSE;
398   }
399
400   AliCDBManager::DataType expectedType = GetDataType();
401
402   if(expectedType != AliCDBManager::kPrivate && type != expectedType) {
403     AliError(Form("It is forbidden to store %s data into a folder of type %s!",
404           AliCDBManager::GetDataTypeName(type),
405           AliCDBManager::GetDataTypeName(expectedType)));
406     return 0;
407   }
408
409
410   TString strMirrors(mirrors);
411   if(!strMirrors.IsNull() && !strMirrors.IsWhitespace())
412     return PutEntry(entry, mirrors);
413   else
414     return PutEntry(entry);
415 }
416
417 //_____________________________________________________________________________
418 void AliCDBStorage::QueryCDB(Int_t run, const char* pathFilter,
419     Int_t version, AliCDBMetaData* md){
420 // query CDB for files valid for given run, and fill list fValidFileIds
421 // Actual query is done in virtual function QueryValidFiles()
422 // If version is not specified, the query will fill fValidFileIds
423 // with highest versions
424
425   fRun = run;
426
427   fPathFilter = pathFilter;
428   if(!fPathFilter.IsValid()) {
429     AliError(Form("Filter not valid: %s", pathFilter));
430     fPathFilter = "*";
431     return;
432   }
433
434   fVersion = version;
435
436   AliInfo(Form("Querying files valid for run %d and path \"%s\" into CDB storage  \"%s://%s\"",
437         fRun, pathFilter, fType.Data(), fBaseFolder.Data()));
438
439   // In fValidFileIds, clear id for the same 3level path, if any
440   AliDebug(3, Form("Clearing list of CDB Id's previously loaded for path \"%s\"", pathFilter));
441   AliCDBPath filter(pathFilter);
442   for (Int_t i=fValidFileIds.GetEntries()-1; i>=0; --i) {
443     AliCDBId *rmMe = dynamic_cast<AliCDBId*>(fValidFileIds.At(i));
444     AliCDBPath rmPath = rmMe->GetAliCDBPath();
445     if (filter.Comprises(rmPath)) {
446       AliDebug(3,Form("Removing id \"%s\" matching: \"%s\"", rmPath.GetPath().Data(), pathFilter));
447       delete fValidFileIds.RemoveAt(i);
448     }
449   }
450
451   if(fMetaDataFilter) {delete fMetaDataFilter; fMetaDataFilter=0;}
452   if(md) fMetaDataFilter = dynamic_cast<AliCDBMetaData*> (md->Clone());
453
454   QueryValidFiles();
455
456   AliInfo(Form("%d valid files found!", fValidFileIds.GetEntries()));
457
458 }
459
460 //_____________________________________________________________________________
461 void AliCDBStorage::PrintQueryCDB(){
462 // print parameters used to load list of CDB Id's (fRun, fPathFilter, fVersion)
463
464   AliCDBId paramId(fPathFilter, fRun, fRun, fVersion);
465   AliInfo(Form("**** QueryCDB Parameters **** \n\t<%s>\n",
466         paramId.ToString().Data()));
467
468   if(fMetaDataFilter) fMetaDataFilter->PrintMetaData();
469
470
471   TString message = "**** Id's of valid objects found *****\n";
472   TIter iter(&fValidFileIds);
473   AliCDBId* anId=0;
474
475   // loop on the list of selection criteria
476   while ((anId = dynamic_cast<AliCDBId*>(iter.Next()))) {
477     message += Form("\t%s\n", anId->ToString().Data());
478   }
479   message += Form("\n\tTotal: %d objects found\n", fValidFileIds.GetEntriesFast());
480   AliInfo(Form("%s", message.Data()));
481 }
482
483 //_____________________________________________________________________________
484 AliCDBManager::DataType AliCDBStorage::GetDataType() const {
485 // returns the type of the data that should be stored into this storage:
486 // kConditions: conditions data; kReference: reference data; kPrivate: private (user-defined) data type
487
488   if(GetType() != "alien") return AliCDBManager::kPrivate;
489
490   TString condFolder = ((AliCDBGridParam*) AliCDBManager::Instance()->GetCondParam())->GetDBFolder();
491   TString refFolder = ((AliCDBGridParam*) AliCDBManager::Instance()->GetRefParam())->GetDBFolder();
492
493   if(GetBaseFolder().Contains(condFolder)) return AliCDBManager::kCondition;
494   if(GetBaseFolder().Contains(refFolder)) return AliCDBManager::kReference;
495
496   return AliCDBManager::kPrivate;
497 }
498
499 //_____________________________________________________________________________
500 void AliCDBStorage::SetMirrorSEs(const char* mirrors) {
501 // if the current storage is not of "alien" type, just issue a warning
502 // AliCDBGrid implements its own SetMirrorSEs method, classes for other storage types do not
503
504   TString storageType = GetType();
505   if(storageType != "alien"){
506     AliWarning(Form("The current storage is of type \"%s\". Setting of SEs to \"%s\" skipped!",storageType.Data(),mirrors));
507     return;
508   }
509   AliError("We should never get here!! AliCDBGrid must have masked this virtual method!");
510   return;
511 }
512
513 //_____________________________________________________________________________
514 const char* AliCDBStorage::GetMirrorSEs() const {
515 // if the current storage is not of "alien" type, just issue a warning
516 // AliCDBGrid implements its own GetMirrorSEs method, classes for other storage types do not
517
518   TString storageType = GetType();
519   if(storageType != "alien"){
520     AliWarning(Form("The current storage is of type \"%s\" and cannot handle SEs. Returning empty string!",storageType.Data()));
521     return "";
522   }
523   AliError("We should never get here!! AliCDBGrid must have masked this virtual method!");
524   return "";
525 }
526
527 //_____________________________________________________________________________
528 void AliCDBStorage::LoadTreeFromFile(AliCDBEntry *entry) const {
529 // Checks whether entry contains a TTree and in case loads it into memory
530
531   TObject *obj = (TObject*) entry->GetObject();
532   if (!obj) {
533     AliError("Cannot retrieve the object:");
534     entry->PrintMetaData();
535     return;
536   }
537
538   if (!strcmp(obj->ClassName(),TTree::Class_Name())) {
539
540     AliWarning("Entry contains a TTree! Loading baskets...");
541
542     TTree* tree = dynamic_cast<TTree*> (obj);
543
544     if(!tree) return;
545
546     tree->LoadBaskets();
547     tree->SetDirectory(0);
548   }
549   else if (!strcmp(obj->ClassName(),TNtuple::Class_Name())){
550
551     AliWarning("Entry contains a TNtuple! Loading baskets...");
552
553     TNtuple* ntu = dynamic_cast<TNtuple*> (obj);
554
555     if(!ntu) return;
556
557     ntu->LoadBaskets();
558     ntu->SetDirectory(0);
559   }
560
561   return;
562 }
563
564 // //_____________________________________________________________________________
565 // void AliCDBStorage::SetTreeToFile(AliCDBEntry *entry, TFile* file) const {
566 // // Checks whether entry contains a TTree and in case assigns it to memory
567 // 
568 //      AliCDBMetaData *md = dynamic_cast<AliCDBMetaData*> (entry->GetMetaData());
569 //      if(!md) return;
570 //      TString objStr = md->GetObjectClassName();
571 //      if(objStr != "TTree") return;
572 //      AliWarning("Entry contains a TTree! Setting file...");
573 // 
574 //      TTree* tree = dynamic_cast<TTree*> (entry->GetObject());
575 // 
576 //      if(!tree) return;
577 // 
578 // //   tree->SetDirectory(file);
579 //      tree->SetDirectory(0);
580 // 
581 //      return;
582 // }