#include "TKeySQL.h"
#include "TROOT.h"
#include "TClass.h"
#include "TBrowser.h"
#include "Riostream.h"
#include "TSQLResult.h"
#include "TBufferSQL2.h"
#include "TSQLStructure.h"
#include "TSQLFile.h"
#include <stdlib.h>
ClassImp(TKeySQL);
TKeySQL::TKeySQL() :
TKey(),
fKeyId(-1),
fObjId(-1)
{
}
TKeySQL::TKeySQL(TDirectory* mother, const TObject* obj, const char* name, const char* title) :
TKey(mother),
fKeyId(-1),
fObjId(-1)
{
if (name) SetName(name); else
if (obj!=0) {SetName(obj->GetName()); fClassName=obj->ClassName();}
else SetName("Noname");
if (title) SetTitle(title);
StoreKeyObject((void*)obj, obj ? obj->IsA() : 0);
}
TKeySQL::TKeySQL(TDirectory* mother, const void* obj, const TClass* cl, const char* name, const char* title) :
TKey(mother),
fKeyId(-1),
fObjId(-1)
{
if (name && *name) SetName(name);
else SetName(cl ? cl->GetName() : "Noname");
if (title) SetTitle(title);
StoreKeyObject(obj, cl);
}
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(mother),
fKeyId(keyid),
fObjId(objid)
{
SetName(name);
if (title) SetTitle(title);
TDatime dt(keydatetime);
fDatime = dt;
fCycle = cycle;
fClassName = classname;
}
TKeySQL::~TKeySQL()
{
}
Bool_t TKeySQL::IsKeyModified(const char* keyname, const char* keytitle, const char* keydatime, Int_t cycle, const char* classname)
{
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;
}
void TKeySQL::Delete(Option_t * )
{
TSQLFile* f = (TSQLFile*) GetFile();
if (f!=0)
f->DeleteKeyFromDB(GetDBKeyId());
fMotherDir->GetListOfKeys()->Remove(this);
}
Long64_t TKeySQL::GetDBDirId() const
{
return GetMotherDir() ? GetMotherDir()->GetSeekDir() : 0;
}
void TKeySQL::StoreKeyObject(const void* obj, const TClass* cl)
{
TSQLFile* f = (TSQLFile*) GetFile();
fCycle = GetMotherDir()->AppendKey(this);
fKeyId = f->DefineNextKeyId();
fObjId = f->StoreObjectInTables(fKeyId, obj, cl);
if (cl) fClassName = cl->GetName();
if (GetDBObjId()>=0) {
fDatime.Set();
if (!f->WriteKeyData(this)) {
Error("StoreKeyObject","Cannot write data to key tables");
f->DeleteKeyFromDB(GetDBKeyId());
fObjId = -1;
}
}
if (GetDBObjId()<0)
GetMotherDir()->GetListOfKeys()->Remove(this);
}
Int_t TKeySQL::Read(TObject* tobj)
{
if (tobj==0) return 0;
void* res = ReadKeyObject(tobj, 0);
return res==0 ? 0 : 1;
}
TObject* TKeySQL::ReadObj()
{
TObject* tobj = (TObject*) ReadKeyObject(0, TObject::Class());
if (tobj!=0) {
if (gROOT->GetForceStyle()) tobj->UseCurrentStyle();
if (tobj->IsA() == TDirectoryFile::Class()) {
TDirectoryFile *dir = (TDirectoryFile*) tobj;
dir->SetName(GetName());
dir->SetTitle(GetTitle());
dir->SetSeekDir(GetDBKeyId());
dir->SetMother(fMotherDir);
dir->ReadKeys();
fMotherDir->Append(dir);
}
}
return tobj;
}
TObject* TKeySQL::ReadObjWithBuffer(char * )
{
TObject* tobj = (TObject*) ReadKeyObject(0, TObject::Class());
if (tobj!=0) {
if (gROOT->GetForceStyle()) tobj->UseCurrentStyle();
if (tobj->IsA() == TDirectoryFile::Class()) {
TDirectoryFile *dir = (TDirectoryFile*) tobj;
dir->SetName(GetName());
dir->SetTitle(GetTitle());
dir->SetSeekDir(GetDBKeyId());
dir->SetMother(fMotherDir);
dir->ReadKeys();
fMotherDir->Append(dir);
}
}
return tobj;
}
void* TKeySQL::ReadObjectAny(const TClass* expectedClass)
{
return ReadKeyObject(0, expectedClass);
}
void* TKeySQL::ReadKeyObject(void* obj, const TClass* expectedClass)
{
TSQLFile* f = (TSQLFile*) GetFile();
if ((GetDBKeyId()<=0) || (f==0)) return obj;
TBufferSQL2 buffer(TBuffer::kRead, f);
TClass* cl = 0;
void* res = buffer.SqlReadAny(GetDBKeyId(), GetDBObjId(), &cl, obj);
if ((cl==0) || (res==0)) return 0;
Int_t delta = 0;
if (expectedClass!=0) {
delta = cl->GetBaseClassOffset(expectedClass);
if (delta<0) {
if (obj==0) cl->Destructor(res);
return 0;
}
if (cl->GetState() > TClass::kEmulated && expectedClass->GetState() <= TClass::kEmulated) {
Warning("XmlReadAny",
"Trying to read an emulated class (%s) to store in a compiled pointer (%s)",
cl->GetName(),expectedClass->GetName());
}
}
return ((char*)res) + delta;
}