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
62/**
63\class TSQLObjectData
64\ingroup IO
65Keeps 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),
87 fCurrentBlob(kFALSE), fBlobPrefixName(0), fBlobTypeName(0), fUnpack(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
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
142Bool_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) {
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) {
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
263void 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
279void 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)
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
330Bool_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
390TSQLObjectDataPool::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}
int Int_t
Definition: RtypesCore.h:43
short Version_t
Definition: RtypesCore.h:63
const Bool_t kFALSE
Definition: RtypesCore.h:90
bool Bool_t
Definition: RtypesCore.h:61
R__EXTERN Int_t gDebug
Definition: RtypesCore.h:117
long long Long64_t
Definition: RtypesCore.h:71
const Bool_t kTRUE
Definition: RtypesCore.h:89
#define ClassImp(name)
Definition: Rtypes.h:361
char name[80]
Definition: TGX11.cxx:109
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:821
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:469
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:891
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 contrsuctor
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:131
const char * Data() const
Definition: TString.h:364
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
const Int_t n
Definition: legend1.C:16
Long64_t atol64(const char *value)