TKeySQL.cxx

Go to the documentation of this file.
00001 // @(#)root/sql:$Id: TKeySQL.cxx 24037 2008-05-28 06:32:07Z brun $
00002 // Author: Sergey Linev  20/11/2005
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //________________________________________________________________________
00013 //
00014 // TKeySQL is represents a metainforamtion about object, which was written to
00015 // SQL database. It keeps object id, which used to locate object data
00016 // from database tables.
00017 //________________________________________________________________________
00018 
00019 
00020 #include "TKeySQL.h"
00021 
00022 #include "TROOT.h"
00023 #include "TClass.h"
00024 #include "TBrowser.h"
00025 #include "Riostream.h"
00026 
00027 #include "TSQLResult.h"
00028 #include "TBufferSQL2.h"
00029 #include "TSQLStructure.h"
00030 #include "TSQLFile.h"
00031 #include <stdlib.h>
00032 
00033 ClassImp(TKeySQL);
00034 
00035 //______________________________________________________________________________
00036 TKeySQL::TKeySQL() :
00037    TKey(),
00038    fKeyId(-1),
00039    fObjId(-1)
00040 {
00041    // default constructor
00042 }
00043 
00044 //______________________________________________________________________________
00045 TKeySQL::TKeySQL(TDirectory* mother, const TObject* obj, const char* name, const char* title) :
00046     TKey(mother),
00047     fKeyId(-1),
00048     fObjId(-1)
00049 {
00050    // Creates TKeySQL and convert obj data to TSQLStructure via TBufferSQL2
00051 
00052    if (name) SetName(name); else
00053       if (obj!=0) {SetName(obj->GetName());  fClassName=obj->ClassName();}
00054       else SetName("Noname");
00055       
00056    if (title) SetTitle(title);
00057 
00058    StoreKeyObject((void*)obj, obj ? obj->IsA() : 0);
00059 }
00060 
00061 //______________________________________________________________________________
00062 TKeySQL::TKeySQL(TDirectory* mother, const void* obj, const TClass* cl, const char* name, const char* title) :
00063     TKey(mother),
00064     fKeyId(-1),
00065     fObjId(-1)
00066 {
00067    // Creates TKeySQL and convert obj data to TSQLStructure via TBufferSQL2
00068 
00069    if (name && *name) SetName(name);
00070    else SetName(cl ? cl->GetName() : "Noname");
00071 
00072    if (title) SetTitle(title);
00073 
00074    StoreKeyObject(obj, cl);
00075 }
00076 
00077 //______________________________________________________________________________
00078 TKeySQL::TKeySQL(TDirectory* mother, Long64_t keyid, Long64_t objid, 
00079                  const char* name, const char* title,
00080                  const char* keydatetime, Int_t cycle, const char* classname) :
00081     TKey(mother),
00082     fKeyId(keyid),
00083     fObjId(objid)
00084 {
00085    // Create TKeySQL object, which correponds to single entry in keys table
00086 
00087    SetName(name);
00088    if (title) SetTitle(title);
00089    TDatime dt(keydatetime);
00090    fDatime = dt;
00091    fCycle = cycle;
00092    fClassName = classname;
00093 }
00094 
00095 //______________________________________________________________________________
00096 TKeySQL::~TKeySQL()
00097 {
00098 // TKeySQL destructor
00099 }
00100 
00101 //______________________________________________________________________________
00102 Bool_t TKeySQL::IsKeyModified(const char* keyname, const char* keytitle, const char* keydatime, Int_t cycle, const char* classname)
00103 {
00104 // Compares keydata with provided and return kTRUE if key was modified
00105 // Used in TFile::StreamKeysForDirectory() method to verify data for that keys
00106 // should be updated
00107   
00108    Int_t len1 = (GetName()==0) ? 0 : strlen(GetName());
00109    Int_t len2 = (keyname==0) ? 0 : strlen(keyname);
00110    if (len1!=len2) return kTRUE;
00111    if ((len1>0) && (strcmp(GetName(), keyname)!=0)) return kTRUE;
00112   
00113    len1 = (GetTitle()==0) ? 0 : strlen(GetTitle());
00114    len2 = (keytitle==0) ? 0 : strlen(keytitle);
00115    if (len1!=len2) return kTRUE;
00116    if ((len1>0) && (strcmp(GetTitle(), keytitle)!=0)) return kTRUE;
00117 
00118    const char* tm = GetDatime().AsSQLString();
00119    len1 = (tm==0) ? 0 : strlen(tm);
00120    len2 = (keydatime==0) ? 0 : strlen(keydatime);
00121    if (len1!=len2) return kTRUE;
00122    if ((len1>0) && (strcmp(tm, keydatime)!=0)) return kTRUE;
00123   
00124    if (cycle!=GetCycle()) return kTRUE;
00125 
00126    len1 = (GetClassName()==0) ? 0 : strlen(GetClassName());
00127    len2 = (classname==0) ? 0 : strlen(classname);
00128    if (len1!=len2) return kTRUE;
00129    if ((len1>0) && (strcmp(GetClassName(), classname)!=0)) return kTRUE;
00130       
00131    return kFALSE;
00132 }
00133 
00134 //______________________________________________________________________________
00135 void TKeySQL::Delete(Option_t * /*option*/)
00136 {
00137 // Removes key from current directory
00138 // Note: TKeySQL object is not deleted. You still have to call "delete key"
00139 
00140    TSQLFile* f = (TSQLFile*) GetFile(); 
00141 
00142    if (f!=0)
00143       f->DeleteKeyFromDB(GetDBKeyId());
00144 
00145    fMotherDir->GetListOfKeys()->Remove(this);
00146 }
00147 
00148 //______________________________________________________________________________
00149 Long64_t TKeySQL::GetDBDirId() const
00150 {
00151    // return sql id of parent directory
00152    
00153    return GetMotherDir() ? GetMotherDir()->GetSeekDir() : 0;
00154 }
00155 
00156 //______________________________________________________________________________
00157 void TKeySQL::StoreKeyObject(const void* obj, const TClass* cl)
00158 {
00159    // Stores object, associated with key, into data tables
00160    
00161    TSQLFile* f = (TSQLFile*) GetFile(); 
00162     
00163    fCycle = GetMotherDir()->AppendKey(this);
00164 
00165    fKeyId = f->DefineNextKeyId();
00166 
00167    fObjId = f->StoreObjectInTables(fKeyId, obj, cl);
00168 
00169    if (cl) fClassName = cl->GetName();
00170    
00171    if (GetDBObjId()>=0) { 
00172       fDatime.Set();
00173       if (!f->WriteKeyData(this)) {
00174          // cannot add entry to keys table                          
00175          Error("StoreKeyObject","Cannot write data to key tables");
00176          // delete everything relevant for that key
00177          f->DeleteKeyFromDB(GetDBKeyId());
00178          fObjId = -1;
00179       }
00180    }
00181    
00182    if (GetDBObjId()<0)
00183       GetMotherDir()->GetListOfKeys()->Remove(this);
00184    // fix me !!! One should delete object by other means
00185    // delete this;
00186 }
00187 
00188 //______________________________________________________________________________
00189 Int_t TKeySQL::Read(TObject* tobj)
00190 {
00191    // To read an object from the file.
00192    // The object associated to this key is read from the file into memory.
00193    // Before invoking this function, obj has been created via the
00194    // default constructor.
00195 
00196    if (tobj==0) return 0; 
00197     
00198    void* res = ReadKeyObject(tobj, 0);
00199    
00200    return res==0 ? 0 : 1;
00201 }
00202 
00203 //______________________________________________________________________________
00204 TObject* TKeySQL::ReadObj()
00205 {
00206 // Read object derived from TObject class
00207 // If it is not TObject or in case of error, return 0
00208 
00209    TObject* tobj = (TObject*) ReadKeyObject(0, TObject::Class());
00210    
00211    if (tobj!=0) {
00212       if (gROOT->GetForceStyle()) tobj->UseCurrentStyle();
00213       if (tobj->IsA() == TDirectoryFile::Class()) {
00214          TDirectoryFile *dir = (TDirectoryFile*) tobj;
00215          dir->SetName(GetName());
00216          dir->SetTitle(GetTitle());
00217          dir->SetSeekDir(GetDBKeyId());
00218          dir->SetMother(fMotherDir);
00219          dir->ReadKeys();
00220          fMotherDir->Append(dir);
00221       }
00222    }
00223        
00224    return tobj;
00225 }
00226 
00227 //______________________________________________________________________________
00228 TObject* TKeySQL::ReadObjWithBuffer(char * /*bufferRead*/)
00229 {
00230 // Read object derived from TObject class
00231 // If it is not TObject or in case of error, return 0
00232 
00233    TObject* tobj = (TObject*) ReadKeyObject(0, TObject::Class());
00234    
00235    if (tobj!=0) {
00236       if (gROOT->GetForceStyle()) tobj->UseCurrentStyle();
00237       if (tobj->IsA() == TDirectoryFile::Class()) {
00238          TDirectoryFile *dir = (TDirectoryFile*) tobj;
00239          dir->SetName(GetName());
00240          dir->SetTitle(GetTitle());
00241          dir->SetSeekDir(GetDBKeyId());
00242          dir->SetMother(fMotherDir);
00243          dir->ReadKeys();
00244          fMotherDir->Append(dir);
00245       }
00246    }
00247        
00248    return tobj;
00249 }
00250 
00251 //______________________________________________________________________________
00252 void* TKeySQL::ReadObjectAny(const TClass* expectedClass)
00253 {
00254 // read object of any type from SQL database
00255 
00256    return ReadKeyObject(0, expectedClass);
00257 }
00258 
00259 //______________________________________________________________________________
00260 void* TKeySQL::ReadKeyObject(void* obj, const TClass* expectedClass)
00261 {
00262    // Read object, associated with key, from database
00263 
00264    TSQLFile* f = (TSQLFile*) GetFile(); 
00265 
00266    if ((GetDBKeyId()<=0) || (f==0)) return obj;
00267 
00268    TBufferSQL2 buffer(TBuffer::kRead, f);
00269    
00270    TClass* cl = 0;
00271 
00272    void* res = buffer.SqlReadAny(GetDBKeyId(), GetDBObjId(), &cl, obj);
00273    
00274    if ((cl==0) || (res==0)) return 0;
00275    
00276    Int_t delta = 0;
00277    
00278    if (expectedClass!=0) {
00279       delta = cl->GetBaseClassOffset(expectedClass);
00280       if (delta<0) {
00281          if (obj==0) cl->Destructor(res);
00282          return 0;
00283       }
00284       if (cl->GetClassInfo() && !expectedClass->GetClassInfo()) {
00285          //we cannot mix a compiled class with an emulated class in the inheritance
00286          Warning("XmlReadAny",
00287                  "Trying to read an emulated class (%s) to store in a compiled pointer (%s)",
00288                  cl->GetName(),expectedClass->GetName());
00289       }
00290    }
00291    
00292    return ((char*)res) + delta;
00293 }

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