source: trunk/MagicSoft/Mars/msql/MSQLServer.cc@ 4693

Last change on this file since 4693 was 4577, checked in by tbretz, 20 years ago
*** empty log message ***
File size: 13.3 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz 2/2004 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2004
21!
22!
23\* ======================================================================== */
24
25////////////////////////////////////////////////////////////////////////
26//
27// MSQLServer
28//
29// Using this instead of a TSQLServer gives the possibility to
30// browse a database server through the TBrowser and it will offer
31// many features usefull working with relational tables.
32//
33// Use it like TSQlServer:
34// new MSQLServer("mysql://localhost:3306", "hercules", "stdmagicpassword");
35// // now start your TBrowser
36// new TBrowser;
37//
38////////////////////////////////////////////////////////////////////////
39#include "MSQLServer.h"
40
41#include <iostream>
42#include <iomanip>
43#include <stdlib.h>
44
45#include <TROOT.h>
46
47#include <TH1.h>
48
49#include <TSQLResult.h>
50#include <TSQLServer.h>
51#include <TSQLRow.h>
52
53#include <TBrowser.h>
54
55ClassImp(MSQLServer);
56
57using namespace std;
58
59// --------------------------------------------------------------------------
60//
61// Used in virtual function TObject::Browse() to create the
62//
63void MSQLServer::BrowseColumn(TBrowser *b) /*FOLD00*/
64{
65 const TString query0(Form("EXPLAIN %s.%s %s", (const char*)fDataBase, (const char*)fTable, (const char*)fColumn));
66 const TString query1(Form("SELECT %s FROM %s.%s", (const char*)fColumn, (const char*)fDataBase, (const char*)fTable));
67
68 //cout << query0 << endl;
69 TSQLResult *res = fServ->Query(query0);
70 if (!res)
71 {
72 cout << "query - failed: " << query0 << endl;
73 return;
74 }
75
76 TSQLRow *row=res->Next();
77 const TString desc((*row)[1]);
78
79 delete res;
80
81 const Bool_t isnum =
82 !desc.Contains("char", TString::kIgnoreCase) &&
83 !desc.Contains("text", TString::kIgnoreCase);
84
85 cout << query1 << endl;
86 res = fServ->Query(query1);
87 if (!res)
88 {
89 cout << "query - failed: " << query1 << endl;
90 return;
91 }
92
93 TArrayD arr(2);
94 Int_t num=0;
95 Double_t max=0;
96 Double_t min=0;
97 Double_t sum=0;
98 Double_t sqr=0;
99
100 while ((row=res->Next()))
101 {
102 const TString row0((*row)[0]);
103
104 if (!isnum)
105 {
106 cout << row0 << endl;
107 continue;
108 }
109
110 if (num==arr.GetSize())
111 arr.Set(arr.GetSize()*2);
112
113 arr[num] = atof(row0.Data());
114
115 if (num==0)
116 min=max=arr[0];
117
118 if (arr[num]>max) max = arr[num];
119 if (arr[num]<min) min = arr[num];
120
121 sum += arr[num];
122 sqr += arr[num]*arr[num];
123
124 num++;
125 }
126
127 delete res;
128
129 if (!isnum)
130 return;
131
132 if (max==min) max += 1;
133
134 Int_t num0 = 1;
135
136 if (num>0)
137 {
138 /*
139 cout << "Num: " << num << endl;
140 cout << "Mean: " << sum/num << endl;
141 cout << "Range: " << max-min << endl;
142 cout << "RMS: " << TMath::Sqrt(sqr/num-sum*sum/num/num) << endl;
143 */
144
145 num0 = (Int_t)((max-min)*40/TMath::Sqrt(sqr/num-sum*sum/num/num));
146 }
147
148 const TString title(Form("#splitline{%s}{<%s>}", (const char*)query1, (const char*)desc));
149
150 TH1F *hist=new TH1F(fColumn, title, num0, min, max);
151 for (int i=0; i<num; i++)
152 hist->Fill(arr[i]);
153
154 //cout << "Done." << endl;
155
156 hist->Draw();
157 hist->SetBit(kCanDelete);
158}
159
160void MSQLServer::BrowseTable(TBrowser *b) /*FOLD00*/
161{
162 TSQLResult *res = fServ->GetColumns(fDataBase, fTable);
163 if (!res)
164 return;
165
166 TSQLRow *row;
167 while ((row=res->Next()))
168 {
169 TString row0((*row)[0]);
170
171 MSQLServer *sql = (MSQLServer*)fList.FindObject(Form("%s/%s/%s", (const char*)fDataBase, (const char*)fTable, (const char*)row0));
172 if (!sql)
173 {
174 sql = new MSQLColumn(fServ, fDataBase, fTable, row0);
175 fList.Add(sql);
176 }
177 b->Add(sql, row0);
178 }
179}
180
181void MSQLServer::BrowseDataBase(TBrowser *b) /*FOLD00*/
182{
183 TSQLResult *res = fServ->GetTables(fDataBase);
184 if (!res)
185 return;
186
187 TSQLRow *row;
188 while ((row=res->Next()))
189 {
190 TString row0((*row)[0]);
191
192 MSQLServer *sql = (MSQLServer*)fList.FindObject(Form("%s/%s", (const char*)fDataBase, (const char*)row0));
193 if (!sql)
194 {
195 sql = new MSQLServer(fServ, fDataBase, row0);
196 fList.Add(sql);
197 }
198 b->Add(sql, row0);
199 }
200}
201
202void MSQLServer::BrowseServer(TBrowser *b) /*FOLD00*/
203{
204 TSQLResult *res = fServ->GetDataBases();
205 if (!res)
206 return;
207
208 TSQLRow *row;
209 while ((row=res->Next()))
210 {
211 const TString row0((*row)[0]);
212
213 MSQLServer *sql = (MSQLServer*)fList.FindObject(row0);
214 if (!sql)
215 {
216 sql = new MSQLServer(fServ, row0);
217 fList.Add(sql);
218 }
219 b->Add(sql, row0);
220 }
221}
222
223void MSQLServer::PrintLine(const TArrayI &max) /*FOLD00*/
224{
225 cout << "+" << setfill('-');
226 for (int i=0; i<max.GetSize(); i++)
227 cout << setw(max[i]+1) << "-" << "-+";
228 cout << endl;
229}
230
231void MSQLServer::PrintTable(TSQLResult &res) /*FOLD00*/
232{
233 Int_t n = res.GetFieldCount();
234
235 TArrayI max(n);
236
237 for (int i=0; i<n; i++)
238 max[i] = strlen(res.GetFieldName(i));
239
240 TSQLRow *row;
241
242 TList rows;
243 while ((row=res.Next()))
244 {
245 for (int i=0; i<n; i++)
246 max[i] = TMath::Max((ULong_t)max[i], row->GetFieldLength(i));
247 rows.Add(row);
248 }
249
250 cout << endl;
251
252 PrintLine(max);
253
254 cout << "|" << setfill(' ');
255 for (int i=0; i<n; i++)
256 cout << setw(max[i]+1) << res.GetFieldName(i) << " |";
257 cout << endl;
258
259 PrintLine(max);
260
261 cout << setfill(' ');
262 TIter Next(&rows);
263 while ((row=(TSQLRow*)Next()))
264 {
265 cout << "|";
266 for (int i=0; i<n; i++)
267 {
268 const char *c = (*row)[i];
269 cout << setw(max[i]+1) << (c?c:"") << " |";
270 }
271 cout << endl;
272 }
273
274 PrintLine(max);
275}
276
277TString MSQLServer::GetFields() const /*FOLD00*/
278{
279 TSQLResult *res = fServ->GetColumns(fDataBase, fTable);
280 if (!res)
281 return "";
282
283 TString fields;
284
285 TSQLRow *row;
286
287 TList rows;
288 while ((row=res->Next()))
289 rows.Add(row);
290
291 TIter Next(&rows);
292 while ((row=(TSQLRow*)Next()))
293 {
294 fields += (*row)[0];
295 if (row!=rows.Last())
296 fields += ", ";
297 }
298
299 return fields;
300}
301
302void MSQLServer::PrintQuery(const char *query) const /*FOLD00*/
303{
304 TSQLResult *res = fServ->Query(query);
305 if (res)
306 {
307 PrintTable(*res);
308 delete res;
309 }
310 else
311 cout << "Query failed: " << query << endl;
312}
313
314void MSQLServer::Print(Option_t *o) const /*FOLD00*/
315{
316 switch (fType)
317 {
318 case kIsServer:
319 PrintQuery("SHOW DATABASES");
320 break;
321
322 case kIsDataBase:
323 PrintQuery(Form("SHOW TABLES FROM %s", (const char*)fDataBase));
324 break;
325
326 case kIsTable:
327 PrintQuery(Form("SELECT * FROM %s.%s", (const char*)fDataBase, (const char*)fTable));
328 break;
329
330 case kIsColumn:
331 PrintQuery(Form("SELECT %s FROM %s.%s", (const char*)fColumn, (const char*)fDataBase, (const char*)fTable));
332 break;
333
334 default:
335 break;
336 }
337}
338
339void MSQLServer::ShowColumns() const /*FOLD00*/
340{
341 switch (fType)
342 {
343 case kIsTable:
344 PrintQuery(Form("SHOW FULl COLUMNS FROM %s.%s", (const char*)fDataBase, (const char*)fTable));
345 break;
346
347 case kIsColumn:
348 PrintQuery(Form("SHOW FULl COLUMNS FROM %s.%s LIKE %s", (const char*)fDataBase, (const char*)fTable, (const char*)fColumn));
349 break;
350
351 default:
352 //Print();
353 break;
354 }
355}
356
357void MSQLServer::ShowStatus() const /*FOLD00*/
358{
359 switch (fType)
360 {
361 case kIsServer:
362 PrintQuery("SHOW STATUS");
363 break;
364
365 case kIsDataBase:
366 PrintQuery(Form("SHOW TABLE STATUS FROM %s", (const char*)fDataBase));
367 break;
368
369 case kIsTable:
370 PrintQuery(Form("SHOW TABLE STATUS FROM %s LIKE %s", (const char*)fDataBase, (const char*)fTable));
371 break;
372
373 default:
374 break;
375 }
376}
377
378void MSQLServer::ShowTableIndex() const /*FOLD00*/
379{
380 switch (fType)
381 {
382 case kIsTable:
383 case kIsColumn:
384 PrintQuery(Form("SHOW INDEX FROM %s.%s", (const char*)fDataBase, (const char*)fTable));
385 break;
386
387 default:
388 break;
389 }
390}
391
392void MSQLServer::ShowTableCreate() const /*FOLD00*/
393{
394 switch (fType)
395 {
396 case kIsTable:
397 case kIsColumn:
398 PrintQuery(Form("SHOW CREATE TABLE %s.%s", (const char*)fDataBase, (const char*)fTable));
399 break;
400
401 default:
402 break;
403 }
404}
405
406void MSQLServer::Close(Option_t *option) /*FOLD00*/
407{
408 if (fType==kIsServer)
409 fServ->Close(option);
410}
411
412TSQLResult *MSQLServer::Query(const char *sql) /*FOLD00*/
413{
414 return fType==kIsServer ? fServ->Query(sql) : NULL;
415}
416
417Int_t MSQLServer::SelectDataBase(const char *dbname) /*FOLD00*/
418{
419 return fType==kIsServer ? fServ->SelectDataBase(dbname) : 0;
420}
421
422TSQLResult *MSQLServer::GetDataBases(const char *wild) /*FOLD00*/
423{
424 return fType==kIsServer ? fServ->GetDataBases(wild) : NULL;
425}
426
427TSQLResult *MSQLServer::GetTables(const char *dbname, const char *wild) /*FOLD00*/
428{
429 return fType==kIsServer ? fServ->GetTables(dbname, wild) : NULL;
430}
431
432TSQLResult *MSQLServer::GetColumns(const char *dbname, const char *table, const char *wild) /*FOLD00*/
433{
434 return fType==kIsServer ? fServ->GetColumns(dbname, table, wild) : NULL;
435}
436
437Int_t MSQLServer::CreateDataBase(const char *dbname) /*FOLD00*/
438{
439 return fType==kIsServer ? fServ->CreateDataBase(dbname) : 0;
440}
441
442Int_t MSQLServer::DropDataBase(const char *dbname) /*FOLD00*/
443{
444 return fType==kIsServer ? fServ->DropDataBase(dbname) : 0;
445}
446
447Int_t MSQLServer::Reload() /*FOLD00*/
448{
449 return fType==kIsServer ? fServ->Reload() : 0;
450}
451
452Int_t MSQLServer::Shutdown() /*FOLD00*/
453{
454 return fType==kIsServer ? fServ->Shutdown() : 0;
455}
456
457const char *MSQLServer::ServerInfo() /*FOLD00*/
458{
459 return fType==kIsServer ? fServ->ServerInfo() : "";
460}
461
462Bool_t MSQLServer::IsConnected() const
463{
464 return fType==kIsServer ? fServ->IsConnected() : kFALSE;
465}
466
467const char *MSQLServer::GetName() const
468{
469 switch (fType)
470 {
471 case kIsServer: return Form("%s://%s:%d", fServ->GetDBMS(), fServ->GetHost(), fServ->GetPort());
472 case kIsDataBase: return GetNameDataBase();
473 case kIsTable: return GetNameTable();
474 case kIsColumn: return GetNameColumn();
475 default: return "n/a";
476 }
477}
478
479void MSQLServer::Init(const char *connection, const char *user, const char *password) /*FOLD00*/
480{
481 fType = kIsZombie;
482
483 fServ = TSQLServer::Connect(connection, user, password);
484 if (fServ)
485 {
486 gROOT->GetListOfBrowsables()->Add(this, connection);
487 fType = kIsServer;
488 }
489 else
490 SetBit(kZombie);
491
492 fList.SetOwner();
493}
494
495MSQLServer::MSQLServer(const char *connection, const char *user, const char *password) /*FOLD00*/
496{
497 Init(connection, user, password);
498}
499
500MSQLServer::MSQLServer(const char *u) : fType(kIsZombie) /*FOLD00*/
501{
502 TString url(u);
503
504 const Ssiz_t pos1 = url.First("://")+3;
505 const Ssiz_t pos2 = url.Last(':') +1;
506 const Ssiz_t pos3 = url.First('@');
507
508 if (pos1<0 || pos2<0 || pos3<0 || pos1>pos2 || pos2>pos3)
509 {
510 SetBit(kZombie);
511 return;
512 }
513
514 const TString user = url(pos1, pos2-pos1-1);
515 const TString pasw = url(pos2, pos3-pos2);
516
517 url.Remove(pos1, pos3+1-pos1);
518
519 Init(url, user, pasw);
520}
521
522MSQLServer::~MSQLServer() /*FOLD00*/
523{
524 Close();
525 if (gDebug>0)
526 cout << "Delete: " << GetName() << endl;
527}
528
529Bool_t MSQLServer::PrintError(const char *txt, const char *q) const /*FOLD00*/
530{
531 cout << "Fatal error acessing database: " << txt << endl;
532 cout << "Query: " << q << endl;
533 return kFALSE;
534}
535
536TString MSQLServer::GetEntry(const char *where, const char *col, const char *table) const /*FOLD00*/
537{
538 if (!fServ)
539 return "";
540
541 if (table==0)
542 table = Form("%s.%s", (const char *)fDataBase, (const char*)fTable);
543 if (col==0)
544 col = (const char *)fColumn;
545
546 const TString query(Form("SELECT %s FROM %s WHERE %s", col, table, where));
547
548 TSQLResult *res = fServ->Query(query);
549 if (!res)
550 return (PrintError("GetEntry - TSQLResult==NULL", query), "");
551
552 if (res->GetFieldCount()!=1)
553 {
554 delete res;
555 return (PrintError("GetEntry - Number of columns != 1", query), "");
556 }
557
558 if (res->GetRowCount()>1)
559 {
560 delete res;
561 return (PrintError("GetEntry - Number of rows > 1", query), "");
562 }
563
564 if (res->GetRowCount()==0)
565 {
566 delete res;
567 return "";
568 }
569
570 const char *fld = res->Next()->GetField(0);
571 if (!fld)
572 {
573 delete res;
574 return (PrintError("GetEntry - Entry is empty", query), "");
575 }
576
577 const TString rc(fld);
578 delete res;
579 return rc;
580}
Note: See TracBrowser for help on using the repository browser.