84235ea138fb2e32bd2e976838c05a0c06149070
[u/mrichter/AliRoot.git] / STEER / AliRunDataFile.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 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////////////
19 //                                                                           //
20 // access classes for a data base in a (local) file                          //
21 //                                                                           //
22 ///////////////////////////////////////////////////////////////////////////////
23
24
25 #include <TFile.h>
26 #include <TKey.h>
27 #include <TROOT.h>
28 #include "AliLog.h"
29 #include "AliRunData.h"
30 #include "AliRunDataFile.h"
31
32
33 ClassImp(AliRunDataFile)
34
35
36 //_____________________________________________________________________________
37 AliRunDataFile::AliRunDataFile(const char* fileName, Bool_t readOnly) :
38   AliRunDataStorage(),
39   fFile(NULL)
40 {
41 // constructor
42
43   if (!fileName) {
44     AliError("no file name given");
45     return;
46   }
47   TDirectory* saveDir = gDirectory;
48   fFile = TFile::Open(fileName, ((readOnly) ? "READ" : "UPDATE"));
49   if (saveDir) saveDir->cd(); else gROOT->cd();
50   if (!fFile || !fFile->IsOpen()) {
51     AliError(Form("could not open file %s", fileName));
52     fFile = NULL;
53   }
54 }
55
56 //_____________________________________________________________________________
57 AliRunDataFile::~AliRunDataFile()
58 {
59 // destructor
60
61   if (fFile) {
62     fFile->Close();
63     delete fFile;
64   }
65 }
66
67 //_____________________________________________________________________________
68 AliRunDataFile::AliRunDataFile(const AliRunDataFile& /*db*/) :
69   AliRunDataStorage(),
70   fFile(NULL)
71 {
72 // copy constructor
73
74   AliFatal("not implemented");
75 }
76
77 //_____________________________________________________________________________
78 AliRunDataFile& AliRunDataFile::operator = (const AliRunDataFile& /*db*/)
79 {
80 // assignment operator
81
82   AliFatal("not implemented");
83   return *this;
84 }
85
86
87 //_____________________________________________________________________________
88 AliRunData* AliRunDataFile::GetEntry(AliMetaData& metaData, Int_t runNumber)
89 {
90 // get an object from the data base
91
92   // go to the directory
93   TDirectory* saveDir = gDirectory;
94   TString name(metaData.GetName());
95   Int_t last = name.Last('/');
96   if (last < 0) {
97     fFile->cd();
98   } else {
99     TString dirName(name(0, last));
100     if (!fFile->cd(dirName)) {
101       AliDebug(1, Form("no directory %s found", dirName.Data()));
102       if (saveDir) saveDir->cd(); else gROOT->cd();
103       return NULL;
104     }
105     name.Remove(0, last+1);
106   }
107
108   TKey* key = fFile->GetKey(name);
109   if (!key) {
110     AliDebug(1, Form("no object with name %s found", metaData.GetName()));
111     if (saveDir) saveDir->cd(); else gROOT->cd();
112     return NULL;
113   }
114   Int_t nCycles = key->GetCycle();
115
116   // find the closest entry
117   AliRunData* closestEntry = NULL;
118   for (Int_t iCycle = nCycles; iCycle > 0; iCycle--) {
119     key = fFile->GetKey(name, iCycle);
120     if (!key) continue;
121     AliRunData* entry = (AliRunData*) key->ReadObj();
122     if (!entry) continue;
123     if (!entry->InheritsFrom(AliRunData::Class())) {
124       AliMetaData metaData;
125       entry = new AliRunData(entry, metaData);
126     }
127     if (!entry->GetMetaData().IsValid(runNumber, &metaData) ||
128         (entry->Compare(closestEntry) <= 0)) {
129       delete entry;
130       continue;
131     }
132     delete closestEntry;
133     closestEntry = entry;
134   }
135   if (saveDir) saveDir->cd(); else gROOT->cd();
136   if (!closestEntry) return NULL;
137   return closestEntry;
138 }
139
140 //_____________________________________________________________________________
141 Bool_t AliRunDataFile::PutEntry(AliRunData* entry)
142 {
143 // put an object into the data base
144
145   if (!entry || !fFile) return kFALSE;
146   if (!fFile->IsWritable()) {
147     AliError(Form("The data base file was opened in read only mode. "
148                   "The object %s was not inserted", entry->GetName()));
149     return kFALSE;
150   }
151   TDirectory* saveDir = gDirectory;
152
153   // go to or create the directory
154   TString name(entry->GetName());
155   while (name.BeginsWith("/")) name.Remove(0);
156   TDirectory* dir = fFile;
157   Int_t index = -1;
158   while ((index = name.Index("/")) >= 0) {
159     TString dirName(name(0, index));
160     if ((index > 0) && !dir->Get(dirName)) dir->mkdir(dirName);
161     dir->cd(dirName);
162     dir = gDirectory;
163     name.Remove(0, index+1);
164   } 
165
166   // determine the version number
167   Int_t version = 0;
168   TKey* key = fFile->GetKey(name);
169   if (key) {
170     Int_t nCycles = key->GetCycle();
171     for (Int_t iCycle = nCycles; iCycle > 0; iCycle--) {
172       key = fFile->GetKey(entry->GetName(), iCycle);
173       if (!key) continue;
174       AliRunData* oldEntry = (AliRunData*) key->ReadObj();
175       if (!oldEntry) continue;
176       if (oldEntry->InheritsFrom(AliRunData::Class())) {
177         if (version <= oldEntry->GetMetaData().GetVersion()) {
178           version = oldEntry->GetMetaData().GetVersion()+1;
179         }
180       }
181       delete oldEntry;
182     }
183   }
184   entry->SetVersion(version);
185
186   Bool_t result = (entry->Write(name) != 0);
187   if (saveDir) saveDir->cd(); else gROOT->cd();
188   return result;
189 }