TSQLObjectData.cxx

Go to the documentation of this file.
00001 // @(#)root/sql:$Id: TSQLObjectData.cxx 20882 2007-11-19 11:31:26Z rdm $
00002 // Author: Sergey Linev  20/11/2005
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //________________________________________________________________________
00013 //
00014 // TSQLObjectData is used in TBufferSQL2 class in reading procedure.
00015 // It contains data, request from database table for one specifc
00016 // object for one specific class. For instance, when data for
00017 // class TH1 required, requests will be done to
00018 // TH1_ver4 and TH1_raw4 tables and result of these requests
00019 // will be kept in single TSQLObjectData instance.
00020 //
00021 //________________________________________________________________________
00022 
00023 #include "TSQLObjectData.h"
00024 
00025 #include "TObjArray.h"
00026 #include "TNamed.h"
00027 #include "TList.h"
00028 #include "TSQLRow.h"
00029 #include "TSQLResult.h"
00030 #include "TSQLClassInfo.h"
00031 #include "TSQLStructure.h"
00032 #include "TSQLStatement.h"
00033 
00034 ClassImp(TSQLObjectInfo)
00035 
00036 //________________________________________________________________________
00037 TSQLObjectInfo::TSQLObjectInfo() :
00038    TObject(),
00039    fObjId(0),
00040    fClassName(),
00041    fVersion(0)
00042 {
00043 }
00044 
00045 //________________________________________________________________________
00046 TSQLObjectInfo::TSQLObjectInfo(Long64_t objid, const char* classname, Version_t version) :
00047    TObject(),
00048    fObjId(objid),
00049    fClassName(classname),
00050    fVersion(version)
00051 {
00052 }
00053 
00054 //________________________________________________________________________
00055 TSQLObjectInfo::~TSQLObjectInfo()
00056 {
00057 }
00058 
00059 
00060 
00061 ClassImp(TSQLObjectData)
00062 
00063 //________________________________________________________________________
00064 TSQLObjectData::TSQLObjectData() :
00065       TObject(),
00066       fInfo(0),
00067       fObjId(0),
00068       fOwner(kFALSE),
00069       fClassData(0),
00070       fBlobData(0),
00071       fBlobStmt(0),
00072       fLocatedColumn(-1),
00073       fClassRow(0),
00074       fBlobRow(0),
00075       fLocatedField(0),
00076       fLocatedValue(0),
00077       fCurrentBlob(kFALSE),
00078       fBlobPrefixName(0),
00079       fBlobTypeName(0),
00080       fUnpack(0)
00081 {
00082    // default contrsuctor
00083 }
00084 
00085 //______________________________________________________________________________
00086 TSQLObjectData::TSQLObjectData(TSQLClassInfo* sqlinfo,
00087                                Long64_t       objid,
00088                                TSQLResult*    classdata,
00089                                TSQLRow*       classrow,
00090                                TSQLResult*    blobdata,
00091                                TSQLStatement* blobstmt) :
00092    TObject(),
00093    fInfo(sqlinfo),
00094    fObjId(objid),
00095    fOwner(kFALSE),
00096    fClassData(classdata),
00097    fBlobData(blobdata),
00098    fBlobStmt(blobstmt),
00099    fLocatedColumn(-1),
00100    fClassRow(classrow),
00101    fBlobRow(0),
00102    fLocatedField(0),
00103    fLocatedValue(0),
00104    fCurrentBlob(kFALSE),
00105    fBlobPrefixName(0),
00106    fBlobTypeName(0),
00107    fUnpack(0)
00108 {
00109    // normal contrsuctor,
00110 
00111    // take ownership if no special row from data pool is provided
00112    if ((fClassData!=0) && (fClassRow==0)) {
00113       fOwner = kTRUE;
00114       fClassRow = fClassData->Next();
00115    }
00116 
00117    ShiftBlobRow();
00118 }
00119 
00120 //______________________________________________________________________________
00121 TSQLObjectData::~TSQLObjectData()
00122 {
00123    // destructor of TSQLObjectData object
00124 
00125    if ((fClassData!=0) && fOwner) delete fClassData;
00126    if (fClassRow!=0) delete fClassRow;
00127    if (fBlobRow!=0) delete fBlobRow;
00128    if (fBlobData!=0) delete fBlobData;
00129    if (fUnpack!=0) { fUnpack->Delete(); delete fUnpack; }
00130    if (fBlobStmt!=0) delete fBlobStmt;
00131 }
00132 
00133 //______________________________________________________________________________
00134 Int_t TSQLObjectData::GetNumClassFields()
00135 {
00136    // return number of columns in class table result
00137 
00138    if (fClassData!=0) return fClassData->GetFieldCount();
00139    return 0;
00140 }
00141 
00142 //______________________________________________________________________________
00143 const char* TSQLObjectData::GetClassFieldName(Int_t n)
00144 {
00145    // get name of class table column
00146 
00147    if (fClassData!=0) return fClassData->GetFieldName(n);
00148    return 0;
00149 }
00150 
00151 //______________________________________________________________________________
00152 Bool_t TSQLObjectData::LocateColumn(const char* colname, Bool_t isblob)
00153 {
00154    // locate column of that name in results
00155 
00156    if (fUnpack!=0) {
00157       fUnpack->Delete();
00158       delete fUnpack;
00159       fUnpack = 0;
00160    }
00161 
00162    fLocatedField = 0;
00163    fLocatedValue = 0;
00164    fCurrentBlob = kFALSE;
00165 
00166    if ((fClassData==0) || (fClassRow==0)) return kFALSE;
00167 
00168 //   Int_t numfields = GetNumClassFields();
00169 
00170    Int_t ncol = fInfo->FindColumn(colname, kFALSE);
00171    if (ncol>0) {
00172       fLocatedColumn = ncol;
00173       fLocatedField = GetClassFieldName(ncol);
00174       fLocatedValue = fClassRow->GetField(ncol);
00175    }
00176   
00177 
00178 /*   for (Int_t ncol=1;ncol<numfields;ncol++) {
00179       const char* fieldname = GetClassFieldName(ncol);
00180       if (strcmp(colname, fieldname)==0) {
00181          fLocatedColumn = ncol;
00182          fLocatedField = fieldname;
00183          fLocatedValue = fClassRow->GetField(ncol);
00184          break;
00185       }
00186    }
00187 */
00188 
00189    if (fLocatedField==0) return kFALSE;
00190 
00191    if (!isblob) return kTRUE;
00192 
00193    if ((fBlobRow==0) && (fBlobStmt==0)) return kFALSE;
00194 
00195    fCurrentBlob = kTRUE;
00196 
00197    ExtractBlobValues();
00198 
00199    return kTRUE;
00200 }
00201 
00202 //______________________________________________________________________________
00203 Bool_t TSQLObjectData::ShiftBlobRow()
00204 {
00205    // shift cursor to next blob value 
00206     
00207    if (fBlobStmt!=0) {
00208       Bool_t res = fBlobStmt->NextResultRow();
00209       if (!res) { delete fBlobStmt; fBlobStmt = 0; }
00210       return res;
00211    }
00212    
00213    delete fBlobRow;
00214    fBlobRow = fBlobData ? fBlobData->Next() : 0;
00215    return fBlobRow!=0;
00216 }
00217 
00218 //______________________________________________________________________________
00219 Bool_t TSQLObjectData::ExtractBlobValues()
00220 {
00221    // extract from curent blob row value and names identifiers
00222 
00223    const char* name = 0;
00224    
00225    Bool_t hasdata = kFALSE;
00226 
00227    if (fBlobStmt!=0) {
00228       name = fBlobStmt->GetString(0);
00229       fLocatedValue = fBlobStmt->GetString(1);
00230       hasdata = kTRUE;
00231    }
00232 
00233    if (!hasdata) {
00234       if (fBlobRow!=0) {
00235          fLocatedValue = fBlobRow->GetField(1);
00236          name = fBlobRow->GetField(0);
00237       }
00238    }
00239    
00240    if (name==0) {
00241       fBlobPrefixName = 0;
00242       fBlobTypeName = 0; 
00243       return kFALSE;
00244    }
00245    
00246    const char* separ = strstr(name, ":"); //SQLNameSeparator()
00247 
00248    if (separ==0) {
00249       fBlobPrefixName = 0;
00250       fBlobTypeName = name;
00251    } else {
00252       fBlobPrefixName = name;
00253       separ+=strlen(":"); //SQLNameSeparator()
00254       fBlobTypeName = separ;
00255    }
00256 
00257 //   if (gDebug>4)
00258 //      Info("ExtractBlobValues","Prefix:%s Type:%s",
00259 //            (fBlobPrefixName ? fBlobPrefixName : "null"),
00260 //            (fBlobTypeName ? fBlobTypeName : "null"));
00261 
00262    return kTRUE;
00263 }
00264 
00265 //______________________________________________________________________________
00266 void TSQLObjectData::AddUnpack(const char* tname, const char* value)
00267 {
00268    // add emulated data
00269    // this used to place version or TObject raw data, read from normal tables
00270 
00271    TNamed* str = new TNamed(tname, value);
00272    if (fUnpack==0) {
00273       fUnpack = new TObjArray();
00274       fBlobPrefixName = 0;
00275       fBlobTypeName = str->GetName();
00276       fLocatedValue = str->GetTitle();
00277    }
00278 
00279    fUnpack->Add(str);
00280 }
00281 
00282 //______________________________________________________________________________
00283 void TSQLObjectData::AddUnpackInt(const char* tname, Int_t value)
00284 {
00285    // emulate integer value in raw data
00286 
00287    TString sbuf;
00288    sbuf.Form("%d", value);
00289    AddUnpack(tname, sbuf.Data());
00290 }
00291 
00292 //______________________________________________________________________________
00293 void TSQLObjectData::ShiftToNextValue()
00294 {
00295    // shift to next column or next row in blob data
00296 
00297    Bool_t doshift = kTRUE;
00298 
00299    if (fUnpack!=0) {
00300       TObject* prev = fUnpack->First();
00301       fUnpack->Remove(prev);
00302       delete prev;
00303       fUnpack->Compress();
00304       if (fUnpack->GetLast()>=0) {
00305          TNamed* curr = (TNamed*) fUnpack->First();
00306          fBlobPrefixName = 0;
00307          fBlobTypeName = curr->GetName();
00308          fLocatedValue = curr->GetTitle();
00309          return;
00310       }
00311       delete fUnpack;
00312       fUnpack = 0;
00313       doshift = kFALSE;
00314    }
00315 
00316    if (fCurrentBlob) {
00317       if (doshift) ShiftBlobRow();
00318       ExtractBlobValues();
00319    } else
00320       if (fClassData!=0) {
00321          if (doshift) fLocatedColumn++;
00322          if (fLocatedColumn<GetNumClassFields()) {
00323             fLocatedField = GetClassFieldName(fLocatedColumn);
00324             fLocatedValue = fClassRow->GetField(fLocatedColumn);
00325          } else {
00326             fLocatedField = 0;
00327             fLocatedValue = 0;
00328          }
00329       }
00330 }
00331 
00332 //______________________________________________________________________________
00333 Bool_t TSQLObjectData::VerifyDataType(const char* tname, Bool_t errormsg)
00334 {
00335    // checks if data type corresponds to that stored in raw table
00336 
00337    if (tname==0) {
00338       if (errormsg)
00339          Error("VerifyDataType","Data type not specified");
00340       return kFALSE;
00341    }
00342 
00343    // here maybe type of column can be checked
00344    if (!IsBlobData()) return kTRUE;
00345 
00346    if (gDebug>4) 
00347       if ((fBlobTypeName==0) && errormsg) {
00348          Error("VerifyDataType","fBlobTypeName is null");
00349          return kFALSE;
00350       }
00351 
00352 
00353    TString v1(fBlobTypeName);
00354    TString v2(tname);
00355 
00356 //   if (strcmp(fBlobTypeName,tname)!=0) {
00357    if (v1!=v2) { 
00358       if (errormsg)
00359          Error("VerifyDataType","Data type missmatch %s - %s", fBlobTypeName, tname);
00360       return kFALSE;
00361    }
00362 
00363    return kTRUE;
00364 }
00365 
00366 //______________________________________________________________________________
00367 Bool_t TSQLObjectData::PrepareForRawData()
00368 {
00369    // prepare to read data from raw table
00370 
00371    if (!ExtractBlobValues()) return kFALSE;
00372 
00373    fCurrentBlob = kTRUE;
00374 
00375    return kTRUE;
00376 }
00377 
00378 //===================================================================================
00379 
00380 //________________________________________________________________________
00381 //
00382 // TSQLObjectDataPool contains list (pool) of data from single class table 
00383 // for differents objects, all belonging to the same key.
00384 // This is typical situation when list of objects stored as single key.
00385 // To optimize reading of such data, one query is submitted and results of that
00386 // query kept in TSQLObjectDataPool object
00387 //
00388 //________________________________________________________________________
00389 
00390 
00391 ClassImp(TSQLObjectDataPool);
00392 
00393 //______________________________________________________________________________
00394 TSQLObjectDataPool::TSQLObjectDataPool() :
00395    TObject(),
00396    fInfo(0),
00397    fClassData(0),
00398    fIsMoreRows(kTRUE),
00399    fRowsPool(0)
00400 {
00401 }
00402 
00403 //______________________________________________________________________________
00404 TSQLObjectDataPool::TSQLObjectDataPool(TSQLClassInfo* info, TSQLResult* data) :
00405    TObject(),
00406    fInfo(info),
00407    fClassData(data),
00408    fIsMoreRows(kTRUE),
00409    fRowsPool(0)
00410 {
00411 }
00412 
00413 //______________________________________________________________________________
00414 TSQLObjectDataPool::~TSQLObjectDataPool()
00415 {
00416    // Destructor of TSQLObjectDataPool class
00417    // Deletes not used rows and class data table
00418    
00419    if (fClassData!=0) delete fClassData;
00420    if (fRowsPool!=0) {
00421       fRowsPool->Delete();
00422       delete fRowsPool;
00423    }
00424 }
00425 
00426 //______________________________________________________________________________
00427 TSQLRow* TSQLObjectDataPool::GetObjectRow(Long64_t objid)
00428 {
00429    // Returns single sql row with object data for that class
00430    
00431    if (fClassData==0) return 0;
00432    
00433    Long64_t rowid;
00434          
00435    if (fRowsPool!=0) {
00436       TObjLink* link = fRowsPool->FirstLink();
00437       while (link!=0) {
00438          TSQLRow* row = (TSQLRow*) link->GetObject();
00439          rowid = sqlio::atol64(row->GetField(0));
00440          if (rowid==objid) {
00441             fRowsPool->Remove(link);   
00442             return row;
00443          }
00444          
00445          link = link->Next();   
00446       }
00447    }
00448    
00449    while (fIsMoreRows) {
00450       TSQLRow* row = fClassData->Next();
00451       if (row==0) 
00452          fIsMoreRows = kFALSE; 
00453       else {
00454          rowid = sqlio::atol64(row->GetField(0));
00455          if (rowid==objid) return row;
00456          if (fRowsPool==0) fRowsPool = new TList();
00457          fRowsPool->Add(row);
00458       }
00459    }
00460    
00461    return 0;
00462 }
00463   

Generated on Tue Jul 5 14:30:32 2011 for ROOT_528-00b_version by  doxygen 1.5.1