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