194 const char *mysql_BasicTypes[21] = {
"VARCHAR(255)",
216 const char *mysql_OtherTypes[13] = {
232 const char *oracle_BasicTypes[21] = {
"VARCHAR(255)",
254 const char *oracle_OtherTypes[13] = {
274 : TFile(), fSQL(0), fSQLClassInfos(0), fUseSuffixes(kTRUE), fSQLIOversion(1), fArrayLimit(21),
275 fCanChangeConfig(kFALSE), fTablesType(), fUseTransactions(0), fUseIndexes(0), fModifyCounter(0), fQuerisCounter(0),
276 fBasicTypes(0), fOtherTypes(0), fUserName(), fLogFile(0), fIdsTableExists(kFALSE), fStmtCounter(0)
278 SetBit(kBinaryFile, kFALSE);
299 TSQLFile::TSQLFile(
const char *dbname, Option_t *option,
const char *user,
const char *pass)
300 : TFile(), fSQL(0), fSQLClassInfos(0), fUseSuffixes(kTRUE), fSQLIOversion(1), fArrayLimit(21),
301 fCanChangeConfig(kFALSE), fTablesType(), fUseTransactions(0), fUseIndexes(0), fModifyCounter(0), fQuerisCounter(0),
302 fBasicTypes(mysql_BasicTypes), fOtherTypes(mysql_OtherTypes), fUserName(user), fLogFile(0),
303 fIdsTableExists(kFALSE), fStmtCounter(0)
306 ::Fatal(
"TFile::TFile",
"ROOT system not initialized");
310 SetTitle(
"TFile interface to SQL DB");
311 TDirectoryFile::Build();
314 if (dbname && strstr(dbname,
"oracle://") != 0) {
315 fBasicTypes = oracle_BasicTypes;
316 fOtherTypes = oracle_OtherTypes;
320 fTablesType = SQLDefaultTableType();
322 fUseTransactions = kTransactionsAuto;
327 fVersion = gROOT->GetVersionInt();
330 SetCompressionLevel(ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault % 100);
339 fProcessIDs =
nullptr;
341 fSeekDir = sqlio::Ids_RootDir;
342 SetBit(kBinaryFile, kFALSE);
347 if (fOption ==
"NEW")
350 Bool_t breaklock = kFALSE;
352 if (fOption ==
"BREAKLOCK") {
357 Bool_t create = (fOption ==
"CREATE") ? kTRUE : kFALSE;
358 Bool_t recreate = (fOption ==
"RECREATE") ? kTRUE : kFALSE;
359 Bool_t update = (fOption ==
"UPDATE") ? kTRUE : kFALSE;
360 Bool_t read = (fOption ==
"READ") ? kTRUE : kFALSE;
362 if (!create && !recreate && !update && !read) {
367 if (!dbname || !dbname[0]) {
368 Error(
"TSQLFile",
"Database not specified");
374 fSQL = TSQLServer::Connect(dbname, user, pass);
377 Error(
"TSQLFile",
"Cannot connect to DB %s", dbname);
382 if (IsTablesExists())
383 if (!IsWriteAccess()) {
384 Error(
"TSQLFile",
"no write permission, DB %s locked", dbname);
387 SQLDeleteAllTables();
393 if (create && IsTablesExists()) {
394 Error(
"TSQLFile",
"DB tables already exists");
399 if (!IsTablesExists()) {
404 if (update && !breaklock && !IsWriteAccess()) {
405 Error(
"TSQLFile",
"no write permission, DB %s locked", dbname);
411 if (!IsTablesExists()) {
412 Error(
"TSQLFile",
"DB %s tables not exist", dbname);
415 if (!IsReadAccess()) {
416 Error(
"TSQLFile",
"no read permission for DB %s tables", dbname);
423 if (create || update) {
426 SetLocking(kLockBusy);
433 fCanChangeConfig = create;
435 InitSqlDatabase(create);
450 void TSQLFile::StartLogFile(
const char *fname)
453 fLogFile =
new std::ofstream(fname);
459 void TSQLFile::StopLogFile()
470 Bool_t TSQLFile::IsMySQL()
const
474 return strcmp(fSQL->ClassName(),
"TMySQLServer") == 0;
480 Bool_t TSQLFile::IsOracle()
const
484 return strcmp(fSQL->ClassName(),
"TOracleServer") == 0;
490 Bool_t TSQLFile::IsODBC()
const
494 return strcmp(fSQL->ClassName(),
"TODBCServer") == 0;
501 void TSQLFile::SetUseSuffixes(Bool_t on)
503 if (!fCanChangeConfig)
504 Error(
"SetUseSuffixes",
"Configurations already cannot be changed");
517 void TSQLFile::SetArrayLimit(Int_t limit)
519 if (!fCanChangeConfig)
520 Error(
"SetArrayLimit",
"Configurations already cannot be changed");
531 void TSQLFile::SetTablesType(
const char *tables_type)
533 if (!fCanChangeConfig)
534 Error(
"SetTablesType",
"Configurations already cannot be changed");
536 fTablesType = tables_type;
551 void TSQLFile::SetUseTransactions(Int_t mode)
553 fUseTransactions = mode;
568 Bool_t TSQLFile::StartTransaction()
570 if (GetUseTransactions() != kTransactionsUser) {
571 Error(
"SQLStartTransaction",
"Only allowed when SetUseTransactions(kUserTransactions) was configured");
575 return SQLStartTransaction();
582 Bool_t TSQLFile::Commit()
584 if (GetUseTransactions() != kTransactionsUser) {
585 Error(
"SQLCommit",
"Only allowed when SetUseTransactions(kUserTransactions) was configured");
596 Bool_t TSQLFile::Rollback()
598 if (GetUseTransactions() != kTransactionsUser) {
599 Error(
"SQLRollback",
"Only allowed when SetUseTransactions(kUserTransactions) was configured");
603 return SQLRollback();
618 void TSQLFile::SetUseIndexes(Int_t use_type)
620 if (!fCanChangeConfig)
621 Error(
"SetUseIndexes",
"Configurations already cannot be changed");
623 fUseIndexes = use_type;
630 const char *TSQLFile::GetDataBaseName()
const
634 const char *name = strrchr(GetName(),
'/');
644 void TSQLFile::Close(Option_t *option)
649 TString opt = option;
650 if (opt.Length() > 0)
655 SetLocking(kLockFree);
662 fClassIndex =
nullptr;
666 TDirectory::TContext ctxt(
this);
668 TDirectoryFile::Close();
673 TIter next(fProcessIDs);
675 while ((pid = (TProcessID *)next())) {
676 if (!pid->DecrementCount()) {
677 if (pid != TProcessID::GetSessionProcessID())
679 }
else if (opt.Contains(
"r")) {
685 R__LOCKGUARD(gROOTMutex);
686 gROOT->GetListOfFiles()->Remove(
this);
692 TSQLFile::~TSQLFile()
696 if (fSQLClassInfos) {
697 fSQLClassInfos->Delete();
698 delete fSQLClassInfos;
699 fSQLClassInfos =
nullptr;
713 Bool_t TSQLFile::IsOpen()
const
715 return fSQL !=
nullptr;
722 Int_t TSQLFile::ReOpen(Option_t *mode)
729 if (opt !=
"READ" && opt !=
"UPDATE") {
730 Error(
"ReOpen",
"mode must be either READ or UPDATE, not %s", opt.Data());
734 if (opt == fOption || (opt ==
"UPDATE" && fOption ==
"CREATE"))
740 if (IsOpen() && IsWritable()) {
742 SetLocking(kLockFree);
751 if (!IsWriteAccess()) {
752 Error(
"ReOpen",
"Tables are locked, no write access");
760 SetLocking(kLockBusy);
769 TKey *TSQLFile::CreateKey(TDirectory *mother,
const TObject *obj,
const char *name, Int_t)
771 return new TKeySQL(mother, obj, name);
777 TKey *TSQLFile::CreateKey(TDirectory *mother,
const void *obj,
const TClass *cl,
const char *name, Int_t)
779 return new TKeySQL(mother, obj, cl, name);
785 void TSQLFile::WriteHeader()
787 WriteSpecialObject(sqlio::Ids_TSQLFile,
this, GetName(), GetTitle());
793 void TSQLFile::WriteStreamerInfo()
798 if (!IsTablesExists())
802 Info(
"WriteStreamerInfo",
"Saving streamer infos to database");
806 TIter iter(gROOT->GetListOfStreamerInfo());
808 TVirtualStreamerInfo *info = 0;
810 while ((info = (TVirtualStreamerInfo *)iter()) != 0) {
811 Int_t uid = info->GetNumber();
812 if (fClassIndex->fArray[uid]) {
814 Info(
"WriteStreamerInfo",
"Add %s", info->GetName());
818 if (list.GetSize() == 0)
820 fClassIndex->fArray[0] = 2;
822 WriteSpecialObject(sqlio::Ids_StreamerInfos, &list,
"StreamerInfo",
"StreamerInfos of this file");
824 fClassIndex->fArray[0] = 0;
832 Bool_t TSQLFile::WriteSpecialObject(Long64_t keyid, TObject *obj,
const char *name,
const char *title)
834 DeleteKeyFromDB(keyid);
838 Long64_t objid = StoreObjectInTables(keyid, obj, obj->IsA());
843 TKeySQL *key =
new TKeySQL(
this, keyid, objid, name, title, now.AsSQLString(), 1, obj->ClassName());
854 TObject *TSQLFile::ReadSpecialObject(Long64_t keyid, TObject *obj)
856 TKeySQL *key =
nullptr;
858 StreamKeysForDirectory(
this, kFALSE, keyid, &key);
862 TBufferSQL2 buffer(TBuffer::kRead,
this);
866 TClass *cl =
nullptr;
868 void *res = buffer.SqlReadAny(key->GetDBKeyId(), key->GetDBObjId(), &cl, obj);
870 if ((cl == TSQLFile::Class()) && (res !=
nullptr) && (obj ==
this)) {
872 SetTitle(key->GetTitle());
877 return (TObject *)res;
885 TFile::InfoListRet TSQLFile::GetStreamerInfoListImpl(
bool )
890 Info(
"GetStreamerInfoList",
"Start reading of streamer infos");
892 ROOT::Internal::RConcurrentHashColl::HashValue hash;
894 TObject *obj = ReadSpecialObject(sqlio::Ids_StreamerInfos);
896 TList *list =
dynamic_cast<TList *
>(obj);
899 return {
nullptr, 1, hash};
902 return {list, 0, hash};
909 void TSQLFile::SaveToDatabase()
923 Int_t TSQLFile::StreamKeysForDirectory(TDirectory *dir, Bool_t doupdate, Long64_t specialkeyid, TKeySQL **specialkey)
928 const char *quote = SQLIdentifierQuote();
930 Long64_t dirid = dir->GetSeekDir();
933 sqlcmd.Form(
"SELECT * FROM %s%s%s WHERE %s%s%s=%lld", quote, sqlio::KeysTable, quote, quote, SQLDirIdColumn(), quote,
935 if (specialkeyid >= 0) {
937 buf.Form(
" AND %s%s%s=%lld", quote, SQLKeyIdColumn(), quote, specialkeyid);
941 TSQLResult *res = SQLQuery(sqlcmd.Data(), 2);
948 TSQLRow *row =
nullptr;
950 while ((row = res->Next()) !=
nullptr) {
953 Long64_t keyid = sqlio::atol64((*row)[0]);
955 Long64_t objid = sqlio::atol64((*row)[2]);
956 const char *keyname = (*row)[3];
957 const char *keytitle = (*row)[4];
958 const char *keydatime = (*row)[5];
959 Int_t cycle = atoi((*row)[6]);
960 const char *classname = (*row)[7];
963 std::cout <<
" Reading keyid = " << keyid <<
" name = " << keyname << std::endl;
965 if ((keyid >= sqlio::Ids_FirstKey) || (keyid == specialkeyid)) {
967 TKeySQL *key = FindSQLKey(dir, keyid);
970 Error(
"StreamKeysForDirectory",
"Key with id %lld not exist in list", keyid);
972 }
else if (key->IsKeyModified(keyname, keytitle, keydatime, cycle, classname))
976 TKeySQL *key =
new TKeySQL(dir, keyid, objid, keyname, keytitle, keydatime, cycle, classname);
981 dir->GetListOfKeys()->Add(key);
990 Info(
"StreamKeysForDirectory",
"dir = %s numread = %d", dir->GetName(), nkeys);
991 dir->GetListOfKeys()->Print(
"*");
1001 void TSQLFile::InitSqlDatabase(Bool_t create)
1003 Int_t len = gROOT->GetListOfStreamerInfo()->GetSize() + 1;
1006 fClassIndex =
new TArrayC(len);
1007 fClassIndex->Reset(0);
1011 Bool_t ok = ReadConfigurations();
1015 ReadSQLClassInfos();
1019 ok = (ReadSpecialObject(sqlio::Ids_TSQLFile,
this) != 0);
1024 ok = StreamKeysForDirectory(
this, kFALSE) >= 0;
1027 Error(
"InitSqlDatabase",
"Cannot detect proper tabled in database. Close.");
1038 R__LOCKGUARD(gROOTMutex);
1039 gROOT->GetListOfFiles()->Add(
this);
1044 TKey *key =
nullptr;
1046 while ((key = (TKey *)iter()) !=
nullptr) {
1047 if (!strcmp(key->GetClassName(),
"TProcessID"))
1051 fProcessIDs =
new TObjArray(fNProcessIDs + 1);
1057 Bool_t TSQLFile::ReadConfigurations()
1059 const char *quote = SQLIdentifierQuote();
1062 sqlcmd.Form(
"SELECT * FROM %s%s%s", quote, sqlio::ConfigTable, quote);
1063 TSQLResult *res = SQLQuery(sqlcmd.Data(), 2);
1073 #define ReadIntCfg(name, target) \
1074 if ((field.CompareTo(name, TString::kIgnoreCase) == 0)) \
1075 target = value.Atoi(); \
1078 #define ReadBoolCfg(name, target) \
1079 if ((field.CompareTo(name, TString::kIgnoreCase) == 0)) \
1080 target = value.CompareTo(sqlio::True, TString::kIgnoreCase) == 0; \
1083 #define ReadStrCfg(name, target) \
1084 if ((field.CompareTo(name, TString::kIgnoreCase) == 0)) \
1088 TSQLRow *row =
nullptr;
1090 while ((row = res->Next()) !=
nullptr) {
1092 TString field = row->GetField(0);
1093 TString value = row->GetField(1);
1097 ReadIntCfg(sqlio::cfg_Version, fSQLIOversion) ReadBoolCfg(sqlio::cfg_UseSufixes, fUseSuffixes)
1098 ReadIntCfg(sqlio::cfg_ArrayLimit, fArrayLimit) ReadStrCfg(sqlio::cfg_TablesType, fTablesType)
1099 ReadIntCfg(sqlio::cfg_UseTransactions, fUseTransactions) ReadIntCfg(sqlio::cfg_UseIndexes, fUseIndexes)
1100 ReadIntCfg(sqlio::cfg_ModifyCounter, fModifyCounter) ReadIntCfg(sqlio::cfg_LockingMode, lock)
1102 Error(
"ReadConfigurations",
"Invalid configuration field %s", field.Data());
1111 return (fSQLIOversion > 0);
1119 void TSQLFile::CreateBasicTables()
1123 const char *quote = SQLIdentifierQuote();
1124 const char *vquote = SQLValueQuote();
1126 if (SQLTestTable(sqlio::ConfigTable)) {
1127 sqlcmd.Form(
"DROP TABLE %s%s%s", quote, sqlio::ConfigTable, quote);
1128 SQLQuery(sqlcmd.Data());
1131 sqlcmd.Form(
"CREATE TABLE %s%s%s (%s%s%s %s, %s%s%s %s)", quote, sqlio::ConfigTable, quote, quote, sqlio::CT_Field,
1132 quote, SQLSmallTextType(), quote, sqlio::CT_Value, quote, SQLSmallTextType());
1133 if ((fTablesType.Length() > 0) && IsMySQL()) {
1134 sqlcmd +=
" ENGINE=";
1135 sqlcmd += fTablesType;
1138 SQLQuery(sqlcmd.Data());
1140 #define WrintCfg(name, type, value) \
1142 sqlcmd.Form("INSERT INTO %s%s%s VALUES (%s%s%s, %s" type "%s)", quote, sqlio::ConfigTable, quote, vquote, name, \
1143 vquote, vquote, value, vquote); \
1144 SQLQuery(sqlcmd.Data()); \
1147 WrintCfg(sqlio::cfg_Version,
"%d", fSQLIOversion);
1148 WrintCfg(sqlio::cfg_UseSufixes,
"%s", fUseSuffixes ? sqlio::True : sqlio::False);
1149 WrintCfg(sqlio::cfg_ArrayLimit,
"%d", fArrayLimit);
1150 WrintCfg(sqlio::cfg_TablesType,
"%s", fTablesType.Data());
1151 WrintCfg(sqlio::cfg_UseTransactions,
"%d", fUseTransactions);
1152 WrintCfg(sqlio::cfg_UseIndexes,
"%d", fUseIndexes);
1153 WrintCfg(sqlio::cfg_ModifyCounter,
"%d", fModifyCounter);
1154 WrintCfg(sqlio::cfg_LockingMode,
"%d", kLockBusy);
1157 fCanChangeConfig = kFALSE;
1159 if (SQLTestTable(sqlio::KeysTable)) {
1160 sqlcmd.Form(
"DROP TABLE %s%s%s", quote, sqlio::KeysTable, quote);
1161 SQLQuery(sqlcmd.Data());
1165 "CREATE TABLE %s%s%s (%s%s%s %s, %s%s%s %s, %s%s%s %s, %s%s%s %s, %s%s%s %s, %s%s%s %s, %s%s%s %s, %s%s%s %s)",
1166 quote, sqlio::KeysTable, quote, quote, SQLKeyIdColumn(), quote, SQLIntType(), quote, SQLDirIdColumn(), quote,
1167 SQLIntType(), quote, SQLObjectIdColumn(), quote, SQLIntType(), quote, sqlio::KT_Name, quote, SQLSmallTextType(),
1168 quote, sqlio::KT_Title, quote, SQLSmallTextType(), quote, sqlio::KT_Datetime, quote, SQLDatetimeType(), quote,
1169 sqlio::KT_Cycle, quote, SQLIntType(), quote, sqlio::KT_Class, quote, SQLSmallTextType());
1171 if ((fTablesType.Length() > 0) && IsMySQL()) {
1172 sqlcmd +=
" ENGINE=";
1173 sqlcmd += fTablesType;
1176 SQLQuery(sqlcmd.Data());
1178 if (GetUseIndexes() > kIndexesNone) {
1179 sqlcmd.Form(
"CREATE UNIQUE INDEX %s%s%s ON %s%s%s (%s%s%s)", quote, sqlio::KeysTableIndex, quote, quote,
1180 sqlio::KeysTable, quote, quote, SQLKeyIdColumn(), quote);
1181 SQLQuery(sqlcmd.Data());
1191 void TSQLFile::IncrementModifyCounter()
1193 if (!IsWritable()) {
1194 Error(
"IncrementModifyCounter",
"Cannot update tables without write accsess");
1199 const char *quote = SQLIdentifierQuote();
1200 const char *vquote = SQLValueQuote();
1202 sqlcmd.Form(
"UPDATE %s%s%s SET %s%s%s=%d WHERE %s%s%s=%s%s%s", quote, sqlio::ConfigTable, quote, quote,
1203 sqlio::CT_Value, quote, ++fModifyCounter, quote, sqlio::CT_Field, quote, vquote,
1204 sqlio::cfg_ModifyCounter, vquote);
1205 SQLQuery(sqlcmd.Data());
1218 TString TSQLFile::MakeSelectQuery(TClass *cl)
1221 TSQLClassInfo *sqlinfo = FindSQLClassInfo(cl);
1225 TString columns, tables;
1228 if (!ProduceClassSelectQuery(cl->GetStreamerInfo(), sqlinfo, columns, tables, tablecnt))
1231 res.Form(
"SELECT %s FROM %s", columns.Data(), tables.Data());
1240 Bool_t TSQLFile::ProduceClassSelectQuery(TVirtualStreamerInfo *info, TSQLClassInfo *sqlinfo, TString &columns,
1241 TString &tables, Int_t &tablecnt)
1243 if (!info || !sqlinfo)
1246 if (!sqlinfo->IsClassTableExist())
1249 const char *quote = SQLIdentifierQuote();
1252 table_syn.Form(
"t%d", ++tablecnt);
1254 Bool_t start = (tables.Length() == 0);
1259 buf.Form(
"%s AS %s", sqlinfo->GetClassTableName(), table_syn.Data());
1261 buf.Form(
" LEFT JOIN %s AS %s USING(%s%s%s)", sqlinfo->GetClassTableName(), table_syn.Data(), quote,
1262 SQLObjectIdColumn(), quote);
1267 columns.Form(
"%s.%s%s%s", table_syn.Data(), quote, SQLObjectIdColumn(), quote);
1269 if (info->GetClass() == TObject::Class()) {
1270 buf.Form(
", %s.%s", table_syn.Data(), sqlio::TObjectUniqueId);
1272 buf.Form(
", %s.%s", table_syn.Data(), sqlio::TObjectBits);
1274 buf.Form(
", %s.%s", table_syn.Data(), sqlio::TObjectProcessId);
1279 TIter iter(info->GetElements());
1280 TStreamerElement *elem =
nullptr;
1282 while ((elem = (TStreamerElement *)iter()) !=
nullptr) {
1283 Int_t coltype = TSQLStructure::DefineElementColumnType(elem,
this);
1284 TString colname = TSQLStructure::DefineElementColumnName(elem,
this);
1289 case TSQLStructure::kColObject:
1290 case TSQLStructure::kColObjectPtr:
1291 case TSQLStructure::kColTString:
1292 case TSQLStructure::kColSimple: {
1293 buf.Form(
", %s.%s%s%s", table_syn.Data(), quote, colname.Data(), quote);
1298 case TSQLStructure::kColParent: {
1299 TClass *parentcl = elem->GetClassPointer();
1300 ProduceClassSelectQuery(parentcl->GetStreamerInfo(), FindSQLClassInfo(parentcl), columns, tables, tablecnt);
1304 case TSQLStructure::kColSimpleArray: {
1305 for (Int_t n = 0; n < elem->GetArrayLength(); n++) {
1306 colname = TSQLStructure::DefineElementColumnName(elem,
this, n);
1307 buf.Form(
", %s.%s%s%s", table_syn.Data(), quote, colname.Data(), quote);
1315 return (columns.Length() > 0) && (tables.Length() > 0);
1321 Bool_t TSQLFile::IsTablesExists()
1323 return SQLTestTable(sqlio::KeysTable) && SQLTestTable(sqlio::ConfigTable);
1329 Bool_t TSQLFile::IsWriteAccess()
1331 return GetLocking() == kLockFree;
1337 void TSQLFile::SetLocking(Int_t mode)
1340 const char *quote = SQLIdentifierQuote();
1341 const char *vquote = SQLValueQuote();
1343 sqlcmd.Form(
"UPDATE %s%s%s SET %s%s%s=%d WHERE %s%s%s=%s%s%s", quote, sqlio::ConfigTable, quote, quote,
1344 sqlio::CT_Value, quote, mode, quote, sqlio::CT_Field, quote, vquote, sqlio::cfg_LockingMode, vquote);
1345 SQLQuery(sqlcmd.Data());
1351 Int_t TSQLFile::GetLocking()
1353 const char *quote = SQLIdentifierQuote();
1354 const char *vquote = SQLValueQuote();
1357 sqlcmd.Form(
"SELECT %s%s%s FROM %s%s%s WHERE %s%s%s=%s%s%s", quote, sqlio::CT_Value, quote, quote,
1358 sqlio::ConfigTable, quote, quote, sqlio::CT_Field, quote, vquote, sqlio::cfg_LockingMode, vquote);
1360 TSQLResult *res = SQLQuery(sqlcmd.Data(), 1);
1361 TSQLRow *row = (res == 0) ? 0 : res->Next();
1362 TString field = (row == 0) ?
"" : row->GetField(0);
1366 if (field.Length() == 0)
1369 return field.Atoi();
1375 Bool_t TSQLFile::IsReadAccess()
1392 TSQLResult *TSQLFile::SQLQuery(
const char *cmd, Int_t flag, Bool_t *ok)
1395 *fLogFile << cmd << std::endl;
1404 Info(
"SQLQuery",
"%s", cmd);
1409 Bool_t res = fSQL->Exec(cmd);
1415 TSQLResult *res = fSQL->Query(cmd);
1428 Bool_t TSQLFile::SQLCanStatement()
1433 if (!fSQL->HasStatement())
1442 TSQLStatement *TSQLFile::SQLStatement(
const char *cmd, Int_t bufsize)
1447 if (!fSQL->HasStatement())
1451 Info(
"SQLStatement",
"%s", cmd);
1456 return fSQL->Statement(cmd, bufsize);
1462 void TSQLFile::SQLDeleteStatement(TSQLStatement *stmt)
1476 Bool_t TSQLFile::SQLApplyCommands(TObjArray *cmds)
1483 TObject *cmd =
nullptr;
1484 while ((cmd = iter()) !=
nullptr) {
1485 SQLQuery(cmd->GetName(), 0, &ok);
1496 Bool_t TSQLFile::SQLTestTable(
const char *tablename)
1501 if (fSQL->HasTable(tablename))
1504 TString buf(tablename);
1506 if (fSQL->HasTable(buf.Data()))
1509 return fSQL->HasTable(buf.Data());
1516 Long64_t TSQLFile::SQLMaximumValue(
const char *tablename,
const char *columnname)
1522 Info(
"SQLMaximumValue",
"Requests for %s column %s", tablename, columnname);
1524 const char *quote = SQLIdentifierQuote();
1527 query.Form(
"SELECT MAX(%s%s%s) FROM %s%s%s", quote, columnname, quote, quote, tablename, quote);
1528 TSQLResult *res = SQLQuery(query.Data(), 1);
1533 TSQLRow *row = res->Next();
1535 Long64_t maxid = -1;
1537 if (row->GetField(0) != 0)
1538 maxid = sqlio::atol64(row->GetField(0));
1544 Info(
"SQLMaximumValue",
"Result = %lld", maxid);
1552 void TSQLFile::SQLDeleteAllTables()
1557 TList *tables = fSQL->GetTablesList();
1562 const char *quote = SQLIdentifierQuote();
1565 TObject *obj =
nullptr;
1566 while ((obj = iter()) !=
nullptr) {
1567 sqlcmd.Form(
"DROP TABLE %s%s%s", quote, obj->GetName(), quote);
1568 SQLQuery(sqlcmd.Data());
1576 Bool_t TSQLFile::SQLStartTransaction()
1578 return fSQL ? fSQL->StartTransaction() : kFALSE;
1584 Bool_t TSQLFile::SQLCommit()
1586 return fSQL ? fSQL->Commit() : kFALSE;
1592 Bool_t TSQLFile::SQLRollback()
1594 return fSQL ? fSQL->Rollback() : kFALSE;
1600 Int_t TSQLFile::SQLMaxIdentifierLength()
1602 Int_t maxlen = !fSQL ? 32 : fSQL->GetMaxIdentifierLength();
1615 void TSQLFile::DeleteKeyFromDB(Long64_t keyid)
1617 if (!IsWritable() || (keyid < 0) || !fSQL)
1621 const char *quote = SQLIdentifierQuote();
1623 sqlcmd.Form(
"SELECT MIN(%s%s%s), MAX(%s%s%s) FROM %s%s%s WHERE %s%s%s=%lld", quote, SQLObjectIdColumn(), quote,
1624 quote, SQLObjectIdColumn(), quote, quote, sqlio::ObjectsTable, quote, quote, SQLKeyIdColumn(), quote,
1626 TSQLResult *res = SQLQuery(sqlcmd.Data(), 2);
1627 TSQLRow *row = res == 0 ? 0 : res->Next();
1628 Long64_t minid(1), maxid(0);
1630 if (row && (row->GetField(0) != 0) && (row->GetField(1) != 0)) {
1631 minid = sqlio::atol64(row->GetField(0));
1632 maxid = sqlio::atol64(row->GetField(1));
1639 if (minid <= maxid) {
1640 TIter iter(fSQLClassInfos);
1641 TSQLClassInfo *info =
nullptr;
1642 TString querymask, query;
1643 querymask.Form(
"DELETE FROM %s%s%s WHERE %s%s%s BETWEEN %lld AND %lld", quote,
"%s", quote, quote,
1644 SQLObjectIdColumn(), quote, minid, maxid);
1646 while ((info = (TSQLClassInfo *)iter()) !=
nullptr) {
1648 if (info->IsClassTableExist()) {
1649 query.Form(querymask.Data(), info->GetClassTableName());
1650 SQLQuery(query.Data());
1653 if (info->IsRawTableExist()) {
1654 query.Form(querymask.Data(), info->GetRawTableName());
1655 SQLQuery(query.Data());
1660 sqlcmd.Form(
"DELETE FROM %s%s%s WHERE %s%s%s=%lld", quote, sqlio::ObjectsTable, quote, quote, SQLKeyIdColumn(),
1662 SQLQuery(sqlcmd.Data());
1664 sqlcmd.Form(
"DELETE FROM %s%s%s WHERE %s%s%s=%lld", quote, sqlio::KeysTable, quote, quote, SQLKeyIdColumn(), quote,
1666 SQLQuery(sqlcmd.Data());
1668 IncrementModifyCounter();
1674 TKeySQL *TSQLFile::FindSQLKey(TDirectory *dir, Long64_t keyid)
1679 TIter next(dir->GetListOfKeys());
1680 TObject *obj =
nullptr;
1682 while ((obj = next()) !=
nullptr) {
1683 TKeySQL *key =
dynamic_cast<TKeySQL *
>(obj);
1684 if (key && (key->GetDBKeyId() == keyid))
1694 Bool_t TSQLFile::WriteKeyData(TKeySQL *key)
1699 if (!IsTablesExists())
1700 CreateBasicTables();
1703 const char *valuequote = SQLValueQuote();
1704 const char *quote = SQLIdentifierQuote();
1706 sqlcmd.Form(
"INSERT INTO %s%s%s VALUES (%lld, %lld, %lld, %s%s%s, %s%s%s, %s%s%s, %d, %s%s%s)", quote,
1707 sqlio::KeysTable, quote, key->GetDBKeyId(), key->GetDBDirId(), key->GetDBObjId(), valuequote,
1708 key->GetName(), valuequote, valuequote, key->GetTitle(), valuequote,
1709 valuequote, TestBit(TFile::kReproducible) ? TDatime((UInt_t) 1).AsSQLString() : key->GetDatime().AsSQLString(), valuequote,
1710 key->GetCycle(), valuequote, key->GetClassName(), valuequote);
1714 SQLQuery(sqlcmd.Data(), 0, &ok);
1717 IncrementModifyCounter();
1725 Bool_t TSQLFile::UpdateKeyData(TKeySQL *key)
1731 const char *valuequote = SQLValueQuote();
1732 const char *quote = SQLIdentifierQuote();
1734 TString keyname = key->GetName();
1735 TString keytitle = key->GetTitle();
1736 TString keydatime = key->GetDatime().AsSQLString();
1738 TSQLStructure::AddStrBrackets(keyname, valuequote);
1739 TSQLStructure::AddStrBrackets(keytitle, valuequote);
1740 TSQLStructure::AddStrBrackets(keydatime, valuequote);
1742 sqlcmd.Form(
"UPDATE %s%s%s SET %s%s%s=%s, %s%s%s=%s, %s%s%s=%s, %s%s%s=%d WHERE %s%s%s=%lld", quote,
1743 sqlio::KeysTable, quote, quote, sqlio::KT_Name, quote, keyname.Data(), quote, sqlio::KT_Title, quote,
1744 keytitle.Data(), quote, sqlio::KT_Datetime, quote, keydatime.Data(), quote, sqlio::KT_Cycle, quote,
1745 key->GetCycle(), quote, SQLKeyIdColumn(), quote, key->GetDBKeyId());
1749 SQLQuery(sqlcmd.Data(), 0, &ok);
1752 IncrementModifyCounter();
1760 Long64_t TSQLFile::DefineNextKeyId()
1764 if (SQLTestTable(sqlio::KeysTable))
1765 max = SQLMaximumValue(sqlio::KeysTable, SQLKeyIdColumn());
1768 return sqlio::Ids_FirstKey;
1776 TSQLClassInfo *TSQLFile::FindSQLClassInfo(
const char *clname, Int_t version)
1778 if (!fSQLClassInfos)
1781 TIter iter(fSQLClassInfos);
1782 TSQLClassInfo *info =
nullptr;
1784 while ((info = (TSQLClassInfo *)iter()) !=
nullptr) {
1785 if (strcmp(info->GetName(), clname) == 0)
1786 if (info->GetClassVersion() == version)
1795 TSQLClassInfo *TSQLFile::FindSQLClassInfo(
const TClass *cl)
1797 return FindSQLClassInfo(cl->GetName(), cl->GetClassVersion());
1803 TSQLClassInfo *TSQLFile::RequestSQLClassInfo(
const char *clname, Int_t version)
1805 TSQLClassInfo *info = FindSQLClassInfo(clname, version);
1814 if (fSQLClassInfos) {
1815 TIter iter(fSQLClassInfos);
1816 while ((info = (TSQLClassInfo *)iter()) !=
nullptr) {
1817 if (info->GetClassId() > maxid)
1818 maxid = info->GetClassId();
1822 info =
new TSQLClassInfo(maxid + 1, clname, version);
1824 info->SetClassTableName(DefineTableName(clname, version, kFALSE));
1825 info->SetRawTableName(DefineTableName(clname, version, kTRUE));
1827 if (!fSQLClassInfos)
1828 fSQLClassInfos =
new TList;
1829 fSQLClassInfos->Add(info);
1837 TString TSQLFile::DefineTableName(
const char *clname, Int_t version, Bool_t rawtable)
1839 Int_t maxlen = SQLMaxIdentifierLength();
1843 const char *suffix = rawtable ?
"_raw" :
"_ver";
1845 res.Form(
"%s%s%d", clname, suffix, version);
1847 if ((res.Length() <= maxlen) && !HasTable(res.Data()))
1852 Int_t len = strlen(clname);
1853 Int_t cnt = version;
1858 scnt.Form(
"%d%s", cnt, suffix);
1859 Int_t numlen = scnt.Length();
1860 if (numlen >= maxlen - 2)
1865 if (len + numlen > maxlen)
1866 res.Resize(maxlen - numlen);
1870 if (!HasTable(res.Data()))
1875 }
while (cnt < 10000);
1877 Error(
"DefineTableName",
"Cannot produce table name for class %s ver %d", clname, version);
1878 res.Form(
"%s%s%d", clname, suffix, version);
1886 Bool_t TSQLFile::HasTable(
const char *name)
1888 if (!fSQLClassInfos)
1891 TIter iter(fSQLClassInfos);
1892 TSQLClassInfo *info =
nullptr;
1893 while ((info = (TSQLClassInfo *)iter()) !=
nullptr) {
1894 if (strcmp(info->GetClassTableName(), name) == 0)
1896 if (strcmp(info->GetRawTableName(), name) == 0)
1906 TSQLClassInfo *TSQLFile::RequestSQLClassInfo(
const TClass *cl)
1908 return RequestSQLClassInfo(cl->GetName(), cl->GetClassVersion());
1914 void TSQLFile::ReadSQLClassInfos()
1919 fIdsTableExists = SQLTestTable(sqlio::IdsTable);
1921 if (!fIdsTableExists)
1925 const char *quote = SQLIdentifierQuote();
1927 sqlcmd.Form(
"SELECT * FROM %s%s%s WHERE %s%s%s = %d ORDER BY %s%s%s", quote, sqlio::IdsTable, quote, quote,
1928 sqlio::IT_Type, quote, TSQLStructure::kIdTable, quote, sqlio::IT_TableID, quote);
1930 TSQLResult *res = SQLQuery(sqlcmd.Data(), 1);
1932 TSQLRow *row =
nullptr;
1935 while ((row = res->Next()) !=
nullptr) {
1936 Long64_t tableid = sqlio::atol64(row->GetField(0));
1937 Int_t version = atoi(row->GetField(1));
1939 const char *classname = row->GetField(3);
1940 const char *classtable = row->GetField(4);
1942 TSQLClassInfo *info =
new TSQLClassInfo(tableid, classname, version);
1943 info->SetClassTableName(classtable);
1945 if (!fSQLClassInfos)
1946 fSQLClassInfos =
new TList;
1947 fSQLClassInfos->Add(info);
1953 TIter next(fSQLClassInfos);
1954 TSQLClassInfo *info =
nullptr;
1956 while ((info = (TSQLClassInfo *)next()) !=
nullptr) {
1957 sqlcmd.Form(
"SELECT * FROM %s%s%s WHERE %s%s%s = %lld ORDER BY %s%s%s", quote, sqlio::IdsTable, quote, quote,
1958 sqlio::IT_TableID, quote, info->GetClassId(), quote, sqlio::IT_SubID, quote);
1959 res = SQLQuery(sqlcmd.Data(), 1);
1961 TObjArray *cols =
nullptr;
1964 while ((row = res->Next()) !=
nullptr) {
1966 Int_t typ = atoi(row->GetField(2));
1968 const char *fullname = row->GetField(3);
1969 const char *sqlname = row->GetField(4);
1970 const char *info2 = row->GetField(5);
1972 if (typ == TSQLStructure::kIdColumn) {
1974 cols =
new TObjArray;
1975 cols->Add(
new TSQLClassColumnInfo(fullname, sqlname, info2));
1983 info->SetColumns(cols);
1986 sqlcmd.Form(
"SELECT * FROM %s%s%s WHERE %s%s%s = %d ORDER BY %s%s%s", quote, sqlio::IdsTable, quote, quote,
1987 sqlio::IT_Type, quote, TSQLStructure::kIdRawTable, quote, sqlio::IT_TableID, quote);
1989 res = SQLQuery(sqlcmd.Data(), 1);
1992 while ((row = res->Next()) !=
nullptr) {
1993 Long64_t tableid = sqlio::atol64(row->GetField(0));
1994 Int_t version = atoi(row->GetField(1));
1996 const char *classname = row->GetField(3);
1997 const char *rawtable = row->GetField(4);
1999 TSQLClassInfo *info2 = FindSQLClassInfo(classname, version);
2002 info2 =
new TSQLClassInfo(tableid, classname, version);
2004 if (!fSQLClassInfos)
2005 fSQLClassInfos =
new TList;
2006 fSQLClassInfos->Add(info2);
2009 info2->SetRawTableName(rawtable);
2010 info2->SetRawExist(kTRUE);
2021 void TSQLFile::AddIdEntry(Long64_t tableid, Int_t subid, Int_t type,
const char *name,
const char *sqlname,
2024 if (!fSQL || !IsWritable())
2028 const char *valuequote = SQLValueQuote();
2029 const char *quote = SQLIdentifierQuote();
2031 if (!fIdsTableExists) {
2033 if (SQLTestTable(sqlio::IdsTable)) {
2034 sqlcmd.Form(
"DROP TABLE %s%s%s", quote, sqlio::IdsTable, quote);
2035 SQLQuery(sqlcmd.Data());
2038 sqlcmd.Form(
"CREATE TABLE %s%s%s (%s%s%s %s, %s%s%s %s, %s%s%s %s, %s%s%s %s, %s%s%s %s, %s%s%s %s)", quote,
2039 sqlio::IdsTable, quote, quote, sqlio::IT_TableID, quote, SQLIntType(), quote, sqlio::IT_SubID, quote,
2040 SQLIntType(), quote, sqlio::IT_Type, quote, SQLIntType(), quote, sqlio::IT_FullName, quote,
2041 SQLSmallTextType(), quote, sqlio::IT_SQLName, quote, SQLSmallTextType(), quote, sqlio::IT_Info, quote,
2042 SQLSmallTextType());
2043 if ((fTablesType.Length() > 0) && IsMySQL()) {
2044 sqlcmd +=
" ENGINE=";
2045 sqlcmd += fTablesType;
2047 SQLQuery(sqlcmd.Data());
2049 fIdsTableExists = kTRUE;
2052 sqlcmd.Form(
"INSERT INTO %s%s%s VALUES (%lld, %d, %d, %s%s%s, %s%s%s, %s%s%s)", quote, sqlio::IdsTable, quote,
2053 tableid, subid, type, valuequote, name, valuequote, valuequote, sqlname, valuequote, valuequote, info,
2056 SQLQuery(sqlcmd.Data());
2062 Bool_t TSQLFile::CreateClassTable(TSQLClassInfo *sqlinfo, TObjArray *colinfos)
2069 return sqlinfo->IsClassTableExist();
2071 if (sqlinfo->IsClassTableExist()) {
2081 Info(
"CreateClassTable",
"cl:%s", sqlinfo->GetName());
2083 const char *quote = SQLIdentifierQuote();
2085 AddIdEntry(sqlinfo->GetClassId(), sqlinfo->GetClassVersion(), TSQLStructure::kIdTable, sqlinfo->GetName(),
2086 sqlinfo->GetClassTableName(),
"Main class table");
2089 sqlcmd.Form(
"CREATE TABLE %s%s%s (", quote, sqlinfo->GetClassTableName(), quote);
2091 TIter iter(colinfos);
2092 TSQLClassColumnInfo *col;
2093 Bool_t first = kTRUE;
2094 Bool_t forcequote = IsOracle();
2096 while ((col = (TSQLClassColumnInfo *)iter()) !=
nullptr) {
2102 const char *colname = col->GetSQLName();
2103 if ((strpbrk(colname,
"[:.]<>") != 0) || forcequote) {
2109 sqlcmd += colname, sqlcmd +=
" ";
2112 sqlcmd += col->GetSQLType();
2114 AddIdEntry(sqlinfo->GetClassId(), colid++, TSQLStructure::kIdColumn, col->GetName(), col->GetSQLName(),
2119 if ((fTablesType.Length() > 0) && IsMySQL()) {
2120 sqlcmd +=
" ENGINE=";
2121 sqlcmd += fTablesType;
2124 SQLQuery(sqlcmd.Data());
2126 sqlinfo->SetColumns(colinfos);
2128 if (GetUseIndexes() > kIndexesBasic) {
2130 TString indxname = sqlinfo->GetClassTableName();
2131 indxname.ReplaceAll(
"_ver",
"_i1x");
2133 sqlcmd.Form(
"CREATE UNIQUE INDEX %s%s_I1%s ON %s%s%s (%s%s%s)", quote, indxname.Data(), quote, quote,
2134 sqlinfo->GetClassTableName(), quote, quote, SQLObjectIdColumn(), quote);
2135 SQLQuery(sqlcmd.Data());
2144 Bool_t TSQLFile::CreateRawTable(TSQLClassInfo *sqlinfo)
2149 if (sqlinfo->IsRawTableExist())
2152 const char *quote = SQLIdentifierQuote();
2155 Info(
"CreateRawTable",
"%s", sqlinfo->GetName());
2159 sqlcmd.Form(
"CREATE TABLE %s%s%s (%s%s%s %s, %s%s%s %s, %s %s, %s %s)", quote, sqlinfo->GetRawTableName(), quote,
2160 quote, SQLObjectIdColumn(), quote, SQLIntType(), quote, SQLRawIdColumn(), quote, SQLIntType(),
2161 sqlio::BT_Field, SQLSmallTextType(), sqlio::BT_Value, SQLSmallTextType());
2163 if ((fTablesType.Length() > 0) && IsMySQL()) {
2164 sqlcmd +=
" ENGINE=";
2165 sqlcmd += fTablesType;
2168 SQLQuery(sqlcmd.Data());
2169 sqlinfo->SetRawExist(kTRUE);
2171 if (GetUseIndexes() > kIndexesClass) {
2172 TString indxname = sqlinfo->GetClassTableName();
2173 indxname.ReplaceAll(
"_ver",
"_i2x");
2175 sqlcmd.Form(
"CREATE UNIQUE INDEX %s%s_I2%s ON %s%s%s (%s%s%s, %s%s%s)", quote, indxname.Data(), quote, quote,
2176 sqlinfo->GetRawTableName(), quote, quote, SQLObjectIdColumn(), quote, quote, SQLRawIdColumn(), quote);
2177 SQLQuery(sqlcmd.Data());
2180 AddIdEntry(sqlinfo->GetClassId(), sqlinfo->GetClassVersion(), TSQLStructure::kIdRawTable, sqlinfo->GetName(),
2181 sqlinfo->GetRawTableName(),
"Raw data class table");
2190 Bool_t TSQLFile::VerifyLongStringTable()
2195 if (SQLTestTable(sqlio::StringsTable))
2198 const char *quote = SQLIdentifierQuote();
2201 sqlcmd.Form(
"CREATE TABLE %s (%s%s%s %s, %s%s%s %s, %s %s)", sqlio::StringsTable, quote, SQLObjectIdColumn(), quote,
2202 SQLIntType(), quote, SQLStrIdColumn(), quote, SQLIntType(), sqlio::ST_Value, SQLBigTextType());
2204 if (fTablesType.Length() > 0) {
2205 sqlcmd +=
" ENGINE=";
2206 sqlcmd += fTablesType;
2209 SQLQuery(sqlcmd.Data());
2217 TString TSQLFile::CodeLongString(Long64_t objid, Int_t strid)
2220 res.Form(
"%s %lld %s %d %s", sqlio::LongStrPrefix, objid, sqlio::LongStrPrefix, strid, sqlio::LongStrPrefix);
2228 Int_t TSQLFile::IsLongStringCode(Long64_t objid,
const char *value)
2232 if (strlen(value) < strlen(sqlio::LongStrPrefix) * 3 + 6)
2234 if (strstr(value, sqlio::LongStrPrefix) != value)
2237 value += strlen(sqlio::LongStrPrefix);
2238 if (*value++ !=
' ')
2240 TString s_strid, s_objid;
2241 if ((*value <
'1') || (*value >
'9'))
2244 s_objid.Append(*value++);
2245 }
while ((*value != 0) && (*value >=
'0') && (*value <=
'9'));
2247 if (*value++ !=
' ')
2249 if ((*value == 0) || (strstr(value, sqlio::LongStrPrefix) != value))
2251 value += strlen(sqlio::LongStrPrefix);
2252 if (*value++ !=
' ')
2255 if ((*value <
'1') || (*value >
'9'))
2258 s_strid.Append(*value++);
2259 }
while ((*value != 0) && (*value >=
'0') && (*value <=
'9'));
2260 if (*value++ !=
' ')
2263 if ((*value == 0) || (strcmp(value, sqlio::LongStrPrefix) != 0))
2266 Long64_t objid2 = sqlio::atol64(s_objid.Data());
2267 if (objid2 != objid)
2270 return atoi(s_strid.Data());
2277 Bool_t TSQLFile::GetLongString(Long64_t objid, Int_t strid, TString &value)
2279 if (!SQLTestTable(sqlio::StringsTable))
2283 const char *quote = SQLIdentifierQuote();
2284 cmd.Form(
"SELECT %s FROM %s%s%s WHERE %s%s%s=%lld AND %s%s%s=%d", sqlio::ST_Value, quote, sqlio::StringsTable, quote,
2285 quote, SQLObjectIdColumn(), quote, objid, quote, SQLStrIdColumn(), quote, strid);
2287 TSQLResult *res = SQLQuery(cmd.Data(), 1);
2290 TSQLRow *row = res->Next();
2295 value = row->GetField(0);
2308 Long64_t TSQLFile::VerifyObjectTable()
2313 Long64_t maxid = -1;
2316 Info(
"VerifyObjectTable",
"Checks if object table is there");
2318 if (SQLTestTable(sqlio::ObjectsTable))
2319 maxid = SQLMaximumValue(sqlio::ObjectsTable, SQLObjectIdColumn());
2322 const char *quote = SQLIdentifierQuote();
2323 sqlcmd.Form(
"CREATE TABLE %s%s%s (%s%s%s %s, %s%s%s %s, %s%s%s %s, %s%s%s %s)", quote, sqlio::ObjectsTable, quote,
2324 quote, SQLKeyIdColumn(), quote, SQLIntType(), quote, SQLObjectIdColumn(), quote, SQLIntType(), quote,
2325 sqlio::OT_Class, quote, SQLSmallTextType(), quote, sqlio::OT_Version, quote, SQLIntType());
2327 if ((fTablesType.Length() > 0) && IsMySQL()) {
2328 sqlcmd +=
" ENGINE=";
2329 sqlcmd += fTablesType;
2332 SQLQuery(sqlcmd.Data());
2334 if (GetUseIndexes() > kIndexesNone) {
2335 sqlcmd.Form(
"CREATE UNIQUE INDEX %s%s%s ON %s%s%s (%s%s%s)", quote, sqlio::ObjectsTableIndex, quote, quote,
2336 sqlio::ObjectsTable, quote, quote, SQLObjectIdColumn(), quote);
2337 SQLQuery(sqlcmd.Data());
2347 Bool_t TSQLFile::SQLObjectInfo(Long64_t objid, TString &clname, Version_t &version)
2353 const char *quote = SQLIdentifierQuote();
2354 sqlcmd.Form(
"SELECT %s%s%s, %s%s%s FROM %s%s%s WHERE %s%s%s=%lld", quote, sqlio::OT_Class, quote, quote,
2355 sqlio::OT_Version, quote, quote, sqlio::ObjectsTable, quote, quote, SQLObjectIdColumn(), quote, objid);
2356 TSQLResult *res = SQLQuery(sqlcmd.Data(), 1);
2359 TSQLRow *row = res->Next();
2361 clname = row->GetField(0);
2362 version = atoi(row->GetField(1));
2367 return row !=
nullptr;
2374 TObjArray *TSQLFile::SQLObjectsInfo(Long64_t keyid)
2380 const char *quote = SQLIdentifierQuote();
2381 sqlcmd.Form(
"SELECT %s%s%s, %s%s%s, %s%s%s FROM %s%s%s WHERE %s%s%s=%lld ORDER BY %s%s%s", quote,
2382 SQLObjectIdColumn(), quote, quote, sqlio::OT_Class, quote, quote, sqlio::OT_Version, quote, quote,
2383 sqlio::ObjectsTable, quote, quote, SQLKeyIdColumn(), quote, keyid, quote, SQLObjectIdColumn(), quote);
2385 TObjArray *arr =
nullptr;
2388 *fLogFile << sqlcmd << std::endl;
2390 Info(
"SQLObjectsInfo",
"%s", sqlcmd.Data());
2393 TSQLStatement *stmt = SQLStatement(sqlcmd.Data(), 1000);
2397 stmt->StoreResult();
2399 while (stmt->NextResultRow()) {
2400 Long64_t objid = stmt->GetLong64(0);
2401 const char *clname = stmt->GetString(1);
2402 Int_t version = stmt->GetInt(2);
2404 TSQLObjectInfo *info =
new TSQLObjectInfo(objid, clname, version);
2406 arr =
new TObjArray();
2414 TSQLResult *res = SQLQuery(sqlcmd.Data(), 1);
2418 TSQLRow *row =
nullptr;
2419 while ((row = res->Next()) !=
nullptr) {
2420 Long64_t objid = atoi(row->GetField(0));
2421 const char *clname = row->GetField(1);
2422 Int_t version = atoi(row->GetField(2));
2424 TSQLObjectInfo *info =
new TSQLObjectInfo(objid, clname, version);
2426 arr =
new TObjArray();
2438 TSQLResult *TSQLFile::GetNormalClassData(Long64_t objid, TSQLClassInfo *sqlinfo)
2440 if (!sqlinfo->IsClassTableExist())
2443 const char *quote = SQLIdentifierQuote();
2444 sqlcmd.Form(
"SELECT * FROM %s%s%s WHERE %s%s%s=%lld", quote, sqlinfo->GetClassTableName(), quote, quote,
2445 SQLObjectIdColumn(), quote, objid);
2446 return SQLQuery(sqlcmd.Data(), 2);
2452 TSQLResult *TSQLFile::GetNormalClassDataAll(Long64_t minobjid, Long64_t maxobjid, TSQLClassInfo *sqlinfo)
2454 if (!sqlinfo->IsClassTableExist())
2457 const char *quote = SQLIdentifierQuote();
2458 sqlcmd.Form(
"SELECT * FROM %s%s%s WHERE %s%s%s BETWEEN %lld AND %lld ORDER BY %s%s%s", quote,
2459 sqlinfo->GetClassTableName(), quote, quote, SQLObjectIdColumn(), quote, minobjid, maxobjid, quote,
2460 SQLObjectIdColumn(), quote);
2461 return SQLQuery(sqlcmd.Data(), 2);
2467 TSQLResult *TSQLFile::GetBlobClassData(Long64_t objid, TSQLClassInfo *sqlinfo)
2469 if (!sqlinfo->IsRawTableExist())
2472 const char *quote = SQLIdentifierQuote();
2473 sqlcmd.Form(
"SELECT %s, %s FROM %s%s%s WHERE %s%s%s=%lld ORDER BY %s%s%s", sqlio::BT_Field, sqlio::BT_Value, quote,
2474 sqlinfo->GetRawTableName(), quote, quote, SQLObjectIdColumn(), quote, objid, quote, SQLRawIdColumn(),
2476 return SQLQuery(sqlcmd.Data(), 2);
2483 TSQLStatement *TSQLFile::GetBlobClassDataStmt(Long64_t objid, TSQLClassInfo *sqlinfo)
2485 if (!sqlinfo->IsRawTableExist())
2489 const char *quote = SQLIdentifierQuote();
2490 sqlcmd.Form(
"SELECT %s, %s FROM %s%s%s WHERE %s%s%s=%lld ORDER BY %s%s%s", sqlio::BT_Field, sqlio::BT_Value, quote,
2491 sqlinfo->GetRawTableName(), quote, quote, SQLObjectIdColumn(), quote, objid, quote, SQLRawIdColumn(),
2495 *fLogFile << sqlcmd << std::endl;
2497 Info(
"BuildStatement",
"%s", sqlcmd.Data());
2500 TSQLStatement *stmt = SQLStatement(sqlcmd.Data(), 1000);
2506 stmt->StoreResult();
2514 Long64_t TSQLFile::StoreObjectInTables(Long64_t keyid,
const void *obj,
const TClass *cl)
2519 Long64_t objid = VerifyObjectTable();
2525 TBufferSQL2 buffer(TBuffer::kWrite,
this);
2529 TSQLStructure *s = buffer.SqlWriteAny(obj, cl, objid);
2531 if ((buffer.GetErrorFlag() > 0) && s) {
2532 Error(
"StoreObjectInTables",
"Cannot convert object data to TSQLStructure");
2538 if (s && !s->ConvertToTables(
this, keyid, &cmds)) {
2539 Error(
"StoreObjectInTables",
"Cannot convert to SQL statements");
2542 Bool_t needcommit = kFALSE;
2544 if (GetUseTransactions() == kTransactionsAuto) {
2545 SQLStartTransaction();
2549 if (!SQLApplyCommands(&cmds)) {
2550 Error(
"StoreObject",
"Cannot correctly store object data in database");
2569 const char *TSQLFile::SQLCompatibleType(Int_t typ)
const
2571 return (typ < 0) || (typ > 18) ? 0 : fBasicTypes[typ];
2577 const char *TSQLFile::SQLIntType()
const
2579 return SQLCompatibleType(TVirtualStreamerInfo::kInt);
2585 Long64_t TSQLFile::DirCreateEntry(TDirectory *dir)
2587 TDirectory *mother = dir->GetMotherDir();
2592 TKeySQL *key =
new TKeySQL(mother, dir, dir->GetName(), dir->GetTitle());
2594 return key->GetDBKeyId();
2600 Int_t TSQLFile::DirReadKeys(TDirectory *dir)
2603 dir->GetListOfKeys()->Delete();
2606 Info(
"DirReadKeys",
"dir = %s id = %lld", dir->GetName(), dir->GetSeekDir());
2608 return StreamKeysForDirectory(dir, kFALSE);
2614 void TSQLFile::DirWriteKeys(TDirectory *dir)
2616 StreamKeysForDirectory(dir, kTRUE);
2622 void TSQLFile::DirWriteHeader(TDirectory *dir)
2624 TSQLClassInfo *sqlinfo = FindSQLClassInfo(
"TDirectory", TDirectoryFile::Class()->GetClassVersion());
2629 TKeySQL *key = FindSQLKey(dir->GetMotherDir(), dir->GetSeekDir());
2633 const char *valuequote = SQLValueQuote();
2634 const char *quote = SQLIdentifierQuote();
2636 TDirectoryFile *fdir =
dynamic_cast<TDirectoryFile *
> (dir);
2637 TString timeC = fdir ? fdir->GetCreationDate().AsSQLString() : fDatimeC.AsSQLString();
2638 TString timeM = fdir ? fdir->GetModificationDate().AsSQLString() : fDatimeM.AsSQLString();;
2639 if (TestBit(TFile::kReproducible))
2640 timeC = timeM = TDatime((UInt_t) 1).AsSQLString();
2642 TSQLStructure::AddStrBrackets(timeC, valuequote);
2643 TSQLStructure::AddStrBrackets(timeM, valuequote);
2645 TString uuid = TestBit(TFile::kReproducible) ? TUUID(
"00000000-0000-0000-0000-000000000000").AsString() : dir->GetUUID().AsString();
2646 TSQLStructure::AddStrBrackets(uuid, valuequote);
2650 TString col1name =
"CreateTime";
2651 TString col2name =
"ModifyTime";
2652 TString col3name =
"UUID";
2653 if (GetUseSuffixes()) {
2654 col1name += sqlio::StrSuffix;
2655 col2name += sqlio::StrSuffix;
2656 col3name += sqlio::StrSuffix;
2659 sqlcmd.Form(
"UPDATE %s%s%s SET %s%s%s=%s, %s%s%s=%s, %s%s%s=%s WHERE %s%s%s=%lld", quote,
2660 sqlinfo->GetClassTableName(), quote, quote, col1name.Data(), quote, timeC.Data(), quote, col2name.Data(),
2661 quote, timeM.Data(), quote, col3name.Data(), quote, uuid.Data(), quote, SQLObjectIdColumn(), quote,
2664 SQLQuery(sqlcmd.Data());
2671 void TSQLFile::Streamer(TBuffer &b)
2675 if (b.IsReading()) {
2676 Version_t R__v = b.ReadVersion(0, 0);
2677 b.ClassBegin(TSQLFile::Class(), R__v);
2679 b.ClassMember(
"CreateTime",
"TString");
2681 TDatime timeC(sbuf.Data());
2684 b.ClassMember(
"ModifyTime",
"TString");
2686 TDatime timeM(sbuf.Data());
2689 b.ClassMember(
"UUID",
"TString");
2691 TUUID id(sbuf.Data());
2694 b.ClassEnd(TSQLFile::Class());
2697 b.WriteVersion(TSQLFile::Class());
2699 b.ClassBegin(TSQLFile::Class());
2701 b.ClassMember(
"CreateTime",
"TString");
2702 sbuf = TestBit(TFile::kReproducible) ? TDatime((UInt_t) 1).AsSQLString() : fDatimeC.AsSQLString();
2706 b.ClassMember(
"ModifyTime",
"TString");
2708 sbuf = TestBit(TFile::kReproducible) ? TDatime((UInt_t) 1).AsSQLString() : fDatimeM.AsSQLString();
2711 b.ClassMember(
"UUID",
"TString");
2712 sbuf = TestBit(TFile::kReproducible) ? TUUID(
"00000000-0000-0000-0000-000000000000").AsString() : fUUID.AsString();
2715 b.ClassEnd(TSQLFile::Class());