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