TTreeSQL.cxx

Go to the documentation of this file.
00001 // @(#)root/tree:$Id: TTreeSQL.cxx 38206 2011-02-24 18:17:23Z pcanal $
00002 // Author: Philippe Canal and al. 08/2004
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, 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 // TTreeSQL                                                             //
00015 //                                                                      //
00016 // Implement TTree for a SQL backend                                    //
00017 //                                                                      //
00018 //////////////////////////////////////////////////////////////////////////
00019 
00020 #include <Riostream.h>
00021 #include <vector>
00022 #include <map>
00023 #include <stdlib.h>
00024 
00025 #include "TString.h"
00026 #include "TROOT.h"
00027 #include "TSystem.h"
00028 #include "TError.h"
00029 #include "TFile.h"
00030 #include "TTree.h"
00031 #include "TLeaf.h"
00032 #include "TBranch.h"
00033 
00034 #include "TSQLRow.h"
00035 #include "TSQLResult.h"
00036 #include "TSQLServer.h"
00037 
00038 #include "TTreeSQL.h"
00039 #include "TBasketSQL.h"
00040 
00041 ClassImp(TTreeSQL)
00042 
00043 //______________________________________________________________________________
00044 TTreeSQL::TTreeSQL(TSQLServer *server, TString DB, const TString& table) :
00045    TTree(table.Data(), "Database read from table: " + table, 0), fDB(DB),
00046    fTable(table.Data()),
00047    fResult(0), fRow(0),
00048    fServer(server),
00049    fBranchChecked(kFALSE)
00050 {
00051    // Constructor with an explicit TSQLServer
00052 
00053    fCurrentEntry = -1;
00054    fQuery = TString("Select * from " + fTable);
00055    fEntries = 0;
00056 
00057    if (fServer==0) {
00058       Error("TTreeSQL","No TSQLServer specified");
00059       return;
00060    }
00061    if (CheckTable(fTable.Data())) {
00062       Init();
00063    }
00064 }
00065 
00066 //______________________________________________________________________________
00067 TBranch* TTreeSQL::BranchImp(const char *, const char *,
00068                              TClass *, void *, Int_t ,
00069                              Int_t )
00070 {
00071    // Not implemented yet
00072 
00073    Fatal("BranchImp","Not implemented yet");
00074    return 0;
00075 }
00076 
00077 //______________________________________________________________________________
00078 TBranch* TTreeSQL::BranchImp(const char *, TClass *,
00079                              void *, Int_t , Int_t )
00080 {
00081    // Not implemented yet
00082 
00083    Fatal("BranchImp","Not implemented yet");
00084    return 0;
00085 }
00086 
00087 //______________________________________________________________________________
00088 Int_t TTreeSQL::Branch(TCollection *, Int_t,
00089                        Int_t, const char *)
00090 {
00091    // Not implemented yet
00092 
00093    Fatal("Branch","Not implemented yet");
00094    return 0;
00095 }
00096 
00097 //______________________________________________________________________________
00098 Int_t TTreeSQL::Branch(TList *, Int_t, Int_t)
00099 {
00100    // Not implemented yet
00101 
00102    Fatal("Branch","Not implemented yet");
00103    return 0;
00104 }
00105 
00106 //______________________________________________________________________________
00107 Int_t TTreeSQL::Branch(const char *, Int_t ,
00108                        Int_t)
00109 {
00110    // Not implemented yet
00111 
00112    Fatal("Branch","Not implemented yet");
00113    return 0;
00114 }
00115 
00116 //______________________________________________________________________________
00117 TBranch* TTreeSQL::Bronch(const char *, const char *, void *,
00118                           Int_t, Int_t)
00119 {
00120    // Not implemented yet
00121 
00122    Fatal("Bronc","Not implemented yet");
00123    return 0;
00124 }
00125 
00126 //______________________________________________________________________________
00127 TBranch* TTreeSQL::BranchOld(const char *, const char *,
00128                              void *, Int_t, Int_t)
00129 {
00130    // Not implemented yet
00131 
00132    Fatal("BranchOld","Not implemented yet");
00133    return 0;
00134 }
00135 
00136 //______________________________________________________________________________
00137 TBranch *TTreeSQL::Branch(const char *, const char *, void *,
00138                           Int_t, Int_t)
00139 {
00140    // Not implemented yet
00141 
00142    Fatal("Branch","Not implemented yet");
00143    return 0;
00144 }
00145 
00146 //______________________________________________________________________________
00147 TBranch * TTreeSQL::Branch(const char *name, void *address,
00148                            const char *leaflist, Int_t bufsize)
00149 {
00150    // Create a branch
00151 
00152    Int_t nb = fBranches.GetEntriesFast();
00153    TBranch *branch;
00154    TString brName;
00155 
00156    for (int i=0;i<nb;i++) {
00157       branch = (TBranch*)fBranches.UncheckedAt(i);
00158       brName = branch->GetName();
00159       if (brName.Index(name) == 0) {
00160          // Now if the branch exists in db, root gives a warning and exit
00161          // Dealing with duplicate branch has been done, but not tested yet.
00162          // So if you want to allow duplicate branch, just comment Fatal() line and uncomment commented
00163          // below Fatal() line
00164 
00165          Fatal("Branch()", "Duplicate branch!!!");
00166 
00167          /* Commented. If uncommented, should comment Fatal line.
00168          // this is a duplicate branch. So reset data structure memory address and return.
00169          branch->SetAddress(address);
00170          return branch;
00171          */
00172       }
00173    }
00174    return TTree::Branch(name, address, leaflist, bufsize);
00175 }
00176 
00177 //______________________________________________________________________________
00178 void TTreeSQL::CheckBasket(TBranch *branch)
00179 {
00180    // Check if the basket is properly setup
00181 
00182    TBasketSQL* basket = (TBasketSQL *)branch->GetBasket(0);
00183 
00184    if (basket==0) {
00185       basket = (TBasketSQL*)CreateBasket(branch);
00186       if (basket==0) return;
00187       //++(branch->fNBaskets);
00188       branch->GetListOfBaskets()->AddAtAndExpand(basket,0);
00189    }
00190    TBuffer * buffer = basket->GetBufferRef();
00191 
00192    if(buffer == 0){
00193       vector<Int_t> *columns = GetColumnIndice(branch);
00194       if (columns) basket->CreateBuffer(branch->GetName(),"A", columns, branch, &fResult);
00195    }
00196 
00197    Int_t nb = branch->GetListOfBranches()->GetEntriesFast();
00198    for (int i=0;i<nb;i++) {
00199       TBranch * subbranch = (TBranch*)branch->GetListOfBranches()->UncheckedAt(i);
00200       if(subbranch) CheckBasket(subbranch);
00201    }
00202 }
00203 
00204 //______________________________________________________________________________
00205 Bool_t TTreeSQL::CheckBranch(TBranch * tb)
00206 {
00207    // Check if the table has a column corresponding the branch
00208    // and that the resultset are properly setup
00209 
00210    if (fServer==0) {
00211       return kFALSE;
00212    }
00213    TString leafName;
00214    TLeaf *leaf;
00215    Int_t nl;
00216    TString str = "";
00217    TString typeName = "";
00218 
00219    if (!tb) return kFALSE;
00220 
00221    TBasketSQL *basket = (TBasketSQL *)tb->GetBasket(0);
00222    if (!basket) return kFALSE;
00223 
00224    TSQLResult *rs = basket->GetResultSet();
00225    if (!rs) {
00226       Error("CheckBranch","%s has basket but no resultset yet",tb->GetName());
00227       return kFALSE;
00228    }
00229 
00230    nl = tb->GetNleaves();
00231 
00232    for(int j=0;j<nl;j++) {
00233       leaf = (TLeaf*)tb->GetListOfLeaves()->UncheckedAt(j);
00234       typeName = leaf->GetTypeName();
00235       typeName = ConvertTypeName(leaf->GetTypeName());
00236       leafName = leaf->GetName();
00237       str = "";
00238       str = tb->GetName();
00239       str += "__";
00240       str += leafName;
00241 
00242       for (int i=0; i< rs->GetFieldCount(); ++i) {
00243          if (str.CompareTo(rs->GetFieldName(i),TString::kIgnoreCase) == 0) return kTRUE;
00244       }
00245       // We assume that if ONE of the leaf is in the table, then ALL the leaf are in
00246       // the table.
00247       // TODO: this assumption is harmful if user changes branch structure while keep its name
00248       CreateBranch(str, typeName);
00249    }
00250    return kFALSE;
00251 }
00252 
00253 //______________________________________________________________________________
00254 Bool_t TTreeSQL::CheckTable(const TString &table) const
00255 {
00256    // Check the table exist in the database
00257 
00258    if (fServer==0) return kFALSE;
00259    TSQLResult * tables = fServer->GetTables(fDB.Data(),table);
00260    TSQLRow * row = 0;
00261    while( (row = tables->Next()) ) {
00262       if(table.CompareTo(row->GetField(0),TString::kIgnoreCase)==0){
00263          return kTRUE;
00264       }
00265    }
00266    // The table is a not a permanent table, let's see if it is a 'temporary' table
00267    Int_t before = gErrorIgnoreLevel;
00268    gErrorIgnoreLevel = kFatal;
00269    TSQLResult *res = fServer->GetColumns(fDB.Data(),table);
00270    if (res) {
00271       delete res;
00272       return kTRUE;
00273    }
00274    gErrorIgnoreLevel = before;
00275 
00276    return kFALSE;
00277 }
00278 
00279 //______________________________________________________________________________
00280 TString TTreeSQL::ConvertTypeName(const TString& typeName )
00281 {
00282    // Convert from ROOT typename to SQL typename
00283 
00284    TString tn = "";
00285 
00286    if(typeName == "Char_t"){
00287       tn = "TEXT";
00288    }
00289    else if(typeName == "Int_t") {
00290       tn = "INTEGER";
00291    }
00292    else if(typeName == "Short_t") {
00293       tn = "SMALLINT";
00294    }
00295    else if( typeName == "UShort_t") {
00296       tn = "SMALLINT UNSIGNED";
00297    }
00298    else if(typeName == "Float_t"){
00299       tn = "FLOAT";
00300    }
00301    else if(typeName == "Float16_t"){
00302       tn = "FLOAT";
00303    }
00304    else if(typeName == "Double_t"){
00305       tn = "DOUBLE";
00306    }
00307    else if(typeName == "Double32_t"){
00308       tn = "FLOAT";
00309    }
00310    else if(typeName == "UInt_t") {
00311       tn = "INT UNSIGNED";
00312    }
00313    else if( typeName == "Long_t") {
00314       tn = "INTEGER";
00315    }
00316    else if( typeName == "ULong_t") {
00317       tn = "INTEGER UNSIGNED";
00318    }
00319    else if( typeName == "Long64_t") {
00320       tn = "BIGINT";
00321    }
00322    else if( typeName == "ULong64_t") {
00323       tn = "BIGINT UNSIGNED";
00324    }
00325    else if( typeName == "Bool_t") {
00326       tn = "BOOL";
00327    }
00328    else {
00329       Error("ConvertTypeName","TypeName (%s) not found",typeName.Data());
00330       return "";
00331    }
00332 
00333    return tn;
00334 }
00335 
00336 //______________________________________________________________________________
00337 TBasket * TTreeSQL::CreateBasket(TBranch * tb)
00338 {
00339    // Create a TBasketSQL
00340 
00341    if (fServer==0) {
00342       Error("CreateBasket","No TSQLServer specified");
00343       return 0;
00344    }
00345    vector<Int_t> *columnVec = GetColumnIndice(tb);
00346    if (columnVec) {
00347       return new TBasketSQL(tb->GetName(), tb->GetName(), tb,
00348                             &fResult, &fInsertQuery, columnVec, &fRow);
00349    } else {
00350       return 0;
00351    }
00352 }
00353 
00354 //______________________________________________________________________________
00355 void TTreeSQL::CreateBranch(const TString &branchName, const TString &typeName)
00356 {
00357    // Create the column(s) in the database that correspond to the branch/
00358 
00359    if (fServer==0) {
00360       Error("CreateBranch","No TSQLServer specified");
00361       return;
00362    }
00363    TString alterSQL = "";
00364    alterSQL = "";
00365    alterSQL = "ALTER TABLE ";
00366    alterSQL += fTable.Data();
00367    alterSQL += " ADD ";
00368    alterSQL += branchName.Data();;
00369    alterSQL += " ";
00370    alterSQL += typeName;
00371    alterSQL += " ";
00372 
00373    fServer->Query(alterSQL);
00374 }
00375 
00376 //_________________________________________________________________________
00377 TString TTreeSQL::CreateBranches(TSQLResult * rs)
00378 {
00379    // determine leaf description string
00380 
00381    if(!rs) return "";
00382 
00383    Int_t rows;
00384    TString type;
00385    TString res;
00386    TString branchName;
00387    TString leafName;
00388    Int_t prec=0;
00389    TBranch * br = 0;
00390    rows = rs->GetRowCount();
00391    TString decl;
00392    TString prevBranch;
00393 
00394    for( int i=0; i < rows; ++i ) {
00395       TSQLRow * row = rs->Next();
00396       type = row->GetField(1);
00397       Int_t index = type.First('(');
00398       if(index>0){
00399          prec = atoi(type(index+1,type.First(')')-1).Data());
00400          type = type(0,index);
00401       }
00402       branchName = row->GetField(0);
00403       Int_t pos;
00404       if ((pos=branchName.Index("__"))!=kNPOS) {
00405          leafName = branchName(pos+2,branchName.Length());
00406          branchName.Remove(pos);
00407       } else {
00408          leafName = branchName;
00409       }
00410       if (prevBranch.Length()) {
00411          if (prevBranch != branchName) {
00412             // new branch let's flush.
00413             if (decl.Length()) decl.Remove(decl.Length()-1);
00414             br = TTree::Branch(prevBranch,0,decl);
00415             br->ResetAddress();
00416 
00417             (br->GetBasketEntry())[0] = 0;
00418             (br->GetBasketEntry())[1] = fEntries;
00419 
00420             br->SetEntries(fEntries);
00421 
00422             //++(br->fNBaskets);
00423             br->GetListOfBaskets()->AddAtAndExpand(CreateBasket(br),0);
00424 
00425             prevBranch = branchName;
00426             decl = "";
00427          }
00428       } else {
00429          prevBranch = branchName;
00430       }
00431 
00432       if(type.CompareTo("varchar",TString::kIgnoreCase)==0 || type.CompareTo("varchar2",TString::kIgnoreCase)==0 || type.CompareTo("char",TString::kIgnoreCase)==0 ) { 
00433          char siz[6];
00434          snprintf(siz,6,"[%d]",prec);
00435          decl.Append( leafName+siz+"/C:" );
00436       }
00437       else if(type.CompareTo("int",TString::kIgnoreCase)==0){
00438          decl.Append( leafName+"/I:" );
00439       }
00440       else if( type.CompareTo("date",TString::kIgnoreCase)==0 ||
00441                type.CompareTo("time",TString::kIgnoreCase)==0 ||
00442                type.CompareTo("timestamp",TString::kIgnoreCase)==0 ) {
00443          decl.Append( leafName+"/I:" );
00444       }
00445       else if(type.CompareTo("bit",TString::kIgnoreCase)==0 ||
00446               type.CompareTo("tinyint",TString::kIgnoreCase)==0 ||
00447               type.CompareTo("smallint",TString::kIgnoreCase)==0 ) {
00448          decl.Append( leafName+"/i:" );
00449       }
00450       else if(type.CompareTo("real",TString::kIgnoreCase)==0 || type.CompareTo("longvarchar",TString::kIgnoreCase)==0 || type.CompareTo("longvarbinary",TString::kIgnoreCase)==0 || type.CompareTo("varbinary",TString::kIgnoreCase)==0 ){
00451          decl.Append( leafName+"/S:" );
00452       }
00453 
00454       //   case kLONGVARCHAR: // not resolved yet how to handle
00455       // case kLONGVARBINARY:
00456       //case kVARBINARY:
00457       //  break;
00458       else /*if(type.CompareTo("bigint",TString::kIgnoreCase)==0 || type.CompareTo("decimal",TString::kIgnoreCase)==0 || type.CompareTo("numeric",TString::kIgnoreCase)==0 || type.CompareTo("double",TString::kIgnoreCase)==0 ||
00459       type.CompareTo("float",TString::kIgnoreCase)==0 )*/{
00460 
00461          decl.Append( leafName+"/F:" );
00462       }
00463 
00464    }
00465 
00466    // new branch let's flush.
00467    if (decl.Length()) decl.Remove(decl.Length()-1);
00468    if (prevBranch.Length()) {
00469       br = TTree::Branch(prevBranch,0,decl);
00470       br->ResetAddress();
00471 
00472       (br->GetBasketEntry())[0] = 0;
00473       (br->GetBasketEntry())[1] = fEntries;
00474       br->SetEntries(fEntries);
00475       br->GetListOfBaskets()->AddAtAndExpand(CreateBasket(br),0);
00476    }
00477 
00478    if(!res.IsNull()) res.Resize(res.Length()-1);   // cut off last ":"
00479    return res;
00480 }
00481 
00482 //______________________________________________________________________________
00483 Bool_t TTreeSQL::CreateTable(const TString &table)
00484 {
00485    // Create the database table corresponding to this TTree.
00486 
00487    if (fServer==0) {
00488       Error("CreateTable","No TSQLServer specified");
00489       return false;
00490    }
00491    Int_t i, j;
00492    Int_t length;
00493    TString branchName, leafName, typeName;
00494    TString createSQL, alterSQL, str;
00495    Int_t nb = fBranches.GetEntriesFast();
00496    Int_t nl = 0;
00497 
00498    TBranch *branch;
00499    TLeaf *leaf;
00500 
00501    for (i=0;i<nb;i++) {
00502       branch = (TBranch*)fBranches.UncheckedAt(i);
00503       branchName = branch->GetName();
00504       nl = branch->GetNleaves();
00505       for(j=0;j<nl;j++) {
00506          leaf = (TLeaf*)branch->GetListOfLeaves()->UncheckedAt(j);
00507          leafName = leaf->GetName();
00508          typeName = ConvertTypeName(leaf->GetTypeName());
00509          length = leaf->GetLenStatic();
00510 
00511          if(i == 0 && j == 0) {
00512             createSQL = "";
00513             createSQL += "CREATE TABLE ";
00514             createSQL += table;
00515             createSQL += " (";
00516             createSQL += branchName;
00517             createSQL += "__";
00518             createSQL += leafName;
00519             createSQL += " ";
00520             createSQL += typeName;
00521             createSQL += " ";
00522             createSQL += ")";
00523 
00524             TSQLResult *sres = fServer->Query(createSQL.Data());
00525             if (!sres) {
00526                Error("CreateTable","May have failed");
00527                return false;
00528             }
00529          }
00530          else {
00531             str = "";
00532             str = branchName;
00533             str += "__";
00534             str += leafName;
00535             CreateBranch(str, typeName);
00536          } //else
00537       }  // inner for loop
00538    } // outer for loop
00539    // retrieve table to initialize fResult
00540    delete fResult;
00541    fResult = fServer->Query(fQuery.Data());
00542    return (fResult!=0);
00543 }
00544 
00545 //______________________________________________________________________________
00546 void TTreeSQL::Init()
00547 {
00548    // Initializeation routine
00549 
00550    fCurrentEntry = -1;
00551 
00552    GetEntries();
00553 
00554    delete fResult;
00555    fResult = fServer->Query(fQuery.Data());
00556    if(!fResult) return;
00557 
00558    CreateBranches(fServer->GetColumns(fDB,fTable));
00559 }
00560 
00561 //______________________________________________________________________________
00562 Int_t TTreeSQL::Fill()
00563 {
00564    // Copy the information from the user object to the TTree
00565 
00566    Int_t nb = fBranches.GetEntriesFast();
00567    TString typeName;
00568    TBranch *branch;
00569 
00570    if (fServer==0) return 0;
00571 
00572    if(!CheckTable(fTable.Data())) {
00573       if (!CreateTable(fTable.Data())) {
00574          return -1;
00575       }
00576    }
00577 
00578    PrepEntry(fEntries);
00579 
00580    for (int i=0;i<nb;i++) {
00581       branch = (TBranch*)fBranches.UncheckedAt(i);
00582       CheckBasket(branch);
00583    }
00584 
00585    if (!fBranchChecked) {
00586       for(int i=0;i<nb;i++) {
00587          branch = (TBranch*)fBranches.UncheckedAt(i);
00588          if (!CheckBranch(branch)) {
00589             Error("Fill","CheckBranch for %s failed",branch->GetName());
00590          }
00591       }
00592       fBranchChecked = kTRUE;
00593    }
00594    ResetQuery();
00595 
00596    TTree::Fill();
00597 
00598    if (fInsertQuery[fInsertQuery.Length()-1]!='(') {
00599       fInsertQuery.Remove(fInsertQuery.Length()-1);
00600       fInsertQuery += ")";
00601       TSQLResult *res = fServer?fServer->Query(fInsertQuery):0;
00602 
00603       if (res) {
00604          return res->GetRowCount();
00605       }
00606    }
00607    return -1;
00608 }
00609 
00610 //______________________________________________________________________________
00611 vector<Int_t> *TTreeSQL::GetColumnIndice(TBranch *branch)
00612 {
00613    // Return a vector of columns index corresponding to the
00614    // current SQL table and the branch given as argument
00615    // Returns 0 if no columns indices is found
00616    // Otherwise returns a pointer to a vector to be deleted by the caller
00617 
00618    if (!CheckTable(fTable)) return 0;
00619 
00620    vector<Int_t> *columns = new vector<Int_t>;
00621 
00622    Int_t nl = branch->GetNleaves();
00623 
00624    vector<TString> names;
00625 
00626    TSQLResult *rs = fServer->GetColumns(fDB,fTable);
00627    if (rs==0) { delete columns; return 0; }
00628    Int_t rows = rs->GetRowCount();
00629 
00630    pair<TString,Int_t> value;
00631 
00632    for (Int_t i=0;i<rows;++i) {
00633       TSQLRow *row = rs->Next();
00634       names.push_back( row->GetField(0) );
00635       delete row;
00636    }
00637    delete rs;
00638 
00639    for(int j=0;j<nl;j++) {
00640 
00641       Int_t col = -1;
00642       TLeaf *leaf = (TLeaf*)branch->GetListOfLeaves()->UncheckedAt(j);
00643       TString leafName = leaf->GetName();
00644       TString str;
00645 
00646       str = "";
00647       str = branch->GetName();
00648       str += "__";
00649       str += leafName;
00650       for (Int_t i=0;i<rows;++i) {
00651          if (str.CompareTo(names[i],TString::kIgnoreCase)==0) {
00652             col = i;
00653             break;
00654          }
00655       }
00656       if (col<0) {
00657          str = leafName;
00658          for (Int_t i=0;i<rows;++i) {
00659             if (str.CompareTo(names[i],TString::kIgnoreCase)==0) {
00660                col = i;
00661                break;
00662             }
00663          }         
00664       }
00665       if(col>=0){
00666          columns->push_back(col);
00667       } else Error("GetColumnIndice","Error finding column %d %s",j,str.Data());
00668    }
00669    if (columns->empty()) {
00670       delete columns; return 0;
00671    } else
00672       return columns;
00673 }
00674 
00675 //______________________________________________________________________________
00676 Long64_t  TTreeSQL::GetEntries() const
00677 {
00678    // Get the number of rows in the database
00679 
00680    if (fServer==0) return GetEntriesFast();
00681    if (!CheckTable(fTable.Data())) return 0;
00682 
00683    TTreeSQL* thisvar = (TTreeSQL*)this;
00684 
00685    // What if the user already started to call GetEntry
00686    // What about the initial value of fEntries is it really 0?
00687 
00688    TString counting = "select count(*) from " + fTable;
00689    TSQLResult *count = fServer->Query(counting);
00690 
00691    if (count==0) {
00692       thisvar->fEntries = 0;
00693    } else {
00694       TString val = count->Next()->GetField(0);
00695       Long_t ret;
00696       sscanf(val.Data(), "%ld",&(ret) );
00697       thisvar->fEntries = ret;
00698    }
00699    return fEntries;
00700 }
00701 
00702 //______________________________________________________________________________
00703 Long64_t  TTreeSQL::GetEntriesFast()    const
00704 {
00705    // Return the number of entries as of the last check.
00706    // Use GetEntries for a more accurate count.
00707 
00708    return fEntries;
00709 }
00710 
00711 //______________________________________________________________________________
00712 Int_t TTreeSQL::GetEntry(Long64_t entry, Int_t getall)
00713 {
00714    // Load the data for the entry from the database.
00715 
00716    if (PrepEntry(entry)>=0) return TTree::GetEntry(entry,getall);
00717    else return -1;
00718 }
00719 
00720 //______________________________________________________________________________
00721 Long64_t TTreeSQL::LoadTree(Long64_t entry)
00722 {
00723    // Setup the tree to the load the specified entry.
00724 
00725    fReadEntry = entry;
00726    return PrepEntry(entry);
00727 }
00728 
00729 //______________________________________________________________________________
00730 Long64_t TTreeSQL::PrepEntry(Long64_t entry)
00731 {
00732    // Make sure the server and result set are setup for the requested entry
00733 
00734    if (entry < 0 || entry >= fEntries || fServer==0) return 0;
00735    fReadEntry = entry;
00736 
00737    if(entry == fCurrentEntry) return entry;
00738 
00739    if(entry < fCurrentEntry || fResult==0){
00740       delete fResult;
00741       fResult = fServer->Query(fQuery.Data());
00742       fCurrentEntry = -1;
00743    }
00744 
00745    Bool_t reset = false;
00746    while ( fCurrentEntry < entry ) {
00747       ++fCurrentEntry;
00748       delete fRow;
00749       fRow = fResult->Next();
00750       if (fRow==0 && !reset) {
00751          delete fResult;
00752          fResult = fServer->Query(fQuery.Data());
00753          fCurrentEntry = -1;
00754          reset = true;
00755       }
00756    }
00757    if (fRow==0) return -1;
00758    return entry;
00759 }
00760 
00761 //______________________________________________________________________________
00762 // void TTreeSQL::LoadNumberEntries()
00763 // {
00764 //    R__ASSERT(0);
00765 
00766 //    fResult =    fServer->Query(fQuery.Data());
00767 //    fEntries=0;
00768 
00769 //    while(fResult->Next()){
00770 //       fEntries++;
00771 //    }
00772 //    fResult =    fServer->Query(fQuery.Data());
00773 // }
00774 
00775 //______________________________________________________________________________
00776 void TTreeSQL::Refresh()
00777 {
00778    //  Refresh contents of this Tree and his branches from the current
00779    //  Tree status in the database
00780    //  One can call this function in case the Tree on its file is being
00781    //  updated by another process
00782 
00783    // Note : something to be done?
00784    GetEntries(); // Re-load the number of entries
00785    fCurrentEntry = -1;
00786    delete fResult; fResult = 0;
00787    delete fRow; fRow = 0;
00788 }
00789 
00790 //______________________________________________________________________________
00791 void TTreeSQL::ResetQuery()
00792 {
00793    // Reset the internal query
00794 
00795    fInsertQuery = "INSERT INTO " + fTable + " VALUES (";
00796 }
00797 
00798 

Generated on Tue Jul 5 15:34:15 2011 for ROOT_528-00b_version by  doxygen 1.5.1