Logo ROOT   6.12/07
Reference Guide
TSQLObjectData.cxx
Go to the documentation of this file.
1 // @(#)root/sql:$Id$
2 // Author: Sergey Linev 20/11/2005
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /**
13 \class TSQLObjectData
14 \ingroup IO
15 
16 TSQLObjectData is used in TBufferSQL2 class in reading procedure.
17 It contains data, request from database table for one specific
18 object for one specific class. For instance, when data for
19 class TH1 required, requests will be done to
20 TH1_ver4 and TH1_raw4 tables and result of these requests
21 will be kept in single TSQLObjectData instance.
22 */
23 
24 #include "TSQLObjectData.h"
25 
26 #include "TObjArray.h"
27 #include "TNamed.h"
28 #include "TList.h"
29 #include "TSQLRow.h"
30 #include "TSQLResult.h"
31 #include "TSQLClassInfo.h"
32 #include "TSQLStructure.h"
33 #include "TSQLStatement.h"
34 
35 /**
36 \class TSQLObjectInfo
37 \ingroup IO
38 Info (classname, version) about object in database
39 */
40 
42 
43 ////////////////////////////////////////////////////////////////////////////////
44 
45 TSQLObjectInfo::TSQLObjectInfo() : TObject(), fObjId(0), fClassName(), fVersion(0)
46 {
47 }
48 
49 ////////////////////////////////////////////////////////////////////////////////
50 
51 TSQLObjectInfo::TSQLObjectInfo(Long64_t objid, const char *classname, Version_t version)
52  : TObject(), fObjId(objid), fClassName(classname), fVersion(version)
53 {
54 }
55 
56 ////////////////////////////////////////////////////////////////////////////////
57 
59 {
60 }
61 
62 /**
63 \class TSQLObjectData
64 \ingroup IO
65 Keeps the data requested from the SQL server for an object.
66 */
67 
69 
70 ////////////////////////////////////////////////////////////////////////////////
71 /// default contrsuctor
72 
74  : TObject(), fInfo(0), fObjId(0), fOwner(kFALSE), fClassData(0), fBlobData(0), fBlobStmt(0), fLocatedColumn(-1),
75  fClassRow(0), fBlobRow(0), fLocatedField(0), fLocatedValue(0), fCurrentBlob(kFALSE), fBlobPrefixName(0),
76  fBlobTypeName(0), fUnpack(0)
77 {
78 }
79 
80 ////////////////////////////////////////////////////////////////////////////////
81 /// normal contrsuctor,
82 
84  TSQLResult *blobdata, TSQLStatement *blobstmt)
85  : TObject(), fInfo(sqlinfo), fObjId(objid), fOwner(kFALSE), fClassData(classdata), fBlobData(blobdata),
86  fBlobStmt(blobstmt), fLocatedColumn(-1), fClassRow(classrow), fBlobRow(0), fLocatedField(0), fLocatedValue(0),
88 {
89  // take ownership if no special row from data pool is provided
90  if ((fClassData != 0) && (fClassRow == 0)) {
91  fOwner = kTRUE;
93  }
94 
95  ShiftBlobRow();
96 }
97 
98 ////////////////////////////////////////////////////////////////////////////////
99 /// destructor of TSQLObjectData object
100 
102 {
103  if ((fClassData != 0) && fOwner)
104  delete fClassData;
105  if (fClassRow != 0)
106  delete fClassRow;
107  if (fBlobRow != 0)
108  delete fBlobRow;
109  if (fBlobData != 0)
110  delete fBlobData;
111  if (fUnpack != 0) {
112  fUnpack->Delete();
113  delete fUnpack;
114  }
115  if (fBlobStmt != 0)
116  delete fBlobStmt;
117 }
118 
119 ////////////////////////////////////////////////////////////////////////////////
120 /// return number of columns in class table result
121 
123 {
124  if (fClassData != 0)
125  return fClassData->GetFieldCount();
126  return 0;
127 }
128 
129 ////////////////////////////////////////////////////////////////////////////////
130 /// get name of class table column
131 
133 {
134  if (fClassData != 0)
135  return fClassData->GetFieldName(n);
136  return 0;
137 }
138 
139 ////////////////////////////////////////////////////////////////////////////////
140 /// locate column of that name in results
141 
142 Bool_t TSQLObjectData::LocateColumn(const char *colname, Bool_t isblob)
143 {
144  if (fUnpack != 0) {
145  fUnpack->Delete();
146  delete fUnpack;
147  fUnpack = 0;
148  }
149 
150  fLocatedField = 0;
151  fLocatedValue = 0;
153 
154  if ((fClassData == 0) || (fClassRow == 0))
155  return kFALSE;
156 
157  // Int_t numfields = GetNumClassFields();
158 
159  Int_t ncol = fInfo->FindColumn(colname, kFALSE);
160  if (ncol > 0) {
161  fLocatedColumn = ncol;
164  }
165 
166  /* for (Int_t ncol=1;ncol<numfields;ncol++) {
167  const char* fieldname = GetClassFieldName(ncol);
168  if (strcmp(colname, fieldname)==0) {
169  fLocatedColumn = ncol;
170  fLocatedField = fieldname;
171  fLocatedValue = fClassRow->GetField(ncol);
172  break;
173  }
174  }
175  */
176 
177  if (fLocatedField == 0)
178  return kFALSE;
179 
180  if (!isblob)
181  return kTRUE;
182 
183  if ((fBlobRow == 0) && (fBlobStmt == 0))
184  return kFALSE;
185 
187 
189 
190  return kTRUE;
191 }
192 
193 ////////////////////////////////////////////////////////////////////////////////
194 /// shift cursor to next blob value
195 
197 {
198  if (fBlobStmt != 0) {
199  Bool_t res = fBlobStmt->NextResultRow();
200  if (!res) {
201  delete fBlobStmt;
202  fBlobStmt = 0;
203  }
204  return res;
205  }
206 
207  delete fBlobRow;
208  fBlobRow = fBlobData ? fBlobData->Next() : 0;
209  return fBlobRow != 0;
210 }
211 
212 ////////////////////////////////////////////////////////////////////////////////
213 /// extract from curent blob row value and names identifiers
214 
216 {
217  const char *name = 0;
218 
219  Bool_t hasdata = kFALSE;
220 
221  if (fBlobStmt != 0) {
222  name = fBlobStmt->GetString(0);
224  hasdata = kTRUE;
225  }
226 
227  if (!hasdata) {
228  if (fBlobRow != 0) {
230  name = fBlobRow->GetField(0);
231  }
232  }
233 
234  if (name == 0) {
235  fBlobPrefixName = 0;
236  fBlobTypeName = 0;
237  return kFALSE;
238  }
239 
240  const char *separ = strstr(name, ":"); // SQLNameSeparator()
241 
242  if (separ == 0) {
243  fBlobPrefixName = 0;
245  } else {
247  separ += strlen(":"); // SQLNameSeparator()
248  fBlobTypeName = separ;
249  }
250 
251  // if (gDebug>4)
252  // Info("ExtractBlobValues","Prefix:%s Type:%s",
253  // (fBlobPrefixName ? fBlobPrefixName : "null"),
254  // (fBlobTypeName ? fBlobTypeName : "null"));
255 
256  return kTRUE;
257 }
258 
259 ////////////////////////////////////////////////////////////////////////////////
260 /// add emulated data
261 /// this used to place version or TObject raw data, read from normal tables
262 
263 void TSQLObjectData::AddUnpack(const char *tname, const char *value)
264 {
265  TNamed *str = new TNamed(tname, value);
266  if (fUnpack == 0) {
267  fUnpack = new TObjArray();
268  fBlobPrefixName = 0;
269  fBlobTypeName = str->GetName();
270  fLocatedValue = str->GetTitle();
271  }
272 
273  fUnpack->Add(str);
274 }
275 
276 ////////////////////////////////////////////////////////////////////////////////
277 /// emulate integer value in raw data
278 
279 void TSQLObjectData::AddUnpackInt(const char *tname, Int_t value)
280 {
281  TString sbuf;
282  sbuf.Form("%d", value);
283  AddUnpack(tname, sbuf.Data());
284 }
285 
286 ////////////////////////////////////////////////////////////////////////////////
287 /// shift to next column or next row in blob data
288 
290 {
291  Bool_t doshift = kTRUE;
292 
293  if (fUnpack != 0) {
294  TObject *prev = fUnpack->First();
295  fUnpack->Remove(prev);
296  delete prev;
297  fUnpack->Compress();
298  if (fUnpack->GetLast() >= 0) {
299  TNamed *curr = (TNamed *)fUnpack->First();
300  fBlobPrefixName = 0;
301  fBlobTypeName = curr->GetName();
302  fLocatedValue = curr->GetTitle();
303  return;
304  }
305  delete fUnpack;
306  fUnpack = 0;
307  doshift = kFALSE;
308  }
309 
310  if (fCurrentBlob) {
311  if (doshift)
312  ShiftBlobRow();
314  } else if (fClassData != 0) {
315  if (doshift)
316  fLocatedColumn++;
320  } else {
321  fLocatedField = 0;
322  fLocatedValue = 0;
323  }
324  }
325 }
326 
327 ////////////////////////////////////////////////////////////////////////////////
328 /// checks if data type corresponds to that stored in raw table
329 
330 Bool_t TSQLObjectData::VerifyDataType(const char *tname, Bool_t errormsg)
331 {
332  if (tname == 0) {
333  if (errormsg)
334  Error("VerifyDataType", "Data type not specified");
335  return kFALSE;
336  }
337 
338  // here maybe type of column can be checked
339  if (!IsBlobData())
340  return kTRUE;
341 
342  if (gDebug > 4)
343  if ((fBlobTypeName == 0) && errormsg) {
344  Error("VerifyDataType", "fBlobTypeName is null");
345  return kFALSE;
346  }
347 
349  TString v2(tname);
350 
351  // if (strcmp(fBlobTypeName,tname)!=0) {
352  if (v1 != v2) {
353  if (errormsg)
354  Error("VerifyDataType", "Data type missmatch %s - %s", fBlobTypeName, tname);
355  return kFALSE;
356  }
357 
358  return kTRUE;
359 }
360 
361 ////////////////////////////////////////////////////////////////////////////////
362 /// prepare to read data from raw table
363 
365 {
366  if (!ExtractBlobValues())
367  return kFALSE;
368 
370 
371  return kTRUE;
372 }
373 
374 //===================================================================================
375 
376 //________________________________________________________________________
377 //
378 // TSQLObjectDataPool contains list (pool) of data from single class table
379 // for differents objects, all belonging to the same key.
380 // This is typical situation when list of objects stored as single key.
381 // To optimize reading of such data, one query is submitted and results of that
382 // query kept in TSQLObjectDataPool object
383 //
384 //________________________________________________________________________
385 
387 
388 ////////////////////////////////////////////////////////////////////////////////
389 
390 TSQLObjectDataPool::TSQLObjectDataPool() : TObject(), fInfo(0), fClassData(0), fIsMoreRows(kTRUE), fRowsPool(0)
391 {
392 }
393 
394 ////////////////////////////////////////////////////////////////////////////////
395 
397  : TObject(), fInfo(info), fClassData(data), fIsMoreRows(kTRUE), fRowsPool(0)
398 {
399 }
400 
401 ////////////////////////////////////////////////////////////////////////////////
402 /// Destructor of TSQLObjectDataPool class
403 /// Deletes not used rows and class data table
404 
406 {
407  if (fClassData != 0)
408  delete fClassData;
409  if (fRowsPool != 0) {
410  fRowsPool->Delete();
411  delete fRowsPool;
412  }
413 }
414 
415 ////////////////////////////////////////////////////////////////////////////////
416 /// Returns single sql row with object data for that class
417 
419 {
420  if (fClassData == 0)
421  return 0;
422 
423  Long64_t rowid;
424 
425  if (fRowsPool != 0) {
426  TObjLink *link = fRowsPool->FirstLink();
427  while (link != 0) {
428  TSQLRow *row = (TSQLRow *)link->GetObject();
429  rowid = sqlio::atol64(row->GetField(0));
430  if (rowid == objid) {
431  fRowsPool->Remove(link);
432  return row;
433  }
434 
435  link = link->Next();
436  }
437  }
438 
439  while (fIsMoreRows) {
440  TSQLRow *row = fClassData->Next();
441  if (row == 0)
443  else {
444  rowid = sqlio::atol64(row->GetField(0));
445  if (rowid == objid)
446  return row;
447  if (fRowsPool == 0)
448  fRowsPool = new TList();
449  fRowsPool->Add(row);
450  }
451  }
452 
453  return 0;
454 }
Version_t fVersion
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
const char * fBlobPrefixName
! name prefix in current blob row
XML object keeper class.
An array of TObjects.
Definition: TObjArray.h:37
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:467
Info (classname, version) about object in database.
long long Long64_t
Definition: RtypesCore.h:69
void ShiftToNextValue()
shift to next column or next row in blob data
virtual ~TSQLObjectInfo()
short Version_t
Definition: RtypesCore.h:61
TSQLStatement * fBlobStmt
TSQLClassInfo * fInfo
! classinfo, for which pool is created
TSQLResult * fClassData
! results with request to selected table
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Definition: TObjArray.cxx:355
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:703
Contains information about tables specific to one class and version.
Definition: TSQLClassInfo.h:42
Basic string class.
Definition: TString.h:125
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TSQLObjectData()
default contrsuctor
const char * fLocatedValue
const char * fBlobTypeName
! name type (without prefix) in current blob row
Bool_t IsBlobData() const
TSQLClassInfo * fInfo
virtual const char * GetString(Int_t)
Definition: TSQLStatement.h:85
TSQLObjectData is used in TBufferSQL2 class in reading procedure.
Long64_t atol64(const char *value)
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
TSQLResult * fBlobData
Int_t GetNumClassFields()
return number of columns in class table result
virtual Bool_t NextResultRow()=0
virtual ~TSQLObjectData()
destructor of TSQLObjectData object
A doubly linked list.
Definition: TList.h:44
TObject * First() const
Return the object in the first slot.
Definition: TObjArray.cxx:495
virtual ~TSQLObjectDataPool()
Destructor of TSQLObjectDataPool class Deletes not used rows and class data table.
Int_t GetLast() const
Return index of last object in array.
Definition: TObjArray.cxx:561
Bool_t ShiftBlobRow()
shift cursor to next blob value
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:818
TString fClassName
Bool_t VerifyDataType(const char *tname, Bool_t errormsg=kTRUE)
checks if data type corresponds to that stored in raw table
TObjArray * fUnpack
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2343
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual const char * GetField(Int_t field)=0
virtual Int_t GetFieldCount()=0
Bool_t LocateColumn(const char *colname, Bool_t isblob=kFALSE)
locate column of that name in results
TSQLRow * GetObjectRow(Long64_t objid)
Returns single sql row with object data for that class.
virtual TObjLink * FirstLink() const
Definition: TList.h:108
const Bool_t kFALSE
Definition: RtypesCore.h:88
Bool_t PrepareForRawData()
prepare to read data from raw table
TSQLResult * fClassData
#define ClassImp(name)
Definition: Rtypes.h:359
void AddUnpack(const char *tname, const char *value)
add emulated data this used to place version or TObject raw data, read from normal tables ...
TList * fRowsPool
! pool of extrcted, but didnot used rows
Mother of all ROOT objects.
Definition: TObject.h:37
const char * GetClassFieldName(Int_t n)
get name of class table column
Bool_t ExtractBlobValues()
extract from curent blob row value and names identifiers
void AddUnpackInt(const char *tname, Int_t value)
emulate integer value in raw data
virtual void Add(TObject *obj)
Definition: TList.h:87
Bool_t fIsMoreRows
! indicates if class data has not yet read rows
TSQLRow * fClassRow
R__EXTERN Int_t gDebug
Definition: Rtypes.h:86
TSQLRow * fBlobRow
void Add(TObject *obj)
Definition: TObjArray.h:73
virtual const char * GetFieldName(Int_t field)=0
virtual void Compress()
Remove empty slots from array.
Definition: TObjArray.cxx:333
const Bool_t kTRUE
Definition: RtypesCore.h:87
Int_t FindColumn(const char *name, Bool_t sqlname=kFALSE)
Search for column of that name.
const Int_t n
Definition: legend1.C:16
const char * fLocatedField
char name[80]
Definition: TGX11.cxx:109
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual TSQLRow * Next()=0
const char * Data() const
Definition: TString.h:345