Changeset 15419


Ignore:
Timestamp:
04/24/13 19:11:15 (12 years ago)
Author:
tbretz
Message:
Removed support for writing to the table; added support for left joins
Location:
trunk/Mars/msql
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Mars/msql/MTreeSQL.cc

    r15417 r15419  
    1919
    2020#include <Riostream.h>
    21 #include <vector>
    2221#include <map>
    2322#include <stdlib.h>
     
    3130#include "TLeaf.h"
    3231#include "TBranch.h"
     32#include "TPRegexp.h"
    3333
    3434#include "TSQLRow.h"
     
    4545//______________________________________________________________________________
    4646MTreeSQL::MTreeSQL(TSQLServer *server, TString DB, const TString& table, const TString &addon) :
    47    TTree(table.Data(), "Database read from table: " + table, 0), fDB(DB),
    48    fTable(table.Data()),
    49    fResult(0), fRow(0),
    50    fServer(server),
    51    fBranchChecked(kFALSE)
    52 {
    53    // Constructor with an explicit TSQLServer
    54 
    55    fCurrentEntry = -1;
    56    fQuery = TString("Select * from " + fTable + " " + addon);
    57    fEntries = 0;
    58 
    59    if (fServer==0) {
    60       Error("MTreeSQL","No TSQLServer specified");
    61       return;
    62    }
    63    if (CheckTable(fTable.Data())) {
    64       Init();
    65    }
     47    TTree(table.Data(), "Database read from table: " + table, 0),
     48    fCurrentEntry(-1), fDB(DB), fQuery(table+" "+addon),fResult(0), fRow(0),
     49    fServer(server)
     50{
     51    fEntries = 0;
     52
     53    if (fServer==0)
     54    {
     55        Error("MTreeSQL","No TSQLServer specified");
     56        return;
     57    }
     58
     59    fTables.push_back(table);
     60
     61    // Constructor with an explicit TSQLServer
     62    TPRegexp reg("LEFT +JOIN +([a-zA-Z0-9_.]+)");
     63
     64    Int_t p = -1;
     65    while (p<addon.Length())
     66    {
     67        TArrayI pos;
     68        if (reg.Match(addon, "ig", ++p, 100, &pos)!=2)
     69            continue;
     70
     71        if (pos[2] >= 0 && pos[3] >= 0)
     72        {
     73            const TString subStr = addon(pos[2], pos[3]-pos[2]);
     74            fTables.push_back(subStr);
     75        }
     76
     77        p = pos[3];
     78    }
     79
     80    for (auto it=fTables.begin(); it!=fTables.end(); it++)
     81    {
     82        cout << *it << endl;
     83        if (!CheckTable(*it))
     84            return;
     85    }
     86
     87    Init();
    6688}
    6789
     
    166188
    167189         Fatal("Branch()", "Duplicate branch!!!");
    168 
    169          /* Commented. If uncommented, should comment Fatal line.
    170          // this is a duplicate branch. So reset data structure memory address and return.
    171          branch->SetAddress(address);
    172          return branch;
    173          */
    174190      }
    175191   }
    176192   return TTree::Branch(name, address, leaflist, bufsize);
    177 }
    178 
    179 //______________________________________________________________________________
    180 void MTreeSQL::CheckBasket(TBranch *branch)
    181 {
    182    // Check if the basket is properly setup
    183 
    184    MBasketSQL* basket = (MBasketSQL *)branch->GetBasket(0);
    185 
    186    if (basket==0) {
    187       basket = (MBasketSQL*)CreateBasket(branch);
    188       if (basket==0) return;
    189       //++(branch->fNBaskets);
    190       branch->GetListOfBaskets()->AddAtAndExpand(basket,0);
    191    }
    192    TBuffer * buffer = basket->GetBufferRef();
    193 
    194    if(buffer == 0){
    195       vector<Int_t> *columns = GetColumnIndice(branch);
    196       if (columns) basket->CreateBuffer(branch->GetName(),"A", columns, branch, &fResult);
    197    }
    198 
    199    Int_t nb = branch->GetListOfBranches()->GetEntriesFast();
    200    for (int i=0;i<nb;i++) {
    201       TBranch * subbranch = (TBranch*)branch->GetListOfBranches()->UncheckedAt(i);
    202       if(subbranch) CheckBasket(subbranch);
    203    }
    204 }
    205 
    206 //______________________________________________________________________________
    207 Bool_t MTreeSQL::CheckBranch(TBranch * tb)
    208 {
    209    // Check if the table has a column corresponding the branch
    210    // and that the resultset are properly setup
    211 
    212    if (fServer==0) {
    213       return kFALSE;
    214    }
    215    TString leafName;
    216    TLeaf *leaf;
    217    Int_t nl;
    218    TString str = "";
    219    TString typeName = "";
    220 
    221    if (!tb) return kFALSE;
    222 
    223    MBasketSQL *basket = (MBasketSQL *)tb->GetBasket(0);
    224    if (!basket) return kFALSE;
    225 
    226    TSQLResult *rs = basket->GetResultSet();
    227    if (!rs) {
    228       Error("CheckBranch","%s has basket but no resultset yet",tb->GetName());
    229       return kFALSE;
    230    }
    231 
    232    nl = tb->GetNleaves();
    233 
    234    for(int j=0;j<nl;j++) {
    235       leaf = (TLeaf*)tb->GetListOfLeaves()->UncheckedAt(j);
    236       typeName = leaf->GetTypeName();
    237       typeName = ConvertTypeName(leaf->GetTypeName());
    238       leafName = leaf->GetName();
    239       str = "";
    240       str = tb->GetName();
    241       str += "__";
    242       str += leafName;
    243 
    244       for (int i=0; i< rs->GetFieldCount(); ++i) {
    245          if (str.CompareTo(rs->GetFieldName(i),TString::kIgnoreCase) == 0) return kTRUE;
    246       }
    247       // We assume that if ONE of the leaf is in the table, then ALL the leaf are in
    248       // the table.
    249       // TODO: this assumption is harmful if user changes branch structure while keep its name
    250       CreateBranch(str, typeName);
    251    }
    252    return kFALSE;
    253193}
    254194
     
    281221
    282222//______________________________________________________________________________
    283 TString MTreeSQL::ConvertTypeName(const TString& typeName )
    284 {
    285    // Convert from ROOT typename to SQL typename
    286 
    287    TString tn = "";
    288 
    289    if(typeName == "Char_t"){
    290       tn = "TEXT";
    291    }
    292    else if(typeName == "Int_t") {
    293       tn = "INTEGER";
    294    }
    295    else if(typeName == "Short_t") {
    296       tn = "SMALLINT";
    297    }
    298    else if( typeName == "UShort_t") {
    299       tn = "SMALLINT UNSIGNED";
    300    }
    301    else if(typeName == "Float_t"){
    302       tn = "FLOAT";
    303    }
    304    else if(typeName == "Float16_t"){
    305       tn = "FLOAT";
    306    }
    307    else if(typeName == "Double_t"){
    308       tn = "DOUBLE";
    309    }
    310    else if(typeName == "Double32_t"){
    311       tn = "FLOAT";
    312    }
    313    else if(typeName == "UInt_t") {
    314       tn = "INT UNSIGNED";
    315    }
    316    else if( typeName == "Long_t") {
    317       tn = "INTEGER";
    318    }
    319    else if( typeName == "ULong_t") {
    320       tn = "INTEGER UNSIGNED";
    321    }
    322    else if( typeName == "Long64_t") {
    323       tn = "BIGINT";
    324    }
    325    else if( typeName == "ULong64_t") {
    326       tn = "BIGINT UNSIGNED";
    327    }
    328    else if( typeName == "Bool_t") {
    329       tn = "BOOL";
    330    }
    331    else {
    332       Error("ConvertTypeName","TypeName (%s) not found",typeName.Data());
    333       return "";
    334    }
    335 
    336    return tn;
    337 }
    338 
    339 //______________________________________________________________________________
    340223TBasket * MTreeSQL::CreateBasket(TBranch * tb)
    341224{
     
    346229      return 0;
    347230   }
     231
     232   static TString dummy;
     233
    348234   vector<Int_t> *columnVec = GetColumnIndice(tb);
    349235   if (columnVec) {
    350236      return new MBasketSQL(tb->GetName(), tb->GetName(), tb,
    351                             &fResult, &fInsertQuery, columnVec, &fRow);
     237                            &fResult, &dummy, columnVec, &fRow);
    352238   } else {
    353239      return 0;
     
    355241}
    356242
    357 //______________________________________________________________________________
    358 void MTreeSQL::CreateBranch(const TString &branchName, const TString &typeName)
    359 {
    360    // Create the column(s) in the database that correspond to the branch/
    361 
    362    if (fServer==0) {
    363       Error("CreateBranch","No TSQLServer specified");
    364       return;
    365    }
    366    TString alterSQL = "";
    367    alterSQL = "";
    368    alterSQL = "ALTER TABLE ";
    369    alterSQL += fTable.Data();
    370    alterSQL += " ADD ";
    371    alterSQL += branchName.Data();;
    372    alterSQL += " ";
    373    alterSQL += typeName;
    374    alterSQL += " ";
    375 
    376    fServer->Query(alterSQL);
    377 }
    378 
    379243//_________________________________________________________________________
    380 TString MTreeSQL::CreateBranches(TSQLResult * rs)
     244TString MTreeSQL::CreateBranches(TSQLResult * rs, const TString &table)
    381245{
    382246   // determine leaf description string
     
    404268         type = type(0,index);
    405269      }
    406       branchName = row->GetField(0);
     270      branchName = table+"."+row->GetField(0);
     271      //cout << table << "." << branchName << endl;
    407272      Int_t pos;
    408273      if ((pos=branchName.Index("__"))!=kNPOS) {
     
    460325      //case kVARBINARY:
    461326      //  break;
    462       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 ||
    463       type.CompareTo("float",TString::kIgnoreCase)==0 )*/{
     327      else
     328      //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 ||
     329      //type.CompareTo("float",TString::kIgnoreCase)==0 )
     330      {
    464331
    465332         decl.Append( leafName+"/F:" );
     
    485352
    486353//______________________________________________________________________________
    487 Bool_t MTreeSQL::CreateTable(const TString &table)
    488 {
    489    // Create the database table corresponding to this TTree.
    490 
    491    if (fServer==0) {
    492       Error("CreateTable","No TSQLServer specified");
    493       return false;
    494    }
    495    Int_t i, j;
    496    TString branchName, leafName, typeName;
    497    TString createSQL, alterSQL, str;
    498    Int_t nb = fBranches.GetEntriesFast();
    499    Int_t nl = 0;
    500 
    501    TBranch *branch;
    502    TLeaf *leaf;
    503 
    504    for (i=0;i<nb;i++) {
    505       branch = (TBranch*)fBranches.UncheckedAt(i);
    506       branchName = branch->GetName();
    507       nl = branch->GetNleaves();
    508       for(j=0;j<nl;j++) {
    509          leaf = (TLeaf*)branch->GetListOfLeaves()->UncheckedAt(j);
    510          leafName = leaf->GetName();
    511          typeName = ConvertTypeName(leaf->GetTypeName());
    512          // length = leaf->GetLenStatic();
    513 
    514          if(i == 0 && j == 0) {
    515             createSQL = "";
    516             createSQL += "CREATE TABLE ";
    517             createSQL += table;
    518             createSQL += " (";
    519             createSQL += branchName;
    520             createSQL += "__";
    521             createSQL += leafName;
    522             createSQL += " ";
    523             createSQL += typeName;
    524             createSQL += " ";
    525             createSQL += ")";
    526 
    527             TSQLResult *sres = fServer->Query(createSQL.Data());
    528             if (!sres) {
    529                Error("CreateTable","May have failed");
    530                return false;
    531             }
    532          }
    533          else {
    534             str = "";
    535             str = branchName;
    536             str += "__";
    537             str += leafName;
    538             CreateBranch(str, typeName);
    539          } //else
    540       }  // inner for loop
    541    } // outer for loop
    542    // retrieve table to initialize fResult
     354void MTreeSQL::Init()
     355{
     356   // Initializeation routine
     357
     358   fCurrentEntry = -1;
     359
     360   GetEntries();
     361
    543362   delete fResult;
    544    fResult = fServer->Query(fQuery.Data());
    545    return (fResult!=0);
    546 }
    547 
    548 //______________________________________________________________________________
    549 void MTreeSQL::Init()
    550 {
    551    // Initializeation routine
    552 
    553    fCurrentEntry = -1;
    554 
    555    GetEntries();
    556 
    557    delete fResult;
    558    fResult = fServer->Query(fQuery.Data());
     363   fResult = fServer->Query(("SELECT * FROM "+fQuery).Data());
    559364   if(!fResult) return;
    560365
    561    CreateBranches(fServer->GetColumns(fDB,fTable));
     366    for (auto it=fTables.begin(); it!=fTables.end(); it++)
     367        CreateBranches(fServer->GetColumns(fDB, *it), *it);
    562368}
    563369
     
    565371Int_t MTreeSQL::Fill()
    566372{
    567    // Copy the information from the user object to the TTree
    568 
    569    Int_t nb = fBranches.GetEntriesFast();
    570    TString typeName;
    571    TBranch *branch;
    572 
    573    if (fServer==0) return 0;
    574 
    575    if(!CheckTable(fTable.Data())) {
    576       if (!CreateTable(fTable.Data())) {
    577          return -1;
    578       }
    579    }
    580 
    581    PrepEntry(fEntries);
    582 
    583    for (int i=0;i<nb;i++) {
    584       branch = (TBranch*)fBranches.UncheckedAt(i);
    585       CheckBasket(branch);
    586    }
    587 
    588    if (!fBranchChecked) {
    589       for(int i=0;i<nb;i++) {
    590          branch = (TBranch*)fBranches.UncheckedAt(i);
    591          if (!CheckBranch(branch)) {
    592             Error("Fill","CheckBranch for %s failed",branch->GetName());
    593          }
    594       }
    595       fBranchChecked = kTRUE;
    596    }
    597    ResetQuery();
    598 
    599    TTree::Fill();
    600 
    601    if (fInsertQuery[fInsertQuery.Length()-1]!='(') {
    602       fInsertQuery.Remove(fInsertQuery.Length()-1);
    603       fInsertQuery += ")";
    604       TSQLResult *res = fServer?fServer->Query(fInsertQuery):0;
    605 
    606       if (res) {
    607          return res->GetRowCount();
    608       }
    609    }
     373   Fatal("Fill","Not implemented yet");
    610374   return -1;
    611375}
     
    619383   // Otherwise returns a pointer to a vector to be deleted by the caller
    620384
    621    if (!CheckTable(fTable)) return 0;
     385   //if (!CheckTable(fTable)) return 0;
    622386
    623387   vector<Int_t> *columns = new vector<Int_t>;
     
    626390
    627391   vector<TString> names;
    628 
    629    TSQLResult *rs = fServer->GetColumns(fDB,fTable);
    630    if (rs==0) { delete columns; return 0; }
    631    Int_t rows = rs->GetRowCount();
    632 
    633392   pair<TString,Int_t> value;
    634393
    635    for (Int_t i=0;i<rows;++i) {
    636       TSQLRow *row = rs->Next();
    637       names.push_back( row->GetField(0) );
    638       delete row;
    639    }
    640    delete rs;
     394    for (auto it=fTables.begin(); it!=fTables.end(); it++)
     395    {
     396        TSQLResult *rs = fServer->GetColumns(fDB, *it);
     397        if (rs==0) { delete columns; return 0; }
     398        Int_t rows = rs->GetRowCount();
     399
     400        for (Int_t i=0;i<rows;++i) {
     401            TSQLRow *row = rs->Next();
     402            names.push_back( *it+"."+row->GetField(0) );
     403            delete row;
     404        }
     405        delete rs;
     406    }
    641407
    642408   for(int j=0;j<nl;j++) {
     
    651417      str += "__";
    652418      str += leafName;
    653       for (Int_t i=0;i<rows;++i) {
     419      for (UInt_t i=0;i<names.size();++i) {
    654420         if (str.CompareTo(names[i],TString::kIgnoreCase)==0) {
    655421            col = i;
     
    659425      if (col<0) {
    660426         str = leafName;
    661          for (Int_t i=0;i<rows;++i) {
    662             if (str.CompareTo(names[i],TString::kIgnoreCase)==0) {
     427         for (UInt_t i=0;i<names.size();++i) {
     428             if (str.CompareTo(names[i],TString::kIgnoreCase)==0) {
    663429               col = i;
    664430               break;
     
    682448
    683449   if (fServer==0) return GetEntriesFast();
    684    if (!CheckTable(fTable.Data())) return 0;
     450   //if (!CheckTable(fTable.Data())) return 0;
    685451
    686452   MTreeSQL* thisvar = const_cast<MTreeSQL*>(this);
     
    689455   // What about the initial value of fEntries is it really 0?
    690456
    691    TString counting = "select count(*) from " + fTable;
     457   const TString counting = "SELECT COUNT(*) FROM " + fQuery;
    692458   TSQLResult *count = fServer->Query(counting);
    693459
     
    747513   if(entry < fCurrentEntry || fResult==0){
    748514      delete fResult;
    749       fResult = fServer->Query(fQuery.Data());
     515      fResult = fServer->Query(("SELECT * FROM "+fQuery).Data());
    750516      fCurrentEntry = -1;
    751517   }
     
    758524      if (fRow==0 && !reset) {
    759525         delete fResult;
    760          fResult = fServer->Query(fQuery.Data());
     526         fResult = fServer->Query(("SELECT * FROM "+fQuery).Data());
    761527         fCurrentEntry = -1;
    762528         reset = true;
     
    766532   return entry;
    767533}
    768 
     534/*
    769535//______________________________________________________________________________
    770536// void MTreeSQL::LoadNumberEntries()
     
    780546//    fResult =    fServer->Query(fQuery.Data());
    781547// }
    782 
     548*/
    783549//______________________________________________________________________________
    784550void MTreeSQL::Refresh()
     
    795561   delete fRow; fRow = 0;
    796562}
    797 
    798 //______________________________________________________________________________
    799 void MTreeSQL::ResetQuery()
    800 {
    801    // Reset the internal query
    802 
    803    fInsertQuery = "INSERT INTO " + fTable + " VALUES (";
    804 }
    805 
    806 
  • trunk/Mars/msql/MTreeSQL.h

    r15417 r15419  
    3939class TSQLServer;
    4040class TSQLRow;
    41 class MBasketSQL;
    4241
    4342class MTreeSQL : public TTree {
     
    4645   Int_t                  fCurrentEntry;
    4746   TString                fDB;
    48    TString                fInsertQuery;   
    4947   TString                fQuery;
    50    TString                fTable;
    5148   TSQLResult            *fResult;
    5249   TSQLRow               *fRow;
    5350   TSQLServer            *fServer;
    54    Bool_t                 fBranchChecked;
     51   std::vector<TString>   fTables;
    5552
    56    void                   CheckBasket(TBranch * tb);
    57    Bool_t                 CheckBranch(TBranch * tb);
    5853   Bool_t                 CheckTable(const TString &table) const;
    59    TString                CreateBranches(TSQLResult * rs);
     54   TString                CreateBranches(TSQLResult * rs, const TString &table);
    6055   std::vector<Int_t>    *GetColumnIndice(TBranch *branch);
    61    void                   Init();   
    62    void                   ResetQuery();
    63    TString                ConvertTypeName(const TString& typeName );
    64    virtual void           CreateBranch(const TString& branchName,const TString &typeName);
    65    Bool_t                 CreateTable(const TString& table);
    66    virtual TBasket       *CreateBasket(TBranch * br);
     56   void                   Init();
     57   virtual TBasket       *CreateBasket(TBranch * br);
    6758
    6859   virtual TBranch *BranchImp(const char *branchname, const char *classname, TClass *ptrClass, void *addobj, Int_t bufsize, Int_t splitlevel);
    6960   virtual TBranch *BranchImp(const char *branchname, TClass *ptrClass, void *addobj, Int_t bufsize, Int_t splitlevel);
    70    
     61
    7162public:
    72    MTreeSQL(TSQLServer * server, TString DB, const TString& table, const TString &addon);
     63   MTreeSQL(TSQLServer * server, TString DB, const TString& table, const TString &addon="");
    7364
    7465   virtual Int_t          Branch(TCollection *list, Int_t bufsize=32000, Int_t splitlevel=99, const char *name="");
     
    8879   virtual Long64_t       GetEntries(const char *sel) { return TTree::GetEntries(sel); }
    8980   virtual Long64_t       GetEntriesFast()const;
    90            TString        GetTableName(){ return fTable; }
    9181   virtual Long64_t       LoadTree(Long64_t entry);
    9282   virtual Long64_t       PrepEntry(Long64_t entry);
Note: See TracChangeset for help on using the changeset viewer.