Index: trunk/Mars/msql/MBasketSQL.cc
===================================================================
--- trunk/Mars/msql/MBasketSQL.cc	(revision 15417)
+++ trunk/Mars/msql/MBasketSQL.cc	(revision 15417)
@@ -0,0 +1,165 @@
+// @(#)root/tree:$Id: MBasketSQL.cxx 43518 2012-03-28 01:04:07Z pcanal $
+// Author: Philippe Canal and al. 08/2004
+
+/*************************************************************************
+ * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// MBasketSQL                                                           //
+//                                                                      //
+// Implement TBasket for a SQL backend                                  //
+//                                                                      //
+//////////////////////////////////////////////////////////////////////////
+
+#ifndef TBASKETSQL_CXX
+#define TBASKETSQL_CXX
+
+#include "TBasket.h"
+#include "TTree.h"
+#include "TBranch.h"
+#include "TFile.h"
+#include "TMath.h"
+#include "MBasketSQL.h"
+#include <Riostream.h>
+#include <vector>
+#include "MTreeSQL.h"
+#include "MBufferSQL.h"
+
+ClassImp(MBasketSQL)
+
+namespace std {} using namespace std;
+
+//_________________________________________________________________________
+MBasketSQL::MBasketSQL() : TBasket(), fResultPtr(0), fRowPtr(0), fInsertQuery(0)
+{
+   // Default constructor.
+
+}
+
+//_________________________________________________________________________
+MBasketSQL::MBasketSQL(const char *name, const char *title, TBranch *branch, 
+                         TSQLResult ** rs, TString *insert_query, 
+                         vector<Int_t> *vc, TSQLRow **r) :
+  fResultPtr(rs),fRowPtr(r)
+{ 
+   // Regular constructor.
+
+   SetName(name);
+   SetTitle(title);
+   fClassName   = "MBasketSQL";
+   fBufferSize  = branch->GetBasketSize();
+   fNevBufSize  = branch->GetEntryOffsetLen();
+   fNevBuf      = 0;
+   fEntryOffset = 0;  //Must be set to 0 before calling Sizeof
+   fDisplacement= 0;  //Must be set to 0 before calling Sizeof
+   fBuffer      = 0;  //Must be set to 0 before calling Sizeof
+   fInsertQuery = insert_query;
+
+   if (vc==0) {
+      fBufferRef = 0;
+   } else {
+      fBufferRef = new MBufferSQL(TBuffer::kWrite, fBufferSize, vc, fInsertQuery, fRowPtr);
+   }
+   fHeaderOnly  = kTRUE;
+   fLast        = 0; // Must initialize before calling Streamer()
+   //Streamer(*fBufferRef);
+   fBuffer      = 0;
+   fBranch      = branch;
+   fHeaderOnly  = kFALSE;
+   branch->GetTree()->IncrementTotalBuffers(fBufferSize);
+
+}
+
+//_________________________________________________________________________
+MBasketSQL::~MBasketSQL()
+{
+   // Destructor
+}
+
+//_________________________________________________________________________
+void MBasketSQL::CreateBuffer(const char *name, TString title, 
+                              vector<Int_t> *vc, 
+                              TBranch *branch, TSQLResult ** rs)
+{
+   // Create a TSQLBuffer for this basket.
+
+   fResultPtr = rs;
+   SetName(name);
+   SetTitle(title);
+   fClassName   = "MBasketSQL";
+   fBufferSize  = branch->GetBasketSize();
+   fNevBufSize  = branch->GetEntryOffsetLen();
+   fNevBuf      = 0;
+   fEntryOffset = 0;  //Must be set to 0 before calling Sizeof
+   fDisplacement= 0;  //Must be set to 0 before calling Sizeof
+   fBuffer      = 0;  //Must be set to 0 before calling Sizeof
+
+   if(vc==0) {
+      fBufferRef = 0;
+      Error("CreateBuffer","Need a vector of columns\n");
+   } else {    
+      fBufferRef   = new MBufferSQL(TBuffer::kWrite, fBufferSize, vc, fInsertQuery, fRowPtr);
+   }
+   fHeaderOnly  = kTRUE;
+   fLast        = 0; 
+   //Streamer(*fBufferRef);
+   fBuffer      = 0;
+   fBranch      = branch;
+   fHeaderOnly  = kFALSE;
+   branch->GetTree()->IncrementTotalBuffers(fBufferSize);
+}
+
+//_________________________________________________________________________
+void MBasketSQL::PrepareBasket(Long64_t entry)
+{
+   // Prepare the basket for the next entry.
+
+   ((MBufferSQL*)fBufferRef)->ResetOffset();
+   ((MTreeSQL*)fBranch->GetTree())->PrepEntry(entry);
+   fBufferRef->Reset();
+}
+
+//_________________________________________________________________________
+Int_t MBasketSQL::ReadBasketBytes(Long64_t , TFile *)
+{
+   // See TBasket::ReadBasketBytes.  This is not implemented in MBasketSQL.
+
+   Error("ReadBasketBytes","This member function should not be called!");
+   return 0;
+}
+
+//_________________________________________________________________________
+Int_t MBasketSQL::ReadBasketBuffers(Long64_t , Int_t, TFile *)
+{	 
+   // See TBasket::ReadBasketBuffers.  This is not implemented in MBasketSQL.
+
+   Error("ReadBasketBuffers","This member function should not be called!");
+   return 0;
+}
+
+//_________________________________________________________________________
+void MBasketSQL::Reset()
+{	 
+   // See TBasket::Reset
+
+   TBasket::Reset();
+}
+
+
+//_________________________________________________________________________
+void MBasketSQL::Update(Int_t, Int_t) 
+{
+   // See TBasket::Update.
+
+   ((MBufferSQL*)fBufferRef)->ResetOffset();
+   fNevBuf++;
+}
+
+
+#endif
Index: trunk/Mars/msql/MBasketSQL.h
===================================================================
--- trunk/Mars/msql/MBasketSQL.h	(revision 15417)
+++ trunk/Mars/msql/MBasketSQL.h	(revision 15417)
@@ -0,0 +1,61 @@
+// @(#)root/tree:$Id: MBasketSQL.h 35231 2010-09-10 17:59:10Z pcanal $
+// Author: Philippe Canal 2005
+
+/*************************************************************************
+ * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+#ifndef TBASKETSQL_H
+#define TBASKETSQL_H
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// MBasketSQL                                                           //
+//                                                                      //
+// Implement TBasket for a SQL backend                                  //
+//                                                                      //
+//////////////////////////////////////////////////////////////////////////
+
+#include <vector>
+#include "TBasket.h"
+
+class TSQLResult;
+class TSQLRow;
+class MBufferSQL;
+
+class MBasketSQL : public TBasket
+{
+
+private:
+   MBasketSQL(const MBasketSQL&);            // MBasketSQL objects are not copiable.
+   MBasketSQL& operator=(const MBasketSQL&); // MBasketSQL objects are not copiable.
+
+protected:
+   TSQLResult **fResultPtr;    //!
+   TSQLRow    **fRowPtr;       //!
+   TString      *fInsertQuery; //!
+
+public:
+   MBasketSQL();
+   MBasketSQL(const char *name, const char *title, 
+              TBranch *branch, TSQLResult **rs, 
+              TString *insert_query, std::vector<Int_t> *vc, TSQLRow **row);
+   ~MBasketSQL();
+   void    PrepareBasket(Long64_t entry);
+   virtual Int_t   ReadBasketBuffers(Long64_t pos, Int_t len, TFile *file);
+   virtual Int_t   ReadBasketBytes(Long64_t pos, TFile *file);
+   virtual void    Reset();
+   TSQLResult * GetResultSet() { return *fResultPtr;}
+   void CreateBuffer(const char *name, TString title, std::vector<Int_t> * vc, TBranch *branch, TSQLResult ** rs);
+
+   void Update(Int_t offset, Int_t skipped);
+
+   ClassDef(MBasketSQL,1)  //the TBranch buffers
+
+};
+
+#endif
Index: trunk/Mars/msql/MBufferSQL.cc
===================================================================
--- trunk/Mars/msql/MBufferSQL.cc	(revision 15417)
+++ trunk/Mars/msql/MBufferSQL.cc	(revision 15417)
@@ -0,0 +1,810 @@
+// @(#)root/tree:$Id: MBufferSQL.cxx 43518 2012-03-28 01:04:07Z pcanal $
+// Author: Philippe Canal and al. 08/2004
+
+/*************************************************************************
+ * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// MBufferSQL                                                           //
+//                                                                      //
+// Implement TBuffer for a SQL backend                                  //
+//                                                                      //
+//////////////////////////////////////////////////////////////////////////
+
+#include <vector>
+#include <stdio.h>
+#include "TError.h"
+
+#include "MBufferSQL.h"
+#include "TSQLResult.h"
+#include "TSQLRow.h"
+#include <stdlib.h>
+
+using namespace std;
+
+ClassImp(MBufferSQL);
+
+//________________________________________________________________________
+MBufferSQL::MBufferSQL(TBuffer::EMode mode, vector<Int_t> *vc, 
+                       TString *insert_query, TSQLRow ** r) : 
+   TBufferFile(mode),
+   fColumnVec(vc), fInsertQuery(insert_query), fRowPtr(r) 
+{
+   // Constructor.
+
+   fIter = fColumnVec->begin();
+}
+
+//________________________________________________________________________
+MBufferSQL::MBufferSQL(TBuffer::EMode mode, Int_t bufsiz, vector<Int_t> *vc, 
+                       TString *insert_query, TSQLRow ** r) : 
+   TBufferFile(mode,bufsiz), 
+   fColumnVec(vc), fInsertQuery(insert_query), fRowPtr(r) 
+{
+   // Constructor.
+
+   fIter = fColumnVec->begin();
+}
+
+//________________________________________________________________________
+MBufferSQL::MBufferSQL(TBuffer::EMode mode, Int_t bufsiz, vector<Int_t> *vc, 
+                       TString *insert_query, TSQLRow ** r,
+                       void *buf, Bool_t adopt) : 
+   TBufferFile(mode,bufsiz,buf,adopt),
+   fColumnVec(vc), fInsertQuery(insert_query), fRowPtr(r) 
+{
+   // Constructor.
+
+   fIter = fColumnVec->begin();
+}
+
+//________________________________________________________________________
+MBufferSQL::MBufferSQL() : TBufferFile(), fColumnVec(0),fInsertQuery(0),fRowPtr(0)
+{
+   // Constructor.
+
+}
+
+//________________________________________________________________________
+MBufferSQL::~MBufferSQL() 
+{
+   // Destructo.
+
+   delete fColumnVec;
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadBool(Bool_t &b) 
+{
+   // Operator>>
+   const char *ptr = (*fRowPtr)->GetField(*fIter);
+
+   b = (Bool_t)atoi(ptr?ptr:"");
+
+   if (fIter != fColumnVec->end()) ++fIter;
+
+   if(ptr==0) Error("operator>>(Bool_t&)","Error reading Bool_t");
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadChar(Char_t &c)
+{
+   // Operator>>
+   const char *ptr = (*fRowPtr)->GetField(*fIter);
+
+   c = (Char_t)atoi(ptr?ptr:"");
+
+   if (fIter != fColumnVec->end()) ++fIter;
+
+   if(ptr==0) Error("operator>>(Char_t&)","Error reading Char_t");
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadShort(Short_t &h)
+{
+   // Operator>>
+   const char *ptr = (*fRowPtr)->GetField(*fIter);
+
+   h = (Short_t)atoi(ptr?ptr:"");
+
+   if (fIter != fColumnVec->end()) ++fIter;
+
+   if(ptr==0) Error("operator>>(Short_t&)","Error reading Short_t");
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadInt(Int_t &i)
+{
+   // Operator>>
+   const char *ptr = (*fRowPtr)->GetField(*fIter);
+
+   i = atoi(ptr?ptr:"");
+
+   if (fIter != fColumnVec->end()) ++fIter;
+
+   if(ptr==0) Error("operator>>(Int_t&)","Error reading Int_t");
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadFloat(Float_t &f)
+{
+   // Operator>>
+   const char *ptr = (*fRowPtr)->GetField(*fIter);
+
+   f = atof(ptr?ptr:"");
+
+   if (fIter != fColumnVec->end()) ++fIter;
+
+   if(ptr==0) Error("operator>>(Float_t&)","Error reading Float_t");
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadLong(Long_t &l)
+{
+   // Operator>>
+   const char *ptr = (*fRowPtr)->GetField(*fIter);
+
+   l = atol(ptr?ptr:"");
+
+   if (fIter != fColumnVec->end()) ++fIter;
+
+   if(ptr==0) Error("operator>>(Long_t&)","Error reading Long_t");
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadDouble(Double_t &d)
+{
+   // Operator>>
+   const char *ptr = (*fRowPtr)->GetField(*fIter);
+
+   d = atof(ptr?ptr:"");
+
+   if (fIter != fColumnVec->end()) ++fIter;
+
+   if(ptr==0) Error("operator>>(Double_t&)","Error reading Double_t");
+}
+
+
+//________________________________________________________________________
+void MBufferSQL::WriteBool(Bool_t    b)
+{
+   // Operator<<
+
+   (*fInsertQuery) += b;
+   (*fInsertQuery) += ",";
+   if (fIter != fColumnVec->end()) ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteChar(Char_t    c)
+{
+   // Operator<<
+
+   (*fInsertQuery) += c;
+   (*fInsertQuery) += ",";
+   if (fIter != fColumnVec->end()) ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteShort(Short_t   h)
+{
+   // Operator<<
+
+   (*fInsertQuery) += h;
+   (*fInsertQuery) += ",";
+   if (fIter != fColumnVec->end()) ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteInt(Int_t     i)
+{
+   // Operator<<
+
+   (*fInsertQuery) += i;
+   (*fInsertQuery) += ",";
+   if (fIter != fColumnVec->end()) ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteLong(Long_t    l)
+{
+   // Operator<<
+
+   (*fInsertQuery) += l;
+   (*fInsertQuery) += ",";
+   if (fIter != fColumnVec->end()) ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteFloat(Float_t   f)
+{
+   // Operator<<
+
+   (*fInsertQuery) += f;
+   (*fInsertQuery) += ",";
+   if (fIter != fColumnVec->end()) ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteDouble(Double_t  d)
+{
+   // Operator<<
+
+   (*fInsertQuery) += d;
+   (*fInsertQuery) += ",";
+   if (fIter != fColumnVec->end()) ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadUChar(UChar_t& uc)
+{
+   // Operator>>
+   const char *ptr = (*fRowPtr)->GetField(*fIter);
+
+   uc = (UChar_t)atoi(ptr?ptr:"");
+
+   if (fIter != fColumnVec->end()) ++fIter;
+
+   if(ptr==0) Error("operator>>(UChar_t&)","Error reading UChar_t");
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadUShort(UShort_t& us)
+{
+   // Operator>>
+   const char *ptr = (*fRowPtr)->GetField(*fIter);
+
+   us = (UShort_t)atoi(ptr?ptr:"");
+
+   if (fIter != fColumnVec->end()) ++fIter;
+
+   if(ptr==0) Error("operator>>(UShort_t&)","Error reading UShort_t");
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadUInt(UInt_t& ui)
+{
+   // Operator>>
+
+   TString val = (*fRowPtr)->GetField(*fIter);
+   Int_t code = sscanf(val.Data(), "%u",&ui);
+   if(code == 0) Error("operator>>(UInt_t&)","Error reading UInt_t");
+
+   if (fIter != fColumnVec->end()) ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadULong(ULong_t& ul)
+{
+   // Operator>>
+
+   TString val = (*fRowPtr)->GetField(*fIter);
+   Int_t code = sscanf(val.Data(), "%lu",&ul);
+   if(code == 0) Error("operator>>(ULong_t&)","Error reading ULong_t");
+
+   if (fIter != fColumnVec->end()) ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadLong64(Long64_t &ll)
+{
+   // Operator>>
+
+   TString val = (*fRowPtr)->GetField(*fIter);
+   Int_t code = sscanf(val.Data(), "%lld",&ll);
+   if(code == 0) Error("operator>>(ULong_t&)","Error reading Long64_t");
+
+   if (fIter != fColumnVec->end()) ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadULong64(ULong64_t &ull)
+{
+   // Operator>>
+
+   TString val = (*fRowPtr)->GetField(*fIter);
+   Int_t code = sscanf(val.Data(), "%llu",&ull);
+   if(code == 0) Error("operator>>(ULong_t&)","Error reading ULong64_t");
+
+   if (fIter != fColumnVec->end()) ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadCharP(Char_t *str)
+{
+   // Operator>>
+
+   strcpy(str,(*fRowPtr)->GetField(*fIter));  // Legacy interface, we have no way to know the user's buffer size ....
+   if (fIter != fColumnVec->end()) ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadTString(TString   &)
+{
+   // Operator>>
+
+   //strcpy(str,(*fRowPtr)->GetField(*fIter));
+   //if (fIter != fColumnVec->end()) ++fIter;
+   printf("ERROR NOT IMPLEMENTED\n");
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteTString(const TString   &)
+{
+   // Operator>>
+
+   //strcpy(str,(*fRowPtr)->GetField(*fIter));
+   //if (fIter != fColumnVec->end()) ++fIter;
+   printf("ERROR NOT IMPLEMENTED\n");
+}
+
+// Method to send to database.
+
+//________________________________________________________________________
+void MBufferSQL::WriteUChar(UChar_t uc)
+{
+   // Operator<<
+
+   (*fInsertQuery) += uc;
+   (*fInsertQuery) += ",";
+   ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteUShort(UShort_t us)
+{
+   // Operator<<
+
+   (*fInsertQuery) += us;
+   (*fInsertQuery) += ",";
+   ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteUInt(UInt_t ui)
+{
+   // Operator<<
+
+   (*fInsertQuery) += ui;
+   (*fInsertQuery) += ",";
+   ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteULong(ULong_t ul)
+{
+   // Operator<<
+
+   (*fInsertQuery) += ul;
+   (*fInsertQuery) += ",";
+   ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteLong64(Long64_t ll)
+{
+   // Operator<<
+
+   (*fInsertQuery) += ll;
+   (*fInsertQuery) += ",";
+   ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteULong64(ULong64_t ull)
+{
+   // Operator<<
+
+   (*fInsertQuery) += ull;
+   (*fInsertQuery) += ",";
+   ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteCharP(const Char_t *str)
+{
+   // Operator<<
+
+   (*fInsertQuery) += "\"";
+   (*fInsertQuery) += str;
+   (*fInsertQuery) += "\",";
+   ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteFastArray(const Bool_t *b, Int_t n)
+{
+   // WriteFastArray SQL implementation.   
+   for(int i=0; i<n; ++i) {
+      (*fInsertQuery) += b[i];
+      (*fInsertQuery) += ",";
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteFastArray(const Char_t *c, Int_t n)
+{
+   // WriteFastArray SQL implementation.   
+
+   for(int i=0; i<n; ++i) {
+      (*fInsertQuery) += (Short_t)c[i];
+      (*fInsertQuery) += ",";
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteFastArrayString(const Char_t *c, Int_t /* n */)
+{
+   // WriteFastArray SQL implementation.   
+
+   (*fInsertQuery) += "\"";
+   (*fInsertQuery) += c;
+   (*fInsertQuery) += "\",";
+   ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteFastArray(const UChar_t *uc, Int_t n)
+{
+   // WriteFastArray SQL implementation.   
+
+   for(int i=0; i<n; ++i) {
+      (*fInsertQuery) += uc[i];
+      (*fInsertQuery) += ",";
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteFastArray(const Short_t *h, Int_t n)
+{
+   // WriteFastArray SQL implementation.   
+
+   for(int i=0; i<n; ++i) {
+      (*fInsertQuery) += h[i];
+      (*fInsertQuery) += ",";
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteFastArray(const UShort_t *us, Int_t n)
+{
+   // WriteFastArray SQL implementation.   
+
+   for(int i=0; i<n; ++i) {
+      (*fInsertQuery) += us[i];
+      (*fInsertQuery) += ",";
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteFastArray(const Int_t     *ii, Int_t n)
+{
+   // WriteFastArray SQL implementation.   
+
+    //   cerr << "Column: " <<*fIter << "   i:" << *ii << endl;
+   for(int i=0; i<n; ++i) {
+      (*fInsertQuery) += ii[i];
+      (*fInsertQuery) += ",";
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteFastArray(const UInt_t *ui, Int_t n)
+{
+   // WriteFastArray SQL implementation.   
+
+   for(int i=0; i<n; ++i) {
+      (*fInsertQuery) += ui[i];
+      (*fInsertQuery) += ",";
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteFastArray(const Long_t    *l, Int_t n)
+{
+   // WriteFastArray SQL implementation.   
+
+   for(int i=0; i<n; ++i) {
+      (*fInsertQuery)+= l[i];
+      (*fInsertQuery)+= ",";
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteFastArray(const ULong_t   *ul, Int_t n)
+{
+   // WriteFastArray SQL implementation.   
+
+   for(int i=0; i<n; ++i) {
+      (*fInsertQuery) += ul[i];
+      (*fInsertQuery) += ",";
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteFastArray(const Long64_t  *l, Int_t n)
+{
+   // WriteFastArray SQL implementation.   
+
+   for(int i=0; i<n; ++i) {
+      (*fInsertQuery) += l[i];
+      (*fInsertQuery) += ",";
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteFastArray(const ULong64_t *ul, Int_t n)
+{
+   // WriteFastArray SQL implementation.   
+
+   for(int i=0; i<n; ++i) {
+      (*fInsertQuery) += ul[i];
+      (*fInsertQuery) += ",";
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteFastArray(const Float_t   *f, Int_t n)
+{
+   // WriteFastArray SQL implementation.   
+
+   for(int i=0; i<n; ++i) {
+      (*fInsertQuery) += f[i];
+      (*fInsertQuery) += ",";
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteFastArray(const Double_t  *d, Int_t n)
+{
+   // WriteFastArray SQL implementation.   
+
+   for(int i=0; i<n; ++i) {
+      (*fInsertQuery) += d[i];
+      (*fInsertQuery )+= ",";
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::WriteFastArray(void*, const TClass*, Int_t, TMemberStreamer *)
+{
+   // WriteFastArray SQL implementation.   
+
+   Fatal("riteFastArray(void*, const TClass*, Int_t, TMemberStreamer *)","Not implemented yet");
+}
+
+//________________________________________________________________________
+Int_t MBufferSQL::WriteFastArray(void **, const TClass*, Int_t, Bool_t, TMemberStreamer*)
+{
+   // WriteFastArray SQL implementation.   
+
+   Fatal("WriteFastArray(void **, const TClass*, Int_t, Bool_t, TMemberStreamer*)","Not implemented yet");
+   return 0;
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadFastArray(Bool_t *b, Int_t n)
+{
+   // ReadFastArray SQL implementation.   
+
+   for(int i=0; i<n; ++i) {  
+      b[i] = (Bool_t)atoi((*fRowPtr)->GetField(*fIter));
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadFastArray(Char_t *c, Int_t n)
+{
+   // ReadFastArray SQL implementation.   
+   for(int i=0; i<n; ++i) {  
+      c[i] = (Char_t)atoi((*fRowPtr)->GetField(*fIter));
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadFastArrayString(Char_t *c, Int_t /* n */)
+{
+   // ReadFastArray SQL implementation.   
+   strcpy(c,((*fRowPtr)->GetField(*fIter)));
+   ++fIter;
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadFastArray(UChar_t *uc, Int_t n)
+{
+   // ReadFastArray SQL implementation.   
+   for(int i=0; i<n; ++i) {  
+      uc[i] = (UChar_t)atoi((*fRowPtr)->GetField(*fIter));
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadFastArray(Short_t *s, Int_t n)
+{
+   // ReadFastArray SQL implementation.   
+   for(int i=0; i<n; ++i) {  
+      s[i] = (Short_t)atoi((*fRowPtr)->GetField(*fIter));
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadFastArray(UShort_t *us, Int_t n)
+{
+   // ReadFastArray SQL implementation.   
+   for(int i=0; i<n; ++i) {  
+      us[i] = (UShort_t)atoi((*fRowPtr)->GetField(*fIter));
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void     MBufferSQL::ReadFastArray(Int_t *in, Int_t n)
+{
+   // ReadFastArray SQL implementation.   
+   for(int i=0; i<n; ++i) {  
+      in[i] = atoi((*fRowPtr)->GetField(*fIter));
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void     MBufferSQL::ReadFastArray(UInt_t *ui, Int_t n)
+{
+   // ReadFastArray SQL implementation.   
+   for(int i=0; i<n; ++i) {  
+      ui[i] = atoi((*fRowPtr)->GetField(*fIter));
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadFastArray(Long_t *l, Int_t n)
+{
+   // ReadFastArray SQL implementation.   
+   for(int i=0; i<n; ++i) {  
+      l[i] = atol((*fRowPtr)->GetField(*fIter));
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadFastArray(ULong_t   *ul, Int_t n)
+{
+   // ReadFastArray SQL implementation.   
+   for(int i=0; i<n; ++i) {  
+      (*this) >> ul[i];
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadFastArray(Long64_t  *ll, Int_t n)
+{
+   // ReadFastArray SQL implementation.   
+   for(int i=0; i<n; ++i) {  
+      (*this) >> ll[i];
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadFastArray(ULong64_t *ull, Int_t n)
+{
+   // ReadFastArray SQL implementation.   
+   for(int i=0; i<n; ++i) {  
+      (*this) >> ull[i];
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadFastArray(Float_t   *f, Int_t n)
+{
+   // ReadFastArray SQL implementation.   
+   for(int i=0; i<n; ++i) {  
+      f[i] = atof((*fRowPtr)->GetField(*fIter));
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void MBufferSQL::ReadFastArray(Double_t *d, Int_t n)
+{
+   // ReadFastArray SQL implementation.   
+   for(int i=0; i<n; ++i) {  
+      d[i] = atof((*fRowPtr)->GetField(*fIter));
+      ++fIter;
+   }
+}
+
+//________________________________________________________________________
+void     MBufferSQL::ReadFastArrayFloat16(Float_t  *, Int_t , TStreamerElement *)
+{
+   // ReadFastArray SQL implementation.   
+   Fatal("ReadFastArrayFloat16(Float_t  *, Int_t , TStreamerElement *)","Not implemented yet");
+}
+
+//________________________________________________________________________
+void     MBufferSQL::ReadFastArrayDouble32(Double_t  *, Int_t , TStreamerElement *)
+{
+   // ReadFastArray SQL implementation.   
+   Fatal("ReadFastArrayDouble32(Double_t  *, Int_t , TStreamerElement *)","Not implemented yet");
+}
+
+//________________________________________________________________________
+void     MBufferSQL::ReadFastArray(void  *, const TClass *, Int_t, TMemberStreamer *, const TClass *)
+{
+   // ReadFastArray SQL implementation.   
+   Fatal("ReadFastArray(void  *, const TClass *, Int_t, TMemberStreamer *, const TClass *)","Not implemented yet");
+}
+
+//________________________________________________________________________
+void     MBufferSQL::ReadFastArray(void **, const TClass *, Int_t, Bool_t, TMemberStreamer *, const TClass *)
+{
+   // ReadFastArray SQL implementation.   
+   Fatal("ReadFastArray(void **, const TClass *, Int_t, Bool_t, TMemberStreamer *, const TClass *)","Not implemented yet");
+}
+
+//________________________________________________________________________
+void MBufferSQL::ResetOffset() 
+{
+   // Reset Offset.
+   fIter = fColumnVec->begin();
+}
+
+#if 0
+//________________________________________________________________________
+void MBufferSQL::insert_test(const char* dsn, const char* usr, 
+                             const char* pwd, const TString& tblname) 
+{
+   TString str;
+   TString select = "select * from ";
+   TString sql;
+   TSQLStatement* stmt; 
+   sql = select + "ins";
+
+   con = gSQLDriverManager->GetConnection(dsn,usr,pwd);
+
+   if(!con)
+      printf("\n\n\nConnection NOT Successful\n\n\n");
+   else
+      printf("\n\n\nConnection Sucessful\n\n\n");
+
+
+
+   stmt = con->CreateStatement(0, odbc::ResultSet::CONCUR_READ_ONLY);
+
+   ptr = stmt->ExecuteQuery(sql.Data()); 
+   if(!ptr) printf("No recorSet found!");	
+
+   ptr->Next();
+   ptr->MoveToInsertRow();
+   cerr << "IsAfterLast(): " << ptr->IsAfterLast() << endl;
+   ptr->UpdateInt(1, 5555);
+   ptr->InsertRow();
+   con->Commit();
+
+   ptr1 = stmt->ExecuteQuery(sql.Data());
+
+}
+#endif
Index: trunk/Mars/msql/MBufferSQL.h
===================================================================
--- trunk/Mars/msql/MBufferSQL.h	(revision 15417)
+++ trunk/Mars/msql/MBufferSQL.h	(revision 15417)
@@ -0,0 +1,131 @@
+// @(#)root/tree:$Id: MBufferSQL.h 25450 2008-09-18 21:13:42Z pcanal $
+// Author: Philippe Canal 2005
+
+/*************************************************************************
+ * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+#ifndef ROOT_MBufferSQL
+#define ROOT_MBufferSQL
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// MBufferSQL                                                           //
+//                                                                      //
+// Implement TBuffer for a SQL backend                                  //
+//                                                                      //
+//////////////////////////////////////////////////////////////////////////
+
+#ifndef ROOT_TBufferFile
+#include "TBufferFile.h"
+#endif
+#ifndef ROOT_TString
+#include "TString.h"
+#endif
+
+
+class TSQLResult;
+class TSQLRow;
+
+class MBufferSQL : public TBufferFile {
+
+private:
+   std::vector<Int_t>::const_iterator fIter;
+
+   std::vector<Int_t>  *fColumnVec;   //!
+   TString             *fInsertQuery; //!
+   TSQLRow            **fRowPtr;      //!
+
+   // TBuffer objects cannot be copied or assigned
+   MBufferSQL(const MBufferSQL &);        // not implemented
+   void operator=(const MBufferSQL &);    // not implemented
+
+public:
+   MBufferSQL();
+   MBufferSQL(TBuffer::EMode mode, std::vector<Int_t> *vc, TString *insert_query, TSQLRow **rowPtr);
+   MBufferSQL(TBuffer::EMode mode, Int_t bufsiz, std::vector<Int_t> *vc, TString *insert_query, TSQLRow **rowPtr);
+   MBufferSQL(TBuffer::EMode mode, Int_t bufsiz, std::vector<Int_t> *vc, TString *insert_query, TSQLRow **rowPtr,void *buf, Bool_t adopt = kTRUE);
+   ~MBufferSQL();
+
+   void ResetOffset();
+
+   virtual   void     ReadBool(Bool_t       &b);
+   virtual   void     ReadChar(Char_t       &c);
+   virtual   void     ReadUChar(UChar_t     &c);
+   virtual   void     ReadShort(Short_t     &s);
+   virtual   void     ReadUShort(UShort_t   &s);
+   virtual   void     ReadInt(Int_t         &i);
+   virtual   void     ReadUInt(UInt_t       &i);
+   virtual   void     ReadLong(Long_t       &l);
+   virtual   void     ReadULong(ULong_t     &l);
+   virtual   void     ReadLong64(Long64_t   &l);
+   virtual   void     ReadULong64(ULong64_t &l);
+   virtual   void     ReadFloat(Float_t     &f);
+   virtual   void     ReadDouble(Double_t   &d);
+   virtual   void     ReadCharP(Char_t      *c);
+   virtual   void     ReadTString(TString   &s);
+
+   virtual   void     WriteBool(Bool_t       b);
+   virtual   void     WriteChar(Char_t       c);
+   virtual   void     WriteUChar(UChar_t     c);
+   virtual   void     WriteShort(Short_t     s);
+   virtual   void     WriteUShort(UShort_t   s);
+   virtual   void     WriteInt(Int_t         i);
+   virtual   void     WriteUInt(UInt_t       i);
+   virtual   void     WriteLong(Long_t       l);
+   virtual   void     WriteULong(ULong_t     l);
+   virtual   void     WriteLong64(Long64_t   l);
+   virtual   void     WriteULong64(ULong64_t l);
+   virtual   void     WriteFloat(Float_t     f);
+   virtual   void     WriteDouble(Double_t   d);
+   virtual   void     WriteCharP(const Char_t *c);
+   virtual   void     WriteTString(const TString  &s);
+
+
+   virtual   void     WriteFastArray(const Bool_t    *b, Int_t n);
+   virtual   void     WriteFastArray(const Char_t    *c, Int_t n);
+   virtual   void     WriteFastArrayString(const Char_t   *c, Int_t n);
+   virtual   void     WriteFastArray(const UChar_t   *c, Int_t n);
+   virtual   void     WriteFastArray(const Short_t   *h, Int_t n);
+   virtual   void     WriteFastArray(const UShort_t  *h, Int_t n);
+   virtual   void     WriteFastArray(const Int_t     *i, Int_t n);
+   virtual   void     WriteFastArray(const UInt_t    *i, Int_t n);
+   virtual   void     WriteFastArray(const Long_t    *l, Int_t n);
+   virtual   void     WriteFastArray(const ULong_t   *l, Int_t n);
+   virtual   void     WriteFastArray(const Long64_t  *l, Int_t n);
+   virtual   void     WriteFastArray(const ULong64_t *l, Int_t n);
+   virtual   void     WriteFastArray(const Float_t   *f, Int_t n);
+   virtual   void     WriteFastArray(const Double_t  *d, Int_t n);
+   virtual   void     WriteFastArray(void  *start,  const TClass *cl, Int_t n=1, TMemberStreamer *s=0);
+   virtual   Int_t    WriteFastArray(void **startp, const TClass *cl, Int_t n=1, Bool_t isPreAlloc=kFALSE, TMemberStreamer *s=0);
+
+   virtual   void     ReadFastArray(Bool_t    *, Int_t );
+   virtual   void     ReadFastArray(Char_t    *, Int_t );
+   virtual   void     ReadFastArrayString(Char_t   *, Int_t );
+   virtual   void     ReadFastArray(UChar_t   *, Int_t );
+   virtual   void     ReadFastArray(Short_t   *, Int_t );
+   virtual   void     ReadFastArray(UShort_t  *, Int_t );
+   virtual   void     ReadFastArray(Int_t     *, Int_t );
+   virtual   void     ReadFastArray(UInt_t    *, Int_t );
+   virtual   void     ReadFastArray(Long_t    *, Int_t );
+   virtual   void     ReadFastArray(ULong_t   *, Int_t );
+   virtual   void     ReadFastArray(Long64_t  *, Int_t );
+   virtual   void     ReadFastArray(ULong64_t *, Int_t );
+   virtual   void     ReadFastArray(Float_t   *, Int_t );
+   virtual   void     ReadFastArray(Double_t  *, Int_t );
+   virtual   void     ReadFastArrayFloat16(Float_t  *f, Int_t n, TStreamerElement *ele=0);
+   virtual   void     ReadFastArrayDouble32(Double_t  *d, Int_t n, TStreamerElement *ele=0);
+   virtual   void     ReadFastArray(void  *, const TClass *, Int_t n=1, TMemberStreamer *s=0, const TClass *onFileClass=0);
+   virtual   void     ReadFastArray(void **, const TClass *, Int_t n=1, Bool_t isPreAlloc=kFALSE, TMemberStreamer *s=0, const TClass *onFileClass=0);
+
+   ClassDef(MBufferSQL, 1); // Implementation of TBuffer to load and write to a SQL database
+
+};
+
+#endif
+
+
Index: trunk/Mars/msql/MTreeSQL.cc
===================================================================
--- trunk/Mars/msql/MTreeSQL.cc	(revision 15417)
+++ trunk/Mars/msql/MTreeSQL.cc	(revision 15417)
@@ -0,0 +1,806 @@
+// @(#)root/tree:$Id: MTreeSQL.cxx 43270 2012-03-06 22:46:11Z pcanal $
+// Author: Philippe Canal and al. 08/2004
+
+/*************************************************************************
+ * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// MTreeSQL                                                             //
+//                                                                      //
+// Implement TTree for a SQL backend                                    //
+//                                                                      //
+//////////////////////////////////////////////////////////////////////////
+
+#include <Riostream.h>
+#include <vector>
+#include <map>
+#include <stdlib.h>
+
+#include "TString.h"
+#include "TROOT.h"
+#include "TSystem.h"
+#include "TError.h"
+#include "TFile.h"
+#include "TTree.h"
+#include "TLeaf.h"
+#include "TBranch.h"
+
+#include "TSQLRow.h"
+#include "TSQLResult.h"
+#include "TSQLServer.h"
+
+#include "MTreeSQL.h"
+#include "MBasketSQL.h"
+
+ClassImp(MTreeSQL);
+
+using namespace std;
+
+//______________________________________________________________________________
+MTreeSQL::MTreeSQL(TSQLServer *server, TString DB, const TString& table, const TString &addon) :
+   TTree(table.Data(), "Database read from table: " + table, 0), fDB(DB),
+   fTable(table.Data()),
+   fResult(0), fRow(0),
+   fServer(server),
+   fBranchChecked(kFALSE)
+{
+   // Constructor with an explicit TSQLServer
+
+   fCurrentEntry = -1;
+   fQuery = TString("Select * from " + fTable + " " + addon);
+   fEntries = 0;
+
+   if (fServer==0) {
+      Error("MTreeSQL","No TSQLServer specified");
+      return;
+   }
+   if (CheckTable(fTable.Data())) {
+      Init();
+   }
+}
+
+//______________________________________________________________________________
+TBranch* MTreeSQL::BranchImp(const char *, const char *,
+                             TClass *, void *, Int_t ,
+                             Int_t )
+{
+   // Not implemented yet
+
+   Fatal("BranchImp","Not implemented yet");
+   return 0;
+}
+
+//______________________________________________________________________________
+TBranch* MTreeSQL::BranchImp(const char *, TClass *,
+                             void *, Int_t , Int_t )
+{
+   // Not implemented yet
+
+   Fatal("BranchImp","Not implemented yet");
+   return 0;
+}
+
+//______________________________________________________________________________
+Int_t MTreeSQL::Branch(TCollection *, Int_t,
+                       Int_t, const char *)
+{
+   // Not implemented yet
+
+   Fatal("Branch","Not implemented yet");
+   return 0;
+}
+
+//______________________________________________________________________________
+Int_t MTreeSQL::Branch(TList *, Int_t, Int_t)
+{
+   // Not implemented yet
+
+   Fatal("Branch","Not implemented yet");
+   return 0;
+}
+
+//______________________________________________________________________________
+Int_t MTreeSQL::Branch(const char *, Int_t ,
+                       Int_t)
+{
+   // Not implemented yet
+
+   Fatal("Branch","Not implemented yet");
+   return 0;
+}
+
+//______________________________________________________________________________
+TBranch* MTreeSQL::Bronch(const char *, const char *, void *,
+                          Int_t, Int_t)
+{
+   // Not implemented yet
+
+   Fatal("Bronc","Not implemented yet");
+   return 0;
+}
+
+//______________________________________________________________________________
+TBranch* MTreeSQL::BranchOld(const char *, const char *,
+                             void *, Int_t, Int_t)
+{
+   // Not implemented yet
+
+   Fatal("BranchOld","Not implemented yet");
+   return 0;
+}
+
+//______________________________________________________________________________
+TBranch *MTreeSQL::Branch(const char *, const char *, void *,
+                          Int_t, Int_t)
+{
+   // Not implemented yet
+
+   Fatal("Branch","Not implemented yet");
+   return 0;
+}
+
+//______________________________________________________________________________
+TBranch * MTreeSQL::Branch(const char *name, void *address,
+                           const char *leaflist, Int_t bufsize)
+{
+   // Create a branch
+
+   Int_t nb = fBranches.GetEntriesFast();
+   TBranch *branch;
+   TString brName;
+
+   for (int i=0;i<nb;i++) {
+      branch = (TBranch*)fBranches.UncheckedAt(i);
+      brName = branch->GetName();
+      if (brName.Index(name) == 0) {
+         // Now if the branch exists in db, root gives a warning and exit
+         // Dealing with duplicate branch has been done, but not tested yet.
+         // So if you want to allow duplicate branch, just comment Fatal() line and uncomment commented
+         // below Fatal() line
+
+         Fatal("Branch()", "Duplicate branch!!!");
+
+         /* Commented. If uncommented, should comment Fatal line.
+         // this is a duplicate branch. So reset data structure memory address and return.
+         branch->SetAddress(address);
+         return branch;
+         */
+      }
+   }
+   return TTree::Branch(name, address, leaflist, bufsize);
+}
+
+//______________________________________________________________________________
+void MTreeSQL::CheckBasket(TBranch *branch)
+{
+   // Check if the basket is properly setup
+
+   MBasketSQL* basket = (MBasketSQL *)branch->GetBasket(0);
+
+   if (basket==0) {
+      basket = (MBasketSQL*)CreateBasket(branch);
+      if (basket==0) return;
+      //++(branch->fNBaskets);
+      branch->GetListOfBaskets()->AddAtAndExpand(basket,0);
+   }
+   TBuffer * buffer = basket->GetBufferRef();
+
+   if(buffer == 0){
+      vector<Int_t> *columns = GetColumnIndice(branch);
+      if (columns) basket->CreateBuffer(branch->GetName(),"A", columns, branch, &fResult);
+   }
+
+   Int_t nb = branch->GetListOfBranches()->GetEntriesFast();
+   for (int i=0;i<nb;i++) {
+      TBranch * subbranch = (TBranch*)branch->GetListOfBranches()->UncheckedAt(i);
+      if(subbranch) CheckBasket(subbranch);
+   }
+}
+
+//______________________________________________________________________________
+Bool_t MTreeSQL::CheckBranch(TBranch * tb)
+{
+   // Check if the table has a column corresponding the branch
+   // and that the resultset are properly setup
+
+   if (fServer==0) {
+      return kFALSE;
+   }
+   TString leafName;
+   TLeaf *leaf;
+   Int_t nl;
+   TString str = "";
+   TString typeName = "";
+
+   if (!tb) return kFALSE;
+
+   MBasketSQL *basket = (MBasketSQL *)tb->GetBasket(0);
+   if (!basket) return kFALSE;
+
+   TSQLResult *rs = basket->GetResultSet();
+   if (!rs) {
+      Error("CheckBranch","%s has basket but no resultset yet",tb->GetName());
+      return kFALSE;
+   }
+
+   nl = tb->GetNleaves();
+
+   for(int j=0;j<nl;j++) {
+      leaf = (TLeaf*)tb->GetListOfLeaves()->UncheckedAt(j);
+      typeName = leaf->GetTypeName();
+      typeName = ConvertTypeName(leaf->GetTypeName());
+      leafName = leaf->GetName();
+      str = "";
+      str = tb->GetName();
+      str += "__";
+      str += leafName;
+
+      for (int i=0; i< rs->GetFieldCount(); ++i) {
+         if (str.CompareTo(rs->GetFieldName(i),TString::kIgnoreCase) == 0) return kTRUE;
+      }
+      // We assume that if ONE of the leaf is in the table, then ALL the leaf are in
+      // the table.
+      // TODO: this assumption is harmful if user changes branch structure while keep its name
+      CreateBranch(str, typeName);
+   }
+   return kFALSE;
+}
+
+//______________________________________________________________________________
+Bool_t MTreeSQL::CheckTable(const TString &table) const
+{
+   // Check the table exist in the database
+
+   if (fServer==0) return kFALSE;
+   TSQLResult * tables = fServer->GetTables(fDB.Data(),table);
+   if (!tables) return kFALSE;
+   TSQLRow * row = 0;
+   while( (row = tables->Next()) ) {
+      if(table.CompareTo(row->GetField(0),TString::kIgnoreCase)==0){
+         return kTRUE;
+      }
+   }
+   // The table is a not a permanent table, let's see if it is a 'temporary' table
+   Int_t before = gErrorIgnoreLevel;
+   gErrorIgnoreLevel = kFatal;
+   TSQLResult *res = fServer->GetColumns(fDB.Data(),table);
+   if (res) {
+      delete res;
+      return kTRUE;
+   }
+   gErrorIgnoreLevel = before;
+
+   return kFALSE;
+}
+
+//______________________________________________________________________________
+TString MTreeSQL::ConvertTypeName(const TString& typeName )
+{
+   // Convert from ROOT typename to SQL typename
+
+   TString tn = "";
+
+   if(typeName == "Char_t"){
+      tn = "TEXT";
+   }
+   else if(typeName == "Int_t") {
+      tn = "INTEGER";
+   }
+   else if(typeName == "Short_t") {
+      tn = "SMALLINT";
+   }
+   else if( typeName == "UShort_t") {
+      tn = "SMALLINT UNSIGNED";
+   }
+   else if(typeName == "Float_t"){
+      tn = "FLOAT";
+   }
+   else if(typeName == "Float16_t"){
+      tn = "FLOAT";
+   }
+   else if(typeName == "Double_t"){
+      tn = "DOUBLE";
+   }
+   else if(typeName == "Double32_t"){
+      tn = "FLOAT";
+   }
+   else if(typeName == "UInt_t") {
+      tn = "INT UNSIGNED";
+   }
+   else if( typeName == "Long_t") {
+      tn = "INTEGER";
+   }
+   else if( typeName == "ULong_t") {
+      tn = "INTEGER UNSIGNED";
+   }
+   else if( typeName == "Long64_t") {
+      tn = "BIGINT";
+   }
+   else if( typeName == "ULong64_t") {
+      tn = "BIGINT UNSIGNED";
+   }
+   else if( typeName == "Bool_t") {
+      tn = "BOOL";
+   }
+   else {
+      Error("ConvertTypeName","TypeName (%s) not found",typeName.Data());
+      return "";
+   }
+
+   return tn;
+}
+
+//______________________________________________________________________________
+TBasket * MTreeSQL::CreateBasket(TBranch * tb)
+{
+   // Create a TBasketSQL
+
+   if (fServer==0) {
+      Error("CreateBasket","No TSQLServer specified");
+      return 0;
+   }
+   vector<Int_t> *columnVec = GetColumnIndice(tb);
+   if (columnVec) {
+      return new MBasketSQL(tb->GetName(), tb->GetName(), tb,
+                            &fResult, &fInsertQuery, columnVec, &fRow);
+   } else {
+      return 0;
+   }
+}
+
+//______________________________________________________________________________
+void MTreeSQL::CreateBranch(const TString &branchName, const TString &typeName)
+{
+   // Create the column(s) in the database that correspond to the branch/
+
+   if (fServer==0) {
+      Error("CreateBranch","No TSQLServer specified");
+      return;
+   }
+   TString alterSQL = "";
+   alterSQL = "";
+   alterSQL = "ALTER TABLE ";
+   alterSQL += fTable.Data();
+   alterSQL += " ADD ";
+   alterSQL += branchName.Data();;
+   alterSQL += " ";
+   alterSQL += typeName;
+   alterSQL += " ";
+
+   fServer->Query(alterSQL);
+}
+
+//_________________________________________________________________________
+TString MTreeSQL::CreateBranches(TSQLResult * rs)
+{
+   // determine leaf description string
+
+   if(!rs) return "";
+
+   Int_t rows;
+   TString type;
+   TString res;
+   TString branchName;
+   TString leafName;
+   Int_t prec=0;
+   TBranch * br = 0;
+   rows = rs->GetRowCount();
+   TString decl;
+   TString prevBranch;
+
+   for( int i=0; i < rows; ++i ) {
+      TSQLRow * row = rs->Next();
+      if (!row) continue;
+      type = row->GetField(1);
+      Int_t index = type.First('(');
+      if(index>0){
+         prec = atoi(type(index+1,type.First(')')-1).Data());
+         type = type(0,index);
+      }
+      branchName = row->GetField(0);
+      Int_t pos;
+      if ((pos=branchName.Index("__"))!=kNPOS) {
+         leafName = branchName(pos+2,branchName.Length());
+         branchName.Remove(pos);
+      } else {
+         leafName = branchName;
+      }
+      if (prevBranch.Length()) {
+         if (prevBranch != branchName) {
+            // new branch let's flush.
+            if (decl.Length()) decl.Remove(decl.Length()-1);
+            br = TTree::Branch(prevBranch,0,decl);
+            br->ResetAddress();
+
+            (br->GetBasketEntry())[0] = 0;
+            (br->GetBasketEntry())[1] = fEntries;
+
+            br->SetEntries(fEntries);
+
+            //++(br->fNBaskets);
+            br->GetListOfBaskets()->AddAtAndExpand(CreateBasket(br),0);
+
+            prevBranch = branchName;
+            decl = "";
+         }
+      } else {
+         prevBranch = branchName;
+      }
+
+      if(type.CompareTo("varchar",TString::kIgnoreCase)==0 || type.CompareTo("varchar2",TString::kIgnoreCase)==0 || type.CompareTo("char",TString::kIgnoreCase)==0 ) { 
+         char siz[6];
+         snprintf(siz,6,"[%d]",prec);
+         decl.Append( leafName+siz+"/C:" );
+      }
+      else if(type.CompareTo("int",TString::kIgnoreCase)==0){
+         decl.Append( leafName+"/I:" );
+      }
+      else if( type.CompareTo("date",TString::kIgnoreCase)==0 ||
+               type.CompareTo("time",TString::kIgnoreCase)==0 ||
+               type.CompareTo("timestamp",TString::kIgnoreCase)==0 ) {
+         decl.Append( leafName+"/I:" );
+      }
+      else if(type.CompareTo("bit",TString::kIgnoreCase)==0 ||
+              type.CompareTo("tinyint",TString::kIgnoreCase)==0 ||
+              type.CompareTo("smallint",TString::kIgnoreCase)==0 ) {
+         decl.Append( leafName+"/i:" );
+      }
+      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 ){
+         decl.Append( leafName+"/S:" );
+      }
+
+      //   case kLONGVARCHAR: // not resolved yet how to handle
+      // case kLONGVARBINARY:
+      //case kVARBINARY:
+      //  break;
+      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 ||
+      type.CompareTo("float",TString::kIgnoreCase)==0 )*/{
+
+         decl.Append( leafName+"/F:" );
+      }
+
+   }
+
+   // new branch let's flush.
+   if (decl.Length()) decl.Remove(decl.Length()-1);
+   if (prevBranch.Length()) {
+      br = TTree::Branch(prevBranch,0,decl);
+      br->ResetAddress();
+
+      (br->GetBasketEntry())[0] = 0;
+      (br->GetBasketEntry())[1] = fEntries;
+      br->SetEntries(fEntries);
+      br->GetListOfBaskets()->AddAtAndExpand(CreateBasket(br),0);
+   }
+
+   if(!res.IsNull()) res.Resize(res.Length()-1);   // cut off last ":"
+   return res;
+}
+
+//______________________________________________________________________________
+Bool_t MTreeSQL::CreateTable(const TString &table)
+{
+   // Create the database table corresponding to this TTree.
+
+   if (fServer==0) {
+      Error("CreateTable","No TSQLServer specified");
+      return false;
+   }
+   Int_t i, j;
+   TString branchName, leafName, typeName;
+   TString createSQL, alterSQL, str;
+   Int_t nb = fBranches.GetEntriesFast();
+   Int_t nl = 0;
+
+   TBranch *branch;
+   TLeaf *leaf;
+
+   for (i=0;i<nb;i++) {
+      branch = (TBranch*)fBranches.UncheckedAt(i);
+      branchName = branch->GetName();
+      nl = branch->GetNleaves();
+      for(j=0;j<nl;j++) {
+         leaf = (TLeaf*)branch->GetListOfLeaves()->UncheckedAt(j);
+         leafName = leaf->GetName();
+         typeName = ConvertTypeName(leaf->GetTypeName());
+         // length = leaf->GetLenStatic();
+
+         if(i == 0 && j == 0) {
+            createSQL = "";
+            createSQL += "CREATE TABLE ";
+            createSQL += table;
+            createSQL += " (";
+            createSQL += branchName;
+            createSQL += "__";
+            createSQL += leafName;
+            createSQL += " ";
+            createSQL += typeName;
+            createSQL += " ";
+            createSQL += ")";
+
+            TSQLResult *sres = fServer->Query(createSQL.Data());
+            if (!sres) {
+               Error("CreateTable","May have failed");
+               return false;
+            }
+         }
+         else {
+            str = "";
+            str = branchName;
+            str += "__";
+            str += leafName;
+            CreateBranch(str, typeName);
+         } //else
+      }  // inner for loop
+   } // outer for loop
+   // retrieve table to initialize fResult
+   delete fResult;
+   fResult = fServer->Query(fQuery.Data());
+   return (fResult!=0);
+}
+
+//______________________________________________________________________________
+void MTreeSQL::Init()
+{
+   // Initializeation routine
+
+   fCurrentEntry = -1;
+
+   GetEntries();
+
+   delete fResult;
+   fResult = fServer->Query(fQuery.Data());
+   if(!fResult) return;
+
+   CreateBranches(fServer->GetColumns(fDB,fTable));
+}
+
+//______________________________________________________________________________
+Int_t MTreeSQL::Fill()
+{
+   // Copy the information from the user object to the TTree
+
+   Int_t nb = fBranches.GetEntriesFast();
+   TString typeName;
+   TBranch *branch;
+
+   if (fServer==0) return 0;
+
+   if(!CheckTable(fTable.Data())) {
+      if (!CreateTable(fTable.Data())) {
+         return -1;
+      }
+   }
+
+   PrepEntry(fEntries);
+
+   for (int i=0;i<nb;i++) {
+      branch = (TBranch*)fBranches.UncheckedAt(i);
+      CheckBasket(branch);
+   }
+
+   if (!fBranchChecked) {
+      for(int i=0;i<nb;i++) {
+         branch = (TBranch*)fBranches.UncheckedAt(i);
+         if (!CheckBranch(branch)) {
+            Error("Fill","CheckBranch for %s failed",branch->GetName());
+         }
+      }
+      fBranchChecked = kTRUE;
+   }
+   ResetQuery();
+
+   TTree::Fill();
+
+   if (fInsertQuery[fInsertQuery.Length()-1]!='(') {
+      fInsertQuery.Remove(fInsertQuery.Length()-1);
+      fInsertQuery += ")";
+      TSQLResult *res = fServer?fServer->Query(fInsertQuery):0;
+
+      if (res) {
+         return res->GetRowCount();
+      }
+   }
+   return -1;
+}
+
+//______________________________________________________________________________
+vector<Int_t> *MTreeSQL::GetColumnIndice(TBranch *branch)
+{
+   // Return a vector of columns index corresponding to the
+   // current SQL table and the branch given as argument
+   // Returns 0 if no columns indices is found
+   // Otherwise returns a pointer to a vector to be deleted by the caller
+
+   if (!CheckTable(fTable)) return 0;
+
+   vector<Int_t> *columns = new vector<Int_t>;
+
+   Int_t nl = branch->GetNleaves();
+
+   vector<TString> names;
+
+   TSQLResult *rs = fServer->GetColumns(fDB,fTable);
+   if (rs==0) { delete columns; return 0; }
+   Int_t rows = rs->GetRowCount();
+
+   pair<TString,Int_t> value;
+
+   for (Int_t i=0;i<rows;++i) {
+      TSQLRow *row = rs->Next();
+      names.push_back( row->GetField(0) );
+      delete row;
+   }
+   delete rs;
+
+   for(int j=0;j<nl;j++) {
+
+      Int_t col = -1;
+      TLeaf *leaf = (TLeaf*)branch->GetListOfLeaves()->UncheckedAt(j);
+      TString leafName = leaf->GetName();
+      TString str;
+
+      str = "";
+      str = branch->GetName();
+      str += "__";
+      str += leafName;
+      for (Int_t i=0;i<rows;++i) {
+         if (str.CompareTo(names[i],TString::kIgnoreCase)==0) {
+            col = i;
+            break;
+         }
+      }
+      if (col<0) {
+         str = leafName;
+         for (Int_t i=0;i<rows;++i) {
+            if (str.CompareTo(names[i],TString::kIgnoreCase)==0) {
+               col = i;
+               break;
+            }
+         }         
+      }
+      if(col>=0){
+         columns->push_back(col);
+      } else Error("GetColumnIndice","Error finding column %d %s",j,str.Data());
+   }
+   if (columns->empty()) {
+      delete columns; return 0;
+   } else
+      return columns;
+}
+
+//______________________________________________________________________________
+Long64_t  MTreeSQL::GetEntries() const
+{
+   // Get the number of rows in the database
+
+   if (fServer==0) return GetEntriesFast();
+   if (!CheckTable(fTable.Data())) return 0;
+
+   MTreeSQL* thisvar = const_cast<MTreeSQL*>(this);
+
+   // What if the user already started to call GetEntry
+   // What about the initial value of fEntries is it really 0?
+
+   TString counting = "select count(*) from " + fTable;
+   TSQLResult *count = fServer->Query(counting);
+
+   if (count==0) {
+      thisvar->fEntries = 0;
+   } else {
+      TSQLRow * row = count->Next();
+      if (row) {
+         TString val = row->GetField(0);
+         Long_t ret;
+         sscanf(val.Data(), "%ld",&(ret) );
+         thisvar->fEntries = ret;
+      } else {
+         thisvar->fEntries = 0;
+      }
+   }
+   return fEntries;
+}
+
+//______________________________________________________________________________
+Long64_t  MTreeSQL::GetEntriesFast()    const
+{
+   // Return the number of entries as of the last check.
+   // Use GetEntries for a more accurate count.
+
+   return fEntries;
+}
+
+//______________________________________________________________________________
+Int_t MTreeSQL::GetEntry(Long64_t entry, Int_t getall)
+{
+   // Load the data for the entry from the database.
+
+   if (PrepEntry(entry)>=0) return TTree::GetEntry(entry,getall);
+   else return -1;
+}
+
+//______________________________________________________________________________
+Long64_t MTreeSQL::LoadTree(Long64_t entry)
+{
+   // Setup the tree to the load the specified entry.
+
+   fReadEntry = entry;
+   return PrepEntry(entry);
+}
+
+//______________________________________________________________________________
+Long64_t MTreeSQL::PrepEntry(Long64_t entry)
+{
+   // Make sure the server and result set are setup for the requested entry
+
+   if (entry < 0 || entry >= fEntries || fServer==0) return 0;
+   fReadEntry = entry;
+
+   if(entry == fCurrentEntry) return entry;
+
+   if(entry < fCurrentEntry || fResult==0){
+      delete fResult;
+      fResult = fServer->Query(fQuery.Data());
+      fCurrentEntry = -1;
+   }
+
+   Bool_t reset = false;
+   while ( fResult && fCurrentEntry < entry ) {
+      ++fCurrentEntry;
+      delete fRow;
+      fRow = fResult->Next();
+      if (fRow==0 && !reset) {
+         delete fResult;
+         fResult = fServer->Query(fQuery.Data());
+         fCurrentEntry = -1;
+         reset = true;
+      }
+   }
+   if (fRow==0) return -1;
+   return entry;
+}
+
+//______________________________________________________________________________
+// void MTreeSQL::LoadNumberEntries()
+// {
+//    R__ASSERT(0);
+
+//    fResult =    fServer->Query(fQuery.Data());
+//    fEntries=0;
+
+//    while(fResult->Next()){
+//       fEntries++;
+//    }
+//    fResult =    fServer->Query(fQuery.Data());
+// }
+
+//______________________________________________________________________________
+void MTreeSQL::Refresh()
+{
+   //  Refresh contents of this Tree and his branches from the current
+   //  Tree status in the database
+   //  One can call this function in case the Tree on its file is being
+   //  updated by another process
+
+   // Note : something to be done?
+   GetEntries(); // Re-load the number of entries
+   fCurrentEntry = -1;
+   delete fResult; fResult = 0;
+   delete fRow; fRow = 0;
+}
+
+//______________________________________________________________________________
+void MTreeSQL::ResetQuery()
+{
+   // Reset the internal query
+
+   fInsertQuery = "INSERT INTO " + fTable + " VALUES (";
+}
+
+
Index: trunk/Mars/msql/MTreeSQL.h
===================================================================
--- trunk/Mars/msql/MTreeSQL.h	(revision 15417)
+++ trunk/Mars/msql/MTreeSQL.h	(revision 15417)
@@ -0,0 +1,99 @@
+// @(#)root/tree:$Id: MTreeSQL.h 30663 2009-10-11 22:11:51Z pcanal $
+// Author: Rene Brun   12/01/96
+
+/*************************************************************************
+ * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+#ifndef ROOT_MTreeSQL
+#define ROOT_MTreeSQL
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// MTreeSQL                                                             //
+//                                                                      //
+// A TTree object is a list of TBranch.                                 //
+//   To Create a TTree object one must:                                 //
+//    - Create the TTree header via the TTree constructor               //
+//    - Call the TBranch constructor for every branch.                  //
+//                                                                      //
+//   To Fill this object, use member function Fill with no parameters.  //
+//     The Fill function loops on all defined TBranch.                  //
+//                                                                      //
+// MTreeSQL is the TTree implementation interfacing with an SQL         //
+// database                                                             //
+//                                                                      //
+//////////////////////////////////////////////////////////////////////////
+
+
+#ifndef ROOT_TTree
+#include "TTree.h"
+#endif
+
+#include <vector>
+
+class TSQLServer;
+class TSQLRow;
+class MBasketSQL;
+
+class MTreeSQL : public TTree {
+
+protected:
+   Int_t                  fCurrentEntry;
+   TString                fDB;
+   TString                fInsertQuery;   
+   TString                fQuery;
+   TString                fTable;
+   TSQLResult            *fResult;
+   TSQLRow               *fRow;
+   TSQLServer            *fServer;
+   Bool_t                 fBranchChecked;
+
+   void                   CheckBasket(TBranch * tb);
+   Bool_t                 CheckBranch(TBranch * tb);
+   Bool_t                 CheckTable(const TString &table) const;
+   TString                CreateBranches(TSQLResult * rs);
+   std::vector<Int_t>    *GetColumnIndice(TBranch *branch);
+   void                   Init();   
+   void                   ResetQuery();
+   TString                ConvertTypeName(const TString& typeName );
+   virtual void           CreateBranch(const TString& branchName,const TString &typeName);
+   Bool_t                 CreateTable(const TString& table);
+   virtual TBasket       *CreateBasket(TBranch * br); 
+
+   virtual TBranch *BranchImp(const char *branchname, const char *classname, TClass *ptrClass, void *addobj, Int_t bufsize, Int_t splitlevel);
+   virtual TBranch *BranchImp(const char *branchname, TClass *ptrClass, void *addobj, Int_t bufsize, Int_t splitlevel);
+   
+public:
+   MTreeSQL(TSQLServer * server, TString DB, const TString& table, const TString &addon);
+
+   virtual Int_t          Branch(TCollection *list, Int_t bufsize=32000, Int_t splitlevel=99, const char *name="");
+   virtual Int_t          Branch(TList *list, Int_t bufsize=32000, Int_t splitlevel=99);
+   virtual Int_t          Branch(const char *folder, Int_t bufsize=32000, Int_t splitlevel=99);
+   virtual TBranch       *Bronch(const char *name, const char *classname, void *addobj, Int_t bufsize=32000, Int_t splitlevel=99);
+   virtual TBranch       *BranchOld(const char *name, const char *classname, void *addobj, Int_t bufsize=32000, Int_t splitlevel=1);
+#if !defined(__CINT__)
+   virtual TBranch       *Branch(const char *name, const char *classname, void *addobj, Int_t bufsize=32000, Int_t splitlevel=99);
+#endif
+
+   virtual TBranch       *Branch(const char *name, void *address, const char *leaflist, Int_t bufsize);
+
+   virtual Int_t          Fill();
+   virtual Int_t          GetEntry(Long64_t entry=0, Int_t getall=0);
+   virtual Long64_t       GetEntries()    const;
+   virtual Long64_t       GetEntries(const char *sel) { return TTree::GetEntries(sel); }
+   virtual Long64_t       GetEntriesFast()const;
+           TString        GetTableName(){ return fTable; }
+   virtual Long64_t       LoadTree(Long64_t entry);
+   virtual Long64_t       PrepEntry(Long64_t entry);
+           void           Refresh();
+
+   ClassDef(MTreeSQL,1);  // TTree Implementation read and write to a SQL database.
+};
+
+
+#endif
