c6a339fdef783ec706bdfd0bc0af63906f4cb8ce
[u/mrichter/AliRoot.git] / STORAGE / AliStorageDatabase.cxx
1 #include "AliStorageDatabase.h"
2
3 #include <iostream>
4 #include <fstream>
5
6 #include <TSQLRow.h>
7 #include <TSQLResult.h>
8 #include <TThread.h>
9 #include <TSystem.h>
10 #include <TFile.h>
11
12 using namespace std;
13
14 AliStorageDatabase::AliStorageDatabase() :
15         fHost(""),
16         fPort(""),
17         fDatabase(""),
18         fUID(""),
19         fPassword(""),
20         fTable(""),
21         fServer(0),
22         fStoragePath("")
23 {
24         TThread::Lock();        
25         ifstream configFile (Form("%s/STORAGE/setupStorageDatabase.sh",
26                                   gSystem->Getenv("ALICE_ROOT")));
27
28         
29         if (configFile.is_open())
30         {
31                 string line;
32                 int from,to;
33                 while(configFile.good())
34                 {
35                         getline(configFile,line);
36                         from = line.find("\"")+1;
37                         to = line.find_last_of("\"");
38                         if(line.find("HOST=")==0)
39                         {
40                                 fHost=line.substr(from,to-from);
41                         }
42                         else if(line.find("PORT=")==0)
43                         {
44                                 fPort=line.substr(from,to-from);
45                         }
46                         else if(line.find("DATABASE=")==0)
47                         {
48                                 fDatabase=line.substr(from,to-from);
49                         }
50                         else if(line.find("USER=")==0)
51                         {
52                                 fUID=line.substr(from,to-from);
53                         }
54                         else if(line.find("PASS=")==0)
55                         {
56                                 fPassword=line.substr(from,to-from);
57                         }
58                         else if(line.find("TABLE=")==0)
59                         {
60                                 fTable=line.substr(from,to-from);
61                         }
62                         else if(line.find("STORAGE_PATH=")==0)
63                         {
64                                 fStoragePath=line.substr(from,to-from);
65                         }
66
67                 }
68                 if(configFile.eof())
69                 {
70                         configFile.clear();
71                 }
72                 configFile.close();
73         }
74         else
75         {
76                 cout << "DATABASE -- Unable to open file" <<endl;
77         }
78         TThread::UnLock();
79
80         
81         fServer = TSQLServer::Connect(Form("mysql://%s:%s/%s",fHost.c_str(),fPort.c_str(),fDatabase.c_str()),fUID.c_str(),fPassword.c_str());
82 }
83
84 AliStorageDatabase::~AliStorageDatabase(){}
85
86 void AliStorageDatabase::InsertEvent(int runNumber,
87                                      int eventNumber,
88                                      char *system,
89                                      int multiplicity,
90                                      char *filePath)
91 {
92         fServer->Query(Form("replace into %s (run_number,event_number,system,multiplicity,permanent,file_path) values (%d,%d,'%s',%d,0,'%s');",fTable.c_str(),runNumber,eventNumber,system,multiplicity,filePath));
93
94 }
95
96 bool AliStorageDatabase::MarkEvent(struct eventStruct event)
97 {
98         if(fServer->Query(Form("UPDATE %s SET permanent = 1 WHERE run_number = %d AND event_number = %d;",fTable.c_str(),event.runNumber,event.eventNumber)))
99         {
100                 return 1;
101         }
102         else
103         {
104                 return 0;
105         }
106 }
107
108 vector<serverListStruct> AliStorageDatabase::GetList(struct listRequestStruct list)
109 {
110         TSQLResult *result = fServer->Query(Form("SELECT * FROM %s WHERE run_number >= %d AND run_number <= %d AND event_number >= %d AND event_number <= %d AND multiplicity >= %d AND multiplicity <= %d AND (permanent = %d OR permanent = %d) AND (system = '%s' OR system = '%s') ORDER BY run_number,event_number;",
111                                                  fTable.c_str(),
112                                                  list.runNumber[0],
113                                                  list.runNumber[1],
114                                                  list.eventNumber[0],
115                                                  list.eventNumber[1],
116                                                  list.multiplicity[0],
117                                                  list.multiplicity[1],
118                                                  list.marked[0],
119                                                  list.marked[1],
120                                                  list.system[0],
121                                                  list.system[1]));
122
123         
124         TSQLRow *row;
125         vector<serverListStruct> eventsVector;
126         
127         while((row = result->Next()))
128         {
129                 serverListStruct resultList;
130
131                 resultList.runNumber = atoi(row->GetField(0));
132                 resultList.eventNumber = atoi(row->GetField(1));
133                 strcpy(resultList.system, row->GetField(2));
134                 resultList.multiplicity = atoi(row->GetField(3));
135                 resultList.marked = atoi(row->GetField(4));
136
137                 eventsVector.push_back(resultList);
138                 delete row;
139         }
140         
141         return eventsVector;
142 }
143
144 AliESDEvent* AliStorageDatabase::GetEvent(struct eventStruct event)
145 {
146         cout<<"database - get event"<<endl;
147         string pathToFile = GetFilePath(event);
148
149         if(!strcmp(pathToFile.c_str(),""))
150         {
151                 cout<<"DATABASE -- no such file in database"<<endl;
152                 return NULL;
153         }
154         
155         TFile *tmpFile = new TFile(pathToFile.c_str(),"read");
156         if(!tmpFile)
157         {
158                 cout<<"DATABASE -- couldn't open temp file"<<endl;
159                 return NULL;
160         }
161         AliESDEvent *data;
162         tmpFile->GetObject(Form("event%d;1",event.eventNumber),data);
163
164         return data;
165         /*
166         //deserialize file??
167         TTree* tree= new TTree("esdTree", "esdTree");
168         data->WriteToTree(tree);
169         tree-> Fill();
170         AliESDEvent* requestedEvent= new AliESDEvent(); 
171         requestedEvent->ReadFromTree(tree);
172         tree->GetEntry(0);
173         delete data;
174         delete tree;
175         
176         
177         if(requestedEvent->GetRunNumber()<0)//if file is not in temp storage, check if it is in perm storage
178         {
179                 cout<<"DATABASE -- could not find file in temp storage -- searching in perm"<<endl;
180                 TFile *permFile = new TFile(Form("%s/permEvents.root",fStoragePath.c_str()),"update");//open/create perm file
181         
182                 if(!permFile)
183                 {
184                         cout<<"DATABASE -- Couldn't open perm file"<<endl;
185                         tmpFile->Close();
186                         if(tmpFile){delete tmpFile;}
187                         if(requestedEvent){delete requestedEvent;}
188                         return NULL;
189                 }
190                 TDirectory *runDirectory = permFile->GetDirectory(Form("run%d",event.runNumber));
191
192                 if(!runDirectory)
193                 {
194                         cout<<"DATABASE -- Couldn't open run directory"<<endl;
195                         
196                         if(tmpFile)
197                         {
198                                 tmpFile->Close();
199                                 delete tmpFile;
200                         }
201                         if(permFile)
202                         {
203                                 permFile->Close();
204                                 delete permFile;
205                         }
206                         if(requestedEvent){delete requestedEvent;}
207                         return NULL;
208                 }
209                 
210                 //if(requestedEvent){delete requestedEvent;}
211                 AliESDEvent *requestedEventPerm = (AliESDEvent*)runDirectory->Get(Form("event%d",event.eventNumber));
212
213                 if(requestedEventPerm->GetRunNumber()<0)
214                 {
215                         cout<<"DATABASE -- could not find event in perm storage"<<endl;
216                         tmpFile->Close();
217                         permFile->Close();
218                         if(tmpFile){delete tmpFile;}
219                         if(permFile){delete permFile;}
220                         return NULL;
221                 }
222                 else
223                 {
224                         return requestedEventPerm;
225                 }
226         }
227         else
228         {
229                 cout<<"DATABASE -- sending event:"<<requestedEvent->GetRunNumber()<<endl;
230                 tmpFile->Close();
231                 if(tmpFile){delete tmpFile;}
232                 return requestedEvent;
233                 }*/
234 }
235
236 struct eventStruct AliStorageDatabase::GetOldestEvent()
237 {
238         struct eventStruct oldestEvent = {0,0};
239
240         TSQLResult *result = fServer->Query(Form("SELECT * FROM %s ORDER BY run_number,event_number;",fTable.c_str()));
241
242         TSQLRow *row;   
243         if((row = result->Next()))
244         {
245                 oldestEvent.runNumber = atoi(row->GetField(0));
246                 oldestEvent.eventNumber = atoi(row->GetField(1));
247         
248                 delete row;
249         }
250         else
251         {
252                 cout<<"DATABASE -- NO OLDEST EVENT FOUND. Storage may be corrupted."<<endl;
253         }
254         return oldestEvent;
255 }
256
257 void AliStorageDatabase::RemoveEvent(struct eventStruct event)
258 {
259         fServer->Query(Form("DELETE FROM %s WHERE run_number = %d AND event_number = %d",fTable.c_str(),event.runNumber,event.eventNumber));
260 }
261
262 string AliStorageDatabase::GetFilePath(struct eventStruct event)
263 {
264         TSQLResult *result = fServer->Query(Form("SELECT * FROM %s WHERE run_number = %d AND event_number = %d;",fTable.c_str(),event.runNumber,event.eventNumber));
265         TSQLRow *row;
266         row = result->Next();
267         if(row)
268         {
269                 string path(row->GetField(5));
270                 delete row;
271                 return path;
272         }
273         else
274         {
275                 return "";
276         }
277 }
278
279 AliESDEvent* AliStorageDatabase::GetNextEvent(struct eventStruct event)
280 {
281         TSQLResult *result = fServer->Query(Form("SELECT * FROM %s ORDER BY run_number,event_number;",fTable.c_str()));
282
283         TSQLRow *row;
284         bool isCurrentEvent=false;
285         struct eventStruct nextEvent;
286         
287         while((row = result->Next()))
288         {
289                 if(isCurrentEvent)
290                 {
291                         nextEvent.runNumber = atoi(row->GetField(0));
292                         nextEvent.eventNumber = atoi(row->GetField(1));
293                         return GetEvent(nextEvent);
294                 }
295
296                 //if current event found
297                 if(atoi(row->GetField(0))==event.runNumber && atoi(row->GetField(1))==event.eventNumber)
298                 {
299                         isCurrentEvent=true;
300                 }
301                 
302                 delete row;
303         }
304
305         return NULL;
306 }
307
308 AliESDEvent* AliStorageDatabase::GetLastEvent()
309 {
310         TSQLResult *result = fServer->Query(Form("SELECT * FROM %s ORDER BY run_number,event_number;",fTable.c_str()));
311
312         TSQLRow *row;
313         struct eventStruct lastEvent = {0,0};
314
315         while((row = result->Next()))
316         {
317                 lastEvent.runNumber = atoi(row->GetField(0));
318                 lastEvent.eventNumber = atoi(row->GetField(1));
319                 delete row;
320         }
321         cout<<"Last event is:"<<lastEvent.eventNumber<<endl;
322         return GetEvent(lastEvent);
323
324 }