#include "TSQLObjectData.h"
#include "TObjArray.h"
#include "TNamed.h"
#include "TList.h"
#include "TSQLRow.h"
#include "TSQLResult.h"
#include "TSQLClassInfo.h"
#include "TSQLStructure.h"
#include "TSQLStatement.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() :
TObject(),
fInfo(0),
fObjId(0),
fOwner(kFALSE),
fClassData(0),
fBlobData(0),
fBlobStmt(0),
fLocatedColumn(-1),
fClassRow(0),
fBlobRow(0),
fLocatedField(0),
fLocatedValue(0),
fCurrentBlob(kFALSE),
fBlobPrefixName(0),
fBlobTypeName(0),
fUnpack(0)
{
}
TSQLObjectData::TSQLObjectData(TSQLClassInfo* sqlinfo,
Long64_t objid,
TSQLResult* classdata,
TSQLRow* classrow,
TSQLResult* blobdata,
TSQLStatement* blobstmt) :
TObject(),
fInfo(sqlinfo),
fObjId(objid),
fOwner(kFALSE),
fClassData(classdata),
fBlobData(blobdata),
fBlobStmt(blobstmt),
fLocatedColumn(-1),
fClassRow(classrow),
fBlobRow(0),
fLocatedField(0),
fLocatedValue(0),
fCurrentBlob(kFALSE),
fBlobPrefixName(0),
fBlobTypeName(0),
fUnpack(0)
{
if ((fClassData!=0) && (fClassRow==0)) {
fOwner = kTRUE;
fClassRow = fClassData->Next();
}
ShiftBlobRow();
}
TSQLObjectData::~TSQLObjectData()
{
if ((fClassData!=0) && fOwner) delete fClassData;
if (fClassRow!=0) delete fClassRow;
if (fBlobRow!=0) delete fBlobRow;
if (fBlobData!=0) delete fBlobData;
if (fUnpack!=0) { fUnpack->Delete(); delete fUnpack; }
if (fBlobStmt!=0) delete fBlobStmt;
}
Int_t TSQLObjectData::GetNumClassFields()
{
if (fClassData!=0) return fClassData->GetFieldCount();
return 0;
}
const char* TSQLObjectData::GetClassFieldName(Int_t n)
{
if (fClassData!=0) return fClassData->GetFieldName(n);
return 0;
}
Bool_t TSQLObjectData::LocateColumn(const char* colname, Bool_t isblob)
{
if (fUnpack!=0) {
fUnpack->Delete();
delete fUnpack;
fUnpack = 0;
}
fLocatedField = 0;
fLocatedValue = 0;
fCurrentBlob = kFALSE;
if ((fClassData==0) || (fClassRow==0)) return kFALSE;
Int_t ncol = fInfo->FindColumn(colname, kFALSE);
if (ncol>0) {
fLocatedColumn = ncol;
fLocatedField = GetClassFieldName(ncol);
fLocatedValue = fClassRow->GetField(ncol);
}
if (fLocatedField==0) return kFALSE;
if (!isblob) return kTRUE;
if ((fBlobRow==0) && (fBlobStmt==0)) return kFALSE;
fCurrentBlob = kTRUE;
ExtractBlobValues();
return kTRUE;
}
Bool_t TSQLObjectData::ShiftBlobRow()
{
if (fBlobStmt!=0) {
Bool_t res = fBlobStmt->NextResultRow();
if (!res) { delete fBlobStmt; fBlobStmt = 0; }
return res;
}
delete fBlobRow;
fBlobRow = fBlobData ? fBlobData->Next() : 0;
return fBlobRow!=0;
}
Bool_t TSQLObjectData::ExtractBlobValues()
{
const char* name = 0;
Bool_t hasdata = kFALSE;
if (fBlobStmt!=0) {
name = fBlobStmt->GetString(0);
fLocatedValue = fBlobStmt->GetString(1);
hasdata = kTRUE;
}
if (!hasdata) {
if (fBlobRow!=0) {
fLocatedValue = fBlobRow->GetField(1);
name = fBlobRow->GetField(0);
}
}
if (name==0) {
fBlobPrefixName = 0;
fBlobTypeName = 0;
return kFALSE;
}
const char* separ = strstr(name, ":");
if (separ==0) {
fBlobPrefixName = 0;
fBlobTypeName = name;
} else {
fBlobPrefixName = name;
separ+=strlen(":");
fBlobTypeName = separ;
}
return kTRUE;
}
void TSQLObjectData::AddUnpack(const char* tname, const char* value)
{
TNamed* str = new TNamed(tname, value);
if (fUnpack==0) {
fUnpack = new TObjArray();
fBlobPrefixName = 0;
fBlobTypeName = str->GetName();
fLocatedValue = str->GetTitle();
}
fUnpack->Add(str);
}
void TSQLObjectData::AddUnpackInt(const char* tname, Int_t value)
{
TString sbuf;
sbuf.Form("%d", value);
AddUnpack(tname, sbuf.Data());
}
void TSQLObjectData::ShiftToNextValue()
{
Bool_t doshift = kTRUE;
if (fUnpack!=0) {
TObject* prev = fUnpack->First();
fUnpack->Remove(prev);
delete prev;
fUnpack->Compress();
if (fUnpack->GetLast()>=0) {
TNamed* curr = (TNamed*) fUnpack->First();
fBlobPrefixName = 0;
fBlobTypeName = curr->GetName();
fLocatedValue = curr->GetTitle();
return;
}
delete fUnpack;
fUnpack = 0;
doshift = kFALSE;
}
if (fCurrentBlob) {
if (doshift) ShiftBlobRow();
ExtractBlobValues();
} else
if (fClassData!=0) {
if (doshift) fLocatedColumn++;
if (fLocatedColumn<GetNumClassFields()) {
fLocatedField = GetClassFieldName(fLocatedColumn);
fLocatedValue = fClassRow->GetField(fLocatedColumn);
} else {
fLocatedField = 0;
fLocatedValue = 0;
}
}
}
Bool_t TSQLObjectData::VerifyDataType(const char* tname, Bool_t errormsg)
{
if (tname==0) {
if (errormsg)
Error("VerifyDataType","Data type not specified");
return kFALSE;
}
if (!IsBlobData()) return kTRUE;
if (gDebug>4)
if ((fBlobTypeName==0) && errormsg) {
Error("VerifyDataType","fBlobTypeName is null");
return kFALSE;
}
TString v1(fBlobTypeName);
TString v2(tname);
if (v1!=v2) {
if (errormsg)
Error("VerifyDataType","Data type missmatch %s - %s", fBlobTypeName, tname);
return kFALSE;
}
return kTRUE;
}
Bool_t TSQLObjectData::PrepareForRawData()
{
if (!ExtractBlobValues()) return kFALSE;
fCurrentBlob = kTRUE;
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;
}