histogram initialization forgot in previous commit
[u/mrichter/AliRoot.git] / STEER / CDB / AliCDBLocal.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 /////////////////////////////////////////////////////////////////////////////////////////////////
17 //                                                                                             //
18 // AliCDBLocal                                                                                 //
19 // access class to a DataBase in a local storage                                               //
20 //                                                                                             //
21 /////////////////////////////////////////////////////////////////////////////////////////////////
22
23 #include <cstdlib>
24 #include <TSystem.h>
25 #include <TObjString.h>
26 #include <TRegexp.h>
27 #include <TFile.h>
28 #include <TKey.h>
29
30 #include "AliCDBLocal.h"
31 #include "AliCDBEntry.h"
32 #include "AliLog.h"
33
34 ClassImp(AliCDBLocal)
35
36 //_____________________________________________________________________________
37 AliCDBLocal::AliCDBLocal(const char* baseDir):
38 fBaseDirectory(baseDir) 
39 {
40 // constructor
41
42   AliDebug(1, Form("fBaseDirectory = %s",fBaseDirectory.Data()));
43
44         // check baseDire: trying to cd to baseDir; if it does not exist, create it
45         void* dir = gSystem->OpenDirectory(baseDir);
46         if (dir == NULL) {
47                 if (gSystem->mkdir(baseDir, kTRUE)) {
48                         AliError(Form("Can't open directory <%s>!", baseDir));
49                 }
50
51         } else {
52                 AliDebug(2,Form("Folder <%s> found",fBaseDirectory.Data()));
53                 gSystem->FreeDirectory(dir);
54         }
55         fType="local";
56         fBaseFolder = fBaseDirectory;
57 }
58
59 //_____________________________________________________________________________
60 AliCDBLocal::~AliCDBLocal() {
61 // destructor
62
63 }
64
65
66 //_____________________________________________________________________________
67 Bool_t AliCDBLocal::FilenameToId(const char* filename, AliCDBRunRange& runRange,
68         Int_t& version, Int_t& subVersion) {
69 // build AliCDBId from filename numbers
70
71
72         Ssiz_t mSize;
73
74         // valid filename: Run#firstRun_#lastRun_v#version_s#subVersion.root
75         TRegexp keyPattern("^Run[0-9]+_[0-9]+_v[0-9]+_s[0-9]+.root$");
76         keyPattern.Index(filename, &mSize);
77         if (!mSize) {
78                 AliDebug(2, Form("Bad filename <%s>.", filename));
79                 return kFALSE;
80         }
81
82         TString idString(filename);
83         idString.Resize(idString.Length() - sizeof(".root") + 1);
84
85         TObjArray* strArray = (TObjArray*) idString.Tokenize("_");
86
87         TString firstRunString(((TObjString*) strArray->At(0))->GetString());
88         runRange.SetFirstRun(atoi(firstRunString.Data() + 3));
89         runRange.SetLastRun(atoi(((TObjString*) strArray->At(1))->GetString()));
90         
91         TString verString(((TObjString*) strArray->At(2))->GetString());
92         version = atoi(verString.Data() + 1);
93
94         TString subVerString(((TObjString*) strArray->At(3))->GetString());
95         subVersion = atoi(subVerString.Data() + 1);
96
97         delete strArray;
98
99         return kTRUE;
100 }
101
102
103 //_____________________________________________________________________________
104 Bool_t AliCDBLocal::IdToFilename(const AliCDBId& id, TString& filename) const {
105 // build file name from AliCDBId data (run range, version, subVersion)
106
107   AliDebug(1, Form("fBaseDirectory = %s",fBaseDirectory.Data()));
108
109         if (!id.GetAliCDBRunRange().IsValid()) {
110                 AliDebug(2,Form("Invalid run range <%d, %d>.", 
111                         id.GetFirstRun(), id.GetLastRun()));
112                 return kFALSE;
113         }
114
115         if (id.GetVersion() < 0) {
116                 AliDebug(2,Form("Invalid version <%d>.", id.GetVersion()));
117                 return kFALSE;
118         }
119
120         if (id.GetSubVersion() < 0) {
121                 AliDebug(2,Form("Invalid subversion <%d>.", id.GetSubVersion()));
122                 return kFALSE;
123         }
124  
125         filename = Form("Run%d_%d_v%d_s%d.root", id.GetFirstRun(), id.GetLastRun(),
126                                                  id.GetVersion(), id.GetSubVersion());
127
128         filename.Prepend(fBaseDirectory +'/' + id.GetPath() + '/');
129
130         return kTRUE;
131 }
132
133 //_____________________________________________________________________________
134 Bool_t AliCDBLocal::PrepareId(AliCDBId& id) {
135 // prepare id (version, subVersion) of the object that will be stored (called by PutEntry)
136
137         TString dirName = Form("%s/%s", fBaseDirectory.Data(), id.GetPath().Data());
138
139         // go to the path; if directory does not exist, create it
140         void* dirPtr = gSystem->OpenDirectory(dirName);
141         if (!dirPtr) {
142                 gSystem->mkdir(dirName, kTRUE);
143                 dirPtr = gSystem->OpenDirectory(dirName);
144
145                 if (!dirPtr) {
146                         AliError(Form("Can't create directory <%s>!", 
147                                         dirName.Data()));
148                         return kFALSE;
149                 }
150         }
151
152         const char* filename;
153         AliCDBRunRange aRunRange; // the runRange got from filename
154         AliCDBRunRange lastRunRange(-1,-1); // highest runRange found
155         Int_t aVersion, aSubVersion; // the version subVersion got from filename
156         Int_t lastVersion = 0, lastSubVersion = -1; // highest version and subVersion found
157
158         if (!id.HasVersion()) { // version not specified: look for highest version & subVersion
159                                 
160                 while ((filename = gSystem->GetDirEntry(dirPtr))) { // loop on the files
161
162                         TString aString(filename);
163                         if (aString == "." || aString == "..") continue;
164         
165                         if (!FilenameToId(filename, aRunRange, aVersion, 
166                                 aSubVersion)) {
167                                 AliDebug(2,Form(
168                                         "Bad filename <%s>! I'll skip it.", 
169                                         filename));
170                                 continue;
171                         }
172                         
173                         if (!aRunRange.Overlaps(id.GetAliCDBRunRange())) continue;
174                         if(aVersion < lastVersion) continue;
175                         if(aVersion > lastVersion) lastSubVersion = -1;
176                         if(aSubVersion < lastSubVersion) continue;
177                         lastVersion = aVersion;
178                         lastSubVersion = aSubVersion;
179                         lastRunRange = aRunRange;
180                 }
181
182                 id.SetVersion(lastVersion);
183                 id.SetSubVersion(lastSubVersion + 1);
184
185         } else { // version specified, look for highest subVersion only
186                 
187                 while ((filename = gSystem->GetDirEntry(dirPtr))) { // loop on the files
188                         
189                         TString aString(filename);
190                         if (aString == "." || aString == "..") {
191                                 continue;
192                         }
193
194                         if (!FilenameToId(filename, aRunRange, aVersion, 
195                                 aSubVersion)) {
196                                 AliDebug(2,Form(
197                                         "Bad filename <%s>!I'll skip it.",
198                                         filename));     
199                                 continue;
200                         }
201
202                         if (aRunRange.Overlaps(id.GetAliCDBRunRange()) 
203                                 && aVersion == id.GetVersion()
204                                 && aSubVersion > lastSubVersion) {
205                                 lastSubVersion = aSubVersion;
206                                 lastRunRange = aRunRange;
207                         }
208         
209                 }
210                 
211                 id.SetSubVersion(lastSubVersion + 1);
212         }
213
214         gSystem->FreeDirectory(dirPtr);
215
216         TString lastStorage = id.GetLastStorage();
217         if(lastStorage.Contains(TString("grid"), TString::kIgnoreCase) &&
218            id.GetSubVersion() > 0 ){
219                 AliError(Form("Grid to Local Storage error! local object with version v%d_s%d found:",id.GetVersion(), id.GetSubVersion()-1));
220                 AliError(Form("This object has been already transferred from Grid (check v%d_s0)!",id.GetVersion()));
221                 return kFALSE;
222         }
223
224         if(lastStorage.Contains(TString("new"), TString::kIgnoreCase) &&
225            id.GetSubVersion() > 0 ){
226                 AliDebug(2, Form("A NEW object is being stored with version v%d_s%d",
227                                         id.GetVersion(),id.GetSubVersion()));
228                 AliDebug(2, Form("and it will hide previously stored object with v%d_s%d!",
229                                         id.GetVersion(),id.GetSubVersion()-1));
230         }
231
232         if(!lastRunRange.IsAnyRange() && !(lastRunRange.IsEqual(& id.GetAliCDBRunRange()))) 
233                 AliWarning(Form("Run range modified w.r.t. previous version (Run%d_%d_v%d_s%d)",
234                         lastRunRange.GetFirstRun(), lastRunRange.GetLastRun(), 
235                         id.GetVersion(), id.GetSubVersion()-1));
236
237         return kTRUE;
238 }
239
240 // //_____________________________________________________________________________
241 // Bool_t AliCDBLocal::GetId(const AliCDBId& query, AliCDBId& result) {
242 // // look for filename matching query (called by GetEntry)
243 // 
244 //      TString dirName = Form("%s/%s", fBaseDirectory.Data(), query.GetPath().Data());
245 // 
246 //      void* dirPtr = gSystem->OpenDirectory(dirName);
247 //      if (!dirPtr) {
248 //              AliDebug(2,Form("Directory <%s> not found", (query.GetPath()).Data()));
249 //              AliDebug(2,Form("in DB folder %s", fBaseDirectory.Data()));
250 //              return kFALSE;
251 //      }
252 // 
253 //      const char* filename;
254 // 
255 //      AliCDBRunRange aRunRange; // the runRange got from filename
256 //      Int_t aVersion, aSubVersion; // the version and subVersion got from filename
257 // 
258 //      if (!query.HasVersion()) { // neither version and subversion specified -> look for highest version and subVersion
259 // 
260 //              while ((filename = gSystem->GetDirEntry(dirPtr))) { // loop on files
261 // 
262 //                      TString aString(filename);
263 //                      if (aString == "." || aString == "..") continue;
264 // 
265 //                      if (!FilenameToId(filename, aRunRange, aVersion, aSubVersion)) continue;
266 //                         // aRunRange, aVersion, aSubVersion filled from filename
267 // 
268 //                      if (!aRunRange.Comprises(query.GetAliCDBRunRange())) continue;
269 //                      // aRunRange contains requested run!
270 // 
271 //                      if (result.GetVersion() < aVersion) {
272 //                              result.SetVersion(aVersion);
273 //                              result.SetSubVersion(aSubVersion);
274 // 
275 //                              result.SetFirstRun(
276 //                                      aRunRange.GetFirstRun());
277 //                              result.SetLastRun(
278 //                                      aRunRange.GetLastRun());
279 // 
280 //                      } else if (result.GetVersion() == aVersion
281 //                              && result.GetSubVersion()
282 //                                      < aSubVersion) {
283 // 
284 //                              result.SetSubVersion(aSubVersion);
285 // 
286 //                              result.SetFirstRun(
287 //                                      aRunRange.GetFirstRun());
288 //                              result.SetLastRun(
289 //                                      aRunRange.GetLastRun());
290 //                      } else if (result.GetVersion() == aVersion
291 //                              && result.GetSubVersion() == aSubVersion){
292 //                                      AliDebug(2,Form("More than one object valid for run %d, version %d_%d!",
293 //                                      query.GetFirstRun(), aVersion, aSubVersion));
294 //                              gSystem->FreeDirectory(dirPtr);
295 //                              return kFALSE;
296 //                              }
297 //              }
298 // 
299 //      } else if (!query.HasSubVersion()) { // version specified but not subversion -> look for highest subVersion
300 // 
301 //              result.SetVersion(query.GetVersion());
302 // 
303 //              while ((filename = gSystem->GetDirEntry(dirPtr))) { // loop on files
304 // 
305 //                         TString aString(filename);
306 //                         if (aString == "." || aString == "..") continue;
307 // 
308 //                      if (!FilenameToId(filename, aRunRange, aVersion, aSubVersion)) continue;
309 //                         // aRunRange, aVersion, aSubVersion filled from filename
310 // 
311 //                         if (!aRunRange.Comprises(query.GetAliCDBRunRange())) continue; 
312 //                      // aRunRange contains requested run!
313 // 
314 //                      if(query.GetVersion() != aVersion) continue;
315 //                      // aVersion is requested version!
316 // 
317 //                      if(result.GetSubVersion() == aSubVersion){
318 //                                      AliDebug(2,Form("More than one object valid for run %d, version %d_%d!",
319 //                                      query.GetFirstRun(), aVersion, aSubVersion));
320 //                              gSystem->FreeDirectory(dirPtr);
321 //                              return kFALSE; 
322 //                      }
323 //                      if( result.GetSubVersion() < aSubVersion) {
324 // 
325 //                                 result.SetSubVersion(aSubVersion);
326 // 
327 //                                 result.SetFirstRun(
328 //                                      aRunRange.GetFirstRun());
329 //                                 result.SetLastRun(
330 //                                      aRunRange.GetLastRun());
331 //                      } 
332 //                 }
333 // 
334 //      } else { // both version and subversion specified
335 // 
336 //              while ((filename = gSystem->GetDirEntry(dirPtr))) { // loop on files
337 // 
338 //                         TString aString(filename);
339 //                         if (aString == "." || aString == "..") continue;
340 // 
341 //                         if (!FilenameToId(filename, aRunRange, aVersion, aSubVersion)) continue;
342 //                         // aRunRange, aVersion, aSubVersion filled from filename
343 // 
344 //                      if (!aRunRange.Comprises(query.GetAliCDBRunRange())) continue;
345 //                      // aRunRange contains requested run!
346 // 
347 //                      if(query.GetVersion() != aVersion || query.GetSubVersion() != aSubVersion) continue;
348 //                      // aVersion and aSubVersion are requested version and subVersion!
349 // 
350 //                      if(result.GetVersion() == aVersion && result.GetSubVersion() == aSubVersion){
351 //                                      AliDebug(2,Form("More than one object valid for run %d, version %d_%d!",
352 //                                      query.GetFirstRun(), aVersion, aSubVersion));
353 //                              gSystem->FreeDirectory(dirPtr);
354 //                              return kFALSE;
355 //                      }
356 //                      result.SetVersion(aVersion);
357 //                      result.SetSubVersion(aSubVersion);
358 //                      result.SetFirstRun(aRunRange.GetFirstRun());
359 //                      result.SetLastRun(aRunRange.GetLastRun());
360 // 
361 //              }
362 //      }
363 // 
364 //      gSystem->FreeDirectory(dirPtr);
365 // 
366 //      return kTRUE;
367 // }
368
369 //_____________________________________________________________________________
370 AliCDBId* AliCDBLocal::GetId(const AliCDBId& query) {
371 // look for filename matching query (called by GetEntryId)
372
373         TString dirName = Form("%s/%s", fBaseDirectory.Data(), query.GetPath().Data());
374
375         void* dirPtr = gSystem->OpenDirectory(dirName);
376         if (!dirPtr) {
377                 AliDebug(2,Form("Directory <%s> not found", (query.GetPath()).Data()));
378                 AliDebug(2,Form("in DB folder %s", fBaseDirectory.Data()));
379                 return NULL;
380         }
381
382         const char* filename;
383         AliCDBId *result = new AliCDBId();
384         result->SetPath(query.GetPath());
385
386         AliCDBRunRange aRunRange; // the runRange got from filename
387         Int_t aVersion, aSubVersion; // the version and subVersion got from filename
388
389         if (!query.HasVersion()) { // neither version and subversion specified -> look for highest version and subVersion
390
391                 while ((filename = gSystem->GetDirEntry(dirPtr))) { // loop on files
392
393                         TString aString(filename);
394                         if (aString == "." || aString == "..") continue;
395
396                         if (!FilenameToId(filename, aRunRange, aVersion, aSubVersion)) continue;
397                         // aRunRange, aVersion, aSubVersion filled from filename
398
399                         if (!aRunRange.Comprises(query.GetAliCDBRunRange())) continue;
400                         // aRunRange contains requested run!
401
402                         AliDebug(1,Form("Filename %s matches\n",filename));
403
404                         if (result->GetVersion() < aVersion) {
405                                 result->SetVersion(aVersion);
406                                 result->SetSubVersion(aSubVersion);
407
408                                 result->SetFirstRun(
409                                         aRunRange.GetFirstRun());
410                                 result->SetLastRun(
411                                         aRunRange.GetLastRun());
412
413                         } else if (result->GetVersion() == aVersion
414                                 && result->GetSubVersion()
415                                         < aSubVersion) {
416
417                                 result->SetSubVersion(aSubVersion);
418
419                                 result->SetFirstRun(
420                                         aRunRange.GetFirstRun());
421                                 result->SetLastRun(
422                                         aRunRange.GetLastRun());
423                         } else if (result->GetVersion() == aVersion
424                                 && result->GetSubVersion() == aSubVersion){
425                                 AliError(Form("More than one object valid for run %d, version %d_%d!",
426                                         query.GetFirstRun(), aVersion, aSubVersion));
427                                 gSystem->FreeDirectory(dirPtr);
428                                 delete result;
429                                 return NULL;
430                                 }
431                 }
432
433         } else if (!query.HasSubVersion()) { // version specified but not subversion -> look for highest subVersion
434
435                 result->SetVersion(query.GetVersion());
436
437                 while ((filename = gSystem->GetDirEntry(dirPtr))) { // loop on files
438
439                         TString aString(filename);
440                         if (aString == "." || aString == "..") continue;
441
442                         if (!FilenameToId(filename, aRunRange, aVersion, aSubVersion)) continue;
443                         // aRunRange, aVersion, aSubVersion filled from filename
444
445                         if (!aRunRange.Comprises(query.GetAliCDBRunRange())) continue; 
446                         // aRunRange contains requested run!
447
448                         if(query.GetVersion() != aVersion) continue;
449                         // aVersion is requested version!
450
451                         if(result->GetSubVersion() == aSubVersion){
452                                 AliError(Form("More than one object valid for run %d, version %d_%d!",
453                                         query.GetFirstRun(), aVersion, aSubVersion));
454                                 gSystem->FreeDirectory(dirPtr);
455                                 delete result;
456                                 return NULL;
457                         }
458                         if( result->GetSubVersion() < aSubVersion) {
459
460                                 result->SetSubVersion(aSubVersion);
461
462                                 result->SetFirstRun(
463                                         aRunRange.GetFirstRun());
464                                 result->SetLastRun(
465                                         aRunRange.GetLastRun());
466                         } 
467                 }
468
469         } else { // both version and subversion specified
470
471                 //AliCDBId dataId(queryId.GetAliCDBPath(), -1, -1, -1, -1);
472         //Bool_t result;
473         while ((filename = gSystem->GetDirEntry(dirPtr))) { // loop on files
474
475                         TString aString(filename);
476                         if (aString == "." || aString == "..") continue;
477
478                         if (!FilenameToId(filename, aRunRange, aVersion, aSubVersion)) continue;
479                         // aRunRange, aVersion, aSubVersion filled from filename
480
481                         if (!aRunRange.Comprises(query.GetAliCDBRunRange())) continue;
482                         // aRunRange contains requested run!
483
484                         if(query.GetVersion() != aVersion || query.GetSubVersion() != aSubVersion) continue;
485                         // aVersion and aSubVersion are requested version and subVersion!
486
487                         if(result->GetVersion() == aVersion && result->GetSubVersion() == aSubVersion){
488                                 AliError(Form("More than one object valid for run %d, version %d_%d!",
489                                         query.GetFirstRun(), aVersion, aSubVersion));
490                                 gSystem->FreeDirectory(dirPtr);
491                                 delete result;
492                                 return NULL;
493                         }
494                         result->SetVersion(aVersion);
495                         result->SetSubVersion(aSubVersion);
496                         result->SetFirstRun(aRunRange.GetFirstRun());
497                         result->SetLastRun(aRunRange.GetLastRun());
498                         
499                 }
500         }
501
502         gSystem->FreeDirectory(dirPtr);
503
504         return result;
505 }
506
507 //_____________________________________________________________________________
508 AliCDBEntry* AliCDBLocal::GetEntry(const AliCDBId& queryId) {
509 // get AliCDBEntry from the database
510
511         AliCDBId* dataId = GetEntryId(queryId);
512
513         if (!dataId || !dataId->IsSpecified()) return NULL;
514
515         TString filename;
516         if (!IdToFilename(*dataId, filename)) {
517
518                 AliDebug(2,Form("Bad data ID encountered! Subnormal error!"));
519                 delete dataId;
520                 return NULL;
521         }
522
523         TFile file(filename, "READ"); // open file
524         if (!file.IsOpen()) {
525                 AliDebug(2,Form("Can't open file <%s>!", filename.Data()));
526                 delete dataId;
527                 return NULL;
528         }
529
530         // get the only AliCDBEntry object from the file
531         // the object in the file is an AliCDBEntry entry named "AliCDBEntry"
532
533         AliCDBEntry* anEntry = dynamic_cast<AliCDBEntry*> (file.Get("AliCDBEntry"));
534         if (!anEntry) {
535                 AliDebug(2,Form("Bad storage data: No AliCDBEntry in file!"));
536                 file.Close();
537                 delete dataId;
538                 return NULL;
539         }
540
541         AliCDBId& entryId = anEntry->GetId();
542
543         // The object's Id are not reset during storage
544         // If object's Id runRange or version do not match with filename,
545         // it means that someone renamed file by hand. In this case a warning msg is issued.
546
547         anEntry-> SetLastStorage("local");
548
549         if(!entryId.IsEqual(dataId)){
550                 AliWarning(Form("Mismatch between file name and object's Id!"));
551                 AliWarning(Form("File name: %s", dataId->ToString().Data()));
552                 AliWarning(Form("Object's Id: %s", entryId.ToString().Data()));
553         }
554
555         // Check whether entry contains a TTree. In case load the tree in memory!
556         LoadTreeFromFile(anEntry);
557
558         // close file, return retieved entry
559         file.Close();
560         delete dataId;
561         return anEntry;
562 }
563
564 //_____________________________________________________________________________
565 AliCDBId* AliCDBLocal::GetEntryId(const AliCDBId& queryId) {
566 // get AliCDBId from the database
567
568         AliCDBId* dataId = 0;
569
570         // look for a filename matching query requests (path, runRange, version, subVersion)
571         if (!queryId.HasVersion()) {
572                 // if version is not specified, first check the selection criteria list
573                 AliCDBId selectedId(queryId);
574                 GetSelection(&selectedId);
575                 dataId = GetId(selectedId);
576         } else {
577                 dataId = GetId(queryId);
578         }
579
580         if (dataId && !dataId->IsSpecified()) {
581                 delete dataId;
582                 return NULL;
583         }
584
585         return dataId;
586 }
587
588 //_____________________________________________________________________________
589 void AliCDBLocal::GetEntriesForLevel0(const char* level0,
590         const AliCDBId& queryId, TList* result) {
591 // multiple request (AliCDBStorage::GetAll)
592
593         TString level0Dir = Form("%s/%s", fBaseDirectory.Data(), level0);
594
595         void* level0DirPtr = gSystem->OpenDirectory(level0Dir);
596         if (!level0DirPtr) {
597                 AliDebug(2,Form("Can't open level0 directory <%s>!",
598                         level0Dir.Data()));
599                 return;
600         }
601
602         const char* level1;
603         Long_t flag=0;
604         while ((level1 = gSystem->GetDirEntry(level0DirPtr))) {
605
606                 TString level1Str(level1);
607                 if (level1Str == "." || level1Str == "..") {
608                         continue;
609                 }
610                 
611                 TString fullPath = Form("%s/%s",level0Dir.Data(), level1); 
612
613                 Int_t res=gSystem->GetPathInfo(fullPath.Data(), 0, (Long64_t*) 0, &flag, 0);
614                 
615                 if(res){
616                         AliDebug(2, Form("Error reading entry %s !",level1Str.Data()));
617                         continue;
618                 }
619                 if(!(flag&2)) continue; // bit 1 of flag = directory!
620                 
621                 if (queryId.GetAliCDBPath().Level1Comprises(level1)) {
622                         GetEntriesForLevel1(level0, level1, queryId, result);
623                 }
624         }
625
626         gSystem->FreeDirectory(level0DirPtr);
627 }
628
629 //_____________________________________________________________________________
630 void AliCDBLocal::GetEntriesForLevel1(const char* level0, const char* level1,
631         const AliCDBId& queryId, TList* result) {
632 // multiple request (AliCDBStorage::GetAll)
633
634         TString level1Dir = Form("%s/%s/%s", fBaseDirectory.Data(), level0,level1);
635
636         void* level1DirPtr = gSystem->OpenDirectory(level1Dir);
637         if (!level1DirPtr) {
638                 AliDebug(2,Form("Can't open level1 directory <%s>!",
639                         level1Dir.Data()));
640                 return;
641         }
642
643         const char* level2;
644         Long_t flag=0;
645         while ((level2 = gSystem->GetDirEntry(level1DirPtr))) {
646
647                 TString level2Str(level2);
648                 if (level2Str == "." || level2Str == "..") {
649                         continue;
650                 }
651
652                 TString fullPath = Form("%s/%s",level1Dir.Data(), level2); 
653
654                 Int_t res=gSystem->GetPathInfo(fullPath.Data(), 0, (Long64_t*) 0, &flag, 0);
655                 
656                 if(res){
657                         AliDebug(2, Form("Error reading entry %s !",level2Str.Data()));
658                         continue;
659                 }
660                 if(!(flag&2)) continue; // bit 1 of flag = directory!
661                 
662                 if (queryId.GetAliCDBPath().Level2Comprises(level2)) {
663
664                         AliCDBPath entryPath(level0, level1, level2);
665                         AliCDBId entryId(entryPath, queryId.GetAliCDBRunRange(),
666                                 queryId.GetVersion(), queryId.GetSubVersion());
667
668                         AliCDBEntry* anEntry = GetEntry(entryId);
669                         if (anEntry) {
670                                 result->Add(anEntry);
671                         }
672                 }
673         }
674
675         gSystem->FreeDirectory(level1DirPtr);
676 }
677
678 //_____________________________________________________________________________
679 TList* AliCDBLocal::GetEntries(const AliCDBId& queryId) {
680 // multiple request (AliCDBStorage::GetAll)
681         
682         void* storageDirPtr = gSystem->OpenDirectory(fBaseDirectory);
683         if (!storageDirPtr) {
684                 AliDebug(2,Form("Can't open storage directory <%s>",
685                         fBaseDirectory.Data()));
686                 return NULL;
687         }
688
689         TList* result = new TList();
690         result->SetOwner();
691
692         const char* level0;
693         Long_t flag=0;
694         while ((level0 = gSystem->GetDirEntry(storageDirPtr))) {
695
696                 TString level0Str(level0);
697                 if (level0Str == "." || level0Str == "..") {
698                         continue;
699                 }
700                 
701                 TString fullPath = Form("%s/%s",fBaseDirectory.Data(), level0); 
702
703                 Int_t res=gSystem->GetPathInfo(fullPath.Data(), 0, (Long64_t*) 0, &flag, 0);
704                 
705                 if(res){
706                         AliDebug(2, Form("Error reading entry %s !",level0Str.Data()));
707                         continue;
708                 }
709                 
710                 if(!(flag&2)) continue; // bit 1 of flag = directory!                           
711
712                 if (queryId.GetAliCDBPath().Level0Comprises(level0)) {
713                         GetEntriesForLevel0(level0, queryId, result);
714                 }
715         }
716
717         gSystem->FreeDirectory(storageDirPtr);
718
719         return result;  
720 }
721
722 //_____________________________________________________________________________
723 Bool_t AliCDBLocal::PutEntry(AliCDBEntry* entry, const char* mirrors) {
724 // put an AliCDBEntry object into the database
725
726         AliCDBId& id = entry->GetId();
727
728         // set version and subVersion for the entry to be stored
729         if (!PrepareId(id)) return kFALSE;
730
731         
732         // build filename from entry's id
733         TString filename="";
734         if (!IdToFilename(id, filename)) {
735
736                 AliDebug(2,Form("Bad ID encountered! Subnormal error!"));
737                 return kFALSE;
738         }
739
740         TString mirrorsString(mirrors);
741         if(!mirrorsString.IsNull())
742                 AliWarning("AliCDBLocal storage cannot take mirror SEs into account. They will be ignored.");
743
744         // open file
745         TFile file(filename, "CREATE");
746         if (!file.IsOpen()) {
747                 AliError(Form("Can't open file <%s>!", filename.Data()));
748                 return kFALSE;
749         }
750         
751         //SetTreeToFile(entry, &file);
752
753         entry->SetVersion(id.GetVersion());
754         entry->SetSubVersion(id.GetSubVersion());
755
756         // write object (key name: "AliCDBEntry")
757         Bool_t result = file.WriteTObject(entry, "AliCDBEntry");
758         if (!result) AliDebug(2,Form("Can't write entry to file: %s", filename.Data()));
759
760         file.Close();
761         if(result) {
762                 if(!(id.GetPath().Contains("SHUTTLE/STATUS")))
763                         AliInfo(Form("CDB object stored into file %s",filename.Data()));
764         }
765
766         return result;
767 }
768
769 //_____________________________________________________________________________
770 TList* AliCDBLocal::GetIdListFromFile(const char* fileName){
771
772         TString fullFileName(fileName);
773         fullFileName.Prepend(fBaseDirectory+'/');
774         TFile *file = TFile::Open(fullFileName);
775         if (!file) {
776                 AliError(Form("Can't open selection file <%s>!", fullFileName.Data()));
777                 return NULL;
778         }
779         file->cd();
780
781         TList *list = new TList();
782         list->SetOwner();
783         int i=0;
784         TString keycycle;
785         
786         AliCDBId *id;
787         while(1){
788                 i++;
789                 keycycle = "AliCDBId;";
790                 keycycle+=i;
791                 
792                 id = (AliCDBId*) file->Get(keycycle);
793                 if(!id) break;
794                 list->AddFirst(id);
795         }
796         file->Close(); delete file; file=0;     
797         return list;
798 }
799
800 //_____________________________________________________________________________
801 Bool_t AliCDBLocal::Contains(const char* path) const{
802 // check for path in storage's fBaseDirectory
803
804         TString dirName = Form("%s/%s", fBaseDirectory.Data(), path);
805         Bool_t result=kFALSE;
806
807         void* dirPtr = gSystem->OpenDirectory(dirName); 
808         if (dirPtr) result=kTRUE;
809         gSystem->FreeDirectory(dirPtr);
810
811         return result;
812 }
813
814 //_____________________________________________________________________________
815 void AliCDBLocal::QueryValidFiles()
816 {
817 // Query the CDB for files valid for AliCDBStorage::fRun
818 // fills list fValidFileIds with AliCDBId objects created from file name
819
820         if(fVersion != -1) AliWarning ("Version parameter is not used by local storage query!");
821         if(fMetaDataFilter) {
822                 AliWarning ("CDB meta data parameters are not used by local storage query!");
823                 delete fMetaDataFilter; fMetaDataFilter=0;
824         }
825
826         void* storageDirPtr = gSystem->OpenDirectory(fBaseDirectory);
827
828         const char* level0;
829         while ((level0 = gSystem->GetDirEntry(storageDirPtr))) {
830
831                 TString level0Str(level0);
832                 if (level0Str == "." || level0Str == "..") {
833                         continue;
834                 }
835
836                 if (fPathFilter.Level0Comprises(level0)) {
837                         TString level0Dir = Form("%s/%s",fBaseDirectory.Data(),level0);
838                         void* level0DirPtr = gSystem->OpenDirectory(level0Dir);
839                         const char* level1;
840                         while ((level1 = gSystem->GetDirEntry(level0DirPtr))) {
841
842                                 TString level1Str(level1);
843                                 if (level1Str == "." || level1Str == "..") {
844                                         continue;
845                                 }
846
847                                 if (fPathFilter.Level1Comprises(level1)) {
848                                         TString level1Dir = Form("%s/%s/%s",
849                                                         fBaseDirectory.Data(),level0,level1);
850
851                                         void* level1DirPtr = gSystem->OpenDirectory(level1Dir);
852                                         const char* level2;
853                                         while ((level2 = gSystem->GetDirEntry(level1DirPtr))) {
854
855                                                 TString level2Str(level2);
856                                                 if (level2Str == "." || level2Str == "..") {
857                                                         continue;
858                                                 }
859
860                                                 if (fPathFilter.Level2Comprises(level2)) {
861                                                         TString dirName = Form("%s/%s/%s/%s",
862                                                                         fBaseDirectory.Data(),level0,level1,level2);
863
864                                                         void* dirPtr = gSystem->OpenDirectory(dirName);
865
866                                                         const char* filename;
867
868                                                         AliCDBRunRange aRunRange; // the runRange got from filename
869                                                         Int_t aVersion, aSubVersion; // the version and subVersion got from filename
870
871                                                         while ((filename = gSystem->GetDirEntry(dirPtr))) { // loop on files
872
873                                                                 TString aString(filename);
874                                                                 if (aString == "." || aString == "..") continue;
875
876                                                                 if (!FilenameToId(filename, aRunRange, aVersion, aSubVersion)) continue;
877                                                                 AliCDBRunRange runrg(fRun,fRun);
878                                                                 if (!aRunRange.Comprises(runrg)) continue;
879                                                                 // aRunRange contains requested run!
880                                                                 AliCDBPath validPath(level0,level1,level2);
881                                                                 AliCDBId validId(validPath,aRunRange,aVersion,aSubVersion);
882                                                                 fValidFileIds.AddLast(validId.Clone());
883                                                         }
884                                                         gSystem->FreeDirectory(dirPtr);
885                                                 }
886                                         }
887                                         gSystem->FreeDirectory(level1DirPtr);
888                                 }
889                         }
890                         gSystem->FreeDirectory(level0DirPtr);
891                 }
892         }
893         gSystem->FreeDirectory(storageDirPtr);
894
895 }
896
897 //_____________________________________________________________________________
898 Int_t AliCDBLocal::GetLatestVersion(const char* path, Int_t run){
899 // get last version found in the database valid for run and path
900
901         AliCDBPath aCDBPath(path);
902         if(!aCDBPath.IsValid() || aCDBPath.IsWildcard()) {
903                 AliError(Form("Invalid path in request: %s", path));
904                 return -1;
905         }
906
907         AliCDBId query(path, run, run, -1, -1);
908         AliCDBId* dataId = GetId(query);
909
910         if(!dataId) return -1;
911
912         Int_t version = dataId->GetVersion();
913         delete dataId;
914
915         return version;
916
917 }
918
919 //_____________________________________________________________________________
920 Int_t AliCDBLocal::GetLatestSubVersion(const char* path, Int_t run, Int_t version){
921 // get last version found in the database valid for run and path
922
923         AliCDBPath aCDBPath(path);
924         if(!aCDBPath.IsValid() || aCDBPath.IsWildcard()) {
925                 AliError(Form("Invalid path in request: %s", path));
926                 return -1;
927         }
928
929         AliCDBId query(path, run, run, version, -1);
930         AliCDBId *dataId = GetId(query);
931
932         if(!dataId) return -1;
933
934         Int_t subVersion = dataId->GetSubVersion();
935
936         delete dataId;
937         return subVersion;
938
939 }
940
941 /////////////////////////////////////////////////////////////////////////////////////////////////
942 //                                                                                             //
943 // AliCDBLocal factory                                                                         //
944 //                                                                                             //
945 /////////////////////////////////////////////////////////////////////////////////////////////////
946
947 ClassImp(AliCDBLocalFactory)
948
949 //_____________________________________________________________________________
950 Bool_t AliCDBLocalFactory::Validate(const char* dbString) {
951 // check if the string is valid local URI
952
953         TRegexp dbPatternLocal("^local://.+$");
954
955         return (TString(dbString).Contains(dbPatternLocal) || TString(dbString).BeginsWith("snapshot://folder="));
956 }
957
958 //_____________________________________________________________________________
959 AliCDBParam* AliCDBLocalFactory::CreateParameter(const char* dbString) {
960 // create AliCDBLocalParam class from the URI string
961
962         if (!Validate(dbString)) {
963                 return NULL;
964         }
965
966         TString checkSS(dbString);
967         if(checkSS.BeginsWith("snapshot://"))
968         {
969             TString snapshotPath("OCDB");
970             snapshotPath.Prepend(TString(gSystem->WorkingDirectory()) + '/');
971             checkSS.Remove(0,checkSS.First(':')+3);
972             return new AliCDBLocalParam(snapshotPath,checkSS);
973         }
974                 
975         // if the string argument is not a snapshot URI, than it is a plain local URI
976         TString pathname(dbString + sizeof("local://") - 1);
977         
978         if(gSystem->ExpandPathName(pathname))
979             return NULL;
980
981         if (pathname[0] != '/') {
982                 pathname.Prepend(TString(gSystem->WorkingDirectory()) + '/');
983         }
984         //pathname.Prepend("local://");
985
986         return new AliCDBLocalParam(pathname);
987 }
988
989 //_____________________________________________________________________________
990 AliCDBStorage* AliCDBLocalFactory::Create(const AliCDBParam* param) {
991 // create AliCDBLocal storage instance from parameters
992         
993         if (AliCDBLocalParam::Class() == param->IsA()) {
994                 
995                 const AliCDBLocalParam* localParam = 
996                         (const AliCDBLocalParam*) param;
997                 
998                 return new AliCDBLocal(localParam->GetPath());
999         }
1000
1001         return NULL;
1002 }
1003 //_____________________________________________________________________________
1004 void AliCDBLocal::SetRetry(Int_t /* nretry */, Int_t /* initsec */) {
1005
1006         // Function to set the exponential retry for putting entries in the OCDB
1007
1008         AliInfo("This function sets the exponential retry for putting entries in the OCDB - to be used ONLY for AliCDBGrid --> returning without doing anything");
1009         return;
1010
1011
1012
1013
1014 /////////////////////////////////////////////////////////////////////////////////////////////////
1015 //                                                                                             //
1016 // AliCDBLocal Parameter class                                                                 //                                          //
1017 //                                                                                             //
1018 /////////////////////////////////////////////////////////////////////////////////////////////////
1019
1020 ClassImp(AliCDBLocalParam)
1021
1022 //_____________________________________________________________________________
1023 AliCDBLocalParam::AliCDBLocalParam():
1024  AliCDBParam(),
1025  fDBPath()
1026  {
1027 // default constructor
1028
1029 }
1030
1031 //_____________________________________________________________________________
1032 AliCDBLocalParam::AliCDBLocalParam(const char* dbPath):
1033  AliCDBParam(),
1034  fDBPath(dbPath)
1035 {
1036 // constructor
1037
1038         SetType("local");
1039         SetURI(TString("local://") + dbPath);
1040 }
1041
1042 //_____________________________________________________________________________
1043 AliCDBLocalParam::AliCDBLocalParam(const char* dbPath, const char* uri):
1044  AliCDBParam(),
1045  fDBPath(dbPath)
1046 {
1047 // constructor
1048
1049         SetType("local");
1050         SetURI(TString("alien://") + uri);
1051 }
1052
1053 //_____________________________________________________________________________
1054 AliCDBLocalParam::~AliCDBLocalParam() {
1055 // destructor
1056
1057 }
1058
1059 //_____________________________________________________________________________
1060 AliCDBParam* AliCDBLocalParam::CloneParam() const {
1061 // clone parameter
1062
1063         return new AliCDBLocalParam(fDBPath);
1064 }
1065
1066 //_____________________________________________________________________________
1067 ULong_t AliCDBLocalParam::Hash() const {
1068 // return Hash function
1069
1070        return fDBPath.Hash();
1071 }
1072
1073 //_____________________________________________________________________________
1074 Bool_t AliCDBLocalParam::IsEqual(const TObject* obj) const {
1075 // check if this object is equal to AliCDBParam obj
1076
1077         if (this == obj) {
1078                 return kTRUE;
1079         }
1080
1081         if (AliCDBLocalParam::Class() != obj->IsA()) {
1082                 return kFALSE;
1083         }
1084
1085         AliCDBLocalParam* other = (AliCDBLocalParam*) obj;
1086
1087         return fDBPath == other->fDBPath;
1088 }
1089