]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/CDB/AliCDBLocal.cxx
Adding the new detector MFT (Antonio Uras)
[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) {
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         // open file
741         TFile file(filename, "CREATE");
742         if (!file.IsOpen()) {
743                 AliError(Form("Can't open file <%s>!", filename.Data()));
744                 return kFALSE;
745         }
746         
747         //SetTreeToFile(entry, &file);
748
749         entry->SetVersion(id.GetVersion());
750         entry->SetSubVersion(id.GetSubVersion());
751
752         // write object (key name: "AliCDBEntry")
753         Bool_t result = file.WriteTObject(entry, "AliCDBEntry");
754         if (!result) AliDebug(2,Form("Can't write entry to file: %s", filename.Data()));
755
756         file.Close();
757         if(result) {
758                 if(!(id.GetPath().Contains("SHUTTLE/STATUS")))
759                         AliInfo(Form("CDB object stored into file %s",filename.Data()));
760         }
761
762         return result;
763 }
764
765 //_____________________________________________________________________________
766 TList* AliCDBLocal::GetIdListFromFile(const char* fileName){
767
768         TString fullFileName(fileName);
769         fullFileName.Prepend(fBaseDirectory+'/');
770         TFile *file = TFile::Open(fullFileName);
771         if (!file) {
772                 AliError(Form("Can't open selection file <%s>!", fullFileName.Data()));
773                 return NULL;
774         }
775         file->cd();
776
777         TList *list = new TList();
778         list->SetOwner();
779         int i=0;
780         TString keycycle;
781         
782         AliCDBId *id;
783         while(1){
784                 i++;
785                 keycycle = "AliCDBId;";
786                 keycycle+=i;
787                 
788                 id = (AliCDBId*) file->Get(keycycle);
789                 if(!id) break;
790                 list->AddFirst(id);
791         }
792         file->Close(); delete file; file=0;     
793         return list;
794 }
795
796 //_____________________________________________________________________________
797 Bool_t AliCDBLocal::Contains(const char* path) const{
798 // check for path in storage's fBaseDirectory
799
800         TString dirName = Form("%s/%s", fBaseDirectory.Data(), path);
801         Bool_t result=kFALSE;
802
803         void* dirPtr = gSystem->OpenDirectory(dirName); 
804         if (dirPtr) result=kTRUE;
805         gSystem->FreeDirectory(dirPtr);
806
807         return result;
808 }
809
810 //_____________________________________________________________________________
811 void AliCDBLocal::QueryValidFiles()
812 {
813 // Query the CDB for files valid for AliCDBStorage::fRun
814 // fills list fValidFileIds with AliCDBId objects created from file name
815
816         if(fVersion != -1) AliWarning ("Version parameter is not used by local storage query!");
817         if(fMetaDataFilter) {
818                 AliWarning ("CDB meta data parameters are not used by local storage query!");
819                 delete fMetaDataFilter; fMetaDataFilter=0;
820         }
821
822         void* storageDirPtr = gSystem->OpenDirectory(fBaseDirectory);
823
824         const char* level0;
825         while ((level0 = gSystem->GetDirEntry(storageDirPtr))) {
826
827                 TString level0Str(level0);
828                 if (level0Str == "." || level0Str == "..") {
829                         continue;
830                 }
831
832                 if (fPathFilter.Level0Comprises(level0)) {
833                         TString level0Dir = Form("%s/%s",fBaseDirectory.Data(),level0);
834                         void* level0DirPtr = gSystem->OpenDirectory(level0Dir);
835                         const char* level1;
836                         while ((level1 = gSystem->GetDirEntry(level0DirPtr))) {
837
838                                 TString level1Str(level1);
839                                 if (level1Str == "." || level1Str == "..") {
840                                         continue;
841                                 }
842
843                                 if (fPathFilter.Level1Comprises(level1)) {
844                                         TString level1Dir = Form("%s/%s/%s",
845                                                         fBaseDirectory.Data(),level0,level1);
846
847                                         void* level1DirPtr = gSystem->OpenDirectory(level1Dir);
848                                         const char* level2;
849                                         while ((level2 = gSystem->GetDirEntry(level1DirPtr))) {
850
851                                                 TString level2Str(level2);
852                                                 if (level2Str == "." || level2Str == "..") {
853                                                         continue;
854                                                 }
855
856                                                 if (fPathFilter.Level2Comprises(level2)) {
857                                                         TString dirName = Form("%s/%s/%s/%s",
858                                                                         fBaseDirectory.Data(),level0,level1,level2);
859
860                                                         void* dirPtr = gSystem->OpenDirectory(dirName);
861
862                                                         const char* filename;
863
864                                                         AliCDBRunRange aRunRange; // the runRange got from filename
865                                                         Int_t aVersion, aSubVersion; // the version and subVersion got from filename
866
867                                                         while ((filename = gSystem->GetDirEntry(dirPtr))) { // loop on files
868
869                                                                 TString aString(filename);
870                                                                 if (aString == "." || aString == "..") continue;
871
872                                                                 if (!FilenameToId(filename, aRunRange, aVersion, aSubVersion)) continue;
873                                                                 AliCDBRunRange runrg(fRun,fRun);
874                                                                 if (!aRunRange.Comprises(runrg)) continue;
875                                                                 // aRunRange contains requested run!
876                                                                 AliCDBPath validPath(level0,level1,level2);
877                                                                 AliCDBId validId(validPath,aRunRange,aVersion,aSubVersion);
878                                                                 fValidFileIds.AddLast(validId.Clone());
879                                                         }
880                                                         gSystem->FreeDirectory(dirPtr);
881                                                 }
882                                         }
883                                         gSystem->FreeDirectory(level1DirPtr);
884                                 }
885                         }
886                         gSystem->FreeDirectory(level0DirPtr);
887                 }
888         }
889         gSystem->FreeDirectory(storageDirPtr);
890
891 }
892
893 //_____________________________________________________________________________
894 Int_t AliCDBLocal::GetLatestVersion(const char* path, Int_t run){
895 // get last version found in the database valid for run and path
896
897         AliCDBPath aCDBPath(path);
898         if(!aCDBPath.IsValid() || aCDBPath.IsWildcard()) {
899                 AliError(Form("Invalid path in request: %s", path));
900                 return -1;
901         }
902
903         AliCDBId query(path, run, run, -1, -1);
904         AliCDBId* dataId = GetId(query);
905
906         if(!dataId) return -1;
907
908         Int_t version = dataId->GetVersion();
909         delete dataId;
910
911         return version;
912
913 }
914
915 //_____________________________________________________________________________
916 Int_t AliCDBLocal::GetLatestSubVersion(const char* path, Int_t run, Int_t version){
917 // get last version found in the database valid for run and path
918
919         AliCDBPath aCDBPath(path);
920         if(!aCDBPath.IsValid() || aCDBPath.IsWildcard()) {
921                 AliError(Form("Invalid path in request: %s", path));
922                 return -1;
923         }
924
925         AliCDBId query(path, run, run, version, -1);
926         AliCDBId *dataId = GetId(query);
927
928         if(!dataId) return -1;
929
930         Int_t subVersion = dataId->GetSubVersion();
931
932         delete dataId;
933         return subVersion;
934
935 }
936
937 /////////////////////////////////////////////////////////////////////////////////////////////////
938 //                                                                                             //
939 // AliCDBLocal factory                                                                         //
940 //                                                                                             //
941 /////////////////////////////////////////////////////////////////////////////////////////////////
942
943 ClassImp(AliCDBLocalFactory)
944
945 //_____________________________________________________________________________
946 Bool_t AliCDBLocalFactory::Validate(const char* dbString) {
947 // check if the string is valid local URI
948
949         TRegexp dbPatternLocal("^local://.+$");
950
951         return (TString(dbString).Contains(dbPatternLocal) || TString(dbString).BeginsWith("snapshot://folder="));
952 }
953
954 //_____________________________________________________________________________
955 AliCDBParam* AliCDBLocalFactory::CreateParameter(const char* dbString) {
956 // create AliCDBLocalParam class from the URI string
957
958         if (!Validate(dbString)) {
959                 return NULL;
960         }
961
962         TString checkSS(dbString);
963         if(checkSS.BeginsWith("snapshot://"))
964         {
965             TString snapshotPath("OCDB");
966             snapshotPath.Prepend(TString(gSystem->WorkingDirectory()) + '/');
967             checkSS.Remove(0,checkSS.First(':')+3);
968             return new AliCDBLocalParam(snapshotPath,checkSS);
969         }
970                 
971         // if the string argument is not a snapshot URI, than it is a plain local URI
972         TString pathname(dbString + sizeof("local://") - 1);
973         
974         if(gSystem->ExpandPathName(pathname))
975             return NULL;
976
977         if (pathname[0] != '/') {
978                 pathname.Prepend(TString(gSystem->WorkingDirectory()) + '/');
979         }
980         //pathname.Prepend("local://");
981
982         return new AliCDBLocalParam(pathname);
983 }
984
985 //_____________________________________________________________________________
986 AliCDBStorage* AliCDBLocalFactory::Create(const AliCDBParam* param) {
987 // create AliCDBLocal storage instance from parameters
988         
989         if (AliCDBLocalParam::Class() == param->IsA()) {
990                 
991                 const AliCDBLocalParam* localParam = 
992                         (const AliCDBLocalParam*) param;
993                 
994                 return new AliCDBLocal(localParam->GetPath());
995         }
996
997         return NULL;
998 }
999 //_____________________________________________________________________________
1000 void AliCDBLocal::SetRetry(Int_t /* nretry */, Int_t /* initsec */) {
1001
1002         // Function to set the exponential retry for putting entries in the OCDB
1003
1004         AliInfo("This function sets the exponential retry for putting entries in the OCDB - to be used ONLY for AliCDBGrid --> returning without doing anything");
1005         return;
1006
1007
1008
1009
1010 /////////////////////////////////////////////////////////////////////////////////////////////////
1011 //                                                                                             //
1012 // AliCDBLocal Parameter class                                                                 //                                          //
1013 //                                                                                             //
1014 /////////////////////////////////////////////////////////////////////////////////////////////////
1015
1016 ClassImp(AliCDBLocalParam)
1017
1018 //_____________________________________________________________________________
1019 AliCDBLocalParam::AliCDBLocalParam():
1020  AliCDBParam(),
1021  fDBPath()
1022  {
1023 // default constructor
1024
1025 }
1026
1027 //_____________________________________________________________________________
1028 AliCDBLocalParam::AliCDBLocalParam(const char* dbPath):
1029  AliCDBParam(),
1030  fDBPath(dbPath)
1031 {
1032 // constructor
1033
1034         SetType("local");
1035         SetURI(TString("local://") + dbPath);
1036 }
1037
1038 //_____________________________________________________________________________
1039 AliCDBLocalParam::AliCDBLocalParam(const char* dbPath, const char* uri):
1040  AliCDBParam(),
1041  fDBPath(dbPath)
1042 {
1043 // constructor
1044
1045         SetType("local");
1046         SetURI(TString("alien://") + uri);
1047 }
1048
1049 //_____________________________________________________________________________
1050 AliCDBLocalParam::~AliCDBLocalParam() {
1051 // destructor
1052
1053 }
1054
1055 //_____________________________________________________________________________
1056 AliCDBParam* AliCDBLocalParam::CloneParam() const {
1057 // clone parameter
1058
1059         return new AliCDBLocalParam(fDBPath);
1060 }
1061
1062 //_____________________________________________________________________________
1063 ULong_t AliCDBLocalParam::Hash() const {
1064 // return Hash function
1065
1066        return fDBPath.Hash();
1067 }
1068
1069 //_____________________________________________________________________________
1070 Bool_t AliCDBLocalParam::IsEqual(const TObject* obj) const {
1071 // check if this object is equal to AliCDBParam obj
1072
1073         if (this == obj) {
1074                 return kTRUE;
1075         }
1076
1077         if (AliCDBLocalParam::Class() != obj->IsA()) {
1078                 return kFALSE;
1079         }
1080
1081         AliCDBLocalParam* other = (AliCDBLocalParam*) obj;
1082
1083         return fDBPath == other->fDBPath;
1084 }
1085