Logo ROOT  
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
16TSQLObjectData is used in TBufferSQL2 class in reading procedure.
17It contains data, request from database table for one specific
18object for one specific class. For instance, when data for
19class TH1 required, requests will be done to
20TH1_ver4 and TH1_raw4 tables and result of these requests
21will 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
38Info (classname, version) about object in database
39*/
40
42
43////////////////////////////////////////////////////////////////////////////////
44
45TSQLObjectInfo::TSQLObjectInfo() : TObject(), fObjId(0), fClassName(), fVersion(0)
46{
47}
48
49////////////////////////////////////////////////////////////////////////////////
50
51TSQLObjectInfo::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
63
64////////////////////////////////////////////////////////////////////////////////
65/// default constructor
66
68 : TObject(), fInfo(0), fObjId(0), fOwner(kFALSE), fClassData(0), fBlobData(0), fBlobStmt(0), fLocatedColumn(-1),
69 fClassRow(0), fBlobRow(0), fLocatedField(0), fLocatedValue(0), fCurrentBlob(kFALSE), fBlobPrefixName(0),
70 fBlobTypeName(0), fUnpack(0)
71{
72}
73
74////////////////////////////////////////////////////////////////////////////////
75/// normal constructor,
76
78 TSQLResult *blobdata, TSQLStatement *blobstmt)
79 : TObject(), fInfo(sqlinfo), fObjId(objid), fOwner(kFALSE), fClassData(classdata), fBlobData(blobdata),
80 fBlobStmt(blobstmt), fLocatedColumn(-1), fClassRow(classrow), fBlobRow(0), fLocatedField(0), fLocatedValue(0),
81 fCurrentBlob(kFALSE), fBlobPrefixName(0), fBlobTypeName(0), fUnpack(0)
82{
83 // take ownership if no special row from data pool is provided
84 if ((fClassData != 0) && (fClassRow == 0)) {
85 fOwner = kTRUE;
87 }
88
90}
91
92////////////////////////////////////////////////////////////////////////////////
93/// destructor of TSQLObjectData object
94
96{
97 if ((fClassData != 0) && fOwner)
98 delete fClassData;
99 if (fClassRow != 0)
100 delete fClassRow;
101 if (fBlobRow != 0)
102 delete fBlobRow;
103 if (fBlobData != 0)
104 delete fBlobData;
105 if (fUnpack != 0) {
106 fUnpack->Delete();
107 delete fUnpack;
108 }
109 if (fBlobStmt != 0)
110 delete fBlobStmt;
111}
112
113////////////////////////////////////////////////////////////////////////////////
114/// return number of columns in class table result
115
117{
118 if (fClassData != 0)
119 return fClassData->GetFieldCount();
120 return 0;
121}
122
123////////////////////////////////////////////////////////////////////////////////
124/// get name of class table column
125
127{
128 if (fClassData != 0)
129 return fClassData->GetFieldName(n);
130 return 0;
131}
132
133////////////////////////////////////////////////////////////////////////////////
134/// locate column of that name in results
135
136Bool_t TSQLObjectData::LocateColumn(const char *colname, Bool_t isblob)
137{
138 if (fUnpack != 0) {
139 fUnpack->Delete();
140 delete fUnpack;
141 fUnpack = 0;
142 }
143
144 fLocatedField = 0;
145 fLocatedValue = 0;
147
148 if ((fClassData == 0) || (fClassRow == 0))
149 return kFALSE;
150
151 // Int_t numfields = GetNumClassFields();
152
153 Int_t ncol = fInfo->FindColumn(colname, kFALSE);
154 if (ncol > 0) {
155 fLocatedColumn = ncol;
158 }
159
160 /* for (Int_t ncol=1;ncol<numfields;ncol++) {
161 const char* fieldname = GetClassFieldName(ncol);
162 if (strcmp(colname, fieldname)==0) {
163 fLocatedColumn = ncol;
164 fLocatedField = fieldname;
165 fLocatedValue = fClassRow->GetField(ncol);
166 break;
167 }
168 }
169 */
170
171 if (fLocatedField == 0)
172 return kFALSE;
173
174 if (!isblob)
175 return kTRUE;
176
177 if ((fBlobRow == 0) && (fBlobStmt == 0))
178 return kFALSE;
179
181
183
184 return kTRUE;
185}
186
187////////////////////////////////////////////////////////////////////////////////
188/// shift cursor to next blob value
189
191{
192 if (fBlobStmt != 0) {
194 if (!res) {
195 delete fBlobStmt;
196 fBlobStmt = 0;
197 }
198 return res;
199 }
200
201 delete fBlobRow;
202 fBlobRow = fBlobData ? fBlobData->Next() : 0;
203 return fBlobRow != 0;
204}
205
206////////////////////////////////////////////////////////////////////////////////
207/// extract from curent blob row value and names identifiers
208
210{
211 const char *name = 0;
212
213 Bool_t hasdata = kFALSE;
214
215 if (fBlobStmt != 0) {
218 hasdata = kTRUE;
219 }
220
221 if (!hasdata) {
222 if (fBlobRow != 0) {
224 name = fBlobRow->GetField(0);
225 }
226 }
227
228 if (name == 0) {
229 fBlobPrefixName = 0;
230 fBlobTypeName = 0;
231 return kFALSE;
232 }
233
234 const char *separ = strstr(name, ":"); // SQLNameSeparator()
235
236 if (separ == 0) {
237 fBlobPrefixName = 0;
239 } else {
241 separ += strlen(":"); // SQLNameSeparator()
242 fBlobTypeName = separ;
243 }
244
245 // if (gDebug>4)
246 // Info("ExtractBlobValues","Prefix:%s Type:%s",
247 // (fBlobPrefixName ? fBlobPrefixName : "null"),
248 // (fBlobTypeName ? fBlobTypeName : "null"));
249
250 return kTRUE;
251}
252
253////////////////////////////////////////////////////////////////////////////////
254/// add emulated data
255/// this used to place version or TObject raw data, read from normal tables
256
257void TSQLObjectData::AddUnpack(const char *tname, const char *value)
258{
259 TNamed *str = new TNamed(tname, value);
260 if (fUnpack == 0) {
261 fUnpack = new TObjArray();
262 fBlobPrefixName = 0;
263 fBlobTypeName = str->GetName();
264 fLocatedValue = str->GetTitle();
265 }
266
267 fUnpack->Add(str);
268}
269
270////////////////////////////////////////////////////////////////////////////////
271/// emulate integer value in raw data
272
273void TSQLObjectData::AddUnpackInt(const char *tname, Int_t value)
274{
275 TString sbuf;
276 sbuf.Form("%d", value);
277 AddUnpack(tname, sbuf.Data());
278}
279
280////////////////////////////////////////////////////////////////////////////////
281/// shift to next column or next row in blob data
282
284{
285 Bool_t doshift = kTRUE;
286
287 if (fUnpack != 0) {
288 TObject *prev = fUnpack->First();
289 fUnpack->Remove(prev);
290 delete prev;
291 fUnpack->Compress();
292 if (fUnpack->GetLast() >= 0) {
293 TNamed *curr = (TNamed *)fUnpack->First();
294 fBlobPrefixName = 0;
295 fBlobTypeName = curr->GetName();
296 fLocatedValue = curr->GetTitle();
297 return;
298 }
299 delete fUnpack;
300 fUnpack = 0;
301 doshift = kFALSE;
302 }
303
304 if (fCurrentBlob) {
305 if (doshift)
306 ShiftBlobRow();
308 } else if (fClassData != 0) {
309 if (doshift)
314 } else {
315 fLocatedField = 0;
316 fLocatedValue = 0;
317 }
318 }
319}
320
321////////////////////////////////////////////////////////////////////////////////
322/// checks if data type corresponds to that stored in raw table
323
324Bool_t TSQLObjectData::VerifyDataType(const char *tname, Bool_t errormsg)
325{
326 if (tname == 0) {
327 if (errormsg)
328 Error("VerifyDataType", "Data type not specified");
329 return kFALSE;
330 }
331
332 // here maybe type of column can be checked
333 if (!IsBlobData())
334 return kTRUE;
335
336 if (gDebug > 4)
337 if ((fBlobTypeName == 0) && errormsg) {
338 Error("VerifyDataType", "fBlobTypeName is null");
339 return kFALSE;
340 }
341
343 TString v2(tname);
344
345 // if (strcmp(fBlobTypeName,tname)!=0) {
346 if (v1 != v2) {
347 if (errormsg)
348 Error("VerifyDataType", "Data type missmatch %s - %s", fBlobTypeName, tname);
349 return kFALSE;
350 }
351
352 return kTRUE;
353}
354
355////////////////////////////////////////////////////////////////////////////////
356/// prepare to read data from raw table
357
359{
360 if (!ExtractBlobValues())
361 return kFALSE;
362
364
365 return kTRUE;
366}
367
368//===================================================================================
369
370//________________________________________________________________________
371//
372// TSQLObjectDataPool contains list (pool) of data from single class table
373// for differents objects, all belonging to the same key.
374// This is typical situation when list of objects stored as single key.
375// To optimize reading of such data, one query is submitted and results of that
376// query kept in TSQLObjectDataPool object
377//
378//________________________________________________________________________
379
381
382////////////////////////////////////////////////////////////////////////////////
383
384TSQLObjectDataPool::TSQLObjectDataPool() : TObject(), fInfo(0), fClassData(0), fIsMoreRows(kTRUE), fRowsPool(0)
385{
386}
387
388////////////////////////////////////////////////////////////////////////////////
389
391 : TObject(), fInfo(info), fClassData(data), fIsMoreRows(kTRUE), fRowsPool(0)
392{
393}
394
395////////////////////////////////////////////////////////////////////////////////
396/// Destructor of TSQLObjectDataPool class
397/// Deletes not used rows and class data table
398
400{
401 if (fClassData != 0)
402 delete fClassData;
403 if (fRowsPool != 0) {
404 fRowsPool->Delete();
405 delete fRowsPool;
406 }
407}
408
409////////////////////////////////////////////////////////////////////////////////
410/// Returns single sql row with object data for that class
411
413{
414 if (fClassData == 0)
415 return 0;
416
417 Long64_t rowid;
418
419 if (fRowsPool != 0) {
420 TObjLink *link = fRowsPool->FirstLink();
421 while (link != 0) {
422 TSQLRow *row = (TSQLRow *)link->GetObject();
423 rowid = sqlio::atol64(row->GetField(0));
424 if (rowid == objid) {
425 fRowsPool->Remove(link);
426 return row;
427 }
428
429 link = link->Next();
430 }
431 }
432
433 while (fIsMoreRows) {
434 TSQLRow *row = fClassData->Next();
435 if (row == 0)
437 else {
438 rowid = sqlio::atol64(row->GetField(0));
439 if (rowid == objid)
440 return row;
441 if (fRowsPool == 0)
442 fRowsPool = new TList();
443 fRowsPool->Add(row);
444 }
445 }
446
447 return 0;
448}
int Int_t
Definition: RtypesCore.h:45
short Version_t
Definition: RtypesCore.h:65
const Bool_t kFALSE
Definition: RtypesCore.h:101
bool Bool_t
Definition: RtypesCore.h:63
long long Long64_t
Definition: RtypesCore.h:80
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:364
char name[80]
Definition: TGX11.cxx:110
Int_t gDebug
Definition: TROOT.cxx:592
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:822
virtual TObjLink * FirstLink() const
Definition: TList.h:108
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:470
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
An array of TObjects.
Definition: TObjArray.h:37
void Add(TObject *obj)
Definition: TObjArray.h:74
virtual void Compress()
Remove empty slots from array.
Definition: TObjArray.cxx:334
TObject * First() const
Return the object in the first slot.
Definition: TObjArray.cxx:496
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Definition: TObjArray.cxx:356
Int_t GetLast() const
Return index of last object in array.
Definition: TObjArray.cxx:577
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:719
Mother of all ROOT objects.
Definition: TObject.h:37
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:893
Contains information about tables specific to one class and version.
Definition: TSQLClassInfo.h:41
Int_t FindColumn(const char *name, Bool_t sqlname=kFALSE)
Search for column of that name.
XML object keeper class.
TSQLRow * GetObjectRow(Long64_t objid)
Returns single sql row with object data for that class.
virtual ~TSQLObjectDataPool()
Destructor of TSQLObjectDataPool class Deletes not used rows and class data table.
TSQLResult * fClassData
! results with request to selected table
TList * fRowsPool
! pool of extracted, but didnot used rows
Bool_t fIsMoreRows
! indicates if class data has not yet read rows
TSQLObjectData is used in TBufferSQL2 class in reading procedure.
Bool_t LocateColumn(const char *colname, Bool_t isblob=kFALSE)
locate column of that name in results
TSQLStatement * fBlobStmt
TSQLObjectData()
default constructor
const char * fBlobPrefixName
! name prefix in current blob row
Bool_t ExtractBlobValues()
extract from curent blob row value and names identifiers
void ShiftToNextValue()
shift to next column or next row in blob data
Bool_t IsBlobData() const
virtual ~TSQLObjectData()
destructor of TSQLObjectData object
const char * GetClassFieldName(Int_t n)
get name of class table column
const char * fLocatedValue
TSQLRow * fClassRow
Bool_t ShiftBlobRow()
shift cursor to next blob value
void AddUnpack(const char *tname, const char *value)
add emulated data this used to place version or TObject raw data, read from normal tables
Int_t GetNumClassFields()
return number of columns in class table result
TSQLRow * fBlobRow
Bool_t PrepareForRawData()
prepare to read data from raw table
TObjArray * fUnpack
Bool_t VerifyDataType(const char *tname, Bool_t errormsg=kTRUE)
checks if data type corresponds to that stored in raw table
TSQLResult * fClassData
const char * fBlobTypeName
! name type (without prefix) in current blob row
void AddUnpackInt(const char *tname, Int_t value)
emulate integer value in raw data
const char * fLocatedField
TSQLClassInfo * fInfo
TSQLResult * fBlobData
Info (classname, version) about object in database.
virtual ~TSQLObjectInfo()
virtual const char * GetFieldName(Int_t field)=0
virtual TSQLRow * Next()=0
virtual Int_t GetFieldCount()=0
virtual const char * GetField(Int_t field)=0
virtual const char * GetString(Int_t)
Definition: TSQLStatement.h:87
virtual Bool_t NextResultRow()=0
Basic string class.
Definition: TString.h:136
const char * Data() const
Definition: TString.h:369
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2314
const Int_t n
Definition: legend1.C:16
Long64_t atol64(const char *value)