From 186aa6e8a116cca6346f01a10b385a3452b97f01 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Wed, 1 Feb 2006 18:57:41 +0000
Subject: [PATCH] From Sergei Linev: Move CreateKey from TDirectory to TFile
 Here is also optimisation of SQL statements and adjustement for Oracle.
 Implementation of ClassBegin()/ClassMember()/ClassEnd() methdos for
 TBufferSQL2 and TBufferXML. I also implementation for ClassMemeber() method
 for case of "raw:data" for SQL and XML cases.

git-svn-id: http://root.cern.ch/svn/root/trunk@13977 27541ba8-7e3a-0410-8455-c3a389f83636
---
 sql/inc/LinkDef.h          |   4 +-
 sql/inc/TBufferSQL2.h      | 483 ++++++++++++++--------------
 sql/inc/TKeySQL.h          |  34 +-
 sql/inc/TSQLFile.h         |  45 +--
 sql/inc/TSQLObjectData.h   |  61 +++-
 sql/inc/TSQLStructure.h    |  46 ++-
 sql/src/TBufferSQL2.cxx    | 595 +++++++++++++++++++++++++---------
 sql/src/TKeySQL.cxx        | 207 ++++++------
 sql/src/TSQLFile.cxx       | 590 ++++++++++++++++++++++++----------
 sql/src/TSQLObjectData.cxx | 117 ++++++-
 sql/src/TSQLStructure.cxx  | 631 ++++++++++++++++++++++---------------
 xml/inc/TKeyXML.h          |  22 +-
 xml/inc/TXMLFile.h         |   7 +-
 xml/src/TBufferXML.cxx     |  12 +-
 xml/src/TKeyXML.cxx        | 173 +++++-----
 xml/src/TXMLFile.cxx       |  13 +-
 16 files changed, 1935 insertions(+), 1105 deletions(-)

diff --git a/sql/inc/LinkDef.h b/sql/inc/LinkDef.h
index 2fdff4be94e..d7450200d0a 100644
--- a/sql/inc/LinkDef.h
+++ b/sql/inc/LinkDef.h
@@ -1,4 +1,4 @@
-/* @(#)root/sql:$Name:  $:$Id: LinkDef.h,v 1.1 2005/12/07 14:49:24 rdm Exp $ */
+/* @(#)root/sql:$Name:  $:$Id: LinkDef.h,v 1.2 2005/12/07 14:59:57 rdm Exp $ */
 
 /*************************************************************************
  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
@@ -14,7 +14,9 @@
 #pragma link C++ class TBufferSQL2;
 #pragma link C++ class TKeySQL;
 #pragma link C++ class TSQLClassInfo;
+#pragma link C++ class TSQLObjectInfo;
 #pragma link C++ class TSQLObjectData;
+#pragma link C++ class TSQLObjectDataPool;
 #pragma link C++ class TSQLStructure;
 #pragma link C++ class TSQLColumnData;
 
diff --git a/sql/inc/TBufferSQL2.h b/sql/inc/TBufferSQL2.h
index e7c8c5014b8..e09bf2a7cfe 100644
--- a/sql/inc/TBufferSQL2.h
+++ b/sql/inc/TBufferSQL2.h
@@ -1,4 +1,4 @@
-// @(#)root/sql:$Name:  $:$Id: TBufferSQL2.h,v 1.6 2005/12/07 14:59:57 rdm Exp $
+// @(#)root/sql:$Name:  $:$Id: TBufferSQL2.h,v 1.7 2006/01/25 16:00:11 pcanal Exp $
 // Author: Sergey Linev  20/11/2005
 
 
@@ -26,6 +26,7 @@
 #include "TObjArray.h"
 #endif
 
+class TMap;
 class TExMap;
 class TStreamerInfo;
 class TStreamerElement;
@@ -39,245 +40,255 @@ class TSQLRow;
 class TSQLFile;
 class TSQLStructure;
 class TSQLObjectData;
+class TSQLClassInfo;
 
 class TBufferSQL2 : public TBuffer {
-   protected:
-
-      TSQLFile*        fSQL;                  //!   instance of TSQLFile
-      TSQLStructure*   fStructure;            //!   structures, created by object storing
-      TSQLStructure*   fStk;                  //!   pointer on current active structure (stack head)
-      TExMap*          fObjMap;               //!   Map between stored objects and object id
-      TObjArray*       fIdArray;              //!   List of used objects ids
-      TString          fReadBuffer;           //!   Buffer for read value
-      Int_t            fErrorFlag;            //!   Error id value 
-      Bool_t           fExpectedChain;        //!   flag to resolve situation when several elements of same basic type stored as FastArray
-      Int_t            fCompressLevel;        //!   compress level used to minimize size of data in database
-      Int_t            fReadVersionBuffer;    //!   buffer, used to by ReadVersion method
-      Int_t            fObjIdCounter;         //!   counter of objects id
-      Bool_t           fIgnoreVerification;   //!   ignore verification of names 
-      TSQLObjectData*  fCurrentData;          //!   
-
-      // TBufferSQL2 objects cannot be copied or assigned
-      TBufferSQL2(const TBufferSQL2 &);       // not implemented
-      void operator=(const TBufferSQL2 &);    // not implemented
-
-      TBufferSQL2();
-
-      // redefined protected virtual functions
-
-      virtual void     WriteObject(const void *actualObjStart, const TClass *actualClass);
-
-      // end redefined protected virtual functions
-
-      TSQLStructure*   PushStack();
-      TSQLStructure*   PopStack();
-      TSQLStructure*   Stack(Int_t depth = 0);
-
-      Bool_t           ProcessPointer(const void* ptr, Int_t& objid);
-      void             RegisterPointer(const void* ptr, Int_t objid);
-      
-      void             WorkWithElement(TStreamerElement* elem, Int_t number);
-
-      Int_t            SqlReadArraySize();
-
-      Bool_t           SqlWriteBasic(Char_t value);
-      Bool_t           SqlWriteBasic(Short_t value);
-      Bool_t           SqlWriteBasic(Int_t value);
-      Bool_t           SqlWriteBasic(Long_t value);
-      Bool_t           SqlWriteBasic(Long64_t value);
-      Bool_t           SqlWriteBasic(Float_t value);
-      Bool_t           SqlWriteBasic(Double_t value);
-      Bool_t           SqlWriteBasic(Bool_t value);
-      Bool_t           SqlWriteBasic(UChar_t value);
-      Bool_t           SqlWriteBasic(UShort_t value);
-      Bool_t           SqlWriteBasic(UInt_t value);
-      Bool_t           SqlWriteBasic(ULong_t value);
-      Bool_t           SqlWriteBasic(ULong64_t value);
-      Bool_t           SqlWriteValue(const char* value, const char* tname);
-
-      void             SqlReadBasic(Char_t& value);
-      void             SqlReadBasic(Short_t& value);
-      void             SqlReadBasic(Int_t& value);
-      void             SqlReadBasic(Long_t& value);
-      void             SqlReadBasic(Long64_t& value);
-      void             SqlReadBasic(Float_t& value);
-      void             SqlReadBasic(Double_t& value);
-      void             SqlReadBasic(Bool_t& value);
-      void             SqlReadBasic(UChar_t& value);
-      void             SqlReadBasic(UShort_t& value);
-      void             SqlReadBasic(UInt_t& value);
-      void             SqlReadBasic(ULong_t& value);
-      void             SqlReadBasic(ULong64_t& value);
-      const char*      SqlReadValue(const char* tname);
-      const char*      SqlReadCharStarValue();
-
-      Int_t            SqlWriteObject(const void* obj, const TClass* objClass, TMemberStreamer *streamer = 0, Int_t streamer_index = 0);
-      void*            SqlReadObject(void* obj, TClass** cl = 0, TMemberStreamer *streamer = 0, Int_t streamer_index = 0);
-      void*            SqlReadObjectDirect(void* obj, TClass** cl, Int_t objid, TMemberStreamer *streamer = 0, Int_t streamer_index = 0);
+
+friend class TSQLStructure;    
     
-   public:
+protected:
+
+   TSQLFile*        fSQL;                  //!   instance of TSQLFile
+   TSQLStructure*   fStructure;            //!   structures, created by object storing
+   TSQLStructure*   fStk;                  //!   pointer on current active structure (stack head)
+   TExMap*          fObjMap;               //!   Map between stored objects and object id
+   TString          fReadBuffer;           //!   Buffer for read value
+   Int_t            fErrorFlag;            //!   Error id value 
+   Bool_t           fExpectedChain;        //!   flag to resolve situation when several elements of same basic type stored as FastArray
+   Int_t            fCompressLevel;        //!   compress level used to minimize size of data in database
+   Int_t            fReadVersionBuffer;    //!   buffer, used to by ReadVersion method
+   Long64_t         fObjIdCounter;         //!   counter of objects id
+   Bool_t           fIgnoreVerification;   //!   ignore verification of names 
+   TSQLObjectData*  fCurrentData;          //!  
+   TObjArray*       fObjectsInfos;         //!   array of objects info for selected key 
+   Long64_t         fFirstObjId;           //!   id of first object to be read from the database
+   Long64_t         fLastObjId;            //!   id of last object correspond to this key
+   TMap*            fPoolsMap;             //!   map of pools with data from different tables
+
+   // TBufferSQL2 objects cannot be copied or assigned
+   TBufferSQL2(const TBufferSQL2 &);       // not implemented
+   void operator=(const TBufferSQL2 &);    // not implemented
+
+   TBufferSQL2();
+
+   // redefined protected virtual functions
+
+   virtual void     WriteObject(const void *actualObjStart, const TClass *actualClass);
+
+   // end redefined protected virtual functions
+
+   TSQLStructure*   PushStack();
+   TSQLStructure*   PopStack();
+   TSQLStructure*   Stack(Int_t depth = 0);
+
+   void             WorkWithClass(const char* classname, Version_t classversion); 
+   void             WorkWithElement(TStreamerElement* elem, Int_t number);
+
+   Int_t            SqlReadArraySize();
+   Bool_t           SqlObjectInfo(Long64_t objid, TString& clname, Version_t& version);
+   TSQLObjectData*  SqlObjectData(Long64_t objid, TSQLClassInfo* sqlinfo);
+
+   Bool_t           SqlWriteBasic(Char_t value);
+   Bool_t           SqlWriteBasic(Short_t value);
+   Bool_t           SqlWriteBasic(Int_t value);
+   Bool_t           SqlWriteBasic(Long_t value);
+   Bool_t           SqlWriteBasic(Long64_t value);
+   Bool_t           SqlWriteBasic(Float_t value);
+   Bool_t           SqlWriteBasic(Double_t value);
+   Bool_t           SqlWriteBasic(Bool_t value);
+   Bool_t           SqlWriteBasic(UChar_t value);
+   Bool_t           SqlWriteBasic(UShort_t value);
+   Bool_t           SqlWriteBasic(UInt_t value);
+   Bool_t           SqlWriteBasic(ULong_t value);
+   Bool_t           SqlWriteBasic(ULong64_t value);
+   Bool_t           SqlWriteValue(const char* value, const char* tname);
+
+   void             SqlReadBasic(Char_t& value);
+   void             SqlReadBasic(Short_t& value);
+   void             SqlReadBasic(Int_t& value);
+   void             SqlReadBasic(Long_t& value);
+   void             SqlReadBasic(Long64_t& value);
+   void             SqlReadBasic(Float_t& value);
+   void             SqlReadBasic(Double_t& value);
+   void             SqlReadBasic(Bool_t& value);
+   void             SqlReadBasic(UChar_t& value);
+   void             SqlReadBasic(UShort_t& value);
+   void             SqlReadBasic(UInt_t& value);
+   void             SqlReadBasic(ULong_t& value);
+   void             SqlReadBasic(ULong64_t& value);
+   const char*      SqlReadValue(const char* tname);
+   const char*      SqlReadCharStarValue();
+
+   Int_t            SqlWriteObject(const void* obj, const TClass* objClass, TMemberStreamer *streamer = 0, Int_t streamer_index = 0);
+   void*            SqlReadObject(void* obj, TClass** cl = 0, TMemberStreamer *streamer = 0, Int_t streamer_index = 0);
+   void*            SqlReadObjectDirect(void* obj, TClass** cl, Long64_t objid, TMemberStreamer *streamer = 0, Int_t streamer_index = 0);
+ 
+public:
+
+   TBufferSQL2(TBuffer::EMode mode);
+   TBufferSQL2(TBuffer::EMode mode, TSQLFile* file);
+   virtual ~TBufferSQL2();
+   
+   void             SetCompressionLevel(int level) { fCompressLevel = level; }
+
+   TSQLStructure*   GetStructure() const { return fStructure; }
+   
+   Int_t            GetErrorFlag() const { return fErrorFlag; }
+   
+   void             SetIgnoreVerification() { fIgnoreVerification = kTRUE; }
+
+   TSQLStructure*   SqlWriteAny(const void* obj, const TClass* cl, Long64_t objid);
+
+   void*            SqlReadAny(Long64_t keyid, Long64_t objid, TClass** cl, void* obj = 0);
+
+   // suppress class writing/reading
+
+   virtual TClass*  ReadClass(const TClass* cl = 0, UInt_t* objTag = 0);
+   virtual void     WriteClass(const TClass* cl);
+
+   // redefined virtual functions of TBuffer
+
+   virtual Int_t    CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss); // SL
+   virtual Int_t    CheckByteCount(UInt_t startpos, UInt_t bcnt, const char *classname); // SL
+   virtual void     SetByteCount(UInt_t cntpos, Bool_t packInVersion = kFALSE);  // SL
+
+   virtual Version_t ReadVersion(UInt_t *start = 0, UInt_t *bcnt = 0, const TClass *cl = 0);  // SL
+   virtual UInt_t   WriteVersion(const TClass *cl, Bool_t useBcnt = kFALSE);  // SL
+
+   virtual void*    ReadObjectAny(const TClass* clCast);
+   virtual void     SkipObjectAny();
+
+   virtual void     IncrementLevel(TStreamerInfo*);
+   virtual void     SetStreamerElementNumber(Int_t);
+   virtual void     DecrementLevel(TStreamerInfo*);
    
-      TBufferSQL2(TBuffer::EMode mode);
-      TBufferSQL2(TBuffer::EMode mode, TSQLFile* file);
-      virtual ~TBufferSQL2();
-      
-      void             SetCompressionLevel(int level) { fCompressLevel = level; }
-
-      TSQLStructure*   GetStructure() const { return fStructure; }
-      
-      Int_t            GetErrorFlag() const { return fErrorFlag; }
-      
-      void             SetIgnoreVerification() { fIgnoreVerification = kTRUE; }
-
-      TSQLStructure*   SqlWrite(const TObject* obj, Int_t objid);
-      TSQLStructure*   SqlWrite(const void* obj, const TClass* cl, Int_t objid);
-
-      void*            SqlReadAny(Int_t objid, void* obj, TClass** cl);
-
-      // suppress class writing/reading
-
-      virtual TClass*  ReadClass(const TClass* cl = 0, UInt_t* objTag = 0);
-      virtual void     WriteClass(const TClass* cl);
-
-      // redefined virtual functions of TBuffer
-
-      virtual Int_t    CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss); // SL
-      virtual Int_t    CheckByteCount(UInt_t startpos, UInt_t bcnt, const char *classname); // SL
-      virtual void     SetByteCount(UInt_t cntpos, Bool_t packInVersion = kFALSE);  // SL
-
-      virtual Version_t ReadVersion(UInt_t *start = 0, UInt_t *bcnt = 0, const TClass *cl = 0);  // SL
-      virtual UInt_t   WriteVersion(const TClass *cl, Bool_t useBcnt = kFALSE);  // SL
-
-      virtual void*    ReadObjectAny(const TClass* clCast);
-      virtual void     SkipObjectAny();
-
-      virtual void     IncrementLevel(TStreamerInfo*);
-      virtual void     SetStreamerElementNumber(Int_t);
-      virtual void     DecrementLevel(TStreamerInfo*);
-
-      virtual void     WriteObject(const TObject *obj);
-
-      virtual void     ReadDouble32 (Double_t *d, TStreamerElement *ele=0);
-      virtual void     WriteDouble32(Double_t *d, TStreamerElement *ele=0);
-
-      virtual Int_t    ReadArray(Bool_t    *&b);
-      virtual Int_t    ReadArray(Char_t    *&c);
-      virtual Int_t    ReadArray(UChar_t   *&c);
-      virtual Int_t    ReadArray(Short_t   *&h);
-      virtual Int_t    ReadArray(UShort_t  *&h);
-      virtual Int_t    ReadArray(Int_t     *&i);
-      virtual Int_t    ReadArray(UInt_t    *&i);
-      virtual Int_t    ReadArray(Long_t    *&l);
-      virtual Int_t    ReadArray(ULong_t   *&l);
-      virtual Int_t    ReadArray(Long64_t  *&l);
-      virtual Int_t    ReadArray(ULong64_t *&l);
-      virtual Int_t    ReadArray(Float_t   *&f);
-      virtual Int_t    ReadArray(Double_t  *&d);
-      virtual Int_t    ReadArrayDouble32(Double_t  *&d, TStreamerElement *ele=0);
-
-      virtual Int_t    ReadStaticArray(Bool_t    *b);
-      virtual Int_t    ReadStaticArray(Char_t    *c);
-      virtual Int_t    ReadStaticArray(UChar_t   *c);
-      virtual Int_t    ReadStaticArray(Short_t   *h);
-      virtual Int_t    ReadStaticArray(UShort_t  *h);
-      virtual Int_t    ReadStaticArray(Int_t     *i);
-      virtual Int_t    ReadStaticArray(UInt_t    *i);
-      virtual Int_t    ReadStaticArray(Long_t    *l);
-      virtual Int_t    ReadStaticArray(ULong_t   *l);
-      virtual Int_t    ReadStaticArray(Long64_t  *l);
-      virtual Int_t    ReadStaticArray(ULong64_t *l);
-      virtual Int_t    ReadStaticArray(Float_t   *f);
-      virtual Int_t    ReadStaticArray(Double_t  *d);
-      virtual Int_t    ReadStaticArrayDouble32(Double_t  *d, TStreamerElement *ele=0);
-
-      virtual void     ReadFastArray(Bool_t    *b, Int_t n);
-      virtual void     ReadFastArray(Char_t    *c, Int_t n);
-      virtual void     ReadFastArray(UChar_t   *c, Int_t n);
-      virtual void     ReadFastArray(Short_t   *h, Int_t n);
-      virtual void     ReadFastArray(UShort_t  *h, Int_t n);
-      virtual void     ReadFastArray(Int_t     *i, Int_t n);
-      virtual void     ReadFastArray(UInt_t    *i, Int_t n);
-      virtual void     ReadFastArray(Long_t    *l, Int_t n);
-      virtual void     ReadFastArray(ULong_t   *l, Int_t n);
-      virtual void     ReadFastArray(Long64_t  *l, Int_t n);
-      virtual void     ReadFastArray(ULong64_t *l, Int_t n);
-      virtual void     ReadFastArray(Float_t   *f, Int_t n);
-      virtual void     ReadFastArray(Double_t  *d, Int_t n);
-      virtual void     ReadFastArrayDouble32(Double_t  *d, Int_t n, TStreamerElement *ele=0);
-
-      virtual void     WriteArray(const Bool_t    *b, Int_t n);
-      virtual void     WriteArray(const Char_t    *c, Int_t n);
-      virtual void     WriteArray(const UChar_t   *c, Int_t n);
-      virtual void     WriteArray(const Short_t   *h, Int_t n);
-      virtual void     WriteArray(const UShort_t  *h, Int_t n);
-      virtual void     WriteArray(const Int_t     *i, Int_t n);
-      virtual void     WriteArray(const UInt_t    *i, Int_t n);
-      virtual void     WriteArray(const Long_t    *l, Int_t n);
-      virtual void     WriteArray(const ULong_t   *l, Int_t n);
-      virtual void     WriteArray(const Long64_t  *l, Int_t n);
-      virtual void     WriteArray(const ULong64_t *l, Int_t n);
-      virtual void     WriteArray(const Float_t   *f, Int_t n);
-      virtual void     WriteArray(const Double_t  *d, Int_t n);
-      virtual void     WriteArrayDouble32(const Double_t  *d, Int_t n, TStreamerElement *ele=0);
-      virtual void     ReadFastArray(void  *start , const TClass *cl, Int_t n=1, TMemberStreamer *s=0);
-      virtual void     ReadFastArray(void **startp, const TClass *cl, Int_t n=1, Bool_t isPreAlloc=kFALSE, TMemberStreamer *s=0);
-
-      virtual void     WriteFastArray(const Bool_t    *b, Int_t n);
-      virtual void     WriteFastArray(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     WriteFastArrayDouble32(const Double_t  *d, Int_t n, TStreamerElement *ele=0);
-      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     StreamObject(void *obj, const type_info &typeinfo);
-      virtual void     StreamObject(void *obj, const char *className);
-      virtual void     StreamObject(void *obj, const TClass *cl);
-      virtual void     StreamObject(TObject *obj);
-      virtual void     StreamObject(void *obj, TMemberStreamer *streamer, const TClass *cl, Int_t n = 0);
-
-      virtual TBuffer  &operator>>(Bool_t    &b);
-      virtual TBuffer  &operator>>(Char_t    &c);
-      virtual TBuffer  &operator>>(UChar_t   &c);
-      virtual TBuffer  &operator>>(Short_t   &h);
-      virtual TBuffer  &operator>>(UShort_t  &h);
-      virtual TBuffer  &operator>>(Int_t     &i);
-      virtual TBuffer  &operator>>(UInt_t    &i);
-      virtual TBuffer  &operator>>(Long_t    &l);
-      virtual TBuffer  &operator>>(ULong_t   &l);
-      virtual TBuffer  &operator>>(Long64_t  &l);
-      virtual TBuffer  &operator>>(ULong64_t &l);
-      virtual TBuffer  &operator>>(Float_t   &f);
-      virtual TBuffer  &operator>>(Double_t  &d);
-      virtual TBuffer  &operator>>(Char_t    *c);
-
-      virtual TBuffer  &operator<<(Bool_t    b);
-      virtual TBuffer  &operator<<(Char_t    c);
-      virtual TBuffer  &operator<<(UChar_t   c);
-      virtual TBuffer  &operator<<(Short_t   h);
-      virtual TBuffer  &operator<<(UShort_t  h);
-      virtual TBuffer  &operator<<(Int_t     i);
-      virtual TBuffer  &operator<<(UInt_t    i);
-      virtual TBuffer  &operator<<(Long_t    l);
-      virtual TBuffer  &operator<<(ULong_t   l);
-      virtual TBuffer  &operator<<(Long64_t  l);
-      virtual TBuffer  &operator<<(ULong64_t l);
-      virtual TBuffer  &operator<<(Float_t   f);
-      virtual TBuffer  &operator<<(Double_t  d);
-      virtual TBuffer  &operator<<(const Char_t *c);
-
-      // end of redefined virtual functions
-
-   ClassDef(TBufferSQL2,1);    //a specialized TBuffer to convert data to SQL statements or read data from SQL tables
+   virtual void     ClassBegin(const TClass*, Version_t = -1);
+   virtual void     ClassEnd(const TClass*);
+   virtual void     ClassMember(const char* name, const char* typeName = 0, Int_t arrsize1 = -1, Int_t arrsize2 = -1);
+
+   virtual void     WriteObject(const TObject *obj);
+
+   virtual void     ReadDouble32 (Double_t *d, TStreamerElement *ele=0);
+   virtual void     WriteDouble32(Double_t *d, TStreamerElement *ele=0);
+
+   virtual Int_t    ReadArray(Bool_t    *&b);
+   virtual Int_t    ReadArray(Char_t    *&c);
+   virtual Int_t    ReadArray(UChar_t   *&c);
+   virtual Int_t    ReadArray(Short_t   *&h);
+   virtual Int_t    ReadArray(UShort_t  *&h);
+   virtual Int_t    ReadArray(Int_t     *&i);
+   virtual Int_t    ReadArray(UInt_t    *&i);
+   virtual Int_t    ReadArray(Long_t    *&l);
+   virtual Int_t    ReadArray(ULong_t   *&l);
+   virtual Int_t    ReadArray(Long64_t  *&l);
+   virtual Int_t    ReadArray(ULong64_t *&l);
+   virtual Int_t    ReadArray(Float_t   *&f);
+   virtual Int_t    ReadArray(Double_t  *&d);
+   virtual Int_t    ReadArrayDouble32(Double_t  *&d, TStreamerElement *ele=0);
+
+   virtual Int_t    ReadStaticArray(Bool_t    *b);
+   virtual Int_t    ReadStaticArray(Char_t    *c);
+   virtual Int_t    ReadStaticArray(UChar_t   *c);
+   virtual Int_t    ReadStaticArray(Short_t   *h);
+   virtual Int_t    ReadStaticArray(UShort_t  *h);
+   virtual Int_t    ReadStaticArray(Int_t     *i);
+   virtual Int_t    ReadStaticArray(UInt_t    *i);
+   virtual Int_t    ReadStaticArray(Long_t    *l);
+   virtual Int_t    ReadStaticArray(ULong_t   *l);
+   virtual Int_t    ReadStaticArray(Long64_t  *l);
+   virtual Int_t    ReadStaticArray(ULong64_t *l);
+   virtual Int_t    ReadStaticArray(Float_t   *f);
+   virtual Int_t    ReadStaticArray(Double_t  *d);
+   virtual Int_t    ReadStaticArrayDouble32(Double_t  *d, TStreamerElement *ele=0);
+
+   virtual void     ReadFastArray(Bool_t    *b, Int_t n);
+   virtual void     ReadFastArray(Char_t    *c, Int_t n);
+   virtual void     ReadFastArray(UChar_t   *c, Int_t n);
+   virtual void     ReadFastArray(Short_t   *h, Int_t n);
+   virtual void     ReadFastArray(UShort_t  *h, Int_t n);
+   virtual void     ReadFastArray(Int_t     *i, Int_t n);
+   virtual void     ReadFastArray(UInt_t    *i, Int_t n);
+   virtual void     ReadFastArray(Long_t    *l, Int_t n);
+   virtual void     ReadFastArray(ULong_t   *l, Int_t n);
+   virtual void     ReadFastArray(Long64_t  *l, Int_t n);
+   virtual void     ReadFastArray(ULong64_t *l, Int_t n);
+   virtual void     ReadFastArray(Float_t   *f, Int_t n);
+   virtual void     ReadFastArray(Double_t  *d, Int_t n);
+   virtual void     ReadFastArrayDouble32(Double_t  *d, Int_t n, TStreamerElement *ele=0);
+
+   virtual void     WriteArray(const Bool_t    *b, Int_t n);
+   virtual void     WriteArray(const Char_t    *c, Int_t n);
+   virtual void     WriteArray(const UChar_t   *c, Int_t n);
+   virtual void     WriteArray(const Short_t   *h, Int_t n);
+   virtual void     WriteArray(const UShort_t  *h, Int_t n);
+   virtual void     WriteArray(const Int_t     *i, Int_t n);
+   virtual void     WriteArray(const UInt_t    *i, Int_t n);
+   virtual void     WriteArray(const Long_t    *l, Int_t n);
+   virtual void     WriteArray(const ULong_t   *l, Int_t n);
+   virtual void     WriteArray(const Long64_t  *l, Int_t n);
+   virtual void     WriteArray(const ULong64_t *l, Int_t n);
+   virtual void     WriteArray(const Float_t   *f, Int_t n);
+   virtual void     WriteArray(const Double_t  *d, Int_t n);
+   virtual void     WriteArrayDouble32(const Double_t  *d, Int_t n, TStreamerElement *ele=0);
+   virtual void     ReadFastArray(void  *start , const TClass *cl, Int_t n=1, TMemberStreamer *s=0);
+   virtual void     ReadFastArray(void **startp, const TClass *cl, Int_t n=1, Bool_t isPreAlloc=kFALSE, TMemberStreamer *s=0);
+
+   virtual void     WriteFastArray(const Bool_t    *b, Int_t n);
+   virtual void     WriteFastArray(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     WriteFastArrayDouble32(const Double_t  *d, Int_t n, TStreamerElement *ele=0);
+   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     StreamObject(void *obj, const type_info &typeinfo);
+   virtual void     StreamObject(void *obj, const char *className);
+   virtual void     StreamObject(void *obj, const TClass *cl);
+   virtual void     StreamObject(TObject *obj);
+   virtual void     StreamObject(void *obj, TMemberStreamer *streamer, const TClass *cl, Int_t n = 0);
+
+   virtual TBuffer  &operator>>(Bool_t    &b);
+   virtual TBuffer  &operator>>(Char_t    &c);
+   virtual TBuffer  &operator>>(UChar_t   &c);
+   virtual TBuffer  &operator>>(Short_t   &h);
+   virtual TBuffer  &operator>>(UShort_t  &h);
+   virtual TBuffer  &operator>>(Int_t     &i);
+   virtual TBuffer  &operator>>(UInt_t    &i);
+   virtual TBuffer  &operator>>(Long_t    &l);
+   virtual TBuffer  &operator>>(ULong_t   &l);
+   virtual TBuffer  &operator>>(Long64_t  &l);
+   virtual TBuffer  &operator>>(ULong64_t &l);
+   virtual TBuffer  &operator>>(Float_t   &f);
+   virtual TBuffer  &operator>>(Double_t  &d);
+   virtual TBuffer  &operator>>(Char_t    *c);
+
+   virtual TBuffer  &operator<<(Bool_t    b);
+   virtual TBuffer  &operator<<(Char_t    c);
+   virtual TBuffer  &operator<<(UChar_t   c);
+   virtual TBuffer  &operator<<(Short_t   h);
+   virtual TBuffer  &operator<<(UShort_t  h);
+   virtual TBuffer  &operator<<(Int_t     i);
+   virtual TBuffer  &operator<<(UInt_t    i);
+   virtual TBuffer  &operator<<(Long_t    l);
+   virtual TBuffer  &operator<<(ULong_t   l);
+   virtual TBuffer  &operator<<(Long64_t  l);
+   virtual TBuffer  &operator<<(ULong64_t l);
+   virtual TBuffer  &operator<<(Float_t   f);
+   virtual TBuffer  &operator<<(Double_t  d);
+   virtual TBuffer  &operator<<(const Char_t *c);
+
+   // end of redefined virtual functions
+
+ClassDef(TBufferSQL2,1);    //a specialized TBuffer to convert data to SQL statements or read data from SQL tables
 };
 
 #endif
diff --git a/sql/inc/TKeySQL.h b/sql/inc/TKeySQL.h
index 492f532238a..237a2fd699d 100644
--- a/sql/inc/TKeySQL.h
+++ b/sql/inc/TKeySQL.h
@@ -1,4 +1,4 @@
-// @(#)root/sql:$Name:  $:$Id: TKeySQL.h,v 1.3 2005/12/07 14:59:57 rdm Exp $
+// @(#)root/sql:$Name:  $:$Id: TKeySQL.h,v 1.4 2006/01/25 16:00:11 pcanal Exp $
 // Author: Sergey Linev  20/11/2005
 
 /*************************************************************************
@@ -33,33 +33,33 @@ protected:
    TKeySQL();
 
    virtual Int_t     Read(const char *name) { return TKey::Read(name); }
-   void              StoreObject(const void* obj, const TClass* cl);
-   void*             SqlReadAny(void* obj, const TClass* expectedClass);
+   void              StoreKeyObject(const void* obj, const TClass* cl);
+   void*             ReadKeyObject(void* obj, const TClass* expectedClass);
   
-   TSQLFile*         fFile;     //!  pointer on SQL file
-   Int_t             fKeyId;    //!  key identifier in KeysTables
-   Int_t             fDirId;    //!  parent directory identifier
-   Int_t             fObjId;    //!  stored object identifer
+   Long64_t          fKeyId;    //!  key identifier in KeysTables
+   Long64_t          fObjId;    //!  stored object identifer
 
 public:
-   TKeySQL(TSQLFile* file, const TObject* obj, const char* name);
-   TKeySQL(TSQLFile* file, const void* obj, const TClass* cl, const char* name);
-   TKeySQL(TSQLFile* file, Int_t keyid, Int_t dirid, Int_t objid, const char* name, 
+   TKeySQL(TDirectory* mother, const TObject* obj, const char* name, const char* title = 0);
+   TKeySQL(TDirectory* mother, const void* obj, const TClass* cl, const char* name, const char* title = 0);
+   TKeySQL(TDirectory* mother, Long64_t keyid, Long64_t objid, 
+           const char* name, const char* title,
            const char* keydatetime, Int_t cycle, const char* classname);
    virtual ~TKeySQL();
+
+   Bool_t            IsKeyModified(const char* keyname, const char* keytitle, const char* keydatime, Int_t cycle, const char* classname);
   
-   Int_t             GetDBKeyId() const { return fKeyId; }
-   Int_t             GetDBDirId() const { return fDirId; }
-   Int_t             GetDBObjId() const { return fObjId; }
+   Long64_t          GetDBKeyId() const { return fKeyId; }
+   Long64_t          GetDBObjId() const { return fObjId; }
+   Long64_t          GetDBDirId() const;
 
    // redefined TKey Methods
-   virtual void      Browse(TBrowser *b);
    virtual void      Delete(Option_t *option="");
    virtual void      DeleteBuffer() {}
    virtual void      FillBuffer(char *&) {}
    virtual char     *GetBuffer() const { return 0; }
-   virtual Long64_t  GetSeekKey() const  { return 1; }
-   virtual Long64_t  GetSeekPdir() const { return 1;}
+   virtual Long64_t  GetSeekKey() const  { return GetDBObjId() > 0 ? GetDBObjId() : 0; }
+   virtual Long64_t  GetSeekPdir() const { return GetDBDirId() > 0 ? GetDBDirId() : 0; }
    virtual void      Keep() {}
 
    virtual Int_t     Read(TObject* obj);
@@ -69,8 +69,6 @@ public:
    virtual void      ReadBuffer(char *&) {}
    virtual void      ReadFile() {}
    virtual void      SetBuffer() { fBuffer = 0; }
-   virtual void      SetParent(const TObject* ) { }
-   virtual Int_t     Sizeof() const { return 0; }
    virtual Int_t     WriteFile(Int_t =1, TFile* = 0) { return 0; }
 
    ClassDef(TKeySQL,1) // a special TKey for SQL data base
diff --git a/sql/inc/TSQLFile.h b/sql/inc/TSQLFile.h
index b77978caed6..46cd1852471 100644
--- a/sql/inc/TSQLFile.h
+++ b/sql/inc/TSQLFile.h
@@ -1,4 +1,4 @@
-// @(#)root/sql:$Name:  $:$Id: TSQLFile.h,v 1.5 2005/11/29 05:29:15 pcanal Exp $
+// @(#)root/sql:$Name:  $:$Id: TSQLFile.h,v 1.6 2005/12/07 14:59:57 rdm Exp $
 // Author: Sergey Linev  20/11/2005
 
 /*************************************************************************
@@ -72,27 +72,25 @@ protected:
    Bool_t            IsWriteAccess();
    Bool_t            IsReadAccess();
   
-   // create key for provided objects
-   virtual TKey*     CreateKey(const TObject* obj, const char* name, Int_t bufsize);
-   virtual TKey*     CreateKey(const void* obj, const TClass* cl, const char* name, Int_t bufsize);
-  
    // generic sql functions
    TSQLResult*       SQLQuery(const char* cmd, Int_t flag = 0, Bool_t* res = 0);
    Bool_t            SQLApplyCommands(TObjArray* cmds);
    TObjArray*        SQLTablesList(const char* searchtable = 0);
    Bool_t            SQLTestTable(const char* tablename);
    TObjArray*        SQLTableColumns(const char* tablename);
-   Int_t             SQLMaximumValue(const char* tablename, const char* columnname);
+   Long64_t          SQLMaximumValue(const char* tablename, const char* columnname);
    void              SQLDeleteAllTables();
    Bool_t            SQLStartTransaction();
    Bool_t            SQLCommit();
    Bool_t            SQLRollback();
 
    // operation with keys structures in database
-   void              DeleteKeyFromDB(Int_t keyid);
-   Bool_t            WriteKeyData(Int_t keyid, Int_t dirid, Int_t objid, const char* name, const char* datime, Int_t cycle, const char* clname);
-   Int_t             DefineNextKeyId();
-   Bool_t            ReadKeysForDirectory(TDirectory* dir, Int_t dir_id);
+   void              DeleteKeyFromDB(Long64_t keyid);
+   Bool_t            WriteKeyData(TKeySQL* key);
+   Bool_t            UpdateKeyData(TKeySQL* key);
+   TKeySQL*          FindSQLKey(TDirectory* dir, Long64_t keyid);
+   Long64_t          DefineNextKeyId();
+   Int_t             StreamKeysForDirectory(TDirectory* dir, Bool_t doupdate, Long64_t specialkeyid = -1, TKeySQL** specialkey = 0);
 
    // handling SQL class info structures
    TSQLClassInfo*    FindSQLClassInfo(const char* clname, Int_t version);
@@ -102,17 +100,22 @@ protected:
    Bool_t            ProduceClassSelectQuery(TStreamerInfo* info, TSQLClassInfo* sqlinfo, TString& columns, TString& tables, Int_t& tablecnt);
 
    // operations with long string table
-   TString           CodeLongString(Int_t objid, Int_t strid);
-   Int_t             IsLongStringCode(const char* value, Int_t objid);
+   TString           CodeLongString(Long64_t objid, Int_t strid);
+   Int_t             IsLongStringCode(Long64_t objid, const char* value);
    Bool_t            VerifyLongStringTable();
-   Bool_t            GetLongString(Int_t objid, Int_t strid, TString& value);
+   Bool_t            GetLongString(Long64_t objid, Int_t strid, TString& value);
 
    // operation with object tables in database
-   Int_t             VerifyObjectTable();
-   TString           SetObjectDataCmd(Int_t keyid, Int_t objid, TClass* cl);
-   Bool_t            GetObjectData(Int_t objid, TString& clname, Version_t &version); 
-   TSQLObjectData*   GetObjectClassData(Int_t objid, TSQLClassInfo* sqlinfo);
-   void              DeleteObjectFromTables(Int_t objid);
+   Long64_t          VerifyObjectTable();
+   Bool_t            SQLObjectInfo(Long64_t objid, TString& clname, Version_t &version);
+   TObjArray*        SQLObjectsInfo(Long64_t keyid);
+   TSQLResult*       GetNormalClassData(Long64_t objid, TSQLClassInfo* sqlinfo);
+   TSQLResult*       GetNormalClassDataAll(Long64_t minobjid, Long64_t maxobjid, TSQLClassInfo* sqlinfo);
+   TSQLResult*       GetBlobClassData(Long64_t objid, TSQLClassInfo* sqlinfo);
+   TSQLObjectData*   GetObjectClassData(Long64_t objid, TSQLClassInfo* sqlinfo);
+   Long64_t          StoreObjectInTables(Long64_t keyid, const void* obj, const TClass* cl);
+   Bool_t            WriteSpecialObject(Long64_t keyid, TObject* obj, const char* name, const char* title);
+   TObject*          ReadSpecialObject(Long64_t keyid, TObject* obj = 0);
   
    // sql specific types
    const char*       SQLCompatibleType(Int_t typ) const;
@@ -143,6 +146,7 @@ protected:
    Int_t             fUseTransactions; //! use transaction statements for writing data into the tables
    Int_t             fUseIndexes;      //! use indexes for tables: 0 - off, 1 - only for basic tables, 2  + normal class tables, 3 - all tables
    Int_t             fModifyCounter;   //! indicates how many changes was done with database tables
+   Int_t             fQuerisCounter;   //! how many query was applied
   
    const char**      fBasicTypes;      //! pointer on list of basic types specific for currently connected SQL server
    const char**      fOtherTypes;      //! pointer on list of other SQL types like TEXT or blob
@@ -186,6 +190,7 @@ public:
    Int_t             GetUseTransactions() const { return fUseTransactions; }
    void              SetUseIndexes(Int_t use_type = kIndexesBasic);
    Int_t             GetUseIndexes() const { return fUseIndexes; }
+   Int_t             GetQuerisCounter() const { return fQuerisCounter; }
 
    TString           MakeSelectQuery(TClass* cl);
    Bool_t            StartTransaction();
@@ -197,6 +202,8 @@ public:
    void              StopLogFile();                    // *MENU*
 
    virtual void      Close(Option_t *option="");       // *MENU*
+   virtual TKey*     CreateKey(TDirectory* mother, const TObject* obj, const char* name, Int_t bufsize);
+   virtual TKey*     CreateKey(TDirectory* mother, const void* obj, const TClass* cl, const char* name, Int_t bufsize);
    virtual void      DrawMap(const char* ="*",Option_t* ="") {} 
    virtual void      FillBuffer(char* &) {}
    virtual void      Flush() {}
@@ -237,7 +244,7 @@ public:
    virtual Int_t     Write(const char* =0, Int_t=0, Int_t=0) { return 0; }
    virtual Int_t     Write(const char* =0, Int_t=0, Int_t=0) const { return 0; }
    virtual void      WriteFree() {}
-   virtual void      WriteHeader() {}
+   virtual void      WriteHeader();
    virtual void      WriteStreamerInfo();
   
    ClassDef(TSQLFile,1)   // ROOT TFile interface to SQL database
diff --git a/sql/inc/TSQLObjectData.h b/sql/inc/TSQLObjectData.h
index 50ea96a4708..fcc2192d158 100644
--- a/sql/inc/TSQLObjectData.h
+++ b/sql/inc/TSQLObjectData.h
@@ -1,4 +1,4 @@
-// @(#)root/sql:$Name:  $:$Id: TSQLObjectData.h,v 1.3 2005/11/24 16:57:23 pcanal Exp $
+// @(#)root/sql:$Name:  $:$Id: TSQLObjectData.h,v 1.4 2005/12/07 14:59:57 rdm Exp $
 // Author: Sergey Linev  20/11/2005
 
 /*************************************************************************
@@ -29,23 +29,51 @@
 #endif
 
 class TObjArray;
+class TList;
 class TSQLClassInfo;
 class TSQLResult;
 class TSQLRow;
 
+
+class TSQLObjectInfo : public TObject {
+
+public:
+
+   TSQLObjectInfo();
+   TSQLObjectInfo(Long64_t objid, const char* classname, Version_t version);
+   virtual ~TSQLObjectInfo();
+  
+   Long64_t          GetObjId() const { return fObjId; }
+   const char*       GetObjClassName() const { return fClassName.Data(); }
+   Version_t         GetObjVersion() const { return fVersion; }
+
+
+protected:
+   Long64_t          fObjId;
+   TString           fClassName;
+   Version_t         fVersion;
+
+ClassDef(TSQLObjectInfo, 1); // Info (classname, version) about object in database 
+    
+};
+
+//=======================================================================
+
 class TSQLObjectData : public TObject {
 
 public:
    TSQLObjectData();
    
    TSQLObjectData(TSQLClassInfo* sqlinfo,
-                  Int_t          objid,
+                  Long64_t       objid,
                   TSQLResult*    classdata,
+                  TSQLRow*       classrow,
                   TSQLResult*    blobdata);
    
    virtual ~TSQLObjectData();
    
-   Int_t             GetObjId() const { return fObjId; }
+   Long64_t          GetObjId() const { return fObjId; }
+   TSQLClassInfo*    GetInfo() const { return fInfo; }
    
    Bool_t            LocateColumn(const char* colname, Bool_t isblob = kFALSE);
    Bool_t            IsBlobData() const { return fCurrentBlob || (fUnpack!=0); }
@@ -69,7 +97,8 @@ protected:
    const char*       GetClassFieldName(Int_t n);
    
    TSQLClassInfo*    fInfo;          //!
-   Int_t             fObjId;         //!
+   Long64_t          fObjId;         //!
+   Bool_t            fOwner;         //!
    TSQLResult*       fClassData;     //!
    TSQLResult*       fBlobData;      //!
    Int_t             fLocatedColumn; //!
@@ -87,4 +116,28 @@ protected:
       
 };
 
+// ======================================================================
+
+class TSQLObjectDataPool : public TObject {
+
+public:
+   TSQLObjectDataPool();
+   TSQLObjectDataPool(TSQLClassInfo* info, TSQLResult* data);
+   virtual ~TSQLObjectDataPool();
+   
+   TSQLClassInfo*    GetSqlInfo() const { return fInfo; }
+   TSQLResult*       GetClassData() const { return fClassData; }
+   TSQLRow*          GetObjectRow(Long64_t objid);   
+   
+protected:
+
+   TSQLClassInfo*    fInfo;          //!  classinfo, for which pool is created
+   TSQLResult*       fClassData;     //!  results with request to selected table
+   Bool_t            fIsMoreRows;    //!  indicates if class data has not yet read rows
+   TList*            fRowsPool;      //!  pool of extrcted, but didnot used rows
+
+ClassDef(TSQLObjectDataPool,1);     
+    
+};
+
 #endif
diff --git a/sql/inc/TSQLStructure.h b/sql/inc/TSQLStructure.h
index 4a0656e2e87..330350c0b03 100644
--- a/sql/inc/TSQLStructure.h
+++ b/sql/inc/TSQLStructure.h
@@ -1,4 +1,4 @@
-// @(#)root/sql:$Name:  $:$Id: TSQLStructure.h,v 1.5 2005/12/01 16:30:43 pcanal Exp $
+// @(#)root/sql:$Name:  $:$Id: TSQLStructure.h,v 1.6 2005/12/07 14:59:57 rdm Exp $
 // Author: Sergey Linev  20/11/2005
 
 /*************************************************************************
@@ -39,6 +39,7 @@ class TStreamerElement;
 class TSQLFile;
 class TSqlRegistry;
 class TSQLObjectData;
+class TBufferSQL2;
 
 class TSQLColumnData : public TObject {
     
@@ -54,7 +55,7 @@ public:
                   const char* value, 
                   Bool_t numeric);
 
-   TSQLColumnData(const char* name, Int_t value);
+   TSQLColumnData(const char* name, Long64_t value);
    virtual ~TSQLColumnData();
   
    virtual const char* GetName() const { return fName.Data(); }
@@ -72,9 +73,9 @@ protected:
 
    Bool_t           CheckNormalClassPair(TSQLStructure* vers, TSQLStructure* info);
 
-   Int_t            FindMaxRef();
+   Long64_t         FindMaxObjectId();
    void             PerformConversion(TSqlRegistry* reg, TObjArray* blobs, const char* topname, Bool_t useblob = kFALSE);
-   Bool_t           StoreObject(TSqlRegistry* reg, const char* objid, TClass* cl, Bool_t registerobj = kTRUE);
+   Bool_t           StoreObject(TSqlRegistry* reg, Long64_t objid, TClass* cl, Bool_t registerobj = kTRUE);
    Bool_t           StoreObjectInNormalForm(TSqlRegistry* reg);
    Bool_t           StoreClassInNormalForm(TSqlRegistry* reg);
    Bool_t           StoreElementInNormalForm(TSqlRegistry* reg, TObjArray* columns);
@@ -107,12 +108,14 @@ public:
    Int_t            GetType() const { return fType; }
    
    // this part requried for writing to SQL tables
-   void             SetObjectRef(Int_t refid, const TClass* cl);
-   void             SetObjectPointer(Int_t ptrid);
+   void             SetObjectRef(Long64_t refid, const TClass* cl);
+   void             SetObjectPointer(Long64_t ptrid);
    void             SetVersion(const TClass* cl, Int_t version = -100);
    void             SetClassStreamer(const TClass* cl);
    void             SetStreamerInfo(const TStreamerInfo* info);
    void             SetStreamerElement(const TStreamerElement* elem, Int_t number);
+   void             SetCustomClass(const TClass* cl, Version_t version);
+   void             SetCustomElement(TStreamerElement* elem);
    void             SetValue(const char* value, const char* tname = 0);
    void             SetArrayIndex(Int_t indx, Int_t cnt=1);
    void             SetArray(Int_t sz = -1);
@@ -123,6 +126,9 @@ public:
    TStreamerInfo*   GetStreamerInfo() const;
    TStreamerElement* GetElement() const;
    Int_t            GetElementNumber() const;
+   TClass*          GetCustomClass() const;
+   Version_t        GetCustomClassVersion() const;
+   Bool_t           GetClassInfo(TClass* &cl, Version_t &version);
    const char*      GetValueType() const;
    const char*      GetValue() const;
    Int_t            GetArrayIndex() const { return fArrayIndex; }
@@ -135,8 +141,7 @@ public:
 
    // this is part specially for reading of sql tables
   
-   Int_t            DefineObjectId();
-   Bool_t           IsClonesArray();
+   Long64_t         DefineObjectId(Bool_t recursive = kTRUE);
   
    void             SetObjectData(TSQLObjectData* objdata);
    void             AddObjectData(TSQLObjectData* objdata);
@@ -145,17 +150,18 @@ public:
    virtual void     Print(Option_t* option = "") const;
    void             PrintLevel(Int_t level) const;
   
-   Bool_t           ConvertToTables(TSQLFile* f, Int_t keyid, TObjArray* cmds);
+   Bool_t           ConvertToTables(TSQLFile* f, Long64_t keyid, TObjArray* cmds);
   
-   Int_t            LocateElementColumn(TSQLFile* f, TSQLObjectData* data);
+   Int_t            LocateElementColumn(TSQLFile* f, TBufferSQL2* buf, TSQLObjectData* data);
 
-   static Bool_t    UnpackTObject(TSQLFile* f, TSQLObjectData* data, Int_t objid, Int_t clversion);
-   static Bool_t    UnpackTString(TSQLFile* f, TSQLObjectData* data, Int_t objid, Int_t clversion);
+   static Bool_t    UnpackTObject(TSQLFile* f, TBufferSQL2* buf, TSQLObjectData* data, Long64_t objid, Int_t clversion);
+   static Bool_t    UnpackTString(TSQLFile* f, TBufferSQL2* buf, TSQLObjectData* data, Long64_t objid, Int_t clversion);
    static Bool_t    IsNumericType(Int_t typ);
    static const char* GetSimpleTypeName(Int_t typ);
    static TString   MakeArrayIndex(TStreamerElement* elem, Int_t n);
    static Int_t     DefineElementColumnType(TStreamerElement* elem, TSQLFile* f);
    static TString   DefineElementColumnName(TStreamerElement* elem, TSQLFile* f, Int_t indx = 0);
+   static void      AddStrBrackets(TString &s, const char* quote);
   
    enum ESQLTypes {
      kSqlObject       = 10001,
@@ -166,7 +172,9 @@ public:
      kSqlElement      = 10006,
      kSqlValue        = 10007,
      kSqlArray        = 10008,
-     kSqlObjectData   = 10009
+     kSqlObjectData   = 10009,
+     kSqlCustomClass  = 10010,
+     kSqlCustomElement= 10011
    };
    
    enum ESQLColumns {
@@ -180,8 +188,7 @@ public:
      kColNormObjectArray = 7,
      kColObjectPtr    = 8,
      kColTString      = 9,
-     kColClonesArray  = 10,
-     kColRawData      = 11
+     kColRawData      = 10
    };   
   
    ClassDef(TSQLStructure, 1); // Table/structure description used internally by YBufferSQL.
@@ -190,8 +197,12 @@ public:
 // text constants, used in SQL I/O
 
 namespace sqlio {
+    
+   extern Long64_t atol64(const char* value);
+    
    extern const Int_t Ids_NullPtr;
    extern const Int_t Ids_RootDir;
+   extern const Int_t Ids_TSQLFile;
    extern const Int_t Ids_StreamerInfos;
    extern const Int_t Ids_FirstKey;
    extern const Int_t Ids_FirstObject;
@@ -234,9 +245,14 @@ namespace sqlio {
    extern const char* KeysTable;
    extern const char* KeysTableIndex;
    extern const char* KT_Name;
+   extern const char* KT_Title;
    extern const char* KT_Datetime;
    extern const char* KT_Cycle;
    extern const char* KT_Class;
+
+   extern const char* DT_Create;
+   extern const char* DT_Modified;
+   extern const char* DT_UUID;
     
    extern const char* ObjectsTable;
    extern const char* ObjectsTableIndex;
diff --git a/sql/src/TBufferSQL2.cxx b/sql/src/TBufferSQL2.cxx
index 6ff6667e260..908a5e9714b 100644
--- a/sql/src/TBufferSQL2.cxx
+++ b/sql/src/TBufferSQL2.cxx
@@ -1,4 +1,4 @@
-// @(#)root/sql:$Name:  $:$Id: TBufferSQL2.cxx,v 1.7 2005/12/07 14:59:57 rdm Exp $
+// @(#)root/sql:$Name:  $:$Id: TBufferSQL2.cxx,v 1.8 2006/01/25 16:00:11 pcanal Exp $
 // Author: Sergey Linev  20/11/2005
 
 /*************************************************************************
@@ -24,8 +24,10 @@
 
 #include "TObjArray.h"
 #include "TROOT.h"
+#include "TDataType.h"
 #include "TClass.h"
 #include "TClassTable.h"
+#include "TMap.h"
 #include "TExMap.h"
 #include "TMethodCall.h"
 #include "TStreamerInfo.h"
@@ -44,14 +46,30 @@
 #include "TSQLFile.h"
 #include "TSQLClassInfo.h"
 
+#ifdef R__VISUAL_CPLUSPLUS
+#define FLong64    "%I64d"
+#define FULong64   "%I64u"
+#else
+#ifdef R__B64
+#define FLong64    "%ld"
+#define FULong64   "%lu"
+#else
+#define FLong64    "%lld"
+#define FULong64   "%llu"
+#endif
+#endif
+
 ClassImp(TBufferSQL2);
 
 //______________________________________________________________________________
 TBufferSQL2::TBufferSQL2() :
    TBuffer(),
-   fSQL(0)
+   fSQL(0),
+   fStructure(0),
+   fObjMap(0),
+   fPoolsMap(0)
 {
-   // Default constructor
+   // Default constructor, should not be used
 }
 
 //______________________________________________________________________________
@@ -61,19 +79,21 @@ TBufferSQL2::TBufferSQL2(TBuffer::EMode mode) :
    fStructure(0),
    fStk(0),
    fObjMap(0),
-   fIdArray(0),
    fErrorFlag(0),
    fExpectedChain(kFALSE),
    fCompressLevel(0),
    fReadVersionBuffer(-1),
    fObjIdCounter(1),
-   fIgnoreVerification(kFALSE)
+   fIgnoreVerification(kFALSE),
+   fObjectsInfos(0),
+   fPoolsMap(0)
 {
    // Creates buffer object to serailize/deserialize data to/from sql.
    // Mode should be either TBuffer::kRead or TBuffer::kWrite.
 
    SetParent(0);
    SetBit(kCannotHandleMemberWiseStreaming);
+   SetBit(kTextBasedStreaming);
 }
 
 //______________________________________________________________________________
@@ -83,12 +103,13 @@ TBufferSQL2::TBufferSQL2(TBuffer::EMode mode, TSQLFile* file) :
    fStructure(0),
    fStk(0),
    fObjMap(0),
-   fIdArray(0),
    fErrorFlag(0),
    fExpectedChain(kFALSE),
    fCompressLevel(0),
    fReadVersionBuffer(-1),
-   fObjIdCounter(1)
+   fObjIdCounter(1),
+   fObjectsInfos(0),
+   fPoolsMap(0)
 {
    // Creates buffer object to serailize/deserialize data to/from sql.
    // This constructor should be used, if data from buffer supposed to be stored in file.
@@ -98,6 +119,7 @@ TBufferSQL2::TBufferSQL2(TBuffer::EMode mode, TSQLFile* file) :
 
    // for TClonesArray recognize if this is special case
    SetBit(kCannotHandleMemberWiseStreaming);
+   SetBit(kTextBasedStreaming);
 
    SetParent(file);
    fSQL = file;
@@ -110,27 +132,25 @@ TBufferSQL2::~TBufferSQL2()
 {
    // destroy sql buffer
    if (fObjMap) delete fObjMap;
-   if (fIdArray) delete fIdArray;
 
    if (fStructure!=0) {
       delete fStructure;
       fStructure = 0;
    }
+   
+   if (fObjectsInfos!=0) {
+      fObjectsInfos->Delete();
+      delete fObjectsInfos;   
+   }
+   
+   if (fPoolsMap!=0) {
+      fPoolsMap->DeleteValues();
+      delete fPoolsMap;   
+   }
 }
 
 //______________________________________________________________________________
-TSQLStructure* TBufferSQL2::SqlWrite(const TObject* obj, Int_t objid)
-{
-   // Convert object, derived from TObject class to sql structures
-   // Return pointer on created TSQLStructure
-   // TSQLStructure object will be owned by TBufferSQL2
-
-   if (obj==0) return SqlWrite(0,0, objid);
-   else return SqlWrite(obj, obj->IsA(), objid);
-}
-
-//______________________________________________________________________________
-TSQLStructure* TBufferSQL2::SqlWrite(const void* obj, const TClass* cl, Int_t objid)
+TSQLStructure* TBufferSQL2::SqlWriteAny(const void* obj, const TClass* cl, Long64_t objid)
 {
    // Convert object of any class to sql structures
    // Return pointer on created TSQLStructure
@@ -140,6 +160,7 @@ TSQLStructure* TBufferSQL2::SqlWrite(const void* obj, const TClass* cl, Int_t ob
 
    fStructure = 0;
 
+   fFirstObjId = objid;   
    fObjIdCounter = objid;
 
    SqlWriteObject(obj, cl);
@@ -155,7 +176,7 @@ TSQLStructure* TBufferSQL2::SqlWrite(const void* obj, const TClass* cl, Int_t ob
 }
 
 //______________________________________________________________________________
-void* TBufferSQL2::SqlReadAny(Int_t objid, void* obj, TClass** cl)
+void* TBufferSQL2::SqlReadAny(Long64_t keyid, Long64_t objid, TClass** cl, void* obj)
 {
    // Recreate object from sql structure.
    // Return pointer to read object.
@@ -164,59 +185,113 @@ void* TBufferSQL2::SqlReadAny(Int_t objid, void* obj, TClass** cl)
    if (cl) *cl = 0;
    if (fSQL==0) return 0;
 
-   fCurrentData=0;
+   fCurrentData = 0;
    fErrorFlag = 0;
 
    fReadVersionBuffer = -1;
+   
+   fObjectsInfos = fSQL->SQLObjectsInfo(keyid);
+//   fObjectsInfos = 0;
+   fFirstObjId = objid;
+   fLastObjId = objid;
+   if (fObjectsInfos!=0) {
+      TSQLObjectInfo* objinfo = (TSQLObjectInfo*) fObjectsInfos->Last();
+      if (objinfo!=0) fLastObjId = objinfo->GetObjId();
+   }
 
    return SqlReadObjectDirect(obj, cl, objid);
 }
 
 //______________________________________________________________________________
-void TBufferSQL2::WriteObject(const TObject *obj)
+Bool_t TBufferSQL2::SqlObjectInfo(Long64_t objid, TString& clname, Version_t& version)
 {
-   // Convert object into sql structures.
-   // !!! Should be used only by TBufferSQL2 itself.
-   // Use SqlWrite() functions to convert your object to sql
-   // Redefined here to avoid gcc 3.x warning
+// Returns object info like classname and version
+// Should be taken from buffer, which is produced in the begginnig
 
-   TBuffer::WriteObject(obj);
+   if ((objid<0) || (fObjectsInfos==0)) return kFALSE;
+
+ //  if (fObjectsInfos==0) return fSQL->SQLObjectInfo(objid, clname, version);
+   
+   // suppose that objects info are sorted out
+   
+   Long64_t shift = objid - fFirstObjId;
+   
+   TSQLObjectInfo* info = 0;
+   if ((shift>=0) && (shift<=fObjectsInfos->GetLast())) {
+      info = (TSQLObjectInfo*) fObjectsInfos->At(shift);
+      if (info->GetObjId()!=objid) info = 0;
+   }
+    
+   if (info==0) {
+      // I hope, i will never get inside it 
+      Info("SqlObjectInfo", "Standard not works %lld", objid); 
+      for (Int_t n=0;n<=fObjectsInfos->GetLast();n++) {
+         info = (TSQLObjectInfo*) fObjectsInfos->At(n);
+         if (info->GetObjId()==objid) break;
+         info = 0;
+      }
+   }
+    
+   if (info==0) return kFALSE;
+   
+   clname = info->GetObjClassName();
+   version = info->GetObjVersion();
+   return kTRUE;
 }
 
+
 //______________________________________________________________________________
-Bool_t TBufferSQL2::ProcessPointer(const void* ptr, Int_t& objid)
+TSQLObjectData* TBufferSQL2::SqlObjectData(Long64_t objid, TSQLClassInfo* sqlinfo)
 {
-   // Return SqlObjectId_Null, if ptr is null or
-   // id of object which was already stored in buffer
+   if (!sqlinfo->IsClassTableExist()) 
+      return fSQL->GetObjectClassData(objid, sqlinfo); 
+   
+   TSQLObjectDataPool* pool = 0;
+   
+   if (fPoolsMap!=0)
+     pool = (TSQLObjectDataPool*) fPoolsMap->GetValue(sqlinfo);
+   
+   if ((pool==0) && (fLastObjId>=fFirstObjId)) {
+      if (gDebug>4) Info("SqlObjectData","Before request to %s",sqlinfo->GetClassTableName());
+      TSQLResult *alldata = fSQL->GetNormalClassDataAll(fFirstObjId, fLastObjId, sqlinfo);
+      if (gDebug>4) Info("SqlObjectData","After request res = %x",alldata);
+      if (alldata==0) {
+         Error("SqlObjectData","Cannot get data from table %s",sqlinfo->GetClassTableName());
+         return 0;
+      }
 
-   if (ptr==0) {
-      objid = 0;
-   } else {
-      if (fObjMap==0) return kFALSE;
-      ULong_t hash = TMath::Hash(&ptr, sizeof(void*));
-      Long_t storedobjid = fObjMap->GetValue(hash, (Long_t) ptr);
-      if (storedobjid==0) return kFALSE;
+      if (fPoolsMap==0) fPoolsMap = new TMap();
+      pool = new TSQLObjectDataPool(sqlinfo, alldata);
+      fPoolsMap->Add(sqlinfo, pool);
+   }
 
-      objid = storedobjid;
+   if (pool==0) return 0;
+
+   if (pool->GetSqlInfo()!=sqlinfo) {
+      Error("SqlObjectData","Missmatch in pools map !!! CANNOT BE !!!");
+      return 0;
    }
 
-   return kTRUE;
+   TSQLResult *classdata = pool->GetClassData();
+   
+   TSQLRow* row = pool->GetObjectRow(objid);
+   if (row==0) {
+      Error("SqlObjectData","Can not find row for objid = %lld in table %s", objid, sqlinfo->GetClassTableName());
+      return 0;
+   }
+   TSQLResult *blobdata = fSQL->GetBlobClassData(objid, sqlinfo);
+   return new TSQLObjectData(sqlinfo, objid, classdata, row, blobdata);
 }
 
 //______________________________________________________________________________
-void TBufferSQL2::RegisterPointer(const void* ptr, Int_t objid)
+void TBufferSQL2::WriteObject(const TObject *obj)
 {
-   // Register pair of object id, in object map
-   // Object id is used to indentify object in tables
-
-   if ((ptr==0) || (objid==sqlio::Ids_NullPtr)) return;
-
-   ULong_t hash = TMath::Hash(&ptr, sizeof(void*));
-
-   if (fObjMap==0) fObjMap = new TExMap();
+   // Convert object into sql structures.
+   // !!! Should be used only by TBufferSQL2 itself.
+   // Use SqlWrite() functions to convert your object to sql
+   // Redefined here to avoid gcc 3.x warning
 
-   if (fObjMap->GetValue(hash, (Long_t) ptr)==0)
-      fObjMap->Add(hash, (Long_t) ptr, (Long_t) objid);
+   TBuffer::WriteObject(obj);
 }
 
 //______________________________________________________________________________
@@ -231,11 +306,21 @@ Int_t TBufferSQL2::SqlWriteObject(const void* obj, const TClass* cl, TMemberStre
 
    PushStack();
 
-   Int_t objid = 0;
+   Long64_t objid = -1;
 
    if (cl==0) obj = 0;
-
-   if (ProcessPointer(obj, objid)) {
+   
+   if (obj==0) 
+      objid = 0;
+   else 
+   if (fObjMap!=0) {
+      ULong_t hash = TMath::Hash(&obj, sizeof(void*));
+      Long_t value = fObjMap->GetValue(hash, (Long_t) obj);
+      if (value>0)
+        objid = fFirstObjId + value - 1;
+   }
+   
+   if (objid>=0) {
       Stack()->SetObjectPointer(objid);
       PopStack();
       return objid;
@@ -244,7 +329,11 @@ Int_t TBufferSQL2::SqlWriteObject(const void* obj, const TClass* cl, TMemberStre
    objid = fObjIdCounter++;
 
    Stack()->SetObjectRef(objid, cl);
-   RegisterPointer(obj, objid);
+   
+   ULong_t hash = TMath::Hash(&obj, sizeof(void*));
+   if (fObjMap==0) fObjMap = new TExMap();
+   if (fObjMap->GetValue(hash, (Long_t) obj)==0)
+      fObjMap->Add(hash, (Long_t) obj, (Long_t) objid - fFirstObjId + 1);
 
    if (streamer!=0)
       (*streamer)(*this, (void*) obj, streamer_index);
@@ -279,21 +368,30 @@ void* TBufferSQL2::SqlReadObject(void* obj, TClass** cl, TMemberStreamer *stream
       fErrorFlag = 1;
       return obj;
    }
+   
+   Long64_t objid = -1;
+   sscanf(refid, FLong64, &objid);
 
    if (!fCurrentData->IsBlobData() ||
        fCurrentData->VerifyDataType(sqlio::ObjectPtr,kFALSE))
-      if (strcmp(refid,"0")==0) {
+      if (objid==0) {
          obj = 0;
          findptr = kTRUE;
       } else
-         if ((fIdArray!=0) && (fObjMap!=0)) {
-            TNamed* identry = (TNamed*) fIdArray->FindObject(refid);
-            if (identry!=0) {
-               obj = (void*) fObjMap->GetValue((Long_t) fIdArray->IndexOf(identry));
-               if (cl) *cl = gROOT->GetClass(identry->GetTitle());
-               findptr = kTRUE;
-            }
+      if (objid==-1) {
+         findptr = kTRUE; 
+      } else 
+      if ((fObjMap!=0) && (objid>=fFirstObjId)) {
+         void* obj1 = (void*) fObjMap->GetValue((Long_t) objid - fFirstObjId);
+         if (obj1!=0) {
+            obj = obj1;
+            findptr = kTRUE;
+            TString clname;
+            Version_t version;
+            if ((cl!=0) && SqlObjectInfo(objid, clname, version))
+              *cl = gROOT->GetClass(clname);
          }
+      }
 
    if ((gDebug>3) && findptr)
       cout << "    Found pointer " << (obj ? obj : 0)
@@ -311,18 +409,16 @@ void* TBufferSQL2::SqlReadObject(void* obj, TClass** cl, TMemberStreamer *stream
          return obj;
       }
 
-   Int_t objid = atoi(refid);
-
    fCurrentData->ShiftToNextValue();
 
-   if (gDebug>2)
+   if ((gDebug>2) || (objid<0))
       cout << "Found object reference " << objid << endl;
 
    return SqlReadObjectDirect(obj, cl, objid, streamer, streamer_index);
 }
 
 //______________________________________________________________________________
-void* TBufferSQL2::SqlReadObjectDirect(void* obj, TClass** cl, Int_t objid, TMemberStreamer *streamer, Int_t streamer_index)
+void* TBufferSQL2::SqlReadObjectDirect(void* obj, TClass** cl, Long64_t objid, TMemberStreamer *streamer, Int_t streamer_index)
 {
    // Read object data.
    // Class name and version are taken from special objects table.
@@ -330,7 +426,10 @@ void* TBufferSQL2::SqlReadObjectDirect(void* obj, TClass** cl, Int_t objid, TMem
    TString clname;
    Version_t version;
 
-   if (!fSQL->GetObjectData(objid, clname, version)) return obj;
+   if (!SqlObjectInfo(objid, clname, version)) return obj;
+
+   if (gDebug>2) 
+      Info("SqlReadObjectDirect","objid = %lld clname = %s ver = %d",objid, clname.Data(), version);
 
    TSQLClassInfo* sqlinfo = fSQL->RequestSQLClassInfo(clname.Data(), version);
 
@@ -342,19 +441,9 @@ void* TBufferSQL2::SqlReadObjectDirect(void* obj, TClass** cl, Int_t objid, TMem
 
    if (obj==0) obj = objClass->New();
 
-   TString strid;
-   strid.Form("%d", objid);
-
-   if (fIdArray==0) {
-      fIdArray = new TObjArray;
-      fIdArray->SetOwner(kTRUE);
-   }
-   TNamed* nid = new TNamed(strid.Data(), objClass->GetName());
-   fIdArray->Add(nid);
-
    if (fObjMap==0) fObjMap = new TExMap();
 
-   fObjMap->Add((Long_t) fIdArray->IndexOf(nid), (Long_t) obj);
+   fObjMap->Add((Long_t) objid - fFirstObjId, (Long_t) obj);
 
    PushStack()->SetObjectRef(objid, objClass);
 
@@ -366,10 +455,10 @@ void* TBufferSQL2::SqlReadObjectDirect(void* obj, TClass** cl, Int_t objid, TMem
 
          TSQLObjectData* objdata = new TSQLObjectData;
          if (objClass==TObject::Class())
-            TSQLStructure::UnpackTObject(fSQL, objdata, objid, version);
+            TSQLStructure::UnpackTObject(fSQL, this, objdata, objid, version);
          else
             if (objClass==TString::Class())
-               TSQLStructure::UnpackTString(fSQL, objdata, objid, version);
+               TSQLStructure::UnpackTString(fSQL, this, objdata, objid, version);
 
          Stack()->AddObjectData(objdata);
          fCurrentData = objdata;
@@ -378,7 +467,7 @@ void* TBufferSQL2::SqlReadObjectDirect(void* obj, TClass** cl, Int_t objid, TMem
          // then streamer functions of TStreamerInfo class
          fReadVersionBuffer = version;
    } else {
-      TSQLObjectData* objdata = fSQL->GetObjectClassData(objid, sqlinfo);
+      TSQLObjectData* objdata = SqlObjectData(objid, sqlinfo);
       if ((objdata==0) || !objdata->PrepareForRawData()) {
          Error("SqlReadObjectDirect","No found raw data for obj %d in class %s version %d table", objid, clname.Data(), version);
          fErrorFlag = 1;
@@ -419,54 +508,10 @@ void  TBufferSQL2::IncrementLevel(TStreamerInfo* info)
 
    PushStack()->SetStreamerInfo(info);
 
-   fExpectedChain = kFALSE;
-
    if (gDebug>2)
-      cout << " IncrementLevel " << info->GetClass()->GetName() << endl;
-
-   if (IsReading()) {
-      Int_t objid = 0;
-
-      Bool_t isclonesarray = Stack()->IsClonesArray();
-
-      if (isclonesarray) {
-         // nothing to do, data will be read from raw data as before
-         return;
-      }
-
-      if ((fCurrentData!=0) && fCurrentData->IsBlobData() &&
-          fCurrentData->VerifyDataType(sqlio::ObjectInst, kFALSE)) {
-         objid = atoi(fCurrentData->GetValue());
-         fCurrentData->ShiftToNextValue();
-         TString sobjid;
-         sobjid.Form("%d",objid);
-         Stack()->ChangeValueOnly(sobjid.Data());
-      } else
-         objid = Stack()->DefineObjectId();
-      if (objid<0) {
-         Error("IncrementLevel","cannot define object id");
-         fErrorFlag = 1;
-         return;
-      }
-
-      TSQLClassInfo* sqlinfo = fSQL->RequestSQLClassInfo(info->GetName(), info->GetClassVersion());
-      if (info==0) {
-         Error("IncrementLevel","Can not find table for class %s version %d",info->GetName(), info->GetClassVersion());
-         fErrorFlag = 1;
-         return;
-      }
-
-      TSQLObjectData* objdata = fSQL->GetObjectClassData(objid, sqlinfo);
-      if (objdata==0) {
-         Error("IncrementLevel","Request error for data of object %d for class %s version %d", objid, info->GetName(), info->GetClassVersion());
-         fErrorFlag = 1;
-         return;
-      }
-
-      Stack()->AddObjectData(objdata);
-
-      fCurrentData = objdata;
-   }
+      cout << " IncrementLevel " << info->GetName() << endl;
+      
+   WorkWithClass(info->GetName(), info->GetClassVersion());
 }
 
 //______________________________________________________________________________
@@ -512,14 +557,261 @@ void TBufferSQL2::SetStreamerElementNumber(Int_t number)
    fExpectedChain = ((elem_type>0) && (elem_type<20)) &&
       (comp_type - elem_type == TStreamerInfo::kOffsetL);
 
-
    WorkWithElement(elem, number);
 }
 
+//______________________________________________________________________________
+void TBufferSQL2::ClassBegin(const TClass* cl, Version_t classversion)
+{
+   // This method inform buffer data of which class now 
+   // will be streamed. When reading, classversion should be specified
+   // as was read by TBuffer::ReadVersion() call
+   // 
+   // ClassBegin(), ClassEnd() & ClassMemeber() should be used in
+   // custom class streamers to specify which kind of data are 
+   // now streamed to/from buffer. That information is used to correctly
+   // convert class data to/from "normal" sql tables with meaningfull names
+   // and correct datatypes. Without that functions data from custom streamer
+   // will be saved as "raw" data in special _streamer_ table one value after another
+   // Such MUST be used when object is written with standard ROOT streaming
+   // procedure, but should be read back in custom streamer. 
+   // For example, custom streamer of TNamed class may look like:
+
+// void TNamed::Streamer(TBuffer &b)   
+//   UInt_t R__s, R__c;
+//   if (b.IsReading()) {
+//      Version_t R__v = b.ReadVersion(&R__s, &R__c);
+//      b.ClassBegin(TNamed::Class(), R__v);
+//      b.ClassMember("TObject");
+//      TObject::Streamer(b);
+//      b.ClassMember("fName","TString");
+//      fName.Streamer(b);
+//      b.ClassMember("fTitle","TString");
+//      fTitle.Streamer(b);
+//      b.ClassEnd(TNamed::Class());
+//      b.SetBufferOffset(R__s+R__c+sizeof(UInt_t));
+//   } else {
+//      TNamed::Class()->WriteBuffer(b,this);
+//   }
+    
+   if (classversion<0) classversion = cl->GetClassVersion();
+   
+   PushStack()->SetCustomClass(cl, classversion);
+
+   if (gDebug>2) Info("ClassBegin", cl->GetName());
+   
+   WorkWithClass(cl->GetName(), classversion);
+}
+
+//______________________________________________________________________________
+void TBufferSQL2::ClassEnd(const TClass* cl)
+{
+   // Method indicates end of streaming of classdata in custom streamer.
+   // See ClassBegin() method for more details. 
+    
+   TSQLStructure* curr = Stack();
+   if (curr->GetType()==TSQLStructure::kSqlCustomElement) PopStack(); // for element
+   PopStack();  // for streamerinfo
+
+   // restore value of object data
+   fCurrentData = Stack()->GetObjectData(kTRUE);
+
+   fExpectedChain = kFALSE;
+
+   if (gDebug>2) Info("ClassEnd",cl->GetName());
+}
+
+//______________________________________________________________________________
+void TBufferSQL2::ClassMember(const char* name, const char* typeName, Int_t arrsize1, Int_t arrsize2)
+{
+   // Method indicates name and typename of class memeber, 
+   // which should be now streamed in custom streamer
+   // Following combinations are supported:
+   // 1. name = "ClassName", typeName = 0 or typename==ClassName
+   //    This is a case, when data of parent class "ClassName" should be streamed.
+   //    For instance, if class directly inherited from TObject, custom
+   //    streamer should include following code:
+   //    b.ClassMember("TObject");
+   //    TObject::Streamer(b);
+   // 2. Basic data type
+   //      b.ClassMember("fInt","Int_t");
+   //      b >> fInt;
+   // 3. Array of basic data types
+   //      b.ClassMember("fArr","Int_t", 5);
+   //      b.ReadFastArray(fArr, 5);
+   // 4. Object as data member
+   //      b.ClassMemeber("fName","TString");
+   //      fName.Streamer(b);
+   // 5. Pointer on object as datamember
+   //      b.ClassMemeber("fObj","TObject*");
+   //      b.StreamObject(b); 
+   // arrsize1 and arrsize2 arguments (when specified) indicate first and
+   // second dimension of array. Can be used for array of basic types.
+   // For more details see ClassBegin() method description.
+    
+   if (typeName==0) typeName = name;
+   
+   if ((name==0) || (strlen(name)==0)) {
+      Error("ClassMember","Invalid member name");
+      fErrorFlag = 1;
+      return;
+   }
+   
+   TString tname = typeName;
+
+   Int_t typ_id = -1;
+   
+   if (strcmp(typeName,"raw:data")==0) 
+      typ_id = TStreamerInfo::kMissing;
+   
+   if (typ_id<0) {
+      TDataType *dt = gROOT->GetType(typeName);
+      if (dt!=0)
+         if ((dt->GetType()>0) && (dt->GetType()<20))
+            typ_id = dt->GetType();
+   }
+   
+   if (typ_id<0) 
+      if (strcmp(name, typeName)==0) {
+         TClass* cl = gROOT->GetClass(tname.Data());
+         if (cl!=0) typ_id = TStreamerInfo::kBase;
+      }
+   
+   if (typ_id<0) {
+      Bool_t isptr = kFALSE;
+      if (tname[tname.Length()-1]=='*') {
+         tname.Resize(tname.Length()-1);
+         isptr = kTRUE;
+      }
+      TClass* cl = gROOT->GetClass(tname.Data());
+      if (cl==0) {
+         Error("ClassMember","Invalid class specifier %s", typeName);
+         fErrorFlag = 1;
+         return;
+      }
+      
+      if (cl->IsTObject())
+        typ_id = isptr ? TStreamerInfo::kObjectp : TStreamerInfo::kObject;
+      else
+        typ_id = isptr ? TStreamerInfo::kAnyp : TStreamerInfo::kAny;
+        
+      if ((cl==TString::Class()) && !isptr)
+         typ_id = TStreamerInfo::kTString;
+   }
+   
+   TStreamerElement* elem = 0;
+   
+   if (typ_id == TStreamerInfo::kMissing) {
+      elem = new TStreamerElement(name,"title",0, typ_id, "raw:data");
+   } else
+   
+   if (typ_id==TStreamerInfo::kBase) {
+      TClass* cl = gROOT->GetClass(tname.Data());
+      if (cl!=0) {
+         TStreamerBase* b = new TStreamerBase(tname.Data(), "title", 0);
+         b->SetBaseVersion(cl->GetClassVersion());
+         elem = b;
+      }
+   } else 
+   
+   if ((typ_id>0) && (typ_id<20)) {
+      elem = new TStreamerBasicType(name, "title", 0, typ_id, typeName);
+   } else
+   
+   if ((typ_id==TStreamerInfo::kObject) ||
+       (typ_id==TStreamerInfo::kTObject) ||
+       (typ_id==TStreamerInfo::kTNamed)) {
+      elem = new TStreamerObject(name, "title", 0, tname.Data());  
+   } else
+   
+   if (typ_id==TStreamerInfo::kObjectp) {
+      elem = new TStreamerObjectPointer(name, "title", 0, tname.Data());
+   } else
+   
+   if (typ_id==TStreamerInfo::kAny) {
+      elem = new TStreamerObjectAny(name, "title", 0, tname.Data());
+   } else
+
+   if (typ_id==TStreamerInfo::kAnyp) {
+      elem = new TStreamerObjectAnyPointer(name, "title", 0, tname.Data());
+   } else
+   
+   if (typ_id==TStreamerInfo::kTString) {
+      elem = new TStreamerString(name, "title", 0);
+   }
+   
+   if (elem==0) {
+      Error("ClassMember","Invalid combination name = %s type = %s", name, typeName);
+      fErrorFlag = 1;
+      return;
+   }
+  
+   if (arrsize1>0) {
+      elem->SetArrayDim(arrsize2>0 ? 2 : 1);
+      elem->SetMaxIndex(0, arrsize1);
+      if (arrsize2>0)
+        elem->SetMaxIndex(1, arrsize2);
+   }
+
+   // return stack to CustomClass node
+   if (Stack()->GetType()==TSQLStructure::kSqlCustomElement) PopStack();
+     
+   fExpectedChain = kFALSE;  
+     
+   // we indicate that there is no streamerinfo 
+   WorkWithElement(elem, -1);
+}
+
+//______________________________________________________________________________
+void TBufferSQL2::WorkWithClass(const char* classname, Version_t classversion)
+{
+   // This function is a part of IncrementLevel method.
+   // Also used in StartClass method
+
+   fExpectedChain = kFALSE;
+
+   if (IsReading()) {
+      Long64_t objid = 0;
+
+      if ((fCurrentData!=0) && fCurrentData->IsBlobData() &&
+          fCurrentData->VerifyDataType(sqlio::ObjectInst, kFALSE)) {
+         objid = atoi(fCurrentData->GetValue());
+         fCurrentData->ShiftToNextValue();
+         TString sobjid;
+         sobjid.Form("%lld",objid);
+         Stack()->ChangeValueOnly(sobjid.Data());
+      } else
+         objid = Stack()->DefineObjectId(kTRUE);
+      if (objid<0) {
+         Error("WorkWithClass","cannot define object id");
+         fErrorFlag = 1;
+         return;
+      }
+
+      TSQLClassInfo* sqlinfo = fSQL->RequestSQLClassInfo(classname, classversion);
+      if (sqlinfo==0) {
+         Error("WorkWithClass","Can not find table for class %s version %d", classname, classversion);
+         fErrorFlag = 1;
+         return;
+      }
+
+      TSQLObjectData* objdata = SqlObjectData(objid, sqlinfo);
+      if (objdata==0) {
+         Error("WorkWithClass","Request error for data of object %lld for class %s version %d", objid, classname, classversion);
+         fErrorFlag = 1;
+         return;
+      }
+
+      Stack()->AddObjectData(objdata);
+
+      fCurrentData = objdata;
+   }
+}
+
 //______________________________________________________________________________
 void TBufferSQL2::WorkWithElement(TStreamerElement* elem, Int_t number)
 {
-   // This function is a part of SetStreamerElementNumber function.
+   // This function is a part of SetStreamerElementNumber method.
    // It is introduced for reading of data for specified data memeber of class.
    // Used also in ReadFastArray methods to resolve problem of compressed data,
    // when several data memebers of the same basic type streamed with single ...FastArray call
@@ -527,7 +819,10 @@ void TBufferSQL2::WorkWithElement(TStreamerElement* elem, Int_t number)
    if (gDebug>2)
       cout << " TBufferSQL2::WorkWithElement " << elem->GetName() << endl;
 
-   PushStack()->SetStreamerElement(elem, number);
+   if (number>=0)
+      PushStack()->SetStreamerElement(elem, number);
+   else 
+      PushStack()->SetCustomElement(elem);
 
    if (IsReading()) {
 
@@ -539,7 +834,7 @@ void TBufferSQL2::WorkWithElement(TStreamerElement* elem, Int_t number)
 
       fCurrentData = Stack()->GetObjectData(kTRUE);
 
-      Int_t located = Stack()->LocateElementColumn(fSQL, fCurrentData);
+      Int_t located = Stack()->LocateElementColumn(fSQL, this, fCurrentData);
 
       if (located==TSQLStructure::kColUnknown) {
          Error("WorkWithElement","Cannot locate correct column in the table");
@@ -595,7 +890,7 @@ void TBufferSQL2::SetByteCount(UInt_t, Bool_t)
 Version_t TBufferSQL2::ReadVersion(UInt_t *start, UInt_t *bcnt, const TClass *)
 {
    // read version value from buffer
-   // actually version is normally defined by table name before
+   // actually version is normally defined by table name
    // and kept in intermediate variable fReadVersionBuffer
 
    Version_t res = 0;
@@ -609,17 +904,17 @@ Version_t TBufferSQL2::ReadVersion(UInt_t *start, UInt_t *bcnt, const TClass *)
       if (gDebug>3)
          cout << "TBufferSQL2::ReadVersion from buffer = " << res << endl;
    } else
-      if ((fCurrentData!=0) && fCurrentData->IsBlobData() &&
-          fCurrentData->VerifyDataType(sqlio::Version)) {
-         TString value = fCurrentData->GetValue();
-         res = value.Atoi();
-         if (gDebug>3)
-            cout << "TBufferSQL2::ReadVersion from blob " << fCurrentData->GetBlobName1() << " = " << res << endl;
-         fCurrentData->ShiftToNextValue();
-      } else {
-         Error("ReadVersion", "No correspondent tags to read version");
-         fErrorFlag = 1;
-      }
+   if ((fCurrentData!=0) && fCurrentData->IsBlobData() &&
+       fCurrentData->VerifyDataType(sqlio::Version)) {
+      TString value = fCurrentData->GetValue();
+      res = value.Atoi();
+      if (gDebug>3)
+         cout << "TBufferSQL2::ReadVersion from blob " << fCurrentData->GetBlobName1() << " = " << res << endl;
+      fCurrentData->ShiftToNextValue();
+   } else {
+      Error("ReadVersion", "No correspondent tags to read version");
+      fErrorFlag = 1;
+   }
 
    return res;
 }
@@ -1994,7 +2289,7 @@ Bool_t TBufferSQL2::SqlWriteBasic(ULong64_t value)
    // converts ULong64_t to string and creates correspondent sql structure
 
    char buf[50];
-   sprintf(buf,"%llu", value);
+   sprintf(buf, FULong64, value);
    return SqlWriteValue(buf, sqlio::ULong64);
 }
 
@@ -2066,7 +2361,7 @@ void TBufferSQL2::SqlReadBasic(Long64_t& value)
 
    const char* res = SqlReadValue(sqlio::Long64);
    if (res)
-      sscanf(res,"%lld", &value);
+      sscanf(res, FLong64, &value);
    else
       value = 0;
 }
@@ -2164,7 +2459,7 @@ void TBufferSQL2::SqlReadBasic(ULong64_t& value)
 
    const char* res = SqlReadValue(sqlio::ULong64);
    if (res)
-      sscanf(res,"%llu", &value);
+      sscanf(res, FULong64, &value);
    else
       value = 0;
 }
@@ -2205,9 +2500,9 @@ const char* TBufferSQL2::SqlReadCharStarValue()
    const char* res = SqlReadValue(sqlio::CharStar);
    if ((res==0) || (fSQL==0)) return 0;
 
-   Int_t objid = Stack()->DefineObjectId();
+   Long64_t objid = Stack()->DefineObjectId(kTRUE);
 
-   Int_t strid = fSQL->IsLongStringCode(res, objid);
+   Int_t strid = fSQL->IsLongStringCode(objid, res);
    if (strid<=0) return res;
 
    fSQL->GetLongString(objid, strid, fReadBuffer);
diff --git a/sql/src/TKeySQL.cxx b/sql/src/TKeySQL.cxx
index ed98c666726..3a5ef2fecf1 100644
--- a/sql/src/TKeySQL.cxx
+++ b/sql/src/TKeySQL.cxx
@@ -1,4 +1,4 @@
-// @(#)root/sql:$Name:  $:$Id: TKeySQL.cxx,v 1.5 2005/12/07 14:59:57 rdm Exp $
+// @(#)root/sql:$Name:  $:$Id: TKeySQL.cxx,v 1.6 2006/01/25 16:00:11 pcanal Exp $
 // Author: Sergey Linev  20/11/2005
 
 /*************************************************************************
@@ -22,6 +22,7 @@
 #include "TROOT.h"
 #include "TClass.h"
 #include "TBrowser.h"
+#include "TDirectory.h"
 #include "Riostream.h"
 
 #include "TSQLResult.h"
@@ -34,16 +35,15 @@ ClassImp(TKeySQL);
 //______________________________________________________________________________
 TKeySQL::TKeySQL() :
    TKey(),
-   fFile(0),
-   fKeyId(-1)
+   fKeyId(-1),
+   fObjId(-1)
 {
    // default constructor
 }
 
 //______________________________________________________________________________
-TKeySQL::TKeySQL(TSQLFile* file, const TObject* obj, const char* name) :
-    TKey(),
-    fFile(file),
+TKeySQL::TKeySQL(TDirectory* mother, const TObject* obj, const char* name, const char* title) :
+    TKey(mother),
     fKeyId(-1),
     fObjId(-1)
 {
@@ -52,14 +52,15 @@ TKeySQL::TKeySQL(TSQLFile* file, const TObject* obj, const char* name) :
    if (name) SetName(name); else
       if (obj!=0) {SetName(obj->GetName());  fClassName=obj->ClassName();}
       else SetName("Noname");
+      
+   if (title) SetTitle(title);
 
-   StoreObject((void*)obj, obj ? obj->IsA() : 0);
+   StoreKeyObject((void*)obj, obj ? obj->IsA() : 0);
 }
 
 //______________________________________________________________________________
-TKeySQL::TKeySQL(TSQLFile* file, const void* obj, const TClass* cl, const char* name) :
-    TKey(),
-    fFile(file),
+TKeySQL::TKeySQL(TDirectory* mother, const void* obj, const TClass* cl, const char* name, const char* title) :
+    TKey(mother),
     fKeyId(-1),
     fObjId(-1)
 {
@@ -68,21 +69,23 @@ TKeySQL::TKeySQL(TSQLFile* file, const void* obj, const TClass* cl, const char*
    if (name && *name) SetName(name);
    else SetName(cl ? cl->GetName() : "Noname");
 
-   StoreObject(obj, cl);
+   if (title) SetTitle(title);
+
+   StoreKeyObject(obj, cl);
 }
 
 //______________________________________________________________________________
-TKeySQL::TKeySQL(TSQLFile* file, Int_t keyid, Int_t dirid, Int_t objid, const char* name,
+TKeySQL::TKeySQL(TDirectory* mother, Long64_t keyid, Long64_t objid, 
+                 const char* name, const char* title,
                  const char* keydatetime, Int_t cycle, const char* classname) :
-    TKey(),
-    fFile(file),
+    TKey(mother),
     fKeyId(keyid),
-    fDirId(dirid),
     fObjId(objid)
 {
    // Create TKeySQL object, which correponds to single entry in keys table
 
    SetName(name);
+   if (title) SetTitle(title);
    TDatime dt(keydatetime);
    fDatime = dt;
    fCycle = cycle;
@@ -96,25 +99,36 @@ TKeySQL::~TKeySQL()
 }
 
 //______________________________________________________________________________
-void TKeySQL::Browse(TBrowser *b)
+Bool_t TKeySQL::IsKeyModified(const char* keyname, const char* keytitle, const char* keydatime, Int_t cycle, const char* classname)
 {
-// Browse object corresponding to this key
-
-   TObject *obj = gDirectory->GetList()->FindObject(GetName());
-   if (obj && !obj->IsFolder()) {
-      if (obj->InheritsFrom(TCollection::Class()))
-         obj->Delete();   // delete also collection elements
-      delete obj;
-      obj = 0;
-   }
-
-   if (!obj)
-      obj = ReadObj();
-
-   if (b && obj) {
-      obj->Browse(b);
-      b->SetRefreshFlag(kTRUE);
-   }
+// Compares keydata with provided and return kTRUE if key was modified
+// Used in TFile::StreamKeysForDirectory() method to verify data for that keys
+// should be updated
+  
+  Int_t len1 = (GetName()==0) ? 0 : strlen(GetName());
+  Int_t len2 = (keyname==0) ? 0 : strlen(keyname);
+  if (len1!=len2) return kTRUE;
+  if ((len1>0) && (strcmp(GetName(), keyname)!=0)) return kTRUE;
+  
+  len1 = (GetTitle()==0) ? 0 : strlen(GetTitle());
+  len2 = (keytitle==0) ? 0 : strlen(keytitle);
+  if (len1!=len2) return kTRUE;
+  if ((len1>0) && (strcmp(GetTitle(), keytitle)!=0)) return kTRUE;
+
+  const char* tm = GetDatime().AsSQLString();
+  len1 = (tm==0) ? 0 : strlen(tm);
+  len2 = (keydatime==0) ? 0 : strlen(keydatime);
+  if (len1!=len2) return kTRUE;
+  if ((len1>0) && (strcmp(tm, keydatime)!=0)) return kTRUE;
+  
+  if (cycle!=GetCycle()) return kTRUE;
+
+  len1 = (GetClassName()==0) ? 0 : strlen(GetClassName());
+  len2 = (classname==0) ? 0 : strlen(classname);
+  if (len1!=len2) return kTRUE;
+  if ((len1>0) && (strcmp(GetClassName(), classname)!=0)) return kTRUE;
+      
+  return kFALSE;
 }
 
 //______________________________________________________________________________
@@ -123,88 +137,47 @@ void TKeySQL::Delete(Option_t * /*option*/)
 // Removes key from current directory
 // Note: TKeySQL object is not deleted. You still have to call "delete key"
 
-   if (fFile!=0)
-      fFile->DeleteKeyFromDB(GetDBKeyId());
+   TSQLFile* f = (TSQLFile*) GetFile(); 
+
+   if (f!=0)
+      f->DeleteKeyFromDB(GetDBKeyId());
 
-   gDirectory->GetListOfKeys()->Remove(this);
+   fMotherDir->GetListOfKeys()->Remove(this);
 }
 
 //______________________________________________________________________________
-void TKeySQL::StoreObject(const void* obj, const TClass* cl)
+Long64_t TKeySQL::GetDBDirId() const
 {
-//  convert object to sql statements and store them in DB
-
-   TObjArray cmds;
-   Bool_t needcommit = kFALSE;
-
-   fCycle = fFile->AppendKey(this);
-
-   fKeyId = fFile->DefineNextKeyId();
-
-   fObjId = fFile->VerifyObjectTable();
-   if (fObjId<=0) fObjId = 1;
-   else fObjId++;
+   // return sql id of parent directory
+   return GetMotherDir() ? GetMotherDir()->GetSeekDir() : 0;
+}
 
-   TBufferSQL2 buffer(TBuffer::kWrite, fFile);
+//______________________________________________________________________________
+void TKeySQL::StoreKeyObject(const void* obj, const TClass* cl)
+{
+   TSQLFile* f = (TSQLFile*) GetFile(); 
+    
+   fCycle = GetMotherDir()->AppendKey(this);
 
-   TSQLStructure* s = buffer.SqlWrite(obj, cl, fObjId);
+   fKeyId = f->DefineNextKeyId();
 
-   if ((buffer.GetErrorFlag()>0) || (s==0)) {
-      Error("StoreObject","Cannot convert object data to TSQLStructure");
-      goto zombie;
-   }
+   fObjId = f->StoreObjectInTables(fKeyId, obj, cl);
 
    if (cl) fClassName = cl->GetName();
    
-   if (fFile->GetUseTransactions()==TSQLFile::kTransactionsAuto) {
-      fFile->SQLStartTransaction();
-      needcommit = kTRUE;
-   }
-
-   // here tables may be already created, therefore 
-   // it should be protected by transactions operations
-   if (!s->ConvertToTables(fFile, fKeyId, &cmds)) {
-      Error("StoreObject","Cannot convert to SQL statements");
-      goto zombie;
-   }
-   
-   if (!fFile->SQLApplyCommands(&cmds)) {
-      Error("StoreObject","Cannot correctly store object data in database");
-      goto zombie; 
-   }
-
-   // commit here, while objects data is already stored 
-   if (needcommit) {
-      fFile->SQLCommit();
-      needcommit = kFALSE;
-   }
-
-   cmds.Delete();
-
-   fDatime.Set();
-   
-   if (!fFile->WriteKeyData(GetDBKeyId(),
-                            sqlio::Ids_RootDir, // later parent directory id should be
-                            GetDBObjId(),
-                            GetName(),
-                            GetDatime().AsSQLString(),
-                            GetCycle(),
-                            GetClassName())) {
-      // cannot add entry to keys table                          
-      Error("StoreObject","Cannot write data to key tables");
-      // delete everything relevant for that key
-      fFile->DeleteKeyFromDB(GetDBKeyId());
-      goto zombie;                           
+   if (GetDBObjId()>=0) { 
+      fDatime.Set();
+      if (!f->WriteKeyData(this)) {
+         // cannot add entry to keys table                          
+         Error("StoreObject","Cannot write data to key tables");
+         // delete everything relevant for that key
+         f->DeleteKeyFromDB(GetDBKeyId());
+         fObjId = -1;
+      }
    }
-
-   return;
    
-zombie:
-   if (needcommit)
-      fFile->SQLRollback();
-
-   cmds.Delete();
-   gDirectory->GetListOfKeys()->Remove(this);
+   if (GetDBObjId()<0)
+      GetMotherDir()->GetListOfKeys()->Remove(this);
    // fix me !!! One should delete object by other means
    // delete this;
 }
@@ -219,7 +192,7 @@ Int_t TKeySQL::Read(TObject* tobj)
 
    if (tobj==0) return 0; 
     
-   void* res = SqlReadAny(tobj, 0);
+   void* res = ReadKeyObject(tobj, 0);
    
    return res==0 ? 0 : 1;
 }
@@ -230,9 +203,20 @@ TObject* TKeySQL::ReadObj()
 // Read object derived from TObject class
 // If it is not TObject or in case of error, return 0
 
-   TObject* tobj = (TObject*) SqlReadAny(0, TObject::Class());
+   TObject* tobj = (TObject*) ReadKeyObject(0, TObject::Class());
    
-   if ((tobj!=0) && gROOT->GetForceStyle()) tobj->UseCurrentStyle();
+   if (tobj!=0) {
+      if (gROOT->GetForceStyle()) tobj->UseCurrentStyle();
+      if (tobj->IsA() == TDirectory::Class()) {
+         TDirectory *dir = (TDirectory*) tobj;
+         dir->SetName(GetName());
+         dir->SetTitle(GetTitle());
+         //dir->SetSeekDir(GetDBKeyId());
+         dir->ReadKeys();
+         dir->SetMother(fMotherDir);
+         fMotherDir->Append(dir);
+      }
+   }
        
    return tobj;
 }
@@ -242,19 +226,22 @@ void* TKeySQL::ReadObjectAny(const TClass* expectedClass)
 {
 // read object of any type from SQL database
 
-   return SqlReadAny(0, expectedClass);
+   return ReadKeyObject(0, expectedClass);
 }
 
 //______________________________________________________________________________
-void* TKeySQL::SqlReadAny(void* obj, const TClass* expectedClass)
+void* TKeySQL::ReadKeyObject(void* obj, const TClass* expectedClass)
 {
-   if ((fKeyId<=0) || (fFile==0)) return 0;
 
-   TBufferSQL2 buffer(TBuffer::kRead, fFile);
+   TSQLFile* f = (TSQLFile*) GetFile(); 
+
+   if ((GetDBKeyId()<=0) || (f==0)) return obj;
+
+   TBufferSQL2 buffer(TBuffer::kRead, f);
    
    TClass* cl = 0;
 
-   void* res = buffer.SqlReadAny(fObjId, obj, &cl);
+   void* res = buffer.SqlReadAny(GetDBKeyId(), GetDBObjId(), &cl, obj);
    
    if ((cl==0) || (res==0)) return 0;
    
diff --git a/sql/src/TSQLFile.cxx b/sql/src/TSQLFile.cxx
index 22ae48dd780..775fada623b 100644
--- a/sql/src/TSQLFile.cxx
+++ b/sql/src/TSQLFile.cxx
@@ -1,4 +1,4 @@
-// @(#)root/sql:$Name:  $:$Id: TSQLFile.cxx,v 1.5 2005/12/07 14:59:57 rdm Exp $
+// @(#)root/sql:$Name:  $:$Id: TSQLFile.cxx,v 1.6 2006/01/25 16:00:11 pcanal Exp $
 // Author: Sergey Linev  20/11/2005
 
 /*************************************************************************
@@ -388,6 +388,7 @@ TSQLFile::TSQLFile() :
    fUseTransactions(0),
    fUseIndexes(0),
    fModifyCounter(0),
+   fQuerisCounter(0),
    fBasicTypes(0),
    fOtherTypes(0),
    fUserName(),
@@ -409,6 +410,7 @@ TSQLFile::TSQLFile(const char* dbname, Option_t* option, const char* user, const
    fUseTransactions(0),
    fUseIndexes(0),
    fModifyCounter(0),
+   fQuerisCounter(0),
    fBasicTypes(mysql_BasicTypes),
    fOtherTypes(mysql_OtherTypes),
    fUserName(user),
@@ -472,6 +474,7 @@ TSQLFile::TSQLFile(const char* dbname, Option_t* option, const char* user, const
    fCache      = 0;
    fProcessIDs = 0;
    fNProcessIDs= 0;
+   fSeekDir    = sqlio::Ids_RootDir;
 
    fOption = option;
    fOption.ToUpper();
@@ -883,17 +886,25 @@ Int_t TSQLFile::ReOpen(Option_t* mode)
 }
 
 //______________________________________________________________________________
-TKey* TSQLFile::CreateKey(const TObject* obj, const char* name, Int_t )
+TKey* TSQLFile::CreateKey(TDirectory* mother, const TObject* obj, const char* name, Int_t )
 {
    // create SQL key, which will store object in data base
-   return new TKeySQL(this, obj, name);
+   return new TKeySQL(mother, obj, name);
 }
 
 //______________________________________________________________________________
-TKey* TSQLFile::CreateKey(const void* obj, const TClass* cl, const char* name, Int_t )
+TKey* TSQLFile::CreateKey(TDirectory* mother, const void* obj, const TClass* cl, const char* name, Int_t )
 {
    // create SQL key, which will store object in data base
-   return new TKeySQL(this, obj, cl, name);
+   return new TKeySQL(mother, obj, cl, name);
+}
+
+//______________________________________________________________________________
+void TSQLFile::WriteHeader()
+{
+   // Write file info like configurations, title, UUID and other
+      
+//   WriteSpecialObject(sqlio::Ids_TSQLFile, this, GetName(), GetTitle());
 }
 
 //______________________________________________________________________________
@@ -908,8 +919,6 @@ void TSQLFile::WriteStreamerInfo()
    // do not write anything when no basic tables was created
    if (!IsTablesExists()) return;
 
-   Int_t keyid = sqlio::Ids_StreamerInfos;
-
    if (gDebug>1)
       Info("WriteStreamerInfo","Saving streamer infos to database");
 
@@ -929,27 +938,60 @@ void TSQLFile::WriteStreamerInfo()
    if (list.GetSize()==0) return;
    fClassIndex->fArray[0] = 2; //to prevent adding classes in TStreamerInfo::TagFile
 
-   DeleteKeyFromDB(keyid);
+   WriteSpecialObject(sqlio::Ids_StreamerInfos, &list, "StreamerInfo", "StreamerInfos of this file");
 
-   Int_t objid = VerifyObjectTable();
-   if (objid<=0) objid = 1;
-   else objid++;
+   fClassIndex->fArray[0] = 0; //to prevent adding classes in TStreamerInfo::TagFile
+}
 
-   TBufferSQL2 buffer(TBuffer::kWrite, this);
+//______________________________________________________________________________
+Bool_t TSQLFile::WriteSpecialObject(Long64_t keyid, TObject* obj, const char* name, const char* title)
+{
+// write special kind of object like streamer infos or file itself    
+// keys for that objects should exist in tables but not indicated in list of keys,
+// therefore users can not get them with TDirectory::Get() method
+    
+   DeleteKeyFromDB(keyid);  
+   if (obj==0) return kTRUE;
 
-   TSQLStructure* s = buffer.SqlWrite(&list, list.IsA(), objid);
-   if (gDebug>4)
-      s->Print("*");
+   Long64_t objid = StoreObjectInTables(keyid, obj, obj->IsA());
 
-   TObjArray cmds;
-   TDatime now;
-   if (s->ConvertToTables(this, keyid, &cmds))
-      if (SQLApplyCommands(&cmds))
-         WriteKeyData(keyid, sqlio::Ids_RootDir, objid, "StreamerInfo", now.AsSQLString(), 1, list.IsA()->GetName());
+   if (objid>0) {
+      TDatime now; 
+      
+      TKeySQL* key = new TKeySQL(this, keyid, objid,
+                                 name, title,
+                                 now.AsSQLString(), 1, obj->ClassName());
+      WriteKeyData(key);
+      delete key;                           
+   }
+   
+   return (objid>0);
+}
 
-   cmds.Delete();
+//______________________________________________________________________________
+TObject* TSQLFile::ReadSpecialObject(Long64_t keyid, TObject* obj)
+{
+// Read data of special kind of objects
 
-   fClassIndex->fArray[0] = 0; //to prevent adding classes in TStreamerInfo::TagFile
+   TKeySQL* key = 0;
+
+   StreamKeysForDirectory(this, kFALSE, keyid, &key);
+   if (key==0) return obj;
+   
+   TBufferSQL2 buffer(TBuffer::kRead, this);
+
+   TClass* cl = 0;
+
+   void* res = buffer.SqlReadAny(key->GetDBKeyId(), key->GetDBObjId(), &cl, obj);
+ 
+   if ((cl==TSQLFile::Class()) && (res!=0) && (obj==this)) {
+      // name should not be preserved while name of database may be was changed 
+      SetTitle(key->GetTitle());
+   }
+   
+   delete key;
+   
+   return (TObject*) res;
 }
 
 //______________________________________________________________________________
@@ -963,53 +1005,106 @@ TList* TSQLFile::GetStreamerInfoList()
    // Hopefully, problem will be solved soon
 
    return new TList;
+   
+   if (gDebug>1)
+      Info("GetStreamerInfoList","Start reading of streamer infos");
+
+   TObject* obj = ReadSpecialObject(sqlio::Ids_StreamerInfos);
+   
+   TList* list = dynamic_cast<TList*> (obj);
+   if (list==0) { delete obj; list = new TList; }
+
+   return list;
 }
 
 //______________________________________________________________________________
 void TSQLFile::SaveToDatabase()
 {
    // save data which is not yet in Database
-   // Typically this is streamerinfos structures
+   // Typically this is streamerinfos structures or 
 
    if (fSQL==0) return;
+   
    WriteStreamerInfo();
+   WriteHeader();
 }
 
 //______________________________________________________________________________
-Bool_t TSQLFile::ReadKeysForDirectory(TDirectory* dir, Int_t dir_id)
+Int_t TSQLFile::StreamKeysForDirectory(TDirectory* dir, Bool_t doupdate, Long64_t specialkeyid, TKeySQL** specialkey)
 {
-   // read keys for specified direccctory
-
-   if ((dir==0) || (dir_id<0)) return kFALSE;
+   // read keys for specified directory (when update == kFALSE)
+   // or update value for modified keys when update == kTRUE
+   // Returns number of succesfully read keys or -1 if error
 
+   if (dir==0) return -1;
+   
    const char* quote = SQLIdentifierQuote();
+   
+   Long64_t dirid = dir->GetSeekDir();
 
    TString sqlcmd;
-   sqlcmd.Form("SELECT * FROM %s%s%s WHERE %s%s%s=%d",
+   sqlcmd.Form("SELECT * FROM %s%s%s WHERE %s%s%s=%lld",
                quote, sqlio::KeysTable, quote,
-               quote, SQLDirIdColumn(), quote, dir_id);
+               quote, SQLDirIdColumn(), quote, dirid);
+   if (specialkeyid>=0) {
+      TString buf;
+      buf.Form(" AND %s%s%s=%lld", quote, SQLKeyIdColumn(), quote, specialkeyid);
+      sqlcmd += buf;
+   }
+               
    TSQLResult* res = SQLQuery(sqlcmd.Data(), 2);
 
-   if (res==0) return kFALSE;
+   if (res==0) return -1;
+   
+   Int_t nkeys = res->GetRowCount();
 
-   for(Int_t nrow=0;nrow<res->GetRowCount();nrow++) {
+   for(Int_t nrow=0;nrow<nkeys;nrow++) {
       TSQLRow* row = res->Next();
-
-      Int_t keyid = atoi((*row)[0]);
+   
+      Long64_t keyid = sqlio::atol64((*row)[0]);
       //      Int_t dirid = atoi((*row)[1]);
-      Int_t objid = atoi((*row)[2]);
-
-      Int_t cycle = atoi((*row)[5]);
-
-      if (keyid!=sqlio::Ids_StreamerInfos) {
-         TKeySQL* key = new TKeySQL(this, keyid, dir_id, objid, (*row)[3], (*row)[4], cycle, (*row)[6]);
-         dir->AppendKey(key);
-      }
+      Long64_t objid = sqlio::atol64((*row)[2]);
+      const char* keyname = (*row)[3];
+      const char* keytitle = (*row)[4];
+      const char* keydatime = (*row)[5];
+      Int_t cycle = atoi((*row)[6]);
+      const char* classname = (*row)[7];
+      
+      if (gDebug>4) 
+        cout << "  Reading keyid = " << keyid << " name = " << keyname << endl;
+
+      if ((keyid>=sqlio::Ids_FirstKey) || (keyid==specialkeyid))
+         if (doupdate) {
+           TKeySQL* key = FindSQLKey(dir, keyid);
+           
+           if (key==0) {
+              Error("StreamKeysForDirectory","Key with id %d not exist in list", keyid);
+              nkeys = -1; // this will finish execution
+           } else 
+           if (key->IsKeyModified(keyname, keytitle, keydatime, cycle, classname))
+              UpdateKeyData(key);
+             
+         } else {
+            TKeySQL* key = new TKeySQL(dir, keyid, objid, 
+                                       keyname, keytitle, 
+                                       keydatime, cycle, classname);
+            if (specialkey!=0) 
+               { *specialkey = key; nkeys = 1; }
+            else   
+               dir->GetListOfKeys()->Add(key);
+         }
 
       delete row;
    }
+   
+   delete res;
 
-   return kTRUE;
+   if (gDebug>4) {
+      Info("StreamKeysForDirectory","dir = %s numread = %d",dir->GetName(), nkeys);
+      dir->GetListOfKeys()->Print("*");   
+   }
+
+   return nkeys;
 }
 
 //______________________________________________________________________________
@@ -1026,11 +1121,16 @@ void TSQLFile::InitSqlDatabase(Bool_t create)
    if (!create) {
       Bool_t ok = ReadConfigurations();
 
+      // read data corresponding to TSQLFile
       if (ok) {
          ReadStreamerInfo();
-         ok = ReadKeysForDirectory(this, sqlio::Ids_RootDir);
+//         ok = (ReadSpecialObject(sqlio::Ids_TSQLFile, this) != 0);  
       }
       
+      // read list of keys   
+      if (ok)   
+         ok = StreamKeysForDirectory(this, kFALSE)>=0;
+         
       if (!ok) {
          Error("InitSqlDatabase", "Cannot detect proper tabled in database. Close.");
          Close();
@@ -1132,11 +1232,11 @@ void TSQLFile::CreateBasicTables()
       SQLQuery(sqlcmd.Data());
    }
 
-   sqlcmd.Form("CREATE TABLE %s%s%s (%s %s, %s %s)",
+   sqlcmd.Form("CREATE TABLE %s%s%s (%s%s%s %s, %s%s%s %s)",
                quote, sqlio::ConfigTable, quote,
-               sqlio::CT_Field, SQLSmallTextType(),
-               sqlio::CT_Value, SQLSmallTextType());
-   if (fTablesType.Length()>0) {
+               quote, sqlio::CT_Field, quote, SQLSmallTextType(),
+               quote, sqlio::CT_Value, quote, SQLSmallTextType());
+   if ((fTablesType.Length()>0) && IsMySQL()) {
       sqlcmd +=" TYPE=";
       sqlcmd += fTablesType;
    }
@@ -1169,17 +1269,18 @@ void TSQLFile::CreateBasicTables()
       SQLQuery(sqlcmd.Data());
    }
 
-   sqlcmd.Form("CREATE TABLE %s%s%s (%s%s%s %s, %s%s%s %s, %s%s%s %s, %s %s, %s %s, %s %s, %s %s)",
+   sqlcmd.Form("CREATE TABLE %s%s%s (%s%s%s %s, %s%s%s %s, %s%s%s %s, %s%s%s %s, %s%s%s %s, %s%s%s %s, %s%s%s %s, %s%s%s %s)",
                quote, sqlio::KeysTable, quote,
                quote, SQLKeyIdColumn(), quote, SQLIntType(),
                quote, SQLDirIdColumn(), quote, SQLIntType(),
                quote, SQLObjectIdColumn(), quote, SQLIntType(),
-               sqlio::KT_Name, SQLSmallTextType(),
-               sqlio::KT_Datetime, SQLDatetimeType(),
-               sqlio::KT_Cycle, SQLIntType(),
-               sqlio::KT_Class, SQLSmallTextType());
+               quote, sqlio::KT_Name, quote, SQLSmallTextType(),
+               quote, sqlio::KT_Title, quote, SQLSmallTextType(),
+               quote, sqlio::KT_Datetime, quote, SQLDatetimeType(),
+               quote, sqlio::KT_Cycle, quote, SQLIntType(),
+               quote, sqlio::KT_Class, quote, SQLSmallTextType());
                
-   if (fTablesType.Length()>0) {
+   if ((fTablesType.Length()>0) && IsMySQL()) {
       sqlcmd +=" TYPE=";
       sqlcmd += fTablesType;
    }
@@ -1413,6 +1514,8 @@ TSQLResult* TSQLFile::SQLQuery(const char* cmd, Int_t flag, Bool_t* ok)
    if (fSQL==0) return 0;
 
    if (gDebug>2) Info("SQLQuery",cmd);
+   
+   fQuerisCounter++;
 
    TSQLResult* res = fSQL->Query(cmd);
    if (ok!=0) *ok = res!=0;
@@ -1466,13 +1569,12 @@ TObjArray* TSQLFile::SQLTablesList(const char* searchtable)
       sqlcmd.Form("SELECT object_name FROM ALL_OBJECTS WHERE object_type='TABLE' and owner='%s'",user.Data());
       if (searchtable!=0) {
          TString table = searchtable;
-         table.ToUpper();
          sqlcmd += Form(" and object_name='%s'",table.Data());
       }
 
       TSQLResult* tables = SQLQuery(sqlcmd.Data(), 1);
       if (tables==0) return 0;
-
+      
       TSQLRow* row = tables->Next();
       while (row!=0) {
          const char* tablename = row->GetField(0);
@@ -1515,7 +1617,20 @@ TObjArray* TSQLFile::SQLTableColumns(const char* tablename)
    TObjArray* res = 0;
 
    if (IsOracle()) {
-      TSQLResult* cols = fSQL->GetColumns(0, tablename, "");
+
+//      TSQLResult* cols = fSQL->GetColumns(0, tablename, "");
+//      if  (cols==0) return 0;
+//      for (Int_t n=0;n<cols->GetFieldCount();n++) {
+//         TNamed* col = new TNamed(cols->GetFieldName(n), "TYPE?");
+//         if (res==0) res = new TObjArray;
+//         res->Add(col);
+//      }
+//      delete cols;
+      TString sqlcmd;
+      const char* quote = SQLIdentifierQuote();
+      sqlcmd.Form("SELECT * FROM %s%s%s WHERE ROWNUM<2",
+                    quote, tablename, quote);
+      TSQLResult* cols = SQLQuery(sqlcmd.Data(), 1);
       if  (cols==0) return 0;
       for (Int_t n=0;n<cols->GetFieldCount();n++) {
          TNamed* col = new TNamed(cols->GetFieldName(n), "TYPE?");
@@ -1523,7 +1638,6 @@ TObjArray* TSQLFile::SQLTableColumns(const char* tablename)
          res->Add(col);
       }
       delete cols;
-
    } else {
       TSQLResult* cols = fSQL->GetColumns(GetDataBaseName(), tablename, "");
 
@@ -1558,13 +1672,15 @@ Bool_t TSQLFile::SQLTestTable(const char* tablename)
 }
 
 //______________________________________________________________________________
-Int_t TSQLFile::SQLMaximumValue(const char* tablename, const char* columnname)
+Long64_t TSQLFile::SQLMaximumValue(const char* tablename, const char* columnname)
 {
    // Returns maximum value, found in specified columnname of table tablename
    // Column type should be numeric
 
    if (fSQL==0) return -1;
 
+   if (fSQL==0) return -1;
+
    if (gDebug>2)
       Info("SQLMaximumValue","Requests for %s column %s", tablename, columnname);
 
@@ -1580,16 +1696,16 @@ Int_t TSQLFile::SQLMaximumValue(const char* tablename, const char* columnname)
 
    TSQLRow* row = res->Next();
 
-   Int_t maxid = -1;
+   Long64_t maxid = -1;
    if (row!=0)
       if (row->GetField(0)!=0)
-         maxid = atoi(row->GetField(0));
+         maxid = sqlio::atol64(row->GetField(0));
 
    delete row;
    delete res;
 
    if (gDebug>2)
-      Info("SQLMaximumValue","Result = %d",maxid);;
+      Info("SQLMaximumValue","Result = %lld",maxid);;
 
    return maxid;
 }
@@ -1645,61 +1761,105 @@ Bool_t TSQLFile::SQLRollback()
 }
 
 //______________________________________________________________________________
-void TSQLFile::DeleteKeyFromDB(Int_t keyid)
+void TSQLFile::DeleteKeyFromDB(Long64_t keyid)
 {
-   // remove key with specified id from keys table
-   // also removes all objects data, releta to this table
-
+// remove key with specified id from keys table
+// also removes all objects data, related to this table
+   
    if (!IsWritable() || (keyid<0) || (fSQL==0)) return;
 
-   TString query;
+   TString sqlcmd;
    const char* quote = SQLIdentifierQuote();
 
-   query.Form("SELECT * FROM %s%s%s WHERE %s%s%s=%d",
-              quote, sqlio::ObjectsTable, quote,
-              quote, SQLKeyIdColumn(), quote,
-              keyid);
-   TSQLResult* res = SQLQuery(query.Data(), 2);
-   if (res==0) return;
-   TSQLRow* row = res->Next();
-   while (row!=0) {
-      Int_t objid = atoi(row->GetField(1));
-      DeleteObjectFromTables(objid);
-      delete row;
-      row = res->Next();
+   sqlcmd.Form("SELECT MIN(%s%s%s), MAX(%s%s%s) FROM %s%s%s WHERE %s%s%s=%lld",
+               quote, SQLObjectIdColumn(), quote,
+               quote, SQLObjectIdColumn(), quote,
+               quote, sqlio::ObjectsTable, quote,
+               quote, SQLKeyIdColumn(), quote, keyid);
+   TSQLResult* res = SQLQuery(sqlcmd.Data(), 2);
+   TSQLRow* row = res==0 ? 0 : res->Next();
+   Long64_t minid(1), maxid(0);
+   
+   if ((row!=0) && (row->GetField(0)!=0) && (row->GetField(1)!=0)) {
+      minid = sqlio::atol64(row->GetField(0));
+      maxid = sqlio::atol64(row->GetField(1));
    }
-
+   
+   delete row;
    delete res;
+  
+   // can be that object tables does not include any entry this that keyid 
+   if (minid<=maxid) {
+      TObjArray* tables = SQLTablesList();
+      TIter iter(tables);
+      TObject* obj = 0;
+      while ((obj=iter())!=0) {
+         TString tablename = obj->GetName();
+
+         if ((tablename.CompareTo(sqlio::KeysTable,TString::kIgnoreCase)==0) ||
+             (tablename.CompareTo(sqlio::ObjectsTable,TString::kIgnoreCase)==0) ||
+             (tablename.CompareTo(sqlio::ConfigTable,TString::kIgnoreCase)==0)) continue;
+   
+         TString query;
+         query.Form("DELETE FROM %s%s%s WHERE %s%s%s BETWEEN %lld AND %lld", 
+                     quote, tablename.Data(), quote,
+                     quote, SQLObjectIdColumn(), quote, 
+                     minid, maxid);
+         SQLQuery(query.Data());
+      }
+   
+      delete tables;
+   }
 
-   query.Form("DELETE FROM %s WHERE %s%s%s=%d", sqlio::ObjectsTable, quote, SQLKeyIdColumn(), quote, keyid);
-   SQLQuery(query.Data());
+   sqlcmd.Form("DELETE FROM %s%s%s WHERE %s%s%s=%lld", quote, sqlio::ObjectsTable, quote, quote, SQLKeyIdColumn(), quote, keyid);
+   SQLQuery(sqlcmd.Data());
 
-   query.Form("DELETE FROM %s WHERE %s%s%s=%d", sqlio::KeysTable, quote, SQLKeyIdColumn(), quote, keyid);
-   SQLQuery(query.Data());
+   sqlcmd.Form("DELETE FROM %s%s%s WHERE %s%s%s=%lld", quote, sqlio::KeysTable, quote, quote, SQLKeyIdColumn(), quote, keyid);
+   SQLQuery(sqlcmd.Data());
    
    IncrementModifyCounter();
 }
 
 //______________________________________________________________________________
-Bool_t TSQLFile::WriteKeyData(Int_t keyid, Int_t dirid, Int_t objid, const char* keyname, const char* datime, Int_t cycle, const char* clname)
+TKeySQL* TSQLFile::FindSQLKey(TDirectory* dir, Long64_t keyid)
+{
+   // Search for TKeySQL object with specified keyid
+    
+   if (dir==0) return 0;
+   
+   TIter next(dir->GetListOfKeys());
+   TObject* obj = 0;
+   
+   while ((obj = next())!=0) {
+      TKeySQL* key = dynamic_cast<TKeySQL*> (obj);
+      if (key!=0)
+        if (key->GetDBKeyId()==keyid) return key;
+   }
+   
+   return 0;
+}
+
+//______________________________________________________________________________
+Bool_t TSQLFile::WriteKeyData(TKeySQL* key)
 {
    // add entry into keys table
 
-   if (fSQL==0) return kFALSE;
+   if ((fSQL==0) || (key==0)) return kFALSE;
 
    if (!IsTablesExists()) CreateBasicTables();
 
    TString sqlcmd;
    const char* valuequote = SQLValueQuote();
    const char* quote = SQLIdentifierQuote();
-
-   sqlcmd.Form("INSERT INTO %s%s%s VALUES (%d, %d, %d, %s%s%s, %s%s%s, %d, %s%s%s)",
+   
+   sqlcmd.Form("INSERT INTO %s%s%s VALUES (%lld, %lld, %lld, %s%s%s, %s%s%s, %s%s%s, %d, %s%s%s)",
                quote, sqlio::KeysTable, quote,
-               keyid, dirid, objid,
-               valuequote, keyname, valuequote,
-               valuequote, datime, valuequote,
-               cycle,
-               valuequote, clname, valuequote);
+               key->GetDBKeyId(), key->GetDBDirId(), key->GetDBObjId(),
+               valuequote, key->GetName(), valuequote,
+               valuequote, key->GetTitle(), valuequote,
+               valuequote, key->GetDatime().AsSQLString(), valuequote,
+               key->GetCycle(),
+               valuequote, key->GetClassName(), valuequote);
 
    Bool_t ok = kTRUE;
    
@@ -1711,11 +1871,37 @@ Bool_t TSQLFile::WriteKeyData(Int_t keyid, Int_t dirid, Int_t objid, const char*
 }
 
 //______________________________________________________________________________
-Int_t TSQLFile::DefineNextKeyId()
+Bool_t TSQLFile::UpdateKeyData(TKeySQL* key)
+{
+   if ((fSQL==0) || (key==0)) return kFALSE;
+
+   TString sqlcmd;
+   const char* valuequote = SQLValueQuote();
+   const char* quote = SQLIdentifierQuote();
+
+   sqlcmd.Form("UPDATE %s%s%s SET %s%s%s=%s, %s%s%s=%s, %s%s%s=%s, %s=%s WHERE %s%s%s=%lld",
+                quote, sqlio::KeysTable, quote,
+                sqlio::KT_Name, valuequote, key->GetName(), valuequote,
+                sqlio::KT_Title, valuequote, key->GetTitle(), valuequote,
+                sqlio::KT_Datetime, valuequote, key->GetDatime().AsSQLString(), valuequote,
+                sqlio::KT_Cycle, key->GetCycle(),
+                quote, SQLKeyIdColumn(), quote, key->GetDBKeyId());
+
+   Bool_t ok = kTRUE;
+   
+   SQLQuery(sqlcmd.Data(), 0, &ok);
+   
+   if (ok) IncrementModifyCounter();
+   
+   return ok;
+}
+
+//______________________________________________________________________________
+Long64_t TSQLFile::DefineNextKeyId()
 {
    // Returns next possible key identifier
 
-   Int_t max = -1;
+   Long64_t max = -1;
 
    if (SQLTestTable(sqlio::KeysTable))
       max = SQLMaximumValue(sqlio::KeysTable, SQLKeyIdColumn());
@@ -1830,7 +2016,7 @@ Bool_t TSQLFile::SyncSQLClassInfo(TSQLClassInfo* sqlinfo, TObjArray* columns, Bo
       }
       sqlcmd += ")";
       
-      if (fTablesType.Length()>0) {
+      if ((fTablesType.Length()>0)  && IsMySQL()) {
          sqlcmd +=" TYPE=";
          sqlcmd += fTablesType;
       }
@@ -1858,7 +2044,7 @@ Bool_t TSQLFile::SyncSQLClassInfo(TSQLClassInfo* sqlinfo, TObjArray* columns, Bo
                   sqlio::BT_Field, SQLSmallTextType(),
                   sqlio::BT_Value, SQLSmallTextType());
                   
-      if (fTablesType.Length()>0) {
+      if ((fTablesType.Length()>0) && IsMySQL()) {
          sqlcmd +=" TYPE=";
          sqlcmd += fTablesType;
       }
@@ -1910,16 +2096,16 @@ Bool_t TSQLFile::VerifyLongStringTable()
 }
 
 //______________________________________________________________________________
-TString TSQLFile::CodeLongString(Int_t objid, Int_t strid)
+TString TSQLFile::CodeLongString(Long64_t objid, Int_t strid)
 {
    // produces id which will be placed in column instead of string itself
    TString res;
-   res.Form("%s %d %s %d %s", sqlio::LongStrPrefix, objid, sqlio::LongStrPrefix, strid, sqlio::LongStrPrefix);
+   res.Form("%s %lld %s %d %s", sqlio::LongStrPrefix, objid, sqlio::LongStrPrefix, strid, sqlio::LongStrPrefix);
    return res;
 }
 
 //______________________________________________________________________________
-Int_t TSQLFile::IsLongStringCode(const char* value, Int_t objid)
+Int_t TSQLFile::IsLongStringCode(Long64_t objid, const char* value)
 {
    // checks if this is long string code
    // returns 0, if not or string id
@@ -1948,13 +2134,14 @@ Int_t TSQLFile::IsLongStringCode(const char* value, Int_t objid)
 
    if ((*value==0) || (strcmp(value, sqlio::LongStrPrefix)!=0)) return 0;
 
-   if (atoi(s_objid.Data())!=objid) return 0;
+   Long64_t objid2 = sqlio::atol64(s_objid.Data());
+   if (objid2!=objid) return 0;
 
    return atoi(s_strid.Data());
 }
 
 //______________________________________________________________________________
-Bool_t TSQLFile::GetLongString(Int_t objid, Int_t strid, TString& value)
+Bool_t TSQLFile::GetLongString(Long64_t objid, Int_t strid, TString& value)
 {
    // returns value of string, extracted from special table,
    // where long strings are stored
@@ -1963,7 +2150,7 @@ Bool_t TSQLFile::GetLongString(Int_t objid, Int_t strid, TString& value)
 
    TString cmd;
    const char* quote = SQLIdentifierQuote();
-   cmd.Form("SELECT %s FROM %s%s%s WHERE %s%s%s=%d AND %s%s%s=%d",
+   cmd.Form("SELECT %s FROM %s%s%s WHERE %s%s%s=%lld AND %s%s%s=%d",
             sqlio::ST_Value,
             quote, sqlio::StringsTable, quote,
             quote, SQLObjectIdColumn(), quote, objid,
@@ -1982,7 +2169,7 @@ Bool_t TSQLFile::GetLongString(Int_t objid, Int_t strid, TString& value)
 }
 
 //______________________________________________________________________________
-Int_t TSQLFile::VerifyObjectTable()
+Long64_t TSQLFile::VerifyObjectTable()
 {
    // Checks that objects table is exists
    // If not, table will be created
@@ -1990,7 +2177,7 @@ Int_t TSQLFile::VerifyObjectTable()
 
    if (fSQL==0) return -1;
 
-   Int_t maxid = -1;
+   Long64_t maxid = -1;
 
    if (gDebug>2)
       Info("VerifyObjectTable", "Checks if object table is there");
@@ -2000,14 +2187,14 @@ Int_t TSQLFile::VerifyObjectTable()
    else {
       TString sqlcmd;
       const char* quote = SQLIdentifierQuote();
-      sqlcmd.Form("CREATE TABLE %s%s%s (%s%s%s %s, %s%s%s %s, %s %s, %s %s)",
+      sqlcmd.Form("CREATE TABLE %s%s%s (%s%s%s %s, %s%s%s %s, %s%s%s %s, %s%s%s %s)",
                   quote, sqlio::ObjectsTable, quote,
                   quote, SQLKeyIdColumn(), quote, SQLIntType(),
                   quote, SQLObjectIdColumn(), quote, SQLIntType(),
-                  sqlio::OT_Class, SQLSmallTextType(),
-                  sqlio::OT_Version, SQLIntType());
+                  quote, sqlio::OT_Class, quote, SQLSmallTextType(),
+                  quote, sqlio::OT_Version, quote, SQLIntType());
 
-      if (fTablesType.Length()>0) {
+      if ((fTablesType.Length()>0) && IsMySQL()) {
          sqlcmd +=" TYPE=";
          sqlcmd += fTablesType;
       }
@@ -2027,28 +2214,7 @@ Int_t TSQLFile::VerifyObjectTable()
 }
 
 //______________________________________________________________________________
-TString TSQLFile::SetObjectDataCmd(Int_t keyid, Int_t objid, TClass* cl)
-{
-   // produces SQL query to set object data
-   // command will be submited later
-
-   TString cmd;
-   const char* quote = SQLIdentifierQuote();
-   const char* valuequote = SQLValueQuote();
-   cmd.Form("INSERT INTO %s%s%s (%s%s%s, %s%s%s, %s, %s) VALUES (%d, %d, %s%s%s, %d)",
-            quote, sqlio::ObjectsTable, quote,
-            quote, SQLKeyIdColumn(), quote,
-            quote, SQLObjectIdColumn(), quote,
-            sqlio::OT_Class,
-            sqlio::OT_Version,
-            keyid, objid,
-            valuequote, cl->GetName(), valuequote,
-            cl->GetClassVersion());
-   return cmd;
-}
-
-//______________________________________________________________________________
-Bool_t TSQLFile::GetObjectData(Int_t objid, TString& clname, Version_t &version)
+Bool_t TSQLFile::SQLObjectInfo(Long64_t objid, TString& clname, Version_t &version)
 {
    // Read from objects table data for specified objectid
 
@@ -2056,8 +2222,9 @@ Bool_t TSQLFile::GetObjectData(Int_t objid, TString& clname, Version_t &version)
 
    TString sqlcmd;
    const char* quote = SQLIdentifierQuote();
-   sqlcmd.Form("SELECT %s, %s FROM %s%s%s WHERE %s%s%s=%d",
-               sqlio::OT_Class, sqlio::OT_Version,
+   sqlcmd.Form("SELECT %s%s%s, %s%s%s FROM %s%s%s WHERE %s%s%s=%lld",
+               quote, sqlio::OT_Class, quote,
+               quote, sqlio::OT_Version, quote,
                quote, sqlio::ObjectsTable, quote,
                quote, SQLObjectIdColumn(), quote, objid);
    TSQLResult* res = SQLQuery(sqlcmd.Data(), 1);
@@ -2074,69 +2241,154 @@ Bool_t TSQLFile::GetObjectData(Int_t objid, TString& clname, Version_t &version)
 }
 
 //______________________________________________________________________________
-TSQLObjectData* TSQLFile::GetObjectClassData(Int_t objid, TSQLClassInfo* sqlinfo)
+TObjArray* TSQLFile::SQLObjectsInfo(Long64_t keyid)
 {
-   // Get data for specified object from particular class table
-   // Returns TSQLObjectData object, which contains one row from
-   // normal class table and data from _streamer_ table.
-   // TSQLObjectData object used later in TBufferSQL2 to unstream object
+// Produce array of TSQLObjectInfo objects for all objects, belong to that key
+// Array should be deleted by calling function afterwards
+   if (fSQL==0) return 0;
 
-   if ((fSQL==0) || (objid<0) || (sqlinfo==0)) return 0;
+   TString sqlcmd;
+   const char* quote = SQLIdentifierQuote();
+   sqlcmd.Form("SELECT %s%s%s, %s%s%s, %s%s%s FROM %s%s%s WHERE %s%s%s=%lld ORDER BY %s%s%s",
+               quote, SQLObjectIdColumn(), quote,
+               quote, sqlio::OT_Class, quote,
+               quote, sqlio::OT_Version, quote,
+               quote, sqlio::ObjectsTable, quote,
+               quote, SQLKeyIdColumn(), quote, keyid,
+               quote, SQLObjectIdColumn(), quote);
+   TSQLResult* res = SQLQuery(sqlcmd.Data(), 1);
+   if (res==0) return 0;
+   
+   TObjArray* arr = 0;
+   TSQLRow* row = 0;
+   while ((row = res->Next()) != 0) {
+      Long64_t objid = atoi(row->GetField(0)); 
+      const char* clname = row->GetField(1);
+      Int_t version = atoi(row->GetField(2)); 
+      
+      TSQLObjectInfo* info = new TSQLObjectInfo(objid, clname, version);
+      if (arr==0) arr = new TObjArray();
+      arr->Add(info);
+      
+      delete row;
+   }
+   delete res;
+   return arr;
+}
 
-   if (gDebug>1)
-      Info("GetObjectClassData","Request for %s", sqlinfo->GetName());
+//______________________________________________________________________________
+TSQLResult* TSQLFile::GetNormalClassData(Long64_t objid, TSQLClassInfo* sqlinfo)
+{
+// Method return request result for specified objid from normal classtable    
 
+   if (!sqlinfo->IsClassTableExist()) return 0;
+   TString sqlcmd;
    const char* quote = SQLIdentifierQuote();
+   sqlcmd.Form("SELECT * FROM %s%s%s WHERE %s%s%s=%lld",
+               quote, sqlinfo->GetClassTableName(), quote,
+               quote, SQLObjectIdColumn(), quote, objid);
+   return SQLQuery(sqlcmd.Data(), 2);
+}
 
-   TSQLResult *classdata = 0, *blobdata = 0;
+//______________________________________________________________________________
+TSQLResult* TSQLFile::GetNormalClassDataAll(Long64_t minobjid, Long64_t maxobjid, TSQLClassInfo* sqlinfo)
+{
+   if (!sqlinfo->IsClassTableExist()) return 0;
+   TString sqlcmd;
+   const char* quote = SQLIdentifierQuote();
+   sqlcmd.Form("SELECT * FROM %s%s%s WHERE %s%s%s BETWEEN %lld AND %lld ORDER BY %s%s%s",
+               quote, sqlinfo->GetClassTableName(), quote,
+               quote, SQLObjectIdColumn(), quote, minobjid, maxobjid,
+               quote, SQLObjectIdColumn(), quote);
+   return SQLQuery(sqlcmd.Data(), 2);
+}
 
-   if (sqlinfo->IsClassTableExist()) {
-      TString sqlcmd;
-      sqlcmd.Form("SELECT * FROM %s%s%s WHERE %s%s%s=%d",
-                  quote, sqlinfo->GetClassTableName(), quote,
-                  quote, SQLObjectIdColumn(), quote, objid);
-      classdata = SQLQuery(sqlcmd.Data(), 2);
-   }
+//______________________________________________________________________________
+TSQLResult* TSQLFile::GetBlobClassData(Long64_t objid, TSQLClassInfo* sqlinfo)
+{
+//  Method return request results for specified objid from _streamer_ classtable 
 
    if (sqlinfo->IsRawTableExist()) {
       TString sqlcmd;
-      sqlcmd.Form("SELECT %s, %s FROM %s%s%s WHERE %s%s%s=%d ORDER BY %s%s%s",
+       const char* quote = SQLIdentifierQuote();
+       sqlcmd.Form("SELECT %s, %s FROM %s%s%s WHERE %s%s%s=%lld ORDER BY %s%s%s",
                   sqlio::BT_Field, sqlio::BT_Value,
                   quote, sqlinfo->GetRawTableName(), quote,
                   quote, SQLObjectIdColumn(), quote, objid,
                   quote, SQLRawIdColumn(), quote);
-      blobdata = SQLQuery(sqlcmd.Data(), 2);
+      return SQLQuery(sqlcmd.Data(), 2);
    }
-
-   return new TSQLObjectData(sqlinfo, objid, classdata, blobdata);
+   
+   return 0;
 }
 
 //______________________________________________________________________________
-void TSQLFile::DeleteObjectFromTables(Int_t objid)
+TSQLObjectData* TSQLFile::GetObjectClassData(Long64_t objid, TSQLClassInfo* sqlinfo)
 {
-   // delete object with specified id from all tables
+   // Get data for specified object from particular class table
+   // Returns TSQLObjectData object, which contains one row from
+   // normal class table and data from _streamer_ table.
+   // TSQLObjectData object used later in TBufferSQL2 to unstream object
 
-   TObjArray* tables = SQLTablesList();
-   if (tables==0) return;
+   if ((fSQL==0) || (objid<0) || (sqlinfo==0)) return 0;
 
-   const char* quote = SQLIdentifierQuote();
+   if (gDebug>1)
+      Info("GetObjectClassData","Request for %s id = %lld", sqlinfo->GetName(), objid);
 
-   TIter iter(tables);
-   TObject* obj = 0;
-   while ((obj=iter())!=0) {
-      TString tablename = obj->GetName();
+   TSQLResult *classdata = GetNormalClassData(objid, sqlinfo);
+   
+   TSQLResult *blobdata = GetBlobClassData(objid, sqlinfo);
+
+   if (gDebug>3)
+      Info("GetObjectClassData","normal = %x blobdata = %x", classdata, blobdata);
 
-      if ((tablename.CompareTo(sqlio::KeysTable,TString::kIgnoreCase)==0) ||
-          (tablename.CompareTo(sqlio::ObjectsTable,TString::kIgnoreCase)==0)) continue;
+   return new TSQLObjectData(sqlinfo, objid, classdata, 0, blobdata);
+}
 
-      TString query;
-      query.Form("DELETE FROM %s WHERE %s%s%s=%d", tablename.Data(),
-                 quote, SQLObjectIdColumn(), quote, objid);
-      SQLQuery(query.Data());
+//______________________________________________________________________________
+Long64_t TSQLFile::StoreObjectInTables(Long64_t keyid, const void* obj, const TClass* cl)
+{
+   // Store object in database. Return stored object id or -1 if error
+   
+   if (fSQL==0) return -1; 
 
-   }
+   Long64_t objid = VerifyObjectTable();
+   if (objid<=0) objid = 1; else objid++;
 
-   delete tables;
+   TBufferSQL2 buffer(TBuffer::kWrite, this);
+
+   TSQLStructure* s = buffer.SqlWriteAny(obj, cl, objid);
+   
+   if ((buffer.GetErrorFlag()>0) && (s!=0)) {
+      Error("StoreObjectInTables","Cannot convert object data to TSQLStructure");
+      objid = -1;
+   } else {
+      TObjArray cmds;    
+      // here tables may be already created, therefore 
+      // it should be protected by transactions operations
+      if (!s->ConvertToTables(this, keyid, &cmds)) {
+         Error("StoreObjectInTables","Cannot convert to SQL statements");    
+         objid = -1; 
+      } else {
+         Bool_t needcommit = kFALSE; 
+          
+         if (GetUseTransactions()==kTransactionsAuto) {
+            SQLStartTransaction();
+            needcommit = kTRUE;
+         }
+          
+         if (!SQLApplyCommands(&cmds)) {
+           Error("StoreObject","Cannot correctly store object data in database");
+           objid = -1;
+           if (needcommit) SQLRollback();
+         } else {
+           if (needcommit) SQLCommit();
+         }
+      }
+      cmds.Delete();
+   }
+   
+   return objid;
 }
 
 //______________________________________________________________________________
diff --git a/sql/src/TSQLObjectData.cxx b/sql/src/TSQLObjectData.cxx
index 8ad05672590..38114f62ace 100644
--- a/sql/src/TSQLObjectData.cxx
+++ b/sql/src/TSQLObjectData.cxx
@@ -1,4 +1,4 @@
-// @(#)root/sql:$Name:  $:$Id: TSQLObjectData.cxx,v 1.2 2005/11/22 20:42:36 pcanal Exp $
+// @(#)root/sql:$Name:  $:$Id: TSQLObjectData.cxx,v 1.3 2005/12/07 14:59:57 rdm Exp $
 // Author: Sergey Linev  20/11/2005
 
 /*************************************************************************
@@ -27,14 +27,43 @@
 #include "TSQLRow.h"
 #include "TSQLResult.h"
 #include "TSQLClassInfo.h"
+#include "TSQLStructure.h"
+
+ClassImp(TSQLObjectInfo)
+
+//________________________________________________________________________
+TSQLObjectInfo::TSQLObjectInfo() :
+   TObject(),
+   fObjId(0),
+   fClassName(),
+   fVersion(0)
+{
+}
+
+//________________________________________________________________________
+TSQLObjectInfo::TSQLObjectInfo(Long64_t objid, const char* classname, Version_t version) :
+   TObject(),
+   fObjId(objid),
+   fClassName(classname),
+   fVersion(version)
+{
+}
+
+//________________________________________________________________________
+TSQLObjectInfo::~TSQLObjectInfo()
+{
+}
+
+
 
 ClassImp(TSQLObjectData)
 
 //________________________________________________________________________
-   TSQLObjectData::TSQLObjectData() :
+TSQLObjectData::TSQLObjectData() :
       TObject(),
       fInfo(0),
       fObjId(0),
+      fOwner(kFALSE),
       fClassData(0),
       fBlobData(0),
       fLocatedColumn(-1),
@@ -52,16 +81,18 @@ ClassImp(TSQLObjectData)
 
 //______________________________________________________________________________
 TSQLObjectData::TSQLObjectData(TSQLClassInfo* sqlinfo,
-                               Int_t          objid,
+                               Long64_t       objid,
                                TSQLResult*    classdata,
+                               TSQLRow*       classrow,
                                TSQLResult*    blobdata) :
    TObject(),
    fInfo(sqlinfo),
    fObjId(objid),
+   fOwner(kFALSE),
    fClassData(classdata),
    fBlobData(blobdata),
    fLocatedColumn(-1),
-   fClassRow(0),
+   fClassRow(classrow),
    fBlobRow(0),
    fLocatedField(0),
    fLocatedValue(0),
@@ -72,11 +103,13 @@ TSQLObjectData::TSQLObjectData(TSQLClassInfo* sqlinfo,
 {
    // normal contrsuctor,
 
-   if (fClassData!=0)
+   // take ownership if no special row from data pool is provided
+   if ((fClassData!=0) && (fClassRow==0)) {
+      fOwner = kTRUE;
       fClassRow = fClassData->Next();
+   }
    if (fBlobData!=0)
       fBlobRow = fBlobData->Next();
-
 }
 
 //______________________________________________________________________________
@@ -84,9 +117,9 @@ TSQLObjectData::~TSQLObjectData()
 {
    // destructor of TSQLObjectData object
 
+   if ((fClassData!=0) && fOwner) delete fClassData;
    if (fClassRow!=0) delete fClassRow;
    if (fBlobRow!=0) delete fBlobRow;
-   if (fClassData!=0) delete fClassData;
    if (fBlobData!=0) delete fBlobData;
    if (fUnpack!=0) { fUnpack->Delete(); delete fUnpack; }
 }
@@ -281,3 +314,73 @@ Bool_t TSQLObjectData::PrepareForRawData()
    return kTRUE;
 }
 
+//===================================================================================
+
+ClassImp(TSQLObjectDataPool);
+
+//______________________________________________________________________________
+TSQLObjectDataPool::TSQLObjectDataPool() :
+   TObject(),
+   fInfo(0),
+   fClassData(0),
+   fIsMoreRows(kTRUE),
+   fRowsPool(0)
+{
+}
+
+//______________________________________________________________________________
+TSQLObjectDataPool::TSQLObjectDataPool(TSQLClassInfo* info, TSQLResult* data) :
+   TObject(),
+   fInfo(info),
+   fClassData(data),
+   fIsMoreRows(kTRUE),
+   fRowsPool(0)
+{
+}
+
+//______________________________________________________________________________
+TSQLObjectDataPool::~TSQLObjectDataPool()
+{
+   if (fClassData!=0) delete fClassData;
+   if (fRowsPool!=0) {
+      fRowsPool->Delete();
+      delete fRowsPool;
+   }
+}
+
+//______________________________________________________________________________
+TSQLRow* TSQLObjectDataPool::GetObjectRow(Long64_t objid)
+{
+   if (fClassData==0) return 0;
+   
+   Long64_t rowid;
+         
+   if (fRowsPool!=0) {
+      TObjLink* link = fRowsPool->FirstLink();
+      while (link!=0) {
+         TSQLRow* row = (TSQLRow*) link->GetObject();
+         rowid = sqlio::atol64(row->GetField(0));
+         if (rowid==objid) {
+            fRowsPool->Remove(link);   
+            return row;
+         }
+         
+         link = link->Next();   
+      }
+   }
+   
+   while (fIsMoreRows) {
+      TSQLRow* row = fClassData->Next();
+      if (row==0) 
+         fIsMoreRows = kFALSE; 
+      else {
+         rowid = sqlio::atol64(row->GetField(0));
+         if (rowid==objid) return row;
+         if (fRowsPool==0) fRowsPool = new TList();
+         fRowsPool->Add(row);
+      }
+   }
+   
+   return 0;
+}
+  
diff --git a/sql/src/TSQLStructure.cxx b/sql/src/TSQLStructure.cxx
index 16a0d1364fd..87466a35bc9 100644
--- a/sql/src/TSQLStructure.cxx
+++ b/sql/src/TSQLStructure.cxx
@@ -1,4 +1,4 @@
-// @(#)root/sql:$Name:  $:$Id: TSQLStructure.cxx,v 1.6 2005/12/01 16:30:43 pcanal Exp $
+// @(#)root/sql:$Name:  $:$Id: TSQLStructure.cxx,v 1.7 2005/12/07 14:59:57 rdm Exp $
 // Author: Sergey Linev  20/11/2005
 
 /*************************************************************************
@@ -24,6 +24,7 @@
 #include "TSQLStructure.h"
 
 #include "Riostream.h"
+#include "TMap.h"
 #include "TClass.h"
 #include "TStreamerInfo.h"
 #include "TStreamerElement.h"
@@ -33,12 +34,14 @@
 #include "TSQLFile.h"
 #include "TSQLClassInfo.h"
 #include "TSQLObjectData.h"
+#include "TBufferSQL2.h"
 
 namespace sqlio {
    const Int_t Ids_NullPtr       = 0; // used to identify NULL pointer in tables
    const Int_t Ids_RootDir       = 0; // dir:id, used for keys stored in root directory.
-   const Int_t Ids_StreamerInfos = 0; // keyid used to store StreamerInfos in ROOT directory
-   const Int_t Ids_FirstKey      = 1; // first key id, which is used in KeysTable (beside streamer info or something else)
+   const Int_t Ids_TSQLFile      = 0; // keyid for TSQLFile entry in keys list
+   const Int_t Ids_StreamerInfos = 1; // keyid used to store StreamerInfos in ROOT directory
+   const Int_t Ids_FirstKey      =10; // first key id, which is used in KeysTable (beside streamer info or something else)
    const Int_t Ids_FirstObject   = 1; // first object id, allowed in object tables
 
    const char* ObjectRef     = "ObjectRef";
@@ -86,9 +89,14 @@ namespace sqlio {
 
    // colummns in Keys table
    const char* KT_Name      = "Name";
+   const char* KT_Title     = "Title";
    const char* KT_Datetime  = "Datime";
    const char* KT_Cycle     = "Cycle";
    const char* KT_Class     = "Class";
+   
+   const char* DT_Create    = "CreateDatime";
+   const char* DT_Modified  = "ModifiedDatime";
+   const char* DT_UUID      = "UUID";
 
    // colummns in Objects table
    const char* OT_Class     = "Class";
@@ -118,6 +126,28 @@ namespace sqlio {
 
 //________________________________________________________________________
 
+#ifdef R__VISUAL_CPLUSPLUS
+#define FLong64    "%I64d"
+#define FULong64   "%I64u"
+#else
+#ifdef R__B64
+#define FLong64    "%ld"
+#define FULong64   "%lu"
+#else
+#define FLong64    "%lld"
+#define FULong64   "%llu"
+#endif
+#endif
+
+Long64_t sqlio::atol64(const char* value)
+{
+   if ((value==0) || (*value==0)) return 0;
+   Long64_t res = 0;
+   sscanf(value, FLong64, &res);
+   return res;
+}
+
+
 ClassImp(TSQLColumnData)
 
 //______________________________________________________________________________
@@ -147,7 +177,7 @@ TSQLColumnData::TSQLColumnData(const char* name,
 }
 
 //________________________________________________________________________
-TSQLColumnData::TSQLColumnData(const char* name, Int_t value) :
+TSQLColumnData::TSQLColumnData(const char* name, Long64_t value) :
    TObject(),
    fName(name),
    fType("INT"),
@@ -156,7 +186,7 @@ TSQLColumnData::TSQLColumnData(const char* name, Int_t value) :
 {
    // constructs TSQLColumnData object for integer column
 
-   fValue.Form("%d",value);
+   fValue.Form("%lld",value);
 }
 
 //________________________________________________________________________
@@ -191,6 +221,10 @@ TSQLStructure::~TSQLStructure()
    if (GetType()==kSqlObjectData) {
       TSQLObjectData* objdata = (TSQLObjectData*) fPointer;
       delete objdata;
+   } else
+   if (GetType()==kSqlCustomElement) {
+      TStreamerElement* elem = (TStreamerElement*) fPointer;
+      delete elem;
    }
 }
 
@@ -211,22 +245,22 @@ TSQLStructure* TSQLStructure::GetChild(Int_t n) const
 }
 
 //________________________________________________________________________
-void TSQLStructure::SetObjectRef(Int_t refid, const TClass* cl)
+void TSQLStructure::SetObjectRef(Long64_t refid, const TClass* cl)
 {
    // set structure type as kSqlObject
 
    fType = kSqlObject;
-   fValue.Form("%d",refid);
+   fValue.Form("%lld",refid);
    fPointer = cl;
 }
 
 //________________________________________________________________________
-void TSQLStructure::SetObjectPointer(Int_t ptrid)
+void TSQLStructure::SetObjectPointer(Long64_t ptrid)
 {
    // set structure type as kSqlPointer
 
    fType = kSqlPointer;
-   fValue.Form("%d",ptrid);
+   fValue.Form("%lld",ptrid);
 }
 
 //________________________________________________________________________
@@ -268,6 +302,21 @@ void TSQLStructure::SetStreamerElement(const TStreamerElement* elem, Int_t numbe
    fArrayIndex = number;
 }
 
+//________________________________________________________________________
+void TSQLStructure::SetCustomClass(const TClass* cl, Version_t version)
+{
+   fType = kSqlCustomClass;
+   fPointer = (void*) cl;
+   fArrayIndex = version;
+}
+
+//________________________________________________________________________
+void TSQLStructure::SetCustomElement(TStreamerElement* elem)
+{
+   fType = kSqlCustomElement;
+   fPointer = elem;
+}
+
 //________________________________________________________________________
 void TSQLStructure::SetValue(const char* value, const char* tname)
 {
@@ -344,7 +393,7 @@ TStreamerElement* TSQLStructure::GetElement() const
 {
    // return TStremerElement* if type is kSqlElement
 
-   return (fType==kSqlElement) ? (TStreamerElement*) fPointer : 0;
+   return (fType==kSqlElement) || (fType==kSqlCustomElement) ? (TStreamerElement*) fPointer : 0;
 }
 
 //________________________________________________________________________
@@ -363,6 +412,35 @@ const char* TSQLStructure::GetValueType() const
    return (fType==kSqlValue) ? (const char*) fPointer : 0;
 }
 
+//________________________________________________________________________
+TClass* TSQLStructure::GetCustomClass() const
+{
+   return (fType==kSqlCustomClass) ? (TClass*) fPointer : 0;
+}
+
+//________________________________________________________________________
+Version_t TSQLStructure::GetCustomClassVersion() const
+{
+   return (fType==kSqlCustomClass) ? fArrayIndex : 0;
+}
+
+//________________________________________________________________________
+Bool_t TSQLStructure::GetClassInfo(TClass* &cl, Version_t &version)
+{
+   if (GetType()==kSqlStreamerInfo) {
+      TStreamerInfo* info = GetStreamerInfo();
+      if (info==0) return kFALSE;
+      cl = info->GetClass();
+      version = info->GetClassVersion();
+   } else 
+   if (GetType()==kSqlCustomClass) {
+      cl = GetCustomClass();
+      version = GetCustomClassVersion();
+   } else 
+      return kFALSE;
+   return kTRUE;
+}   
+
 //________________________________________________________________________
 const char* TSQLStructure::GetValue() const
 {
@@ -405,7 +483,7 @@ void TSQLStructure::AddValue(const char* value, const char* tname)
 }
 
 //________________________________________________________________________
-Int_t TSQLStructure::DefineObjectId()
+Long64_t TSQLStructure::DefineObjectId(Bool_t recursive)
 {
    // defines current object id, to which this structure belong
    // make life complicated, because some objects do not get id
@@ -413,56 +491,22 @@ Int_t TSQLStructure::DefineObjectId()
 
    TSQLStructure* curr = this;
    while (curr!=0) {
-      // workaround to store object id in element structure
-      if ((curr->GetType()==kSqlElement) ||
+      if ((curr->GetType()==kSqlObject) || 
+         // workaround to store object id in element structure
+          (curr->GetType()==kSqlElement) ||
+          (curr->GetType()==kSqlCustomElement) ||
+          (curr->GetType()==kSqlCustomClass) ||
           (curr->GetType()==kSqlStreamerInfo)) {
          const char* value = curr->GetValue();
-         if ((value!=0) && (strlen(value)>0)) return atoi(value);
+         if ((value!=0) && (strlen(value)>0)) 
+            return sqlio::atol64(value);
       }
 
-      if (curr->GetType()==kSqlObject)
-         return atoi(curr->GetValue());
-      curr = curr->GetParent();
+      curr = recursive ? curr->GetParent() : 0;
    }
    return -1;
 }
 
-//________________________________________________________________________
-Bool_t TSQLStructure::IsClonesArray()
-{
-   // defines if this structure below node, which correspondes to
-   // clones array. Used to force convertion of all data into raw format
-
-   // disable any special handling of TClonesArray
-   
-   return kFALSE;
-
-   TSQLStructure* curr = this;
-   while (curr!=0) {
-      if (curr->GetType()==kSqlObject)
-         return curr->GetObjectClass()==TClonesArray::Class();
-
-      // workaround for nested TClonesArray
-      if ((curr->GetType()==kSqlElement) ||
-          (curr->GetType()==kSqlStreamerInfo)) {
-         const char* value = curr->GetValue();
-         // check that element has object id and one can analyse it class
-         if ((value!=0) && (strlen(value)>0)) {
-            TStreamerInfo* info = GetStreamerInfo();
-            if (info!=0)
-               return info->GetClass()==TClonesArray::Class();
-            TStreamerElement* elem = GetElement();
-            if (elem!=0)
-               return elem->GetClassPointer()==TClonesArray::Class();
-            return kFALSE;
-         }
-      }
-
-      curr = curr->GetParent();
-   }
-   return kFALSE;
-}
-
 //________________________________________________________________________
 void TSQLStructure::SetObjectData(TSQLObjectData* objdata)
 {
@@ -523,6 +567,7 @@ void TSQLStructure::PrintLevel(Int_t level) const
       cout << "Class: " << info->GetName();
       break;
    }
+   case kSqlCustomElement:
    case kSqlElement: {
       const TStreamerElement* elem = (const TStreamerElement*) fPointer;
       cout << "Member: " << elem->GetName();
@@ -539,6 +584,11 @@ void TSQLStructure::PrintLevel(Int_t level) const
       if (fValue.Length()>0) cout << "  sz = " << fValue;
       break;
    }
+   case kSqlCustomClass: {
+      TClass* cl = (TClass*) fPointer;
+      cout << "CustomClass: " << cl->GetName() << "  ver = " << fValue;
+      break;
+   }
    default:
       cout << "Unknown type";
    }
@@ -618,6 +668,37 @@ const char* TSQLStructure::GetSimpleTypeName(Int_t typ)
    return 0;
 }
 
+// ======================================================================
+
+class TSqlCmdsBuffer : public TObject {
+  
+public:
+   TSqlCmdsBuffer(TSQLClassInfo* info = 0) : 
+      TObject(),
+      fInfo(info)
+   {
+   }
+   
+   virtual ~TSqlCmdsBuffer() 
+   {
+      fNormCmds.Delete(); 
+      fBlobCmds.Delete(); 
+   }
+   
+   void AddValues(Bool_t isnorm, const char* values)
+   {
+      TObjString* str = new TObjString(values);
+      if (isnorm) fNormCmds.Add(str);
+             else fBlobCmds.Add(str);
+   }
+       
+   TSQLClassInfo* fInfo;
+   TObjArray fNormCmds;
+   TObjArray fBlobCmds;
+};
+
+
+
 //________________________________________________________________________
 class TSqlRegistry : public TObject {
 
@@ -629,28 +710,38 @@ public:
       fLastObjId(-1),
       fCmds(0),
       fFirstObjId(0),
-      fRegCmds(),
-      fCurrentObjId(),
+      fCurrentObjId(0),
       fCurrentObjClass(0),
-      fLastLongStrId(0)
+      fLastLongStrId(0),
+      fPool(),
+      fLongStrValues(),
+      fRegValues()
    {
    }
 
    TSQLFile*  f;
-   Int_t      fKeyId;
-   Int_t      fLastObjId;
+   Long64_t   fKeyId;
+   Long64_t   fLastObjId;
    TObjArray* fCmds;
-   Int_t      fFirstObjId;
-   TObjArray  fRegCmds;
+   Long64_t   fFirstObjId;
 
-   TString    fCurrentObjId;
+   Long64_t   fCurrentObjId;
    TClass*    fCurrentObjClass;
 
    Int_t      fLastLongStrId;
+   
+   TMap       fPool;
+   TObjArray  fLongStrValues;
+   TObjArray  fRegValues;
 
-   virtual ~TSqlRegistry() {}
+   virtual ~TSqlRegistry() 
+   { 
+      fPool.DeleteValues(); 
+      fLongStrValues.Delete();
+      fRegValues.Delete();
+   }
 
-   Int_t GetNextObjId() { return ++fLastObjId; }
+   Long64_t GetNextObjId() { return ++fLastObjId; }
 
    void AddSqlCmd(const char* query)
    {
@@ -658,25 +749,85 @@ public:
       if (fCmds==0) fCmds = new TObjArray;
       fCmds->Add(new TObjString(query));
    }
-
-   void AddBrackets(TString& s, const char* quote)
+   
+   TSqlCmdsBuffer* GetCmdsBuffer(TSQLClassInfo* sqlinfo) 
    {
-      // add brackets to the string value
-      if (strcmp(quote,"\"")==0) s.ReplaceAll("\"","\\\"");
-      else  s.ReplaceAll("'","''");
-      s.Prepend(quote);
-      s.Append(quote);
+      if (sqlinfo==0) return 0;
+      TSqlCmdsBuffer* buf = (TSqlCmdsBuffer*) fPool.GetValue(sqlinfo);
+      if (buf==0) {
+         buf = new TSqlCmdsBuffer(sqlinfo);
+         fPool.Add(sqlinfo, buf);
+      }
+      return buf;
    }
+   
+   void ConvertSqlValues(TObjArray& values, const char* tablename)
+   {
+   // this function transforms array of values for one table
+   // to SQL command. For MySQL one INSERT querie can
+   // contain data for more than one row
+
+      if ((values.GetLast()<0) || (tablename==0)) return;
+
+      Bool_t canbelong = f->IsMySQL();
+
+      Int_t maxsize = 50000;
+      TString sqlcmd(maxsize), value, onecmd, cmdmask;
 
-   void AddRegCmd(const char* cmd, Int_t objid)
+      const char* quote = f->SQLIdentifierQuote();
+
+      TIter iter(&values);
+      TObject* cmd = 0;
+      while ((cmd = iter())!=0) {
+
+         if (sqlcmd.Length()==0)
+            sqlcmd.Form("INSERT INTO %s%s%s VALUES (%s)",
+                        quote, tablename, quote, cmd->GetName());
+         else {
+            sqlcmd+=", (";
+            sqlcmd += cmd->GetName();
+            sqlcmd+=")";
+         }
+
+         if (!canbelong || (sqlcmd.Length()>maxsize*0.9)) {
+            AddSqlCmd(sqlcmd.Data());
+            sqlcmd = "";
+         }
+      }
+
+      if (sqlcmd.Length()>0) AddSqlCmd(sqlcmd.Data());
+   }
+   
+   void ConvertPoolValues()
    {
-      // add special command to register object in objects table
+      TSQLClassInfo* sqlinfo = 0;
+      TIter iter(&fPool);
+      while ((sqlinfo = (TSQLClassInfo*) iter())!=0) {
+         TSqlCmdsBuffer* buf = (TSqlCmdsBuffer*) fPool.GetValue(sqlinfo);
+         if (buf==0) continue;
+         ConvertSqlValues(buf->fNormCmds, sqlinfo->GetClassTableName());
+         ConvertSqlValues(buf->fBlobCmds, sqlinfo->GetRawTableName());
+      }
+       
+      ConvertSqlValues(fLongStrValues, sqlio::StringsTable);
+      ConvertSqlValues(fRegValues, sqlio::ObjectsTable);
+   }
 
-      Int_t indx = objid-fFirstObjId;
-      if (indx<0)
-         Error("AddRegCmd","Soemthing wrong");
-      else
-         fRegCmds.AddAtAndExpand(new TObjString(cmd), indx);
+
+   void AddRegCmd(Long64_t objid, TClass* cl)
+   {
+      Long64_t indx = objid-fFirstObjId;
+      if (indx<0) {
+         Error("AddRegCmd","Something wrong with objid = %lld", objid);
+         return;
+      }
+      const char* valuequote = f->SQLValueQuote();
+      TString cmd;
+      cmd.Form("%lld, %lld, %s%s%s, %d",
+                fKeyId, objid,
+                valuequote, cl->GetName(), valuequote,
+                cl->GetClassVersion());
+      fRegValues.AddAtAndExpand(new TObjString(cmd), indx);
    }
 
    Int_t AddLongString(const char* strvalue)
@@ -688,136 +839,76 @@ public:
       Int_t strid = ++fLastLongStrId;
       TString value = strvalue;
       const char* valuequote = f->SQLValueQuote();
-      const char* quote = f->SQLIdentifierQuote();
-      AddBrackets(value, valuequote);
+      TSQLStructure::AddStrBrackets(value, valuequote);
 
       TString cmd;
-      cmd.Form("INSERT INTO %s%s%s VALUES (%s, %d, %s)",
-               quote, sqlio::StringsTable, quote,
-               fCurrentObjId.Data(), strid, value.Data());
-      AddSqlCmd(cmd.Data());
-      return strid;
-   }
+      cmd.Form("%lld, %d, %s", fCurrentObjId, strid, value.Data());
 
-   void ConvertRawOracle(TObjArray* blobs, TSQLClassInfo* sqlinfo, Int_t& rawid)
-   {
-      // special code for Oracle, which does not allow multiple INSERT syntax
-      // therefore eachline in raw table should be inseretd with
-      // separate INSERT command
+      fLongStrValues.Add(new TObjString(cmd));
 
-      TString sqlcmd, value;
-      TIter iter(blobs);
-      TNamed* cmd = 0;
-      const char* valuequote = f->SQLValueQuote();
-      const char* quote = f->SQLIdentifierQuote();
-      while ((cmd = (TNamed*)iter())!=0) {
-         value = cmd->GetTitle();
-         AddBrackets(value, valuequote);
-
-         sqlcmd.Form("INSERT INTO %s%s%s VALUES (%s, %d, %s%s%s, %s)",
-                     quote, sqlinfo->GetRawTableName(), quote,
-                     fCurrentObjId.Data(),
-                     rawid++,
-                     valuequote, cmd->GetName(), valuequote,
-                     value.Data());
-         AddSqlCmd(sqlcmd.Data());
-      }
+      return strid;
    }
-
+   
    void ConvertBlobs(TObjArray* blobs, TSQLClassInfo* sqlinfo, Int_t& rawid)
    {
-      // this function transforms blob pairs (field, value) to SQL command
-      // one command includes more than one row to improve speed
-
-      if (f->IsOracle()) {
-         ConvertRawOracle(blobs, sqlinfo, rawid);
-         return;
-      }
-
-      Int_t maxsize = 50000;
-      TString sqlcmd(maxsize), value, onecmd, cmdmask;
+      TSqlCmdsBuffer* buf = GetCmdsBuffer(sqlinfo);
+      if (buf==0) return; 
+       
+      TString value, onecmd, cmdmask;
 
       const char* valuequote = f->SQLValueQuote();
-      const char* quote = f->SQLIdentifierQuote();
 
-      cmdmask.Form("(%s, %s, %s%s%s, %s)", fCurrentObjId.Data(), "%d", valuequote, "%s", valuequote, "%s");
+      cmdmask.Form("%lld, %s, %s%s%s, %s", fCurrentObjId, "%d", valuequote, "%s", valuequote, "%s");
 
       TIter iter(blobs);
       TNamed* cmd = 0;
       while ((cmd = (TNamed*)iter())!=0) {
          value = cmd->GetTitle();
-         AddBrackets(value, valuequote);
+         TSQLStructure::AddStrBrackets(value, valuequote);
          onecmd.Form(cmdmask.Data(), rawid++, cmd->GetName(), value.Data());
-
-         if (sqlcmd.Length()==0)
-            sqlcmd.Form("INSERT INTO %s%s%s VALUES %s",
-                        quote, sqlinfo->GetRawTableName(), quote,
-                        onecmd.Data());
-         else {
-            sqlcmd+=", ";
-            sqlcmd += onecmd;
-         }
-
-         if (sqlcmd.Length()>maxsize*0.9) {
-            AddSqlCmd(sqlcmd.Data());
-            sqlcmd = "";
-         }
+         buf->AddValues(kFALSE, onecmd.Data());
       }
-
-      if (sqlcmd.Length()>0) AddSqlCmd(sqlcmd.Data());
    }
-
-   void InsertToNormalTable(TObjArray* columns, const char* tablename)
+   
+   void InsertToNormalTable(TObjArray* columns, TSQLClassInfo* sqlinfo)
    {
       // produce SQL query to insert object data into normal table
 
-      TString names, values;
-
       TIter iter(columns);
       TSQLColumnData* col;
-      const char* quote = f->SQLIdentifierQuote();
       const char* valuequote = f->SQLValueQuote();
 
-      Bool_t forcequote = f->IsOracle();
+      TString values;
+      
+      Bool_t first = kTRUE;
 
       while ((col=(TSQLColumnData*)iter())!=0) {
-         if (names.Length()>0) names+=", ";
-         const char* colname = col->GetName();
-         if (forcequote || (strpbrk(colname,"[:.]<>")!=0)) {
-            names+=quote;
-            names+=colname;
-            names+=quote;
-         } else names+=colname;
-
-         if (values.Length()>0) values+=", ";
+         if (first) first = kFALSE; 
+               else values+=", "; 
          if (col->IsNumeric())
             values+=col->GetValue();
          else {
             TString value = col->GetValue();
-            AddBrackets(value, valuequote);
+            TSQLStructure::AddStrBrackets(value, valuequote);
             values += value;
          }
       }
+     
+      TSqlCmdsBuffer* buf = GetCmdsBuffer(sqlinfo);
+      if (buf!=0) buf->AddValues(kTRUE, values.Data());
 
-      TString cmd;
-      cmd.Form("INSERT INTO %s%s%s (%s) VALUES(%s)",
-               quote, tablename, quote,
-               names.Data(), values.Data());
-      AddSqlCmd(cmd.Data());
    }
 };
 
 //________________________________________________________________________
-Int_t TSQLStructure::FindMaxRef()
+Long64_t TSQLStructure::FindMaxObjectId()
 {
    // define maximum reference id, used for objects
 
-   Int_t max = 0;
-   if ((GetType()==kSqlPointer) || (GetType()==kSqlObject))
-      max = atoi(fValue.Data());
+   Long64_t max = DefineObjectId(kFALSE);
 
    for (Int_t n=0;n<NumChilds();n++) {
-      Int_t zn = GetChild(n)->FindMaxRef();
+      Long64_t zn = GetChild(n)->FindMaxObjectId();
       if (zn>max) max = zn;
    }
 
@@ -825,7 +916,7 @@ Int_t TSQLStructure::FindMaxRef()
 }
 
 //________________________________________________________________________
-Bool_t TSQLStructure::ConvertToTables(TSQLFile* file, Int_t keyid, TObjArray* cmds)
+Bool_t TSQLStructure::ConvertToTables(TSQLFile* file, Long64_t keyid, TObjArray* cmds)
 {
    // Convert structure to sql statements
    // This function is called immidiately after TBufferSQL2 produces
@@ -839,13 +930,15 @@ Bool_t TSQLStructure::ConvertToTables(TSQLFile* file, Int_t keyid, TObjArray* cm
    reg.fCmds = cmds;
    reg.f = file;
    reg.fKeyId = keyid;
-   reg.fFirstObjId = atoi(GetValue()); // this is id of main object to be stored
+   // this is id of main object to be stored
+   reg.fFirstObjId = DefineObjectId(kFALSE); 
    // this is maximum objectid which is now in use
-   reg.fLastObjId = FindMaxRef();
+   reg.fLastObjId = FindMaxObjectId();
 
-   Bool_t res = StoreObject(&reg, GetValue(), GetObjectClass());
+   Bool_t res = StoreObject(&reg, reg.fFirstObjId, GetObjectClass());
 
-   cmds->AddAll(&(reg.fRegCmds));
+   // convert values from pool to SQL commands
+   reg.ConvertPoolValues();
 
    return res;
 }
@@ -863,7 +956,7 @@ void TSQLStructure::PerformConversion(TSqlRegistry* reg, TObjArray* blobs, const
    switch (fType) {
    case kSqlObject: {
 
-      if (!StoreObject(reg, GetValue(), GetObjectClass())) break;
+      if (!StoreObject(reg, DefineObjectId(kFALSE), GetObjectClass())) break;
 
       AddCmd(blobs, sqlio::ObjectRef, GetValue(), topname, ns);
 
@@ -895,15 +988,16 @@ void TSQLStructure::PerformConversion(TSqlRegistry* reg, TObjArray* blobs, const
             child->PerformConversion(reg, blobs, info->GetName(), useblob);
          }
       } else {
-         Int_t objid = reg->GetNextObjId();
+         Long64_t objid = reg->GetNextObjId();
          TString sobjid;
-         sobjid.Form("%d",objid);
-         if (!StoreObject(reg, sobjid.Data(), info->GetClass(), kTRUE)) return;
+         sobjid.Form("%lld",objid);
+         if (!StoreObject(reg, objid, info->GetClass(), kTRUE)) return;
          AddCmd(blobs, sqlio::ObjectInst, sobjid.Data(), topname, ns);
       }
       break;
    }
 
+   case kSqlCustomElement:
    case kSqlElement: {
       const TStreamerElement* elem = (const TStreamerElement*) fPointer;
 
@@ -934,7 +1028,7 @@ void TSQLStructure::PerformConversion(TSqlRegistry* reg, TObjArray* blobs, const
          Int_t size = strlen(value);
          if (size > reg->f->SQLSmallTextTypeLimit()) {
             Int_t strid = reg->AddLongString(value);
-            buf = reg->f->CodeLongString(atoi(reg->fCurrentObjId.Data()), strid);
+            buf = reg->f->CodeLongString(reg->fCurrentObjId, strid);
             value = buf.Data();
          }
       }
@@ -957,13 +1051,13 @@ void TSQLStructure::PerformConversion(TSqlRegistry* reg, TObjArray* blobs, const
 }
 
 //________________________________________________________________________
-Bool_t TSQLStructure::StoreObject(TSqlRegistry* reg, const char* objid, TClass* cl, Bool_t registerobj)
+Bool_t TSQLStructure::StoreObject(TSqlRegistry* reg, Long64_t objid, TClass* cl, Bool_t registerobj)
 {
    // convert object data to sql statements
    // if normal (columnwise) representation is not possible,
    // complete object will be converted to raw format
 
-   if (cl==0) return kFALSE;
+   if ((cl==0) || (objid<0)) return kFALSE;
 
    if (gDebug>1) {
       cout << "Store object " << objid <<" cl = " << cl->GetName() << endl;
@@ -973,7 +1067,7 @@ Bool_t TSQLStructure::StoreObject(TSqlRegistry* reg, const char* objid, TClass*
 
    TSQLClassInfo* sqlinfo = 0;
 
-   TString oldid = reg->fCurrentObjId;
+   Long64_t oldid = reg->fCurrentObjId;
    TClass* oldcl = reg->fCurrentObjClass;
 
    reg->fCurrentObjId = objid;
@@ -983,22 +1077,19 @@ Bool_t TSQLStructure::StoreObject(TSqlRegistry* reg, const char* objid, TClass*
 
    Bool_t res = kTRUE;
 
-   Bool_t isclonesarray = kFALSE; //(cl==TClonesArray::Class());
-
    if (cl==TObject::Class())
       normstore = StoreTObject(reg);
    else
    if (cl==TString::Class())
       normstore = StoreTString(reg);
    else
-      if (!isclonesarray)
-         if (GetType()==kSqlStreamerInfo)
-            // this is a case when array of objects are stored in blob and each object
-            // has normal streamer. Then it will be stored in normal form and only one tag
-            // will be kept to remind about
-            normstore = StoreClassInNormalForm(reg);
-         else
-            normstore = StoreObjectInNormalForm(reg);
+     if (GetType()==kSqlStreamerInfo)
+        // this is a case when array of objects are stored in blob and each object
+        // has normal streamer. Then it will be stored in normal form and only one tag
+        // will be kept to remind about
+        normstore = StoreClassInNormalForm(reg);
+     else
+        normstore = StoreObjectInNormalForm(reg);
 
    if (gDebug>2)
       cout << "Store object " << objid << " of class " << cl->GetName() << "  normal = " << normstore << " sqltype = " << GetType() << endl;
@@ -1010,7 +1101,7 @@ Bool_t TSQLStructure::StoreObject(TSqlRegistry* reg, const char* objid, TClass*
       // when TClonesArray, all data will be stored in raw format
       for(Int_t n=0;n<NumChilds();n++) {
          TSQLStructure* child = GetChild(n);
-         child->PerformConversion(reg, &objblobs, 0 /*cl->GetName()*/, isclonesarray);
+         child->PerformConversion(reg, &objblobs, 0 /*cl->GetName()*/);
       }
 
       if (objblobs.GetLast()<0)
@@ -1025,11 +1116,8 @@ Bool_t TSQLStructure::StoreObject(TSqlRegistry* reg, const char* objid, TClass*
       objblobs.Delete();
    }
 
-   if (registerobj) {
-      Int_t objidint = atoi(objid);
-      TString regcmd = reg->f->SetObjectDataCmd(reg->fKeyId, objidint, cl);
-      reg->AddRegCmd(regcmd.Data(), objidint);
-   }
+   if (registerobj) 
+      reg->AddRegCmd(objid, cl);
 
    reg->fCurrentObjId = oldid;
    reg->fCurrentObjClass = oldcl;
@@ -1048,7 +1136,7 @@ Bool_t TSQLStructure::StoreObjectInNormalForm(TSqlRegistry* reg)
    TSQLStructure* s_ver = GetChild(0);
 
    TSQLStructure* s_info = GetChild(1);
-
+   
    if (!CheckNormalClassPair(s_ver, s_info)) return kFALSE;
 
    return s_info->StoreClassInNormalForm(reg);
@@ -1060,10 +1148,10 @@ Bool_t TSQLStructure::StoreClassInNormalForm(TSqlRegistry* reg)
    // produces data for complete class table
    // where not possible, raw data for some elements are created
 
-   TStreamerInfo* info = GetStreamerInfo();
-   if (info==0) return kFALSE;
-   TClass* cl = info->GetClass();
-   Int_t version = info->GetClassVersion();
+   TClass* cl = 0;
+   Version_t version = 0;
+   if (!GetClassInfo(cl, version)) return kFALSE;
+   if (cl==0) return kFALSE;   
 
    TSQLClassInfo* sqlinfo = reg->f->RequestSQLClassInfo(cl->GetName(), version);
 
@@ -1073,7 +1161,7 @@ Bool_t TSQLStructure::StoreClassInNormalForm(TSqlRegistry* reg)
    Int_t currrawid = 0;
 
    // add first column with object id
-   columns.Add(new TSQLColumnData(reg->f->SQLObjectIdColumn(), reg->f->SQLIntType(), reg->fCurrentObjId, kTRUE));
+   columns.Add(new TSQLColumnData(reg->f->SQLObjectIdColumn(), reg->fCurrentObjId));
 
    for(Int_t n=0;n<=fChilds.GetLast();n++) {
       TSQLStructure* child = (TSQLStructure*) fChilds.At(n);
@@ -1102,7 +1190,7 @@ Bool_t TSQLStructure::StoreClassInNormalForm(TSqlRegistry* reg)
 
       if (doblobs)
          child->PerformConversion(reg, &blobs, elem->GetName(), kFALSE);
-
+         
       Int_t blobid = -1;
       if (blobs.GetLast()>=0) {
          blobid = currrawid; // column will contain first raw id
@@ -1120,7 +1208,7 @@ Bool_t TSQLStructure::StoreClassInNormalForm(TSqlRegistry* reg)
 
    reg->f->SyncSQLClassInfo(sqlinfo, &columns, needblob);
 
-   reg->InsertToNormalTable(&columns, sqlinfo->GetClassTableName());
+   reg->InsertToNormalTable(&columns, sqlinfo);
 
    columns.Delete();
 
@@ -1178,7 +1266,7 @@ Bool_t TSQLStructure::StoreElementInNormalForm(TSqlRegistry* reg, TObjArray* col
          columns->Add(new TSQLColumnData(colname.Data(), stype, value, kFALSE));
       else {
          Int_t strid = reg->AddLongString(value);
-         TString buf = reg->f->CodeLongString(atoi(reg->fCurrentObjId.Data()), strid);
+         TString buf = reg->f->CodeLongString(reg->fCurrentObjId, strid);
          columns->Add(new TSQLColumnData(colname.Data(), stype, buf.Data(), kFALSE));
       }
 
@@ -1186,10 +1274,10 @@ Bool_t TSQLStructure::StoreElementInNormalForm(TSqlRegistry* reg, TObjArray* col
    }
 
    if (columntyp==kColParent) {
-      TString objid = reg->fCurrentObjId; // DefineObjectIdStr();
+      Long64_t objid = reg->fCurrentObjId; 
       TClass* basecl = elem->GetClassPointer();
       Int_t resversion = basecl->GetClassVersion();
-      if (!StoreObject(reg, objid.Data(), basecl, kFALSE))
+      if (!StoreObject(reg, objid, basecl, kFALSE))
          resversion = -1;
       columns->Add(new TSQLColumnData(colname.Data(), resversion));
       return kTRUE;
@@ -1197,27 +1285,26 @@ Bool_t TSQLStructure::StoreElementInNormalForm(TSqlRegistry* reg, TObjArray* col
    
    if (columntyp==kColObject) {
       
-      TString sobjid;
-      Int_t objid = 0;
+      Long64_t objid = -1;
        
       if (NumChilds()==1) {
          TSQLStructure* child = GetChild(0);
          
          if (child->GetType()==kSqlObject) {
-            if (!child->StoreObject(reg, child->GetValue(), child->GetObjectClass())) return kFALSE;
-            sobjid = child->GetValue(); 
+            objid = child->DefineObjectId(kFALSE); 
+            if (!child->StoreObject(reg, objid, child->GetObjectClass())) return kFALSE;
          } else
-         if (child->GetType()==kSqlPointer)
-            sobjid = child->GetValue(); 
+         if (child->GetType()==kSqlPointer) {
+            TString sobjid = child->GetValue(); 
+            if (sobjid.Length()>0)
+              objid = sqlio::atol64(sobjid.Data());
+         }
       }
        
-      if (sobjid.Length()>0) {
-         objid = sobjid.Atoi(); 
-      } else {
+      if (objid<0) {
          //cout << "!!!! Not standard " << elem->GetName() << " class = " << elem->GetClassPointer()->GetName() << endl; 
          objid = reg->GetNextObjId();
-         sobjid.Form("%d",objid);
-         if (!StoreObject(reg, sobjid.Data(), elem->GetClassPointer()))
+         if (!StoreObject(reg, objid, elem->GetClassPointer()))
             objid = -1;  // this is a case, when no data was stored for this object
       }
 
@@ -1236,16 +1323,20 @@ Bool_t TSQLStructure::StoreElementInNormalForm(TSqlRegistry* reg, TObjArray* col
       if ((child->GetType()!=kSqlPointer) && (child->GetType()!=kSqlObject)) return kFALSE;
 
       Bool_t normal = kTRUE;
+      
+      Long64_t objid = -1;
 
-      if (child->GetType()==kSqlObject)
-         normal = child->StoreObject(reg, child->GetValue(), child->GetObjectClass());
+      if (child->GetType()==kSqlObject) {
+         objid = child->DefineObjectId(kFALSE); 
+         normal = child->StoreObject(reg, objid, child->GetObjectClass());
+      }
 
       if (!normal) {
          Error("kColNormObject","child->StoreObject fails");
          return kFALSE;
       }
 
-      columns->Add(new TSQLColumnData(colname.Data(), "INT", child->GetValue(), kTRUE));
+      columns->Add(new TSQLColumnData(colname.Data(), objid));
       return kTRUE;
    }
 
@@ -1258,14 +1349,18 @@ Bool_t TSQLStructure::StoreElementInNormalForm(TSqlRegistry* reg, TObjArray* col
              (child->GetType()!=kSqlObject)) return kFALSE;
          Bool_t normal = kTRUE;
          
-         if (child->GetType()==kSqlObject)
-            normal = child->StoreObject(reg, child->GetValue(), child->GetObjectClass());
+         Long64_t objid = -1;
+         
+         if (child->GetType()==kSqlObject) {
+            objid = child->DefineObjectId(kFALSE); 
+            normal = child->StoreObject(reg, objid, child->GetObjectClass());
+         }
 
          if (!normal) return kFALSE;
          
          colname = DefineElementColumnName(elem, reg->f, index);
 
-         columns->Add(new TSQLColumnData(colname.Data(), "INT", child->GetValue(), kTRUE));
+         columns->Add(new TSQLColumnData(colname.Data(), objid));
       }
       return kTRUE;
    }
@@ -1276,13 +1371,16 @@ Bool_t TSQLStructure::StoreElementInNormalForm(TSqlRegistry* reg, TObjArray* col
       if ((child->GetType()!=kSqlPointer) && (child->GetType()!=kSqlObject)) return kFALSE;
 
       Bool_t normal = kTRUE;
+      Long64_t objid = -1;
 
-      if (child->GetType()==kSqlObject)
-         normal = child->StoreObject(reg, child->GetValue(), child->GetObjectClass());
+      if (child->GetType()==kSqlObject) {
+         objid = child->DefineObjectId(kFALSE);  
+         normal = child->StoreObject(reg, objid, child->GetObjectClass());
+      }
 
       if (!normal) return kFALSE;
 
-      columns->Add(new TSQLColumnData(colname.Data(), "INT", child->GetValue(), kTRUE));
+      columns->Add(new TSQLColumnData(colname.Data(), objid));
       return kTRUE;
    }
 
@@ -1367,14 +1465,15 @@ Bool_t TSQLStructure::TryConvertObjectArray(TSqlRegistry* reg, TObjArray* blobs)
    while (indx<NumChilds()-1) {
       indx++; //TSQLStructure* s_ver = GetChild(indx++);
       TSQLStructure* s_info = GetChild(indx++);
-      TStreamerInfo* info = s_info->GetStreamerInfo();
-      Int_t objid = reg->GetNextObjId();
-      TString sobjid;
-      sobjid.Form("%d",objid);
-      if (!s_info->StoreObject(reg, sobjid.Data(), info->GetClass())) {
+      TClass* cl = 0;
+      Version_t version = 0;
+      if (!s_info->GetClassInfo(cl, version)) return kFALSE;
+      Long64_t objid = reg->GetNextObjId();
+      if (!s_info->StoreObject(reg, objid, cl)) 
          objid = -1;  // this is a case, when no data was stored for this object
-         sobjid = "-1";
-      }
+      
+      TString sobjid;
+      sobjid.Form("%lld", objid);
 
       AddCmd(blobs, sqlio::ObjectRef_Arr, sobjid.Data(), elem->GetName(), ns);
    }
@@ -1388,12 +1487,16 @@ Bool_t TSQLStructure::CheckNormalClassPair(TSQLStructure* s_ver, TSQLStructure*
    // check if pair of two element corresponds
    // to start of object, stored in normal form
 
-   if ((s_ver==0) || (s_info==0) || (s_ver->GetType()!=kSqlVersion) ||
-       (s_info->GetType()!=kSqlStreamerInfo)) return kFALSE;
+   if ((s_ver==0) || (s_info==0) || (s_ver->GetType()!=kSqlVersion)) return kFALSE;
+
+   TClass* ver_cl = s_ver->GetVersionClass();
 
-   TClass* cl = s_ver->GetVersionClass();
-   TStreamerInfo* info = s_info->GetStreamerInfo();
-   if ((cl==0) || (cl!=info->GetClass()) || (cl->GetClassVersion()!=info->GetClassVersion())) return kFALSE;
+   TClass* info_cl = 0;
+   Version_t info_ver = 0;
+   if (!s_info->GetClassInfo(info_cl, info_ver)) return kFALSE;
+
+   if ((ver_cl==0) || (info_cl==0) || (ver_cl!=info_cl) || 
+       (ver_cl->GetClassVersion()!=info_ver)) return kFALSE;
 
    return kTRUE;
 }
@@ -1429,7 +1532,7 @@ Bool_t TSQLStructure::StoreTObject(TSqlRegistry* reg)
 
    const char* uinttype = reg->f->SQLCompatibleType(TStreamerInfo::kUInt);
 
-   columns.Add(new TSQLColumnData(reg->f->SQLObjectIdColumn(), reg->f->SQLIntType(), reg->fCurrentObjId, kTRUE));
+   columns.Add(new TSQLColumnData(reg->f->SQLObjectIdColumn(), reg->fCurrentObjId));
 
    columns.Add(new TSQLColumnData(sqlio::TObjectUniqueId, uinttype, str_id->GetValue(), kTRUE));
    columns.Add(new TSQLColumnData(sqlio::TObjectBits, uinttype, str_bits->GetValue(), kTRUE));
@@ -1437,7 +1540,7 @@ Bool_t TSQLStructure::StoreTObject(TSqlRegistry* reg)
 
    reg->f->SyncSQLClassInfo(sqlinfo, &columns, kFALSE);
 
-   reg->InsertToNormalTable(&columns, sqlinfo->GetClassTableName());
+   reg->InsertToNormalTable(&columns, sqlinfo);
 
    columns.Delete();
 
@@ -1458,11 +1561,11 @@ Bool_t TSQLStructure::StoreTString(TSqlRegistry* reg)
 
    TObjArray columns;
 
-   columns.Add(new TSQLColumnData(reg->f->SQLObjectIdColumn(), reg->f->SQLIntType(), reg->fCurrentObjId, kTRUE));
+   columns.Add(new TSQLColumnData(reg->f->SQLObjectIdColumn(), reg->fCurrentObjId));
    columns.Add(new TSQLColumnData(sqlio::TStringValue, reg->f->SQLBigTextType(), value, kFALSE));
 
    reg->f->SyncSQLClassInfo(sqlinfo, &columns, kFALSE);
-   reg->InsertToNormalTable(&columns, sqlinfo->GetClassTableName());
+   reg->InsertToNormalTable(&columns, sqlinfo);
    columns.Delete();
    return kTRUE;
 }
@@ -1516,6 +1619,8 @@ Int_t TSQLStructure::DefineElementColumnType(TStreamerElement* elem, TSQLFile* f
    if (elem==0) return kColUnknown;
 
    Int_t typ = elem->GetType();
+   
+   if (typ == TStreamerInfo::kMissing) return kColRawData;
 
    if ((typ>0) && (typ<20) &&
        (typ!=TStreamerInfo::kCharStar)) return kColSimple;
@@ -1572,7 +1677,6 @@ Int_t TSQLStructure::DefineElementColumnType(TStreamerElement* elem, TSQLFile* f
       if (elem->GetStreamer()!=0) return kColNormObject; 
                              else return kColNormObjectArray;
 
-
    if ((typ==TStreamerInfo::kObject) ||
        (typ==TStreamerInfo::kAny) ||
        (typ==TStreamerInfo::kAnyp) ||
@@ -1685,13 +1789,10 @@ TString TSQLStructure::DefineElementColumnName(TStreamerElement* elem, TSQLFile*
 }
 
 //________________________________________________________________________
-Int_t TSQLStructure::LocateElementColumn(TSQLFile* f, TSQLObjectData* data)
+Int_t TSQLStructure::LocateElementColumn(TSQLFile* f, TBufferSQL2* buf, TSQLObjectData* data)
 {
    // find column in TSQLObjectData object, which correspond to current element
 
-   // for TClonesArray do nothing, just exit
-   if (IsClonesArray()) return kColClonesArray;
-
    TStreamerElement* elem = GetElement();
    if ((elem==0) || (data==0)) return kColUnknown;
 
@@ -1708,6 +1809,10 @@ Int_t TSQLStructure::LocateElementColumn(TSQLFile* f, TSQLObjectData* data)
    
    TString colname = DefineElementColumnName(elem, f);
 
+   if (gDebug>4)
+     cout << "         colname = " << colname << " in " << 
+            data->GetInfo()->GetClassTableName() << endl;
+
    switch (coltype) {
    case kColSimple: {
       located = data->LocateColumn(colname.Data());
@@ -1723,16 +1828,16 @@ Int_t TSQLStructure::LocateElementColumn(TSQLFile* f, TSQLObjectData* data)
       located = data->LocateColumn(colname.Data());
       if (located==kColUnknown) return kColUnknown;
 
-      Int_t objid = DefineObjectId();
+      Long64_t objid = DefineObjectId(kTRUE);
       const char* clname = elemname;
-      Int_t version = atoi(data->GetValue());
+      Version_t version = atoi(data->GetValue());
 
       // this is a case, when parent store nothing in the database
       if (version<0) break;
 
       // special treatment for TObject
       if (strcmp(clname,TObject::Class()->GetName())==0) {
-         UnpackTObject(f, data, objid, version);
+         UnpackTObject(f, buf, data, objid, version);
          break;
       }
 
@@ -1743,7 +1848,7 @@ Int_t TSQLStructure::LocateElementColumn(TSQLFile* f, TSQLObjectData* data)
       if (sqlinfo->IsClassTableExist()) {
          data->AddUnpackInt(sqlio::Version, version);
       } else {
-         TSQLObjectData* objdata = f->GetObjectClassData(objid, sqlinfo);
+         TSQLObjectData* objdata = buf->SqlObjectData(objid, sqlinfo);
          if ((objdata==0) || !objdata->PrepareForRawData()) return kColUnknown;
          AddObjectData(objdata);
       }
@@ -1765,7 +1870,7 @@ Int_t TSQLStructure::LocateElementColumn(TSQLFile* f, TSQLObjectData* data)
       const char* strobjid = data->GetValue();
       if (strobjid==0) return kColUnknown;
 
-      Int_t objid = atoi(strobjid);
+      Long64_t objid = sqlio::atol64(strobjid);
 
       // when nothing was stored, nothing need to be read. skip
       if (objid<0) break;
@@ -1773,11 +1878,11 @@ Int_t TSQLStructure::LocateElementColumn(TSQLFile* f, TSQLObjectData* data)
       TString clname;
       Version_t version;
 
-      if (!f->GetObjectData(objid, clname, version)) return kColUnknown;
+      if (!buf->SqlObjectInfo(objid, clname, version)) return kColUnknown;
 
       // special treatment for TObject
       if (clname==TObject::Class()->GetName()) {
-         UnpackTObject(f, data, objid, version);
+         UnpackTObject(f, buf, data, objid, version);
          break;
       }
 
@@ -1787,7 +1892,7 @@ Int_t TSQLStructure::LocateElementColumn(TSQLFile* f, TSQLObjectData* data)
       if (sqlinfo->IsClassTableExist()) {
          data->AddUnpackInt(sqlio::Version, version);
       } else {
-         TSQLObjectData* objdata = f->GetObjectClassData(objid, sqlinfo);
+         TSQLObjectData* objdata = buf->SqlObjectData(objid, sqlinfo);
          if ((objdata==0) || !objdata->PrepareForRawData()) return kColUnknown;
          AddObjectData(objdata);
       }
@@ -1826,8 +1931,8 @@ Int_t TSQLStructure::LocateElementColumn(TSQLFile* f, TSQLObjectData* data)
       if (located==kColUnknown) return located;
       const char* value = data->GetValue();
 
-      Int_t objid = DefineObjectId();
-      Int_t strid = f->IsLongStringCode(value, objid);
+      Long64_t objid = DefineObjectId(kTRUE);
+      Int_t strid = f->IsLongStringCode(objid, value);
 
       TString buf;
 
@@ -1865,14 +1970,14 @@ Int_t TSQLStructure::LocateElementColumn(TSQLFile* f, TSQLObjectData* data)
 }
 
 //________________________________________________________________________
-Bool_t TSQLStructure::UnpackTObject(TSQLFile* f, TSQLObjectData* data, Int_t objid, Int_t clversion)
+Bool_t TSQLStructure::UnpackTObject(TSQLFile* f, TBufferSQL2* buf, TSQLObjectData* data, Long64_t objid, Int_t clversion)
 {
    // Unpack TObject data in form, understodable by custom TObject streamer
 
    TSQLClassInfo* sqlinfo = f->RequestSQLClassInfo(TObject::Class()->GetName(), clversion);
    if (sqlinfo==0) return kFALSE;
 
-   TSQLObjectData* tobjdata = f->GetObjectClassData(objid, sqlinfo);
+   TSQLObjectData* tobjdata = buf->SqlObjectData(objid, sqlinfo);
    if (tobjdata==0) return kFALSE;
 
    data->AddUnpackInt(sqlio::Version, clversion);
@@ -1896,14 +2001,14 @@ Bool_t TSQLStructure::UnpackTObject(TSQLFile* f, TSQLObjectData* data, Int_t obj
 }
 
 //________________________________________________________________________
-Bool_t TSQLStructure::UnpackTString(TSQLFile* f, TSQLObjectData* data, Int_t objid, Int_t clversion)
+Bool_t TSQLStructure::UnpackTString(TSQLFile* f, TBufferSQL2* buf, TSQLObjectData* data, Long64_t objid, Int_t clversion)
 {
    // Unpack TString data in form, understodable by custom TString streamer
 
    TSQLClassInfo* sqlinfo = f->RequestSQLClassInfo(TString::Class()->GetName(), clversion);
    if (sqlinfo==0) return kFALSE;
 
-   TSQLObjectData* tstringdata = f->GetObjectClassData(objid, sqlinfo);
+   TSQLObjectData* tstringdata = buf->SqlObjectData(objid, sqlinfo);
    if (tstringdata==0) return kFALSE;
 
    tstringdata->LocateColumn(sqlio::TStringValue);
@@ -1924,3 +2029,13 @@ Bool_t TSQLStructure::UnpackTString(TSQLFile* f, TSQLObjectData* data, Int_t obj
 
    return kTRUE;
 }
+
+//________________________________________________________________________
+void TSQLStructure::AddStrBrackets(TString &s, const char* quote)
+{
+   // adds quotes arround string value and replaces some special symbols
+   if (strcmp(quote,"\"")==0) s.ReplaceAll("\"","\\\"");
+                        else  s.ReplaceAll("'","''");
+   s.Prepend(quote);
+   s.Append(quote);
+}
diff --git a/xml/inc/TKeyXML.h b/xml/inc/TKeyXML.h
index 2c38455bdb9..4743f4373c2 100644
--- a/xml/inc/TKeyXML.h
+++ b/xml/inc/TKeyXML.h
@@ -1,4 +1,4 @@
-// @(#)root/xml:$Name:  $:$Id: TKeyXML.h,v 1.3 2005/11/20 05:07:41 pcanal Exp $
+// @(#)root/xml:$Name:  $:$Id: TKeyXML.h,v 1.4 2006/01/25 16:00:11 pcanal Exp $
 // Author: Sergey Linev  10.05.2004
 
 /*************************************************************************
@@ -26,19 +26,18 @@ class TKeyXML : public TKey {
       TKeyXML();
     
    public:
-      TKeyXML(TXMLFile* file, const TObject* obj, const char* name = 0);
-      TKeyXML(TXMLFile* file, const void* obj, const TClass* cl, const char* name);
-      TKeyXML(TXMLFile* file, XMLNodePointer_t keynode);
+      TKeyXML(TDirectory* mother, const TObject* obj, const char* name = 0);
+      TKeyXML(TDirectory* mother, const void* obj, const TClass* cl, const char* name);
+      TKeyXML(TDirectory* mother, XMLNodePointer_t keynode);
       virtual ~TKeyXML();
 
       // redefined TKey Methods
-      virtual void      Browse(TBrowser *b);
       virtual void      Delete(Option_t *option="");
       virtual void      DeleteBuffer() {}
       virtual void      FillBuffer(char *&) {}
       virtual char     *GetBuffer() const { return 0; }
-      virtual Long64_t  GetSeekKey() const  { return 1; }
-      virtual Long64_t  GetSeekPdir() const { return 1;}
+      virtual Long64_t  GetSeekKey() const  { return fKeyNode ? 1024 : 0;}
+      virtual Long64_t  GetSeekPdir() const { return fKeyNode ? 1024 : 0;}
       //virtual ULong_t   Hash() const { return 0; }
       virtual void      Keep() {}
       //virtual void      ls(Option_t* ="") const;
@@ -51,26 +50,19 @@ class TKeyXML : public TKey {
       virtual void      ReadBuffer(char *&) {}
       virtual void      ReadFile() {}
       virtual void      SetBuffer() { fBuffer = 0; }
-      virtual void      SetParent(const TObject* ) { }
-      virtual Int_t     Sizeof() const { return 0; }
       virtual Int_t     WriteFile(Int_t =1, TFile* = 0) { return 0; }
 
       // TKeyXML specific methods
 
       XMLNodePointer_t  KeyNode() const { return fKeyNode; }
-      void              SetXML(TXMLEngine* xml) { fXML = xml; }
-
 
    protected:
       virtual Int_t     Read(const char *name) { return TKey::Read(name); }
       void              StoreObject(const void* obj, const TClass* cl);
-      XMLNodePointer_t  ObjNode();
-      XMLNodePointer_t  BlockNode();
+      TXMLEngine*       XMLEngine();
       
       void*             XmlReadAny(void* obj, const TClass* expectedClass);
       
-      TXMLFile*         fFile;     //!
-      TXMLEngine*       fXML;      //!
       XMLNodePointer_t  fKeyNode;  //!
 
    ClassDef(TKeyXML,1) // a special TKey for XML files      
diff --git a/xml/inc/TXMLFile.h b/xml/inc/TXMLFile.h
index e6b692a67aa..a1582abfec3 100644
--- a/xml/inc/TXMLFile.h
+++ b/xml/inc/TXMLFile.h
@@ -1,4 +1,4 @@
-// @(#)root/xml:$Name:  $:$Id: TXMLFile.h,v 1.11 2005/11/28 23:22:31 pcanal Exp $
+// @(#)root/xml:$Name:  $:$Id: TXMLFile.h,v 1.12 2006/01/20 01:12:13 pcanal Exp $
 // Author: Sergey Linev  10.05.2004
 
 /*************************************************************************
@@ -52,6 +52,8 @@ class TXMLFile : public TFile, public TXMLSetup {
       virtual ~TXMLFile();
 
       virtual void      Close(Option_t *option=""); // *MENU*
+      virtual TKey*     CreateKey(TDirectory* mother, const TObject* obj, const char* name, Int_t bufsize);
+      virtual TKey*     CreateKey(TDirectory* mother, const void* obj, const TClass* cl, const char* name, Int_t bufsize);
       virtual void      DrawMap(const char* ="*",Option_t* ="") {} 
       virtual void      FillBuffer(char* &) {}
       virtual void      Flush() {}
@@ -105,9 +107,6 @@ class TXMLFile : public TFile, public TXMLSetup {
    protected:
       // functions to store streamer infos
       
-      virtual TKey*     CreateKey(const TObject* obj, const char* name, Int_t bufsize);
-      virtual TKey*     CreateKey(const void* obj, const TClass* cl, const char* name, Int_t bufsize);
-      
       void              StoreStreamerElement(XMLNodePointer_t node, TStreamerElement* elem);
       void              ReadStreamerElement(XMLNodePointer_t node, TStreamerInfo* info);
 
diff --git a/xml/src/TBufferXML.cxx b/xml/src/TBufferXML.cxx
index c6b70f65d48..1e5c722cfe7 100644
--- a/xml/src/TBufferXML.cxx
+++ b/xml/src/TBufferXML.cxx
@@ -1,4 +1,4 @@
-// @(#)root/:$Name:  $:$Id: TBufferXML.cxx,v 1.8 2006/01/20 01:12:13 pcanal Exp $
+// @(#)root/:$Name:  $:$Id: TBufferXML.cxx,v 1.9 2006/01/25 16:00:11 pcanal Exp $
 // Author: Sergey Linev, Rene Brun  10.05.2004
 
 /*************************************************************************
@@ -89,6 +89,7 @@ TBufferXML::TBufferXML(TBuffer::EMode mode) :
 
    SetParent(0);
    SetBit(kCannotHandleMemberWiseStreaming);
+   SetBit(kTextBasedStreaming);
 }
 
 //______________________________________________________________________________
@@ -117,6 +118,7 @@ TBufferXML::TBufferXML(TBuffer::EMode mode, TXMLFile* file) :
 
    SetParent(file);
    SetBit(kCannotHandleMemberWiseStreaming);
+   SetBit(kTextBasedStreaming);
    if (XmlFile()) {
       SetXML(XmlFile()->XML());
       SetCompressionLevel(XmlFile()->GetCompressionLevel());
@@ -1031,6 +1033,9 @@ void TBufferXML::ClassMember(const char* name, const char* typeName, Int_t arrsi
 
    Int_t typ_id = -1;
    
+   if (strcmp(typeName,"raw:data")==0) 
+      typ_id = TStreamerInfo::kMissing;
+   
    if (typ_id<0) {
       TDataType *dt = gROOT->GetType(typeName);
       if (dt!=0)
@@ -1068,6 +1073,11 @@ void TBufferXML::ClassMember(const char* name, const char* typeName, Int_t arrsi
    
    TStreamerElement* elem = 0;
    
+   if (typ_id == TStreamerInfo::kMissing) {
+      elem = new TStreamerElement(name,"title",0, typ_id, "raw:data");
+   } else
+   
+
    if (typ_id==TStreamerInfo::kBase) {
       TClass* cl = gROOT->GetClass(tname.Data());
       if (cl!=0) {
diff --git a/xml/src/TKeyXML.cxx b/xml/src/TKeyXML.cxx
index b4e4d94fcc9..0cd49c9350b 100644
--- a/xml/src/TKeyXML.cxx
+++ b/xml/src/TKeyXML.cxx
@@ -1,4 +1,4 @@
-// @(#)root/xml:$Name:  $:$Id: TKeyXML.cxx,v 1.5 2006/01/20 01:12:13 pcanal Exp $
+// @(#)root/xml:$Name:  $:$Id: TKeyXML.cxx,v 1.6 2006/01/25 16:00:11 pcanal Exp $
 // Author: Sergey Linev, Rene Brun  10.05.2004
 
 /*************************************************************************
@@ -30,18 +30,14 @@ ClassImp(TKeyXML);
 //______________________________________________________________________________
 TKeyXML::TKeyXML() :
    TKey(),
-   fFile(0),
-   fXML(0),
    fKeyNode(0)
 {
    // default constructor
 }
 
 //______________________________________________________________________________
-TKeyXML::TKeyXML(TXMLFile* file, const TObject* obj, const char* name) :
-    TKey(),
-    fFile(file),
-    fXML(file->XML()),
+TKeyXML::TKeyXML(TDirectory* mother, const TObject* obj, const char* name) :
+    TKey(mother),
     fKeyNode(0)
 {
    // Creates TKeyXML and convert obj data to xml structures
@@ -59,10 +55,8 @@ TKeyXML::TKeyXML(TXMLFile* file, const TObject* obj, const char* name) :
 }
 
 //______________________________________________________________________________
-TKeyXML::TKeyXML(TXMLFile* file, const void* obj, const TClass* cl, const char* name) :
-   TKey(),
-   fFile(file),
-   fXML(file->XML()),
+TKeyXML::TKeyXML(TDirectory* mother, const void* obj, const TClass* cl, const char* name) :
+   TKey(mother),
    fKeyNode(0)
 {
    // Creates TKeyXML and convert obj data to xml structures
@@ -74,60 +68,39 @@ TKeyXML::TKeyXML(TXMLFile* file, const void* obj, const TClass* cl, const char*
 }
 
 //______________________________________________________________________________
-TKeyXML::TKeyXML(TXMLFile* file, XMLNodePointer_t keynode) :
-   TKey(),
-   fFile(file),
-   fXML(file->XML()),
+TKeyXML::TKeyXML(TDirectory* mother, XMLNodePointer_t keynode) :
+   TKey(mother),
    fKeyNode(keynode)
 {
    // Creates TKeyXML and takes ownership over xml node, from which object can be restored
 
-   SetName(fXML->GetAttr(keynode, xmlio::Name));
+   TXMLEngine* xml = XMLEngine();
+
+   SetName(xml->GetAttr(keynode, xmlio::Name));
    
-   if (fXML->HasAttr(keynode, xmlio::Title))
-      SetTitle(fXML->GetAttr(keynode, xmlio::Title));
+   if (xml->HasAttr(keynode, xmlio::Title))
+      SetTitle(xml->GetAttr(keynode, xmlio::Title));
 
-   fCycle = fXML->GetIntAttr(keynode, xmlio::Cycle);
+   fCycle = xml->GetIntAttr(keynode, xmlio::Cycle);
       
-   if (fXML->HasAttr(keynode, xmlio::CreateTm)) {
-      TDatime tm(fXML->GetAttr(keynode, xmlio::CreateTm)); 
+   if (xml->HasAttr(keynode, xmlio::CreateTm)) {
+      TDatime tm(xml->GetAttr(keynode, xmlio::CreateTm)); 
       fDatime = tm;
    }
 
-   XMLNodePointer_t objnode = fXML->GetChild(keynode);
-   fXML->SkipEmpty(objnode);
+   XMLNodePointer_t objnode = xml->GetChild(keynode);
+   xml->SkipEmpty(objnode);
 
-   fClassName = fXML->GetAttr(objnode, xmlio::ObjClass);
+   fClassName = xml->GetAttr(objnode, xmlio::ObjClass);
 }
 
 //______________________________________________________________________________
 TKeyXML::~TKeyXML()
 {
    // TKeyXML destructor
-   if (fKeyNode)
-      fXML->FreeNode(fKeyNode);
-}
-
-//______________________________________________________________________________
-void TKeyXML::Browse(TBrowser *b)
-{
-   // Browse object corresponding to this key
-
-   TObject *obj = gDirectory->GetList()->FindObject(GetName());
-   if (obj && !obj->IsFolder()) {
-      if (obj->InheritsFrom(TCollection::Class()))
-         obj->Delete();   // delete also collection elements
-      delete obj;
-      obj = 0;
-   }
-
-   if (!obj)
-      obj = ReadObj();
-
-   if (b && obj) {
-      obj->Browse(b);
-      b->SetRefreshFlag(kTRUE);
-   }
+   TXMLEngine* xml = XMLEngine();
+   if (fKeyNode && xml)
+      xml->FreeNode(fKeyNode);
 }
 
 //______________________________________________________________________________
@@ -136,67 +109,52 @@ void TKeyXML::Delete(Option_t * /*option*/)
    // Delete key from current directory
    // Note: TKeyXML object is not deleted. You still have to call "delete key"
 
-   gDirectory->GetListOfKeys()->Remove(this);
+   TXMLEngine* xml = XMLEngine();
+   if (fKeyNode && xml) {
+      xml->FreeNode(fKeyNode);
+      fKeyNode = 0;
+   }
+
+   fMotherDir->GetListOfKeys()->Remove(this);
 }
 
 //______________________________________________________________________________
 void TKeyXML::StoreObject(const void* obj, const TClass* cl)
 {
    //  convert object to xml structure and keep this structure in key
+   
+   TXMLFile* f = (TXMLFile*) GetFile();
+   TXMLEngine* xml = XMLEngine();
+   if ((f==0) || (xml==0)) return;
 
-   fCycle  = fFile->AppendKey(this);
+   fCycle  = GetMotherDir()->AppendKey(this);
 
-   fKeyNode = fXML->NewChild(0, 0, xmlio::Xmlkey, 0);
-   fXML->NewAttr(fKeyNode, 0, xmlio::Name, GetName());
+   fKeyNode = xml->NewChild(0, 0, xmlio::Xmlkey, 0);
+   xml->NewAttr(fKeyNode, 0, xmlio::Name, GetName());
    
-   fXML->NewIntAttr(fKeyNode, xmlio::Cycle, fCycle);
+   xml->NewIntAttr(fKeyNode, xmlio::Cycle, fCycle);
    
-   if (fFile->GetIOVersion()>1) {
+   if (f->GetIOVersion()>1) {
       if (strlen(GetTitle())>0)
-         fXML->NewAttr(fKeyNode, 0, xmlio::Title, GetTitle());
+         xml->NewAttr(fKeyNode, 0, xmlio::Title, GetTitle());
       fDatime.Set();
-      fXML->NewAttr(fKeyNode, 0, xmlio::CreateTm, fDatime.AsSQLString());
+      xml->NewAttr(fKeyNode, 0, xmlio::CreateTm, fDatime.AsSQLString());
    }
    
-   TBufferXML buffer(TBuffer::kWrite, fFile);
-   if (fFile->GetIOVersion()==1)
+   TBufferXML buffer(TBuffer::kWrite, f);
+   if (f->GetIOVersion()==1)
       buffer.SetBit(TBuffer::kCannotHandleMemberWiseStreaming, kFALSE);
    
    XMLNodePointer_t node = buffer.XmlWriteAny(obj, cl);
 
    if (node!=0)
-      fXML->AddChild(fKeyNode, node);
+      xml->AddChild(fKeyNode, node);
 
    buffer.XmlWriteBlock(fKeyNode);
 
    if (cl) fClassName = cl->GetName();
 }
 
-//______________________________________________________________________________
-XMLNodePointer_t TKeyXML::ObjNode()
-{
-   // return starting node, where object was stored
-
-   if (fKeyNode==0) return 0;
-   XMLNodePointer_t node = fXML->GetChild(fKeyNode);
-   fXML->SkipEmpty(node);
-   return node;
-}
-
-//______________________________________________________________________________
-XMLNodePointer_t TKeyXML::BlockNode()
-{
-   // return node, where key binary data is stored
-   if (fKeyNode==0) return 0;
-   XMLNodePointer_t node = fXML->GetChild(fKeyNode);
-   fXML->SkipEmpty(node);
-   while (node!=0) {
-      if (strcmp(fXML->GetNodeName(node), xmlio::XmlBlock)==0) return node;
-      fXML->ShiftToNext(node);
-   }
-   return 0;
-}
-
 //______________________________________________________________________________
 Int_t TKeyXML::Read(TObject* tobj)
 {
@@ -220,7 +178,17 @@ TObject* TKeyXML::ReadObj()
 
    TObject* tobj = (TObject*) XmlReadAny(0, TObject::Class());
    
-   if ((tobj!=0) && gROOT->GetForceStyle()) tobj->UseCurrentStyle();
+   if (tobj!=0) {
+      if (gROOT->GetForceStyle()) tobj->UseCurrentStyle(); 
+      if (tobj->IsA() == TDirectory::Class()) {
+         TDirectory *dir = (TDirectory*) tobj;
+         dir->SetName(GetName());
+         dir->SetTitle(GetTitle());
+         dir->ReadKeys();
+         dir->SetMother(fMotherDir);
+         fMotherDir->Append(dir);
+      }
+   }
        
    return tobj;
 }
@@ -238,17 +206,31 @@ void* TKeyXML::XmlReadAny(void* obj, const TClass* expectedClass)
 {
    // read object from key and cast to expected class
 
-   if (fKeyNode==0) return 0;
+   if (fKeyNode==0) return obj;
+   
+   TXMLFile* f = (TXMLFile*) GetFile();
+   TXMLEngine* xml = XMLEngine();
+   if ((f==0) || (xml==0)) return obj;
    
-   TBufferXML buffer(TBuffer::kRead, fFile);
-   if (fFile->GetIOVersion()==1)
+   TBufferXML buffer(TBuffer::kRead, f);
+   if (f->GetIOVersion()==1)
       buffer.SetBit(TBuffer::kCannotHandleMemberWiseStreaming, kFALSE);
-   buffer.XmlReadBlock(BlockNode());
+
+   XMLNodePointer_t blocknode = xml->GetChild(fKeyNode);
+   xml->SkipEmpty(blocknode);
+   while (blocknode!=0) {
+      if (strcmp(xml->GetNodeName(blocknode), xmlio::XmlBlock)==0) break;
+      xml->ShiftToNext(blocknode);
+   }
+   buffer.XmlReadBlock(blocknode);
+
+   XMLNodePointer_t objnode = xml->GetChild(fKeyNode);
+   xml->SkipEmpty(objnode);
 
    TClass* cl = 0;
-   void* res = buffer.XmlReadAny(ObjNode(), obj, &cl);
+   void* res = buffer.XmlReadAny(objnode, obj, &cl);
    
-   if ((cl==0) || (res==0)) return 0;
+   if ((cl==0) || (res==0)) return obj;
    
    Int_t delta = 0;
    
@@ -268,3 +250,12 @@ void* TKeyXML::XmlReadAny(void* obj, const TClass* expectedClass)
    
    return ((char*)res) + delta;
 }
+
+//______________________________________________________________________________
+TXMLEngine* TKeyXML::XMLEngine()
+{
+   // return pointer on TXMLEngine object, used for xml conversion 
+    
+   TXMLFile* f = (TXMLFile*) GetFile();
+   return f==0 ? 0 : f->XML();
+}
diff --git a/xml/src/TXMLFile.cxx b/xml/src/TXMLFile.cxx
index 72ca6214fff..5725899b841 100644
--- a/xml/src/TXMLFile.cxx
+++ b/xml/src/TXMLFile.cxx
@@ -1,4 +1,4 @@
-// @(#)root/xml:$Name:  $:$Id: TXMLFile.cxx,v 1.16 2005/12/08 15:50:48 pcanal Exp $
+// @(#)root/xml:$Name:  $:$Id: TXMLFile.cxx,v 1.17 2006/01/20 01:12:13 pcanal Exp $
 // Author: Sergey Linev, Rene Brun  10.05.2004
 
 /*************************************************************************
@@ -140,8 +140,7 @@ TXMLFile::TXMLFile(const char* filename, Option_t* option, const char* title, In
    gDirectory = 0;
    SetName(filename);
    SetTitle(title);
-   TDirectory::Build();
-   fFile = this;
+   TDirectory::Build(this, 0);
 
    fD          = -1;
    fFile       = this;
@@ -432,19 +431,19 @@ Int_t TXMLFile::ReOpen(Option_t* mode)
 }
 
 //______________________________________________________________________________
-TKey* TXMLFile::CreateKey(const TObject* obj, const char* name, Int_t)
+TKey* TXMLFile::CreateKey(TDirectory* mother, const TObject* obj, const char* name, Int_t)
 {
    // create XML key, which will store object in xml structures
 
-   return new TKeyXML(this, obj, name);
+   return new TKeyXML(mother, obj, name);
 }
 
 //______________________________________________________________________________
-TKey* TXMLFile::CreateKey(const void* obj, const TClass* cl, const char* name, Int_t)
+TKey* TXMLFile::CreateKey(TDirectory* mother, const void* obj, const TClass* cl, const char* name, Int_t)
 {
    // create XML key, which will store object in xml structures
 
-   return new TKeyXML(this, obj, cl, name);
+   return new TKeyXML(mother, obj, cl, name);
 }
 
 //______________________________________________________________________________
-- 
GitLab