46 TTreeSQL::TTreeSQL(TSQLServer *server, TString DB,
const TString& table) :
47 TTree(table.Data(),
"Database read from table: " + table, 0), fDB(DB),
51 fBranchChecked(kFALSE),
55 fQuery = TString(
"Select * from " + fTable);
59 Error(
"TTreeSQL",
"No TSQLServer specified");
62 if (CheckTable(fTable.Data())) {
70 TBranch* TTreeSQL::BranchImp(
const char *,
const char *,
71 TClass *,
void *, Int_t ,
74 Fatal(
"BranchImp",
"Not implemented yet");
81 TBranch* TTreeSQL::BranchImp(
const char *, TClass *,
82 void *, Int_t , Int_t )
84 Fatal(
"BranchImp",
"Not implemented yet");
90 Int_t TTreeSQL::Branch(TCollection *, Int_t,
93 Fatal(
"Branch",
"Not implemented yet");
100 Int_t TTreeSQL::Branch(TList *, Int_t, Int_t)
102 Fatal(
"Branch",
"Not implemented yet");
109 Int_t TTreeSQL::Branch(
const char *, Int_t ,
112 Fatal(
"Branch",
"Not implemented yet");
119 TBranch* TTreeSQL::Bronch(
const char *,
const char *,
void *,
122 Fatal(
"Bronch",
"Not implemented yet");
129 TBranch* TTreeSQL::BranchOld(
const char *,
const char *,
130 void *, Int_t, Int_t)
132 Fatal(
"BranchOld",
"Not implemented yet");
139 TBranch *TTreeSQL::Branch(
const char *,
const char *,
void *,
142 Fatal(
"Branch",
"Not implemented yet");
149 TBranch * TTreeSQL::Branch(
const char *name,
void *address,
150 const char *leaflist, Int_t bufsize)
152 Int_t nb = fBranches.GetEntriesFast();
156 for (
int i=0;i<nb;i++) {
157 branch = (TBranch*)fBranches.UncheckedAt(i);
158 brName = branch->GetName();
159 if (brName.CompareTo(name) == 0) {
165 Fatal(
"Branch()",
"Duplicate branch!!!");
175 return TTree::Branch(name, address, leaflist, bufsize);
181 void TTreeSQL::CheckBasket(TBranch *branch)
183 TBasketSQL* basket = (TBasketSQL *)branch->GetBasket(0);
186 basket = (TBasketSQL*)CreateBasket(branch);
187 if (basket==0)
return;
189 branch->GetListOfBaskets()->AddAtAndExpand(basket,0);
191 TBuffer * buffer = basket->GetBufferRef();
194 std::vector<Int_t> *columns = GetColumnIndice(branch);
195 if (columns) basket->CreateBuffer(branch->GetName(),
"A", columns, branch, &fResult);
198 Int_t nb = branch->GetListOfBranches()->GetEntriesFast();
199 for (
int i=0;i<nb;i++) {
200 TBranch * subbranch = (TBranch*)branch->GetListOfBranches()->UncheckedAt(i);
201 if(subbranch) CheckBasket(subbranch);
209 Bool_t TTreeSQL::CheckBranch(TBranch * tb)
218 TString typeName =
"";
220 if (!tb)
return kFALSE;
222 TBasketSQL *basket = (TBasketSQL *)tb->GetBasket(0);
223 if (!basket)
return kFALSE;
225 TSQLResult *rs = basket->GetResultSet();
227 Error(
"CheckBranch",
"%s has basket but no resultset yet",tb->GetName());
231 nl = tb->GetNleaves();
233 for(
int j=0;j<nl;j++) {
234 leaf = (TLeaf*)tb->GetListOfLeaves()->UncheckedAt(j);
235 typeName = leaf->GetTypeName();
236 typeName = ConvertTypeName(leaf->GetTypeName());
237 leafName = leaf->GetName();
243 for (
int i=0; i< rs->GetFieldCount(); ++i) {
244 if (str.CompareTo(rs->GetFieldName(i),TString::kIgnoreCase) == 0)
return kTRUE;
249 CreateBranch(str, typeName);
257 Bool_t TTreeSQL::CheckTable(
const TString &table)
const
259 if (fServer==0)
return kFALSE;
260 TSQLResult * tables = fServer->GetTables(fDB.Data(),table);
261 if (!tables)
return kFALSE;
263 while( (row = tables->Next()) ) {
264 if(table.CompareTo(row->GetField(0),TString::kIgnoreCase)==0){
269 Int_t before = gErrorIgnoreLevel;
270 gErrorIgnoreLevel = kFatal;
271 TSQLResult *res = fServer->GetColumns(fDB.Data(),table);
276 gErrorIgnoreLevel = before;
284 TString TTreeSQL::ConvertTypeName(
const TString& typeName )
288 if(typeName ==
"Char_t"){
291 else if(typeName ==
"Int_t") {
294 else if(typeName ==
"Short_t") {
297 else if( typeName ==
"UShort_t") {
298 tn =
"SMALLINT UNSIGNED";
300 else if(typeName ==
"Float_t"){
303 else if(typeName ==
"Float16_t"){
306 else if(typeName ==
"Double_t"){
309 else if(typeName ==
"Double32_t"){
312 else if(typeName ==
"UInt_t") {
315 else if( typeName ==
"Long_t") {
318 else if( typeName ==
"ULong_t") {
319 tn =
"INTEGER UNSIGNED";
321 else if( typeName ==
"Long64_t") {
324 else if( typeName ==
"ULong64_t") {
325 tn =
"BIGINT UNSIGNED";
327 else if( typeName ==
"Bool_t") {
330 else if( typeName ==
"TString") {
335 Error(
"ConvertTypeName",
"TypeName (%s) not found",typeName.Data());
345 TBasket * TTreeSQL::CreateBasket(TBranch * tb)
348 Error(
"CreateBasket",
"No TSQLServer specified");
351 std::vector<Int_t> *columnVec = GetColumnIndice(tb);
353 return new TBasketSQL(tb->GetName(), tb->GetName(), tb,
354 &fResult, &fInsertQuery, columnVec, &fRow);
363 void TTreeSQL::CreateBranch(
const TString &branchName,
const TString &typeName)
366 Error(
"CreateBranch",
"No TSQLServer specified");
369 TString alterSQL =
"";
371 alterSQL =
"ALTER TABLE ";
372 alterSQL += fTable.Data();
374 alterSQL += branchName.Data();;
376 alterSQL += typeName;
379 fServer->Query(alterSQL);
385 void TTreeSQL::CreateBranches()
387 TList * columns = fTableInfo->GetColumns();
396 TSQLColumnInfo * info;
397 while ( (info = ((TSQLColumnInfo*) next()) ))
399 type = info->GetTypeName();
400 branchName = info->GetName();
404 if ((pos=branchName.Index(
"__"))!=kNPOS) {
405 leafName = branchName(pos+2,branchName.Length());
406 branchName.Remove(pos);
408 leafName = branchName;
419 if(type.CompareTo(
"varchar",TString::kIgnoreCase)==0 ||
420 type.CompareTo(
"varchar2",TString::kIgnoreCase)==0 ||
421 type.CompareTo(
"char",TString::kIgnoreCase)==0 ||
422 type.CompareTo(
"longvarchar",TString::kIgnoreCase)==0 ||
423 type.CompareTo(
"longvarbinary",TString::kIgnoreCase)==0 ||
424 type.CompareTo(
"varbinary",TString::kIgnoreCase)==0 ||
425 type.CompareTo(
"text",TString::kIgnoreCase )==0 ) {
426 br = TTree::Branch(leafName,&str);
429 else if(type.CompareTo(
"int",TString::kIgnoreCase)==0 ){
430 br = TTree::Branch(leafName,&i);
435 else if( type.CompareTo(
"date",TString::kIgnoreCase)==0 ||
436 type.CompareTo(
"time",TString::kIgnoreCase)==0 ||
437 type.CompareTo(
"timestamp",TString::kIgnoreCase)==0 ||
438 type.CompareTo(
"datetime",TString::kIgnoreCase)==0 ) {
439 br = TTree::Branch(leafName,&str);
443 else if(type.CompareTo(
"bit",TString::kIgnoreCase)==0 ||
444 type.CompareTo(
"tinyint",TString::kIgnoreCase)==0 ||
445 type.CompareTo(
"smallint",TString::kIgnoreCase)==0 ) {
446 br = TTree::Branch(leafName,&ui);
449 else if( type.CompareTo(
"decimal",TString::kIgnoreCase)==0 ||
450 type.CompareTo(
"numeric",TString::kIgnoreCase)==0 ||
451 type.CompareTo(
"double",TString::kIgnoreCase)==0 ||
452 type.CompareTo(
"float",TString::kIgnoreCase)==0 )
454 br = TTree::Branch(leafName,&f);
456 else if( type.CompareTo(
"bigint",TString::kIgnoreCase)==0 ||
457 type.CompareTo(
"real",TString::kIgnoreCase) == 0)
459 br = TTree::Branch(leafName,&d);
464 Error(
"CreateBranches",
"Skipped %s", branchName.Data());
470 (br->GetBasketEntry())[0] = 0;
471 (br->GetBasketEntry())[1] = fEntries;
472 br->SetEntries(fEntries);
475 br->GetListOfBaskets()->AddAtAndExpand(CreateBasket(br),0);
482 Bool_t TTreeSQL::CreateTable(
const TString &table)
485 Error(
"CreateTable",
"No TSQLServer specified");
489 TString branchName, leafName, typeName;
490 TString createSQL, alterSQL, str;
491 Int_t nb = fBranches.GetEntriesFast();
498 branch = (TBranch*)fBranches.UncheckedAt(i);
499 branchName = branch->GetName();
500 nl = branch->GetNleaves();
502 leaf = (TLeaf*)branch->GetListOfLeaves()->UncheckedAt(j);
503 leafName = leaf->GetName();
504 typeName = ConvertTypeName(leaf->GetTypeName());
507 if(i == 0 && j == 0) {
509 createSQL +=
"CREATE TABLE ";
512 createSQL += branchName;
514 createSQL += leafName;
516 createSQL += typeName;
520 TSQLResult *sres = fServer->Query(createSQL.Data());
522 Error(
"CreateTable",
"May have failed");
531 CreateBranch(str, typeName);
537 fResult = fServer->Query(fQuery.Data());
544 void TTreeSQL::Init()
551 fResult = fServer->Query(fQuery.Data());
555 fServer->SelectDataBase(fDB);
557 fTableInfo = fServer->GetTableInfo(fTable);
564 Int_t TTreeSQL::Fill()
566 Int_t nb = fBranches.GetEntriesFast();
570 if (fServer==0)
return 0;
572 if(!CheckTable(fTable.Data())) {
573 if (!CreateTable(fTable.Data())) {
580 for (
int i=0;i<nb;i++) {
581 branch = (TBranch*)fBranches.UncheckedAt(i);
585 if (!fBranchChecked) {
586 for(
int i=0;i<nb;i++) {
587 branch = (TBranch*)fBranches.UncheckedAt(i);
588 if (!CheckBranch(branch)) {
589 Error(
"Fill",
"CheckBranch for %s failed",branch->GetName());
592 fBranchChecked = kTRUE;
598 if (fInsertQuery[fInsertQuery.Length()-1]!=
'(') {
599 fInsertQuery.Remove(fInsertQuery.Length()-1);
601 TSQLResult *res = fServer?fServer->Query(fInsertQuery):0;
604 return res->GetRowCount();
616 std::vector<Int_t> *TTreeSQL::GetColumnIndice(TBranch *branch)
618 if (!CheckTable(fTable))
return 0;
620 std::vector<Int_t> *columns =
new std::vector<Int_t>;
622 Int_t nl = branch->GetNleaves();
624 std::vector<TString> names;
626 TList *col_list = fTableInfo->GetColumns();
632 std::pair<TString,Int_t> value;
634 TIter next(col_list);
635 TSQLColumnInfo * cinfo;
637 while ((cinfo = (TSQLColumnInfo*) next())) {
638 names.push_back( cinfo->GetName() );
642 for(
int j=0;j<nl;j++) {
645 TLeaf *leaf = (TLeaf*)branch->GetListOfLeaves()->UncheckedAt(j);
646 TString leafName = leaf->GetName();
650 str = branch->GetName();
653 for (Int_t i=0;i<rows;++i) {
654 if (str.CompareTo(names[i],TString::kIgnoreCase)==0) {
661 for (Int_t i=0;i<rows;++i) {
662 if (str.CompareTo(names[i],TString::kIgnoreCase)==0) {
669 columns->push_back(col);
670 }
else Error(
"GetColumnIndice",
"Error finding column %d %s",j,str.Data());
672 if (columns->empty()) {
682 Long64_t TTreeSQL::GetEntries()
const
684 if (fServer==0)
return GetEntriesFast();
685 if (!CheckTable(fTable.Data()))
return 0;
687 TTreeSQL* thisvar =
const_cast<TTreeSQL*
>(
this);
692 TString counting =
"select count(*) from " + fTable;
693 TSQLResult *count = fServer->Query(counting);
696 thisvar->fEntries = 0;
698 TSQLRow * row = count->Next();
700 TString val = row->GetField(0);
702 sscanf(val.Data(),
"%ld",&(ret) );
703 thisvar->fEntries = ret;
705 thisvar->fEntries = 0;
715 Long64_t TTreeSQL::GetEntriesFast()
const
723 Int_t TTreeSQL::GetEntry(Long64_t entry, Int_t getall)
725 if (PrepEntry(entry)>=0)
return TTree::GetEntry(entry,getall);
732 Long64_t TTreeSQL::LoadTree(Long64_t entry)
735 return PrepEntry(entry);
741 Long64_t TTreeSQL::PrepEntry(Long64_t entry)
743 if (entry < 0 || entry >= fEntries || fServer==0)
return 0;
746 if(entry == fCurrentEntry)
return entry;
748 if(entry < fCurrentEntry || fResult==0){
750 fResult = fServer->Query(fQuery.Data());
754 Bool_t reset =
false;
755 while ( fResult && fCurrentEntry < entry ) {
758 fRow = fResult->Next();
759 if (fRow==0 && !reset) {
761 fResult = fServer->Query(fQuery.Data());
766 if (fRow==0)
return -1;
790 void TTreeSQL::Refresh()
795 delete fResult; fResult = 0;
796 delete fRow; fRow = 0;
802 void TTreeSQL::ResetQuery()
804 fInsertQuery =
"INSERT INTO " + fTable +
" VALUES (";
811 TTreeSQL::~TTreeSQL()