MythTV  master
dbutil.cpp
Go to the documentation of this file.
1 #include <climits>
2 #include <cstdio>
3 #include <cstdlib>
4 #include <sys/stat.h>
5 #include <sys/types.h>
6 #include <unistd.h>
7 
8 #include <QDir>
9 #include <QFile>
10 #include <QRegularExpression>
11 #include <QDateTime>
12 #include <QSqlError>
13 #include <QSqlRecord>
14 
15 #include "dbutil.h"
16 #include "mythcorecontext.h"
17 #include "storagegroup.h"
18 #include "mythmiscutil.h"
19 #include "mythdate.h"
20 #include "mythdb.h"
21 #include "mythdirs.h"
22 #include "mythlogging.h"
23 #include "mythsystemlegacy.h"
24 #include "exitcodes.h"
25 
26 #define LOC QString("DBUtil: ")
27 
28 #if QT_VERSION < QT_VERSION_CHECK(5,15,2)
29 #define capturedView capturedRef
30 #endif
31 
32 const int DBUtil::kUnknownVersionNumber = INT_MIN;
33 
39 {
40  if (m_versionString.isEmpty())
42  return m_versionString;
43 }
44 
57 int DBUtil::CompareDBMSVersion(int major, int minor, int point)
58 {
59  if (m_versionMajor < 0)
60  if (!ParseDBMSVersion())
61  return kUnknownVersionNumber;
62 
63  int result = 0;
65  std::array<int,3> compareto {major, minor, point};
66  for (int i = 0; i < 3 && !result; i++)
67  {
68  if ((version[i] > -1) || (compareto[i] != 0))
69  result = version[i] - compareto[i];
70  }
71 
72  return result;
73 }
74 
79 {
80  const QStringList tables = GetTables();
81  const int size = tables.size();
82  // Usually there will be a single table called schemalock, but check for
83  // no tables, also, just in case.
84  return (((size == 1) && (tables.at(0).endsWith(".`schemalock`"))) ||
85  (size == 0));
86 }
87 
93 {
94  QString backupStartTimeStr =
95  gCoreContext->GetSetting("BackupDBLastRunStart");
96  QString backupEndTimeStr = gCoreContext->GetSetting("BackupDBLastRunEnd");
97 
98  if (backupStartTimeStr.isEmpty())
99  {
100  LOG(VB_DATABASE, LOG_ERR, "DBUtil::BackupInProgress(): No start time "
101  "found, database backup is not in progress.");
102  return false;
103  }
104 
105  backupStartTimeStr.replace(" ", "T");
106 
107  QDateTime backupStartTime = MythDate::fromString(backupStartTimeStr);
108  auto backupElapsed = MythDate::secsInPast(backupStartTime);
109 
110  // No end time set
111  if (backupEndTimeStr.isEmpty())
112  {
113  // If DB Backup started less then 10 minutes ago, assume still running
114  if (backupElapsed < 10min)
115  {
116  LOG(VB_DATABASE, LOG_INFO,
117  QString("DBUtil::BackupInProgress(): Found "
118  "database backup start time of %1 which was %2 seconds "
119  "ago, therefore it appears the backup is still running.")
120  .arg(backupStartTimeStr)
121  .arg(backupElapsed.count()));
122  return true;
123  }
124  LOG(VB_DATABASE, LOG_ERR, QString("DBUtil::BackupInProgress(): "
125  "Database backup started at %1, but no end time was found. "
126  "The backup started %2 seconds ago and should have "
127  "finished by now therefore it appears it is not running .")
128  .arg(backupStartTimeStr)
129  .arg(backupElapsed.count()));
130  return false;
131  }
132 
133  backupEndTimeStr.replace(" ", "T");
134 
135  QDateTime backupEndTime = MythDate::fromString(backupEndTimeStr);
136 
137  if (backupEndTime >= backupStartTime)
138  {
139  LOG(VB_DATABASE, LOG_ERR,
140  QString("DBUtil::BackupInProgress(): Found "
141  "database backup end time of %1 later than start time "
142  "of %2, therefore backup is not running.")
143  .arg(backupEndTimeStr, backupStartTimeStr));
144  return false;
145  }
146  if (backupElapsed > 10min)
147  {
148  LOG(VB_DATABASE, LOG_ERR,
149  QString("DBUtil::BackupInProgress(): "
150  "Database backup started at %1, but has not ended yet. "
151  "The backup started %2 seconds ago and should have "
152  "finished by now therefore it appears it is not running")
153  .arg(backupStartTimeStr)
154  .arg(backupElapsed.count()));
155  return false;
156  }
157 
158  // start > end and started less than 10 minutes ago
159  LOG(VB_DATABASE, LOG_INFO, QString("DBUtil::BackupInProgress(): "
160  "Database backup started at %1, and is still running.")
161  .arg(backupStartTimeStr));
162  return true;
163 }
164 
191  [[maybe_unused]] bool disableRotation)
192 {
193  filename = QString();
194 
195 #ifdef _WIN32
196  LOG(VB_GENERAL, LOG_CRIT, "Database backups disabled on Windows.");
197  return kDB_Backup_Disabled;
198 #else
199 
200  if (gCoreContext->GetBoolSetting("DisableAutomaticBackup", false))
201  {
202  LOG(VB_GENERAL, LOG_CRIT,
203  "Database backups disabled. Skipping backup.");
204  return kDB_Backup_Disabled;
205  }
206 
207  if (IsNewDatabase())
208  {
209  LOG(VB_GENERAL, LOG_CRIT, "New database detected. Skipping backup.");
210  return kDB_Backup_Empty_DB;
211  }
212 
213  QString backupScript = GetShareDir() + "mythconverg_backup.pl";
214  backupScript = gCoreContext->GetSetting("DatabaseBackupScript",
215  backupScript);
216 
217  if (!QFile::exists(backupScript))
218  {
219  LOG(VB_GENERAL, LOG_CRIT, QString("Database backup script does "
220  "not exist: %1").arg(backupScript));
221  backupScript.clear();
222  }
223 
224  bool result = false;
225  MSqlQuery query(MSqlQuery::InitCon());
226 
228  "BackupDBLastRunStart",
230 
231  if (!backupScript.isEmpty())
232  {
233  result = DoBackup(backupScript, filename, disableRotation);
234  if (!result)
235  LOG(VB_GENERAL, LOG_CRIT, "Script-based database backup failed. "
236  "Retrying with internal backup.");
237  }
238 
239  if (!result)
240  result = DoBackup(filename);
241 
243  "BackupDBLastRunEnd",
245 
246  if (query.isConnected())
247  {
248  QString dbTag("BackupDB");
249  query.prepare("DELETE FROM housekeeping WHERE tag = :TAG ;");
250  query.bindValue(":TAG", dbTag);
251  if (!query.exec())
252  MythDB::DBError("DBUtil::BackupDB", query);
253 
254  query.prepare("INSERT INTO housekeeping(tag,lastrun) "
255  "values(:TAG ,now()) ;");
256  query.bindValue(":TAG", dbTag);
257  if (!query.exec())
258  MythDB::DBError("DBUtil::BackupDB", query);
259  }
260 
261  if (result)
262  return kDB_Backup_Completed;
263 
264  return kDB_Backup_Failed;
265 #endif // _WIN32
266 }
267 
279 bool DBUtil::CheckTables(const bool repair, const QString &options)
280 {
281  MSqlQuery query(MSqlQuery::InitCon());
282  if (!query.isConnected())
283  return false;
284 
285  const QStringList all_tables = GetTables(QStringList("MyISAM"));
286 
287  if (all_tables.empty())
288  return true;
289 
290  QString sql = QString("CHECK TABLE %1 %2;")
291  .arg(all_tables.join(", "), options);
292 
293  LOG(VB_GENERAL, LOG_CRIT, "Checking database tables.");
294  if (!query.exec(sql))
295  {
296  MythDB::DBError("DBUtil Checking Tables", query);
297  return false;
298  }
299 
300  QStringList tables = CheckRepairStatus(query);
301  bool result = true;
302  if (!tables.empty())
303  {
304  LOG(VB_GENERAL, LOG_CRIT, QString("Found crashed database table(s): %1")
305  .arg(tables.join(", ")));
306  if (repair)
307  {
308  // If RepairTables() repairs the crashed tables, return true
309  result = RepairTables(tables);
310  }
311  else
312  {
313  result = false;
314  }
315  }
316 
317  return result;
318 }
319 
337 bool DBUtil::RepairTables(const QStringList &tables)
338 {
339  MSqlQuery query(MSqlQuery::InitCon());
340  if (!query.isConnected())
341  return false;
342 
343  QString all_tables = tables.join(", ");
344  LOG(VB_GENERAL, LOG_CRIT, QString("Repairing database tables: %1")
345  .arg(all_tables));
346 
347  QString sql = QString("REPAIR TABLE %1;").arg(all_tables);
348  if (!query.exec(sql))
349  {
350  MythDB::DBError("DBUtil Repairing Tables", query);
351  return false;
352  }
353 
354  QStringList bad_tables = CheckRepairStatus(query);
355  bool result = true;
356  if (!bad_tables.empty())
357  {
358  LOG(VB_GENERAL, LOG_CRIT,
359  QString("Unable to repair crashed table(s): %1")
360  .arg(bad_tables.join(", ")));
361  result = false;
362  }
363  return result;
364 }
365 
385 {
386  QStringList tables;
387  QSqlRecord record = query.record();
388  int table_index = record.indexOf("Table");
389  int type_index = record.indexOf("Msg_type");
390  int text_index = record.indexOf("Msg_text");
391  QString table;
392  QString type;
393  QString text;
394  QString previous_table;
395  bool ok = true;
396  while (query.next())
397  {
398  table = query.value(table_index).toString();
399  type = query.value(type_index).toString();
400  text = query.value(text_index).toString();
401  if (table != previous_table)
402  {
403  if (!ok)
404  {
405  tables.append(previous_table);
406  ok = true;
407  }
408  previous_table = table;
409  }
410  // If the final row shows status OK, the table is now good
411  if ("status" == type.toLower() && "ok" == text.toLower())
412  ok = true;
413  else if ("error" == type.toLower() ||
414  ("status" == type.toLower() && "ok" != text.toLower()))
415  ok = false;
416  }
417  // Check the last table in the list
418  if (!ok)
419  tables.append(table);
420  return tables;
421 }
422 
428 QStringList DBUtil::GetTables(const QStringList &engines)
429 {
430  QStringList result;
431 
432  MSqlQuery query(MSqlQuery::InitCon());
433  if (!query.isConnected())
434  return result;
435 
436  QString sql = "SELECT CONCAT('`', TABLE_SCHEMA, "
437  " '`.`', TABLE_NAME, "
438  " '`') AS `TABLE_NAME` "
439  " FROM INFORMATION_SCHEMA.TABLES "
440  " WHERE TABLE_SCHEMA = DATABASE() "
441  " AND TABLE_TYPE = 'BASE TABLE'";
442  if (!engines.empty())
443  sql.append(QString(" AND ENGINE IN ('%1')")
444  .arg(engines.join("', '")));
445  if (!query.exec(sql))
446  {
447  MythDB::DBError("DBUtil Finding Tables", query);
448  return result;
449  }
450 
451  while (query.next())
452  {
453  result.append(query.value(0).toString());
454  }
455 
456  return result;
457 }
458 
471 QString DBUtil::CreateBackupFilename(const QString& prefix, const QString& extension)
472 {
474  return QString("%1-%2%3").arg(prefix, time, extension);
475 }
476 
487 {
488  QString directory;
489  StorageGroup sgroup("DB Backups", gCoreContext->GetHostName());
490  QStringList dirList = sgroup.GetDirList();
491  if (!dirList.empty())
492  {
493  directory = sgroup.FindNextDirMostFree();
494 
495  if (!QDir(directory).exists())
496  {
497  LOG(VB_FILE, LOG_INFO, "GetBackupDirectory() - ignoring " +
498  directory + ", using /tmp");
499  directory.clear();
500  }
501  }
502 
503  if (directory.isNull())
504  {
505  // Rather than use kDefaultStorageDir, the default for
506  // FindNextDirMostFree() when no dirs are defined for the StorageGroup,
507  // use /tmp as it's possible that kDefaultStorageDir doesn't exist
508  // and (at least on *nix) less possible that /tmp doesn't exist
509  directory = "/tmp";
510  }
511 
512  return directory;
513 }
514 
524  const QString &privateinfo, QString &filename)
525 {
526  bool ok = true;
527  filename = createTempFile("/tmp/mythtv_db_backup_conf_XXXXXX");
528  const QByteArray tmpfile = filename.toLocal8Bit();
529 
530  FILE *fp = fopen(tmpfile.constData(), "w");
531  if (!fp)
532  {
533  LOG(VB_GENERAL, LOG_ERR, LOC +
534  QString("Unable to create temporary "
535  "configuration file for creating DB backup: %1")
536  .arg(tmpfile.constData()));
537  filename = "";
538  ok = false;
539  }
540  else
541  {
542  if (chmod(tmpfile.constData(), S_IRUSR))
543  {
544  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Error changing permissions '%1'")
545  .arg(tmpfile.constData()) + ENO);
546  }
547 
548  QByteArray outarr = privateinfo.toLocal8Bit();
549  fprintf(fp, "%s", outarr.constData());
550 
551  if (fclose(fp))
552  {
553  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Error closing '%1'")
554  .arg(tmpfile.constData()) + ENO);
555  }
556  }
557 
558  return ok;
559 }
560 
567 bool DBUtil::DoBackup(const QString &backupScript, QString &filename,
568  bool disableRotation)
569 {
570  DatabaseParams dbParams = GetMythDB()->GetDatabaseParams();
571  QString dbSchemaVer = gCoreContext->GetSetting("DBSchemaVer");
572  QString backupDirectory = GetBackupDirectory();
573  QString backupFilename = CreateBackupFilename(dbParams.m_dbName + "-" +
574  dbSchemaVer, ".sql");
575  QString scriptArgs = gCoreContext->GetSetting("BackupDBScriptArgs");
576  QString rotate = "";
577  if (disableRotation)
578  {
579  if (!(scriptArgs.contains("rotate", Qt::CaseInsensitive)))
580  rotate = "rotate=-1";
581  }
582 
583 
584  QString privateinfo =
585  QString("DBHostName=%1\nDBPort=%2\n"
586  "DBUserName=%3\nDBPassword=%4\n"
587  "DBName=%5\nDBSchemaVer=%6\n"
588  "DBBackupDirectory=%7\nDBBackupFilename=%8\n%9\n")
589  .arg(dbParams.m_dbHostName, QString::number(dbParams.m_dbPort),
590  dbParams.m_dbUserName, dbParams.m_dbPassword,
591  dbParams.m_dbName, dbSchemaVer,
592  backupDirectory, backupFilename,
593  rotate);
594  QString tempDatabaseConfFile;
595  bool hastemp = CreateTemporaryDBConf(privateinfo, tempDatabaseConfFile);
596  if (!hastemp)
597  LOG(VB_GENERAL, LOG_ERR, LOC + "Attempting backup, anyway.");
598 
599  LOG(VB_GENERAL, LOG_ERR, QString("Backing up database with script: '%1'")
600  .arg(backupScript));
601 
602  QString command = backupScript + " " + scriptArgs + " " +
603  tempDatabaseConfFile;
605 
606  if (hastemp)
607  {
608  QByteArray tmpfile = tempDatabaseConfFile.toLocal8Bit();
609  unlink(tmpfile.constData());
610  }
611 
612  if (status != GENERIC_EXIT_OK)
613  {
614  LOG(VB_GENERAL, LOG_ERR, LOC +
615  QString("Error backing up database: %1 (%2)")
616  .arg(command).arg(status));
617  filename = "__FAILED__";
618  return false;
619  }
620 
621  LOG(VB_GENERAL, LOG_CRIT, "Database Backup complete.");
622 
623  QDir dir(backupDirectory, backupFilename + "*");
624  uint numfiles = dir.count();
625  if (numfiles < 1)
626  {
627  // If no file begins with the suggested filename, don't show the backup
628  // filename in the GUI message -- the script probably used some other
629  // filename
630  filename = "";
631  LOG(VB_FILE, LOG_ERR, LOC +
632  QString("No files beginning with the suggested database backup "
633  "filename '%1' were found in '%2'.")
634  .arg(backupFilename, backupDirectory));
635  }
636  else
637  {
638  filename = dir.path() + "/" + dir[0];;
639  if (numfiles > 1)
640  {
641  LOG(VB_FILE, LOG_ERR, LOC +
642  QString("Multiple files beginning with the suggested database "
643  "backup filename '%1' were found in '%2'. "
644  "Assuming the first is the backup.")
645  .arg(backupFilename, backupDirectory));
646  }
647  }
648 
649  if (!filename.isEmpty())
650  {
651  LOG(VB_GENERAL, LOG_CRIT, QString("Backed up database to file: '%1'")
652  .arg(filename));
653  }
654 
655  return true;
656 }
657 
665 {
666  DatabaseParams dbParams = GetMythDB()->GetDatabaseParams();
667  QString dbSchemaVer = gCoreContext->GetSetting("DBSchemaVer");
668  QString backupDirectory = GetBackupDirectory();
669 
670  QString command;
671  QString compressCommand("");
672  QString extension = ".sql";
673  if (QFile::exists("/bin/gzip"))
674  compressCommand = "/bin/gzip";
675  else if (QFile::exists("/usr/bin/gzip"))
676  compressCommand = "/usr/bin/gzip";
677  else
678  LOG(VB_GENERAL, LOG_CRIT, "Neither /bin/gzip nor /usr/bin/gzip exist. "
679  "The database backup will be uncompressed.");
680 
681  QString backupFilename = CreateBackupFilename(
682  dbParams.m_dbName + "-" + dbSchemaVer, extension);
683  QString backupPathname = backupDirectory + "/" + backupFilename;
684 
685  QString privateinfo = QString(
686  "[client]\npassword=%1\n[mysqldump]\npassword=%2\n")
687  .arg(dbParams.m_dbPassword, dbParams.m_dbPassword);
688  QString tempExtraConfFile;
689  if (!CreateTemporaryDBConf(privateinfo, tempExtraConfFile))
690  return false;
691 
692  QString portArg = "";
693  if (dbParams.m_dbPort > 0)
694  portArg = QString(" --port='%1'").arg(dbParams.m_dbPort);
695  command = QString("mysqldump --defaults-extra-file='%1' --host='%2'%3"
696  " --user='%4' --add-drop-table --add-locks"
697  " --allow-keywords --complete-insert"
698  " --extended-insert --lock-tables --no-create-db --quick"
699  " '%5' > '%6' 2>/dev/null")
700  .arg(tempExtraConfFile, dbParams.m_dbHostName,
701  portArg, dbParams.m_dbUserName,
702  dbParams.m_dbName, backupPathname);
703 
704  LOG(VB_FILE, LOG_INFO, QString("Backing up database with command: '%1'")
705  .arg(command));
706  LOG(VB_GENERAL, LOG_CRIT, QString("Backing up database to file: '%1'")
707  .arg(backupPathname));
708 
710 
711  QByteArray tmpfile = tempExtraConfFile.toLocal8Bit();
712  unlink(tmpfile.constData());
713 
714  if (status != GENERIC_EXIT_OK)
715  {
716  LOG(VB_GENERAL, LOG_ERR, LOC +
717  QString("Error backing up database: '%1' (%2)")
718  .arg(command).arg(status));
719  filename = "__FAILED__";
720  return false;
721  }
722 
723  if (compressCommand != "")
724  {
725  LOG(VB_GENERAL, LOG_CRIT, "Compressing database backup file.");
726  compressCommand += " " + backupPathname;
727  status = myth_system(compressCommand, kMSDontBlockInputDevs);
728 
729  if (status != GENERIC_EXIT_OK)
730  {
731  LOG(VB_GENERAL, LOG_CRIT,
732  "Compression failed, backup file will remain uncompressed.");
733  }
734  else
735  {
736  backupPathname += ".gz";
737 
738  LOG(VB_GENERAL, LOG_CRIT, QString("Database Backup filename: '%1'")
739  .arg(backupPathname));
740  }
741  }
742 
743  LOG(VB_GENERAL, LOG_CRIT, "Database Backup complete.");
744 
745  filename = backupPathname;
746  return true;
747 }
748 
754 {
755  // Allow users to override the string provided by the database server in
756  // case the value was changed to an unrecognizable string by whomever
757  // compiled the MySQL server
758  QString dbmsVersion = gCoreContext->GetSetting("DBMSVersionOverride");
759 
760  if (dbmsVersion.isEmpty())
761  {
762  MSqlQuery query(MSqlQuery::InitCon());
763  query.prepare("SELECT VERSION();");
764  if (!query.exec() || !query.next())
765  {
766  LOG(VB_GENERAL, LOG_ERR, LOC +
767  "Unable to determine MySQL version.");
768  MythDB::DBError("DBUtil Querying DBMS version", query);
769  dbmsVersion.clear();
770  }
771  else
772  dbmsVersion = query.value(0).toString();
773  }
774  m_versionString = dbmsVersion;
775 
776  return !m_versionString.isEmpty();
777 }
778 
783 {
784  if (m_versionString.isEmpty())
785  if (!QueryDBMSVersion())
786  return false;
787 
788  static const QRegularExpression parseVersion
789  { R"(^(\d+)(?:\.(\d+)(?:\.(\d+))?)?)" };
790  auto match = parseVersion.match(m_versionString);
791  if (!match.hasMatch())
792  return false;
793 
794  // If any of these wasn't matched, the captured string will be
795  // empty and toInt will parse it as a zero.
796  m_versionMajor = match.capturedView(1).toInt(nullptr);
797  m_versionMinor = match.capturedView(2).toInt(nullptr);
798  m_versionPoint = match.capturedView(3).toInt(nullptr);
799 
800  return m_versionMajor > -1;
801 }
802 
807 {
808  int count = 0;
809 
810  MSqlQuery query(MSqlQuery::InitCon());
811  if (!query.isConnected())
812  {
813  LOG(VB_GENERAL, LOG_DEBUG, "Not connected to DB");
814  return count;
815  }
816 
817  if (!query.exec("SHOW PROCESSLIST;"))
818  {
819  MythDB::DBError("DBUtil CountClients", query);
820  return count;
821  }
822 
823  QSqlRecord record = query.record();
824  int db_index = record.indexOf("db");
825  QString dbName = GetMythDB()->GetDatabaseName();
826  QString inUseDB;
827 
828  while (query.next())
829  {
830  inUseDB = query.value(db_index).toString();
831  if (inUseDB == dbName)
832  ++count;
833  }
834 
835  // On average, each myth program has 4 database connections,
836  // but we round up just in case a new program is loading:
837  count = (count + 3)/4;
838 
839  LOG(VB_GENERAL, LOG_DEBUG,
840  QString("DBUtil::CountClients() found %1").arg(count));
841 
842  return count;
843 }
844 
848 bool DBUtil::TryLockSchema(MSqlQuery &query, uint timeout_secs)
849 {
850  query.prepare("SELECT GET_LOCK('schemaLock', :TIMEOUT)");
851  query.bindValue(":TIMEOUT", timeout_secs);
852  return query.exec() && query.first() && query.value(0).toBool();
853 }
854 
856 {
857  query.prepare("SELECT RELEASE_LOCK('schemaLock')");
858  if (!query.exec())
859  {
860  MythDB::DBError("DBUtil UnlockSchema", query);
861  }
862 }
863 
868 {
869  MSqlQuery query(MSqlQuery::InitCon());
870  query.prepare("SELECT CONVERT_TZ(NOW(), 'SYSTEM', 'Etc/UTC')");
871  if (!query.exec() || !query.next())
872  {
873  LOG(VB_GENERAL, LOG_ERR, "MySQL time zone support check failed");
874  return false;
875  }
876 
877  return !query.value(0).isNull();
878 }
879 
880 /* vim: set expandtab tabstop=4 shiftwidth=4: */
DBUtil::QueryDBMSVersion
bool QueryDBMSVersion(void)
Reads and returns the QString version name from the DBMS or returns QString() in the event of an erro...
Definition: dbutil.cpp:753
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:811
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:128
LOC
#define LOC
Definition: dbutil.cpp:26
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:84
ENO
#define ENO
This can be appended to the LOG args with "+".
Definition: mythlogging.h:73
DatabaseParams::m_dbHostName
QString m_dbHostName
database server
Definition: mythdbparams.h:22
dbutil.h
kMSDontBlockInputDevs
@ kMSDontBlockInputDevs
avoid blocking LIRC & Joystick Menu
Definition: mythsystem.h:36
kMSAnonLog
@ kMSAnonLog
anonymize the logs
Definition: mythsystem.h:44
mythdb.h
DatabaseParams
Structure containing the basic Database parameters.
Definition: mythdbparams.h:10
MSqlQuery::record
QSqlRecord record(void) const
Definition: mythdbcon.h:217
DBUtil::CreateBackupFilename
static QString CreateBackupFilename(const QString &prefix="mythconverg", const QString &extension=".sql")
Creates a filename to use for the filename.
Definition: dbutil.cpp:471
DBUtil::IsBackupInProgress
static bool IsBackupInProgress(void)
Test to see if a DB backup is in progress.
Definition: dbutil.cpp:92
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:205
kDB_Backup_Empty_DB
@ kDB_Backup_Empty_DB
Definition: dbutil.h:14
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:617
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
DBUtil::CheckTables
static bool CheckTables(bool repair=false, const QString &options="QUICK")
Checks database tables.
Definition: dbutil.cpp:279
GetMythDB
MythDB * GetMythDB(void)
Definition: mythdb.cpp:50
mythdirs.h
myth_system
uint myth_system(const QString &command, uint flags, std::chrono::seconds timeout)
Definition: mythsystemlegacy.cpp:506
GENERIC_EXIT_OK
@ GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:11
hardwareprofile.distros.mythtv_data.data_mythtv.prefix
string prefix
Definition: data_mythtv.py:40
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
mythburn.FILE
int FILE
Definition: mythburn.py:139
DBUtil::ParseDBMSVersion
bool ParseDBMSVersion(void)
Parses m_versionString to find the major, minor, and point version.
Definition: dbutil.cpp:782
mythsystemlegacy.h
DBUtil::m_versionMinor
int m_versionMinor
Definition: dbutil.h:81
DBUtil::GetDBMSVersion
QString GetDBMSVersion(void)
Returns the QString version name of the DBMS or QString() in the event of an error.
Definition: dbutil.cpp:38
DBUtil::m_versionString
QString m_versionString
Definition: dbutil.h:78
DatabaseParams::m_dbPort
int m_dbPort
database port
Definition: mythdbparams.h:24
mythdate.h
minor
#define minor(X)
Definition: compat.h:78
kDB_Backup_Disabled
@ kDB_Backup_Disabled
Definition: dbutil.h:15
mythlogging.h
DBUtil::CheckRepairStatus
static QStringList CheckRepairStatus(MSqlQuery &query)
Parse the results of a CHECK TABLE or REPAIR TABLE run.
Definition: dbutil.cpp:384
DBUtil::CreateTemporaryDBConf
static bool CreateTemporaryDBConf(const QString &privateinfo, QString &filename)
Creates temporary file containing sensitive DB info.
Definition: dbutil.cpp:523
MythDate::kFilename
@ kFilename
Default UTC, "yyyyMMddhhmmss".
Definition: mythdate.h:18
MSqlQuery::first
bool first(void)
Wrap QSqlQuery::first() so we can display the query results.
Definition: mythdbcon.cpp:821
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:549
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:226
GetShareDir
QString GetShareDir(void)
Definition: mythdirs.cpp:254
kDB_Backup_Completed
@ kDB_Backup_Completed
Definition: dbutil.h:13
createTempFile
QString createTempFile(QString name_template, bool dir)
Definition: mythmiscutil.cpp:323
DBUtil::BackupDB
static MythDBBackupStatus BackupDB(QString &filename, bool disableRotation=false)
Requests a backup of the database.
Definition: dbutil.cpp:190
DBUtil::CheckTimeZoneSupport
static bool CheckTimeZoneSupport(void)
Check if MySQL has working timz zone support.
Definition: dbutil.cpp:867
storagegroup.h
DBUtil::CountClients
static int CountClients(void)
Estimate the number of MythTV programs using the database.
Definition: dbutil.cpp:806
DBUtil::m_versionPoint
int m_versionPoint
Definition: dbutil.h:82
DBUtil::DoBackup
static bool DoBackup(const QString &backupScript, QString &filename, bool disableRotation=false)
Creates a backup of the database by executing the backupScript.
Definition: dbutil.cpp:567
DatabaseParams::m_dbPassword
QString m_dbPassword
DB password.
Definition: mythdbparams.h:26
kDB_Backup_Failed
@ kDB_Backup_Failed
Definition: dbutil.h:12
DatabaseParams::m_dbName
QString m_dbName
database name
Definition: mythdbparams.h:27
StorageGroup::GetDirList
QStringList GetDirList(void) const
Definition: storagegroup.h:23
MSqlQuery::isConnected
bool isConnected(void) const
Only updated once during object creation.
Definition: mythdbcon.h:138
uint
unsigned int uint
Definition: compat.h:81
MythDBBackupStatus
MythDBBackupStatus
Definition: dbutil.h:9
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
DBUtil::TryLockSchema
static bool TryLockSchema(MSqlQuery &query, uint timeout_secs)
Try to get a lock on the table schemalock.
Definition: dbutil.cpp:848
DBUtil::RepairTables
static bool RepairTables(const QStringList &tables)
Repairs database tables.
Definition: dbutil.cpp:337
MythDate::fromString
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:34
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:905
mythmiscutil.h
MythDate::secsInPast
std::chrono::seconds secsInPast(const QDateTime &past)
Definition: mythdate.cpp:203
mythcorecontext.h
StorageGroup::FindNextDirMostFree
QString FindNextDirMostFree(void)
Definition: storagegroup.cpp:671
DBUtil::GetBackupDirectory
static QString GetBackupDirectory()
Determines the appropriate path for the database backup.
Definition: dbutil.cpp:486
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:887
DatabaseParams::m_dbUserName
QString m_dbUserName
DB user name.
Definition: mythdbparams.h:25
DBUtil::kUnknownVersionNumber
static const int kUnknownVersionNumber
Definition: dbutil.h:57
DBUtil::m_versionMajor
int m_versionMajor
Definition: dbutil.h:80
DBUtil::IsNewDatabase
static bool IsNewDatabase(void)
Returns true for a new (empty) database.
Definition: dbutil.cpp:78
StorageGroup
Definition: storagegroup.h:11
MythDate::kDatabase
@ kDatabase
Default UTC, database format.
Definition: mythdate.h:27
DBUtil::UnlockSchema
static void UnlockSchema(MSqlQuery &query)
Definition: dbutil.cpp:855
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:837
exitcodes.h
DBUtil::GetTables
static QStringList GetTables(const QStringList &engines=QStringList())
Retrieves a list of tables from the database.
Definition: dbutil.cpp:428
build_compdb.filename
filename
Definition: build_compdb.py:21
nv_python_libs.bbciplayer.bbciplayer_api.version
string version
Definition: bbciplayer_api.py:77
build_compdb.options
options
Definition: build_compdb.py:11
MythCoreContext::SaveSettingOnHost
bool SaveSettingOnHost(const QString &key, const QString &newValue, const QString &host)
Definition: mythcorecontext.cpp:890
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:897
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:836
DBUtil::CompareDBMSVersion
int CompareDBMSVersion(int major, int minor=0, int point=0)
Compares the version of the active DBMS with the provided version.
Definition: dbutil.cpp:57