Changes required by Effective C++
[u/mrichter/AliRoot.git] / STEER / AliCDBManager.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 //   Implementation of AliCDBManager and AliCDBParam classe
17 //   Author: Alberto Colla 
18 //   e-mail: Alberto.Colla@cern.ch
19 //-------------------------------------------------------------------------
20
21 #include "AliCDBManager.h"
22 #include "AliCDBStorage.h"
23 #include "AliLog.h"
24 #include "AliCDBDump.h"
25 #include "AliCDBLocal.h"
26 #include "AliCDBGrid.h"
27 #include "AliCDBEntry.h"
28 #include "AliCDBMetaData.h"
29
30 #include <TObjString.h>
31 #include <TSystem.h>
32
33 ClassImp(AliCDBParam)
34
35 ClassImp(AliCDBManager)
36
37 AliCDBManager* AliCDBManager::fgInstance = 0x0;
38
39 //_____________________________________________________________________________
40 AliCDBManager* AliCDBManager::Instance() {
41 // returns AliCDBManager instance (singleton)
42
43         if (!fgInstance) {
44                 fgInstance = new AliCDBManager();
45                 fgInstance->Init();
46         }
47
48         return fgInstance;
49 }
50
51 //_____________________________________________________________________________
52 void AliCDBManager::Init() {
53 // factory registering
54
55         RegisterFactory(new AliCDBDumpFactory());
56         RegisterFactory(new AliCDBLocalFactory()); 
57         // AliCDBGridFactory is registered only if AliEn libraries are enabled in Root
58         if(!gSystem->Exec("root-config --has-alien |grep yes 2>&1 > /dev/null")){ // returns 0 if yes
59                 AliInfo("AliEn classes enabled in Root. AliCDBGrid factory registered.");
60                 RegisterFactory(new AliCDBGridFactory());
61         }
62 }
63 //_____________________________________________________________________________
64 void AliCDBManager::Destroy() {
65 // delete ALCDBManager instance and active storages
66
67         if (fgInstance) {
68                 //fgInstance->Delete();
69                 delete fgInstance;
70                 fgInstance = 0x0;
71         }
72 }
73
74 //_____________________________________________________________________________
75 AliCDBManager::AliCDBManager():
76   TObject(),
77   fFactories(),
78   fActiveStorages(),
79   fSpecificStorages(),
80   fDefaultStorage(NULL),
81   fDrainStorage(NULL),
82   fEntryCache(),
83   fCache(kTRUE),
84   fRun(-1)
85 {
86 // default constuctor
87         fFactories.SetOwner(1);
88         fActiveStorages.SetOwner(1);
89         fSpecificStorages.SetOwner(1);
90         fEntryCache.SetOwner(1);
91 }
92
93 //_____________________________________________________________________________
94 AliCDBManager::~AliCDBManager() {
95 // destructor
96         ClearCache();
97         DestroyActiveStorages();
98         fFactories.Delete();
99         fDrainStorage = 0x0;
100         fDefaultStorage = 0x0;
101 }
102
103 //_____________________________________________________________________________
104 void AliCDBManager::PutActiveStorage(AliCDBParam* param, AliCDBStorage* storage){
105 // put a storage object into the list of active storages
106
107         fActiveStorages.Add(param, storage);
108         AliDebug(1, Form("Active storages: %d", fActiveStorages.GetEntries()));
109 }
110
111 //_____________________________________________________________________________
112 void AliCDBManager::RegisterFactory(AliCDBStorageFactory* factory) {
113 // add a storage factory to the list of registerd factories
114  
115         if (!fFactories.Contains(factory)) {
116                 fFactories.Add(factory);
117         }
118 }
119
120 //_____________________________________________________________________________
121 Bool_t AliCDBManager::HasStorage(const char* dbString) const {
122 // check if dbString is a URI valid for one of the registered factories 
123
124         TIter iter(&fFactories);
125
126         AliCDBStorageFactory* factory=0;
127         while ((factory = (AliCDBStorageFactory*) iter.Next())) {
128
129                 if (factory->Validate(dbString)) {
130                         return kTRUE;
131                 }       
132         }
133
134         return kFALSE;
135 }
136
137 //_____________________________________________________________________________
138 AliCDBParam* AliCDBManager::CreateParameter(const char* dbString) const {
139 // create AliCDBParam object from URI string
140
141         TIter iter(&fFactories);
142
143         AliCDBStorageFactory* factory=0;
144         while ((factory = (AliCDBStorageFactory*) iter.Next())) {
145                 AliCDBParam* param = factory->CreateParameter(dbString);
146                 if(param) return param;
147         }
148
149         return NULL;
150 }
151
152 //_____________________________________________________________________________
153 AliCDBStorage* AliCDBManager::GetStorage(const char* dbString) {
154 // get storage object from URI string
155         
156         AliCDBParam* param = CreateParameter(dbString);
157         if (!param) {
158                 return NULL;
159         }
160
161         AliCDBStorage* aStorage = GetStorage(param);
162
163         delete param;
164         return aStorage;
165 }
166
167 //_____________________________________________________________________________
168 AliCDBStorage* AliCDBManager::GetStorage(const AliCDBParam* param) {
169 // get storage object from AliCDBParam object
170
171         // if the list of active storages already contains
172         // the requested storage, return it
173         AliCDBStorage* aStorage = GetActiveStorage(param);
174         if (aStorage) {
175                 return aStorage;
176         }
177
178         TIter iter(&fFactories);
179
180         AliCDBStorageFactory* factory=0;
181
182         // loop on the list of registered factories
183         while ((factory = (AliCDBStorageFactory*) iter.Next())) {
184
185                 // each factory tries to create its storage from the parameter
186                 aStorage = factory->Create(param);
187                 if (aStorage) {
188                         PutActiveStorage(param->CloneParam(), aStorage);
189                         aStorage->SetURI(param->GetURI());
190                         return aStorage;
191                 }
192         }
193
194         return NULL;
195 }
196
197 //_____________________________________________________________________________
198 AliCDBStorage* AliCDBManager::GetActiveStorage(const AliCDBParam* param) {
199 // get a storage object from the list of active storages
200
201         return dynamic_cast<AliCDBStorage*> (fActiveStorages.GetValue(param));
202 }
203
204 //_____________________________________________________________________________
205 TList* AliCDBManager::GetActiveStorages() {
206 // return list of active storages
207 // user has responsibility to delete returned object
208
209         TList* result = new TList();
210
211         TIter iter(fActiveStorages.GetTable());
212         TPair* aPair=0;
213         while ((aPair = (TPair*) iter.Next())) {
214                 result->Add(aPair->Value());
215         }
216
217         return result;
218 }
219
220 //_____________________________________________________________________________
221 void AliCDBManager::SetDrain(const char* dbString) {
222 // set drain storage from URI string
223
224         fDrainStorage = GetStorage(dbString);   
225 }
226
227 //_____________________________________________________________________________
228 void AliCDBManager::SetDrain(const AliCDBParam* param) {
229 // set drain storage from AliCDBParam
230         
231         fDrainStorage = GetStorage(param);
232 }
233
234 //_____________________________________________________________________________
235 void AliCDBManager::SetDrain(AliCDBStorage* storage) {
236 // set drain storage from another active storage
237         
238         fDrainStorage = storage;
239 }
240
241 //_____________________________________________________________________________
242 Bool_t AliCDBManager::Drain(AliCDBEntry *entry) {
243 // drain retrieved object to drain storage
244
245         AliInfo("Draining into drain storage...");
246         return fDrainStorage->Put(entry);
247 }
248
249 //_____________________________________________________________________________
250 void AliCDBManager::SetDefaultStorage(const char* dbString) {
251 // sets default storage from URI string
252
253         AliInfo(Form("Setting Default storage to: %s",dbString));
254         fDefaultStorage = GetStorage(dbString);
255 }
256
257 //_____________________________________________________________________________
258 void AliCDBManager::SetDefaultStorage(const AliCDBParam* param) {
259 // set default storage from AliCDBParam object
260         
261         fDrainStorage = GetStorage(param);
262 }
263
264 //_____________________________________________________________________________
265 void AliCDBManager::SetDefaultStorage(AliCDBStorage* storage) {
266 // set default storage from another active storage
267         
268         fDefaultStorage = storage;
269 }
270
271 //_____________________________________________________________________________
272 void AliCDBManager::SetSpecificStorage(const char* calibType, const char* dbString) {
273 // sets storage specific for detector or calibration type (works with AliCDBManager::Get(...))
274
275         AliCDBParam *aPar = CreateParameter(dbString);
276         if(!aPar) return;
277         SetSpecificStorage(calibType, aPar);
278         delete aPar;
279 }
280
281 //_____________________________________________________________________________
282 void AliCDBManager::SetSpecificStorage(const char* calibType, AliCDBParam* param) {
283 // sets storage specific for detector or calibration type (works with AliCDBManager::Get(...))
284 // Default storage should be defined prior to any specific storages, e.g.:
285 // AliCDBManager::instance()->SetDefaultStorage("alien://");
286 // AliCDBManager::instance()->SetSpecificStorage("TPC","local://DB_TPC");
287 // AliCDBManager::instance()->SetSpecificStorage("RICH/Align","local://DB_TPCAlign");
288
289         if(!fDefaultStorage) {
290                 AliError("Please activate a default storage first!");   
291                 return;
292         }
293         
294         AliCDBPath aPath(calibType);
295         if(!aPath.IsValid()){
296                 AliError(Form("Not a valid path: %s", calibType));
297                 return;
298         }
299
300         TObjString *objCalibType = new TObjString(aPath.GetPath());
301         if(fSpecificStorages.Contains(objCalibType)){
302                 AliWarning(Form("Storage \"%s\" already activated! It will be replaced by the new one",
303                                         calibType));
304                 fSpecificStorages.Remove(objCalibType);
305         }
306         GetStorage(param);
307         fSpecificStorages.Add(objCalibType, param->CloneParam());
308 }
309
310 //_____________________________________________________________________________
311 AliCDBStorage* AliCDBManager::GetSpecificStorage(const char* calibType) {
312 // get storage specific for detector or calibration type 
313
314         AliCDBParam *checkPar = (AliCDBParam*) fSpecificStorages.GetValue(calibType);
315         if(!checkPar){
316                 AliError(Form("%s storage not found!",calibType));
317                 return NULL;
318         } else {
319                 return GetStorage(checkPar);
320         }
321         
322 }
323
324 //_____________________________________________________________________________
325 AliCDBParam* AliCDBManager::SelectSpecificStorage(const TString& path) {
326 // select storage valid for path from the list of specific storages
327
328         AliCDBPath aPath(path);
329         if(!aPath.IsValid()){
330                 AliError(Form("Not a valid path: %s", path.Data()));
331                 return NULL;
332         }
333
334         TIter iter(&fSpecificStorages);
335         TObjString *aCalibType=0;
336         AliCDBParam* aPar=0;
337         while((aCalibType = (TObjString*) iter.Next())){
338                 AliCDBPath calibTypePath(aCalibType->GetName());
339                 if(calibTypePath.Comprises(aPath)) {
340                         aPar = (AliCDBParam*) fSpecificStorages.GetValue(aCalibType);
341                         break;
342                 }
343         }
344         return aPar;
345 }
346
347 //_____________________________________________________________________________
348 AliCDBEntry* AliCDBManager::Get(const AliCDBPath& path, Int_t runNumber, 
349         Int_t version, Int_t subVersion) {
350 // get an AliCDBEntry object from the database
351
352         if(runNumber < 0){
353                 // RunNumber is not specified. Try with fRun
354                 if (fRun < 0){
355                         AliError("Run number neither specified in query nor set in AliCDBManager! Use AliCDBManager::SetRun.");
356                         return NULL;
357                 }
358                 runNumber = fRun;
359         }
360
361         return Get(AliCDBId(path, runNumber, runNumber, version, subVersion));
362 }
363
364 //_____________________________________________________________________________
365 AliCDBEntry* AliCDBManager::Get(const AliCDBPath& path, 
366         const AliCDBRunRange& runRange, Int_t version,
367         Int_t subVersion) {
368 // get an AliCDBEntry object from the database!
369
370         return Get(AliCDBId(path, runRange, version, subVersion));
371 }
372
373 //_____________________________________________________________________________
374 AliCDBEntry* AliCDBManager::Get(const AliCDBId& query) {        
375 // get an AliCDBEntry object from the database
376         
377         if(!fDefaultStorage) {
378                 AliError("No storage set!");
379                 return NULL;
380         }
381
382         // check if query's path and runRange are valid
383         // query is invalid also if version is not specified and subversion is!
384         if (!query.IsValid()) {
385                 AliError(Form("Invalid query: %s", query.ToString().Data()));
386                 return NULL;
387         }
388         
389         // query is not specified if path contains wildcard or run range= [-1,-1]
390         if (!query.IsSpecified()) {
391                 AliError(Form("Unspecified query: %s", 
392                                 query.ToString().Data()));
393                 return NULL;
394         }
395
396         if(fCache && query.GetFirstRun() != fRun) 
397                 AliWarning("Run number explicitly set in query: CDB cache temporarily disabled!");
398
399         
400         AliCDBEntry *entry=0;
401         
402         // first look into map of cached objects
403         if(fCache && query.GetFirstRun() == fRun)
404                 entry = (AliCDBEntry*) fEntryCache.GetValue(query.GetPath());
405
406         if(entry) {
407                 AliInfo(Form("Object %s retrieved from cache !!",query.GetPath().Data()));
408                 return entry;
409         }
410         
411         // Entry is not in cache -> retrieve it from CDB and cache it!!   
412         AliCDBStorage *aStorage=0;
413         AliCDBParam *aPar=SelectSpecificStorage(query.GetPath());
414
415         if(aPar) {
416                 aStorage=GetStorage(aPar);
417                 TString str = aPar->GetURI();
418                 AliDebug(2,Form("Looking into storage: %s",str.Data()));
419                 
420         } else {
421                 aStorage=GetDefaultStorage();
422                 AliDebug(2,"Looking into default storage");     
423         }
424                         
425         entry = aStorage->Get(query);
426         if (!entry) return NULL;
427
428         if(fCache && (query.GetFirstRun() == fRun)){
429                 AliDebug(2,Form("Caching entry %s !",query.GetPath().Data()));
430                 CacheEntry(query.GetPath(), entry);
431         }
432   
433         return entry;
434                 
435 }
436
437 //_____________________________________________________________________________
438 TList* AliCDBManager::GetAll(const AliCDBPath& path, Int_t runNumber,
439         Int_t version, Int_t subVersion) {
440 // get multiple AliCDBEntry objects from the database
441
442         if(runNumber < 0){
443                 // RunNumber is not specified. Try with fRun
444                 if (fRun < 0){
445                         AliError("Run number neither specified in query nor set in AliCDBManager! Use AliCDBManager::SetRun.");
446                         return NULL;
447                 }
448                 runNumber = fRun;
449         }
450
451         return GetAll(AliCDBId(path, runNumber, runNumber, version,     
452                         subVersion));
453 }
454
455 //_____________________________________________________________________________
456 TList* AliCDBManager::GetAll(const AliCDBPath& path, 
457         const AliCDBRunRange& runRange, Int_t version, Int_t subVersion) {
458 // get multiple AliCDBEntry objects from the database
459
460         return GetAll(AliCDBId(path, runRange, version, subVersion));
461 }
462
463 //_____________________________________________________________________________
464 TList* AliCDBManager::GetAll(const AliCDBId& query) {
465 // get multiple AliCDBEntry objects from the database
466 // Warning: this method works correctly only for queries of the type "Detector/*"
467 //              and not for more specific queries e.g. "Detector/Calib/*" !
468
469         if(!fDefaultStorage) {
470                 AliError("No storage set!");
471                 return NULL;
472         }
473
474         if (!query.IsValid()) {
475                 AliError(Form("Invalid query: %s", query.ToString().Data()));
476                 return NULL;
477         }
478
479         if((fSpecificStorages.GetEntries()>0) && query.GetPath().BeginsWith('*')){
480                 // if specific storages are active a query with "*" is ambiguous
481                 AliError("Query too generic in this context!");
482                 return NULL;            
483         }
484
485         if (query.IsAnyRange()) {
486                 AliError(Form("Unspecified run or runrange: %s",
487                                 query.ToString().Data()));      
488                 return NULL;
489         }       
490         
491         TObjString objStrLev0(query.GetLevel0());
492         AliCDBParam *aPar = (AliCDBParam*) fSpecificStorages.GetValue(&objStrLev0);
493
494         AliCDBStorage *aStorage;        
495         if(aPar) {
496                 aStorage=GetStorage(aPar);
497                 TString str = aPar->GetURI();
498                 AliDebug(2,Form("Looking into storage: %s",str.Data()));
499                 
500         } else {
501                 aStorage=GetDefaultStorage();
502                 AliDebug(2,"Looking into default storage");     
503         }
504
505         TList *result = aStorage->GetAll(query);
506
507         return result;
508 }
509
510 //_____________________________________________________________________________
511 Bool_t AliCDBManager::Put(TObject* object, AliCDBId& id,  AliCDBMetaData* metaData){
512 // store an AliCDBEntry object into the database
513
514         AliCDBEntry anEntry(object, id, metaData);
515         return Put(&anEntry);
516
517 }
518
519
520 //_____________________________________________________________________________
521 Bool_t AliCDBManager::Put(AliCDBEntry* entry){
522 // store an AliCDBEntry object into the database
523
524         if(!fDefaultStorage) {
525                 AliError("No storage set!");
526                 return kFALSE;
527         }
528
529         if (!entry){
530                 AliError("No entry!");
531                 return kFALSE;
532         }
533
534         if (!entry->GetId().IsValid()) {
535                 AliError(Form("Invalid entry ID: %s", 
536                         entry->GetId().ToString().Data()));
537                 return kFALSE;
538         }       
539
540         if (!entry->GetId().IsSpecified()) {
541                 AliError(Form("Unspecified entry ID: %s", 
542                         entry->GetId().ToString().Data()));
543                 return kFALSE;
544         }
545
546         AliCDBId id = entry->GetId();
547         AliCDBParam *aPar = SelectSpecificStorage(id.GetPath());
548
549         AliCDBStorage *aStorage;
550         
551         if(aPar) {
552                 aStorage=GetStorage(aPar);
553                 TString str = aPar->GetURI();
554                 AliDebug(2,Form("Storing object into storage: %s",str.Data()));
555                 
556         } else {
557                 aStorage=GetDefaultStorage();
558                 AliDebug(2,"Storing object into default storage");      
559         }
560
561         return aStorage->Put(entry);
562
563
564 }
565
566 //_____________________________________________________________________________
567 void AliCDBManager::CacheEntry(const char* path, AliCDBEntry* entry)
568 {
569 // cache AliCDBEntry. Cache is valid until run number is changed.
570
571         AliDebug(2,Form("Filling cache with entry %s",path));
572         fEntryCache.Add(new TObjString(path), entry);
573         AliDebug(2,Form("Cache entries: %d",fEntryCache.GetEntries()));
574
575 }
576
577 //_____________________________________________________________________________
578 void AliCDBManager::Print(Option_t* /*option*/) const
579 {
580 // Print list of active storages and their URIs
581         AliInfo(Form("Run number: %d\n",fRun));
582
583         TString output;
584         output = "Cache is ";
585         if(!fCache) output += "NOT ";
586         output += "ACTIVE\n";
587         AliInfo(output.Data());
588
589         if(fDefaultStorage) {
590                 AliInfo("*** Default Storage: ***");
591                 output = Form("%s\n",fDefaultStorage->GetURI().Data());
592                 AliInfo(output.Data());
593         }
594         if(fSpecificStorages.GetEntries()>0) {
595                 AliInfo("*** Specific Storages: ***");
596                 TIter iter(fSpecificStorages.GetTable());
597                 TPair *aPair=0;
598                 while((aPair = (TPair*) iter.Next())){
599                         output = Form("Key: %s - Storage: %s",
600                                 ((TObjString*) aPair->Key())->GetName(),
601                                 ((AliCDBParam*) aPair->Value())->GetURI().Data());
602                         AliInfo(output.Data());
603                 }
604                 printf("\n");
605         }
606         if(fDrainStorage) {
607                 AliInfo("*** Drain Storage: ***");
608                 output = Form("%s\n",fDrainStorage->GetURI().Data());
609                 AliInfo(output.Data());
610         }
611         AliInfo(Form("Total number of active storages: %d",fActiveStorages.GetEntries()));
612
613 }
614
615 //_____________________________________________________________________________
616 void AliCDBManager::SetRun(Long64_t run)
617 {
618 // Sets current run number.
619 // When the run number changes the caching is cleared.
620   
621         if (fRun == run)
622                 return;
623   
624         fRun = run;
625         ClearCache();
626         QueryCDB();
627 }
628
629 //_____________________________________________________________________________
630 void AliCDBManager::ClearCache(){
631 // clear AliCDBEntry cache
632
633         AliDebug(2,Form("Clearing cache!"));
634         fEntryCache.DeleteAll();
635         AliDebug(2,Form("Cache entries: %d",fEntryCache.GetEntries()));
636
637 }
638
639 //_____________________________________________________________________________
640 void AliCDBManager::DestroyActiveStorages() {
641 // delete list of active storages
642
643         fActiveStorages.DeleteAll();
644         fSpecificStorages.DeleteAll();
645 }
646
647 //_____________________________________________________________________________
648 void AliCDBManager::DestroyActiveStorage(AliCDBStorage* /*storage*/) {
649 // destroys active storage
650
651 /*
652         TIter iter(fActiveStorages.GetTable());
653         TPair* aPair;
654         while ((aPair = (TPair*) iter.Next())) {
655                 if(storage == (AliCDBStorage*) aPair->Value())
656                         delete fActiveStorages.Remove(aPair->Key());
657                         storage->Delete(); storage=0x0;
658         }
659 */      
660
661 }
662
663 //_____________________________________________________________________________
664 void AliCDBManager::QueryCDB() {
665 // query default and specific storages for files valid for fRun. Every storage loads the Ids into its list.
666
667         if (fRun < 0){
668                 AliError("Run number not yet set! Use AliCDBManager::SetRun.");
669         return;
670         }
671
672         AliInfo(Form("Querying default and specific storages for files valid for run %ld", (long) fRun));
673         fDefaultStorage->QueryCDB(fRun);
674
675         TIter iter(&fSpecificStorages);
676         TObjString *aCalibType=0;
677         AliCDBParam* aPar=0;
678         while((aCalibType = dynamic_cast<TObjString*> (iter.Next()))){
679                 aPar = (AliCDBParam*) fSpecificStorages.GetValue(aCalibType);
680                 if(aPar) {
681                         AliDebug(2,Form("Qerying specific storage %s",aCalibType->GetName()));
682                         GetStorage(aPar)->QueryCDB(fRun,aCalibType->GetName());
683
684                 }
685         }
686
687 }
688
689
690 ///////////////////////////////////////////////////////////
691 // AliCDBManager Parameter class                         //
692 // interface to specific AliCDBParameter class           //
693 // (AliCDBGridParam, AliCDBLocalParam, AliCDBDumpParam)  //
694 ///////////////////////////////////////////////////////////
695
696 AliCDBParam::AliCDBParam():
697   fType(),
698   fURI()
699 {
700 // constructor
701
702 }
703
704 //_____________________________________________________________________________
705 AliCDBParam::~AliCDBParam() {
706 // destructor
707
708 }
709