Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TSQLMonitoring.cxx
Go to the documentation of this file.
1// Author: J.F. Grosse-Oetringhaus, G.Ganis
2
3/*************************************************************************
4 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
11//////////////////////////////////////////////////////////////////////////
12// //
13// TSQLMonitoringWriter //
14// //
15// SQL implementation of TVirtualMonitoringWriter. //
16// //
17//////////////////////////////////////////////////////////////////////////
18
19#include "TList.h"
20#include "TParameter.h"
21#include "TEnv.h"
22#include "TObjString.h"
23#include "TSQLMonitoring.h"
24#include "TSQLServer.h"
25#include "TSQLResult.h"
26
27////////////////////////////////////////////////////////////////////////////////
28/// Constructor.
29
31 const char *pass, const char *table)
32 : TVirtualMonitoringWriter("SQL", 0.0), fTable(table), fVerbose(kFALSE)
33{
34 // Open connection to SQL server
36 if (!fDB || fDB->IsZombie()) {
38 // Invalid object
39 MakeZombie();
40 }
41 // Set the max bulk insertion size
42 fMaxBulkSize = 16 * 1024 * 1024;
43 TString smx = gEnv->GetValue("SQLMonitoringWriter.MaxBulkSize", "16M");
44 if (!smx.IsDigit()) {
45 if (smx.EndsWith("K", TString::kIgnoreCase)) {
46 smx.Remove(smx.Length()-1);
47 if (smx.IsDigit()) fMaxBulkSize = smx.Atoi() * 1024;
48 } else if (smx.EndsWith("M", TString::kIgnoreCase)) {
49 smx.Remove(smx.Length()-1);
50 if (smx.IsDigit()) fMaxBulkSize = smx.Atoi() * 1024 * 1024;
51 } else if (smx.EndsWith("G", TString::kIgnoreCase)) {
52 smx.Remove(smx.Length()-1);
53 if (smx.IsDigit()) fMaxBulkSize = smx.Atoi() * 1024 * 1024 * 1024;
54 }
55 } else {
56 fMaxBulkSize = smx.Atoi();
57 }
58}
59
60////////////////////////////////////////////////////////////////////////////////
61/// Destructor
62
67
68////////////////////////////////////////////////////////////////////////////////
69/// Register query log using the information in the list which is in the form
70/// TParameter(<par>,<value>) or TNamed(<name>,<string>). For bulk sending,
71/// the first entry in the list is an TObjString defining the variable names
72/// in the format
73/// VARname1,VARname2,...
74/// while the other entries are TObjStrings with the multiplets to be sent
75/// VARvalue1,VARvalue2,...
76///
77/// The string 'opt' allows the following additional control:
78/// table=`[<db>.]<table>` allows to insert to a different table from the
79/// one defined at construction (change is not
80/// persistent); if `<db>` is not specified, the same
81/// db defined at cinstruction is used.
82/// bulk Do a bulk insert
83/// More options can be given concurrently, comma-separated .
84/// The specified table must already have been created in the DB.
85
87{
88 if (!fDB) {
89 // Invalid instance
90 return kFALSE;
91 }
92
93 // The list must contain something
94 if (!values || (values && values->GetSize() < 1))
95 return kFALSE;
96
97 // Parse options
98 TString table(fTable), op, ops(opt);
99 Ssiz_t from = 0;
101 while (ops.Tokenize(op, from, ",")) {
102 if (op == "bulk") {
103 bulk = kTRUE;
104 } else if (op.BeginsWith("table=")) {
105 op.ReplaceAll("table=", "");
106 if (!op.IsNull()) {
107 Ssiz_t idot = table.Index('.');
108 if (idot != kNPOS && op.Index('.') == kNPOS) {
109 table.Remove(idot+1);
110 table += op;
111 } else {
112 table = op;
113 }
114 }
115 }
116 }
117
118 TIter nxi(values);
119 TObject *o = 0;
120
121 // now prepare the strings
122 TString sql = TString::Format("INSERT INTO %s", table.Data());
123
124 TSQLResult *res = 0;
125 if (!bulk) {
126
127 // the column and values strings
128 char c = '(';
129 TString cols, vals;
130 while ((o = nxi())) {
131 if (!strncmp(o->ClassName(), "TNamed", 6)) {
132 cols += TString::Format("%c%s", c, ((TNamed *)o)->GetName());
133 vals += TString::Format("%c'%s'", c, ((TNamed *)o)->GetTitle());
134 } else if (!strcmp(o->ClassName(), "TParameter<Long64_t>")) {
135 cols += TString::Format("%c%s", c, ((TParameter<Long64_t> *)o)->GetName());
136 vals += TString::Format("%c%lld", c, ((TParameter<Long64_t> *)o)->GetVal());
137 } else if (!strcmp(o->ClassName(), "TParameter<double>")) {
138 cols += TString::Format("%c%s", c, ((TParameter<double> *)o)->GetName());
139 vals += TString::Format("%c%f", c, ((TParameter<double> *)o)->GetVal());
140 } else if (!strcmp(o->ClassName(), "TParameter<float>")) {
141 cols += TString::Format("%c%s", c, ((TParameter<float> *)o)->GetName());
142 vals += TString::Format("%c%f", c, ((TParameter<float> *)o)->GetVal());
143 } else if (!strcmp(o->ClassName(), "TParameter<int>")) {
144 cols += TString::Format("%c%s", c, ((TParameter<int> *)o)->GetName());
145 vals += TString::Format("%c%d", c, ((TParameter<int> *)o)->GetVal());
146 } else if (!strcmp(o->ClassName(), "TParameter<long>")) {
147 cols += TString::Format("%c%s", c, ((TParameter<long> *)o)->GetName());
148 vals += TString::Format("%c%ld", c, ((TParameter<long> *)o)->GetVal());
149 }
150 c = ',';
151 }
152 cols += ")";
153 vals += ")";
154
155 // Put everything together
156 sql += TString::Format(" %s VALUES %s", cols.Data(), vals.Data());
157
158 // Post query
159 if (fVerbose) Info("SendParameters", "sending: '%s'", sql.Data());
160 if (!(res = fDB->Query(sql))) {
161 Error("SendParameters", "insert into %s failed", table.Data());
162 if (sql.Length() > 1024) {
163 TString head(sql(0,508)), tail(sql(sql.Length()-512,512));
164 Printf("%s...%s", head.Data(), tail.Data());
165 } else {
166 Printf("%s", sql.Data());
167 }
168 return kFALSE;
169 }
170 delete res;
171
172 } else {
173 // Prepare for bulk submission
174 o = nxi();
175 TObjString *os = dynamic_cast<TObjString *>(o);
176 if (!os) {
177 Error("SendParameters", "bulk insert: first entry in list is not 'TObjString' but '%s'", o ? o->ClassName() : "noclass" );
178 return kFALSE;
179 }
180 // Continue preparing the string
181 sql += TString::Format(" (%s) VALUES ", os->GetName());
182 TString head = sql;
183 if (fVerbose) Info("SendParameters", "sending: '%s' (bulk of %d nplets)", head.Data(), values->GetSize() - 1);
184 char c = ' ';
185 while ((o = nxi())) {
186 if ((os = dynamic_cast<TObjString *>(o))) {
187 sql += TString::Format("%c(%s)", c, os->GetName());
188 c = ',';
189 } else {
190 Warning("SendParameters", "bulk insert: ignoring not 'TObjString' entry ('%s')", o->ClassName() );
191 }
192 // Check size (we cannot exceed fMaxBulkSize ('max_allowed_packet' in [mysqld] conf section)
193 if (sql.Length() > 0.9 * fMaxBulkSize) {
194 if (!(res = fDB->Query(sql))) {
195 Error("SendParameters", "bulk insert into %s failed", table.Data());
196 if (sql.Length() > 1024) {
197 TString hd(sql(0,508)), tl(sql(sql.Length()-512,512));
198 Printf("%s...%s", hd.Data(), tl.Data());
199 } else {
200 Printf("%s", sql.Data());
201 }
202 return kFALSE;
203 }
204 delete res;
205 sql = head;
206 c = ' ';
207 }
208 }
209 // Check if there is still something to send
210 if (sql.Length() > head.Length()) {
211 if (!(res = fDB->Query(sql))) {
212 Error("SendParameters", "bulk insert into %s failed", table.Data());
213 if (sql.Length() > 1024) {
214 TString hd(sql(0,508)), tl(sql(sql.Length()-512,512));
215 Printf("%s...%s", hd.Data(), tl.Data());
216 } else {
217 Printf("%s", sql.Data());
218 }
219 return kFALSE;
220 }
221 delete res;
222 }
223 }
224
225 // Done successfully
226 return kTRUE;
227}
#define SafeDelete(p)
Definition RConfig.hxx:533
#define c(i)
Definition RSha256.hxx:101
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Ssiz_t kNPOS
The equivalent of std::string::npos for the ROOT class TString.
Definition RtypesCore.h:131
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
R__EXTERN TEnv * gEnv
Definition TEnv.h:170
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Definition TString.cxx:2510
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:491
A doubly linked list.
Definition TList.h:38
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
Collectable string class.
Definition TObjString.h:28
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:227
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1058
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition TObject.h:159
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1072
void MakeZombie()
Definition TObject.h:53
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1046
virtual ~TSQLMonitoringWriter()
Destructor.
Bool_t SendParameters(TList *values, const char *) override
Register query log using the information in the list which is in the form TParameter(<par>,...
TSQLMonitoringWriter(const TSQLMonitoringWriter &)=delete
virtual TSQLResult * Query(const char *sql)=0
static TSQLServer * Connect(const char *db, const char *uid, const char *pw)
The db should be of the form: <dbms>://<host>[:<port>][/<database>], e.g.: mysql://pcroot....
Basic string class.
Definition TString.h:138
Ssiz_t Length() const
Definition TString.h:425
const char * Data() const
Definition TString.h:384
@ kIgnoreCase
Definition TString.h:285
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2385