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