Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
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_SQL
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_SQL
38Info (classname, version) about object in database
39*/
40
41
42////////////////////////////////////////////////////////////////////////////////
43
47
48////////////////////////////////////////////////////////////////////////////////
49
50TSQLObjectInfo::TSQLObjectInfo(Long64_t objid, const char *classname, Version_t version)
51 : TObject(), fObjId(objid), fClassName(classname), fVersion(version)
52{
53}
54
55////////////////////////////////////////////////////////////////////////////////
56
60
61
62////////////////////////////////////////////////////////////////////////////////
63/// default constructor
64
66 : TObject(), fInfo(nullptr), fObjId(0), fOwner(kFALSE), fClassData(nullptr), fBlobData(nullptr), fBlobStmt(nullptr), fLocatedColumn(-1),
67 fClassRow(nullptr), fBlobRow(nullptr), fLocatedField(nullptr), fLocatedValue(nullptr), fCurrentBlob(kFALSE), fBlobPrefixName(nullptr),
68 fBlobTypeName(nullptr), fUnpack(nullptr)
69{
70}
71
72////////////////////////////////////////////////////////////////////////////////
73/// normal constructor,
74
76 TSQLResult *blobdata, TSQLStatement *blobstmt)
77 : TObject(), fInfo(sqlinfo), fObjId(objid), fOwner(kFALSE), fClassData(classdata), fBlobData(blobdata),
78 fBlobStmt(blobstmt), fLocatedColumn(-1), fClassRow(classrow), fBlobRow(nullptr), fLocatedField(nullptr), fLocatedValue(nullptr),
79 fCurrentBlob(kFALSE), fBlobPrefixName(nullptr), fBlobTypeName(nullptr), fUnpack(nullptr)
80{
81 // take ownership if no special row from data pool is provided
82 if (fClassData && !fClassRow) {
83 fOwner = kTRUE;
84 fClassRow = fClassData->Next();
85 }
86
88}
89
90////////////////////////////////////////////////////////////////////////////////
91/// destructor of TSQLObjectData object
92
94{
95 if (fClassData && fOwner)
96 delete fClassData;
97 if (fClassRow)
98 delete fClassRow;
99 if (fBlobRow)
100 delete fBlobRow;
101 if (fBlobData)
102 delete fBlobData;
103 if (fUnpack) {
104 fUnpack->Delete();
105 delete fUnpack;
106 }
107 if (fBlobStmt)
108 delete fBlobStmt;
109}
110
111////////////////////////////////////////////////////////////////////////////////
112/// return number of columns in class table result
113
115{
116 if (fClassData)
117 return fClassData->GetFieldCount();
118 return 0;
119}
120
121////////////////////////////////////////////////////////////////////////////////
122/// get name of class table column
123
125{
126 if (fClassData)
127 return fClassData->GetFieldName(n);
128 return nullptr;
129}
130
131////////////////////////////////////////////////////////////////////////////////
132/// locate column of that name in results
133
134Bool_t TSQLObjectData::LocateColumn(const char *colname, Bool_t isblob)
135{
136 if (fUnpack) {
137 fUnpack->Delete();
138 delete fUnpack;
139 fUnpack = nullptr;
140 }
141
142 fLocatedField = nullptr;
143 fLocatedValue = nullptr;
145
146 if (!fClassData || !fClassRow)
147 return kFALSE;
148
149 // Int_t numfields = GetNumClassFields();
150
151 Int_t ncol = fInfo->FindColumn(colname, kFALSE);
152 if (ncol > 0) {
153 fLocatedColumn = ncol;
155 fLocatedValue = fClassRow->GetField(ncol);
156 }
157
158 /* for (Int_t ncol=1;ncol<numfields;ncol++) {
159 const char* fieldname = GetClassFieldName(ncol);
160 if (strcmp(colname, fieldname)==0) {
161 fLocatedColumn = ncol;
162 fLocatedField = fieldname;
163 fLocatedValue = fClassRow->GetField(ncol);
164 break;
165 }
166 }
167 */
168
169 if (!fLocatedField)
170 return kFALSE;
171
172 if (!isblob)
173 return kTRUE;
174
175 if (!fBlobRow && !fBlobStmt)
176 return kFALSE;
177
179
181
182 return kTRUE;
183}
184
185////////////////////////////////////////////////////////////////////////////////
186/// shift cursor to next blob value
187
189{
190 if (fBlobStmt) {
191 Bool_t res = fBlobStmt->NextResultRow();
192 if (!res) {
193 delete fBlobStmt;
194 fBlobStmt = nullptr;
195 }
196 return res;
197 }
198
199 delete fBlobRow;
200 fBlobRow = fBlobData ? fBlobData->Next() : nullptr;
201 return fBlobRow != nullptr;
202}
203
204////////////////////////////////////////////////////////////////////////////////
205/// extract from curent blob row value and names identifiers
206
208{
209 const char *name = nullptr;
210
211 Bool_t hasdata = kFALSE;
212
213 if (fBlobStmt) {
214 name = fBlobStmt->GetString(0);
215 fLocatedValue = fBlobStmt->GetString(1);
216 hasdata = kTRUE;
217 }
218
219 if (!hasdata) {
220 if (fBlobRow) {
221 fLocatedValue = fBlobRow->GetField(1);
222 name = fBlobRow->GetField(0);
223 }
224 }
225
226 if (!name) {
227 fBlobPrefixName = nullptr;
228 fBlobTypeName = nullptr;
229 return kFALSE;
230 }
231
232 const char *separ = strstr(name, ":"); // SQLNameSeparator()
233
234 if (!separ) {
235 fBlobPrefixName = nullptr;
237 } else {
239 separ += std::char_traits<char>::length(":"); // SQLNameSeparator()
240 fBlobTypeName = separ;
241 }
242
243 // if (gDebug>4)
244 // Info("ExtractBlobValues","Prefix:%s Type:%s",
245 // (fBlobPrefixName ? fBlobPrefixName : "null"),
246 // (fBlobTypeName ? fBlobTypeName : "null"));
247
248 return kTRUE;
249}
250
251////////////////////////////////////////////////////////////////////////////////
252/// add emulated data
253/// this used to place version or TObject raw data, read from normal tables
254
255void TSQLObjectData::AddUnpack(const char *tname, const char *value)
256{
257 TNamed *str = new TNamed(tname, value);
258 if (!fUnpack) {
259 fUnpack = new TObjArray();
260 fBlobPrefixName = nullptr;
261 fBlobTypeName = str->GetName();
262 fLocatedValue = str->GetTitle();
263 }
264
265 fUnpack->Add(str);
266}
267
268////////////////////////////////////////////////////////////////////////////////
269/// emulate integer value in raw data
270
271void TSQLObjectData::AddUnpackInt(const char *tname, Int_t value)
272{
273 TString sbuf;
274 sbuf.Form("%d", value);
275 AddUnpack(tname, sbuf.Data());
276}
277
278////////////////////////////////////////////////////////////////////////////////
279/// shift to next column or next row in blob data
280
282{
283 Bool_t doshift = kTRUE;
284
285 if (fUnpack) {
286 TObject *prev = fUnpack->First();
287 fUnpack->Remove(prev);
288 delete prev;
289 fUnpack->Compress();
290 if (fUnpack->GetLast() >= 0) {
291 TNamed *curr = (TNamed *)fUnpack->First();
292 fBlobPrefixName = nullptr;
293 fBlobTypeName = curr->GetName();
294 fLocatedValue = curr->GetTitle();
295 return;
296 }
297 delete fUnpack;
298 fUnpack = nullptr;
299 doshift = kFALSE;
300 }
301
302 if (fCurrentBlob) {
303 if (doshift)
304 ShiftBlobRow();
306 } else if (fClassData) {
307 if (doshift)
312 } else {
313 fLocatedField = nullptr;
314 fLocatedValue = nullptr;
315 }
316 }
317}
318
319////////////////////////////////////////////////////////////////////////////////
320/// checks if data type corresponds to that stored in raw table
321
322Bool_t TSQLObjectData::VerifyDataType(const char *tname, Bool_t errormsg)
323{
324 if (!tname) {
325 if (errormsg)
326 Error("VerifyDataType", "Data type not specified");
327 return kFALSE;
328 }
329
330 // here maybe type of column can be checked
331 if (!IsBlobData())
332 return kTRUE;
333
334 if (gDebug > 4)
335 if (!fBlobTypeName && errormsg) {
336 Error("VerifyDataType", "fBlobTypeName is null");
337 return kFALSE;
338 }
339
341 TString v2(tname);
342
343 // if (strcmp(fBlobTypeName,tname)!=0) {
344 if (v1 != v2) {
345 if (errormsg)
346 Error("VerifyDataType", "Data type mismatch %s - %s", fBlobTypeName, tname);
347 return kFALSE;
348 }
349
350 return kTRUE;
351}
352
353////////////////////////////////////////////////////////////////////////////////
354/// prepare to read data from raw table
355
357{
358 if (!ExtractBlobValues())
359 return kFALSE;
360
362
363 return kTRUE;
364}
365
366//===================================================================================
367
368//________________________________________________________________________
369//
370// TSQLObjectDataPool contains list (pool) of data from single class table
371// for differents objects, all belonging to the same key.
372// This is typical situation when list of objects stored as single key.
373// To optimize reading of such data, one query is submitted and results of that
374// query kept in TSQLObjectDataPool object
375//
376//________________________________________________________________________
377
378
379////////////////////////////////////////////////////////////////////////////////
380
384
385////////////////////////////////////////////////////////////////////////////////
386
391
392////////////////////////////////////////////////////////////////////////////////
393/// Destructor of TSQLObjectDataPool class
394/// Deletes not used rows and class data table
395
397{
398 if (fClassData)
399 delete fClassData;
400 if (fRowsPool) {
401 fRowsPool->Delete();
402 delete fRowsPool;
403 }
404}
405
406////////////////////////////////////////////////////////////////////////////////
407/// Returns single sql row with object data for that class
408
410{
411 if (!fClassData)
412 return nullptr;
413
414 Long64_t rowid;
415
416 if (fRowsPool) {
417 TObjLink *link = fRowsPool->FirstLink();
418 while (link) {
419 TSQLRow *row = (TSQLRow *)link->GetObject();
420 rowid = sqlio::atol64(row->GetField(0));
421 if (rowid == objid) {
422 fRowsPool->Remove(link);
423 return row;
424 }
425
426 link = link->Next();
427 }
428 }
429
430 while (fIsMoreRows) {
431 TSQLRow *row = fClassData->Next();
432 if (!row)
434 else {
435 rowid = sqlio::atol64(row->GetField(0));
436 if (rowid == objid)
437 return row;
438 if (!fRowsPool)
439 fRowsPool = new TList();
440 fRowsPool->Add(row);
441 }
442 }
443
444 return nullptr;
445}
int Int_t
Signed integer 4 bytes (int).
Definition RtypesCore.h:59
short Version_t
Class version identifier (short).
Definition RtypesCore.h:79
bool Bool_t
Boolean (0=false, 1=true) (bool).
Definition RtypesCore.h:77
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:83
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
char name[80]
Definition TGX11.cxx:148
Int_t gDebug
Definition TROOT.cxx:777
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
An array of TObjects.
Definition TObjArray.h:31
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1098
TObject()
TObject constructor.
Definition TObject.h:259
Contains information about tables specific to one class and version.
TSQLRow * GetObjectRow(Long64_t objid)
Returns single sql row with object data for that class.
TSQLResult * fClassData
! results with request to selected table
TList * fRowsPool
! pool of extracted, but didnot used rows
~TSQLObjectDataPool() override
Destructor of TSQLObjectDataPool class Deletes not used rows and class data table.
Bool_t fIsMoreRows
! indicates if class data has not yet read rows
TSQLClassInfo * fInfo
! classinfo, for which pool is created
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
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
~TSQLObjectData() override
destructor of TSQLObjectData object
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
!
Version_t fVersion
~TSQLObjectInfo() override
Basic string class.
Definition TString.h:138
const char * Data() const
Definition TString.h:384
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2363
const Int_t n
Definition legend1.C:16
Long64_t atol64(const char *value)