]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliCDBGrid.cxx
Fixes for some mem-leaks: most changes where pretty basic (i.e. adding deletes).
[u/mrichter/AliRoot.git] / STEER / AliCDBGrid.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 // AliCDBGrid                                                                                  //
19 // access class to a DataBase in an AliEn storage                                              //
20 //                                                                                             //
21 /////////////////////////////////////////////////////////////////////////////////////////////////
22
23
24 #include <TGrid.h>
25 #include <TGridResult.h>
26 #include <TFile.h>
27 #include <TKey.h>
28 #include <TROOT.h>
29 #include <TList.h>
30 #include <TObjArray.h>
31 #include <TObjString.h>
32 #include <TRegexp.h>
33
34 #include "AliLog.h"
35 #include "AliCDBEntry.h"
36 #include "AliCDBGrid.h"
37 #include "AliCDBManager.h"
38
39
40 ClassImp(AliCDBGrid)
41
42 //_____________________________________________________________________________
43 AliCDBGrid::AliCDBGrid(const char *gridUrl, const char *user, const char *dbFolder, const char *se) :
44 AliCDBStorage(),
45 fGridUrl(gridUrl),
46 fUser(user),
47 fDBFolder(dbFolder),
48 fSE(se)
49 {
50 // constructor //
51
52         // if the same Grid is alreay active, skip connection
53         if (!gGrid || fGridUrl != gGrid->GridUrl()
54              || (( fUser != "" ) && ( fUser != gGrid->GetUser() )) ) {
55                 // connection to the Grid
56                 AliInfo("Connection to the Grid...");
57                 if(gGrid){
58                         AliInfo(Form("gGrid = %x; fGridUrl = %s; gGrid->GridUrl() = %s",gGrid,fGridUrl.Data(), gGrid->GridUrl()));
59                         AliInfo(Form("fUser = %s; gGrid->GetUser() = %s",fUser.Data(), gGrid->GetUser()));
60                 }
61                 TGrid::Connect(fGridUrl.Data(),fUser.Data());
62         }
63
64         if(!gGrid) {
65                 AliError("Connection failed!");
66                 return;
67         }
68
69         TString initDir(gGrid->Pwd(0));
70         if (fDBFolder[0] != '/') {
71                 fDBFolder.Prepend(initDir);
72         }
73
74         // check DBFolder: trying to cd to DBFolder; if it does not exist, create it
75         if(!gGrid->Cd(fDBFolder.Data(),0)){
76                 AliDebug(2,Form("Creating new folder <%s> ...",fDBFolder.Data()));
77                 if(!gGrid->Mkdir(fDBFolder.Data(),"",0)){
78                         AliError(Form("Cannot create folder <%s> !",fDBFolder.Data()));
79                 }
80         } else {
81                 AliDebug(2,Form("Folder <%s> found",fDBFolder.Data()));
82         }
83
84         // removes any '/' at the end of path, then append one '/'
85         while(fDBFolder.EndsWith("/")) fDBFolder.Remove(fDBFolder.Last('/')); 
86         fDBFolder+="/";
87
88         fType="alien";
89         fBaseFolder = fDBFolder;
90
91         // return to the initial directory
92         gGrid->Cd(initDir.Data(),0);
93 }
94
95 //_____________________________________________________________________________
96 AliCDBGrid::~AliCDBGrid()
97 {
98 // destructor
99         delete gGrid; gGrid=0;
100
101 }
102
103 //_____________________________________________________________________________
104 Bool_t AliCDBGrid::FilenameToId(TString& filename, AliCDBId& id) {
105 // build AliCDBId from full path filename (fDBFolder/path/Run#x_#y_v#z_s0.root)
106
107         if(filename.Contains(fDBFolder)){
108                 filename = filename(fDBFolder.Length(),filename.Length()-fDBFolder.Length());
109         }
110
111         TString idPath = filename(0,filename.Last('/'));
112         id.SetPath(idPath);
113         if(!id.IsValid()) return kFALSE;
114
115         filename=filename(idPath.Length()+1,filename.Length()-idPath.Length());
116
117         Ssiz_t mSize;
118         // valid filename: Run#firstRun_#lastRun_v#version_s0.root
119         TRegexp keyPattern("^Run[0-9]+_[0-9]+_v[0-9]+_s0.root$");
120         keyPattern.Index(filename, &mSize);
121         if (!mSize) {
122
123                 // TODO backward compatibility ... maybe remove later!
124                 Ssiz_t oldmSize;
125                 TRegexp oldKeyPattern("^Run[0-9]+_[0-9]+_v[0-9]+.root$");
126                 oldKeyPattern.Index(filename, &oldmSize);
127                 if(!oldmSize) {
128                         AliDebug(2,Form("Bad filename <%s>.", filename.Data()));
129                         return kFALSE;
130                 } else {
131                         AliDebug(2,Form("Old filename format <%s>.", filename.Data()));
132                         id.SetSubVersion(-11); // TODO trick to ensure backward compatibility
133                 }
134
135         } else {
136                 id.SetSubVersion(-1); // TODO trick to ensure backward compatibility
137         }
138
139         filename.Resize(filename.Length() - sizeof(".root") + 1);
140
141         TObjArray* strArray = (TObjArray*) filename.Tokenize("_");
142
143         TString firstRunString(((TObjString*) strArray->At(0))->GetString());
144         id.SetFirstRun(atoi(firstRunString.Data() + 3));
145         id.SetLastRun(atoi(((TObjString*) strArray->At(1))->GetString()));
146
147         TString verString(((TObjString*) strArray->At(2))->GetString());
148         id.SetVersion(atoi(verString.Data() + 1));
149
150         delete strArray;
151
152         return kTRUE;
153 }
154
155 //_____________________________________________________________________________
156 Bool_t AliCDBGrid::IdToFilename(const AliCDBId& id, TString& filename) const {
157 // build file name from AliCDBId (path, run range, version) and fDBFolder
158
159         if (!id.GetAliCDBRunRange().IsValid()) {
160                 AliDebug(2,Form("Invalid run range <%d, %d>.",
161                         id.GetFirstRun(), id.GetLastRun()));
162                 return kFALSE;
163         }
164
165         if (id.GetVersion() < 0) {
166                 AliDebug(2,Form("Invalid version <%d>.", id.GetVersion()));
167                 return kFALSE;
168         }
169
170         filename = Form("Run%d_%d_v%d",
171                                 id.GetFirstRun(),
172                                 id.GetLastRun(),
173                                 id.GetVersion());
174
175         if (id.GetSubVersion() != -11) filename += "_s0"; // TODO to ensure backward compatibility
176         filename += ".root";
177
178         filename.Prepend(fDBFolder + id.GetPath() + '/');
179
180         return kTRUE;
181 }
182
183 //_____________________________________________________________________________
184 Bool_t AliCDBGrid::PrepareId(AliCDBId& id) {
185 // prepare id (version) of the object that will be stored (called by PutEntry)
186
187         TString initDir(gGrid->Pwd(0));
188
189         TString dirName(fDBFolder);
190
191         Bool_t dirExist=kFALSE;
192
193
194
195         // go to the path; if directory does not exist, create it
196         for(int i=0;i<3;i++){
197                 dirName+=Form("%s/",id.GetPathLevel(i).Data());
198                 dirExist=gGrid->Cd(dirName,0);
199                 if (!dirExist) {
200                         AliDebug(2,Form("Creating new folder <%s> ...",dirName.Data()));
201                         if(!gGrid->Mkdir(dirName,"",0)){
202                                 AliError(Form("Cannot create directory <%s> !",dirName.Data()));
203                                 gGrid->Cd(initDir.Data());
204                         return kFALSE;
205                         }
206
207                         // if folders are new add tags to them
208                         if(i == 1) {
209                                 // TODO Currently disabled
210                                 // AliInfo("Tagging level 1 folder with \"ShortLived\" tag");
211                                 // if(!AddTag(dirName,"ShortLived_try")){
212                                 //      AliError(Form("Could not tag folder %s !", dirName.Data()));
213                                 //      if(!gGrid->Rmdir(dirName.Data())){
214                                 //              AliError(Form("Unexpected: could not remove %s directory!", dirName.Data()));
215                                 //      }
216                                 //      return 0;
217                                 //}
218
219                         } else if(i == 2) {
220                                 AliInfo("Tagging level 2 folder with \"CDB\" and \"CDB_MD\" tag");
221                                 if(!AddTag(dirName,"CDB")){
222                                         AliError(Form("Could not tag folder %s !", dirName.Data()));
223                                         if(!gGrid->Rmdir(dirName.Data())){
224                                                 AliError(Form("Unexpected: could not remove %s directory!", dirName.Data()));
225                                         }
226                                         return 0;
227                                 }
228                                 if(!AddTag(dirName,"CDB_MD")){
229                                         AliError(Form("Could not tag folder %s !", dirName.Data()));
230                                         if(!gGrid->Rmdir(dirName.Data())){
231                                                 AliError(Form("Unexpected: could not remove %s directory!", dirName.Data()));
232                                         }
233                                         return 0;
234                                 }
235
236                                 // add short lived tag!
237                                 // TODO Currently disabled
238                                 // TString path=id.GetPath();
239                                 // if(AliCDBManager::Instance()->IsShortLived(path.Data())) {
240                                 //      AliInfo(Form("Tagging %s as short lived", dirName.Data()));
241                                 //      if(!TagShortLived(dirName, kTRUE)){
242                                 //              AliError(Form("Could not tag folder %s !", dirName.Data()));
243                                 //              if(!gGrid->Rmdir(dirName.Data())){
244                                 //                      AliError(Form("Unexpected: could not remove %s directory!", dirName.Data()));
245                                 //              }
246                                 //              return 0;
247                                 //      }
248                                 // } else {
249                                 //      AliInfo(Form("Tagging %s as long lived", dirName.Data()));
250                                 //      if(!TagShortLived(dirName, kFALSE)){
251                                 //              AliError(Form("Could not tag folder %s !", dirName.Data()));
252                                 //              if(!gGrid->Rmdir(dirName.Data())){
253                                 //                      AliError(Form("Unexpected: could not remove %s directory!", dirName.Data()));
254                                 //              }
255                                 //              return 0;
256                                 //      }
257                                 // }
258                         }
259                 }
260         }
261         gGrid->Cd(initDir,0);
262
263         TString filename;
264         AliCDBId anId; // the id got from filename
265         AliCDBRunRange lastRunRange(-1,-1); // highest runRange found
266         Int_t lastVersion=0; // highest version found
267
268         TGridResult *res = gGrid->Ls(dirName);
269
270         //loop on the files in the directory, look for highest version
271         for(int i=0; i < res->GetEntries(); i++){
272                 filename=res->GetFileNamePath(i);
273                 if (!FilenameToId(filename, anId)) continue;
274                 if (anId.GetAliCDBRunRange().Overlaps(id.GetAliCDBRunRange()) && anId.GetVersion() > lastVersion) {
275                         lastVersion = anId.GetVersion();
276                         lastRunRange = anId.GetAliCDBRunRange();
277                 }
278
279         }
280         delete res;
281
282         id.SetVersion(lastVersion + 1);
283         id.SetSubVersion(0);
284
285         TString lastStorage = id.GetLastStorage();
286         if(lastStorage.Contains(TString("new"), TString::kIgnoreCase) && id.GetVersion() > 1 ){
287                 AliDebug(2, Form("A NEW object is being stored with version %d",
288                                         id.GetVersion()));
289                 AliDebug(2, Form("and it will hide previously stored object with version %d!",
290                                         id.GetVersion()-1));
291         }
292
293         if(!lastRunRange.IsAnyRange() && !(lastRunRange.IsEqual(&id.GetAliCDBRunRange())))
294                 AliWarning(Form("Run range modified w.r.t. previous version (Run%d_%d_v%d)",
295                         lastRunRange.GetFirstRun(), lastRunRange.GetLastRun(), id.GetVersion()));
296
297         return kTRUE;
298 }
299
300 //_____________________________________________________________________________
301 AliCDBId* AliCDBGrid::GetId(const TObjArray& validFileIds, const AliCDBId& query) {
302 // look for the Id that matches query's requests (highest or exact version)
303
304         if(validFileIds.GetEntriesFast() < 1) {
305                 return NULL;
306         } else if (validFileIds.GetEntriesFast() == 1) {
307                 return dynamic_cast<AliCDBId*> (validFileIds.At(0)->Clone());
308         }
309
310         TIter iter(&validFileIds);
311
312         AliCDBId *anIdPtr=0;
313         AliCDBId* result=0;
314
315         while((anIdPtr = dynamic_cast<AliCDBId*> (iter.Next()))){
316                 if(anIdPtr->GetPath() != query.GetPath()) continue;
317
318                 //if(!CheckVersion(query, anIdPtr, result)) return NULL;
319
320                 if (!query.HasVersion()){ // look for highest version
321                         if(result && result->GetVersion() > anIdPtr->GetVersion()) continue;
322                         if(result && result->GetVersion() == anIdPtr->GetVersion()) {
323                                 AliError(Form("More than one object valid for run %d, version %d!",
324                                         query.GetFirstRun(), anIdPtr->GetVersion()));
325                                 return NULL;
326                         }
327                         result = anIdPtr;
328                 } else { // look for specified version
329                         if(query.GetVersion() != anIdPtr->GetVersion()) continue;
330                         if(result && result->GetVersion() == anIdPtr->GetVersion()){
331                                 AliError(Form("More than one object valid for run %d, version %d!",
332                                         query.GetFirstRun(), anIdPtr->GetVersion()));
333                                 return NULL;
334                         }
335                         result = anIdPtr;
336                 }
337
338         }
339
340         return dynamic_cast<AliCDBId*> (result->Clone());
341 }
342
343 //_____________________________________________________________________________
344 AliCDBId* AliCDBGrid::GetEntryId(const AliCDBId& queryId) {
345 // get AliCDBId from the database
346 // User must delete returned object
347
348         AliCDBId* dataId=0;
349
350         AliCDBId selectedId(queryId);
351         if (!selectedId.HasVersion()) {
352                 // if version is not specified, first check the selection criteria list
353                 GetSelection(&selectedId);
354         }
355
356         TObjArray validFileIds;
357         validFileIds.SetOwner(1);
358
359         // look for file matching query requests (path, runRange, version)
360         if(selectedId.GetFirstRun() == fRun &&
361                         fPathFilter.Comprises(selectedId.GetAliCDBPath()) && fVersion < 0 && !fMetaDataFilter){
362                 // look into list of valid files previously loaded with AliCDBStorage::FillValidFileIds()
363                 AliDebug(2, Form("List of files valid for run %d and for path %s was loaded. Looking there!",
364                                         selectedId.GetFirstRun(), selectedId.GetPath().Data()));
365                 dataId = GetId(fValidFileIds, selectedId);
366
367         } else {
368                 // List of files valid for reqested run was not loaded. Looking directly into CDB
369                 AliDebug(2, Form("List of files valid for run %d and for path %s was not loaded. Looking directly into CDB!",
370                                         selectedId.GetFirstRun(), selectedId.GetPath().Data()));
371
372                 TString filter;
373                 MakeQueryFilter(selectedId.GetFirstRun(), selectedId.GetLastRun(), 0, filter);
374
375                 TString pattern = Form("%s/Run*", selectedId.GetPath().Data());
376                 if(selectedId.GetVersion() >= 0) pattern += Form("_v%d*",selectedId.GetVersion());
377                 pattern += ".root";
378                 AliDebug(2,Form("pattern: %s", pattern.Data()));
379
380                 TGridResult *res = gGrid->Query(fDBFolder, pattern, filter, "");
381                 AliCDBId validFileId;
382                 for(int i=0; i<res->GetEntries(); i++){
383                         TString filename = res->GetKey(i, "lfn");
384                         if(filename == "") continue;
385                         if(FilenameToId(filename, validFileId))
386                                         validFileIds.AddLast(validFileId.Clone());
387                 }
388                 delete res;
389                 dataId = GetId(validFileIds, selectedId);
390         }
391
392         return dataId;
393 }
394
395 //_____________________________________________________________________________
396 AliCDBEntry* AliCDBGrid::GetEntry(const AliCDBId& queryId) {
397 // get AliCDBEntry from the database
398
399         AliCDBId* dataId = GetEntryId(queryId);
400
401         if (!dataId) return NULL;
402
403         TString filename;
404         if (!IdToFilename(*dataId, filename)) {
405                 AliDebug(2,Form("Bad data ID encountered! Subnormal error!"));
406                 delete dataId;
407                 return NULL;
408         }
409
410         AliCDBEntry* anEntry = GetEntryFromFile(filename, dataId);
411
412         delete dataId;
413         return anEntry;
414 }
415
416 //_____________________________________________________________________________
417 AliCDBEntry* AliCDBGrid::GetEntryFromFile(TString& filename, AliCDBId* dataId){
418 // Get AliCBEntry object from file "filename"
419
420         AliDebug(2,Form("Opening file: %s",filename.Data()));
421
422         filename.Prepend("/alien");
423         TFile *file = TFile::Open(filename);
424         if (!file) {
425                 AliDebug(2,Form("Can't open file <%s>!", filename.Data()));
426                 return NULL;
427         }
428
429         // get the only AliCDBEntry object from the file
430         // the object in the file is an AliCDBEntry entry named "AliCDBEntry"
431
432         AliCDBEntry* anEntry = dynamic_cast<AliCDBEntry*> (file->Get("AliCDBEntry"));
433
434         if (!anEntry) {
435                 AliDebug(2,Form("Bad storage data: file does not contain an AliCDBEntry object!"));
436                 file->Close();
437                 return NULL;
438         }
439
440         // The object's Id is not reset during storage
441         // If object's Id runRange or version do not match with filename,
442         // it means that someone renamed file by hand. In this case a warning msg is issued.
443
444         if(anEntry){
445                 AliCDBId entryId = anEntry->GetId();
446                 Int_t tmpSubVersion = dataId->GetSubVersion();
447                 dataId->SetSubVersion(entryId.GetSubVersion()); // otherwise filename and id may mismatch
448                 if(!entryId.IsEqual(dataId)){
449                         AliWarning(Form("Mismatch between file name and object's Id!"));
450                         AliWarning(Form("File name: %s", dataId->ToString().Data()));
451                         AliWarning(Form("Object's Id: %s", entryId.ToString().Data()));
452                 }
453                 dataId->SetSubVersion(tmpSubVersion);
454         }
455
456         anEntry->SetLastStorage("grid");
457
458         // Check whether entry contains a TTree. In case load the tree in memory!
459         LoadTreeFromFile(anEntry);
460
461         // close file, return retieved entry
462         file->Close(); delete file; file=0;
463
464         return anEntry;
465 }
466
467 //_____________________________________________________________________________
468 TList* AliCDBGrid::GetEntries(const AliCDBId& queryId) {
469 // multiple request (AliCDBStorage::GetAll)
470
471         TList* result = new TList();
472         result->SetOwner();
473
474         TObjArray validFileIds;
475         validFileIds.SetOwner(1);
476
477         Bool_t alreadyLoaded = kFALSE;
478
479         // look for file matching query requests (path, runRange)
480         if(queryId.GetFirstRun() == fRun &&
481                         fPathFilter.Comprises(queryId.GetAliCDBPath()) && fVersion < 0 && !fMetaDataFilter){
482                 // look into list of valid files previously loaded with AliCDBStorage::FillValidFileIds()
483                 AliDebug(2,Form("List of files valid for run %d and for path %s was loaded. Looking there!",
484                                         queryId.GetFirstRun(), queryId.GetPath().Data()));
485
486                 alreadyLoaded = kTRUE;
487
488         } else {
489                 // List of files valid for reqested run was not loaded. Looking directly into CDB
490                 AliDebug(2,Form("List of files valid for run %d and for path %s was not loaded. Looking directly into CDB!",
491                                         queryId.GetFirstRun(), queryId.GetPath().Data()));
492
493                 TString filter;
494                 MakeQueryFilter(queryId.GetFirstRun(), queryId.GetLastRun(), 0, filter);
495
496                 TString pattern = Form("%s/Run*.root", queryId.GetPath().Data());
497                 AliDebug(2,Form("pattern: %s", pattern.Data()));
498
499                 TGridResult *res = gGrid->Query(fDBFolder, pattern, filter, "");
500
501                 AliCDBId validFileId;
502                 for(int i=0; i<res->GetEntries(); i++){
503                         TString filename = res->GetKey(i, "lfn");
504                         if(filename == "") continue;
505                         if(FilenameToId(filename, validFileId))
506                                         validFileIds.AddLast(validFileId.Clone());
507                 }
508                 delete res;
509         }
510
511         TIter *iter=0;
512         if(alreadyLoaded){
513                 iter = new TIter(&fValidFileIds);
514         } else {
515                 iter = new TIter(&validFileIds);
516         }
517
518         TObjArray selectedIds;
519         selectedIds.SetOwner(1);
520
521         // loop on list of valid Ids to select the right version to get.
522         // According to query and to the selection criteria list, version can be the highest or exact
523         AliCDBPath pathCopy;
524         AliCDBId* anIdPtr=0;
525         AliCDBId* dataId=0;
526         AliCDBPath queryPath = queryId.GetAliCDBPath();
527         while((anIdPtr = dynamic_cast<AliCDBId*> (iter->Next()))){
528                 AliCDBPath thisCDBPath = anIdPtr->GetAliCDBPath();
529                 if(!(queryPath.Comprises(thisCDBPath)) || pathCopy.GetPath() == thisCDBPath.GetPath()) continue;
530                 pathCopy = thisCDBPath;
531
532                 // check the selection criteria list for this query
533                 AliCDBId thisId(*anIdPtr);
534                 thisId.SetVersion(queryId.GetVersion());
535                 if(!thisId.HasVersion()) GetSelection(&thisId);
536
537                 if(alreadyLoaded){
538                         dataId = GetId(fValidFileIds, thisId);
539                 } else {
540                         dataId = GetId(validFileIds, thisId);
541                 }
542                 if(dataId) selectedIds.Add(dataId);
543         }
544
545         delete iter; iter=0;
546
547         // selectedIds contains the Ids of the files matching all requests of query!
548         // All the objects are now ready to be retrieved
549         iter = new TIter(&selectedIds);
550         while((anIdPtr = dynamic_cast<AliCDBId*> (iter->Next()))){
551                 TString filename;
552                 if (!IdToFilename(*anIdPtr, filename)) {
553                         AliDebug(2,Form("Bad data ID encountered! Subnormal error!"));
554                         continue;
555                 }
556
557                 AliCDBEntry* anEntry = GetEntryFromFile(filename, anIdPtr);
558
559                 if(anEntry) result->Add(anEntry);
560
561         }
562         delete iter; iter=0;
563
564         return result;
565 }
566
567 //_____________________________________________________________________________
568 Bool_t AliCDBGrid::PutEntry(AliCDBEntry* entry) {
569 // put an AliCDBEntry object into the database
570
571         AliCDBId& id = entry->GetId();
572
573         // set version for the entry to be stored
574         if (!PrepareId(id)) return kFALSE;
575
576         // build filename from entry's id
577         TString filename;
578         if (!IdToFilename(id, filename)) {
579                 AliError("Bad ID encountered! Subnormal error!");
580                 return kFALSE;
581         }
582
583         TString folderToTag = Form("%s%s",
584                                         fDBFolder.Data(),
585                                         id.GetPath().Data());
586
587         TDirectory* saveDir = gDirectory;
588
589         TString fullFilename = Form("/alien%s", filename.Data());
590         // specify SE to filename
591         if (fSE != "default") fullFilename += Form("?se=%s",fSE.Data());
592
593         // open file
594         TFile *file = TFile::Open(fullFilename,"CREATE");
595         if(!file || !file->IsWritable()){
596                 AliError(Form("Can't open file <%s>!", filename.Data()));
597                 if(file && !file->IsWritable()) file->Close(); delete file; file=0;
598                 return kFALSE;
599         }
600
601         file->cd();
602
603         //SetTreeToFile(entry, file);
604
605         entry->SetVersion(id.GetVersion());
606
607         // write object (key name: "AliCDBEntry")
608         Bool_t result = (file->WriteTObject(entry, "AliCDBEntry") != 0);
609         if (!result) AliError(Form("Can't write entry to file <%s>!", filename.Data()));
610
611
612         if (saveDir) saveDir->cd(); else gROOT->cd();
613         file->Close(); delete file; file=0;
614
615         if(result) {
616                 AliInfo(Form("CDB object stored into file %s", filename.Data()));
617                 AliInfo(Form("using S.E.: %s", fSE.Data()));
618
619                 if(!TagFileId(filename, &id)){
620                         AliInfo(Form("CDB tagging failed. Deleting file %s!",filename.Data()));
621                         if(!gGrid->Rm(filename.Data()))
622                                 AliError("Can't delete file!");
623                         return kFALSE;
624                 }
625
626                 TagFileMetaData(filename, entry->GetMetaData());
627         }
628
629         return result;
630 }
631 //_____________________________________________________________________________
632 Bool_t AliCDBGrid::AddTag(TString& folderToTag, const char* tagname){
633 // add "tagname" tag (CDB or CDB_MD) to folder where object will be stored
634
635         Bool_t result = kTRUE;
636         AliDebug(2, Form("adding %s tag to folder %s", tagname, folderToTag.Data()));
637         TString addTag = Form("addTag %s %s", folderToTag.Data(), tagname);
638         TGridResult *gridres = gGrid->Command(addTag.Data());
639         const char* resCode = gridres->GetKey(0,"__result__"); // '1' if success
640         if(resCode[0] != '1') {
641                 AliError(Form("Couldn't add %s tags to folder %s !",
642                                                 tagname, folderToTag.Data()));
643                 result = kFALSE;
644         }
645         delete gridres;
646         return result;
647 }
648
649 //_____________________________________________________________________________
650 Bool_t AliCDBGrid::TagFileId(TString& filename, const AliCDBId* id){
651 // tag stored object in CDB table using object Id's parameters
652
653         TString addTagValue1 = Form("addTagValue %s CDB ", filename.Data());
654         TString addTagValue2 = Form("first_run=%d last_run=%d version=%d ",
655                                         id->GetFirstRun(),
656                                         id->GetLastRun(),
657                                         id->GetVersion());
658         TString addTagValue3 = Form("path_level_0=\"%s\" path_level_1=\"%s\" path_level_2=\"%s\"",
659                                         id->GetPathLevel(0).Data(),
660                                         id->GetPathLevel(1).Data(),
661                                         id->GetPathLevel(2).Data());
662         TString addTagValue = Form("%s%s%s",
663                                         addTagValue1.Data(),
664                                         addTagValue2.Data(),
665                                         addTagValue3.Data());
666
667         Bool_t result = kFALSE;
668         AliDebug(2, Form("Tagging file. Tag command: %s", addTagValue.Data()));
669         TGridResult* res = gGrid->Command(addTagValue.Data());
670         const char* resCode = res->GetKey(0,"__result__"); // '1' if success
671         if(resCode[0] != '1') {
672                 AliError(Form("Couldn't add CDB tag value to file %s !",
673                                                 filename.Data()));
674                 result = kFALSE;
675         } else {
676                 AliInfo("Object successfully tagged.");
677                 result = kTRUE;
678         }
679         delete res;
680         return result;
681
682 }
683
684 //_____________________________________________________________________________
685 Bool_t AliCDBGrid::TagShortLived(TString& filename, Bool_t value){
686 // tag folder with ShortLived tag
687
688         TString addTagValue = Form("addTagValue %s ShortLived_try value=%d", filename.Data(), value);
689
690         Bool_t result = kFALSE;
691         AliDebug(2, Form("Tagging file. Tag command: %s", addTagValue.Data()));
692         TGridResult* res = gGrid->Command(addTagValue.Data());
693         const char* resCode = res->GetKey(0,"__result__"); // '1' if success
694         if(resCode[0] != '1') {
695                 AliError(Form("Couldn't add ShortLived tag value to file %s !", filename.Data()));
696                 result = kFALSE;
697         } else {
698                 AliInfo("Object successfully tagged.");
699                 result = kTRUE;
700         }
701         delete res;
702         return result;
703
704 }
705
706 //_____________________________________________________________________________
707 Bool_t AliCDBGrid::TagFileMetaData(TString& filename, const AliCDBMetaData* md){
708 // tag stored object in CDB table using object Id's parameters
709
710         TString addTagValue1 = Form("addTagValue %s CDB_MD ", filename.Data());
711         TString addTagValue2 = Form("object_classname=\"%s\" responsible=\"%s\" beam_period=%d ",
712                                         md->GetObjectClassName(),
713                                         md->GetResponsible(),
714                                         md->GetBeamPeriod());
715         TString addTagValue3 = Form("aliroot_version=\"%s\" comment=\"%s\"",
716                                         md->GetAliRootVersion(),
717                                         md->GetComment());
718         TString addTagValue = Form("%s%s%s",
719                                         addTagValue1.Data(),
720                                         addTagValue2.Data(),
721                                         addTagValue3.Data());
722
723         Bool_t result = kFALSE;
724         AliDebug(2, Form("Tagging file. Tag command: %s", addTagValue.Data()));
725         TGridResult* res = gGrid->Command(addTagValue.Data());
726         const char* resCode = res->GetKey(0,"__result__"); // '1' if success
727         if(resCode[0] != '1') {
728                 AliWarning(Form("Couldn't add CDB_MD tag value to file %s !",
729                                                 filename.Data()));
730                 result = kFALSE;
731         } else {
732                 AliInfo("Object successfully tagged.");
733                 result = kTRUE;
734         }
735         return result;
736 }
737
738 //_____________________________________________________________________________
739 TList* AliCDBGrid::GetIdListFromFile(const char* fileName){
740
741         TString turl(fileName);
742         turl.Prepend("/alien" + fDBFolder);
743         turl += "?se="; turl += fSE.Data();
744         TFile *file = TFile::Open(turl);
745         if (!file) {
746                 AliError(Form("Can't open selection file <%s>!", turl.Data()));
747                 return NULL;
748         }
749
750         TList *list = new TList();
751         list->SetOwner();
752         int i=0;
753         TString keycycle;
754
755         AliCDBId *id;
756         while(1){
757                 i++;
758                 keycycle = "AliCDBId;";
759                 keycycle+=i;
760                 
761                 id = (AliCDBId*) file->Get(keycycle);
762                 if(!id) break;
763                 list->AddFirst(id);
764         }
765         file->Close(); delete file; file=0;
766         
767         return list;
768
769
770 }
771
772 //_____________________________________________________________________________
773 Bool_t AliCDBGrid::Contains(const char* path) const{
774 // check for path in storage's DBFolder
775
776         TString initDir(gGrid->Pwd(0));
777         TString dirName(fDBFolder);
778         dirName += path; // dirName = fDBFolder/path
779         Bool_t result=kFALSE;
780         if (gGrid->Cd(dirName,0)) result=kTRUE;
781         gGrid->Cd(initDir.Data(),0);
782         return result;
783 }
784
785 //_____________________________________________________________________________
786 void AliCDBGrid::QueryValidFiles()
787 {
788 // Query the CDB for files valid for AliCDBStorage::fRun
789 // fills list fValidFileIds with AliCDBId objects created from file name
790
791         TString filter;
792         MakeQueryFilter(fRun, fRun, fMetaDataFilter, filter);
793
794         TString pattern = Form("%s/Run*", fPathFilter.GetPath().Data());
795         if(fVersion >= 0) pattern += Form("_v%d*", fVersion);
796         pattern += ".root";
797         AliDebug(2,Form("pattern: %s", pattern.Data()));
798
799         TGridResult *res = gGrid->Query(fDBFolder, pattern, filter, "");
800
801         AliCDBId validFileId;
802         for(int i=0; i<res->GetEntries(); i++){
803                 TString filename = res->GetKey(i, "lfn");
804                 if(filename == "") continue;
805                 AliDebug(2,Form("Found valid file: %s", filename.Data()));
806                 Bool_t result = FilenameToId(filename, validFileId);
807                 if(result) {
808                         fValidFileIds.AddLast(validFileId.Clone());
809                 }
810         }
811         delete res;
812
813 }
814
815 //_____________________________________________________________________________
816 void AliCDBGrid::MakeQueryFilter(Int_t firstRun, Int_t lastRun,
817                                         const AliCDBMetaData* md, TString& result) const
818 {
819 // create filter for file query
820
821         result = Form("CDB:first_run<=%d and CDB:last_run>=%d", firstRun, lastRun);
822
823 //      if(version >= 0) {
824 //              result += Form(" and CDB:version=%d", version);
825 //      }
826 //      if(pathFilter.GetLevel0() != "*") {
827 //              result += Form(" and CDB:path_level_0=\"%s\"", pathFilter.GetLevel0().Data());
828 //      }
829 //      if(pathFilter.GetLevel1() != "*") {
830 //              result += Form(" and CDB:path_level_1=\"%s\"", pathFilter.GetLevel1().Data());
831 //      }
832 //      if(pathFilter.GetLevel2() != "*") {
833 //              result += Form(" and CDB:path_level_2=\"%s\"", pathFilter.GetLevel2().Data());
834 //      }
835
836         if(md){
837                 if(md->GetObjectClassName()[0] != '\0') {
838                         result += Form(" and CDB_MD:object_classname=\"%s\"", md->GetObjectClassName());
839                 }
840                 if(md->GetResponsible()[0] != '\0') {
841                         result += Form(" and CDB_MD:responsible=\"%s\"", md->GetResponsible());
842                 }
843                 if(md->GetBeamPeriod() != 0) {
844                         result += Form(" and CDB_MD:beam_period=%d", md->GetBeamPeriod());
845                 }
846                 if(md->GetAliRootVersion()[0] != '\0') {
847                         result += Form(" and CDB_MD:aliroot_version=\"%s\"", md->GetAliRootVersion());
848                 }
849                 if(md->GetComment()[0] != '\0') {
850                         result += Form(" and CDB_MD:comment=\"%s\"", md->GetComment());
851                 }
852         }
853         AliDebug(2, Form("filter: %s",result.Data()));
854
855 }
856
857 //_____________________________________________________________________________
858 Int_t AliCDBGrid::GetLatestVersion(const char* path, Int_t run){
859 // get last version found in the database valid for run and path
860
861         AliCDBPath aCDBPath(path);
862         if(!aCDBPath.IsValid() || aCDBPath.IsWildcard()) {
863                 AliError(Form("Invalid path in request: %s", path));
864                 return -1;
865         }
866         AliCDBId query(path, run, run, -1, -1);
867         AliCDBId* dataId = 0;
868
869         // look for file matching query requests (path, runRange, version)
870         if(run == fRun && fPathFilter.Comprises(aCDBPath) && fVersion < 0){
871                 // look into list of valid files previously loaded with AliCDBStorage::FillValidFileIds()
872                 AliDebug(2, Form("List of files valid for run %d and for path %s was loaded. Looking there!",
873                                         run, path));
874                 dataId = GetId(fValidFileIds, query);
875                 if (!dataId) return -1;
876                 Int_t version = dataId->GetVersion();
877                 delete dataId;
878                 return version;
879
880         }
881         // List of files valid for reqested run was not loaded. Looking directly into CDB
882         AliDebug(2, Form("List of files valid for run %d and for path %s was not loaded. Looking directly into CDB!",
883                                 run, path));
884
885         TObjArray validFileIds;
886         validFileIds.SetOwner(1);
887
888         TString filter;
889         MakeQueryFilter(run, run, 0, filter);
890
891         TString pattern = Form("%s/Run*.root", path);
892         AliDebug(2,Form("pattern: %s", pattern.Data()));
893
894         TGridResult *res = gGrid->Query(fDBFolder, pattern, filter, "");
895         AliCDBId validFileId;
896         for(int i=0; i<res->GetEntries(); i++){
897                 TString filename = res->GetKey(i, "lfn");
898                 if(filename == "") continue;
899                 if(FilenameToId(filename, validFileId))
900                                 validFileIds.AddLast(validFileId.Clone());
901         }
902         delete res;
903
904         dataId = GetId(validFileIds, query);
905         if (!dataId) return -1;
906
907         Int_t version = dataId->GetVersion();
908         delete dataId;
909         return version;
910
911 }
912
913 //_____________________________________________________________________________
914 Int_t AliCDBGrid::GetLatestSubVersion(const char* /*path*/, Int_t /*run*/, Int_t /*version*/){
915 // get last subversion found in the database valid for run and path
916         AliError("Objects in GRID storage have no sub version!");
917         return -1;
918 }
919
920
921 /////////////////////////////////////////////////////////////////////////////////////////////////
922 //                                                                                             //
923 // AliCDBGrid factory                                                                          //
924 //                                                                                             //
925 /////////////////////////////////////////////////////////////////////////////////////////////////
926
927 ClassImp(AliCDBGridFactory)
928
929 //_____________________________________________________________________________
930 Bool_t AliCDBGridFactory::Validate(const char* gridString) {
931 // check if the string is valid Grid URI
932
933         // pattern: alien://hostName:Port;user;dbPath;SE
934         // example of a valid pattern:
935         // "alien://aliendb4.cern.ch:9000;colla;DBTest;ALICE::CERN::Server"
936 //        TRegexp gridPattern("^alien://.+:[0-9]+;[a-zA-Z0-9_-.]+;.+;.+$");
937         TRegexp gridPattern("^alien://.+$");
938
939         return TString(gridString).Contains(gridPattern);
940 }
941
942 //_____________________________________________________________________________
943 AliCDBParam* AliCDBGridFactory::CreateParameter(const char* gridString) {
944 // create AliCDBGridParam class from the URI string
945
946         if (!Validate(gridString)) {
947                 return NULL;
948         }
949         //TString buffer(gridString + sizeof("alien://") - 1);
950         TString buffer(gridString);
951
952         TString gridUrl         = "alien://";
953         TString user            = "";
954         TString dbFolder        = "";
955         TString se              = "default";
956
957         TObjArray *arr = buffer.Tokenize('?');
958         TIter iter(arr);
959         TObjString *str = 0;
960
961         while((str = (TObjString*) iter.Next())){
962                 TString entry(str->String());
963                 Int_t indeq = entry.Index('=');
964                 if(indeq == -1) {
965                         if(entry.BeginsWith("alien://")) { // maybe it's a gridUrl!
966                                 gridUrl = entry;
967                                 continue;
968                         } else {
969                                 AliError(Form("Invalid entry! %s",entry.Data()));
970                                 continue;
971                         }
972                 }
973                 
974                 TString key = entry(0,indeq);
975                 TString value = entry(indeq+1,entry.Length()-indeq);
976
977                 if(key.Contains("grid",TString::kIgnoreCase)) {
978                         gridUrl += value;
979                 } 
980                 else if (key.Contains("user",TString::kIgnoreCase)){
981                         user = value;
982                 }
983                 else if (key.Contains("folder",TString::kIgnoreCase)){
984                         dbFolder = value;
985                 }
986                 else if (key.Contains("se",TString::kIgnoreCase)){
987                         se = value;
988                 }
989                 else{
990                         AliError(Form("Invalid entry! %s",entry.Data()));
991                 }
992         }
993         delete arr; arr=0;
994                 
995         AliDebug(2, Form("gridUrl:      %s",gridUrl.Data()));
996         AliDebug(2, Form("user: %s",user.Data()));
997         AliDebug(2, Form("dbFolder:     %s",dbFolder.Data()));
998         AliDebug(2, Form("s.e.: %s",se.Data()));
999
1000         if(dbFolder == ""){
1001                 AliError("DBFolder must be specified!");
1002                 return NULL;
1003         }
1004
1005         return new AliCDBGridParam(gridUrl.Data(), user.Data(), dbFolder.Data(), se.Data());
1006 }
1007
1008 //_____________________________________________________________________________
1009 AliCDBStorage* AliCDBGridFactory::Create(const AliCDBParam* param) {
1010 // create AliCDBGrid storage instance from parameters
1011         
1012         AliCDBGrid *grid = 0;
1013         if (AliCDBGridParam::Class() == param->IsA()) {
1014
1015                 const AliCDBGridParam* gridParam = (const AliCDBGridParam*) param;
1016                 grid = new AliCDBGrid(gridParam->GridUrl().Data(),
1017                                       gridParam->GetUser().Data(),
1018                                       gridParam->GetDBFolder().Data(),
1019                                       gridParam->GetSE().Data());
1020
1021         }
1022
1023         if(!gGrid && grid) {
1024                 delete grid; grid=0;
1025         }
1026
1027         return grid;
1028 }
1029
1030 /////////////////////////////////////////////////////////////////////////////////////////////////
1031 //                                                                                             //
1032 // AliCDBGrid Parameter class                                                                  //                                          //
1033 //                                                                                             //
1034 /////////////////////////////////////////////////////////////////////////////////////////////////
1035
1036 ClassImp(AliCDBGridParam)
1037
1038 //_____________________________________________________________________________
1039 AliCDBGridParam::AliCDBGridParam():
1040  AliCDBParam(),
1041  fGridUrl(),
1042  fUser(),
1043  fDBFolder(),
1044  fSE()
1045  {
1046 // default constructor
1047
1048 }
1049
1050 //_____________________________________________________________________________
1051 AliCDBGridParam::AliCDBGridParam(const char* gridUrl, 
1052                                 const char* user,
1053                                 const char* dbFolder, 
1054                                 const char* se):
1055  AliCDBParam(),
1056  fGridUrl(gridUrl),
1057  fUser(user),
1058  fDBFolder(dbFolder),
1059  fSE(se)
1060 {
1061 // constructor
1062         
1063         SetType("alien");
1064
1065         TString uri = Form("%s?User=%s?DBFolder=%s?SE=%s",
1066                         fGridUrl.Data(), fUser.Data(),
1067                         fDBFolder.Data(), fSE.Data());
1068
1069         SetURI(uri.Data());
1070 }
1071
1072 //_____________________________________________________________________________
1073 AliCDBGridParam::~AliCDBGridParam() {
1074 // destructor
1075
1076 }
1077
1078 //_____________________________________________________________________________
1079 AliCDBParam* AliCDBGridParam::CloneParam() const {
1080 // clone parameter
1081
1082         return new AliCDBGridParam(fGridUrl.Data(), fUser.Data(),
1083                                         fDBFolder.Data(), fSE.Data());
1084 }
1085
1086 //_____________________________________________________________________________
1087 ULong_t AliCDBGridParam::Hash() const {
1088 // return Hash function
1089
1090         return fGridUrl.Hash()+fUser.Hash()+fDBFolder.Hash()+fSE.Hash();
1091 }
1092
1093 //_____________________________________________________________________________
1094 Bool_t AliCDBGridParam::IsEqual(const TObject* obj) const {
1095 // check if this object is equal to AliCDBParam obj
1096
1097         if (this == obj) {
1098                 return kTRUE;
1099         }
1100
1101         if (AliCDBGridParam::Class() != obj->IsA()) {
1102                 return kFALSE;
1103         }
1104
1105         AliCDBGridParam* other = (AliCDBGridParam*) obj;
1106
1107         if(fGridUrl != other->fGridUrl) return kFALSE;
1108         if(fUser != other->fUser) return kFALSE;
1109         if(fDBFolder != other->fDBFolder) return kFALSE;
1110         if(fSE != other->fSE) return kFALSE;
1111         return kTRUE;
1112 }
1113