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