BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
installLocalDB.C
Go to the documentation of this file.
1#if !defined(__CLING__) || defined(__MAKECLING__)
2#include "TString.h"
3#include "TSystem.h"
4
5#include <cstdio>
6#include <iostream>
7#include <stdio.h>
8#include <stdlib.h>
9using namespace std;
10#endif
11
12bool exists_file(const char* name)
13{
14 return (access(name, F_OK) != -1);
15}
16
17unsigned long int getServerRevision(const char* url)
18{
19 unsigned long int serverRev = 0;
20 gSystem->Exec(TString::Format("wget -O server_revision.txt \"%s/get_cur_timestamp.php\" > /dev/null 2>&1", url));
21 ifstream myFile_Handler;
22 string myLine;
23 myFile_Handler.open("server_revision.txt");
24 if (myFile_Handler.is_open()) {
25 char* ptr;
26 while (getline(myFile_Handler, myLine)) {
27 serverRev = strtoul(myLine.c_str(), &ptr, 10);
28 break;
29 }
30 myFile_Handler.close();
31 std::remove("server_revision.txt");
32 }
33 return serverRev;
34}
35
36unsigned long int getLocalRevision(TString& localDbPath)
37{
38 unsigned long int localRev = 0;
39 char type;
40 if (exists_file(localDbPath)) {
41 ostringstream stringStream;
42 stringStream << "sqlite://" << localDbPath;
43 TSQLiteServer db(stringStream.str().c_str());
44 stringStream.str("");
45 if (db.IsConnected()) {
46 stringStream << "select value_field from config where key_field='config_time';";
47 cout << stringStream.str().c_str() << std::endl;
48 TSQLResult* resQ = db.Query(stringStream.str().c_str());
49 if (resQ != 0) {
50 TSQLRow* row = resQ->Next();
51 if (row != NULL) {
52 const char* ch_time = row->GetField(0);
53 char* ptr;
54 if (ch_time != NULL)
55 localRev = strtoul(ch_time, &ptr, 10);
56 }
57 }
58 }
59 }
60 return localRev;
61}
62
63int installLocalDB(const char* tag = nullptr, const char* url = "https://bmn-geometry.jinr.int")
64{
65 // get DBL_FILE_PATH variable with local geometry database path
66 TString localDbPath = gSystem->ExpandPathName(getenv("DBL_FILE_PATH"));
67 if (localDbPath == "") {
68 cerr << "DBL_FILE_PATH is not set. Please, set DBL_FILE_PATH as a path to the local database" << endl;
69 return -1;
70 }
71
72 // if DBL_FILE_PATH is a directory, then add "/local.db" to the path
73 FileStat_t file_stat;
74 gSystem->GetPathInfo(localDbPath.Data(), file_stat);
75 if (R_ISDIR(file_stat.fMode))
76 localDbPath += "/local.db";
77
78 if (tag == nullptr) {
79 ostringstream stringStream;
80 unsigned long int localRev = 0, serverRev = 0;
81 char type;
82 if (exists_file(localDbPath)) {
83 localRev = getLocalRevision(localDbPath);
84 /* std::ostringstream stringStream;
85 stringStream<<"sqlite://"<<localDbPath;
86 TSQLiteServer db(stringStream.str().c_str());
87 stringStream.str("");
88 unsigned long int localRev = 0,serverRev=0;
89 if(db.IsConnected()){
90 stringStream<<"select value_field from config where key_field='config_time';";
91 cout<<stringStream.str().c_str()<<std::endl;
92 TSQLResult* resQ = db.Query(stringStream.str().c_str());
93 if (resQ != 0)
94 {
95 TSQLRow* row = resQ->Next();
96 if (row != NULL){
97 const char* ch_time = row->GetField(0);
98 char *ptr;
99 if(ch_time!=NULL)
100 localRev = strtoul(ch_time, &ptr, 10);
101 }
102 }
103 }*/
104 stringStream.str("");
105 stringStream << " Local revision: ";
106 if (localRev == 0)
107 stringStream << "Undifined.";
108 else
109 stringStream << localRev;
110 cout << "\033[31m" << "The local database with path " << localDbPath << " already exists."
111 << stringStream.str().c_str() << "\033[0m" << endl;
112 // if(exists_file("server_revision.txt"))
113 // std::remove("server_revision.txt");
114 /* gSystem->Exec(TString::Format("wget -O server_revision.txt \"%s/get_cur_timestamp.php\" > /dev/null
115 2>&1", url)); std::ifstream myFile_Handler; std::string myLine;
116 myFile_Handler.open("server_revision.txt"); if(myFile_Handler.is_open())
117 {
118 char *ptr;
119 while(getline(myFile_Handler, myLine))
120 {
121 serverRev=strtoul(myLine.c_str(), &ptr, 10);
122 break;
123 }
124 myFile_Handler.close();
125 }*/
126 serverRev = getServerRevision(url);
127 if (serverRev == 0) {
128 cerr << "The server revision is not detected. Please contact with administrator for check the problem.";
129 return -2;
130 }
131 if (serverRev == localRev) {
132 cout << "\033[32m" << "The current local version of geometry database is last. Instalation is stopped."
133 << "\033[0m" << std::endl;
134 return 0;
135 }
136
137 cout << "\033[31m" << "The server revision: " << serverRev << "\033[0m" << endl;
138 do {
139 cout << "Do you want to update it[y/n]?" << "\033[0m" << endl;
140 cin >> type;
141 } while (!cin.fail() && type != 'y' && type != 'n');
142 if (type == 'n') {
143 cout << "Break install because local database already exist" << "\033[0m";
144 return -1;
145 } else if (type == 'y') {
146 }
147 }
148 }
149
150 // extract directory and file name from the path
151 TString dirName(gSystem->DirName(localDbPath.Data()));
152 TString fileName(gSystem->BaseName(localDbPath.Data()));
153 // create the directory if not exists
154 if (gSystem->AccessPathName(dirName.Data(), kFileExists)) {
155 if (gSystem->mkdir(dirName, true) != 0) {
156 cerr << "ERROR: cannot create folder: " << dirName << endl;
157 return -3;
158 }
159 }
160
161 // get archive with the database file
162 // --tries: retries are done by the loop below, otherwise are multiplied by wget internal ones (20 by def.)
163 // --read-timeout is not set (900 seconds by default)
164 // --connect-timeout=10: do not hang forever on a stalled connection
166 "wget --tries=1 --dns-timeout=10 --connect-timeout=10 -O localdb.tar \"%s/download_file.php", url);
167 if (tag == nullptr)
168 st += "?type=all&tag=all\"";
169 else
170 st += TString::Format("?type=s&tag=%s\"", tag);
171 st += "> /dev/null 2>&1";
172 // cerr<<st<<endl;
173
174 // try to download the archive up to 3 times, the connection may be slow or unstable
175 const int maxAttempts = 3;
176 bool downloaded = false;
177 TString failReason; // the reason of the last failed attempt, reported once after all attempts
178 for (int attempt = 1; attempt <= maxAttempts; ++attempt) {
179 // report only the retries, the first attempt is silent
180 if (attempt > 1)
181 cout << "Retrying to download the geometry database (attempt " << attempt << " of " << maxAttempts << ")..."
182 << endl;
183 gSystem->Unlink("localdb.tar");
184 // Exec returns the raw status of system(), the wget exit code is its high byte:
185 // 4 - network failure, 8 - error response from the server (e.g. 404), see 'man wget'
186 int wgetStatus = gSystem->Exec(st);
187
188 if (wgetStatus != 0)
189 failReason = TString::Format("wget could not download the file (exit code %d)", wgetStatus / 256);
190 else if (gSystem->AccessPathName("localdb.tar", kFileExists))
191 failReason = "the geometry database file was not downloaded";
192 else {
193 gSystem->GetPathInfo("localdb.tar", file_stat);
194 if (file_stat.fSize == 0)
195 failReason = "the downloaded geometry database file has 0 size";
196 // the server may answer with an HTML error/redirect page (HTTP 200) instead of the archive, or the
197 // download may be truncated: such a file is not empty but is not a valid tar, so check the exit
198 // code of tar listing its content (a truncated archive prints its first entries and then fails)
199 else if (gSystem->Exec("tar -tf localdb.tar > /dev/null 2>&1") != 0)
200 failReason = "the downloaded file is not a valid tar archive (probably an HTML error page or an "
201 "incomplete download)";
202 else {
203 downloaded = true;
204 break;
205 }
206 }
207
208 if (attempt < maxAttempts)
209 gSystem->Sleep(5000); // wait 5 seconds before the next attempt
210 }
211
212 if (!downloaded) {
213 cerr << "ERROR: downloading the geometry database failed after " << maxAttempts << " attempts: " << failReason
214 << ", please, check url: " << url << endl;
215 return -4;
216 }
217
218 // untar archive with the database file
219 gSystem->Exec(TString::Format("tar -xvf localdb.tar -C \"%s/\" > /dev/null 2>&1", dirName.Data()));
220 if (gSystem->AccessPathName(gSystem->ConcatFileName(dirName.Data(), "local.db"), kFileExists)) {
221 cerr << "ERROR: unarchiving the geometry database failed, please, check url: " << url << endl;
222 return -6;
223 }
224
225 // remove temporary archive
226 gSystem->Exec("rm -rf localdb.tar");
227
228 // move local.db file to the given path
229 if (fileName != "local.db") {
230 gSystem->CopyFile(gSystem->ConcatFileName(dirName.Data(), "local.db"),
231 gSystem->ConcatFileName(dirName.Data(), fileName.Data()), kTRUE);
232 gSystem->Unlink(gSystem->ConcatFileName(dirName.Data(), "local.db"));
233 }
234
235 cout << "The Local Geometry Database was successfully installed to the directory: " << dirName << endl;
236 return 0;
237}
constexpr Bool_t kTRUE
kFileExists
Bool_t R_ISDIR(Int_t mode)
R__EXTERN TSystem * gSystem
virtual TSQLRow * Next()=0
virtual const char * GetField(Int_t field)=0
virtual Bool_t IsConnected() const
TSQLResult * Query(const char *sql) final
const char * Data() const
static TString Format(const char *fmt,...)
unsigned long int getServerRevision(const char *url)
unsigned long int getLocalRevision(TString &localDbPath)
bool exists_file(const char *name)
int installLocalDB(const char *tag=nullptr, const char *url="https://bmn-geometry.jinr.int")
Definition json.hpp:4446
Long64_t fSize