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