00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "TSQLStructure.h"
00025
00026 #include "Riostream.h"
00027 #include "TMap.h"
00028 #include "TClass.h"
00029 #include "TStreamerInfo.h"
00030 #include "TStreamerElement.h"
00031 #include "TObjString.h"
00032 #include "TClonesArray.h"
00033
00034 #include "TSQLFile.h"
00035 #include "TSQLClassInfo.h"
00036 #include "TSQLObjectData.h"
00037 #include "TBufferSQL2.h"
00038
00039 #include "TSQLStatement.h"
00040 #include "TSQLServer.h"
00041 #include "TDataType.h"
00042
00043 namespace sqlio {
00044 const Int_t Ids_NullPtr = 0;
00045 const Int_t Ids_RootDir = 0;
00046 const Int_t Ids_TSQLFile = 0;
00047 const Int_t Ids_StreamerInfos = 1;
00048 const Int_t Ids_FirstKey =10;
00049 const Int_t Ids_FirstObject = 1;
00050
00051 const char* ObjectRef = "ObjectRef";
00052 const char* ObjectRef_Arr = "ObjectRefArr";
00053 const char* ObjectPtr = "ObjectPtr";
00054 const char* ObjectInst = "ObjectInst";
00055 const char* Version = "Version";
00056 const char* TObjectUniqueId = "UniqueId";
00057 const char* TObjectBits = "Bits";
00058 const char* TObjectProcessId = "ProcessId";
00059 const char* TStringValue= "StringValue";
00060 const char* IndexSepar = "..";
00061 const char* RawSuffix = ":rawdata";
00062 const char* ParentSuffix = ":parent";
00063 const char* ObjectSuffix = ":object";
00064 const char* PointerSuffix = ":pointer";
00065 const char* StrSuffix = ":str";
00066 const char* LongStrPrefix = "#~#";
00067
00068 const char* Array = "Array";
00069 const char* Bool = "Bool_t";
00070 const char* Char = "Char_t";
00071 const char* Short = "Short_t";
00072 const char* Int = "Int_t";
00073 const char* Long = "Long_t";
00074 const char* Long64 = "Long64_t";
00075 const char* Float = "Float_t";
00076 const char* Double = "Double_t";
00077 const char* UChar = "UChar_t";
00078 const char* UShort = "UShort_t";
00079 const char* UInt = "UInt_t";
00080 const char* ULong = "ULong_t";
00081 const char* ULong64 = "ULong64_t";
00082 const char* CharStar = "CharStar";
00083 const char* True = "1";
00084 const char* False = "0";
00085
00086
00087 const char* KeysTable = "KeysTable";
00088 const char* KeysTableIndex = "KeysTableIndex";
00089 const char* ObjectsTable = "ObjectsTable";
00090 const char* ObjectsTableIndex = "ObjectsTableIndex";
00091 const char* IdsTable = "IdsTable";
00092 const char* IdsTableIndex = "IdsTableIndex";
00093 const char* StringsTable = "StringsTable";
00094 const char* ConfigTable = "Configurations";
00095
00096
00097 const char* KT_Name = "Name";
00098 const char* KT_Title = "Title";
00099 const char* KT_Datetime = "Datime";
00100 const char* KT_Cycle = "Cycle";
00101 const char* KT_Class = "Class";
00102
00103 const char* DT_Create = "CreateDatime";
00104 const char* DT_Modified = "ModifiedDatime";
00105 const char* DT_UUID = "UUID";
00106
00107
00108 const char* OT_Class = "Class";
00109 const char* OT_Version = "Version";
00110
00111
00112 const char* IT_TableID = "TableId";
00113 const char* IT_SubID = "SubId";
00114 const char* IT_Type = "Type";
00115 const char* IT_FullName = "FullName";
00116 const char* IT_SQLName = "SQLName";
00117 const char* IT_Info = "Info";
00118
00119
00120 const char* BT_Field = "Field";
00121 const char* BT_Value = "Value";
00122
00123
00124 const char* ST_Value = "LongStringValue";
00125
00126
00127 const char* CT_Field = "Field";
00128 const char* CT_Value = "Value";
00129
00130
00131 const char* cfg_Version = "SQL_IO_version";
00132 const char* cfg_UseSufixes = "UseNameSuffix";
00133 const char* cfg_ArrayLimit = "ArraySizeLimit";
00134 const char* cfg_TablesType = "TablesType";
00135 const char* cfg_UseTransactions = "UseTransactions";
00136 const char* cfg_UseIndexes = "UseIndexes";
00137 const char* cfg_LockingMode = "LockingMode";
00138 const char* cfg_ModifyCounter = "ModifyCounter";
00139 };
00140
00141
00142
00143 #ifdef R__VISUAL_CPLUSPLUS
00144 #define FLong64 "%I64d"
00145 #define FULong64 "%I64u"
00146 #else
00147 #define FLong64 "%lld"
00148 #define FULong64 "%llu"
00149 #endif
00150
00151 Long64_t sqlio::atol64(const char* value)
00152 {
00153 if ((value==0) || (*value==0)) return 0;
00154 Long64_t res = 0;
00155 sscanf(value, FLong64, &res);
00156 return res;
00157 }
00158
00159
00160 ClassImp(TSQLColumnData)
00161
00162
00163 TSQLColumnData::TSQLColumnData() :
00164 TObject(),
00165 fName(),
00166 fType(),
00167 fValue(),
00168 fNumeric(kFALSE)
00169 {
00170
00171 }
00172
00173
00174 TSQLColumnData::TSQLColumnData(const char* name,
00175 const char* sqltype,
00176 const char* value,
00177 Bool_t numeric) :
00178 TObject(),
00179 fName(name),
00180 fType(sqltype),
00181 fValue(value),
00182 fNumeric(numeric)
00183 {
00184
00185
00186 }
00187
00188
00189 TSQLColumnData::TSQLColumnData(const char* name, Long64_t value) :
00190 TObject(),
00191 fName(name),
00192 fType("INT"),
00193 fValue(),
00194 fNumeric(kTRUE)
00195 {
00196
00197
00198 fValue.Form("%lld",value);
00199 }
00200
00201
00202 TSQLColumnData::~TSQLColumnData()
00203 {
00204
00205 }
00206
00207
00208 ClassImp(TSQLTableData);
00209
00210
00211 TSQLTableData::TSQLTableData(TSQLFile* f, TSQLClassInfo* info) :
00212 TObject(),
00213 fFile(f),
00214 fInfo(info),
00215 fColumns(),
00216 fColInfos(0)
00217 {
00218
00219
00220 if (!info->IsClassTableExist())
00221 fColInfos = new TObjArray;
00222 }
00223
00224
00225 TSQLTableData::~TSQLTableData()
00226 {
00227
00228
00229 fColumns.Delete();
00230 if (fColInfos!=0) {
00231 fColInfos->Delete();
00232 delete fColInfos;
00233 }
00234 }
00235
00236
00237 void TSQLTableData::AddColumn(const char* name, Long64_t value)
00238 {
00239
00240
00241 TObjString* v = new TObjString(Form("%lld",value));
00242 v->SetBit(BIT(20), kTRUE);
00243 fColumns.Add(v);
00244
00245
00246
00247
00248 if (fColInfos!=0)
00249 fColInfos->Add(new TSQLClassColumnInfo(name, DefineSQLName(name), "INT"));
00250 }
00251
00252
00253 void TSQLTableData::AddColumn(const char* name,
00254 const char* sqltype,
00255 const char* value,
00256 Bool_t numeric)
00257 {
00258
00259
00260 TObjString* v = new TObjString(value);
00261 v->SetBit(BIT(20), numeric);
00262 fColumns.Add(v);
00263
00264
00265
00266
00267 if (fColInfos!=0)
00268 fColInfos->Add(new TSQLClassColumnInfo(name, DefineSQLName(name), sqltype));
00269 }
00270
00271
00272 TString TSQLTableData::DefineSQLName(const char* fullname)
00273 {
00274
00275
00276 Int_t maxlen = fFile->SQLMaxIdentifierLength();
00277
00278 Int_t len = strlen(fullname);
00279
00280 if ((len<=maxlen) && !HasSQLName(fullname)) return TString(fullname);
00281
00282 Int_t cnt = -1;
00283 TString res, scnt;
00284
00285 do {
00286
00287 scnt.Form("%d",cnt);
00288 Int_t numlen = cnt<0 ? 0 : scnt.Length();
00289
00290 res = fullname;
00291
00292 if (len + numlen > maxlen)
00293 res.Resize(maxlen - numlen);
00294
00295 if (cnt>=0) res+=scnt;
00296
00297 if (!HasSQLName(res.Data())) return res;
00298
00299 cnt++;
00300
00301 } while (cnt<10000);
00302
00303 Error("DefineSQLName","Cannot find reasonable column name for field %s",fullname);
00304
00305 return TString(fullname);
00306 }
00307
00308
00309 Bool_t TSQLTableData::HasSQLName(const char* sqlname)
00310 {
00311
00312
00313 TIter next(fColInfos);
00314
00315 TSQLClassColumnInfo* col = 0;
00316
00317 while ((col = (TSQLClassColumnInfo*) next()) != 0) {
00318 const char* colname = col->GetSQLName();
00319 if (strcmp(colname, sqlname)==0) return kTRUE;
00320 }
00321
00322 return kFALSE;
00323
00324 }
00325
00326
00327 Int_t TSQLTableData::GetNumColumns()
00328 {
00329
00330
00331 return fColumns.GetLast() +1;
00332 }
00333
00334
00335 const char* TSQLTableData::GetColumn(Int_t n)
00336 {
00337
00338 return fColumns[n]->GetName();
00339 }
00340
00341
00342 Bool_t TSQLTableData::IsNumeric(Int_t n)
00343 {
00344
00345
00346 return fColumns[n]->TestBit(BIT(20));
00347 }
00348
00349
00350 TObjArray* TSQLTableData::TakeColInfos()
00351 {
00352
00353
00354 TObjArray* res = fColInfos;
00355 fColInfos = 0;
00356 return res;
00357 }
00358
00359
00360
00361 ClassImp(TSQLStructure);
00362
00363 TSQLStructure::TSQLStructure() :
00364 TObject(),
00365 fParent(0),
00366 fType(0),
00367 fPointer(0),
00368 fValue(),
00369 fArrayIndex(-1),
00370 fRepeatCnt(0),
00371 fChilds()
00372 {
00373
00374 }
00375
00376
00377 TSQLStructure::~TSQLStructure()
00378 {
00379
00380
00381 fChilds.Delete();
00382 if (GetType()==kSqlObjectData) {
00383 TSQLObjectData* objdata = (TSQLObjectData*) fPointer;
00384 delete objdata;
00385 } else
00386 if (GetType()==kSqlCustomElement) {
00387 TStreamerElement* elem = (TStreamerElement*) fPointer;
00388 delete elem;
00389 }
00390 }
00391
00392
00393 Int_t TSQLStructure::NumChilds() const
00394 {
00395
00396
00397 return fChilds.GetLast()+1;
00398 }
00399
00400
00401 TSQLStructure* TSQLStructure::GetChild(Int_t n) const
00402 {
00403
00404
00405 return (n<0) || (n>fChilds.GetLast()) ? 0 : (TSQLStructure*) fChilds[n];
00406 }
00407
00408
00409 void TSQLStructure::SetObjectRef(Long64_t refid, const TClass* cl)
00410 {
00411
00412
00413 fType = kSqlObject;
00414 fValue.Form("%lld",refid);
00415 fPointer = cl;
00416 }
00417
00418
00419 void TSQLStructure::SetObjectPointer(Long64_t ptrid)
00420 {
00421
00422
00423 fType = kSqlPointer;
00424 fValue.Form("%lld",ptrid);
00425 }
00426
00427
00428 void TSQLStructure::SetVersion(const TClass* cl, Int_t version)
00429 {
00430
00431
00432 fType = kSqlVersion;
00433 fPointer = cl;
00434 if (version<0) version = cl->GetClassVersion();
00435 fValue.Form("%d",version);
00436 }
00437
00438
00439 void TSQLStructure::SetClassStreamer(const TClass* cl)
00440 {
00441
00442
00443 fType = kSqlClassStreamer;
00444 fPointer = cl;
00445 }
00446
00447
00448 void TSQLStructure::SetStreamerInfo(const TStreamerInfo* info)
00449 {
00450
00451
00452 fType = kSqlStreamerInfo;
00453 fPointer = info;
00454 }
00455
00456
00457 void TSQLStructure::SetStreamerElement(const TStreamerElement* elem, Int_t number)
00458 {
00459
00460
00461 fType = kSqlElement;
00462 fPointer = elem;
00463 fArrayIndex = number;
00464 }
00465
00466
00467 void TSQLStructure::SetCustomClass(const TClass* cl, Version_t version)
00468 {
00469
00470
00471 fType = kSqlCustomClass;
00472 fPointer = (void*) cl;
00473 fArrayIndex = version;
00474 }
00475
00476
00477 void TSQLStructure::SetCustomElement(TStreamerElement* elem)
00478 {
00479
00480
00481 fType = kSqlCustomElement;
00482 fPointer = elem;
00483 }
00484
00485
00486 void TSQLStructure::SetValue(const char* value, const char* tname)
00487 {
00488
00489
00490 fType = kSqlValue;
00491 fValue = value;
00492 fPointer = tname;
00493 }
00494
00495
00496 void TSQLStructure::ChangeValueOnly(const char* value)
00497 {
00498
00499
00500
00501 fValue = value;
00502 }
00503
00504
00505 void TSQLStructure::SetArrayIndex(Int_t indx, Int_t cnt)
00506 {
00507
00508
00509 fArrayIndex = indx;
00510 fRepeatCnt = cnt;
00511 }
00512
00513
00514 void TSQLStructure::ChildArrayIndex(Int_t index, Int_t cnt)
00515 {
00516
00517
00518 TSQLStructure* last = (TSQLStructure*) fChilds.Last();
00519 if ((last!=0) && (last->GetType()==kSqlValue))
00520 last->SetArrayIndex(index, cnt);
00521 }
00522
00523
00524 void TSQLStructure::SetArray(Int_t sz)
00525 {
00526
00527
00528 fType = kSqlArray;
00529 if (sz>=0) fValue.Form("%d",sz);
00530 }
00531
00532
00533 TClass* TSQLStructure::GetObjectClass() const
00534 {
00535
00536
00537 return (fType==kSqlObject) ? (TClass*) fPointer : 0;
00538 }
00539
00540
00541 TClass* TSQLStructure::GetVersionClass() const
00542 {
00543
00544
00545 return (fType==kSqlVersion) ? (TClass*) fPointer : 0;
00546 }
00547
00548
00549 TStreamerInfo* TSQLStructure::GetStreamerInfo() const
00550 {
00551
00552
00553 return (fType==kSqlStreamerInfo) ? (TStreamerInfo*) fPointer : 0;
00554 }
00555
00556
00557 TStreamerElement* TSQLStructure::GetElement() const
00558 {
00559
00560
00561 return (fType==kSqlElement) || (fType==kSqlCustomElement) ? (TStreamerElement*) fPointer : 0;
00562 }
00563
00564
00565 Int_t TSQLStructure::GetElementNumber() const
00566 {
00567
00568
00569 return (fType==kSqlElement) ? fArrayIndex : 0;
00570 }
00571
00572
00573 const char* TSQLStructure::GetValueType() const
00574 {
00575
00576
00577 return (fType==kSqlValue) ? (const char*) fPointer : 0;
00578 }
00579
00580
00581 TClass* TSQLStructure::GetCustomClass() const
00582 {
00583
00584
00585 return (fType==kSqlCustomClass) ? (TClass*) fPointer : 0;
00586 }
00587
00588
00589 Version_t TSQLStructure::GetCustomClassVersion() const
00590 {
00591
00592
00593 return (fType==kSqlCustomClass) ? fArrayIndex : 0;
00594 }
00595
00596
00597 Bool_t TSQLStructure::GetClassInfo(TClass* &cl, Version_t &version)
00598 {
00599
00600
00601 if (GetType()==kSqlStreamerInfo) {
00602 TStreamerInfo* info = GetStreamerInfo();
00603 if (info==0) return kFALSE;
00604 cl = info->GetClass();
00605 version = info->GetClassVersion();
00606 } else
00607 if (GetType()==kSqlCustomClass) {
00608 cl = GetCustomClass();
00609 version = GetCustomClassVersion();
00610 } else
00611 return kFALSE;
00612 return kTRUE;
00613 }
00614
00615
00616 const char* TSQLStructure::GetValue() const
00617 {
00618
00619
00620
00621
00622 return fValue.Data();
00623 }
00624
00625
00626 void TSQLStructure::Add(TSQLStructure* child)
00627 {
00628
00629
00630 if (child!=0) {
00631 child->SetParent(this);
00632 fChilds.Add(child);
00633 }
00634 }
00635
00636
00637 void TSQLStructure::AddVersion(const TClass* cl, Int_t version)
00638 {
00639
00640
00641 TSQLStructure* ver = new TSQLStructure;
00642 ver->SetVersion(cl, version);
00643 Add(ver);
00644 }
00645
00646
00647 void TSQLStructure::AddValue(const char* value, const char* tname)
00648 {
00649
00650
00651 TSQLStructure* child = new TSQLStructure;
00652 child->SetValue(value, tname);
00653 Add(child);
00654 }
00655
00656
00657 Long64_t TSQLStructure::DefineObjectId(Bool_t recursive)
00658 {
00659
00660
00661
00662
00663 TSQLStructure* curr = this;
00664 while (curr!=0) {
00665 if ((curr->GetType()==kSqlObject) ||
00666 (curr->GetType()==kSqlPointer) ||
00667
00668 (curr->GetType()==kSqlElement) ||
00669 (curr->GetType()==kSqlCustomElement) ||
00670 (curr->GetType()==kSqlCustomClass) ||
00671 (curr->GetType()==kSqlStreamerInfo)) {
00672 const char* value = curr->GetValue();
00673 if ((value!=0) && (strlen(value)>0))
00674 return sqlio::atol64(value);
00675 }
00676
00677 curr = recursive ? curr->GetParent() : 0;
00678 }
00679 return -1;
00680 }
00681
00682
00683 void TSQLStructure::SetObjectData(TSQLObjectData* objdata)
00684 {
00685
00686
00687 fType = kSqlObjectData;
00688 fPointer = objdata;
00689 }
00690
00691
00692 void TSQLStructure::AddObjectData(TSQLObjectData* objdata)
00693 {
00694
00695
00696 TSQLStructure* child = new TSQLStructure;
00697 child->SetObjectData(objdata);
00698 Add(child);
00699 }
00700
00701
00702 TSQLObjectData* TSQLStructure::GetObjectData(Bool_t search)
00703 {
00704
00705
00706 TSQLStructure* child = GetChild(0);
00707 if ((child!=0) && (child->GetType()==kSqlObjectData))
00708 return (TSQLObjectData*) child->fPointer;
00709 if (search && (GetParent()!=0))
00710 return GetParent()->GetObjectData(search);
00711 return 0;
00712 }
00713
00714
00715 void TSQLStructure::Print(Option_t*) const
00716 {
00717
00718
00719 PrintLevel(0);
00720 }
00721
00722
00723 void TSQLStructure::PrintLevel(Int_t level) const
00724 {
00725
00726
00727 for(Int_t n=0;n<level;n++) cout << " ";
00728 switch (fType) {
00729 case 0: cout << "Undefined type"; break;
00730 case kSqlObject: cout << "Object ref = " << fValue; break;
00731 case kSqlPointer: cout << "Pointer ptr = " << fValue; break;
00732 case kSqlVersion: {
00733 const TClass* cl = (const TClass*) fPointer;
00734 cout << "Version cl = " << cl->GetName() << " ver = " << cl->GetClassVersion();
00735 break;
00736 }
00737 case kSqlStreamerInfo: {
00738 const TStreamerInfo* info = (const TStreamerInfo*) fPointer;
00739 cout << "Class: " << info->GetName();
00740 break;
00741 }
00742 case kSqlCustomElement:
00743 case kSqlElement: {
00744 const TStreamerElement* elem = (const TStreamerElement*) fPointer;
00745 cout << "Member: " << elem->GetName();
00746 break;
00747 }
00748 case kSqlValue: {
00749 cout << "Value: " << fValue;
00750 if (fRepeatCnt>1) cout << " cnt:" << fRepeatCnt;
00751 if (fPointer!=0) cout << " type = " << (const char*)fPointer;
00752 break;
00753 }
00754 case kSqlArray: {
00755 cout << "Array ";
00756 if (fValue.Length()>0) cout << " sz = " << fValue;
00757 break;
00758 }
00759 case kSqlCustomClass: {
00760 TClass* cl = (TClass*) fPointer;
00761 cout << "CustomClass: " << cl->GetName() << " ver = " << fValue;
00762 break;
00763 }
00764 default:
00765 cout << "Unknown type";
00766 }
00767 cout << endl;
00768
00769 for(Int_t n=0;n<NumChilds();n++)
00770 GetChild(n)->PrintLevel(level+2);
00771 }
00772
00773
00774 Bool_t TSQLStructure::IsNumericType(Int_t typ)
00775 {
00776
00777
00778 switch(typ) {
00779 case TStreamerInfo::kShort : return kTRUE;
00780 case TStreamerInfo::kInt : return kTRUE;
00781 case TStreamerInfo::kLong : return kTRUE;
00782 case TStreamerInfo::kFloat : return kTRUE;
00783 case TStreamerInfo::kFloat16 : return kTRUE;
00784 case TStreamerInfo::kCounter : return kTRUE;
00785 case TStreamerInfo::kDouble : return kTRUE;
00786 case TStreamerInfo::kDouble32: return kTRUE;
00787 case TStreamerInfo::kUChar : return kTRUE;
00788 case TStreamerInfo::kUShort : return kTRUE;
00789 case TStreamerInfo::kUInt : return kTRUE;
00790 case TStreamerInfo::kULong : return kTRUE;
00791 case TStreamerInfo::kBits : return kTRUE;
00792 case TStreamerInfo::kLong64 : return kTRUE;
00793 case TStreamerInfo::kULong64 : return kTRUE;
00794 case TStreamerInfo::kBool : return kTRUE;
00795 }
00796 return kFALSE;
00797 }
00798
00799
00800 const char* TSQLStructure::GetSimpleTypeName(Int_t typ)
00801 {
00802
00803
00804
00805 switch(typ) {
00806 case TStreamerInfo::kChar : return sqlio::Char;
00807 case TStreamerInfo::kShort : return sqlio::Short;
00808 case TStreamerInfo::kInt : return sqlio::Int;
00809 case TStreamerInfo::kLong : return sqlio::Long;
00810 case TStreamerInfo::kFloat : return sqlio::Float;
00811 case TStreamerInfo::kFloat16 : return sqlio::Float;
00812 case TStreamerInfo::kCounter : return sqlio::Int;
00813 case TStreamerInfo::kDouble : return sqlio::Double;
00814 case TStreamerInfo::kDouble32: return sqlio::Double;
00815 case TStreamerInfo::kUChar : return sqlio::UChar;
00816 case TStreamerInfo::kUShort : return sqlio::UShort;
00817 case TStreamerInfo::kUInt : return sqlio::UInt;
00818 case TStreamerInfo::kULong : return sqlio::ULong;
00819 case TStreamerInfo::kBits : return sqlio::UInt;
00820 case TStreamerInfo::kLong64 : return sqlio::Long64;
00821 case TStreamerInfo::kULong64 : return sqlio::ULong64;
00822 case TStreamerInfo::kBool : return sqlio::Bool;
00823 }
00824
00825 return 0;
00826 }
00827
00828
00829
00830
00831
00832
00833
00834 class TSqlCmdsBuffer : public TObject {
00835
00836 public:
00837 TSqlCmdsBuffer(TSQLFile* f, TSQLClassInfo* info) :
00838 TObject(),
00839 fFile(f),
00840 fInfo(info),
00841 fBlobStmt(0),
00842 fNormStmt(0)
00843 {
00844 }
00845
00846 virtual ~TSqlCmdsBuffer()
00847 {
00848 fNormCmds.Delete();
00849 fBlobCmds.Delete();
00850 fFile->SQLDeleteStatement(fBlobStmt);
00851 fFile->SQLDeleteStatement(fNormStmt);
00852 }
00853
00854 void AddValues(Bool_t isnorm, const char* values)
00855 {
00856 TObjString* str = new TObjString(values);
00857 if (isnorm) fNormCmds.Add(str);
00858 else fBlobCmds.Add(str);
00859 }
00860
00861 TSQLFile* fFile;
00862 TSQLClassInfo* fInfo;
00863 TObjArray fNormCmds;
00864 TObjArray fBlobCmds;
00865 TSQLStatement* fBlobStmt;
00866 TSQLStatement* fNormStmt;
00867 };
00868
00869
00870
00871
00872
00873 class TSqlRegistry : public TObject {
00874
00875 public:
00876 TSqlRegistry() :
00877 TObject(),
00878 f(0),
00879 fKeyId(0),
00880 fLastObjId(-1),
00881 fCmds(0),
00882 fFirstObjId(0),
00883 fCurrentObjId(0),
00884 fCurrentObjClass(0),
00885 fLastLongStrId(0),
00886 fPool(),
00887 fLongStrValues(),
00888 fRegValues(),
00889 fRegStmt(0)
00890 {
00891 }
00892
00893 TSQLFile* f;
00894 Long64_t fKeyId;
00895 Long64_t fLastObjId;
00896 TObjArray* fCmds;
00897 Long64_t fFirstObjId;
00898
00899 Long64_t fCurrentObjId;
00900 TClass* fCurrentObjClass;
00901
00902 Int_t fLastLongStrId;
00903
00904 TMap fPool;
00905 TObjArray fLongStrValues;
00906 TObjArray fRegValues;
00907
00908 TSQLStatement* fRegStmt;
00909
00910
00911 virtual ~TSqlRegistry()
00912 {
00913 fPool.DeleteValues();
00914 fLongStrValues.Delete();
00915 fRegValues.Delete();
00916 f->SQLDeleteStatement(fRegStmt);
00917 }
00918
00919 Long64_t GetNextObjId() { return ++fLastObjId; }
00920
00921 void AddSqlCmd(const char* query)
00922 {
00923
00924 if (fCmds==0) fCmds = new TObjArray;
00925 fCmds->Add(new TObjString(query));
00926 }
00927
00928 TSqlCmdsBuffer* GetCmdsBuffer(TSQLClassInfo* sqlinfo)
00929 {
00930 if (sqlinfo==0) return 0;
00931 TSqlCmdsBuffer* buf = (TSqlCmdsBuffer*) fPool.GetValue(sqlinfo);
00932 if (buf==0) {
00933 buf = new TSqlCmdsBuffer(f, sqlinfo);
00934 fPool.Add(sqlinfo, buf);
00935 }
00936 return buf;
00937 }
00938
00939 void ConvertSqlValues(TObjArray& values, const char* tablename)
00940 {
00941
00942
00943
00944
00945 if ((values.GetLast()<0) || (tablename==0)) return;
00946
00947 Bool_t canbelong = f->IsMySQL();
00948
00949 Int_t maxsize = 50000;
00950 TString sqlcmd(maxsize), value, onecmd, cmdmask;
00951
00952 const char* quote = f->SQLIdentifierQuote();
00953
00954 TIter iter(&values);
00955 TObject* cmd = 0;
00956 while ((cmd = iter())!=0) {
00957
00958 if (sqlcmd.Length()==0)
00959 sqlcmd.Form("INSERT INTO %s%s%s VALUES (%s)",
00960 quote, tablename, quote, cmd->GetName());
00961 else {
00962 sqlcmd+=", (";
00963 sqlcmd += cmd->GetName();
00964 sqlcmd+=")";
00965 }
00966
00967 if (!canbelong || (sqlcmd.Length()>maxsize*0.9)) {
00968 AddSqlCmd(sqlcmd.Data());
00969 sqlcmd = "";
00970 }
00971 }
00972
00973 if (sqlcmd.Length()>0) AddSqlCmd(sqlcmd.Data());
00974 }
00975
00976 void ConvertPoolValues()
00977 {
00978 TSQLClassInfo* sqlinfo = 0;
00979 TIter iter(&fPool);
00980 while ((sqlinfo = (TSQLClassInfo*) iter())!=0) {
00981 TSqlCmdsBuffer* buf = (TSqlCmdsBuffer*) fPool.GetValue(sqlinfo);
00982 if (buf==0) continue;
00983 ConvertSqlValues(buf->fNormCmds, sqlinfo->GetClassTableName());
00984
00985 if (buf->fBlobCmds.GetLast()>=0) f->CreateRawTable(sqlinfo);
00986 ConvertSqlValues(buf->fBlobCmds, sqlinfo->GetRawTableName());
00987 if (buf->fBlobStmt)
00988 buf->fBlobStmt->Process();
00989 if (buf->fNormStmt)
00990 buf->fNormStmt->Process();
00991 }
00992
00993 ConvertSqlValues(fLongStrValues, sqlio::StringsTable);
00994 ConvertSqlValues(fRegValues, sqlio::ObjectsTable);
00995 if (fRegStmt) fRegStmt->Process();
00996 }
00997
00998
00999 void AddRegCmd(Long64_t objid, TClass* cl)
01000 {
01001 Long64_t indx = objid-fFirstObjId;
01002 if (indx<0) {
01003 Error("AddRegCmd","Something wrong with objid = %lld", objid);
01004 return;
01005 }
01006
01007 if (f->IsOracle() || f->IsODBC()) {
01008 if ((fRegStmt==0) && f->SQLCanStatement()) {
01009 const char* quote = f->SQLIdentifierQuote();
01010
01011 TString sqlcmd;
01012 const char* pars = f->IsOracle() ? ":1, :2, :3, :4" : "?, ?, ?, ?";
01013 sqlcmd.Form("INSERT INTO %s%s%s VALUES (%s)",
01014 quote, sqlio::ObjectsTable, quote, pars);
01015 fRegStmt = f->SQLStatement(sqlcmd.Data(), 1000);
01016 }
01017
01018 if (fRegStmt!=0) {
01019 fRegStmt->NextIteration();
01020 fRegStmt->SetLong64(0, fKeyId);
01021 fRegStmt->SetLong64(1, objid);
01022 fRegStmt->SetString(2, cl->GetName(), f->SQLSmallTextTypeLimit());
01023 fRegStmt->SetInt(3, cl->GetClassVersion());
01024 return;
01025 }
01026 }
01027
01028 const char* valuequote = f->SQLValueQuote();
01029 TString cmd;
01030 cmd.Form("%lld, %lld, %s%s%s, %d",
01031 fKeyId, objid,
01032 valuequote, cl->GetName(), valuequote,
01033 cl->GetClassVersion());
01034 fRegValues.AddAtAndExpand(new TObjString(cmd), indx);
01035 }
01036
01037 Int_t AddLongString(const char* strvalue)
01038 {
01039
01040
01041
01042 if (fLastLongStrId==0) f->VerifyLongStringTable();
01043 Int_t strid = ++fLastLongStrId;
01044 TString value = strvalue;
01045 const char* valuequote = f->SQLValueQuote();
01046 TSQLStructure::AddStrBrackets(value, valuequote);
01047
01048 TString cmd;
01049 cmd.Form("%lld, %d, %s", fCurrentObjId, strid, value.Data());
01050
01051 fLongStrValues.Add(new TObjString(cmd));
01052
01053 return strid;
01054 }
01055
01056 Bool_t InsertToNormalTableOracle(TSQLTableData* columns, TSQLClassInfo* sqlinfo)
01057 {
01058 TSqlCmdsBuffer* buf = GetCmdsBuffer(sqlinfo);
01059 if (buf==0) return kFALSE;
01060
01061 TSQLStatement* stmt = buf->fNormStmt;
01062 if (stmt==0) {
01063
01064 if (!f->SQLCanStatement()) return kFALSE;
01065
01066 const char* quote = f->SQLIdentifierQuote();
01067 TString sqlcmd;
01068 sqlcmd.Form("INSERT INTO %s%s%s VALUES (",
01069 quote, sqlinfo->GetClassTableName(), quote);
01070 for (int n=0;n<columns->GetNumColumns();n++) {
01071 if (n>0) sqlcmd +=", ";
01072 if (f->IsOracle()) {
01073 sqlcmd += ":";
01074 sqlcmd += (n+1);
01075 } else
01076 sqlcmd += "?";
01077 }
01078 sqlcmd += ")";
01079
01080 stmt = f->SQLStatement(sqlcmd.Data(), 1000);
01081 if (stmt==0) return kFALSE;
01082 buf->fNormStmt = stmt;
01083 }
01084
01085 stmt->NextIteration();
01086
01087 Int_t sizelimit = f->SQLSmallTextTypeLimit();
01088
01089 for (Int_t ncol=0;ncol<columns->GetNumColumns();ncol++) {
01090 const char* value = columns->GetColumn(ncol);
01091 if (value==0) value = "";
01092 stmt->SetString(ncol, value, sizelimit);
01093 }
01094
01095 return kTRUE;
01096 }
01097
01098 void InsertToNormalTable(TSQLTableData* columns, TSQLClassInfo* sqlinfo)
01099 {
01100
01101
01102 if (f->IsOracle() || f->IsODBC())
01103 if (InsertToNormalTableOracle(columns, sqlinfo))
01104 return;
01105
01106 const char* valuequote = f->SQLValueQuote();
01107
01108 TString values;
01109
01110 for (Int_t n=0;n<columns->GetNumColumns();n++) {
01111 if (n>0) values+=", ";
01112
01113 if (columns->IsNumeric(n))
01114 values+=columns->GetColumn(n);
01115 else {
01116 TString value = columns->GetColumn(n);
01117 TSQLStructure::AddStrBrackets(value, valuequote);
01118 values += value;
01119 }
01120 }
01121
01122 TSqlCmdsBuffer* buf = GetCmdsBuffer(sqlinfo);
01123 if (buf!=0) buf->AddValues(kTRUE, values.Data());
01124 }
01125 };
01126
01127
01128
01129
01130
01131
01132
01133
01134 class TSqlRawBuffer : public TObject {
01135
01136 public:
01137
01138 TSqlRawBuffer(TSqlRegistry* reg, TSQLClassInfo* sqlinfo) :
01139 TObject(),
01140 fFile(0),
01141 fInfo(0),
01142 fCmdBuf(0),
01143 fObjId(0),
01144 fRawId(0),
01145 fValueMask(),
01146 fValueQuote(0),
01147 fMaxStrSize(255)
01148 {
01149 fFile = reg->f;
01150 fInfo = sqlinfo;
01151 fCmdBuf = reg->GetCmdsBuffer(sqlinfo);
01152 fObjId = reg->fCurrentObjId;
01153 fValueQuote = fFile->SQLValueQuote();
01154 fValueMask.Form("%lld, %s, %s%s%s, %s", fObjId, "%d", fValueQuote, "%s", fValueQuote, "%s");
01155 fMaxStrSize = reg->f->SQLSmallTextTypeLimit();
01156 }
01157
01158 virtual ~TSqlRawBuffer()
01159 {
01160
01161 TSQLStatement* stmt = fCmdBuf->fBlobStmt;
01162 if ((stmt!=0) && fFile->IsOracle()) {
01163 stmt->Process();
01164 delete stmt;
01165 fCmdBuf->fBlobStmt = 0;
01166 }
01167 }
01168
01169 Bool_t IsAnyData() const { return fRawId>0; }
01170
01171 void AddLine(const char* name, const char* value, const char* topname = 0, const char* ns = 0)
01172 {
01173 if (fCmdBuf==0) return;
01174
01175
01176 if (fRawId==0) {
01177 Bool_t maketmt = kFALSE;
01178 if (fFile->IsOracle() || fFile->IsODBC())
01179 maketmt = (fCmdBuf->fBlobStmt==0) && fFile->SQLCanStatement();
01180
01181 if (maketmt) {
01182
01183 fFile->CreateRawTable(fInfo);
01184
01185 const char* quote = fFile->SQLIdentifierQuote();
01186 TString sqlcmd;
01187 const char* params = fFile->IsOracle() ? ":1, :2, :3, :4" : "?, ?, ?, ?";
01188 sqlcmd.Form("INSERT INTO %s%s%s VALUES (%s)",
01189 quote, fInfo->GetRawTableName(), quote, params);
01190 TSQLStatement* stmt = fFile->SQLStatement(sqlcmd.Data(), 2000);
01191 fCmdBuf->fBlobStmt = stmt;
01192 }
01193 }
01194
01195 TString buf;
01196 const char* fullname = name;
01197 if ((topname!=0) && (ns!=0)) {
01198 buf+=topname;
01199 buf+=ns;
01200 buf+=name;
01201 fullname = buf.Data();
01202 }
01203
01204 TSQLStatement* stmt = fCmdBuf->fBlobStmt;
01205
01206 if (stmt!=0) {
01207 stmt->NextIteration();
01208 stmt->SetLong64(0, fObjId);
01209 stmt->SetInt(1, fRawId++);
01210 stmt->SetString(2, fullname, fMaxStrSize);
01211
01212 stmt->SetString(3, value, fMaxStrSize);
01213 } else {
01214 TString valuebuf(value);
01215 TSQLStructure::AddStrBrackets(valuebuf, fValueQuote);
01216 TString cmd;
01217 cmd.Form(fValueMask.Data(), fRawId++, fullname, valuebuf.Data());
01218 fCmdBuf->AddValues(kFALSE, cmd.Data());
01219 }
01220 }
01221
01222 TSQLFile* fFile;
01223 TSQLClassInfo* fInfo;
01224 TSqlCmdsBuffer* fCmdBuf;
01225 Long64_t fObjId;
01226 Int_t fRawId;
01227 TString fValueMask;
01228 const char* fValueQuote;
01229 Int_t fMaxStrSize;
01230 };
01231
01232
01233 Long64_t TSQLStructure::FindMaxObjectId()
01234 {
01235
01236
01237 Long64_t max = DefineObjectId(kFALSE);
01238
01239 for (Int_t n=0;n<NumChilds();n++) {
01240 Long64_t zn = GetChild(n)->FindMaxObjectId();
01241 if (zn>max) max = zn;
01242 }
01243
01244 return max;
01245 }
01246
01247
01248 Bool_t TSQLStructure::ConvertToTables(TSQLFile* file, Long64_t keyid, TObjArray* cmds)
01249 {
01250
01251
01252
01253
01254
01255 if ((file==0) || (cmds==0)) return kFALSE;
01256
01257 TSqlRegistry reg;
01258
01259 reg.fCmds = cmds;
01260 reg.f = file;
01261 reg.fKeyId = keyid;
01262
01263 reg.fFirstObjId = DefineObjectId(kFALSE);
01264
01265 reg.fLastObjId = FindMaxObjectId();
01266
01267 Bool_t res = StoreObject(®, reg.fFirstObjId, GetObjectClass());
01268
01269
01270 reg.ConvertPoolValues();
01271
01272 return res;
01273 }
01274
01275
01276 void TSQLStructure::PerformConversion(TSqlRegistry* reg, TSqlRawBuffer* blobs, const char* topname, Bool_t useblob)
01277 {
01278
01279
01280
01281
01282 TString sbuf;
01283 const char* ns = reg->f->SQLNameSeparator();
01284
01285 switch (fType) {
01286 case kSqlObject: {
01287
01288 if (!StoreObject(reg, DefineObjectId(kFALSE), GetObjectClass())) break;
01289
01290 blobs->AddLine(sqlio::ObjectRef, GetValue(), topname, ns);
01291
01292 break;
01293 }
01294
01295 case kSqlPointer: {
01296 blobs->AddLine(sqlio::ObjectPtr, fValue.Data(), topname,ns);
01297 break;
01298 }
01299
01300 case kSqlVersion: {
01301 if (fPointer!=0)
01302 topname = ((TClass*) fPointer)->GetName();
01303 else
01304 Error("PerformConversion","version without class");
01305 blobs->AddLine(sqlio::Version, fValue.Data(), topname, ns);
01306 break;
01307 }
01308
01309 case kSqlStreamerInfo: {
01310
01311 TStreamerInfo* info = GetStreamerInfo();
01312 if (info==0) return;
01313
01314 if (useblob) {
01315 for(Int_t n=0;n<=fChilds.GetLast();n++) {
01316 TSQLStructure* child = (TSQLStructure*) fChilds.At(n);
01317 child->PerformConversion(reg, blobs, info->GetName(), useblob);
01318 }
01319 } else {
01320 Long64_t objid = reg->GetNextObjId();
01321 TString sobjid;
01322 sobjid.Form("%lld",objid);
01323 if (!StoreObject(reg, objid, info->GetClass(), kTRUE)) return;
01324 blobs->AddLine(sqlio::ObjectInst, sobjid.Data(), topname, ns);
01325 }
01326 break;
01327 }
01328
01329 case kSqlCustomElement:
01330 case kSqlElement: {
01331 const TStreamerElement* elem = (const TStreamerElement*) fPointer;
01332
01333 Int_t indx = 0;
01334 while (indx<NumChilds()) {
01335 TSQLStructure* child = GetChild(indx++);
01336 child->PerformConversion(reg, blobs, elem->GetName(), useblob);
01337 }
01338 break;
01339 }
01340
01341 case kSqlValue: {
01342 const char* tname = (const char*) fPointer;
01343 if (fArrayIndex>=0) {
01344 if (fRepeatCnt>1)
01345 sbuf.Form("%s%d%s%d%s%s%s", "[", fArrayIndex, sqlio::IndexSepar, fArrayIndex+fRepeatCnt-1, "]", ns, tname);
01346 else
01347 sbuf.Form("%s%d%s%s%s", "[", fArrayIndex, "]", ns, tname);
01348 } else {
01349 if (tname!=0) sbuf = tname;
01350 else sbuf = "Value";
01351 }
01352
01353 TString buf;
01354 const char* value = fValue.Data();
01355
01356 if ((tname==sqlio::CharStar) && (value!=0)) {
01357 Int_t size = strlen(value);
01358 if (size > reg->f->SQLSmallTextTypeLimit()) {
01359 Int_t strid = reg->AddLongString(value);
01360 buf = reg->f->CodeLongString(reg->fCurrentObjId, strid);
01361 value = buf.Data();
01362 }
01363 }
01364
01365 blobs->AddLine(sbuf.Data(), value, (fArrayIndex>=0) ? 0 : topname, ns);
01366
01367 break;
01368 }
01369
01370 case kSqlArray: {
01371 if (fValue.Length()>0)
01372 blobs->AddLine(sqlio::Array, fValue.Data(), topname, ns);
01373 for(Int_t n=0;n<=fChilds.GetLast();n++) {
01374 TSQLStructure* child = (TSQLStructure*) fChilds.At(n);
01375 child->PerformConversion(reg, blobs, topname, useblob);
01376 }
01377 break;
01378 }
01379 }
01380 }
01381
01382
01383 Bool_t TSQLStructure::StoreObject(TSqlRegistry* reg, Long64_t objid, TClass* cl, Bool_t registerobj)
01384 {
01385
01386
01387
01388
01389 if ((cl==0) || (objid<0)) return kFALSE;
01390
01391 if (gDebug>1) {
01392 cout << "Store object " << objid <<" cl = " << cl->GetName() << endl;
01393 if (GetStreamerInfo()) cout << "Info = " << GetStreamerInfo()->GetName() << endl; else
01394 if (GetElement()) cout << "Element = " << GetElement()->GetName() << endl;
01395 }
01396
01397 Long64_t oldid = reg->fCurrentObjId;
01398 TClass* oldcl = reg->fCurrentObjClass;
01399
01400 reg->fCurrentObjId = objid;
01401 reg->fCurrentObjClass = cl;
01402
01403 Bool_t normstore = kFALSE;
01404
01405 Bool_t res = kTRUE;
01406
01407 if (cl==TObject::Class())
01408 normstore = StoreTObject(reg);
01409 else
01410 if (cl==TString::Class())
01411 normstore = StoreTString(reg);
01412 else
01413 if (GetType()==kSqlStreamerInfo)
01414
01415
01416
01417 normstore = StoreClassInNormalForm(reg);
01418 else
01419 normstore = StoreObjectInNormalForm(reg);
01420
01421 if (gDebug>2)
01422 cout << "Store object " << objid << " of class " << cl->GetName() << " normal = " << normstore << " sqltype = " << GetType() << endl;
01423
01424 if (!normstore) {
01425
01426
01427
01428 TSQLClassInfo* sqlinfo = reg->f->RequestSQLClassInfo(cl);
01429 TSqlRawBuffer rawdata(reg, sqlinfo);
01430
01431 for(Int_t n=0;n<NumChilds();n++) {
01432 TSQLStructure* child = GetChild(n);
01433 child->PerformConversion(reg, &rawdata, 0 );
01434 }
01435
01436 res = rawdata.IsAnyData();
01437 }
01438
01439 if (registerobj)
01440 reg->AddRegCmd(objid, cl);
01441
01442 reg->fCurrentObjId = oldid;
01443 reg->fCurrentObjClass = oldcl;
01444
01445 return res;
01446 }
01447
01448
01449 Bool_t TSQLStructure::StoreObjectInNormalForm(TSqlRegistry* reg)
01450 {
01451
01452
01453
01454 if (fChilds.GetLast()!=1) return kFALSE;
01455
01456 TSQLStructure* s_ver = GetChild(0);
01457
01458 TSQLStructure* s_info = GetChild(1);
01459
01460 if (!CheckNormalClassPair(s_ver, s_info)) return kFALSE;
01461
01462 return s_info->StoreClassInNormalForm(reg);
01463 }
01464
01465
01466 Bool_t TSQLStructure::StoreClassInNormalForm(TSqlRegistry* reg)
01467 {
01468
01469
01470
01471 TClass* cl = 0;
01472 Version_t version = 0;
01473 if (!GetClassInfo(cl, version)) return kFALSE;
01474 if (cl==0) return kFALSE;
01475
01476 TSQLClassInfo* sqlinfo = reg->f->RequestSQLClassInfo(cl->GetName(), version);
01477
01478 TSQLTableData columns(reg->f, sqlinfo);
01479 Bool_t needblob = kFALSE;
01480
01481 TSqlRawBuffer rawdata(reg, sqlinfo);
01482
01483
01484
01485
01486 columns.AddColumn(reg->f->SQLObjectIdColumn(), reg->fCurrentObjId);
01487
01488 for(Int_t n=0;n<=fChilds.GetLast();n++) {
01489 TSQLStructure* child = (TSQLStructure*) fChilds.At(n);
01490 TStreamerElement* elem = child->GetElement();
01491
01492 if (elem==0) {
01493 Error("StoreClassInNormalForm", "CAN NOT BE");
01494 continue;
01495 }
01496
01497 if (child->StoreElementInNormalForm(reg, &columns)) continue;
01498
01499 Int_t columntyp = DefineElementColumnType(elem, reg->f);
01500 if ((columntyp!=kColRawData) && (columntyp!=kColObjectArray)) {
01501 Error("StoreClassInNormalForm","Element %s typ=%d has problem with normal store ", elem->GetName(), columntyp);
01502 continue;
01503 }
01504
01505
01506 Bool_t doblobs = kTRUE;
01507
01508 Int_t blobid = rawdata.fRawId;
01509
01510 if (columntyp==kColObjectArray)
01511 if (child->TryConvertObjectArray(reg, &rawdata))
01512 doblobs = kFALSE;
01513
01514 if (doblobs)
01515 child->PerformConversion(reg, &rawdata, elem->GetName(), kFALSE);
01516
01517 if (blobid==rawdata.fRawId)
01518 blobid = -1;
01519 else {
01520
01521
01522
01523 needblob = kTRUE;
01524 }
01525
01526
01527 TString blobname = elem->GetName();
01528 if (reg->f->GetUseSuffixes())
01529 blobname += sqlio::RawSuffix;
01530
01531 columns.AddColumn(blobname, blobid);
01532 }
01533
01534 reg->f->CreateClassTable(sqlinfo, columns.TakeColInfos());
01535
01536 reg->InsertToNormalTable(&columns, sqlinfo);
01537
01538 return kTRUE;
01539 }
01540
01541
01542 TString TSQLStructure::MakeArrayIndex(TStreamerElement* elem, Int_t index)
01543 {
01544
01545
01546 TString res;
01547 if ((elem==0) || (elem->GetArrayLength()==0)) return res;
01548
01549 for(Int_t ndim=elem->GetArrayDim()-1;ndim>=0;ndim--) {
01550 Int_t ix = index % elem->GetMaxIndex(ndim);
01551 index = index / elem->GetMaxIndex(ndim);
01552 TString buf;
01553 buf.Form("%s%d%s","[",ix,"]");
01554 res = buf + res;
01555 }
01556 return res;
01557 }
01558
01559
01560 Bool_t TSQLStructure::StoreElementInNormalForm(TSqlRegistry* reg, TSQLTableData* columns)
01561 {
01562
01563
01564 TStreamerElement* elem = GetElement();
01565 if (elem==0) return kFALSE;
01566
01567 Int_t typ = elem->GetType();
01568
01569 Int_t columntyp = DefineElementColumnType(elem, reg->f);
01570
01571 if (gDebug>4)
01572 cout << "Element " << elem->GetName()
01573 << " type = " << typ
01574 << " column = " << columntyp << endl;
01575
01576 TString colname = DefineElementColumnName(elem, reg->f);
01577
01578 if (columntyp==kColTString) {
01579 const char* value;
01580 if (!RecognizeTString(value)) return kFALSE;
01581
01582 Int_t len = value ? strlen(value) : 0;
01583
01584 Int_t sizelimit = reg->f->SQLSmallTextTypeLimit();
01585
01586 const char* stype = reg->f->SQLSmallTextType();
01587
01588 if (len<=sizelimit)
01589 columns->AddColumn(colname.Data(), stype, value, kFALSE);
01590 else {
01591 Int_t strid = reg->AddLongString(value);
01592 TString buf = reg->f->CodeLongString(reg->fCurrentObjId, strid);
01593 columns->AddColumn(colname.Data(), stype, buf.Data(), kFALSE);
01594 }
01595
01596 return kTRUE;
01597 }
01598
01599 if (columntyp==kColParent) {
01600 Long64_t objid = reg->fCurrentObjId;
01601 TClass* basecl = elem->GetClassPointer();
01602 Int_t resversion = basecl->GetClassVersion();
01603 if (!StoreObject(reg, objid, basecl, kFALSE))
01604 resversion = -1;
01605 columns->AddColumn(colname.Data(), resversion);
01606 return kTRUE;
01607 }
01608
01609 if (columntyp==kColObject) {
01610
01611 Long64_t objid = -1;
01612
01613 if (NumChilds()==1) {
01614 TSQLStructure* child = GetChild(0);
01615
01616 if (child->GetType()==kSqlObject) {
01617 objid = child->DefineObjectId(kFALSE);
01618 if (!child->StoreObject(reg, objid, child->GetObjectClass())) return kFALSE;
01619 } else
01620 if (child->GetType()==kSqlPointer) {
01621 TString sobjid = child->GetValue();
01622 if (sobjid.Length()>0)
01623 objid = sqlio::atol64(sobjid.Data());
01624 }
01625 }
01626
01627 if (objid<0) {
01628
01629 objid = reg->GetNextObjId();
01630 if (!StoreObject(reg, objid, elem->GetClassPointer()))
01631 objid = -1;
01632 }
01633
01634 columns->AddColumn(colname.Data(), objid);
01635 return kTRUE;
01636 }
01637
01638 if (columntyp==kColNormObject) {
01639
01640 if (NumChilds()!=1) {
01641 Error("kColNormObject","NumChilds()=%d", NumChilds());
01642 PrintLevel(20);
01643 return kFALSE;
01644 }
01645 TSQLStructure* child = GetChild(0);
01646 if ((child->GetType()!=kSqlPointer) && (child->GetType()!=kSqlObject)) return kFALSE;
01647
01648 Bool_t normal = kTRUE;
01649
01650 Long64_t objid = -1;
01651
01652 if (child->GetType()==kSqlObject) {
01653 objid = child->DefineObjectId(kFALSE);
01654 normal = child->StoreObject(reg, objid, child->GetObjectClass());
01655 } else {
01656 objid = child->DefineObjectId(kFALSE);
01657 }
01658
01659 if (!normal) {
01660 Error("kColNormObject","child->StoreObject fails");
01661 return kFALSE;
01662 }
01663
01664 columns->AddColumn(colname.Data(), objid);
01665 return kTRUE;
01666 }
01667
01668 if (columntyp==kColNormObjectArray) {
01669
01670 if (elem->GetArrayLength()!=NumChilds()) return kFALSE;
01671
01672 for (Int_t index=0;index<NumChilds();index++) {
01673 TSQLStructure* child = GetChild(index);
01674 if ((child->GetType()!=kSqlPointer) &&
01675 (child->GetType()!=kSqlObject)) return kFALSE;
01676 Bool_t normal = kTRUE;
01677
01678 Long64_t objid = child->DefineObjectId(kFALSE);
01679
01680 if (child->GetType()==kSqlObject)
01681 normal = child->StoreObject(reg, objid, child->GetObjectClass());
01682
01683 if (!normal) return kFALSE;
01684
01685 colname = DefineElementColumnName(elem, reg->f, index);
01686
01687 columns->AddColumn(colname.Data(), objid);
01688 }
01689 return kTRUE;
01690 }
01691
01692 if (columntyp==kColObjectPtr) {
01693 if (NumChilds()!=1) return kFALSE;
01694 TSQLStructure* child = GetChild(0);
01695 if ((child->GetType()!=kSqlPointer) && (child->GetType()!=kSqlObject)) return kFALSE;
01696
01697 Bool_t normal = kTRUE;
01698 Long64_t objid = -1;
01699
01700 if (child->GetType()==kSqlObject) {
01701 objid = child->DefineObjectId(kFALSE);
01702 normal = child->StoreObject(reg, objid, child->GetObjectClass());
01703 }
01704
01705 if (!normal) return kFALSE;
01706
01707 columns->AddColumn(colname.Data(), objid);
01708 return kTRUE;
01709 }
01710
01711 if (columntyp==kColSimple) {
01712
01713
01714 if (NumChilds()!=1) {
01715 Error("StoreElementInNormalForm","Enexpected number %d for simple element %s", NumChilds(), elem->GetName());
01716 return kFALSE;
01717 }
01718
01719 TSQLStructure* child = GetChild(0);
01720 if (child->GetType()!=kSqlValue) return kFALSE;
01721
01722 const char* value = child->GetValue();
01723 if (value==0) return kFALSE;
01724
01725 const char* sqltype = reg->f->SQLCompatibleType(typ);
01726
01727 columns->AddColumn(colname.Data(), sqltype, value, IsNumericType(typ));
01728
01729 return kTRUE;
01730 }
01731
01732 if (columntyp==kColSimpleArray) {
01733
01734
01735 if (NumChilds()!=1) {
01736 Error("StoreElementInNormalForm","In fixed array %s only array node should be", elem->GetName());
01737 return kFALSE;
01738 }
01739 TSQLStructure* arr = GetChild(0);
01740
01741 const char* sqltype = reg->f->SQLCompatibleType(typ % 20);
01742
01743 for(Int_t n=0;n<arr->NumChilds();n++) {
01744 TSQLStructure* child = arr->GetChild(n);
01745 if (child->GetType()!=kSqlValue) return kFALSE;
01746
01747 const char* value = child->GetValue();
01748 if (value==0) return kFALSE;
01749
01750 Int_t index = child->GetArrayIndex();
01751 Int_t last = index + child->GetRepeatCounter();
01752
01753 while (index<last) {
01754 colname = DefineElementColumnName(elem, reg->f, index);
01755 columns->AddColumn(colname.Data(), sqltype, value, kTRUE);
01756 index++;
01757 }
01758 }
01759 return kTRUE;
01760 }
01761
01762 return kFALSE;
01763 }
01764
01765
01766 Bool_t TSQLStructure::TryConvertObjectArray(TSqlRegistry* reg, TSqlRawBuffer* blobs)
01767 {
01768
01769
01770
01771
01772
01773 TStreamerElement* elem = GetElement();
01774 if (elem==0) return kFALSE;
01775
01776 if (NumChilds() % 2 !=0) return kFALSE;
01777
01778 Int_t indx = 0;
01779
01780 while (indx<NumChilds()) {
01781 TSQLStructure* s_ver = GetChild(indx++);
01782 TSQLStructure* s_info = GetChild(indx++);
01783 if (!CheckNormalClassPair(s_ver, s_info)) return kFALSE;
01784 }
01785
01786 indx = 0;
01787 const char* ns = reg->f->SQLNameSeparator();
01788
01789 while (indx<NumChilds()-1) {
01790 indx++;
01791 TSQLStructure* s_info = GetChild(indx++);
01792 TClass* cl = 0;
01793 Version_t version = 0;
01794 if (!s_info->GetClassInfo(cl, version)) return kFALSE;
01795 Long64_t objid = reg->GetNextObjId();
01796 if (!s_info->StoreObject(reg, objid, cl))
01797 objid = -1;
01798
01799 TString sobjid;
01800 sobjid.Form("%lld", objid);
01801
01802 blobs->AddLine(sqlio::ObjectRef_Arr, sobjid.Data(), elem->GetName(), ns);
01803 }
01804
01805 return kTRUE;
01806 }
01807
01808
01809 Bool_t TSQLStructure::CheckNormalClassPair(TSQLStructure* s_ver, TSQLStructure* s_info)
01810 {
01811
01812
01813
01814 if ((s_ver==0) || (s_info==0) || (s_ver->GetType()!=kSqlVersion)) return kFALSE;
01815
01816 TClass* ver_cl = s_ver->GetVersionClass();
01817
01818 TClass* info_cl = 0;
01819 Version_t info_ver = 0;
01820 if (!s_info->GetClassInfo(info_cl, info_ver)) return kFALSE;
01821
01822 if ((ver_cl==0) || (info_cl==0) || (ver_cl!=info_cl) ||
01823 (ver_cl->GetClassVersion()!=info_ver)) return kFALSE;
01824
01825 return kTRUE;
01826 }
01827
01828
01829 Bool_t TSQLStructure::StoreTObject(TSqlRegistry* reg)
01830 {
01831
01832
01833
01834
01835 if ((NumChilds()<3) || (NumChilds()>4)) return kFALSE;
01836
01837 TSQLStructure* str_ver = GetChild(0);
01838 TSQLStructure* str_id = GetChild(1);
01839 TSQLStructure* str_bits = GetChild(2);
01840 TSQLStructure* str_prid = GetChild(3);
01841
01842 if (str_ver->GetType()!=kSqlVersion) return kFALSE;
01843 if ((str_id->GetType()!=kSqlValue) ||
01844 (str_id->GetValueType()!=sqlio::UInt)) return kFALSE;
01845 if ((str_bits->GetType()!=kSqlValue) ||
01846 (str_bits->GetValueType()!=sqlio::UInt)) return kFALSE;
01847 if (str_prid!=0)
01848 if ((str_prid->GetType()!=kSqlValue) ||
01849 (str_prid->GetValueType()!=sqlio::UShort)) return kFALSE;
01850
01851 TSQLClassInfo* sqlinfo = reg->f->RequestSQLClassInfo(TObject::Class());
01852
01853 if (sqlinfo==0) return kFALSE;
01854
01855 TSQLTableData columns(reg->f, sqlinfo);
01856
01857 const char* uinttype = reg->f->SQLCompatibleType(TStreamerInfo::kUInt);
01858
01859 columns.AddColumn(reg->f->SQLObjectIdColumn(), reg->fCurrentObjId);
01860
01861 columns.AddColumn(sqlio::TObjectUniqueId, uinttype, str_id->GetValue(), kTRUE);
01862 columns.AddColumn(sqlio::TObjectBits, uinttype, str_bits->GetValue(), kTRUE);
01863 columns.AddColumn(sqlio::TObjectProcessId, "CHAR(3)", (str_prid ? str_prid->GetValue() : ""), kFALSE);
01864
01865 reg->f->CreateClassTable(sqlinfo, columns.TakeColInfos());
01866
01867 reg->InsertToNormalTable(&columns, sqlinfo);
01868
01869 return kTRUE;
01870 }
01871
01872
01873 Bool_t TSQLStructure::StoreTString(TSqlRegistry* reg)
01874 {
01875
01876
01877
01878 const char* value = 0;
01879 if (!RecognizeTString(value)) return kFALSE;
01880
01881 TSQLClassInfo* sqlinfo = reg->f->RequestSQLClassInfo(TString::Class());
01882 if (sqlinfo==0) return kFALSE;
01883
01884 TSQLTableData columns(reg->f, sqlinfo);
01885
01886 columns.AddColumn(reg->f->SQLObjectIdColumn(), reg->fCurrentObjId);
01887 columns.AddColumn(sqlio::TStringValue, reg->f->SQLBigTextType(), value, kFALSE);
01888
01889 reg->f->CreateClassTable(sqlinfo, columns.TakeColInfos());
01890
01891 reg->InsertToNormalTable(&columns, sqlinfo);
01892 return kTRUE;
01893 }
01894
01895
01896 Bool_t TSQLStructure::RecognizeTString(const char* &value)
01897 {
01898
01899
01900 value = 0;
01901
01902 if ((NumChilds()==0) || (NumChilds()>3)) return kFALSE;
01903
01904 TSQLStructure *len=0, *lenbig=0, *chars=0;
01905 for (Int_t n=0;n<NumChilds();n++) {
01906 TSQLStructure* curr = GetChild(n);
01907 if (curr->fType!=kSqlValue) return kFALSE;
01908 if (curr->fPointer==sqlio::UChar) {
01909 if (len==0) len=curr; else return kFALSE;
01910 } else
01911 if (curr->fPointer==sqlio::Int) {
01912 if (lenbig==0) lenbig=curr; else return kFALSE;
01913 } else
01914 if (curr->fPointer==sqlio::CharStar) {
01915 if (chars==0) chars=curr; else return kFALSE;
01916 } else return kFALSE;
01917 }
01918
01919 if (len==0) return kFALSE;
01920 if ((lenbig!=0) && ((chars==0) || (len==0))) return kFALSE;
01921
01922 if (chars!=0)
01923 value = chars->GetValue();
01924
01925 return kTRUE;
01926 }
01927
01928
01929 Int_t TSQLStructure::DefineElementColumnType(TStreamerElement* elem, TSQLFile* f)
01930 {
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941 if (elem==0) return kColUnknown;
01942
01943 Int_t typ = elem->GetType();
01944
01945 if (typ == TStreamerInfo::kMissing) return kColRawData;
01946
01947 if ((typ>0) && (typ<20) &&
01948 (typ!=TStreamerInfo::kCharStar)) return kColSimple;
01949
01950 if ((typ>TStreamerInfo::kOffsetL) &&
01951 (typ<TStreamerInfo::kOffsetP))
01952 if ((f->GetArrayLimit()<0) ||
01953 (elem->GetArrayLength()<=f->GetArrayLimit()))
01954 return kColSimpleArray;
01955
01956 if (typ==TStreamerInfo::kTObject) {
01957 if (elem->InheritsFrom(TStreamerBase::Class()))
01958 return kColParent;
01959 else
01960 return kColObject;
01961 }
01962
01963 if (typ==TStreamerInfo::kTNamed) {
01964 if (elem->InheritsFrom(TStreamerBase::Class()))
01965 return kColParent;
01966 else
01967 return kColObject;
01968 }
01969
01970 if (typ==TStreamerInfo::kTString) return kColTString;
01971
01972 if (typ==TStreamerInfo::kBase) return kColParent;
01973
01974 if (typ==TStreamerInfo::kSTL)
01975 if (elem->InheritsFrom(TStreamerBase::Class()))
01976 return kColParent;
01977
01978
01979
01980 if ((typ==TStreamerInfo::kObject) ||
01981 (typ==TStreamerInfo::kAny)) {
01982 if (elem->GetArrayLength()==0)
01983 return kColObject;
01984 else
01985 if (elem->GetStreamer()==0)
01986 return kColObjectArray;
01987 }
01988
01989 if ((typ==TStreamerInfo::kObject) ||
01990 (typ==TStreamerInfo::kAny) ||
01991 (typ==TStreamerInfo::kAnyp) ||
01992 (typ==TStreamerInfo::kObjectp) ||
01993 (typ==TStreamerInfo::kAnyP) ||
01994 (typ==TStreamerInfo::kObjectP)) {
01995 if ((elem->GetArrayLength()==0) ||
01996 (elem->GetStreamer()!=0))
01997 return kColNormObject;
01998 else
01999 return kColNormObjectArray;
02000 }
02001
02002 if ((typ==TStreamerInfo::kObject + TStreamerInfo::kOffsetL) ||
02003 (typ==TStreamerInfo::kAny + TStreamerInfo::kOffsetL) ||
02004 (typ==TStreamerInfo::kAnyp + TStreamerInfo::kOffsetL) ||
02005 (typ==TStreamerInfo::kObjectp + TStreamerInfo::kOffsetL) ||
02006 (typ==TStreamerInfo::kAnyP + TStreamerInfo::kOffsetL) ||
02007 (typ==TStreamerInfo::kObjectP + TStreamerInfo::kOffsetL)) {
02008 if (elem->GetStreamer()!=0)
02009 return kColNormObject;
02010 else
02011 return kColNormObjectArray;
02012 }
02013
02014 if ((typ==TStreamerInfo::kObject) ||
02015 (typ==TStreamerInfo::kAny) ||
02016 (typ==TStreamerInfo::kAnyp) ||
02017 (typ==TStreamerInfo::kObjectp) ||
02018 (typ==TStreamerInfo::kSTL)) {
02019 if (elem->GetArrayLength()==0)
02020 return kColObject;
02021 else
02022 if (elem->GetStreamer()==0)
02023 return kColObjectArray;
02024 }
02025
02026 if (((typ==TStreamerInfo::kAnyP) ||
02027 (typ==TStreamerInfo::kObjectP)) &&
02028 (elem->GetArrayDim()==0)) return kColObjectPtr;
02029
02030
02031
02032
02033
02034
02035
02036
02037 return kColRawData;
02038 }
02039
02040
02041 TString TSQLStructure::DefineElementColumnName(TStreamerElement* elem, TSQLFile* f, Int_t indx)
02042 {
02043
02044
02045 TString colname = "";
02046
02047 Int_t coltype = DefineElementColumnType(elem, f);
02048 if (coltype==kColUnknown) return colname;
02049
02050 const char* elemname = elem->GetName();
02051
02052 switch (coltype) {
02053 case kColSimple: {
02054 colname = elemname;
02055 if (f->GetUseSuffixes()) {
02056 colname+=f->SQLNameSeparator();
02057 colname+=GetSimpleTypeName(elem->GetType());
02058 }
02059 break;
02060 }
02061
02062 case kColSimpleArray: {
02063 colname = elemname;
02064 colname+=MakeArrayIndex(elem, indx);
02065 break;
02066 }
02067
02068 case kColParent: {
02069 colname = elemname;
02070 if (f->GetUseSuffixes())
02071 colname+=sqlio::ParentSuffix;
02072 break;
02073 }
02074
02075 case kColNormObject: {
02076 colname = elemname;
02077 if (f->GetUseSuffixes())
02078 colname += sqlio::ObjectSuffix;
02079 break;
02080 }
02081
02082 case kColNormObjectArray: {
02083 colname = elemname;
02084 colname+=MakeArrayIndex(elem, indx);
02085 if (f->GetUseSuffixes())
02086 colname += sqlio::ObjectSuffix;
02087 break;
02088 }
02089
02090 case kColObject: {
02091 colname = elemname;
02092 if (f->GetUseSuffixes())
02093 colname += sqlio::ObjectSuffix;
02094 break;
02095 }
02096
02097 case kColObjectPtr: {
02098 colname = elemname;
02099 if (f->GetUseSuffixes())
02100 colname += sqlio::PointerSuffix;
02101 break;
02102 }
02103
02104 case kColTString: {
02105 colname = elem->GetName();
02106 if (f->GetUseSuffixes())
02107 colname+=sqlio::StrSuffix;
02108 break;
02109 }
02110
02111 case kColRawData: {
02112 colname = elemname;
02113 if (f->GetUseSuffixes())
02114 colname += sqlio::RawSuffix;
02115 break;
02116 }
02117
02118 case kColObjectArray: {
02119 colname = elemname;
02120 if (f->GetUseSuffixes())
02121 colname += sqlio::RawSuffix;
02122 break;
02123 }
02124 }
02125
02126 return colname;
02127 }
02128
02129
02130 Int_t TSQLStructure::LocateElementColumn(TSQLFile* f, TBufferSQL2* buf, TSQLObjectData* data)
02131 {
02132
02133
02134 TStreamerElement* elem = GetElement();
02135 if ((elem==0) || (data==0)) return kColUnknown;
02136
02137 Int_t coltype = DefineElementColumnType(elem, f);
02138
02139 if (gDebug>4)
02140 cout <<"TSQLStructure::LocateElementColumn " << elem->GetName() <<
02141 " coltyp = " << coltype << " : " << elem->GetType() << " len = " << elem->GetArrayLength() << endl;
02142
02143 if (coltype==kColUnknown) return kColUnknown;
02144
02145 const char* elemname = elem->GetName();
02146 Bool_t located = kFALSE;
02147
02148 TString colname = DefineElementColumnName(elem, f);
02149
02150 if (gDebug>4)
02151 cout << " colname = " << colname << " in " <<
02152 data->GetInfo()->GetClassTableName() << endl;
02153
02154 switch (coltype) {
02155 case kColSimple: {
02156 located = data->LocateColumn(colname.Data());
02157 break;
02158 }
02159
02160 case kColSimpleArray: {
02161 located = data->LocateColumn(colname);
02162 break;
02163 }
02164
02165 case kColParent: {
02166 located = data->LocateColumn(colname.Data());
02167 if (located==kColUnknown) return kColUnknown;
02168
02169 Long64_t objid = DefineObjectId(kTRUE);
02170 const char* clname = elemname;
02171 Version_t version = atoi(data->GetValue());
02172
02173
02174 if (version<0) break;
02175
02176
02177 if (strcmp(clname,TObject::Class()->GetName())==0) {
02178 UnpackTObject(f, buf, data, objid, version);
02179 break;
02180 }
02181
02182 TSQLClassInfo* sqlinfo = f->FindSQLClassInfo(clname, version);
02183 if (sqlinfo==0) return kColUnknown;
02184
02185
02186 if (sqlinfo->IsClassTableExist()) {
02187 data->AddUnpackInt(sqlio::Version, version);
02188 } else {
02189 TSQLObjectData* objdata = buf->SqlObjectData(objid, sqlinfo);
02190 if ((objdata==0) || !objdata->PrepareForRawData()) return kColUnknown;
02191 AddObjectData(objdata);
02192 }
02193
02194 break;
02195 }
02196
02197
02198
02199
02200
02201
02202
02203
02204 case kColObject: {
02205 located = data->LocateColumn(colname.Data());
02206 if (located==kColUnknown) return located;
02207
02208 const char* strobjid = data->GetValue();
02209 if (strobjid==0) return kColUnknown;
02210
02211 Long64_t objid = sqlio::atol64(strobjid);
02212
02213
02214 if (objid<0) break;
02215
02216 TString clname;
02217 Version_t version;
02218
02219 if (!buf->SqlObjectInfo(objid, clname, version)) return kColUnknown;
02220
02221
02222 if (clname==TObject::Class()->GetName()) {
02223 UnpackTObject(f, buf, data, objid, version);
02224 break;
02225 }
02226
02227 TSQLClassInfo* sqlinfo = f->FindSQLClassInfo(clname.Data(), version);
02228 if (sqlinfo==0) return kColUnknown;
02229
02230 if (sqlinfo->IsClassTableExist()) {
02231 data->AddUnpackInt(sqlio::Version, version);
02232 } else {
02233 TSQLObjectData* objdata = buf->SqlObjectData(objid, sqlinfo);
02234 if ((objdata==0) || !objdata->PrepareForRawData()) return kColUnknown;
02235 AddObjectData(objdata);
02236 }
02237
02238
02239 fValue = strobjid;
02240
02241 break;
02242 }
02243
02244
02245
02246
02247
02248 case kColObjectPtr: {
02249 located = data->LocateColumn(colname.Data());
02250 break;
02251 }
02252
02253
02254
02255
02256
02257 case kColNormObject: {
02258 located = data->LocateColumn(colname.Data());
02259 break;
02260 }
02261
02262 case kColNormObjectArray: {
02263 located = data->LocateColumn(colname.Data());
02264 break;
02265 }
02266
02267 case kColTString: {
02268 located = data->LocateColumn(colname);
02269 if (located==kColUnknown) return located;
02270 const char* value = data->GetValue();
02271
02272 Long64_t objid = DefineObjectId(kTRUE);
02273 Int_t strid = f->IsLongStringCode(objid, value);
02274
02275 TString buf2;
02276
02277
02278 if (strid>0)
02279 if (f->GetLongString(objid, strid, buf2))
02280 value = buf2.Data();
02281
02282 Int_t len = (value==0) ? 0 : strlen(value);
02283 if (len<255) {
02284 data->AddUnpackInt(sqlio::UChar, len);
02285 } else {
02286 data->AddUnpackInt(sqlio::UChar, 255);
02287 data->AddUnpackInt(sqlio::Int, len);
02288 }
02289 if (len>0)
02290 data->AddUnpack(sqlio::CharStar, value);
02291 break;
02292 }
02293
02294 case kColRawData: {
02295 located = data->LocateColumn(colname.Data(), kTRUE);
02296 break;
02297 }
02298
02299 case kColObjectArray: {
02300 located = data->LocateColumn(colname.Data(), kTRUE);
02301 break;
02302 }
02303 }
02304
02305 if (!located) coltype = kColUnknown;
02306
02307 return coltype;
02308 }
02309
02310
02311 Bool_t TSQLStructure::UnpackTObject(TSQLFile* f, TBufferSQL2* buf, TSQLObjectData* data, Long64_t objid, Int_t clversion)
02312 {
02313
02314
02315 TSQLClassInfo* sqlinfo = f->FindSQLClassInfo(TObject::Class()->GetName(), clversion);
02316 if (sqlinfo==0) return kFALSE;
02317
02318 TSQLObjectData* tobjdata = buf->SqlObjectData(objid, sqlinfo);
02319 if (tobjdata==0) return kFALSE;
02320
02321 data->AddUnpackInt(sqlio::Version, clversion);
02322
02323 tobjdata->LocateColumn(sqlio::TObjectUniqueId);
02324 data->AddUnpack(sqlio::UInt, tobjdata->GetValue());
02325 tobjdata->ShiftToNextValue();
02326
02327 tobjdata->LocateColumn(sqlio::TObjectBits);
02328 data->AddUnpack(sqlio::UInt, tobjdata->GetValue());
02329 tobjdata->ShiftToNextValue();
02330
02331 tobjdata->LocateColumn(sqlio::TObjectProcessId);
02332 const char* value = tobjdata->GetValue();
02333 if ((value!=0) && (strlen(value)>0))
02334 data->AddUnpack(sqlio::UShort, value);
02335
02336 delete tobjdata;
02337
02338 return kTRUE;
02339 }
02340
02341
02342 Bool_t TSQLStructure::UnpackTString(TSQLFile* f, TBufferSQL2* buf, TSQLObjectData* data, Long64_t objid, Int_t clversion)
02343 {
02344
02345
02346 TSQLClassInfo* sqlinfo = f->FindSQLClassInfo(TString::Class()->GetName(), clversion);
02347 if (sqlinfo==0) return kFALSE;
02348
02349 TSQLObjectData* tstringdata = buf->SqlObjectData(objid, sqlinfo);
02350 if (tstringdata==0) return kFALSE;
02351
02352 tstringdata->LocateColumn(sqlio::TStringValue);
02353
02354 const char* value = tstringdata->GetValue();
02355
02356 Int_t len = (value==0) ? 0 : strlen(value);
02357 if (len<255) {
02358 data->AddUnpackInt(sqlio::UChar, len);
02359 } else {
02360 data->AddUnpackInt(sqlio::UChar, 255);
02361 data->AddUnpackInt(sqlio::Int, len);
02362 }
02363 if (len>0)
02364 data->AddUnpack(sqlio::CharStar, value);
02365
02366 delete tstringdata;
02367
02368 return kTRUE;
02369 }
02370
02371
02372 void TSQLStructure::AddStrBrackets(TString &s, const char* quote)
02373 {
02374
02375 if (strcmp(quote,"\"")==0) s.ReplaceAll("\"","\\\"");
02376 else s.ReplaceAll("'","''");
02377 s.Prepend(quote);
02378 s.Append(quote);
02379 }