Completely Updated (Mario Sitta)
[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 // Bool_t AliCDBDump::GetId(const AliCDBId& query, AliCDBId& result) {
256 // // look for filename matching query (called by GetEntry)
257 // 
258 // 
259 //         AliCDBRunRange aRunRange; // the runRange got from filename
260 //         Int_t aVersion, aSubVersion; // the version and subVersion got from filename
261 // 
262 //      TIter iter(gDirectory->GetListOfKeys());
263 //      TKey* key;
264 // 
265 //      if (!query.HasVersion()) { // neither version and subversion specified -> look for highest version and subVersion
266 // 
267 //                 while ((key = (TKey*) iter.Next())) { // loop on the keys
268 // 
269 //                      if (!KeyNameToId(key->GetName(), aRunRange, aVersion, aSubVersion)) continue;
270 //                         // aRunRange, aVersion, aSubVersion filled from filename
271 // 
272 //                      if (!aRunRange.Comprises(query.GetAliCDBRunRange())) continue;
273 //                      // aRunRange contains requested run!
274 // 
275 //                      if (result.GetVersion() < aVersion) {
276 //                              result.SetVersion(aVersion);
277 //                              result.SetSubVersion(aSubVersion);
278 // 
279 //                              result.SetFirstRun(
280 //                                      aRunRange.GetFirstRun());
281 //                              result.SetLastRun(
282 //                                      aRunRange.GetLastRun());
283 // 
284 //                      } else if (result.GetVersion() == aVersion
285 //                              && result.GetSubVersion()
286 //                                      < aSubVersion) {
287 // 
288 //                              result.SetSubVersion(aSubVersion);
289 // 
290 //                              result.SetFirstRun(
291 //                                      aRunRange.GetFirstRun());
292 //                              result.SetLastRun(
293 //                                      aRunRange.GetLastRun());
294 //                      } else if (result.GetVersion() == aVersion
295 //                              && result.GetSubVersion() == aSubVersion){
296 //                                      AliDebug(2,Form("More than one object valid for run %d, version %d_%d!",
297 //                                      query.GetFirstRun(), aVersion, aSubVersion));
298 //                              result.SetRunRange(-1,-1); result.SetVersion(-1); result.SetSubVersion(-1);
299 //                              return kFALSE;
300 //                              }
301 //              }
302 // 
303 //      } else if (!query.HasSubVersion()) { // version specified but not subversion -> look for highest subVersion
304 // 
305 //              result.SetVersion(query.GetVersion());
306 // 
307 //                 while ((key = (TKey*) iter.Next())) { // loop on the keys
308 // 
309 //                      if (!KeyNameToId(key->GetName(), aRunRange, aVersion, aSubVersion)) continue;
310 //                         // aRunRange, aVersion, aSubVersion filled from filename
311 // 
312 //                        if (!aRunRange.Comprises(query.GetAliCDBRunRange())) continue;
313 //                      // aRunRange contains requested run!
314 //                      
315 //                      if(query.GetVersion() != aVersion) continue;
316 //                      // aVersion is requested version!
317 // 
318 //                      if(result.GetSubVersion() == aSubVersion){
319 //                                      AliDebug(2,Form("More than one object valid for run %d, version %d_%d!",
320 //                                      query.GetFirstRun(), aVersion, aSubVersion));
321 //                              result.SetRunRange(-1,-1); result.SetVersion(-1); result.SetSubVersion(-1);
322 //                              return kFALSE;
323 //                      }
324 //                      if( result.GetSubVersion() < aSubVersion) {
325 // 
326 //                                 result.SetSubVersion(aSubVersion);
327 // 
328 //                                 result.SetFirstRun(
329 //                                      aRunRange.GetFirstRun());
330 //                                 result.SetLastRun(
331 //                                      aRunRange.GetLastRun());
332 //                      }
333 //                 }
334 // 
335 //      } else { // both version and subversion specified
336 // 
337 //                 while ((key = (TKey*) iter.Next())) { // loop on the keys
338 // 
339 //                      if (!KeyNameToId(key->GetName(), aRunRange, aVersion, aSubVersion)) continue;
340 //                         // aRunRange, aVersion, aSubVersion filled from filename
341 // 
342 //                      if (!aRunRange.Comprises(query.GetAliCDBRunRange())) continue;
343 //                      // aRunRange contains requested run!
344 // 
345 //                      if(query.GetVersion() != aVersion || query.GetSubVersion() != aSubVersion) continue;
346 //                      // aVersion and aSubVersion are requested version and subVersion!
347 // 
348 //                      if(result.GetVersion() == aVersion && result.GetSubVersion() == aSubVersion){
349 //                                      AliDebug(2,Form("More than one object valid for run %d, version %d_%d!",
350 //                                      query.GetFirstRun(), aVersion, aSubVersion));
351 //                              result.SetRunRange(-1,-1); result.SetVersion(-1); result.SetSubVersion(-1);
352 //                              return kFALSE; 
353 //                      }
354 //                      result.SetVersion(aVersion);
355 //                      result.SetSubVersion(aSubVersion);
356 //                      result.SetFirstRun(aRunRange.GetFirstRun());
357 //                      result.SetLastRun(aRunRange.GetLastRun());
358 // 
359 //              }
360 //      }
361 // 
362 //      return kTRUE;
363 // }
364
365 //_____________________________________________________________________________
366 AliCDBId* AliCDBDump::GetId(const AliCDBId& query) {
367 // look for filename matching query (called by GetEntry)
368
369
370         AliCDBRunRange aRunRange; // the runRange got from filename
371         Int_t aVersion, aSubVersion; // the version and subVersion got from filename
372
373         TIter iter(gDirectory->GetListOfKeys());
374         TKey* key;
375
376         AliCDBId* result = new AliCDBId();
377         result->SetPath(query.GetPath());
378
379         if (!query.HasVersion()) { // neither version and subversion specified -> look for highest version and subVersion
380
381                 while ((key = (TKey*) iter.Next())) { // loop on the keys
382                         
383                         if (!KeyNameToId(key->GetName(), aRunRange, aVersion, aSubVersion)) continue;
384                         // aRunRange, aVersion, aSubVersion filled from filename
385
386                         if (!aRunRange.Comprises(query.GetAliCDBRunRange())) continue;
387                         // aRunRange contains requested run!
388
389                         if (result->GetVersion() < aVersion) {
390                                 result->SetVersion(aVersion);
391                                 result->SetSubVersion(aSubVersion);
392
393                                 result->SetFirstRun(
394                                         aRunRange.GetFirstRun());
395                                 result->SetLastRun(
396                                         aRunRange.GetLastRun());
397
398                         } else if (result->GetVersion() == aVersion
399                                 && result->GetSubVersion()
400                                         < aSubVersion) {
401
402                                 result->SetSubVersion(aSubVersion);
403
404                                 result->SetFirstRun(
405                                         aRunRange.GetFirstRun());
406                                 result->SetLastRun(
407                                         aRunRange.GetLastRun());
408                         } else if (result->GetVersion() == aVersion
409                                 && result->GetSubVersion() == aSubVersion){
410                                 AliError(Form("More than one object valid for run %d, version %d_%d!",
411                                         query.GetFirstRun(), aVersion, aSubVersion));
412                                 delete result;
413                                 return NULL;
414                                 }
415                 }
416
417         } else if (!query.HasSubVersion()) { // version specified but not subversion -> look for highest subVersion
418
419                 result->SetVersion(query.GetVersion());
420
421                 while ((key = (TKey*) iter.Next())) { // loop on the keys
422
423                         if (!KeyNameToId(key->GetName(), aRunRange, aVersion, aSubVersion)) continue;
424                         // aRunRange, aVersion, aSubVersion filled from filename
425
426                        if (!aRunRange.Comprises(query.GetAliCDBRunRange())) continue; 
427                         // aRunRange contains requested run!
428                         
429                         if(query.GetVersion() != aVersion) continue;
430                         // aVersion is requested version!
431
432                         if(result->GetSubVersion() == aSubVersion){
433                                 AliError(Form("More than one object valid for run %d, version %d_%d!",
434                                         query.GetFirstRun(), aVersion, aSubVersion));
435                                 delete result;
436                                 return NULL;
437                         }
438                         if( result->GetSubVersion() < aSubVersion) {
439
440                                 result->SetSubVersion(aSubVersion);
441
442                                 result->SetFirstRun(
443                                         aRunRange.GetFirstRun());
444                                 result->SetLastRun(
445                                         aRunRange.GetLastRun());
446                         } 
447                 }
448
449         } else { // both version and subversion specified
450
451                 while ((key = (TKey*) iter.Next())) { // loop on the keys
452                         
453                         if (!KeyNameToId(key->GetName(), aRunRange, aVersion, aSubVersion)) continue;
454                         // aRunRange, aVersion, aSubVersion filled from filename
455
456                         if (!aRunRange.Comprises(query.GetAliCDBRunRange())) continue;
457                         // aRunRange contains requested run!
458
459                         if(query.GetVersion() != aVersion || query.GetSubVersion() != aSubVersion) continue;
460                         // aVersion and aSubVersion are requested version and subVersion!
461
462                         if(result->GetVersion() == aVersion && result->GetSubVersion() == aSubVersion){
463                                 AliError(Form("More than one object valid for run %d, version %d_%d!",
464                                         query.GetFirstRun(), aVersion, aSubVersion));
465                                 delete result;
466                                 return NULL;
467                         }
468                         result->SetVersion(aVersion);
469                         result->SetSubVersion(aSubVersion);
470                         result->SetFirstRun(aRunRange.GetFirstRun());
471                         result->SetLastRun(aRunRange.GetLastRun());
472                         
473                 }
474         }
475
476         return result;
477 }
478
479 //_____________________________________________________________________________
480 AliCDBEntry* AliCDBDump::GetEntry(const AliCDBId& queryId) {
481 // get AliCDBEntry from the database
482
483         TDirectory::TContext context(gDirectory, fFile);
484
485         if (!(fFile && fFile->IsOpen())) {
486                 AliError("AliCDBDump storage is not initialized properly");
487                 return NULL;
488         }
489
490         if (!gDirectory->cd(queryId.GetPath())) {
491                 return NULL;
492         }
493
494         AliCDBId *dataId = GetEntryId(queryId);
495
496         if (!dataId || !dataId->IsSpecified()) {
497                 if(dataId) delete dataId;
498                 return NULL;
499         }
500
501         TString keyname;
502         if (!IdToKeyName(dataId->GetAliCDBRunRange(), dataId->GetVersion(),
503                 dataId->GetSubVersion(), keyname)) {
504                 AliDebug(2,Form("Bad ID encountered! Subnormal error!"));
505                 delete dataId;
506                 return NULL;
507         }
508
509         // get the only AliCDBEntry object from the file
510         // the object in the file is an AliCDBEntry entry named keyname
511         // keyName = Run#firstRun_#lastRun_v#version_s#subVersion
512
513         TObject* anObject = gDirectory->Get(keyname);
514         if (!anObject) {
515                 AliDebug(2,Form("Bad storage data: NULL entry object!"));
516                 delete dataId;
517                 return NULL;
518         } 
519
520         if (AliCDBEntry::Class() != anObject->IsA()) {
521                 AliDebug(2,Form("Bad storage data: Invalid entry object!"));
522                 delete dataId;
523                 return NULL;
524         }
525
526         ((AliCDBEntry*) anObject)->SetLastStorage("dump");
527
528         delete dataId;
529         return (AliCDBEntry*) anObject;
530 }
531
532 //_____________________________________________________________________________
533 AliCDBId* AliCDBDump::GetEntryId(const AliCDBId& queryId) {
534 // get AliCDBEntry from the database
535
536         TDirectory::TContext context(gDirectory, fFile);
537
538         if (!(fFile && fFile->IsOpen())) {
539                 AliError("AliCDBDump storage is not initialized properly");
540                 return NULL;
541         }
542
543         if (!gDirectory->cd(queryId.GetPath())) {
544                 return NULL;
545         }
546
547         AliCDBId* dataId = 0;
548
549         // look for a filename matching query requests (path, runRange, version, subVersion)
550         if (!queryId.HasVersion()) {
551                 // if version is not specified, first check the selection criteria list
552                 AliCDBId selectedId(queryId);
553                 GetSelection(&selectedId);
554                 dataId = GetId(queryId);
555         } else {
556                 dataId = GetId(queryId);
557         }
558
559         if (dataId && !dataId->IsSpecified()) {
560                 delete dataId;
561                 return NULL;
562         }
563
564         return dataId;
565 }
566
567 //_____________________________________________________________________________
568 void AliCDBDump::GetEntriesForLevel0(const AliCDBId& queryId, TList* result) {
569 // multiple request (AliCDBStorage::GetAll)
570
571         TDirectory* saveDir = gDirectory;
572
573         TIter iter(gDirectory->GetListOfKeys());
574         TKey* key;
575
576         while ((key = (TKey*) iter.Next())) {
577
578                 TString keyNameStr(key->GetName());
579                 if (queryId.GetAliCDBPath().Level1Comprises(keyNameStr)) {
580                         gDirectory->cd(keyNameStr);
581                         GetEntriesForLevel1(queryId, result);
582                         
583                         saveDir->cd();
584                 }
585         }
586 }
587
588 //_____________________________________________________________________________
589 void AliCDBDump::GetEntriesForLevel1(const AliCDBId& queryId, TList* result) {
590 // multiple request (AliCDBStorage::GetAll)
591
592         TIter iter(gDirectory->GetListOfKeys());
593         TKey* key;
594
595         TDirectory* level0Dir = (TDirectory*) gDirectory->GetMother();
596
597         while ((key = (TKey*) iter.Next())) {
598
599                 TString keyNameStr(key->GetName());
600                 if (queryId.GetAliCDBPath().Level2Comprises(keyNameStr)) {
601                         
602                         AliCDBPath aPath(level0Dir->GetName(), 
603                                         gDirectory->GetName(), keyNameStr);
604                         AliCDBId anId(aPath, queryId.GetAliCDBRunRange(), 
605                                         queryId.GetVersion(), -1);
606
607                         AliCDBEntry* anEntry = GetEntry(anId);
608                         if (anEntry) {
609                                 result->Add(anEntry);
610                         }
611         
612                 }
613         }
614
615 }
616
617                         
618 //_____________________________________________________________________________
619 TList* AliCDBDump::GetEntries(const AliCDBId& queryId) {
620 // multiple request (AliCDBStorage::GetAll)
621
622         TDirectory::TContext context(gDirectory, fFile);
623
624         if (!(fFile && fFile->IsOpen())) {
625                 AliError("AliCDBDump storage is not initialized properly");
626                 return NULL;
627         }
628
629         TList* result = new TList();
630         result->SetOwner();
631
632         TIter iter(gDirectory->GetListOfKeys());
633         TKey* key;
634
635         while ((key = (TKey*) iter.Next())) {
636                 
637                 TString keyNameStr(key->GetName());
638                 if (queryId.GetAliCDBPath().Level0Comprises(keyNameStr)) {
639                         gDirectory->cd(keyNameStr);
640                         GetEntriesForLevel0(queryId, result);
641
642                         fFile->cd();
643                 }
644         }
645
646         return result;
647 }
648
649 //_____________________________________________________________________________
650 Bool_t AliCDBDump::PutEntry(AliCDBEntry* entry) {
651 // put an AliCDBEntry object into the database
652
653         TDirectory::TContext context(gDirectory, fFile);
654
655         if (!(fFile && fFile->IsOpen())) {
656                 AliError("AliCDBDump storage is not initialized properly");
657                 return kFALSE;
658         }
659
660         if (fReadOnly) {
661                 AliError("AliCDBDump storage is read only!");
662                 return kFALSE;
663         }
664
665         AliCDBId& id = entry->GetId();
666         
667         if (!gDirectory->cd(id.GetPath())) {
668                 if (!MkDir(id.GetPath())) {
669                         AliError(Form("Can't open directory <%s>!", 
670                                         id.GetPath().Data()));
671                         return kFALSE;
672                 }
673         }
674
675         // set version and subVersion for the entry to be stored
676         if (!PrepareId(id)) {
677                 return kFALSE;          
678         }
679
680         // build keyname from entry's id
681         TString keyname;
682         if (!IdToKeyName(id.GetAliCDBRunRange(), id.GetVersion(), id.GetSubVersion(), keyname)) {
683                 AliError("Invalid ID encountered! Subnormal error!");
684                 return kFALSE;
685         }       
686
687         // write object (key name: Run#firstRun_#lastRun_v#version_s#subVersion)
688         Bool_t result = gDirectory->WriteTObject(entry, keyname);
689         if (!result) {
690                 AliError(Form("Can't write entry to file: %s",
691                                 fFile->GetName()));
692         }
693
694         if(result) {
695                 AliInfo(Form("CDB object stored into file %s",fFile->GetName()));
696                 AliInfo(Form("TDirectory/key name: %s/%s",id.GetPath().Data(),keyname.Data()));
697         }
698
699         return result;
700 }
701 //_____________________________________________________________________________
702 TList* AliCDBDump::GetIdListFromFile(const char* fileName){
703
704         TString turl(fileName);
705         if (turl[0] != '/') {
706                 turl.Prepend(TString(gSystem->WorkingDirectory()) + '/');
707         }
708         TFile *file = TFile::Open(turl);
709         if (!file) {
710                 AliError(Form("Can't open selection file <%s>!", turl.Data()));
711                 return NULL;
712         }
713         file->cd();
714
715         TList *list = new TList();
716         list->SetOwner();
717         int i=0;
718         TString keycycle;
719         
720         AliCDBId *id;
721         while(1){
722                 i++;
723                 keycycle = "AliCDBId;";
724                 keycycle+=i;
725                 
726                 id = (AliCDBId*) file->Get(keycycle);
727                 if(!id) break;
728                 list->AddFirst(id);
729         }
730         file->Close(); delete file; file=0;     
731         return list;
732 }
733
734 //_____________________________________________________________________________
735 Bool_t AliCDBDump::Contains(const char* path) const{
736 // check for path in storage
737
738         TDirectory::TContext context(gDirectory, fFile);
739         if (!(fFile && fFile->IsOpen())) {
740                 AliError("AliCDBDump storage is not initialized properly");
741                 return kFALSE;
742         }
743         
744         return gDirectory->cd(path);
745
746 }
747
748 //_____________________________________________________________________________
749 void AliCDBDump::QueryValidFiles()
750 {
751 // Query the CDB for files valid for AliCDBStorage::fRun
752 // fills list fValidFileIds with AliCDBId objects created from file name
753
754         AliError("Not yet (and maybe never) implemented");
755 }
756
757 //_____________________________________________________________________________
758 Bool_t AliCDBDump::IdToFilename(const AliCDBId& /*id*/, TString& /*filename*/) const {
759 // build file name from AliCDBId (path, run range, version) and fDBFolder
760
761         AliError("Not implemented");
762         return kFALSE;
763 }
764
765 //_____________________________________________________________________________
766 Int_t AliCDBDump::GetLatestVersion(const char* path, Int_t run){
767 // get last version found in the database valid for run and path
768
769         AliCDBPath aCDBPath(path);
770         if(!aCDBPath.IsValid() || aCDBPath.IsWildcard()) {
771                 AliError(Form("Invalid path in request: %s", path));
772                 return -1;
773         }
774
775         AliCDBId query(path, run, run, -1, -1);
776         AliCDBId *dataId = GetId(query);
777
778         if(!dataId) return -1;
779         Int_t version = dataId->GetVersion();
780
781         delete dataId;
782         return version;
783 }
784
785 //_____________________________________________________________________________
786 Int_t AliCDBDump::GetLatestSubVersion(const char* path, Int_t run, Int_t version){
787 // get last version found in the database valid for run and path
788
789         AliCDBPath aCDBPath(path);
790         if(!aCDBPath.IsValid() || aCDBPath.IsWildcard()) {
791                 AliError(Form("Invalid path in request: %s", path));
792                 return -1;
793         }
794
795         AliCDBId query(path, run, run, version, -1);
796         AliCDBId *dataId = GetId(query);
797
798         if(!dataId) return -1;
799
800         Int_t subVersion = dataId->GetSubVersion();
801
802         delete dataId;
803         return subVersion;
804
805 }
806
807
808 /////////////////////////////////////////////////////////////////////////////////////////////////
809 //                                                                                             //
810 // AliCDBDump factory                                                                          //
811 //                                                                                             //
812 /////////////////////////////////////////////////////////////////////////////////////////////////
813
814 ClassImp(AliCDBDumpFactory)
815
816 //_____________________________________________________________________________
817 Bool_t AliCDBDumpFactory::Validate(const char* dbString) {
818 // check if the string is valid dump URI
819
820         TRegexp dbPattern("^dump://.+$");
821
822         return TString(dbString).Contains(dbPattern);
823 }
824
825 //_____________________________________________________________________________
826 AliCDBParam* AliCDBDumpFactory::CreateParameter(const char* dbString) {
827 // create AliCDBDumpParam class from the URI string
828
829         if (!Validate(dbString)) {
830                 return NULL;
831         }
832
833         TString pathname(dbString + sizeof("dump://") - 1);
834
835         Bool_t readOnly;
836
837         if (pathname.Contains(TRegexp(";ReadOnly$"))) {
838                 pathname.Resize(pathname.Length() - sizeof(";ReadOnly") + 1);
839                 readOnly = kTRUE;
840         } else {
841                 readOnly = kFALSE;
842         }
843
844         gSystem->ExpandPathName(pathname);
845         
846         if (pathname[0] != '/') {
847                 pathname.Prepend(TString(gSystem->WorkingDirectory()) + '/');
848         }
849
850         return new AliCDBDumpParam(pathname, readOnly);
851 }
852
853 //_____________________________________________________________________________
854 AliCDBStorage* AliCDBDumpFactory::Create(const AliCDBParam* param) {
855 // create AliCDBDump storage instance from parameters
856
857         if (AliCDBDumpParam::Class() == param->IsA()) {
858
859                 const AliCDBDumpParam* dumpParam = 
860                         (const AliCDBDumpParam*) param;
861
862                 return new AliCDBDump(dumpParam->GetPath(),
863                                 dumpParam->IsReadOnly());
864         }
865
866         return NULL;
867 }
868
869 /////////////////////////////////////////////////////////////////////////////////////////////////
870 //                                                                                             //
871 // AliCDBDump parameter class                                                                  //
872 //                                                                                             //
873 /////////////////////////////////////////////////////////////////////////////////////////////////
874
875 ClassImp(AliCDBDumpParam)
876
877 //_____________________________________________________________________________
878 AliCDBDumpParam::AliCDBDumpParam():
879 fDBPath(), fReadOnly(kFALSE)
880 {
881 // default constructor
882
883 }
884
885 //_____________________________________________________________________________
886 AliCDBDumpParam::AliCDBDumpParam(const char* dbPath, Bool_t readOnly):
887         fDBPath(dbPath), fReadOnly(readOnly)
888 {
889 // constructor
890
891         TString uri;
892         uri += "dump://";
893         uri += dbPath;
894
895         if (fReadOnly) {
896                 uri += ";ReadOnly";
897         }
898         
899         SetURI(uri);
900         SetType("dump");
901 }
902
903 //_____________________________________________________________________________
904 AliCDBDumpParam::~AliCDBDumpParam() {
905 // destructor
906
907 }
908
909 //_____________________________________________________________________________
910 AliCDBParam* AliCDBDumpParam::CloneParam() const {
911 // clone parameter
912
913         return new AliCDBDumpParam(fDBPath, fReadOnly);
914 }
915
916 //_____________________________________________________________________________
917 ULong_t AliCDBDumpParam::Hash() const {
918 // return Hash function
919
920         return fDBPath.Hash();
921 }
922
923 //_____________________________________________________________________________
924 Bool_t AliCDBDumpParam::IsEqual(const TObject* obj) const {
925 // check if this object is equal to AliCDBParam obj
926         
927         if (this == obj) {
928                 return kTRUE;
929         }
930
931         if (AliCDBDumpParam::Class() != obj->IsA()) {
932                 return kFALSE;
933         }
934
935         AliCDBDumpParam* other = (AliCDBDumpParam*) obj;
936
937         return fDBPath == other->fDBPath;
938 }