]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliCDBLocal.cxx
Implementation of Grid CDB access using the Grid metadata tables.
[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 <TSystem.h>
24 #include <TObjString.h>
25 #include <TRegexp.h>
26 #include <TFile.h>
27 #include <TKey.h>
28
29 #include "AliCDBLocal.h"
30 #include "AliCDBEntry.h"
31 #include "AliLog.h"
32
33 ClassImp(AliCDBLocal)
34
35 //_____________________________________________________________________________
36 AliCDBLocal::AliCDBLocal(const char* baseDir):
37 fBaseDirectory(baseDir) 
38 {
39 // constructor
40
41         // check baseDire: trying to cd to baseDir; if it does not exist, create it
42         void* dir = gSystem->OpenDirectory(baseDir);
43         if (dir == NULL) {
44                 if (gSystem->mkdir(baseDir, kTRUE)) {
45                         AliError(Form("Can't open directory <%s>!", baseDir));
46                 }
47
48         } else {
49                 AliDebug(2,Form("Folder <%s> found",fBaseDirectory.Data()));
50                 gSystem->FreeDirectory(dir);
51         }
52         fType="local";
53         fBaseFolder = fBaseDirectory;
54 }
55
56 //_____________________________________________________________________________
57 AliCDBLocal::~AliCDBLocal() {
58 // destructor
59
60 }
61
62
63 //_____________________________________________________________________________
64 Bool_t AliCDBLocal::FilenameToId(const char* filename, AliCDBRunRange& runRange,
65         Int_t& version, Int_t& subVersion) {
66 // build AliCDBId from filename numbers
67
68
69         Ssiz_t mSize;
70
71         // valid filename: Run#firstRun_#lastRun_v#version_s#subVersion.root
72         TRegexp keyPattern("^Run[0-9]+_[0-9]+_v[0-9]+_s[0-9]+.root$");
73         keyPattern.Index(filename, &mSize);
74         if (!mSize) {
75                 AliDebug(2, Form("Bad filename <%s>.", filename));
76                 return kFALSE;
77         }
78
79         TString idString(filename);
80         idString.Resize(idString.Length() - sizeof(".root") + 1);
81
82         TObjArray* strArray = (TObjArray*) idString.Tokenize("_");
83
84         TString firstRunString(((TObjString*) strArray->At(0))->GetString());
85         runRange.SetFirstRun(atoi(firstRunString.Data() + 3));
86         runRange.SetLastRun(atoi(((TObjString*) strArray->At(1))->GetString()));
87         
88         TString verString(((TObjString*) strArray->At(2))->GetString());
89         version = atoi(verString.Data() + 1);
90
91         TString subVerString(((TObjString*) strArray->At(3))->GetString());
92         subVersion = atoi(subVerString.Data() + 1);
93
94         delete strArray;
95
96         return kTRUE;
97 }
98
99
100 //_____________________________________________________________________________
101 Bool_t AliCDBLocal::IdToFilename(const AliCDBRunRange& runRange, Int_t version,
102         Int_t subVersion, TString& filename) {
103 // build file name from AliCDBId data (run range, version, subVersion)
104
105         if (!runRange.IsValid()) {
106                 AliDebug(2,Form("Invalid run range <%d, %d>.", 
107                         runRange.GetFirstRun(), runRange.GetLastRun()));
108                 return kFALSE;
109         }
110
111         if (version < 0) {
112                 AliDebug(2,Form("Invalid version <%d>.", version));
113                 return kFALSE;
114         }
115
116         if (subVersion < 0) {
117                 AliDebug(2,Form("Invalid subversion <%s>.", subVersion));
118                 return kFALSE;
119         }
120  
121         filename += "Run";
122         filename += runRange.GetFirstRun();
123         filename += "_";
124         filename += runRange.GetLastRun();
125         filename += "_v";
126         filename += version;
127         filename += "_s";
128         filename += subVersion;
129         filename += ".root";
130
131         return kTRUE;
132 }
133
134 //_____________________________________________________________________________
135 Bool_t AliCDBLocal::PrepareId(AliCDBId& id) {
136 // prepare id (version, subVersion) of the object that will be stored (called by PutEntry)
137
138         TString dirName;
139         dirName += fBaseDirectory;
140         dirName += '/';
141         dirName += id.GetPath();
142
143         // go to the path; if directory does not exist, create it
144         void* dirPtr = gSystem->OpenDirectory(dirName);
145         if (!dirPtr) {
146                 gSystem->mkdir(dirName, kTRUE);
147                 dirPtr = gSystem->OpenDirectory(dirName);
148
149                 if (!dirPtr) {
150                         AliError(Form("Can't create directory <%s>!", 
151                                         dirName.Data()));
152                         return kFALSE;
153                 }
154         }
155
156         const char* filename;
157         AliCDBRunRange aRunRange; // the runRange got from filename 
158         AliCDBRunRange lastRunRange(-1,-1); // highest runRange found
159         Int_t aVersion, aSubVersion; // the version subVersion got from filename
160         Int_t lastVersion = 0, lastSubVersion = -1; // highest version and subVersion found
161
162         if (!id.HasVersion()) { // version not specified: look for highest version & subVersion
163                                 
164                 while ((filename = gSystem->GetDirEntry(dirPtr))) { // loop on the files
165
166                         TString aString(filename);
167                         if (aString == "." || aString == "..") continue;
168         
169                         if (!FilenameToId(filename, aRunRange, aVersion, 
170                                 aSubVersion)) {
171                                 AliDebug(2,Form(
172                                         "Bad filename <%s>! I'll skip it.", 
173                                         filename));
174                                 continue;
175                         }
176                         
177                         if (!aRunRange.Overlaps(id.GetAliCDBRunRange())) continue;
178                         if(aVersion < lastVersion) continue;
179                         if(aVersion > lastVersion) lastSubVersion = -1;
180                         if(aSubVersion < lastSubVersion) continue;
181                         lastVersion = aVersion;
182                         lastSubVersion = aSubVersion;
183                         lastRunRange = aRunRange;
184                 }
185
186                 id.SetVersion(lastVersion);
187                 id.SetSubVersion(lastSubVersion + 1);
188
189         } else { // version specified, look for highest subVersion only
190                 
191                 while ((filename = gSystem->GetDirEntry(dirPtr))) { // loop on the files
192                         
193                         TString aString(filename);
194                         if (aString == "." || aString == "..") {
195                                 continue;
196                         }
197
198                         if (!FilenameToId(filename, aRunRange, aVersion, 
199                                 aSubVersion)) {
200                                 AliDebug(2,Form(
201                                         "Bad filename <%s>!I'll skip it.",
202                                         filename));     
203                                 continue;
204                         }
205
206                         if (aRunRange.Overlaps(id.GetAliCDBRunRange()) 
207                                 && aVersion == id.GetVersion()
208                                 && aSubVersion > lastSubVersion) {
209                                 lastSubVersion = aSubVersion;
210                                 lastRunRange = aRunRange;
211                         }
212         
213                 }
214                 
215                 id.SetSubVersion(lastSubVersion + 1);
216         }
217
218         gSystem->FreeDirectory(dirPtr);
219
220         TString lastStorage = id.GetLastStorage();
221         if(lastStorage.Contains(TString("grid"), TString::kIgnoreCase) &&
222            id.GetSubVersion() > 0 ){
223                 AliError(Form("Grid to Local Storage error! local object with version v%d_s%d found:",id.GetVersion(), id.GetSubVersion()-1));
224                 AliError(Form("This object has been already transferred from Grid (check v%d_s0)!",id.GetVersion()));
225                 return kFALSE;
226         }
227
228         if(lastStorage.Contains(TString("new"), TString::kIgnoreCase) &&
229            id.GetSubVersion() > 0 ){
230                 AliDebug(2, Form("A NEW object is being stored with version v%d_s%d",
231                                         id.GetVersion(),id.GetSubVersion()));
232                 AliDebug(2, Form("and it will hide previously stored object with v%d_s%d!",
233                                         id.GetVersion(),id.GetSubVersion()-1));
234         }
235
236         if(!lastRunRange.IsAnyRange() && !(lastRunRange.IsEqual(& id.GetAliCDBRunRange()))) 
237                 AliWarning(Form("Run range modified w.r.t. previous version (Run%d_%d_v%d_s%d)",
238                         lastRunRange.GetFirstRun(), lastRunRange.GetLastRun(), 
239                         id.GetVersion(), id.GetSubVersion()-1));
240
241         return kTRUE;
242 }
243
244 //_____________________________________________________________________________
245 Bool_t AliCDBLocal::GetId(const AliCDBId& query, AliCDBId& result) {
246 // look for filename matching query (called by GetEntry)
247
248         TString dirName;
249         dirName += fBaseDirectory;
250         dirName += '/';
251         dirName += query.GetPath(); // dirName = fDBPath/idPath
252
253         void* dirPtr = gSystem->OpenDirectory(dirName); 
254         if (!dirPtr) {
255                 AliDebug(2,Form("Directory <%s> not found", (query.GetPath()).Data()));
256                 AliDebug(2,Form("in DB folder %s", fBaseDirectory.Data()));
257                 return kFALSE;
258         }
259
260         const char* filename;   
261         
262         AliCDBRunRange aRunRange; // the runRange got from filename
263         Int_t aVersion, aSubVersion; // the version and subVersion got from filename
264
265         if (!query.HasVersion()) { // neither version and subversion specified -> look for highest version and subVersion
266                 
267                 while ((filename = gSystem->GetDirEntry(dirPtr))) { // loop on files
268                         
269                         TString aString(filename);
270                         if (aString == "." || aString == "..") continue;
271
272                         if (!FilenameToId(filename, aRunRange, aVersion, aSubVersion)) continue;
273                         // aRunRange, aVersion, aSubVersion filled from filename
274
275                         if (!aRunRange.Comprises(query.GetAliCDBRunRange())) continue;
276                         // aRunRange contains requested run!
277                         
278                         if (result.GetVersion() < aVersion) {
279                                 result.SetVersion(aVersion);
280                                 result.SetSubVersion(aSubVersion);
281
282                                 result.SetFirstRun(
283                                         aRunRange.GetFirstRun());
284                                 result.SetLastRun(
285                                         aRunRange.GetLastRun());
286
287                         } else if (result.GetVersion() == aVersion 
288                                 && result.GetSubVersion() 
289                                         < aSubVersion) {
290
291                                 result.SetSubVersion(aSubVersion);
292
293                                 result.SetFirstRun(
294                                         aRunRange.GetFirstRun());
295                                 result.SetLastRun(
296                                         aRunRange.GetLastRun());
297                         } else if (result.GetVersion() == aVersion
298                                 && result.GetSubVersion() == aSubVersion){
299                                 AliDebug(2,Form("More than one object valid for run %d, version %d_%d!", 
300                                         query.GetFirstRun(), aVersion, aSubVersion));
301                                 gSystem->FreeDirectory(dirPtr);
302                                 return kFALSE; 
303                                 }
304                 }
305                 
306         } else if (!query.HasSubVersion()) { // version specified but not subversion -> look for highest subVersion
307
308                 result.SetVersion(query.GetVersion());
309
310                 while ((filename = gSystem->GetDirEntry(dirPtr))) { // loop on files
311
312                         TString aString(filename);
313                         if (aString == "." || aString == "..") continue;
314
315                         if (!FilenameToId(filename, aRunRange, aVersion, aSubVersion)) continue;       
316                         // aRunRange, aVersion, aSubVersion filled from filename
317
318                         if (!aRunRange.Comprises(query.GetAliCDBRunRange())) continue; 
319                         // aRunRange contains requested run!
320                         
321                         if(query.GetVersion() != aVersion) continue;
322                         // aVersion is requested version!
323                         
324                         if(result.GetSubVersion() == aSubVersion){
325                                 AliDebug(2,Form("More than one object valid for run %d, version %d_%d!", 
326                                         query.GetFirstRun(), aVersion, aSubVersion));
327                                 gSystem->FreeDirectory(dirPtr);
328                                 return kFALSE; 
329                         }
330                         if( result.GetSubVersion() < aSubVersion) {
331
332                                 result.SetSubVersion(aSubVersion);
333
334                                 result.SetFirstRun(
335                                         aRunRange.GetFirstRun());
336                                 result.SetLastRun(
337                                         aRunRange.GetLastRun());
338                         } 
339                 }
340
341         } else { // both version and subversion specified
342
343                 while ((filename = gSystem->GetDirEntry(dirPtr))) { // loop on files
344
345                         TString aString(filename);
346                         if (aString == "." || aString == "..") continue;
347
348                         if (!FilenameToId(filename, aRunRange, aVersion, aSubVersion)) continue;
349                         // aRunRange, aVersion, aSubVersion filled from filename
350                         
351                         if (!aRunRange.Comprises(query.GetAliCDBRunRange())) continue;
352                         // aRunRange contains requested run!
353
354                         if(query.GetVersion() != aVersion || query.GetSubVersion() != aSubVersion) continue; 
355                         // aVersion and aSubVersion are requested version and subVersion!
356                         
357                         if(result.GetVersion() == aVersion && result.GetSubVersion() == aSubVersion){
358                                 AliDebug(2,Form("More than one object valid for run %d, version %d_%d!", 
359                                         query.GetFirstRun(), aVersion, aSubVersion));
360                                 gSystem->FreeDirectory(dirPtr);
361                                 return kFALSE; 
362                         }
363                         result.SetVersion(aVersion);
364                         result.SetSubVersion(aSubVersion);
365                         result.SetFirstRun(aRunRange.GetFirstRun());
366                         result.SetLastRun(aRunRange.GetLastRun());
367                         
368                 }
369         }
370
371         gSystem->FreeDirectory(dirPtr);
372
373         return kTRUE;
374 }
375
376 //_____________________________________________________________________________
377 AliCDBEntry* AliCDBLocal::GetEntry(const AliCDBId& queryId) {
378 // get AliCDBEntry from the database
379
380         AliCDBId dataId(queryId.GetAliCDBPath(), -1, -1, -1, -1);
381         Bool_t result;
382                 
383         // look for a filename matching query requests (path, runRange, version, subVersion)
384         if (!queryId.HasVersion()) {
385                 // if version is not specified, first check the selection criteria list
386                 AliCDBId selectedId(queryId);
387                 GetSelection(&selectedId);
388                 result = GetId(selectedId, dataId);
389         } else {
390                 result = GetId(queryId, dataId);
391         }
392
393         if (!result || !dataId.IsSpecified()) return NULL;
394
395         TString filename;
396         if (!IdToFilename(dataId.GetAliCDBRunRange(), dataId.GetVersion(),
397                  dataId.GetSubVersion(), filename)) {
398
399                 AliDebug(2,Form("Bad data ID encountered! Subnormal error!"));
400                 return NULL;
401         }
402         
403         filename.Prepend((fBaseDirectory +'/' + queryId.GetPath() + '/'));
404
405         TFile file(filename, "READ"); // open file
406         if (!file.IsOpen()) {
407                 AliDebug(2,Form("Can't open file <%s>!", filename.Data()));
408                 return NULL;
409         }
410
411         // get the only AliCDBEntry object from the file
412         // the object in the file is an AliCDBEntry entry named "AliCDBEntry"
413         
414         AliCDBEntry* anEntry = dynamic_cast<AliCDBEntry*> (file.Get("AliCDBEntry"));
415         if (!anEntry) {
416                 AliDebug(2,Form("Bad storage data: No AliCDBEntry in file!"));
417                 file.Close();
418                 return NULL;
419         }
420
421         AliCDBId entryId = anEntry->GetId();
422  
423         // The object's Id are not reset during storage
424         // If object's Id runRange or version do not match with filename,
425         // it means that someone renamed file by hand. In this case a warning msg is issued.
426
427         anEntry-> SetLastStorage("local");
428  
429         if(!((entryId.GetAliCDBRunRange()).IsEqual(& dataId.GetAliCDBRunRange())) || 
430                 (entryId.GetVersion() != dataId.GetVersion()) || (entryId.GetSubVersion() != dataId.GetSubVersion())){
431                 AliWarning(Form("Either object Id's RunRange or version do noth match with file name:"));
432                 AliWarning("someone renamed file by hand!");
433         }
434         
435         // close file, return retieved entry
436         file.Close();
437         return anEntry;
438 }
439
440 //_____________________________________________________________________________
441 void AliCDBLocal::GetEntriesForLevel0(const char* level0,
442         const AliCDBId& queryId, TList* result) {
443 // multiple request (AliCDBStorage::GetAll)
444
445         TString level0Dir;
446         level0Dir += fBaseDirectory;
447         level0Dir += '/';
448         level0Dir += level0;
449         
450         void* level0DirPtr = gSystem->OpenDirectory(level0Dir);
451         if (!level0DirPtr) {
452                 AliDebug(2,Form("Can't open level0 directory <%s>!", 
453                         level0Dir.Data()));
454                 return;
455         } 
456
457         const char* level1;
458         while ((level1 = gSystem->GetDirEntry(level0DirPtr))) {
459
460                 TString level1Str(level1);
461                 if (level1Str == "." || level1Str == "..") {
462                         continue;
463                 }
464
465                 if (queryId.GetAliCDBPath().Level1Comprises(level1)) {
466                         GetEntriesForLevel1(level0, level1, queryId, result);
467                 }
468         }
469
470         gSystem->FreeDirectory(level0DirPtr);
471 }
472
473 //_____________________________________________________________________________
474 void AliCDBLocal::GetEntriesForLevel1(const char* level0, const char* level1,
475         const AliCDBId& queryId, TList* result) {
476 // multiple request (AliCDBStorage::GetAll)
477
478         TString level1Dir;
479         level1Dir += fBaseDirectory;
480         level1Dir += '/';
481         level1Dir += level0;
482         level1Dir += '/';
483         level1Dir += level1;
484
485         void* level1DirPtr = gSystem->OpenDirectory(level1Dir);
486         if (!level1DirPtr) {
487                 AliDebug(2,Form("Can't open level1 directory <%s>!", 
488                         level1Dir.Data()));
489                 return;
490         }
491
492         const char* level2;
493         while ((level2 = gSystem->GetDirEntry(level1DirPtr))) {
494
495                 TString level2Str(level2);
496                 if (level2Str == "." || level2Str == "..") {
497                         continue;
498                 }
499
500                 if (queryId.GetAliCDBPath().Level2Comprises(level2)) {
501
502                         AliCDBPath entryPath(level0, level1, level2);
503                         AliCDBId entryId(entryPath, queryId.GetAliCDBRunRange(),
504                                 queryId.GetVersion(), queryId.GetSubVersion());
505
506                         AliCDBEntry* anEntry = GetEntry(entryId);
507                         if (anEntry) {
508                                 result->Add(anEntry);
509                         }
510                 }
511         }
512
513         gSystem->FreeDirectory(level1DirPtr);
514 }
515
516 //_____________________________________________________________________________
517 TList* AliCDBLocal::GetEntries(const AliCDBId& queryId) {
518 // multiple request (AliCDBStorage::GetAll)
519
520         void* storageDirPtr = gSystem->OpenDirectory(fBaseDirectory);
521         if (!storageDirPtr) {
522                 AliDebug(2,Form("Can't open storage directory <%s>",
523                         fBaseDirectory.Data()));
524                 return NULL;
525         }       
526
527         TList* result = new TList();
528         result->SetOwner();
529
530         const char* level0;
531         while ((level0 = gSystem->GetDirEntry(storageDirPtr))) {
532                 
533                 TString level0Str(level0);
534                 if (level0Str == "." || level0Str == "..") {
535                         continue;
536                 }
537
538                 if (queryId.GetAliCDBPath().Level0Comprises(level0)) {
539                         GetEntriesForLevel0(level0, queryId, result);   
540                 }
541         }       
542         
543         gSystem->FreeDirectory(storageDirPtr);
544
545         return result;  
546 }
547
548 //_____________________________________________________________________________
549 Bool_t AliCDBLocal::PutEntry(AliCDBEntry* entry) {
550 // put an AliCDBEntry object into the database
551
552         AliCDBId& id = entry->GetId();
553
554         // set version and subVersion for the entry to be stored
555         if (!PrepareId(id)) return kFALSE;              
556
557         
558         // build filename from entry's id
559         TString filename="";
560         if (!IdToFilename(id.GetAliCDBRunRange(), id.GetVersion(),
561                 id.GetSubVersion(), filename)) {
562
563                 AliDebug(2,Form("Bad ID encountered! Subnormal error!"));
564                 return kFALSE;
565         }
566         
567         filename.Prepend(fBaseDirectory +'/' + id.GetPath() + '/');
568         
569         // open file
570         TFile file(filename, "CREATE");
571         if (!file.IsOpen()) {
572                 AliError(Form("Can't open file <%s>!", filename.Data()));
573                 return kFALSE;
574         }
575         
576         entry->SetVersion(id.GetVersion());
577         entry->SetSubVersion(id.GetSubVersion());
578
579         // write object (key name: "AliCDBEntry")
580         Bool_t result = file.WriteTObject(entry, "AliCDBEntry");
581         if (!result) AliDebug(2,Form("Can't write entry to file: %s", filename.Data()));
582
583         file.Close();
584         if(result) {
585                 // TODO this is to make the SHUTTLE output lighter
586                 if(!(id.GetPath().Contains("SHUTTLE/STATUS")))
587                         AliInfo(Form("CDB object stored into file %s",filename.Data()));
588         }
589
590         return result;
591 }
592
593 //_____________________________________________________________________________
594 TList* AliCDBLocal::GetIdListFromFile(const char* fileName){
595
596         TString fullFileName(fileName);
597         fullFileName.Prepend(fBaseDirectory+'/');
598         TFile *file = TFile::Open(fullFileName);
599         if (!file) {
600                 AliError(Form("Can't open selection file <%s>!", fullFileName.Data()));
601                 return NULL;
602         }
603         file->cd();
604
605         TList *list = new TList();
606         list->SetOwner();
607         int i=0;
608         TString keycycle;
609         
610         AliCDBId *id;
611         while(1){
612                 i++;
613                 keycycle = "AliCDBId;";
614                 keycycle+=i;
615                 
616                 id = (AliCDBId*) file->Get(keycycle);
617                 if(!id) break;
618                 list->AddFirst(id);
619         }
620         file->Close(); delete file; file=0;     
621         return list;
622 }
623
624 //_____________________________________________________________________________
625 Bool_t AliCDBLocal::Contains(const char* path) const{
626 // check for path in storage's fBaseDirectory
627
628         TString dirName;
629         dirName += fBaseDirectory;
630         dirName += '/';
631         dirName += path; // dirName = fDBPath/path
632         Bool_t result=kFALSE;
633
634         void* dirPtr = gSystem->OpenDirectory(dirName); 
635         if (dirPtr) result=kTRUE;
636         gSystem->FreeDirectory(dirPtr);
637
638         return result;
639 }
640
641 //_____________________________________________________________________________
642 void AliCDBLocal::QueryValidFiles()
643 {
644 // blabla
645
646 }
647
648 /////////////////////////////////////////////////////////////////////////////////////////////////
649 //                                                                                             //
650 // AliCDBLocal factory                                                                         //
651 //                                                                                             //
652 /////////////////////////////////////////////////////////////////////////////////////////////////
653
654 ClassImp(AliCDBLocalFactory)
655
656 //_____________________________________________________________________________
657 Bool_t AliCDBLocalFactory::Validate(const char* dbString) {
658 // check if the string is valid local URI
659
660         TRegexp dbPattern("^local://.+$");
661
662         return TString(dbString).Contains(dbPattern);
663 }
664
665 //_____________________________________________________________________________
666 AliCDBParam* AliCDBLocalFactory::CreateParameter(const char* dbString) {
667 // create AliCDBLocalParam class from the URI string
668
669         if (!Validate(dbString)) {
670                 return NULL;
671         }
672
673         TString pathname(dbString + sizeof("local://") - 1);
674         
675         gSystem->ExpandPathName(pathname);
676
677         if (pathname[0] != '/') {
678                 pathname.Prepend(TString(gSystem->WorkingDirectory()) + '/');
679         }
680
681         return new AliCDBLocalParam(pathname);       
682 }
683
684 //_____________________________________________________________________________
685 AliCDBStorage* AliCDBLocalFactory::Create(const AliCDBParam* param) {
686 // create AliCDBLocal storage instance from parameters
687         
688         if (AliCDBLocalParam::Class() == param->IsA()) {
689                 
690                 const AliCDBLocalParam* localParam = 
691                         (const AliCDBLocalParam*) param;
692                 
693                 return new AliCDBLocal(localParam->GetPath());
694         }
695
696         return NULL;
697 }
698
699 /////////////////////////////////////////////////////////////////////////////////////////////////
700 //                                                                                             //
701 // AliCDBLocal Parameter class                                                                 //                                          //
702 //                                                                                             //
703 /////////////////////////////////////////////////////////////////////////////////////////////////
704
705 ClassImp(AliCDBLocalParam)
706
707 //_____________________________________________________________________________
708 AliCDBLocalParam::AliCDBLocalParam():
709  AliCDBParam(),
710  fDBPath()
711  {
712 // default constructor
713
714 }
715
716 //_____________________________________________________________________________
717 AliCDBLocalParam::AliCDBLocalParam(const char* dbPath):
718  AliCDBParam(),
719  fDBPath(dbPath)
720 {
721 // constructor
722
723         SetType("local");
724         SetURI(TString("local://") + dbPath);
725 }
726
727 //_____________________________________________________________________________
728 AliCDBLocalParam::~AliCDBLocalParam() {
729 // destructor
730
731 }
732
733 //_____________________________________________________________________________
734 AliCDBParam* AliCDBLocalParam::CloneParam() const {
735 // clone parameter
736
737         return new AliCDBLocalParam(fDBPath);
738 }
739
740 //_____________________________________________________________________________
741 ULong_t AliCDBLocalParam::Hash() const {
742 // return Hash function
743
744        return fDBPath.Hash();
745 }
746
747 //_____________________________________________________________________________
748 Bool_t AliCDBLocalParam::IsEqual(const TObject* obj) const {
749 // check if this object is equal to AliCDBParam obj
750
751         if (this == obj) {
752                 return kTRUE;
753         }
754
755         if (AliCDBLocalParam::Class() != obj->IsA()) {
756                 return kFALSE;
757         }
758
759         AliCDBLocalParam* other = (AliCDBLocalParam*) obj;
760
761         return fDBPath == other->fDBPath;
762 }
763