MythTV  master
mythtv/libs/libmythtv/dbcheck.cpp
Go to the documentation of this file.
1 #include "mythconfig.h"
2 
3 #include <cstdio>
4 #include <iostream>
5 using namespace std;
6 
7 #include <QString>
8 #include <QSqlError>
9 #include "dbcheck.h"
10 
11 #include "mythversion.h"
12 #include "dbutil.h"
13 #include "mythcorecontext.h"
14 #include "schemawizard.h"
15 #include "mythdb.h"
16 #include "mythlogging.h"
17 #include "videodbcheck.h" // for 1267
18 #include "compat.h"
19 #include "recordingrule.h"
20 #include "recordingprofile.h"
21 #include "recordinginfo.h"
22 #include "cardutil.h"
23 #include "videodisplayprofile.h"
24 
25 // TODO convert all dates to UTC
26 
27 #define MINIMUM_DBMS_VERSION 5,0,15
28 
30 
31 static bool UpdateDBVersionNumber(const QString &newnumber, QString &dbver);
32 static bool performActualUpdate(
33  const char **updates, const char *version, QString &dbver);
34 static bool doUpgradeTVDatabaseSchema(void);
35 
36 #if CONFIG_SYSTEMD_NOTIFY
37 #include <systemd/sd-daemon.h>
38 #define db_sd_notify(x) \
39  if (informSystemd) \
40  (void)sd_notify(0, "STATUS=Database update " x);
41 #else
42 #define db_sd_notify(x)
43 #endif
44 
357 static bool UpdateDBVersionNumber(const QString &newnumber, QString &dbver)
358 {
359  // delete old schema version
360  MSqlQuery query(MSqlQuery::InitCon());
361 
362  QString thequery = "DELETE FROM settings WHERE value='DBSchemaVer';";
363  query.prepare(thequery);
364 
365  if (!query.exec())
366  {
367  QString msg =
368  QString("DB Error (Deleting old DB version number): \n"
369  "Query was: %1 \nError was: %2 \nnew version: %3")
370  .arg(thequery)
371  .arg(MythDB::DBErrorMessage(query.lastError()))
372  .arg(newnumber);
373  LOG(VB_GENERAL, LOG_ERR, msg);
374  return false;
375  }
376 
377  // set new schema version
378  thequery = QString("INSERT INTO settings (value, data, hostname) "
379  "VALUES ('DBSchemaVer', %1, NULL);").arg(newnumber);
380  query.prepare(thequery);
381 
382  if (!query.exec())
383  {
384  QString msg =
385  QString("DB Error (Setting new DB version number): \n"
386  "Query was: %1 \nError was: %2 \nnew version: %3")
387  .arg(thequery)
388  .arg(MythDB::DBErrorMessage(query.lastError()))
389  .arg(newnumber);
390  LOG(VB_GENERAL, LOG_ERR, msg);
391  return false;
392  }
393 
394  dbver = newnumber;
395 
396  return true;
397 }
398 
405 static bool performUpdateSeries(const char **updates)
406 {
407  MSqlQuery query(MSqlQuery::InitCon());
408 
409  int counter = 0;
410  const char *thequery = updates[counter];
411 
412  while (thequery != nullptr)
413  {
414  if ((strlen(thequery) != 0U) && !query.exec(thequery))
415  {
416  QString msg =
417  QString("DB Error (Performing database upgrade): \n"
418  "Query was: %1 \nError was: %2")
419  .arg(thequery)
420  .arg(MythDB::DBErrorMessage(query.lastError()));
421  LOG(VB_GENERAL, LOG_ERR, msg);
422  return false;
423  }
424 
425  counter++;
426  thequery = updates[counter];
427  }
428 
429  return true;
430 }
431 
442  const char **updates, const char *version, QString &dbver)
443 {
444  MSqlQuery query(MSqlQuery::InitCon());
445 
446  LOG(VB_GENERAL, LOG_CRIT, QString("Upgrading to MythTV schema version ") +
447  version);
448 
449  if (!performUpdateSeries(updates))
450  return false;
451 
452  if (!UpdateDBVersionNumber(version, dbver))
453  return false;
454 
455  return true;
456 }
457 
472 bool UpgradeTVDatabaseSchema(const bool upgradeAllowed,
473  const bool upgradeIfNoUI,
474  const bool informSystemd)
475 {
476 #ifdef IGNORE_SCHEMA_VER_MISMATCH
477  return true;
478 #endif
479 #if CONFIG_SYSTEMD_NOTIFY == 0
480  Q_UNUSED(informSystemd);
481 #endif
482  SchemaUpgradeWizard *schema_wizard = nullptr;
483 
484  // Suppress DB messages and turn of the settings cache,
485  // These are likely to confuse the users and the code, respectively.
486  GetMythDB()->SetSuppressDBMessages(true);
488 
489  // Get the schema upgrade lock
490  MSqlQuery query(MSqlQuery::InitCon());
491  bool locked = DBUtil::TryLockSchema(query, 1);
492  for (uint i = 0; i < 2*60 && !locked; i++)
493  {
494  db_sd_notify("waiting for lock");
495  LOG(VB_GENERAL, LOG_INFO, "Waiting for database schema upgrade lock");
496  locked = DBUtil::TryLockSchema(query, 1);
497  if (locked)
498  LOG(VB_GENERAL, LOG_INFO, "Got schema upgrade lock");
499  }
500  if (!locked)
501  {
502  LOG(VB_GENERAL, LOG_INFO, "Failed to get schema upgrade lock");
503  goto upgrade_error_exit;
504  }
505 
506  // Determine if an upgrade is needed
507  schema_wizard = SchemaUpgradeWizard::Get(
508  "DBSchemaVer", "MythTV", currentDatabaseVersion);
509  if (schema_wizard->Compare() == 0) // DB schema is what we need it to be..
510  goto upgrade_ok_exit;
511 
512  if (!upgradeAllowed)
513  LOG(VB_GENERAL, LOG_WARNING, "Not allowed to upgrade the database.");
514 
515  db_sd_notify("waiting for user input");
516  // Pop up messages, questions, warnings, etc.
517  switch (schema_wizard->PromptForUpgrade(
518  "TV", upgradeAllowed, upgradeIfNoUI, MINIMUM_DBMS_VERSION))
519  {
521  goto upgrade_ok_exit;
522  case MYTH_SCHEMA_ERROR:
523  case MYTH_SCHEMA_EXIT:
524  goto upgrade_error_exit;
525  case MYTH_SCHEMA_UPGRADE:
526  break;
527  }
528 
529  LOG(VB_GENERAL, LOG_DEBUG, QString("Newest MythTV Schema Version : %1")
530  .arg(currentDatabaseVersion));
531 
532  // Upgrade the schema
533  db_sd_notify("upgrading database");
535  {
536  LOG(VB_GENERAL, LOG_ERR, "Database schema upgrade failed.");
537  goto upgrade_error_exit;
538  }
539 
540  LOG(VB_GENERAL, LOG_INFO, "Database schema upgrade complete.");
541 
542  // On any exit we want to re-enable the DB messages so errors
543  // are reported and we want to make sure the setting cache is
544  // enabled for good performance and we must unlock the schema
545  // lock. We use gotos with labels so it's impossible to miss
546  // these steps.
547  upgrade_ok_exit:
548  db_sd_notify("success");
549  GetMythDB()->SetSuppressDBMessages(false);
551  if (locked)
552  DBUtil::UnlockSchema(query);
553  return true;
554 
555  upgrade_error_exit:
556  db_sd_notify("failed");
557  GetMythDB()->SetSuppressDBMessages(false);
559  if (locked)
560  DBUtil::UnlockSchema(query);
561  return false;
562 }
563 
577 static bool doUpgradeTVDatabaseSchema(void)
578 {
579  QString dbver = gCoreContext->GetSetting("DBSchemaVer");
580 
581  if (dbver == currentDatabaseVersion)
582  {
583  return true;
584  }
585 
586  // Don't rely on this, please specify these when creating the database.
587  {
588  MSqlQuery query(MSqlQuery::InitCon());
589  if (!query.exec(QString("ALTER DATABASE %1 DEFAULT "
590  "CHARACTER SET utf8 COLLATE utf8_general_ci;")
592  {
593  MythDB::DBError("UpgradeTVDatabaseSchema -- alter charset", query);
594  }
595  }
596 
597  if (DBUtil::IsNewDatabase())
598  {
599  if (!InitializeMythSchema())
600  return false;
601  dbver = gCoreContext->GetSetting("DBSchemaVer");
602  }
603 
604  if (dbver.isEmpty() || dbver.toInt() < 1027)
605  {
606  LOG(VB_GENERAL, LOG_ERR, "Unrecognized database schema version. "
607  "Unable to upgrade database.");
608  return false;
609  }
610  if (dbver.toInt() < 1244)
611  {
612  LOG(VB_GENERAL, LOG_ERR, "Your database version is too old to upgrade "
613  "with this version of MythTV. You will need "
614  "to use mythtv-setup from MythTV 0.22, 0.23, "
615  "or 0.24 to upgrade your database before "
616  "upgrading to this version of MythTV.");
617  return false;
618  }
619 
620  if (dbver == "1244")
621  {
622  const char *updates[] = {
623 "ALTER TABLE cardinput DROP COLUMN freetoaironly;",
624 "ALTER TABLE cardinput DROP COLUMN radioservices;",
625 nullptr
626 };
627  if (!performActualUpdate(updates, "1245", dbver))
628  return false;
629  }
630 
631  if (dbver == "1245")
632  {
633  const char *updates[] = {
634 "DELETE FROM capturecard WHERE cardtype = 'DBOX2';",
635 "DELETE FROM profilegroups WHERE cardtype = 'DBOX2';",
636 "ALTER TABLE capturecard DROP COLUMN dbox2_port;",
637 "ALTER TABLE capturecard DROP COLUMN dbox2_httpport;",
638 "ALTER TABLE capturecard DROP COLUMN dbox2_host;",
639 nullptr
640 };
641  if (!performActualUpdate(updates, "1246", dbver))
642  return false;
643  }
644 
645  if (dbver == "1246")
646  {
647  const char *updates[] = {
648 "ALTER TABLE recorded ADD COLUMN bookmarkupdate timestamp default 0 NOT NULL",
649 "UPDATE recorded SET bookmarkupdate = lastmodified+1 WHERE bookmark = 1",
650 "UPDATE recorded SET bookmarkupdate = lastmodified WHERE bookmark = 0",
651 nullptr
652 };
653  if (!performActualUpdate(updates, "1247", dbver))
654  return false;
655  }
656 
657  if (dbver == "1247")
658  {
659  const char *updates[] = {
660 "INSERT INTO profilegroups SET name = \"Import Recorder\", cardtype = 'IMPORT', is_default = 1;",
661 "INSERT INTO recordingprofiles SET name = \"Default\", profilegroup = 14;",
662 "INSERT INTO recordingprofiles SET name = \"Live TV\", profilegroup = 14;",
663 "INSERT INTO recordingprofiles SET name = \"High Quality\", profilegroup = 14;",
664 "INSERT INTO recordingprofiles SET name = \"Low Quality\", profilegroup = 14;",
665 nullptr
666 };
667  if (!performActualUpdate(updates, "1248", dbver))
668  return false;
669  }
670 
671  if (dbver == "1248")
672  {
673  const char *updates[] = {
674 "DELETE FROM keybindings WHERE action = 'CUSTOMEDIT' "
675  "AND context = 'TV Frontend' AND keylist = 'E';",
676 nullptr
677 };
678  if (!performActualUpdate(updates, "1249", dbver))
679  return false;
680  }
681 
682  if (dbver == "1249")
683  {
684  LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1250");
685 
686  MSqlQuery select(MSqlQuery::InitCon());
687  select.prepare("SELECT hostname, data FROM settings "
688  " WHERE value = 'StickyKeys'");
689 
690  if (!select.exec())
691  {
692  MythDB::DBError("Unable to retrieve StickyKeys values.", select);
693  }
694  else
695  {
696  MSqlQuery update(MSqlQuery::InitCon());
697  while (select.next())
698  {
699  QString hostname = select.value(0).toString();
700  QString sticky_keys = select.value(1).toString();
701 
702  if ("1" == sticky_keys)
703  {
704  // Only remap the keys if they're currently set to defaults
705  update.prepare("UPDATE keybindings "
706  " SET keylist = :KEYS "
707  " WHERE context = 'TV Playback' AND "
708  " action = :ACTION AND "
709  " hostname = :HOSTNAME AND "
710  " keylist = :DEFAULT_KEYS");
711 
712  QString keylist = "";
713  QString action = "SEEKFFWD";
714  QString default_keys = "Right";
715 
716  update.bindValue(":KEYS", keylist);
717  update.bindValue(":ACTION", action);
718  update.bindValue(":HOSTNAME", hostname);
719  update.bindValue(":DEFAULT_KEYS", default_keys);
720  if (!update.exec())
721  MythDB::DBError("Unable to update keybindings",
722  update);
723 
724  keylist = "";
725  action = "SEEKRWND";
726  default_keys = "Left";
727 
728  update.bindValue(":KEYS", keylist);
729  update.bindValue(":ACTION", action);
730  update.bindValue(":HOSTNAME", hostname);
731  update.bindValue(":DEFAULT_KEYS", default_keys);
732  if (!update.exec())
733  MythDB::DBError("Unable to update keybindings",
734  update);
735 
736  keylist = ">,.,Right";
737  action = "FFWDSTICKY";
738  default_keys = ">,.";
739 
740  update.bindValue(":KEYS", keylist);
741  update.bindValue(":ACTION", action);
742  update.bindValue(":HOSTNAME", hostname);
743  update.bindValue(":DEFAULT_KEYS", default_keys);
744  if (!update.exec())
745  MythDB::DBError("Unable to update keybindings",
746  update);
747 
748  keylist = ",,<,Left";
749  action = "RWNDSTICKY";
750  default_keys = ",,<";
751 
752  update.bindValue(":KEYS", keylist);
753  update.bindValue(":ACTION", action);
754  update.bindValue(":HOSTNAME", hostname);
755  update.bindValue(":DEFAULT_KEYS", default_keys);
756  if (!update.exec())
757  MythDB::DBError("Unable to update keybindings",
758  update);
759  }
760  }
761  }
762 
763  if (!UpdateDBVersionNumber("1250", dbver))
764  return false;
765  }
766 
767  if (dbver == "1250")
768  {
769  const char *updates[] = {
770 "UPDATE recorded SET bookmark = 1 WHERE bookmark != 0;",
771 nullptr
772 };
773  if (!performActualUpdate(updates, "1251", dbver))
774  return false;
775  }
776 
777  if (dbver == "1251")
778  {
779  LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1252");
780 
781  MSqlQuery query(MSqlQuery::InitCon());
782  query.prepare("SHOW INDEX FROM recgrouppassword");
783 
784  if (!query.exec())
785  {
786  MythDB::DBError("Unable to retrieve current indices on "
787  "recgrouppassword.", query);
788  }
789  else
790  {
791  while (query.next())
792  {
793  QString index_name = query.value(2).toString();
794 
795  if ("recgroup" == index_name)
796  {
797  MSqlQuery update(MSqlQuery::InitCon());
798  update.prepare("ALTER TABLE recgrouppassword "
799  " DROP INDEX recgroup");
800 
801  if (!update.exec())
802  MythDB::DBError("Unable to drop duplicate index on "
803  "recgrouppassword. Ignoring.",
804  update);
805  break;
806  }
807  }
808  }
809 
810  if (!UpdateDBVersionNumber("1252", dbver))
811  return false;
812  }
813 
814  if (dbver == "1252")
815  {
816  LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1253");
817 
818  MSqlQuery select(MSqlQuery::InitCon());
819  select.prepare("SELECT hostname, data FROM settings "
820  " WHERE value = 'StickyKeys'");
821 
822  if (!select.exec())
823  {
824  MythDB::DBError("Unable to retrieve StickyKeys values.", select);
825  }
826  else
827  {
828  MSqlQuery update(MSqlQuery::InitCon());
829  while (select.next())
830  {
831  QString hostname = select.value(0).toString();
832  QString sticky_keys = select.value(1).toString();
833 
834  if ("1" == sticky_keys)
835  {
836  // Only remap the keys if they're currently set to defaults
837  update.prepare("UPDATE keybindings "
838  " SET keylist = :KEYS "
839  " WHERE context = 'TV Playback' AND "
840  " action = :ACTION AND "
841  " hostname = :HOSTNAME AND "
842  " keylist = :DEFAULT_KEYS");
843 
844  QString keylist = ">,.";
845  QString action = "FFWDSTICKY";
846  QString default_keys = ">,.,Right";
847 
848  update.bindValue(":KEYS", keylist);
849  update.bindValue(":ACTION", action);
850  update.bindValue(":HOSTNAME", hostname);
851  update.bindValue(":DEFAULT_KEYS", default_keys);
852  if (!update.exec())
853  MythDB::DBError("Unable to update keybindings",
854  update);
855 
856  keylist = ",,<";
857  action = "RWNDSTICKY";
858  default_keys = ",,<,Left";
859 
860  update.bindValue(":KEYS", keylist);
861  update.bindValue(":ACTION", action);
862  update.bindValue(":HOSTNAME", hostname);
863  update.bindValue(":DEFAULT_KEYS", default_keys);
864  if (!update.exec())
865  MythDB::DBError("Unable to update keybindings",
866  update);
867  }
868  }
869  }
870 
871  if (!UpdateDBVersionNumber("1253", dbver))
872  return false;
873  }
874 
875  if (dbver == "1253")
876  {
877  if (gCoreContext->GetNumSetting("have-nit-fix") == 1)
878  {
879  // User has previously applied patch from ticket #7486.
880  LOG(VB_GENERAL, LOG_CRIT,
881  "Upgrading to MythTV schema version 1254");
882  if (!UpdateDBVersionNumber("1254", dbver))
883  return false;
884  }
885  else
886  {
887  const char *updates[] = {
888  "ALTER TABLE videosource ADD dvb_nit_id INT(6) DEFAULT -1;",
889  nullptr
890  };
891  if (!performActualUpdate(updates, "1254", dbver))
892  return false;
893  }
894  }
895 
896  if (dbver == "1254")
897  {
898  const char *updates[] = {
899 "ALTER TABLE cardinput DROP COLUMN shareable;",
900 nullptr
901 };
902  if (!performActualUpdate(updates, "1255", dbver))
903  return false;
904  }
905 
906  if (dbver == "1255")
907  {
908  const char *updates[] = {
909 "INSERT INTO keybindings (SELECT 'Main Menu', 'EXIT', 'System Exit', "
910  "(CASE data WHEN '1' THEN 'Ctrl+Esc' WHEN '2' THEN 'Meta+Esc' "
911  "WHEN '3' THEN 'Alt+Esc' WHEN '4' THEN 'Esc' ELSE '' END), hostname "
912  "FROM settings WHERE value = 'AllowQuitShutdown' GROUP BY hostname) "
913  "ON DUPLICATE KEY UPDATE keylist = VALUES(keylist);",
914 nullptr
915 };
916  if (!performActualUpdate(updates, "1256", dbver))
917  return false;
918  }
919 
920  if (dbver == "1256")
921  {
922  const char *updates[] = {
923 "ALTER TABLE record DROP COLUMN tsdefault;",
924 nullptr
925 };
926  if (!performActualUpdate(updates, "1257", dbver))
927  return false;
928  }
929 
930  if (dbver == "1257")
931  {
932  const char *updates[] = {
933 "CREATE TABLE internetcontent "
934 "( name VARCHAR(255) NOT NULL,"
935 " thumbnail VARCHAR(255),"
936 " type SMALLINT(3) NOT NULL,"
937 " author VARCHAR(128) NOT NULL,"
938 " description TEXT NOT NULL,"
939 " commandline TEXT NOT NULL,"
940 " version DOUBLE NOT NULL,"
941 " updated DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',"
942 " search BOOL NOT NULL,"
943 " tree BOOL NOT NULL,"
944 " podcast BOOL NOT NULL,"
945 " download BOOL NOT NULL,"
946 " host VARCHAR(128)) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
947 "CREATE TABLE internetcontentarticles "
948 "( feedtitle VARCHAR(255) NOT NULL,"
949 " path TEXT NOT NULL,"
950 " paththumb TEXT NOT NULL,"
951 " title VARCHAR(255) NOT NULL,"
952 " subtitle VARCHAR(255) NOT NULL,"
953 " season SMALLINT(5) NOT NULL DEFAULT '0',"
954 " episode SMALLINT(5) NOT NULL DEFAULT '0',"
955 " description TEXT NOT NULL,"
956 " url TEXT NOT NULL,"
957 " type SMALLINT(3) NOT NULL,"
958 " thumbnail TEXT NOT NULL,"
959 " mediaURL TEXT NOT NULL,"
960 " author VARCHAR(255) NOT NULL,"
961 " date DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',"
962 " time INT NOT NULL,"
963 " rating VARCHAR(255) NOT NULL,"
964 " filesize BIGINT NOT NULL,"
965 " player VARCHAR(255) NOT NULL,"
966 " playerargs TEXT NOT NULL,"
967 " download VARCHAR(255) NOT NULL,"
968 " downloadargs TEXT NOT NULL,"
969 " width SMALLINT NOT NULL,"
970 " height SMALLINT NOT NULL,"
971 " language VARCHAR(128) NOT NULL,"
972 " podcast BOOL NOT NULL,"
973 " downloadable BOOL NOT NULL,"
974 " customhtml BOOL NOT NULL,"
975 " countries VARCHAR(255) NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
976 nullptr
977 };
978  if (!performActualUpdate(updates, "1258", dbver))
979  return false;
980  }
981 
982  if (dbver == "1258")
983  {
984  LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1259");
985 
986  MSqlQuery select(MSqlQuery::InitCon());
987  select.prepare("SELECT hostname, data FROM settings "
988  " WHERE value = 'IndividualMuteControl'");
989 
990  if (!select.exec())
991  {
992  MythDB::DBError("Unable to retrieve IndividualMuteControl values.",
993  select);
994  return false;
995  }
996 
997  MSqlQuery update(MSqlQuery::InitCon());
998  while (select.next())
999  {
1000  QString hostname = select.value(0).toString();
1001  QString individual_mute = select.value(1).toString();
1002 
1003  if ("1" == individual_mute)
1004  {
1005  update.prepare("DELETE FROM keybindings "
1006  " WHERE action = 'CYCLEAUDIOCHAN' AND "
1007  " hostname = :HOSTNAME AND "
1008  " context IN ('TV Frontend', "
1009  " 'TV Playback')");
1010 
1011  update.bindValue(":HOSTNAME", hostname);
1012 
1013  if (!update.exec())
1014  {
1015  MythDB::DBError("Unable to update keybindings",
1016  update);
1017  return false;
1018  }
1019 
1020  update.prepare("UPDATE keybindings "
1021  " SET action = 'CYCLEAUDIOCHAN', "
1022  " description = 'Cycle audio channels'"
1023  " WHERE action = 'MUTE' AND "
1024  " hostname = :HOSTNAME AND "
1025  " context IN ('TV Frontend', "
1026  " 'TV Playback')");
1027 
1028  update.bindValue(":HOSTNAME", hostname);
1029 
1030  if (!update.exec())
1031  {
1032  MythDB::DBError("Unable to update keybindings",
1033  update);
1034  return false;
1035  }
1036 
1037  update.prepare("REPLACE INTO keybindings "
1038  " VALUES (:CONTEXT, 'MUTE', 'Mute', "
1039  " '', :HOSTNAME)");
1040 
1041  update.bindValue(":CONTEXT", "TV Playback");
1042  update.bindValue(":HOSTNAME", hostname);
1043  if (!update.exec())
1044  {
1045  MythDB::DBError("Unable to update keybindings",
1046  update);
1047  return false;
1048  }
1049  update.bindValue(":CONTEXT", "TV Frontend");
1050  update.bindValue(":HOSTNAME", hostname);
1051  if (!update.exec())
1052  {
1053  MythDB::DBError("Unable to update keybindings",
1054  update);
1055  return false;
1056  }
1057 
1058  }
1059  }
1060 
1061  if (!UpdateDBVersionNumber("1259", dbver))
1062  return false;
1063  }
1064 
1065  if (dbver == "1259")
1066  {
1067  LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1260");
1068 
1069  MSqlQuery query(MSqlQuery::InitCon());
1070  query.prepare("DELETE FROM keybindings WHERE "
1071  "action IN ('PAGEUP','PAGEDOWN') AND "
1072  "context = 'TV FRONTEND'");
1073  if (!query.exec())
1074  {
1075  MythDB::DBError("Unable to update keybindings", query);
1076  return false;
1077  }
1078 
1079  query.prepare("SELECT data FROM settings "
1080  " WHERE value = 'EPGEnableJumpToChannel'");
1081 
1082  if (!query.exec())
1083  {
1084  MythDB::DBError("Unable to retrieve EPGEnableJumpToChannel values.",
1085  query);
1086  return false;
1087  }
1088 
1089  MSqlQuery bindings(MSqlQuery::InitCon());
1090  while (query.next())
1091  {
1092  QString EPGEnableJumpToChannel = query.value(0).toString();
1093 
1094  if ("1" == EPGEnableJumpToChannel)
1095  {
1096  bindings.prepare("SELECT action, context, hostname, keylist "
1097  " FROM keybindings "
1098  " WHERE action IN ('DAYLEFT', "
1099  " 'DAYRIGHT', 'TOGGLEEPGORDER') AND "
1100  " context IN ('TV Frontend', "
1101  " 'TV Playback')");
1102 
1103  if (!bindings.exec())
1104  {
1105  MythDB::DBError("Unable to update keybindings",
1106  bindings);
1107  return false;
1108  }
1109  while (bindings.next())
1110  {
1111  QString action = bindings.value(0).toString();
1112  QString context = bindings.value(1).toString();
1113  QString hostname = bindings.value(2).toString();
1114  QStringList oldKeylist = bindings.value(3).toString().split(',');
1115  QStringList newKeyList;
1116 
1117  QStringList::iterator it;
1118  for (it = oldKeylist.begin(); it != oldKeylist.end();++it)
1119  {
1120  bool ok = false;
1121  int num = (*it).toInt(&ok);
1122  if (!ok && num >= 0 && num <= 9)
1123  newKeyList << (*it);
1124  }
1125  QString keyList = newKeyList.join(",");
1126 
1127  MSqlQuery update(MSqlQuery::InitCon());
1128  update.prepare("UPDATE keybindings "
1129  " SET keylist = :KEYLIST "
1130  " WHERE action = :ACTION "
1131  " AND context = :CONTEXT "
1132  " AND hostname = :HOSTNAME");
1133 
1134  update.bindValue(":KEYLIST", keyList);
1135  update.bindValue(":ACTION", action);
1136  update.bindValue(":CONTEXT", context);
1137  update.bindValue(":HOSTNAME", hostname);
1138 
1139  if (!update.exec())
1140  {
1141  MythDB::DBError("Unable to update keybindings",
1142  update);
1143  return false;
1144  }
1145  }
1146  }
1147  }
1148 
1149  if (!UpdateDBVersionNumber("1260", dbver))
1150  return false;
1151  }
1152 
1153  if (dbver == "1260")
1154  {
1155  if (gCoreContext->GetBoolSetting("MythFillFixProgramIDsHasRunOnce", false))
1156  {
1157  LOG(VB_GENERAL, LOG_CRIT,
1158  "Upgrading to MythTV schema version 1261");
1159  if (!UpdateDBVersionNumber("1261", dbver))
1160  return false;
1161  }
1162  else
1163  {
1164 
1165  const char *updates[] = {
1166 "UPDATE recorded SET programid=CONCAT(SUBSTRING(programid, 1, 2), '00', "
1167 " SUBSTRING(programid, 3)) WHERE length(programid) = 12;",
1168 "UPDATE oldrecorded SET programid=CONCAT(SUBSTRING(programid, 1, 2), '00', "
1169 " SUBSTRING(programid, 3)) WHERE length(programid) = 12;",
1170 "UPDATE program SET programid=CONCAT(SUBSTRING(programid, 1, 2), '00', "
1171 " SUBSTRING(programid, 3)) WHERE length(programid) = 12;",
1172 nullptr
1173 };
1174  if (!performActualUpdate(updates, "1261", dbver))
1175  return false;
1176  }
1177  }
1178 
1179  if (dbver == "1261")
1180  {
1181  const char *updates[] = {
1182 "UPDATE program SET description = '' WHERE description IS NULL;",
1183 "UPDATE record SET description = '' WHERE description IS NULL;",
1184 "UPDATE recorded SET description = '' WHERE description IS NULL;",
1185 "UPDATE recordedprogram SET description = '' WHERE description IS NULL;",
1186 "UPDATE oldrecorded SET description = '' WHERE description IS NULL;",
1187 "UPDATE mythlog SET details = '' WHERE details IS NULL;",
1188 "UPDATE settings SET data = '' WHERE data IS NULL;",
1189 "UPDATE powerpriority SET selectclause = '' WHERE selectclause IS NULL;",
1190 "UPDATE customexample SET fromclause = '' WHERE fromclause IS NULL;",
1191 "UPDATE customexample SET whereclause = '' WHERE whereclause IS NULL;",
1192 "ALTER TABLE program MODIFY COLUMN description VARCHAR(16000) "
1193 " NOT NULL default '';",
1194 "ALTER TABLE record MODIFY COLUMN description VARCHAR(16000) "
1195 " NOT NULL default '';",
1196 "ALTER TABLE recorded MODIFY COLUMN description VARCHAR(16000) "
1197 " NOT NULL default '';",
1198 "ALTER TABLE recordedprogram MODIFY COLUMN description VARCHAR(16000) "
1199 " NOT NULL default '';",
1200 "ALTER TABLE oldrecorded MODIFY COLUMN description VARCHAR(16000) "
1201 " NOT NULL default '';",
1202 "ALTER TABLE mythlog MODIFY COLUMN details VARCHAR(16000) "
1203 " NOT NULL default '';",
1204 "ALTER TABLE settings MODIFY COLUMN data VARCHAR(16000) "
1205 " NOT NULL default '';",
1206 "ALTER TABLE powerpriority MODIFY COLUMN selectclause VARCHAR(16000) "
1207 " NOT NULL default '';",
1208 "ALTER TABLE customexample MODIFY COLUMN fromclause VARCHAR(10000) "
1209 " NOT NULL default '';",
1210 "ALTER TABLE customexample MODIFY COLUMN whereclause VARCHAR(10000) "
1211 " NOT NULL default '';",
1212 nullptr
1213 };
1214  if (!performActualUpdate(updates, "1262", dbver))
1215  return false;
1216  }
1217 
1218  if (dbver == "1262")
1219  {
1220  const char *updates[] = {
1221 "INSERT INTO recgrouppassword (recgroup, password) SELECT 'All Programs',data FROM settings WHERE value='AllRecGroupPassword' LIMIT 1;",
1222 "DELETE FROM settings WHERE value='AllRecGroupPassword';",
1223 nullptr
1224 };
1225  if (!performActualUpdate(updates, "1263", dbver))
1226  return false;
1227  }
1228 
1229  if (dbver == "1263")
1230  {
1231  const char *updates[] = {
1232 "UPDATE settings SET hostname = NULL WHERE value='ISO639Language0' AND data != 'aar' AND hostname IS NOT NULL LIMIT 1;",
1233 "UPDATE settings SET hostname = NULL WHERE value='ISO639Language1' AND data != 'aar' AND hostname IS NOT NULL LIMIT 1;",
1234 "DELETE FROM settings WHERE value='ISO639Language0' AND hostname IS NOT NULL;",
1235 "DELETE FROM settings WHERE value='ISO639Language1' AND hostname IS NOT NULL;",
1236 nullptr
1237 };
1238  if (!performActualUpdate(updates, "1264", dbver))
1239  return false;
1240  }
1241 
1242  if (dbver == "1264")
1243  {
1244  const char *updates[] = {
1245 "DELETE FROM displayprofiles WHERE profilegroupid IN "
1246 " (SELECT profilegroupid FROM displayprofilegroups "
1247 " WHERE name IN ('CPU++', 'CPU+', 'CPU--'))",
1248 "DELETE FROM displayprofilegroups WHERE name IN ('CPU++', 'CPU+', 'CPU--')",
1249 "DELETE FROM settings WHERE value = 'DefaultVideoPlaybackProfile' "
1250 " AND data IN ('CPU++', 'CPU+', 'CPU--')",
1251 "UPDATE displayprofiles SET data = 'ffmpeg' WHERE data = 'libmpeg2'",
1252 "UPDATE displayprofiles SET data = 'ffmpeg' WHERE data = 'xvmc'",
1253 "UPDATE displayprofiles SET data = 'xv-blit' WHERE data = 'xvmc-blit'",
1254 "UPDATE displayprofiles SET data = 'softblend' WHERE data = 'ia44blend'",
1255 nullptr
1256 };
1257  if (!performActualUpdate(updates, "1265", dbver))
1258  return false;
1259  }
1260 
1261  if (dbver == "1265")
1262  {
1263  const char *updates[] = {
1264 "ALTER TABLE dtv_multiplex MODIFY COLUMN updatetimestamp "
1265 " TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;",
1266 "ALTER TABLE dvdbookmark MODIFY COLUMN `timestamp` "
1267 " TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;",
1268 "ALTER TABLE jobqueue MODIFY COLUMN statustime "
1269 " TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;",
1270 "ALTER TABLE recorded MODIFY COLUMN lastmodified "
1271 " TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;",
1272 nullptr
1273 };
1274  if (!performActualUpdate(updates, "1266", dbver))
1275  return false;
1276  }
1277 
1278  if (dbver == "1266")
1279  {
1281  return false;
1282 
1283  const char *updates[] = {
1284 "DELETE FROM settings WHERE value = 'mythvideo.DBSchemaVer'",
1285 nullptr
1286 };
1287  if (!performActualUpdate(updates, "1267", dbver))
1288  return false;
1289  }
1290 
1291  if (dbver == "1267")
1292  {
1293  const char *updates[] = {
1294 "ALTER TABLE channel MODIFY xmltvid VARCHAR(255) NOT NULL DEFAULT '';",
1295 nullptr
1296 };
1297  if (!performActualUpdate(updates, "1268", dbver))
1298  return false;
1299  }
1300 
1301  if (dbver == "1268")
1302  {
1303 
1304  const char *updates[] = {
1305 "DELETE FROM keybindings WHERE action='PREVSOURCE' AND keylist='Ctrl+Y';",
1306 nullptr
1307 };
1308  if (!performActualUpdate(updates, "1269", dbver))
1309  return false;
1310  }
1311 
1312  if (dbver == "1269")
1313  {
1314  const char *updates[] = {
1315 "DELETE FROM profilegroups WHERE id >= 15;",
1316 "DELETE FROM recordingprofiles WHERE profilegroup >= 15;",
1317 // NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
1318 "INSERT INTO profilegroups SET id = '15', name = 'ASI Recorder (DVEO)',"
1319 " cardtype = 'ASI', is_default = 1;",
1320 "INSERT INTO recordingprofiles SET name = \"Default\", profilegroup = 15;",
1321 "INSERT INTO recordingprofiles SET name = \"Live TV\", profilegroup = 15;",
1322 "INSERT INTO recordingprofiles SET name = \"High Quality\", profilegroup = 15;",
1323 "INSERT INTO recordingprofiles SET name = \"Low Quality\", profilegroup = 15;",
1324 "INSERT INTO profilegroups SET id = '16', name = 'OCUR Recorder (CableLabs)',"
1325 " cardtype = 'OCUR', is_default = 1;",
1326 "INSERT INTO recordingprofiles SET name = \"Default\", profilegroup = 16;",
1327 "INSERT INTO recordingprofiles SET name = \"Live TV\", profilegroup = 16;",
1328 "INSERT INTO recordingprofiles SET name = \"High Quality\", profilegroup = 16;",
1329 "INSERT INTO recordingprofiles SET name = \"Low Quality\", profilegroup = 16;",
1330 nullptr
1331 };
1332  if (!performActualUpdate(updates, "1270", dbver))
1333  return false;
1334  }
1335 
1336  if (dbver == "1270")
1337  {
1338  const char *updates[] = {
1339 "ALTER TABLE oldrecorded ADD future TINYINT(1) NOT NULL DEFAULT 0;",
1340 "UPDATE oldrecorded SET future=0;",
1341 nullptr
1342 };
1343  if (!performActualUpdate(updates, "1271", dbver))
1344  return false;
1345  }
1346 
1347  if (dbver == "1271")
1348  {
1349  const char *updates[] = {
1350 "ALTER TABLE recordmatch MODIFY recordid INT UNSIGNED NOT NULL;",
1351 "ALTER TABLE recordmatch MODIFY chanid INT UNSIGNED NOT NULL;",
1352 "ALTER TABLE recordmatch MODIFY starttime DATETIME NOT NULL;",
1353 "ALTER TABLE recordmatch MODIFY manualid INT UNSIGNED NOT NULL;",
1354 "ALTER TABLE recordmatch ADD INDEX (starttime, chanid);",
1355 "ALTER TABLE oldrecorded MODIFY generic TINYINT(1) NOT NULL;",
1356 "ALTER TABLE oldrecorded ADD INDEX (future);",
1357 "ALTER TABLE oldrecorded ADD INDEX (starttime, chanid);",
1358 nullptr
1359 };
1360  if (!performActualUpdate(updates, "1272", dbver))
1361  return false;
1362  }
1363 
1364  if (dbver == "1272")
1365  {
1366  const char *updates[] = {
1367 "DROP INDEX starttime ON recordmatch;",
1368 "DROP INDEX starttime ON oldrecorded;",
1369 "ALTER TABLE recordmatch ADD INDEX (chanid, starttime, manualid);",
1370 "ALTER TABLE oldrecorded ADD INDEX (chanid, starttime);",
1371 nullptr
1372 };
1373  if (!performActualUpdate(updates, "1273", dbver))
1374  return false;
1375  }
1376 
1377  if (dbver == "1273")
1378  {
1379  const char *updates[] = {
1380 "ALTER TABLE internetcontent MODIFY COLUMN updated "
1381 " DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00';",
1382 "ALTER TABLE internetcontentarticles MODIFY COLUMN `date` "
1383 " DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00';",
1384 nullptr
1385 };
1386 
1387  if (!performActualUpdate(updates, "1274", dbver))
1388  return false;
1389  }
1390 
1391  if (dbver == "1274")
1392  {
1393  const char *updates[] = {
1394 "UPDATE cardinput SET tunechan=NULL"
1395 " WHERE inputname='DVBInput' OR inputname='MPEG2TS';"
1396 "UPDATE dtv_multiplex SET symbolrate = NULL"
1397 " WHERE modulation LIKE 't%' OR modulation LIKE '%t';",
1398 "UPDATE dtv_multiplex"
1399 " SET bandwidth=SUBSTR(modulation,2,1)"
1400 " WHERE SUBSTR(modulation,3,3)='qam' OR"
1401 " SUBSTR(modulation,3,4)='qpsk';",
1402 "UPDATE dtv_multiplex"
1403 " SET bandwidth=SUBSTR(modulation,5,1)"
1404 " WHERE SUBSTR(modulation,1,4)='auto' AND"
1405 " LENGTH(modulation)=6;",
1406 "UPDATE dtv_multiplex SET modulation='auto'"
1407 " WHERE modulation LIKE 'auto%';",
1408 "UPDATE dtv_multiplex SET modulation='qam_16'"
1409 " WHERE modulation LIKE '%qam16%';",
1410 "UPDATE dtv_multiplex SET modulation='qam_32'"
1411 " WHERE modulation LIKE '%qam32%';",
1412 "UPDATE dtv_multiplex SET modulation='qam_64'"
1413 " WHERE modulation LIKE '%qam64%';",
1414 "UPDATE dtv_multiplex SET modulation='qam_128'"
1415 " WHERE modulation LIKE '%qam128%';",
1416 "UPDATE dtv_multiplex SET modulation='qam_256'"
1417 " WHERE modulation LIKE '%qam256%';",
1418 nullptr
1419 };
1420  if (!performActualUpdate(updates, "1275", dbver))
1421  return false;
1422  }
1423 
1424  if (dbver == "1275")
1425  {
1426  const char *updates[] = {
1427 "DROP TABLE IF EXISTS `logging`;",
1428 "CREATE TABLE `logging` ( "
1429 " `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, "
1430 " `host` varchar(64) NOT NULL, "
1431 " `application` varchar(64) NOT NULL, "
1432 " `pid` int(11) NOT NULL, "
1433 " `thread` varchar(64) NOT NULL, "
1434 " `msgtime` datetime NOT NULL, "
1435 " `level` int(11) NOT NULL, "
1436 " `message` varchar(2048) NOT NULL, "
1437 " PRIMARY KEY (`id`), "
1438 " KEY `host` (`host`,`application`,`pid`,`msgtime`), "
1439 " KEY `msgtime` (`msgtime`), "
1440 " KEY `level` (`level`) "
1441 ") ENGINE=MyISAM DEFAULT CHARSET=utf8; ",
1442 nullptr
1443 };
1444  if (!performActualUpdate(updates, "1276", dbver))
1445  return false;
1446  }
1447 
1448  if (dbver == "1276")
1449  {
1450  const char *updates[] = {
1451 "ALTER TABLE record ADD COLUMN filter INT UNSIGNED NOT NULL DEFAULT 0;",
1452 "CREATE TABLE IF NOT EXISTS recordfilter ("
1453 " filterid INT UNSIGNED NOT NULL PRIMARY KEY,"
1454 " description VARCHAR(64) DEFAULT NULL,"
1455 " clause VARCHAR(256) DEFAULT NULL,"
1456 " newruledefault TINYINT(1) DEFAULT 0) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
1457 "INSERT INTO recordfilter (filterid, description, clause, newruledefault) "
1458 " VALUES (0, 'New episode', 'program.previouslyshown = 0', 0);",
1459 "INSERT INTO recordfilter (filterid, description, clause, newruledefault) "
1460 " VALUES (1, 'Identifiable episode', 'program.generic = 0', 0);",
1461 "INSERT INTO recordfilter (filterid, description, clause, newruledefault) "
1462 " VALUES (2, 'First showing', 'program.first > 0', 0);",
1463 "INSERT INTO recordfilter (filterid, description, clause, newruledefault) "
1464 " VALUES (3, 'Primetime', 'HOUR(program.starttime) >= 19 AND HOUR(program.starttime) < 23', 0);",
1465 "INSERT INTO recordfilter (filterid, description, clause, newruledefault) "
1466 " VALUES (4, 'Commercial free', 'channel.commmethod = -2', 0);",
1467 "INSERT INTO recordfilter (filterid, description, clause, newruledefault) "
1468 " VALUES (5, 'High definition', 'program.hdtv > 0', 0);",
1469 nullptr
1470 };
1471 
1472  if (!performActualUpdate(updates, "1277", dbver))
1473  return false;
1474  }
1475 
1476  if (dbver == "1277")
1477  {
1478  const char *updates[] = {
1479 // NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
1480 "ALTER TABLE record ADD autometadata TINYINT(1) NOT NULL DEFAULT "
1481 " 0 AFTER autouserjob4;",
1482 "ALTER TABLE record ADD inetref VARCHAR(40) NOT NULL AFTER programid;",
1483 "ALTER TABLE record ADD season SMALLINT(5) NOT NULL AFTER description;",
1484 "ALTER TABLE record ADD episode SMALLINT(5) NOT NULL AFTER season;",
1485 "ALTER TABLE recorded ADD inetref VARCHAR(40) NOT NULL AFTER programid;",
1486 "ALTER TABLE recorded ADD season SMALLINT(5) NOT NULL AFTER description;",
1487 "ALTER TABLE recorded ADD episode SMALLINT(5) NOT NULL AFTER season;",
1488 "ALTER TABLE oldrecorded ADD inetref VARCHAR(40) NOT NULL AFTER programid;",
1489 "ALTER TABLE oldrecorded ADD season SMALLINT(5) NOT NULL AFTER description;",
1490 "ALTER TABLE oldrecorded ADD episode SMALLINT(5) NOT NULL AFTER season;",
1491 nullptr
1492 };
1493  if (!performActualUpdate(updates, "1278", dbver))
1494  return false;
1495  }
1496 
1497  if (dbver == "1278")
1498  {
1499  const char *updates[] = {
1500 "CREATE TABLE recordedartwork ( "
1501 " inetref VARCHAR(255) NOT NULL, "
1502 " season SMALLINT(5) NOT NULL, "
1503 " host TEXT NOT NULL, "
1504 " coverart TEXT NOT NULL, "
1505 " fanart TEXT NOT NULL, "
1506 " banner TEXT NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
1507 nullptr
1508 };
1509  if (!performActualUpdate(updates, "1279", dbver))
1510  return false;
1511  }
1512 
1513  if (dbver == "1279")
1514  {
1515  LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1280");
1516 
1517  MSqlQuery select(MSqlQuery::InitCon());
1518  // New DBs/hosts will not have a NoPromptOnExit, so they'll get defaults
1519  select.prepare("SELECT hostname, data FROM settings "
1520  " WHERE value = 'NoPromptOnExit'");
1521  if (!select.exec())
1522  {
1523  MythDB::DBError("Unable to retrieve confirm exit values.", select);
1524  }
1525  else
1526  {
1527  MSqlQuery update(MSqlQuery::InitCon());
1528  while (select.next())
1529  {
1530  QString hostname = select.value(0).toString();
1531  // Yes, enabled NoPromptOnExit meant to prompt on exit
1532  QString prompt_on_exit = select.value(1).toString();
1533  // Default EXITPROMPT is wrong for all upgrades
1534  update.prepare("DELETE FROM keybindings "
1535  " WHERE action = 'EXITPROMPT' "
1536  " AND context = 'Main Menu' "
1537  " AND hostname = :HOSTNAME ;");
1538  update.bindValue(":HOSTNAME", hostname);
1539  if (!update.exec())
1540  MythDB::DBError("Unable to delete EXITPROMPT binding",
1541  update);
1542 
1543  if ("0" == prompt_on_exit)
1544  {
1545  // EXIT is already mapped appropriately, so just create a
1546  // no-keylist mapping for EXITPROMPT to prevent conflict
1547  update.prepare("INSERT INTO keybindings (context, action, "
1548  " description, keylist, hostname) "
1549  "VALUES ('Main Menu', 'EXITPROMPT', '', "
1550  " '', :HOSTNAME );");
1551  update.bindValue(":HOSTNAME", hostname);
1552  if (!update.exec())
1553  MythDB::DBError("Unable to create EXITPROMPT binding",
1554  update);
1555  }
1556  else
1557  {
1558  // EXIT must be changed to EXITPROMPT
1559  update.prepare("UPDATE keybindings "
1560  " SET action = 'EXITPROMPT' "
1561  " WHERE action = 'EXIT' "
1562  " AND context = 'Main Menu' "
1563  " AND hostname = :HOSTNAME ;");
1564  update.bindValue(":HOSTNAME", hostname);
1565  if (!update.exec())
1566  MythDB::DBError("Unable to update EXITPROMPT binding",
1567  update);
1568  }
1569  }
1570  }
1571 
1572  if (!UpdateDBVersionNumber("1280", dbver))
1573  return false;
1574  }
1575 
1576  if (dbver == "1280")
1577  {
1578  const char *updates[] = {
1579 "ALTER TABLE program ADD INDEX (subtitle);",
1580 "ALTER TABLE program ADD INDEX (description(255));",
1581 "ALTER TABLE oldrecorded ADD INDEX (subtitle);",
1582 "ALTER TABLE oldrecorded ADD INDEX (description(255));",
1583 nullptr
1584 };
1585  if (!performActualUpdate(updates, "1281", dbver))
1586  return false;
1587  }
1588 
1589  if (dbver == "1281")
1590  {
1591  const char *updates[] = {
1592 "ALTER TABLE cardinput ADD changer_device VARCHAR(128) "
1593 "AFTER externalcommand;",
1594 "ALTER TABLE cardinput ADD changer_model VARCHAR(128) "
1595 "AFTER changer_device;",
1596 nullptr
1597 };
1598  if (!performActualUpdate(updates, "1282", dbver))
1599  return false;
1600  }
1601 
1602  if (dbver == "1282")
1603  {
1604  const char *updates[] = {
1605 "UPDATE settings"
1606 " SET data = SUBSTR(data, INSTR(data, 'share/mythtv/metadata')+13)"
1607 " WHERE value "
1608 " IN ('TelevisionGrabber', "
1609 " 'MovieGrabber', "
1610 " 'mythgame.MetadataGrabber');",
1611 nullptr
1612 };
1613 
1614  if (!performActualUpdate(updates, "1283", dbver))
1615  return false;
1616  }
1617 
1618  if (dbver == "1283")
1619  {
1620  const char *updates[] = {
1621 "UPDATE record SET filter = filter | 1 WHERE record.dupin & 0x20",
1622 "UPDATE record SET filter = filter | 2 WHERE record.dupin & 0x40",
1623 "UPDATE record SET filter = filter | 5 WHERE record.dupin & 0x80",
1624 "UPDATE record SET dupin = dupin & ~0xe0",
1625 // NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
1626 "INSERT INTO recordfilter (filterid, description, clause, newruledefault) "
1627 " VALUES (6, 'This Episode', '(program.programid <> '''' AND program.programid = RECTABLE.programid) OR (program.programid = '''' AND program.subtitle = RECTABLE.subtitle AND program.description = RECTABLE.description)', 0);",
1628 nullptr
1629 };
1630 
1631  if (!performActualUpdate(updates, "1284", dbver))
1632  return false;
1633  }
1634 
1635  if (dbver == "1284")
1636  {
1637  const char *updates[] = {
1638 "REPLACE INTO recordfilter (filterid, description, clause, newruledefault) "
1639 " VALUES (6, 'This Episode', '(RECTABLE.programid <> '''' AND program.programid = RECTABLE.programid) OR (RECTABLE.programid = '''' AND program.subtitle = RECTABLE.subtitle AND program.description = RECTABLE.description)', 0);",
1640 nullptr
1641 };
1642 
1643  if (!performActualUpdate(updates, "1285", dbver))
1644  return false;
1645  }
1646 
1647  if (dbver == "1285")
1648  {
1649  const char *updates[] = {
1650 "DELETE FROM profilegroups WHERE id >= 17;",
1651 "DELETE FROM recordingprofiles WHERE profilegroup >= 17;",
1652 // NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
1653 "INSERT INTO profilegroups SET id = '17', name = 'Ceton Recorder',"
1654 " cardtype = 'CETON', is_default = 1;",
1655 "INSERT INTO recordingprofiles SET name = \"Default\", profilegroup = 17;",
1656 "INSERT INTO recordingprofiles SET name = \"Live TV\", profilegroup = 17;",
1657 "INSERT INTO recordingprofiles SET name = \"High Quality\", profilegroup = 17;",
1658 "INSERT INTO recordingprofiles SET name = \"Low Quality\", profilegroup = 17;",
1659 nullptr
1660 };
1661  if (!performActualUpdate(updates, "1286", dbver))
1662  return false;
1663  }
1664 
1665  if (dbver == "1286")
1666  {
1667  LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1287");
1668  MSqlQuery query(MSqlQuery::InitCon());
1669  query.prepare("SELECT cardid, videodevice "
1670  "FROM capturecard "
1671  "WHERE cardtype='CETON'");
1672  if (!query.exec())
1673  {
1674  LOG(VB_GENERAL, LOG_ERR,
1675  "Unable to query capturecard table for upgrade to 1287.");
1676  return false;
1677  }
1678 
1679  MSqlQuery update(MSqlQuery::InitCon());
1680  update.prepare("UPDATE capturecard SET videodevice=:VIDDEV "
1681  "WHERE cardid=:CARDID");
1682  while (query.next())
1683  {
1684  uint cardid = query.value(0).toUInt();
1685  QString videodevice = query.value(1).toString();
1686  QStringList parts = videodevice.split("-");
1687  if (parts.size() != 2)
1688  {
1689  LOG(VB_GENERAL, LOG_ERR,
1690  "Unable to parse videodevice in upgrade to 1287.");
1691  return false;
1692  }
1693  if (parts[1].contains("."))
1694  continue; // already in new format, skip it..
1695 
1696  int input = max(parts[1].toInt() - 1, 0);
1697  videodevice = parts[0] + QString("-0.%1").arg(input);
1698  update.bindValue(":CARDID", cardid);
1699  update.bindValue(":VIDDEV", videodevice);
1700  if (!update.exec())
1701  {
1702  LOG(VB_GENERAL, LOG_ERR,
1703  "Failed to update videodevice in upgrade to 1287.");
1704  return false;
1705  }
1706  }
1707 
1708  if (!UpdateDBVersionNumber("1287", dbver))
1709  return false;
1710  }
1711 
1712  if (dbver == "1287")
1713  {
1714  const char *updates[] = {
1715 "CREATE TABLE IF NOT EXISTS livestream ( "
1716 " id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, "
1717 " width INT UNSIGNED NOT NULL, "
1718 " height INT UNSIGNED NOT NULL, "
1719 " bitrate INT UNSIGNED NOT NULL, "
1720 " audiobitrate INT UNSIGNED NOT NULL, "
1721 " samplerate INT UNSIGNED NOT NULL, "
1722 " audioonlybitrate INT UNSIGNED NOT NULL, "
1723 " segmentsize INT UNSIGNED NOT NULL DEFAULT 10, "
1724 " maxsegments INT UNSIGNED NOT NULL DEFAULT 0, "
1725 " startsegment INT UNSIGNED NOT NULL DEFAULT 0, "
1726 " currentsegment INT UNSIGNED NOT NULL DEFAULT 0, "
1727 " segmentcount INT UNSIGNED NOT NULL DEFAULT 0, "
1728 " percentcomplete INT UNSIGNED NOT NULL DEFAULT 0, "
1729 " created DATETIME NOT NULL, "
1730 " lastmodified DATETIME NOT NULL, "
1731 " relativeurl VARCHAR(512) NOT NULL, "
1732 " fullurl VARCHAR(1024) NOT NULL, "
1733 " status INT UNSIGNED NOT NULL DEFAULT 0, "
1734 " statusmessage VARCHAR(256) NOT NULL, "
1735 " sourcefile VARCHAR(512) NOT NULL, "
1736 " sourcehost VARCHAR(64) NOT NULL, "
1737 " sourcewidth INT UNSIGNED NOT NULL DEFAULT 0, "
1738 " sourceheight INT UNSIGNED NOT NULL DEFAULT 0, "
1739 " outdir VARCHAR(256) NOT NULL, "
1740 " outbase VARCHAR(128) NOT NULL "
1741 ") ENGINE=MyISAM DEFAULT CHARSET=utf8; ",
1742 nullptr
1743 };
1744 
1745  if (!performActualUpdate(updates, "1288", dbver))
1746  return false;
1747  }
1748 
1749  if (dbver == "1288")
1750  {
1751  const char *updates[] = {
1752 "ALTER TABLE recordedprogram CHANGE COLUMN videoprop videoprop "
1753 " SET('HDTV', 'WIDESCREEN', 'AVC', '720', '1080', 'DAMAGED') NOT NULL; ",
1754 nullptr
1755 };
1756  if (!performActualUpdate(updates, "1289", dbver))
1757  return false;
1758  }
1759 
1760  if (dbver == "1289")
1761  {
1762  const char *updates[] = {
1763 "DROP TABLE IF EXISTS netvisionrssitems;",
1764 "DROP TABLE IF EXISTS netvisionsearchgrabbers;",
1765 "DROP TABLE IF EXISTS netvisionsites;",
1766 "DROP TABLE IF EXISTS netvisiontreegrabbers;",
1767 "DROP TABLE IF EXISTS netvisiontreeitems;",
1768 nullptr
1769 };
1770 
1771  if (!performActualUpdate(updates, "1290", dbver))
1772  return false;
1773  }
1774 
1775  if (dbver == "1290")
1776  {
1777  const char *updates[] = {
1778 "ALTER TABLE logging "
1779 " ALTER COLUMN host SET DEFAULT '', "
1780 " ALTER COLUMN application SET DEFAULT '', "
1781 " ALTER COLUMN pid SET DEFAULT '0', "
1782 " ALTER COLUMN thread SET DEFAULT '', "
1783 " ALTER COLUMN level SET DEFAULT '0';",
1784 "ALTER TABLE logging "
1785 " ADD COLUMN tid INT(11) NOT NULL DEFAULT '0' AFTER pid, "
1786 " ADD COLUMN filename VARCHAR(255) NOT NULL DEFAULT '' AFTER thread, "
1787 " ADD COLUMN line INT(11) NOT NULL DEFAULT '0' AFTER filename, "
1788 " ADD COLUMN function VARCHAR(255) NOT NULL DEFAULT '' AFTER line;",
1789 nullptr
1790 };
1791 
1792  if (!performActualUpdate(updates, "1291", dbver))
1793  return false;
1794  }
1795 
1796  if (dbver == "1291")
1797  {
1798  const char *updates[] = {
1799 "UPDATE recorded r, recordedprogram rp SET r.duplicate=0 "
1800 " WHERE r.chanid=rp.chanid AND r.progstart=rp.starttime AND "
1801 " FIND_IN_SET('DAMAGED', rp.videoprop);",
1802 nullptr
1803 };
1804 
1805  if (!performActualUpdate(updates, "1292", dbver))
1806  return false;
1807  }
1808 
1809  if (dbver == "1292")
1810  {
1811  const char *updates[] = {
1812 "ALTER TABLE cardinput "
1813 " ADD COLUMN schedorder INT(10) UNSIGNED NOT NULL DEFAULT '0', "
1814 " ADD COLUMN livetvorder INT(10) UNSIGNED NOT NULL DEFAULT '0';",
1815 "UPDATE cardinput SET schedorder = cardinputid;",
1816 "UPDATE cardinput SET livetvorder = cardid;",
1817 nullptr
1818 };
1819 
1820  if (gCoreContext->GetBoolSetting("LastFreeCard", false))
1821  {
1822  updates[2] =
1823  "UPDATE cardinput SET livetvorder = "
1824  " (SELECT MAX(cardid) FROM capturecard) - cardid + 1;";
1825  }
1826 
1827  if (!performActualUpdate(updates, "1293", dbver))
1828  return false;
1829  }
1830 
1831  if (dbver == "1293")
1832  {
1833  const char *updates[] = {
1834 "TRUNCATE TABLE recordmatch",
1835 "ALTER TABLE recordmatch DROP INDEX recordid",
1836 "ALTER TABLE recordmatch ADD UNIQUE INDEX (recordid, chanid, starttime)",
1837 "UPDATE recordfilter SET description='Prime time' WHERE filterid=3",
1838 "UPDATE recordfilter SET description='This episode' WHERE filterid=6",
1839 // NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
1840 "REPLACE INTO recordfilter (filterid, description, clause, newruledefault) "
1841 " VALUES (7, 'This series', '(RECTABLE.seriesid <> '''' AND program.seriesid = RECTABLE.seriesid)', 0);",
1842 nullptr
1843 };
1844 
1845  if (!performActualUpdate(updates, "1294", dbver))
1846  return false;
1847  }
1848 
1849  if (dbver == "1294")
1850  {
1851  const char *updates[] = {
1852 "CREATE TABLE videocollection ("
1853 " intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
1854 " title varchar(256) NOT NULL,"
1855 " contenttype set('MOVIE', 'TELEVISION', 'ADULT', 'MUSICVIDEO', 'HOMEVIDEO') NOT NULL default '',"
1856 " plot text,"
1857 " network varchar(128) DEFAULT NULL,"
1858 " inetref varchar(128) NOT NULL,"
1859 " certification varchar(128) DEFAULT NULL,"
1860 " genre int(10) unsigned DEFAULT '0',"
1861 " releasedate date DEFAULT NULL,"
1862 " language varchar(10) DEFAULT NULL,"
1863 " status varchar(64) DEFAULT NULL,"
1864 " rating float DEFAULT 0,"
1865 " ratingcount int(10) DEFAULT 0,"
1866 " runtime smallint(5) unsigned DEFAULT '0',"
1867 " banner text,"
1868 " fanart text,"
1869 " coverart text,"
1870 " PRIMARY KEY (intid),"
1871 " KEY title (title)"
1872 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
1873 "CREATE TABLE videopathinfo ("
1874 " intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
1875 " path text,"
1876 " contenttype set('MOVIE', 'TELEVISION', 'ADULT', 'MUSICVIDEO', 'HOMEVIDEO') NOT NULL default '',"
1877 " collectionref int(10) default '0',"
1878 " recurse tinyint(1) default '0',"
1879 " PRIMARY KEY (intid)"
1880 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
1881 "ALTER TABLE videometadata ADD collectionref int(10) NOT NULL DEFAULT '0' AFTER inetref;",
1882 "ALTER TABLE videometadata ADD playcount int(10) NOT NULL DEFAULT '0' AFTER length;",
1883 "ALTER TABLE videometadata ADD contenttype set('MOVIE', 'TELEVISION', 'ADULT', 'MUSICVIDEO', 'HOMEVIDEO') NOT NULL default ''",
1884 "UPDATE videometadata SET contenttype = 'MOVIE';",
1885 "UPDATE videometadata SET contenttype = 'TELEVISION' WHERE season > 0 OR episode > 0;",
1886 nullptr
1887 };
1888 
1889  if (!performActualUpdate(updates, "1295", dbver))
1890  return false;
1891  }
1892 
1893  if (dbver == "1295")
1894  {
1895  LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1296");
1896  MSqlQuery query(MSqlQuery::InitCon());
1897  query.prepare("SELECT data, hostname "
1898  "FROM settings "
1899  "WHERE value='BackendServerIP'");
1900  if (!query.exec())
1901  {
1902  LOG(VB_GENERAL, LOG_ERR,
1903  "Unable to repair IP addresses for IPv4/IPv6 split.");
1904  return false;
1905  }
1906 
1907  MSqlQuery update(MSqlQuery::InitCon()), insert(MSqlQuery::InitCon());
1908  update.prepare("UPDATE settings "
1909  "SET data=:IP4ADDY "
1910  "WHERE value='BackendServerIP' "
1911  "AND hostname=:HOSTNAME");
1912  insert.prepare("INSERT INTO settings "
1913  "SET value='BackendServerIP6',"
1914  "data=:IP6ADDY,"
1915  "hostname=:HOSTNAME");
1916  while (query.next())
1917  {
1918  QHostAddress oldaddr(query.value(0).toString());
1919  QString hostname = query.value(1).toString();
1920 
1921  update.bindValue(":HOSTNAME", hostname);
1922  insert.bindValue(":HOSTNAME", hostname);
1923 
1924  if (oldaddr.protocol() == QAbstractSocket::IPv6Protocol)
1925  {
1926  update.bindValue(":IP4ADDY", "127.0.0.1");
1927  insert.bindValue(":IP6ADDY", query.value(0).toString());
1928  }
1929  else if (oldaddr.protocol() == QAbstractSocket::IPv4Protocol)
1930  {
1931  update.bindValue(":IP4ADDY", query.value(0).toString());
1932  insert.bindValue(":IP6ADDY", "::1");
1933  }
1934  else
1935  {
1936  update.bindValue(":IP4ADDY", "127.0.0.1");
1937  insert.bindValue(":IP6ADDY", "::1");
1938  LOG(VB_GENERAL, LOG_CRIT,
1939  QString("Invalid address string '%1' found on %2. "
1940  "Reverting to localhost defaults.")
1941  .arg(query.value(0).toString()).arg(hostname));
1942  }
1943 
1944  if (!update.exec() || !insert.exec())
1945  {
1946  LOG(VB_GENERAL, LOG_ERR, QString("Failed to separate IPv4 "
1947  "and IPv6 addresses for %1").arg(hostname));
1948  return false;
1949  }
1950 
1951  }
1952 
1953  if (!UpdateDBVersionNumber("1296", dbver))
1954  return false;
1955  }
1956 
1957  if (dbver == "1296")
1958  {
1959  const char *updates[] = {
1960 "ALTER TABLE videocollection CHANGE inetref collectionref "
1961 "VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci "
1962 "NOT NULL",
1963 "ALTER TABLE videocollection CHANGE genre genre VARCHAR(128) NULL DEFAULT ''",
1964 nullptr
1965 };
1966 
1967  if (!performActualUpdate(updates, "1297", dbver))
1968  return false;
1969  }
1970 
1971  if (dbver == "1297")
1972  {
1973  const char *updates[] = {
1974 "ALTER TABLE videometadata CHANGE collectionref collectionref INT(10) "
1975 "NOT NULL DEFAULT -1",
1976 "UPDATE videometadata SET collectionref = '-1'",
1977 nullptr
1978 };
1979 
1980  if (!performActualUpdate(updates, "1298", dbver))
1981  return false;
1982  }
1983 
1984  if (dbver == "1298")
1985  {
1986  LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1299");
1987 
1988  // DeletedMaxAge setting only exists if the user ever triggered the
1989  // DeletedExpireOptions TriggeredConfigurationGroup (enabled
1990  // AutoExpireInsteadOfDelete) and changed DeletedMaxAge from its
1991  // default of zero, so "reset" it to ensure it's in the database before
1992  // the update
1993  QString deletedMaxAge = gCoreContext->GetSetting("DeletedMaxAge", "0");
1994  gCoreContext->SaveSettingOnHost("DeletedMaxAge", deletedMaxAge, nullptr);
1995 
1996  QString queryStr;
1997  if (gCoreContext->GetBoolSetting("AutoExpireInsteadOfDelete", false))
1998  {
1999  queryStr = "UPDATE settings SET data='-1' WHERE "
2000  "value='DeletedMaxAge' AND data='0'";
2001  }
2002  else
2003  {
2004  queryStr = "UPDATE settings SET data='0' WHERE "
2005  "value='DeletedMaxAge'";
2006  }
2007 
2008  MSqlQuery query(MSqlQuery::InitCon());
2009  query.prepare(queryStr);
2010  if (!query.exec())
2011  {
2012  MythDB::DBError("Could not perform update for '1299'", query);
2013  return false;
2014  }
2015 
2016  if (!UpdateDBVersionNumber("1299", dbver))
2017  return false;
2018  }
2019 
2020  if (dbver == "1299")
2021  {
2022  const char *updates[] = {
2023 "ALTER TABLE recordmatch ADD COLUMN findid INT NOT NULL DEFAULT 0",
2024 "ALTER TABLE recordmatch ADD INDEX (recordid, findid)",
2025 nullptr
2026 };
2027 
2028  if (!performActualUpdate(updates, "1300", dbver))
2029  return false;
2030  }
2031 
2032  if (dbver == "1300")
2033  {
2034  const char *updates[] = {
2035 "ALTER TABLE channel ADD COLUMN iptvid SMALLINT(6) UNSIGNED;",
2036 "CREATE TABLE iptv_channel ("
2037 " iptvid SMALLINT(6) UNSIGNED NOT NULL auto_increment,"
2038 " chanid INT(10) UNSIGNED NOT NULL,"
2039 " url TEXT NOT NULL,"
2040 " type set('data', "
2041 " 'rfc2733-1','rfc2733-2', "
2042 " 'rfc5109-1','rfc5109-2', "
2043 " 'smpte2022-1','smpte2022-2'),"
2044 " bitrate INT(10) UNSIGNED NOT NULL,"
2045 " PRIMARY KEY (iptvid)"
2046 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
2047 nullptr
2048 };
2049 
2050  if (!performActualUpdate(updates, "1301", dbver))
2051  return false;
2052  }
2053 
2054  if (dbver == "1301")
2055  {
2056  LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1302");
2057  // Create the Default recording rule template
2058  RecordingRule record;
2059  record.MakeTemplate("Default");
2060  record.m_type = kTemplateRecord;
2061  // Take some defaults from now obsoleted settings.
2062  record.m_startOffset =
2063  gCoreContext->GetNumSetting("DefaultStartOffset", 0);
2064  record.m_endOffset =
2065  gCoreContext->GetNumSetting("DefaultEndOffset", 0);
2066  record.m_dupMethod =
2067  static_cast<RecordingDupMethodType>(
2069  "prefDupMethod", kDupCheckSubDesc));
2071  record.m_autoExpire =
2072  gCoreContext->GetBoolSetting("AutoExpireDefault", false);
2073  record.m_autoCommFlag =
2074  gCoreContext->GetBoolSetting("AutoCommercialFlag", true);
2075  record.m_autoTranscode =
2076  gCoreContext->GetBoolSetting("AutoTranscode", false);
2077  record.m_transcoder =
2079  "DefaultTranscoder", static_cast<int>(RecordingProfile::TranscoderAutodetect));
2080  record.m_autoUserJob1 =
2081  gCoreContext->GetBoolSetting("AutoRunUserJob1", false);
2082  record.m_autoUserJob2 =
2083  gCoreContext->GetBoolSetting("AutoRunUserJob2", false);
2084  record.m_autoUserJob3 =
2085  gCoreContext->GetBoolSetting("AutoRunUserJob3", false);
2086  record.m_autoUserJob4 =
2087  gCoreContext->GetBoolSetting("AutoRunUserJob4", false);
2088  record.m_autoMetadataLookup =
2089  gCoreContext->GetBoolSetting("AutoMetadataLookup", true);
2090  record.Save(false);
2091 
2092  if (!UpdateDBVersionNumber("1302", dbver))
2093  return false;
2094  }
2095 
2096  if (dbver == "1302")
2097  {
2098  QDateTime loc = QDateTime::currentDateTime();
2099  QDateTime utc = loc.toUTC();
2100  loc = QDateTime(loc.date(), loc.time(), Qt::UTC);
2101  int utc_offset = loc.secsTo(utc) / 60;
2102 
2103  QList<QByteArray> updates_ba;
2104 
2105  // Convert DATE and TIME in record into DATETIME
2106  const char *pre_sql[] = {
2107  "CREATE TEMPORARY TABLE recordupdate ("
2108  "recid INT, starttime DATETIME, endtime DATETIME)",
2109  "INSERT INTO recordupdate (recid, starttime, endtime) "
2110  "SELECT recordid, "
2111  " CONCAT(startdate, ' ', starttime), "
2112  " CONCAT(enddate, ' ', endtime) FROM record",
2113  };
2114  for (size_t i = 0; i < sizeof(pre_sql)/sizeof(char*); i++)
2115  updates_ba.push_back(QByteArray(pre_sql[i]));
2116 
2117  // Convert various DATETIME fields from local time to UTC
2118  if (0 != utc_offset)
2119  {
2120  const char *with_endtime[] = {
2121  "program", "recorded", "oldrecorded", "recordupdate",
2122  };
2123  const char *without_endtime[] = {
2124  "programgenres", "programrating", "credits",
2125  "jobqueue",
2126  };
2127  QString order = (utc_offset > 0) ? "-starttime" : "starttime";
2128 
2129  for (size_t i = 0; i < sizeof(with_endtime)/sizeof(char*); i++)
2130  {
2131  updates_ba.push_back(
2132  QString("UPDATE %1 "
2133  "SET starttime = "
2134  " CONVERT_TZ(starttime, 'SYSTEM', 'Etc/UTC'), "
2135  " endtime = "
2136  " CONVERT_TZ(endtime, 'SYSTEM', 'Etc/UTC') "
2137  "ORDER BY %4")
2138  .arg(with_endtime[i])
2139  .arg(order).toLocal8Bit());
2140  }
2141 
2142  for (size_t i = 0; i < sizeof(without_endtime)/sizeof(char*); i++)
2143  {
2144  updates_ba.push_back(
2145  QString("UPDATE %1 "
2146  "SET starttime = "
2147  " CONVERT_TZ(starttime, 'SYSTEM', 'Etc/UTC') "
2148  "ORDER BY %3")
2149  .arg(without_endtime[i]).arg(order)
2150  .toLocal8Bit());
2151  }
2152 
2153  updates_ba.push_back(
2154  QString("UPDATE oldprogram "
2155  "SET airdate = "
2156  " CONVERT_TZ(airdate, 'SYSTEM', 'Etc/UTC') "
2157  "ORDER BY %3")
2158  .arg((utc_offset > 0) ? "-airdate" :
2159  "airdate").toLocal8Bit());
2160 
2161  updates_ba.push_back(
2162  QString("UPDATE recorded "
2163  "set progstart = "
2164  " CONVERT_TZ(progstart, 'SYSTEM', 'Etc/UTC'), "
2165  " progend = "
2166  " CONVERT_TZ(progend, 'SYSTEM', 'Etc/UTC') ")
2167  .toLocal8Bit());
2168  }
2169 
2170  // Convert DATETIME back to separate DATE and TIME in record table
2171  const char *post_sql[] = {
2172  "UPDATE record, recordupdate "
2173  "SET record.startdate = DATE(recordupdate.starttime), "
2174  " record.starttime = TIME(recordupdate.starttime), "
2175  " record.enddate = DATE(recordupdate.endtime), "
2176  " record.endtime = TIME(recordupdate.endtime), "
2177  " record.last_record = "
2178  " CONVERT_TZ(last_record, 'SYSTEM', 'Etc/UTC'), "
2179  " record.last_delete = "
2180  " CONVERT_TZ(last_delete, 'SYSTEM', 'Etc/UTC') "
2181  "WHERE recordid = recid",
2182  "DROP TABLE recordupdate",
2183  };
2184 
2185  for (size_t i = 0; i < sizeof(post_sql)/sizeof(char*); i++)
2186  updates_ba.push_back(QByteArray(post_sql[i]));
2187 
2188  // Convert update ByteArrays to NULL terminated char**
2189  QList<QByteArray>::const_iterator it = updates_ba.begin();
2190  vector<const char*> updates;
2191  for (; it != updates_ba.end(); ++it)
2192  updates.push_back((*it).constData());
2193  updates.push_back(nullptr);
2194 
2195  // do the actual update
2196  if (!performActualUpdate(&updates[0], "1303", dbver))
2197  return false;
2198  }
2199 
2200  if (dbver == "1303")
2201  {
2202  QDateTime loc = QDateTime::currentDateTime();
2203  QDateTime utc = loc.toUTC();
2204  loc = QDateTime(loc.date(), loc.time(), Qt::UTC);
2205  int utc_offset = loc.secsTo(utc) / 60;
2206 
2207  QList<QByteArray> updates_ba;
2208 
2209  // Convert various DATETIME fields from local time to UTC
2210  if (0 != utc_offset)
2211  {
2212  const char *with_endtime[] = {
2213  "recordedprogram",
2214  };
2215  const char *without_endtime[] = {
2216  "recordedseek", "recordedmarkup", "recordedrating",
2217  "recordedcredits",
2218  };
2219  QString order = (utc_offset > 0) ? "-starttime" : "starttime";
2220 
2221  for (size_t i = 0; i < sizeof(with_endtime)/sizeof(char*); i++)
2222  {
2223  updates_ba.push_back(
2224  QString("UPDATE %1 "
2225  "SET starttime = CONVERT_TZ(starttime, 'SYSTEM', 'Etc/UTC'), "
2226  " endtime = CONVERT_TZ(endtime, 'SYSTEM', 'Etc/UTC') "
2227  "ORDER BY %4")
2228  .arg(with_endtime[i]).arg(order).toLocal8Bit());
2229  }
2230 
2231  for (size_t i = 0; i < sizeof(without_endtime)/sizeof(char*); i++)
2232  {
2233  updates_ba.push_back(
2234  QString("UPDATE %1 "
2235  "SET starttime = CONVERT_TZ(starttime, 'SYSTEM', 'Etc/UTC') "
2236  "ORDER BY %3")
2237  .arg(without_endtime[i]).arg(order).toLocal8Bit());
2238  }
2239  }
2240 
2241  // Convert update ByteArrays to NULL terminated char**
2242  QList<QByteArray>::const_iterator it = updates_ba.begin();
2243  vector<const char*> updates;
2244  for (; it != updates_ba.end(); ++it)
2245  updates.push_back((*it).constData());
2246  updates.push_back(nullptr);
2247 
2248  // do the actual update
2249  if (!performActualUpdate(&updates[0], "1304", dbver))
2250  return false;
2251  }
2252 
2253  if (dbver == "1304")
2254  {
2255  QList<QByteArray> updates_ba;
2256 
2257  updates_ba.push_back(
2258 "UPDATE recordfilter SET clause="
2259 "'HOUR(CONVERT_TZ(program.starttime, ''Etc/UTC'', ''SYSTEM'')) >= 19 AND "
2260 "HOUR(CONVERT_TZ(program.starttime, ''Etc/UTC'', ''SYSTEM'')) < 22' "
2261 "WHERE filterid=3");
2262 
2263  updates_ba.push_back(QString(
2264 "UPDATE record SET findday = "
2265 " DAYOFWEEK(CONVERT_TZ(ADDTIME('2012-06-02 00:00:00', findtime), "
2266 " 'SYSTEM', 'Etc/UTC') + INTERVAL findday DAY) "
2267 "WHERE findday > 0").toLocal8Bit());
2268 
2269  updates_ba.push_back(QString(
2270 "UPDATE record SET findtime = "
2271 " TIME(CONVERT_TZ(ADDTIME('2012-06-02 00:00:00', findtime), "
2272 " 'SYSTEM', 'Etc/UTC')) ")
2273  .toLocal8Bit());
2274 
2275  // Convert update ByteArrays to NULL terminated char**
2276  QList<QByteArray>::const_iterator it = updates_ba.begin();
2277  vector<const char*> updates;
2278  for (; it != updates_ba.end(); ++it)
2279  updates.push_back((*it).constData());
2280  updates.push_back(nullptr);
2281 
2282  if (!performActualUpdate(&updates[0], "1305", dbver))
2283  return false;
2284  }
2285 
2286  if (dbver == "1305")
2287  {
2288  // Reverse the findday/findtime changes from above since those
2289  // values need to be kept in local time.
2290 
2291  QList<QByteArray> updates_ba;
2292 
2293  updates_ba.push_back(QString(
2294 "UPDATE record SET findday = "
2295 " DAYOFWEEK(CONVERT_TZ(ADDTIME('2012-06-02 00:00:00', findtime), "
2296 " 'Etc/UTC', 'SYSTEM') + INTERVAL findday DAY) "
2297 "WHERE findday > 0").toLocal8Bit());
2298 
2299  updates_ba.push_back(QString(
2300 "UPDATE record SET findtime = "
2301 " TIME(CONVERT_TZ(ADDTIME('2012-06-02 00:00:00', findtime), "
2302 " 'Etc/UTC', 'SYSTEM')) ").toLocal8Bit());
2303 
2304  // Convert update ByteArrays to NULL terminated char**
2305  QList<QByteArray>::const_iterator it = updates_ba.begin();
2306  vector<const char*> updates;
2307  for (; it != updates_ba.end(); ++it)
2308  updates.push_back((*it).constData());
2309  updates.push_back(nullptr);
2310 
2311  if (!performActualUpdate(&updates[0], "1306", dbver))
2312  return false;
2313  }
2314 
2315  if (dbver == "1306")
2316  {
2317  // staging temporary tables to use with rewritten file scanner
2318  // due to be replaced by finalized RecordedFile changes
2319 
2320  const char *updates[] = {
2321 "CREATE TABLE scannerfile ("
2322 " `fileid` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,"
2323 " `filesize` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,"
2324 " `filehash` VARCHAR(64) NOT NULL DEFAULT '',"
2325 " `added` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,"
2326 " PRIMARY KEY (`fileid`),"
2327 " UNIQUE KEY filehash (`filehash`)"
2328 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
2329 "CREATE TABLE scannerpath ("
2330 " `fileid` BIGINT(20) UNSIGNED NOT NULL,"
2331 " `hostname` VARCHAR(64) NOT NULL DEFAULT 'localhost',"
2332 " `storagegroup` VARCHAR(32) NOT NULL DEFAULT 'Default',"
2333 " `filename` VARCHAR(255) NOT NULL DEFAULT '',"
2334 " PRIMARY KEY (`fileid`)"
2335 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
2336 "CREATE TABLE videopart ("
2337 " `fileid` BIGINT(20) UNSIGNED NOT NULL,"
2338 " `videoid` INT(10) UNSIGNED NOT NULL,"
2339 " `order` SMALLINT UNSIGNED NOT NULL DEFAULT 1,"
2340 " PRIMARY KEY `part` (`videoid`, `order`)"
2341 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
2342 nullptr
2343 };
2344 
2345 // removed "UNIQUE KEY path (`storagegroup`, `hostname`, `filename`)" from
2346 // scannerpath as a quick fix for key length constraints
2347 
2348  if (!performActualUpdate(updates, "1307", dbver))
2349  return false;
2350  }
2351 
2352  if (dbver == "1307")
2353  {
2354  const char *updates[] = {
2355 "ALTER TABLE channel MODIFY COLUMN icon varchar(255) NOT NULL DEFAULT '';",
2356 "UPDATE channel SET icon='' WHERE icon='none';",
2357 nullptr
2358 };
2359  if (!performActualUpdate(updates, "1308", dbver))
2360  return false;
2361  }
2362 
2363  if (dbver == "1308")
2364  {
2365  const char *updates[] = {
2366 // Add this time filter
2367 "REPLACE INTO recordfilter (filterid, description, clause, newruledefault) "
2368 " VALUES (8, 'This time', 'ABS(TIMESTAMPDIFF(MINUTE, CONVERT_TZ("
2369 " ADDTIME(RECTABLE.startdate, RECTABLE.starttime), ''Etc/UTC'', ''SYSTEM''), "
2370 " CONVERT_TZ(program.starttime, ''Etc/UTC'', ''SYSTEM''))) MOD 1440 <= 10', 0)",
2371 // Add this day and time filter
2372 "REPLACE INTO recordfilter (filterid, description, clause, newruledefault) "
2373 " VALUES (9, 'This day and time', 'ABS(TIMESTAMPDIFF(MINUTE, CONVERT_TZ("
2374 " ADDTIME(RECTABLE.startdate, RECTABLE.starttime), ''Etc/UTC'', ''SYSTEM''), "
2375 " CONVERT_TZ(program.starttime, ''Etc/UTC'', ''SYSTEM''))) MOD 10080 <= 10', 0)",
2376 // Convert old, normal Timeslot rules to Channel with time filter
2377 "UPDATE record SET type = 3, filter = filter|256 "
2378 " WHERE type = 2 AND search = 0",
2379 // Convert old, normal Weekslot rules to Channel with day and time filter
2380 "UPDATE record SET type = 3, filter = filter|512 "
2381 " WHERE type = 5 AND search = 0",
2382 // Convert old, normal find daily to new, power search, find daily
2383 "UPDATE record SET type = 2, search = 1, chanid = 0, station = '', "
2384 " subtitle = '', description = CONCAT('program.title = ''', "
2385 " REPLACE(title, '''', ''''''), ''''), "
2386 " title = CONCAT(title, ' (Power Search)') WHERE type = 9 AND search = 0",
2387 // Convert old, normal find weekly to new, power search, find weekly
2388 "UPDATE record SET type = 5, search = 1, chanid = 0, station = '', "
2389 " subtitle = '', description = CONCAT('program.title = ''', "
2390 " REPLACE(title, '''', ''''''), ''''), "
2391 " title = CONCAT(title, ' (Power Search)') WHERE type = 10 AND search = 0",
2392 // Convert old, find daily to new, find daily
2393 "UPDATE record SET type = 2 WHERE type = 9",
2394 // Convert old, find weekly to new, find weekly
2395 "UPDATE record SET type = 5 WHERE type = 10",
2396 nullptr
2397 };
2398  if (!performActualUpdate(updates, "1309", dbver))
2399  return false;
2400  }
2401 
2402  if (dbver == "1309")
2403  {
2404  const char *updates[] = {
2405 // Add this channel filter
2406 "REPLACE INTO recordfilter (filterid, description, clause, newruledefault) "
2407 " VALUES (10, 'This channel', 'channel.callsign = RECTABLE.station', 0)",
2408 // Convert old, Channel rules to All with channel filter
2409 "UPDATE record SET type = 4, filter = filter|1024 WHERE type = 3",
2410 nullptr
2411 };
2412  if (!performActualUpdate(updates, "1310", dbver))
2413  return false;
2414  }
2415 
2416  if (dbver == "1310")
2417  {
2418  const char *updates[] = {
2419 // Move old table temporarily
2420 "RENAME TABLE `housekeeping` TO `oldhousekeeping`;",
2421 // Create new table in its place
2422 "CREATE TABLE `housekeeping` ("
2423 " `tag` VARCHAR(64) NOT NULL,"
2424 " `hostname` VARCHAR(64),"
2425 " `lastrun` DATETIME,"
2426 " UNIQUE KEY `task` (`tag`, `hostname`)"
2427 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
2428 // Migrate old data over
2429 "INSERT INTO `housekeeping` (`tag`, `hostname`, `lastrun`)"
2430 " SELECT SUBSTRING_INDEX(`tag`, '-', 1) AS `tag`,"
2431 " IF(LOCATE('-', `tag`) > 0,"
2432 " SUBSTRING(`tag` FROM LENGTH(SUBSTRING_INDEX(`tag`, '-', 1)) +2),"
2433 " NULL) AS `hostname`,"
2434 " `lastrun`"
2435 " FROM `oldhousekeeping`;",
2436 // Delete old data
2437 "DROP TABLE `oldhousekeeping`;",
2438 nullptr
2439 };
2440 
2441  if (!performActualUpdate(updates, "1311", dbver))
2442  return false;
2443  }
2444 
2445  if (dbver == "1311")
2446  {
2447  const char *updates[] = {
2448 // Create a global enable/disable instead of one per-host
2449 // Any hosts previously running it mean all hosts do now
2450 "INSERT INTO `settings` (`value`, `hostname`, `data`)"
2451 " SELECT 'HardwareProfileEnabled',"
2452 " NULL,"
2453 " IF((SELECT COUNT(1)"
2454 " FROM `settings`"
2455 " WHERE `value` = 'HardwareProfileLastUpdated' > 0),"
2456 " 1, 0);",
2457 // Create 'lastrun' times using existing data in settings
2458 "INSERT INTO `housekeeping` (`tag`, `hostname`, `lastrun`)"
2459 " SELECT 'HardwareProfiler',"
2460 " `hostname`,"
2461 " `data`"
2462 " FROM `settings`"
2463 " WHERE `value` = 'HardwareProfileLastUpdated';",
2464 // Clear out old settings
2465 "DELETE FROM `settings` WHERE `value` = 'HardwareProfileLastUpdated';",
2466 nullptr
2467 };
2468  if (!performActualUpdate(updates, "1312", dbver))
2469  return false;
2470  }
2471 
2472  if (dbver == "1312")
2473  {
2474  const char *updates[] = {
2475 // DVD bookmark updates
2476 "DELETE FROM `dvdbookmark` WHERE `framenum` = 0;",
2477 "ALTER TABLE dvdbookmark ADD COLUMN dvdstate varchar(1024) NOT NULL DEFAULT '';",
2478 nullptr
2479 };
2480  if (!performActualUpdate(updates, "1313", dbver))
2481  return false;
2482  }
2483 
2484  if (dbver == "1313")
2485  {
2486  // Make sure channel timeouts are long enough. No actual
2487  // schema change.
2488  const char *updates[] = {
2489  "UPDATE capturecard SET channel_timeout = 3000 WHERE "
2490  "cardtype = \"DVB\" AND channel_timeout < 3000;",
2491  "UPDATE capturecard SET channel_timeout = 30000 WHERE "
2492  "cardtype = \"FREEBOX\" AND channel_timeout < 30000;",
2493  "UPDATE capturecard SET channel_timeout = 9000 WHERE "
2494  "cardtype = \"FIREWIRE\" AND channel_timeout < 9000;",
2495  "UPDATE capturecard SET channel_timeout = 3000 WHERE "
2496  "cardtype = \"HDHOMERUN\" AND channel_timeout < 3000;",
2497  "UPDATE capturecard SET channel_timeout = 15000 WHERE "
2498  "cardtype = \"HDPVR\" AND channel_timeout < 15000;",
2499  "UPDATE capturecard SET channel_timeout = 12000 WHERE "
2500  "cardtype = \"MPEG\" AND channel_timeout < 12000;",
2501  nullptr
2502  };
2503  if (!performActualUpdate(updates, "1314", dbver))
2504  return false;
2505  }
2506 
2507  if (dbver == "1314")
2508  {
2509  // Migrate users from tmdb.py to tmdb3.py
2510  // The web interface tmdb.py uses will be shut down 2013-09-15
2511  const char *updates[] = {
2512  "UPDATE settings SET data=REPLACE(data, 'tmdb.py', 'tmdb3.py') "
2513  "WHERE value='MovieGrabber'",
2514  nullptr
2515  };
2516  if (!performActualUpdate(updates, "1315", dbver))
2517  return false;
2518  }
2519 
2520  if (dbver == "1315")
2521  {
2522  const char *updates[] = {
2523 "ALTER TABLE program ADD INDEX title_subtitle_start (title, subtitle, starttime);",
2524 "ALTER TABLE program DROP INDEX title;",
2525 nullptr
2526 };
2527  if (!performActualUpdate(updates, "1316", dbver))
2528  return false;
2529  }
2530 
2531  if (dbver == "1316")
2532  {
2533  const char *updates[] = {
2534 // adjust programid type in various tables to match the program table
2535 "ALTER TABLE oldrecorded CHANGE COLUMN programid programid varchar(64);",
2536 "ALTER TABLE oldrecorded CHANGE COLUMN seriesid seriesid varchar(64);",
2537 "ALTER TABLE record CHANGE COLUMN programid programid varchar(64);",
2538 "ALTER TABLE record CHANGE COLUMN seriesid seriesid varchar(64);",
2539 "ALTER TABLE recorded CHANGE COLUMN programid programid varchar(64);",
2540 "ALTER TABLE recorded CHANGE COLUMN seriesid seriesid varchar(64);",
2541 "ALTER TABLE recordedprogram CHANGE COLUMN programid programid varchar(64);",
2542 "ALTER TABLE recordedprogram CHANGE COLUMN seriesid seriesid varchar(64);",
2543 nullptr
2544 };
2545  if (!performActualUpdate(updates, "1317", dbver))
2546  return false;
2547  }
2548 
2549  if (dbver == "1317")
2550  {
2551  const char *updates[] = {
2552  "CREATE TABLE IF NOT EXISTS gallery_directories ("
2553  " dir_id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,"
2554  " filename VARCHAR(255) NOT NULL,"
2555  " name VARCHAR(255) NOT NULL,"
2556  " path VARCHAR(255) NOT NULL,"
2557  " parent_id INT(11) NOT NULL,"
2558  " dir_count INT(11) NOT NULL DEFAULT '0',"
2559  " file_count INT(11) NOT NULL DEFAULT '0',"
2560  " hidden TINYINT(1) NOT NULL DEFAULT '0'"
2561  ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
2562  "CREATE TABLE IF NOT EXISTS gallery_files ("
2563  " file_id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,"
2564  " filename VARCHAR(255) NOT NULL,"
2565  " name VARCHAR(255) NOT NULL,"
2566  " path VARCHAR(255) NOT NULL,"
2567  " dir_id INT(11) NOT NULL DEFAULT '0',"
2568  " type INT(11) NOT NULL DEFAULT '0',"
2569  " modtime INT(11) NOT NULL DEFAULT '0',"
2570  " size INT(11) NOT NULL DEFAULT '0',"
2571  " extension VARCHAR(255) NOT NULL,"
2572  " angle INT(11) NOT NULL DEFAULT '0',"
2573  " date INT(11) NOT NULL DEFAULT '0',"
2574  " zoom INT(11) NOT NULL DEFAULT '0',"
2575  " hidden TINYINT(1) NOT NULL DEFAULT '0',"
2576  " orientation INT(11) NOT NULL DEFAULT '0'"
2577  ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
2578  "INSERT INTO settings VALUES ('ImageStorageGroupName', 'Images', NULL);",
2579  "INSERT INTO settings VALUES ('ImageSortOrder', 0, NULL);",
2580  "INSERT INTO settings VALUES ('ImageShowHiddenFiles', 0, NULL);",
2581  "INSERT INTO settings VALUES ('ImageSlideShowTime', 3500, NULL);",
2582  "INSERT INTO settings VALUES ('ImageTransitionType', 1, NULL);",
2583  "INSERT INTO settings VALUES ('ImageTransitionTime', 1000, NULL);",
2584  nullptr
2585  };
2586 
2587  if (!performActualUpdate(&updates[0], "1318", dbver))
2588  return false;
2589  }
2590 
2591  if (dbver == "1318")
2592  {
2593  const char *updates[] = {
2594  "ALTER TABLE program "
2595  " ADD COLUMN season INT(4) NOT NULL DEFAULT '0', "
2596  " ADD COLUMN episode INT(4) NOT NULL DEFAULT '0';",
2597  "ALTER TABLE recordedprogram "
2598  " ADD COLUMN season INT(4) NOT NULL DEFAULT '0', "
2599  " ADD COLUMN episode INT(4) NOT NULL DEFAULT '0';",
2600  nullptr
2601  };
2602 
2603  if (!performActualUpdate(&updates[0], "1319", dbver))
2604  return false;
2605  }
2606 
2607  if (dbver == "1319")
2608  {
2609  // Total number of episodes in the series (season)
2610  const char *updates[] = {
2611  "ALTER TABLE program "
2612  " ADD COLUMN totalepisodes INT(4) NOT NULL DEFAULT '0';",
2613  "ALTER TABLE recordedprogram "
2614  " ADD COLUMN totalepisodes INT(4) NOT NULL DEFAULT '0';",
2615  nullptr
2616  };
2617 
2618  if (!performActualUpdate(&updates[0], "1320", dbver))
2619  return false;
2620  }
2621 
2622  if (dbver == "1320")
2623  {
2624  const char *updates[] = {
2625  "CREATE TABLE IF NOT EXISTS recgroups ("
2626  "recgroupid SMALLINT(4) NOT NULL AUTO_INCREMENT, "
2627  "recgroup VARCHAR(64) NOT NULL DEFAULT '', "
2628  "displayname VARCHAR(64) NOT NULL DEFAULT '', "
2629  "password VARCHAR(40) NOT NULL DEFAULT '', "
2630  "special TINYINT(1) NOT NULL DEFAULT '0',"
2631  "PRIMARY KEY (recgroupid), "
2632  "UNIQUE KEY recgroup ( recgroup )"
2633  ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
2634  // Create the built-in, 'special', groups
2635  "INSERT INTO recgroups ( recgroupid, recgroup, special ) VALUES ( 1, 'Default', '1' );",
2636  "INSERT INTO recgroups ( recgroupid, recgroup, special ) VALUES ( 2, 'LiveTV', '1' );",
2637  "INSERT INTO recgroups ( recgroupid, recgroup, special ) VALUES ( 3, 'Deleted', '1' );",
2638  // Copy in the passwords for the built-in groups
2639  "DELETE FROM recgrouppassword WHERE password = '';",
2640  "UPDATE recgroups r, recgrouppassword p SET r.password = p.password WHERE r.recgroup = p.recgroup;",
2641  // Copy over all existing recording groups, this information may be split over three tables!
2642  "INSERT IGNORE INTO recgroups ( recgroup, displayname, password ) SELECT DISTINCT recgroup, recgroup, password FROM recgrouppassword;",
2643  "INSERT IGNORE INTO recgroups ( recgroup, displayname ) SELECT DISTINCT recgroup, recgroup FROM record;",
2644  "INSERT IGNORE INTO recgroups ( recgroup, displayname ) SELECT DISTINCT recgroup, recgroup FROM recorded;",
2645  // Create recgroupid columns in record and recorded tables
2646  "ALTER TABLE record ADD COLUMN recgroupid SMALLINT(4) NOT NULL DEFAULT '1', ADD INDEX ( recgroupid );",
2647  "ALTER TABLE recorded ADD COLUMN recgroupid SMALLINT(4) NOT NULL DEFAULT '1', ADD INDEX ( recgroupid );",
2648  // Populate those columns with the corresponding recgroupid from the new recgroups table
2649  "UPDATE recorded, recgroups SET recorded.recgroupid = recgroups.recgroupid WHERE recorded.recgroup = recgroups.recgroup;",
2650  "UPDATE record, recgroups SET record.recgroupid = recgroups.recgroupid WHERE record.recgroup = recgroups.recgroup;",
2651  nullptr
2652  };
2653 
2654 
2655 
2656  if (!performActualUpdate(&updates[0], "1321", dbver))
2657  return false;
2658  }
2659 
2660  if (dbver == "1321")
2661  {
2662  const char *updates[] = {
2663  "ALTER TABLE `housekeeping` ADD COLUMN `lastsuccess` DATETIME;",
2664  "UPDATE `housekeeping` SET `lastsuccess`=`lastrun`;",
2665  nullptr
2666  };
2667 
2668  if (!performActualUpdate(&updates[0], "1322", dbver))
2669  return false;
2670  }
2671 
2672  if (dbver == "1322")
2673  {
2674  const char *updates[] = {
2675  // add inetref to (recorded)program before season/episode
2676  // NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
2677  "ALTER TABLE program "
2678  " ADD COLUMN inetref varchar(40) DEFAULT '' AFTER videoprop;",
2679  "ALTER TABLE recordedprogram "
2680  " ADD COLUMN inetref varchar(40) DEFAULT '' AFTER videoprop;",
2681  "DELETE FROM settings WHERE value='DefaultStartOffset';",
2682  "DELETE FROM settings WHERE value='DefaultEndOffset';",
2683  "DELETE FROM settings WHERE value='AutoExpireDefault';",
2684  "DELETE FROM settings WHERE value='AutoCommercialFlag';",
2685  "DELETE FROM settings WHERE value='AutoTranscode';",
2686  "DELETE FROM settings WHERE value='DefaultTranscoder';",
2687  "DELETE FROM settings WHERE value='AutoRunUserJob1';",
2688  "DELETE FROM settings WHERE value='AutoRunUserJob2';",
2689  "DELETE FROM settings WHERE value='AutoRunUserJob3';",
2690  "DELETE FROM settings WHERE value='AutoRunUserJob4';",
2691  "DELETE FROM settings WHERE value='AutoMetadataLookup';",
2692  "DELETE FROM housekeeping WHERE tag='DailyCleanup';",
2693  "DELETE FROM housekeeping WHERE tag='ThemeChooserInfoCacheUpdate';",
2694  nullptr
2695  };
2696  if (!performActualUpdate(updates, "1323", dbver))
2697  return false;
2698  }
2699 
2700  if (dbver == "1323")
2701  {
2702  const char *updates[] = {
2703  // add columns for Unicable related configuration data, see #9726
2704  "ALTER TABLE diseqc_tree "
2705  " ADD COLUMN scr_userband INTEGER UNSIGNED NOT NULL DEFAULT 0 AFTER address, "
2706  " ADD COLUMN scr_frequency INTEGER UNSIGNED NOT NULL DEFAULT 1400 AFTER scr_userband, "
2707  " ADD COLUMN scr_pin INTEGER NOT NULL DEFAULT '-1' AFTER scr_frequency;",
2708  nullptr
2709  };
2710 
2711  if (!performActualUpdate(updates, "1324", dbver))
2712  return false;
2713  }
2714 
2715  if (dbver == "1324")
2716  {
2717  const char *updates[] = {
2718  "ALTER TABLE recorded "
2719  " DROP PRIMARY KEY, "
2720  " ADD recordedid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, "
2721  " ADD UNIQUE KEY (chanid, starttime) ;",
2722  nullptr
2723  };
2724 
2725  if (!performActualUpdate(updates, "1325", dbver))
2726  return false;
2727  }
2728 
2729  if (dbver == "1325")
2730  {
2731  const char *updates[] = {
2732  "ALTER TABLE recorded ADD inputname VARCHAR(32);",
2733  nullptr
2734  };
2735 
2736  if (!performActualUpdate(&updates[0], "1326", dbver))
2737  return false;
2738  }
2739 
2740  if (dbver == "1326")
2741  {
2742  const char *updates[] = {
2743 // Add this time filter
2744 "REPLACE INTO recordfilter (filterid, description, clause, newruledefault) "
2745 " VALUES (8, 'This time', 'ABS(TIMESTAMPDIFF(MINUTE, CONVERT_TZ("
2746 " ADDTIME(RECTABLE.startdate, RECTABLE.starttime), ''Etc/UTC'', ''SYSTEM''), "
2747 " CONVERT_TZ(program.starttime, ''Etc/UTC'', ''SYSTEM''))) MOD 1440 "
2748 " NOT BETWEEN 11 AND 1429', 0)",
2749 // Add this day and time filter
2750 "REPLACE INTO recordfilter (filterid, description, clause, newruledefault) "
2751 " VALUES (9, 'This day and time', 'ABS(TIMESTAMPDIFF(MINUTE, CONVERT_TZ("
2752 " ADDTIME(RECTABLE.startdate, RECTABLE.starttime), ''Etc/UTC'', ''SYSTEM''), "
2753 " CONVERT_TZ(program.starttime, ''Etc/UTC'', ''SYSTEM''))) MOD 10080 "
2754 " NOT BETWEEN 11 AND 10069', 0)",
2755 nullptr
2756 };
2757  if (!performActualUpdate(updates, "1327", dbver))
2758  return false;
2759  }
2760 
2761  if (dbver == "1327")
2762  {
2763  const char *updates[] = {
2764  "DELETE r1 FROM record r1, record r2 "
2765  " WHERE r1.chanid = r2.chanid AND "
2766  " r1.starttime = r2.starttime AND "
2767  " r1.startdate = r2.startdate AND "
2768  " r1.title = r2.title AND "
2769  " r1.type = r2.type AND "
2770  " r1.recordid > r2.recordid",
2771  "ALTER TABLE record DROP INDEX chanid",
2772  "ALTER TABLE record ADD UNIQUE INDEX "
2773  " (chanid, starttime, startdate, title, type)",
2774  nullptr
2775  };
2776  if (!performActualUpdate(updates, "1328", dbver))
2777  return false;
2778  }
2779 
2780  if (dbver == "1328")
2781  {
2782  const char *updates[] = {
2783  "ALTER TABLE recordedfile "
2784  "DROP KEY `chanid`, "
2785  "DROP COLUMN `chanid`, "
2786  "DROP COLUMN `starttime`;",
2787  "ALTER TABLE recordedfile "
2788  "ADD COLUMN recordedid int(10) unsigned NOT NULL, "
2789  "ADD UNIQUE KEY `recordedid` (recordedid);",
2790  "ALTER TABLE recordedfile "
2791  "CHANGE audio_type audio_codec varchar(255) NOT NULL DEFAULT '';"
2792  "ALTER TABLE recordedfile "
2793  "CHANGE video_type video_codec varchar(255) NOT NULL DEFAULT '';",
2794  nullptr
2795  };
2796  if (!performActualUpdate(updates, "1329", dbver))
2797  return false;
2798  }
2799 
2800  if (dbver == "1329")
2801  {
2802  const char *updates[] = {
2803  "ALTER TABLE recordedfile "
2804  "DROP COLUMN audio_bits_per_sample ;", // Instead create two columns for avg and max bitrates
2805  "ALTER TABLE recordedfile "
2806  "ADD COLUMN container VARCHAR(255) NOT NULL DEFAULT '', "
2807  "ADD COLUMN total_bitrate MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, " // Kbps
2808  "ADD COLUMN video_avg_bitrate MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, " // Kbps
2809  "ADD COLUMN video_max_bitrate MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, " // Kbps
2810  "ADD COLUMN audio_avg_bitrate MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, " // Kbps
2811  "ADD COLUMN audio_max_bitrate MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 ;", // Kbps
2812  nullptr
2813  };
2814  if (!performActualUpdate(updates, "1330", dbver))
2815  return false;
2816  }
2817 
2818  if (dbver == "1330")
2819  {
2820  MSqlQuery query(MSqlQuery::InitCon());
2821  query.prepare("SELECT recordedid FROM recorded");
2822  query.exec();
2823  while (query.next())
2824  {
2825  int recordingID = query.value(0).toInt();
2826  auto *recInfo = new RecordingInfo(recordingID);
2827  RecordingFile *recFile = recInfo->GetRecordingFile();
2828  recFile->m_fileName = recInfo->GetBasename();
2829  recFile->m_fileSize = recInfo->GetFilesize();
2830  recFile->m_storageGroup = recInfo->GetStorageGroup();
2831  recFile->m_storageDeviceID = recInfo->GetHostname();
2832  switch (recInfo->QueryAverageAspectRatio())
2833  {
2834  case MARK_ASPECT_1_1 :
2835  recFile->m_videoAspectRatio = 1.0;
2836  break;
2837  case MARK_ASPECT_4_3:
2838  recFile->m_videoAspectRatio = 1.33333333333;
2839  break;
2840  case MARK_ASPECT_16_9:
2841  recFile->m_videoAspectRatio = 1.77777777777;
2842  break;
2843  case MARK_ASPECT_2_21_1:
2844  recFile->m_videoAspectRatio = 2.21;
2845  break;
2846  default:
2847  break;
2848  }
2849  QSize resolution(recInfo->QueryAverageWidth(),
2850  recInfo->QueryAverageHeight());
2851  recFile->m_videoResolution = resolution;
2852  recFile->m_videoFrameRate = (double)recInfo->QueryAverageFrameRate() / 1000.0;
2853  recFile->Save();
2854  delete recInfo;
2855  }
2856 
2857  if (!UpdateDBVersionNumber("1331", dbver))
2858  return false;
2859  }
2860 
2861  if (dbver == "1331")
2862  {
2863  LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1332");
2864  MSqlQuery select(MSqlQuery::InitCon());
2865  MSqlQuery update(MSqlQuery::InitCon());
2866 
2867  // Find all second or higher inputs using the same card.
2868  select.prepare("SELECT DISTINCT i1.cardid, i1.cardinputid "
2869  "FROM cardinput i1, cardinput i2 "
2870  "WHERE i1.cardid = i2.cardid AND "
2871  " i1.cardinputid > i2.cardinputid "
2872  "ORDER BY i1.cardid, i1.cardinputid");
2873  if (!select.exec())
2874  {
2875  MythDB::DBError("Unable to retrieve cardinputids.", select);
2876  return false;
2877  }
2878 
2879  while (select.next())
2880  {
2881  int cardid = select.value(0).toInt();
2882  int inputid = select.value(1).toInt();
2883 
2884  // Create a new card for this input.
2885  update.prepare("INSERT INTO capturecard "
2886  " ( videodevice, audiodevice, vbidevice, "
2887  " cardtype, defaultinput, audioratelimit, "
2888  " hostname, dvb_swfilter, dvb_sat_type, "
2889  " dvb_wait_for_seqstart, skipbtaudio, "
2890  " dvb_on_demand, dvb_diseqc_type, "
2891  " firewire_speed, firewire_model, "
2892  " firewire_connection, signal_timeout, "
2893  " channel_timeout, dvb_tuning_delay, "
2894  " contrast, brightness, colour, hue, "
2895  " diseqcid, dvb_eitscan ) "
2896  "SELECT videodevice, audiodevice, vbidevice, "
2897  " cardtype, defaultinput, audioratelimit, "
2898  " hostname, dvb_swfilter, dvb_sat_type, "
2899  " dvb_wait_for_seqstart, skipbtaudio, "
2900  " dvb_on_demand, dvb_diseqc_type, "
2901  " firewire_speed, firewire_model, "
2902  " firewire_connection, signal_timeout, "
2903  " channel_timeout, dvb_tuning_delay, "
2904  " contrast, brightness, colour, hue, "
2905  " diseqcid, dvb_eitscan "
2906  "FROM capturecard c "
2907  "WHERE c.cardid = :CARDID");
2908  update.bindValue(":CARDID", cardid);
2909  if (!update.exec())
2910  {
2911  MythDB::DBError("Unable to insert new card.", update);
2912  return false;
2913  }
2914  int newcardid = update.lastInsertId().toInt();
2915 
2916  // Now attach the input to the new card.
2917  update.prepare("UPDATE cardinput "
2918  "SET cardid = :NEWCARDID "
2919  "WHERE cardinputid = :INPUTID");
2920  update.bindValue(":NEWCARDID", newcardid);
2921  update.bindValue(":INPUTID", inputid);
2922  if (!update.exec())
2923  {
2924  MythDB::DBError("Unable to update input.", update);
2925  return false;
2926  }
2927  }
2928 
2929  const char *updates[] = {
2930  // Delete old, automatically created inputgroups.
2931  "DELETE FROM inputgroup WHERE inputgroupname LIKE 'DVB_%'",
2932  "DELETE FROM inputgroup WHERE inputgroupname LIKE 'CETON_%'",
2933  "DELETE FROM inputgroup WHERE inputgroupname LIKE 'HDHOMERUN_%'",
2934  // Increase the size of inputgroup.inputgroupname.
2935  "ALTER TABLE inputgroup "
2936  " MODIFY COLUMN inputgroupname VARCHAR(48)",
2937  // Rename remaining inputgroups to have 'user:' prefix.
2938  "UPDATE inputgroup "
2939  " SET inputgroupname = CONCAT('user:', inputgroupname)",
2940  // Change inputgroup.inputid to equal cardid.
2941  "UPDATE inputgroup ig "
2942  " JOIN cardinput i ON ig.cardinputid = i.cardinputid "
2943  " SET ig.cardinputid = i.cardid",
2944  // Change record.prefinput to equal cardid.
2945  "UPDATE record r "
2946  " JOIN cardinput i ON r.prefinput = i.cardinputid "
2947  " SET r.prefinput = i.cardid",
2948  // Change diseqc_config.cardinputid to equal cardid.
2949  "UPDATE diseqc_config dc "
2950  " JOIN cardinput i ON dc.cardinputid = i.cardinputid "
2951  " SET dc.cardinputid = i.cardid",
2952  // Change cardinput.cardinputid to equal cardid. Do in
2953  // multiple steps to avoid duplicate ids.
2954  "SELECT MAX(cardid) INTO @maxcardid FROM capturecard",
2955  "SELECT MAX(cardinputid) INTO @maxcardinputid FROM cardinput",
2956  "UPDATE cardinput i "
2957  " SET i.cardinputid = i.cardid + @maxcardid + @maxcardinputid",
2958  "UPDATE cardinput i "
2959  " SET i.cardinputid = i.cardid",
2960  nullptr
2961  };
2962 
2963  if (!performUpdateSeries(updates))
2964  return false;
2965 
2966  // Create an automatically generated inputgroup for each card.
2967  select.prepare("SELECT cardid, hostname, videodevice "
2968  "FROM capturecard c "
2969  "ORDER BY c.cardid");
2970  if (!select.exec())
2971  {
2972  MythDB::DBError("Unable to retrieve cardtids.", select);
2973  return false;
2974  }
2975 
2976  while (select.next())
2977  {
2978  uint cardid = select.value(0).toUInt();
2979  QString host = select.value(1).toString();
2980  QString device = select.value(2).toString();
2981  QString name = host + "|" + device;
2982  uint groupid = CardUtil::CreateInputGroup(name);
2983  if (!groupid)
2984  return false;
2985  if (!CardUtil::LinkInputGroup(cardid, groupid))
2986  return false;
2987  }
2988 
2989  // Remove orphan and administrative inputgroup entries.
2990  if (!CardUtil::UnlinkInputGroup(0, 0))
2991  return false;
2992 
2993  if (!UpdateDBVersionNumber("1332", dbver))
2994  return false;
2995  }
2996 
2997  if (dbver == "1332")
2998  {
2999  const char *updates[] = {
3000  // Move contents of cardinput to capturecard.
3001  "ALTER TABLE capturecard "
3002  " ADD COLUMN inputname VARCHAR(32) NOT NULL DEFAULT '', "
3003  " ADD COLUMN sourceid INT(10) UNSIGNED NOT NULL DEFAULT 0, "
3004  " ADD COLUMN externalcommand VARCHAR(128), "
3005  " ADD COLUMN changer_device VARCHAR(128), "
3006  " ADD COLUMN changer_model VARCHAR(128), "
3007  " ADD COLUMN tunechan VARCHAR(10), "
3008  " ADD COLUMN startchan VARCHAR(10), "
3009  " ADD COLUMN displayname VARCHAR(64) NOT NULL DEFAULT '', "
3010  " ADD COLUMN dishnet_eit TINYINT(1) NOT NULL DEFAULT 0, "
3011  " ADD COLUMN recpriority INT(11) NOT NULL DEFAULT 0, "
3012  " ADD COLUMN quicktune TINYINT(4) NOT NULL DEFAULT 0, "
3013  " ADD COLUMN schedorder INT(10) UNSIGNED NOT NULL DEFAULT 0, "
3014  " ADD COLUMN livetvorder INT(10) UNSIGNED NOT NULL DEFAULT 0",
3015  "UPDATE capturecard c "
3016  " JOIN cardinput i ON c.cardid = i.cardinputid "
3017  " SET c.inputname = i.inputname, "
3018  " c.sourceid = i.sourceid, "
3019  " c.externalcommand = i.externalcommand, "
3020  " c.changer_device = i.changer_device, "
3021  " c.changer_model = i.changer_model, "
3022  " c.tunechan = i.tunechan, "
3023  " c.startchan = i.startchan, "
3024  " c.displayname = i.displayname, "
3025  " c.dishnet_eit = i.dishnet_eit, "
3026  " c.recpriority = i.recpriority, "
3027  " c.quicktune = i.quicktune, "
3028  " c.schedorder = i.schedorder, "
3029  " c.livetvorder = i.livetvorder",
3030  "TRUNCATE cardinput",
3031  nullptr
3032  };
3033  if (!performActualUpdate(updates, "1333", dbver))
3034  return false;
3035  }
3036 
3037  if (dbver == "1333")
3038  {
3039  const char *updates[] = {
3040  // Fix default value of capturecard.inputname.
3041  "ALTER TABLE capturecard "
3042  " MODIFY COLUMN inputname VARCHAR(32) NOT NULL DEFAULT 'None'",
3043  "UPDATE capturecard c "
3044  " SET inputname = 'None' WHERE inputname = '' ",
3045  nullptr
3046  };
3047  if (!performActualUpdate(updates, "1334", dbver))
3048  return false;
3049  }
3050 
3051  if (dbver == "1334")
3052  {
3053  const char *updates[] = {
3054  // Change the default sched/livetvorder from 0 to 1.
3055  "ALTER TABLE capturecard "
3056  " MODIFY COLUMN schedorder INT(10) UNSIGNED "
3057  " NOT NULL DEFAULT 1, "
3058  " MODIFY COLUMN livetvorder INT(10) UNSIGNED "
3059  " NOT NULL DEFAULT 1",
3060  nullptr
3061  };
3062  if (!performActualUpdate(updates, "1335", dbver))
3063  return false;
3064  }
3065 
3066  if (dbver == "1335")
3067  {
3068  const char *updates[] = {
3069  // Fix custom record and custom priority references to
3070  // cardinput and cardinputid.
3071  "UPDATE record SET description = "
3072  " replace(description, 'cardinputid', 'cardid') "
3073  " WHERE search = 1",
3074  "UPDATE record SET description = "
3075  " replace(description, 'cardinput', 'capturecard') "
3076  " WHERE search = 1",
3077  "UPDATE powerpriority SET selectclause = "
3078  " replace(selectclause, 'cardinputid', 'cardid')",
3079  "UPDATE powerpriority SET selectclause = "
3080  " replace(selectclause, 'cardinput', 'capturecard')",
3081  nullptr
3082  };
3083  if (!performActualUpdate(updates, "1336", dbver))
3084  return false;
3085  }
3086 
3087  if (dbver == "1336")
3088  {
3089  const char *updates[] = {
3090  // Add a parentid columne to capturecard.
3091  "ALTER TABLE capturecard "
3092  " ADD parentid INT UNSIGNED NOT NULL DEFAULT 0 AFTER cardid",
3093  "UPDATE capturecard c, "
3094  " (SELECT min(cardid) cardid, hostname, videodevice, "
3095  " inputname, cardtype "
3096  " FROM capturecard "
3097  " WHERE cardtype NOT IN "
3098  " ('FREEBOX', 'IMPORT', 'DEMO', 'EXTERNAL') "
3099  " GROUP BY hostname, videodevice, inputname) mins "
3100  "SET c.parentid = mins.cardid "
3101  "WHERE c.hostname = mins.hostname and "
3102  " c.videodevice = mins.videodevice and "
3103  " c.inputname = mins.inputname and "
3104  " c.cardid <> mins.cardid",
3105  nullptr
3106  };
3107  if (!performActualUpdate(updates, "1337", dbver))
3108  return false;
3109  }
3110 
3111  if (dbver == "1337")
3112  {
3113  const char *updates[] = {
3114  // All next_record, last_record and last_delete to be NULL.
3115  "ALTER TABLE record MODIFY next_record DATETIME NULL",
3116  "UPDATE record SET next_record = NULL "
3117  " WHERE next_record = '0000-00-00 00:00:00'",
3118  "ALTER TABLE record MODIFY last_record DATETIME NULL",
3119  "UPDATE record SET last_record = NULL "
3120  " WHERE last_record = '0000-00-00 00:00:00'",
3121  "ALTER TABLE record MODIFY last_delete DATETIME NULL",
3122  "UPDATE record SET last_delete = NULL "
3123  " WHERE last_delete = '0000-00-00 00:00:00'",
3124  nullptr
3125  };
3126  if (!performActualUpdate(updates, "1338", dbver))
3127  return false;
3128  }
3129 
3130  if (dbver == "1338")
3131  {
3132  const char *updates[] = {
3133  "CREATE TABLE users ("
3134  " userid int(5) unsigned NOT NULL AUTO_INCREMENT,"
3135  " username varchar(128) NOT NULL DEFAULT '',"
3136  " password_digest varchar(32) NOT NULL DEFAULT '',"
3137  " lastlogin datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
3138  " PRIMARY KEY (userid),"
3139  " KEY username (username)"
3140  " ) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3141  "CREATE TABLE user_permissions ("
3142  " userid int(5) unsigned NOT NULL,"
3143  " permission varchar(128) NOT NULL DEFAULT '',"
3144  " PRIMARY KEY (userid)"
3145  " ) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3146  "CREATE TABLE user_sessions ("
3147  " sessiontoken varchar(40) NOT NULL DEFAULT ''," // SHA1
3148  " userid int(5) unsigned NOT NULL,"
3149  " client varchar(128) NOT NULL, "
3150  " created datetime NOT NULL,"
3151  " lastactive datetime NOT NULL,"
3152  " expires datetime NOT NULL,"
3153  " PRIMARY KEY (sessionToken),"
3154  " UNIQUE KEY userid_client (userid,client)"
3155  " ) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3156  "INSERT INTO users SET username='admin'," // Temporary default account
3157  " password_digest='bcd911b2ecb15ffbd6d8e6e744d60cf6';",
3158  nullptr
3159  };
3160  if (!performActualUpdate(updates, "1339", dbver))
3161  return false;
3162  }
3163 
3164  if (dbver == "1339")
3165  {
3166  MSqlQuery query(MSqlQuery::InitCon());
3167 
3168  // insert a new profile group for the VBox
3169  query.prepare("INSERT INTO profilegroups SET name = 'VBox Recorder', "
3170  "cardtype = 'VBOX', is_default = 1;");
3171  if (!query.exec())
3172  {
3173  MythDB::DBError("Unable to insert vbox profilegroup.", query);
3174  return false;
3175  }
3176 
3177  // get the id of the new profile group
3178  int groupid = query.lastInsertId().toInt();
3179 
3180  // insert the recording profiles
3181  query.prepare("INSERT INTO recordingprofiles SET name = \"Default\", profilegroup = :GROUPID;");
3182  query.bindValue(":GROUPID", groupid);
3183  if (!query.exec())
3184  {
3185  MythDB::DBError("Unable to insert 'Default' recordingprofile.", query);
3186  return false;
3187  }
3188 
3189  query.prepare("INSERT INTO recordingprofiles SET name = \"Live TV\", profilegroup = :GROUPID;");
3190  query.bindValue(":GROUPID", groupid);
3191  if (!query.exec())
3192  {
3193  MythDB::DBError("Unable to insert 'Live TV' recordingprofile.", query);
3194  return false;
3195  }
3196 
3197  query.prepare("INSERT INTO recordingprofiles SET name = \"High Quality\", profilegroup = :GROUPID;");
3198  query.bindValue(":GROUPID", groupid);
3199  if (!query.exec())
3200  {
3201  MythDB::DBError("Unable to insert 'High Quality' recordingprofile.", query);
3202  return false;
3203  }
3204 
3205  query.prepare("INSERT INTO recordingprofiles SET name = \"Low Quality\", profilegroup = :GROUPID;");
3206  query.bindValue(":GROUPID", groupid);
3207  if (!query.exec())
3208  {
3209  MythDB::DBError("Unable to insert 'Low Quality' recordingprofile.", query);
3210  return false;
3211  }
3212 
3213  if (!UpdateDBVersionNumber("1340", dbver))
3214  return false;
3215  }
3216 
3217  if (dbver == "1340")
3218  {
3219  const char *updates[] = {
3220  // Add filter to ignore episodes (e.g. in a person search)
3221  "REPLACE INTO recordfilter (filterid, description, clause, newruledefault) "
3222  " VALUES (11, 'No episodes', 'program.category_type <> ''series''', 0)",
3223  nullptr
3224  };
3225  if (!performActualUpdate(updates, "1341", dbver))
3226  return false;
3227  }
3228 
3229  if (dbver == "1341")
3230  {
3231  const char *updates[] = {
3232  "UPDATE profilegroups SET cardtype='FREEBOX' WHERE cardtype='Freebox'",
3233  nullptr
3234  };
3235  if (!performActualUpdate(updates, "1342", dbver))
3236  return false;
3237  }
3238 
3239  if (dbver == "1342")
3240  {
3241  LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1343");
3242  MSqlQuery select(MSqlQuery::InitCon());
3243  MSqlQuery update(MSqlQuery::InitCon());
3244 
3245  const char *updates[] = {
3246  // Delete automatically created inputgroups.
3247  "DELETE FROM inputgroup WHERE inputgroupname REGEXP '^[a-z_-]*\\\\|'",
3248  // Increase the size of inputgroup.inputgroupname.
3249  "ALTER TABLE inputgroup "
3250  " MODIFY COLUMN inputgroupname VARCHAR(128)",
3251  nullptr
3252  };
3253 
3254  if (!performUpdateSeries(updates))
3255  return false;
3256 
3257  // Recreate automatically generated inputgroup for each card.
3258  select.prepare("SELECT cardid, parentid, cardtype, hostname, "
3259  " videodevice "
3260  "FROM capturecard c "
3261  "ORDER BY c.cardid");
3262  if (!select.exec())
3263  {
3264  MythDB::DBError("Unable to retrieve cardtids.", select);
3265  return false;
3266  }
3267 
3268  while (select.next())
3269  {
3270  uint cardid = select.value(0).toUInt();
3271  uint parentid = select.value(1).toUInt();
3272  QString type = select.value(2).toString();
3273  QString host = select.value(3).toString();
3274  QString device = select.value(4).toString();
3275  QString name = host + "|" + device;
3276  if (type == "FREEBOX" || type == "IMPORT" ||
3277  type == "DEMO" || type == "EXTERNAL")
3278  name += QString("|%1").arg(parentid ? parentid : cardid);
3279  uint groupid = CardUtil::CreateInputGroup(name);
3280  if (!groupid)
3281  return false;
3282  if (!CardUtil::LinkInputGroup(cardid, groupid))
3283  return false;
3284  }
3285 
3286  // Remove orphan and administrative inputgroup entries.
3287  if (!CardUtil::UnlinkInputGroup(0, 0))
3288  return false;
3289 
3290  if (!UpdateDBVersionNumber("1343", dbver))
3291  return false;
3292  }
3293 
3294  if (dbver == "1343")
3295  {
3296  const char *updates[] = {
3297  "DROP TABLE IF EXISTS bdbookmark;",
3298  "CREATE TABLE bdbookmark ("
3299  " serialid varchar(40) NOT NULL DEFAULT '',"
3300  " `name` varchar(128) DEFAULT NULL,"
3301  " bdstate varchar(4096) NOT NULL DEFAULT '',"
3302  " `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,"
3303  " PRIMARY KEY (serialid)"
3304  ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3305 
3306  // #12612 strip \0 characters from channel/channelscan_channel callsign and name
3307  "UPDATE channel SET callsign=REPLACE(callsign,'\\0',''),"
3308  "name=REPLACE(name,'\\0','');",
3309 
3310  // "BackendWSPort" was removed in caaaeef8166722888012f4ecaf3e9b0f09df512a
3311  "DELETE FROM settings WHERE value='BackendWSPort';",
3312  nullptr
3313  };
3314 
3315  if (!performActualUpdate(&updates[0], "1344", dbver))
3316  return false;
3317  }
3318 
3319  if (dbver == "1344")
3320  {
3321  const char *updates[] = {
3322  "ALTER TABLE capturecard ADD COLUMN "
3323  " reclimit INT UNSIGNED DEFAULT 1 NOT NULL",
3324  "UPDATE capturecard cc, "
3325  " ( SELECT IF(parentid>0, parentid, cardid) cardid, "
3326  " count(*) cnt "
3327  " FROM capturecard "
3328  " GROUP BY if(parentid>0, parentid, cardid) "
3329  " ) p "
3330  "SET cc.reclimit = p.cnt "
3331  "WHERE cc.cardid = p.cardid OR cc.parentid = p.cardid",
3332  nullptr
3333  };
3334 
3335  if (!performActualUpdate(&updates[0], "1345", dbver))
3336  return false;
3337  }
3338 
3339  if (dbver == "1345")
3340  {
3341  const char *updates[] = {
3342  "ALTER TABLE capturecard ADD COLUMN "
3343  " schedgroup TINYINT(1) DEFAULT 0 NOT NULL",
3344  nullptr
3345  };
3346 
3347  if (!performActualUpdate(&updates[0], "1346", dbver))
3348  return false;
3349  }
3350 
3351  /*
3352  * TODO the following settings are no more, clean them up with the next schema change
3353  * to avoid confusion by stale settings in the database
3354  *
3355  * WatchTVGuide
3356  */
3357 
3358  if (dbver == "1346")
3359  {
3360  QString master;
3361  // Create new MasterServerName setting
3362  if (gCoreContext->IsMasterHost())
3363  master =
3364  "insert into settings (value,data,hostname) "
3365  "values('MasterServerName','"
3366  + gCoreContext->GetHostName() + "', null);";
3367  else
3368  master =
3369  "insert into settings (value,data,hostname) "
3370  "select 'MasterServerName', b.hostname, null "
3371  "from settings a, settings b "
3372  "where a.value = 'MasterServerIP' "
3373  "and b.value in ('BackendServerIP','BackendServerIP6')"
3374  "and a.data = b.data;";
3375 
3376  const char *updates[] = {
3377  // Create new MasterServerName setting
3378  master.toLocal8Bit().constData(),
3379  // Create new BackendServerAddr setting for each backend server
3380  // Assume using IPV4 value.
3381  "insert into settings (value,data,hostname) "
3382  "select 'BackendServerAddr', data,hostname from settings "
3383  "where value = 'BackendServerIP';",
3384  // Update BackendServerAddr setting for cases where IPV6 is used
3385  "update settings a, settings b "
3386  "set b.data = a.data "
3387  "where a.value = 'BackendServerIP6' "
3388  "and b.hostname = a.hostname "
3389  "and b.value = 'BackendServerAddr' "
3390  "and b.data = '127.0.0.1' "
3391  "and a.data != '::1' "
3392  "and a.data is not null "
3393  "and a.data != ''; ",
3394  // Update BackendServerAddr setting for master backend to
3395  // conform to MasterServerIP setting
3396  "update settings a, settings b, settings c "
3397  "set c.data = a.data "
3398  "where a.value = 'MasterServerIP' " // 1 row
3399  "and b.value = 'MasterServerName' " // 1 row
3400  "and c.value = 'BackendServerAddr' " // 1 row per BE
3401  "and c.hostname = b.data;", // restrict to master
3402  // Delete obsolete settings
3403  "delete from settings "
3404  "where value in ('WatchTVGuide');",
3405  nullptr
3406  };
3407 
3408  if (!performActualUpdate(&updates[0], "1347", dbver))
3409  return false;
3410  }
3411 
3412  if (dbver == "1347")
3413  {
3414  const char *updates[] = {
3415  "ALTER TABLE record MODIFY COLUMN startdate DATE DEFAULT NULL",
3416  "ALTER TABLE record MODIFY COLUMN enddate DATE DEFAULT NULL",
3417  "ALTER TABLE record MODIFY COLUMN starttime TIME DEFAULT NULL",
3418  "ALTER TABLE record MODIFY COLUMN endtime TIME DEFAULT NULL",
3419  nullptr
3420  };
3421  if (!performActualUpdate(updates, "1348", dbver))
3422  return false;
3423  }
3424 
3425  if (dbver == "1348")
3426  {
3427  const char *updates[] = {
3428  "update capturecard "
3429  " set videodevice=left(videodevice, "
3430  " locate('-', videodevice)-1) "
3431  " where cardtype='HDHOMERUN' "
3432  " and videodevice like '%-%'",
3433  nullptr
3434  };
3435  if (!performActualUpdate(updates, "1349", dbver))
3436  return false;
3437  }
3438 
3439  if (dbver == "1349")
3440  {
3441  const char *updates[] = {
3442  // Incorrect DB update removed
3443  nullptr
3444  };
3445  if (!performActualUpdate(updates, "1350", dbver))
3446  return false;
3447  }
3448 
3449  if (dbver == "1350")
3450  {
3451  const char *updates[] = {
3452  "ALTER TABLE videosource ADD COLUMN bouquet_id INT DEFAULT 0;",
3453  "ALTER TABLE videosource ADD COLUMN region_id INT DEFAULT 0;",
3454  nullptr
3455  };
3456  if (!performActualUpdate(updates, "1351", dbver))
3457  return false;
3458  }
3459 
3460  if (dbver == "1351")
3461  {
3462  const char *updates[] = {
3463  "ALTER TABLE videosource MODIFY bouquet_id INT UNSIGNED;",
3464  "ALTER TABLE videosource MODIFY region_id INT UNSIGNED;",
3465  "ALTER TABLE channel ADD COLUMN service_type INT UNSIGNED DEFAULT 0 AFTER serviceid;",
3466  nullptr
3467  };
3468  if (!performActualUpdate(updates, "1352", dbver))
3469  return false;
3470  }
3471 
3472  if (dbver == "1352")
3473  {
3474  const char *updates[] = {
3475  "ALTER TABLE capturecard MODIFY schedgroup TINYINT(1) DEFAULT 1 NOT NULL",
3476  nullptr
3477  };
3478  if (!performActualUpdate(updates, "1353", dbver))
3479  return false;
3480  }
3481 
3482  if (dbver == "1353")
3483  {
3484  const char *updates[] = {
3485  "ALTER TABLE channel ADD COLUMN deleted TIMESTAMP NULL",
3486  nullptr
3487  };
3488  if (!performActualUpdate(updates, "1354", dbver))
3489  return false;
3490  }
3491 
3492  if (dbver == "1354")
3493  {
3494  const char *updates[] = {
3495  "ALTER TABLE videosource ADD COLUMN scanfrequency INT UNSIGNED DEFAULT 0;",
3496  nullptr
3497  };
3498  if (!performActualUpdate(updates, "1355", dbver))
3499  return false;
3500  }
3501 
3502  if (dbver == "1355")
3503  {
3504  const char *updates[] = {
3505  "UPDATE capturecard "
3506  "SET displayname = CONCAT('Input ', cardid) "
3507  "WHERE displayname = ''",
3508  nullptr
3509  };
3510  if (!performActualUpdate(updates, "1356", dbver))
3511  return false;
3512  }
3513 
3514  if (dbver == "1356")
3515  {
3516  const char *updates[] = {
3517  "REPLACE INTO recordfilter (filterid, description, clause, "
3518  " newruledefault) "
3519  " VALUES (12, 'Priority channel', 'channel.recpriority > 0', 0)",
3520  nullptr
3521  };
3522  if (!performActualUpdate(updates, "1357", dbver))
3523  return false;
3524  }
3525 
3526  if (dbver == "1357")
3527  {
3528  // convert old VideoDisplayProfile settings to new format
3529  ProfileItem temp;
3530  vector<ProfileItem> profiles;
3531 
3532  MSqlQuery query(MSqlQuery::InitCon());
3533  query.prepare("SELECT profileid, value, data FROM displayprofiles "
3534  "ORDER BY profileid");
3535 
3536  for (;;)
3537  {
3538  if (!query.exec())
3539  break;
3540 
3541  uint currentprofile = 0;
3542  while (query.next())
3543  {
3544  if (query.value(0).toUInt() != currentprofile)
3545  {
3546  if (currentprofile)
3547  {
3548  temp.SetProfileID(currentprofile);
3549  profiles.push_back(temp);
3550  }
3551  temp.Clear();
3552  currentprofile = query.value(0).toUInt();
3553  }
3554  temp.Set(query.value(1).toString(), query.value(2).toString());
3555  }
3556 
3557  if (currentprofile)
3558  {
3559  temp.SetProfileID(currentprofile);
3560  profiles.push_back(temp);
3561  }
3562 
3563  foreach(ProfileItem profile, profiles)
3564  {
3565  QString newdecoder;
3566  QString newrender;
3567  QString newdeint0;
3568  QString newdeint1;
3569 
3570  QString olddecoder = profile.Get("pref_decoder");
3571  QString oldrender = profile.Get("pref_videorenderer");
3572  QString olddeint0 = profile.Get("pref_deint0");
3573  QString olddeint1 = profile.Get("pref_deint1");
3574 
3575  if (oldrender == "xv-blit")
3576  {
3577  newdecoder = "ffmpeg";
3578  newrender = "opengl-yv12";
3579  }
3580  if (olddecoder == "openmax" || oldrender == "openmax")
3581  {
3582  newdecoder = "mmal-dec";
3583  newrender = "opengl-yv12";
3584  }
3585  if ((olddecoder == "mediacodec") || (olddecoder == "nvdec") ||
3586  (olddecoder == "vda") || (olddecoder == "vaapi2") ||
3587  (olddecoder == "vaapi" && oldrender == "openglvaapi") ||
3588  (olddecoder == "vdpau" && oldrender == "vdpau"))
3589  {
3590  if (oldrender != "opengl-hw")
3591  newrender = "opengl-hw";
3592  }
3593  if (olddecoder == "vda")
3594  newdecoder = "vtb";
3595  if (olddecoder == "vaapi2")
3596  newdecoder = "vaapi";
3597 
3598  auto UpdateDeinterlacer = [](const QString &Olddeint, QString &Newdeint, const QString &Decoder)
3599  {
3600  if (Olddeint.isEmpty())
3601  {
3602  Newdeint = "none";
3603  }
3604  else if (Olddeint == "none" ||
3605  Olddeint.contains(DEINT_QUALITY_SHADER) ||
3606  Olddeint.contains(DEINT_QUALITY_DRIVER) ||
3607  Olddeint.contains(DEINT_QUALITY_LOW) ||
3608  Olddeint.contains(DEINT_QUALITY_MEDIUM) ||
3609  Olddeint.contains(DEINT_QUALITY_HIGH))
3610  {
3611  return;
3612  }
3613 
3614  QStringList newsettings;
3615  bool driver = (Decoder != "ffmpeg") &&
3616  (Olddeint.contains("vaapi") || Olddeint.contains("vdpau") ||
3617  Olddeint.contains("nvdec"));
3618  if (driver)
3619  newsettings << DEINT_QUALITY_DRIVER;
3620  if (Olddeint.contains("opengl") || driver)
3621  newsettings << DEINT_QUALITY_SHADER;
3622 
3623  if (Olddeint.contains("greedy") || Olddeint.contains("yadif") ||
3624  Olddeint.contains("kernel") || Olddeint.contains("advanced") ||
3625  Olddeint.contains("compensated") || Olddeint.contains("adaptive"))
3626  {
3627  newsettings << DEINT_QUALITY_HIGH;
3628  }
3629  else if (Olddeint.contains("bob") || Olddeint.contains("onefield") ||
3630  Olddeint.contains("linedouble"))
3631  {
3632  newsettings << DEINT_QUALITY_LOW;
3633  }
3634  else
3635  {
3636  newsettings << DEINT_QUALITY_MEDIUM;
3637  }
3638  Newdeint = newsettings.join(":");
3639  };
3640 
3641  QString decoder = newdecoder.isEmpty() ? olddecoder : newdecoder;
3642  UpdateDeinterlacer(olddeint0, newdeint0, decoder);
3643  UpdateDeinterlacer(olddeint1, newdeint1, decoder);
3644 
3645  auto UpdateData = [](uint ProfileID, const QString &Value, const QString &Data)
3646  {
3647  MSqlQuery update(MSqlQuery::InitCon());
3648  update.prepare(
3649  "UPDATE displayprofiles SET data = :DATA "
3650  "WHERE profileid = :PROFILEID AND value = :VALUE");
3651  update.bindValue(":PROFILEID", ProfileID);
3652  update.bindValue(":VALUE", Value);
3653  update.bindValue(":DATA", Data);
3654  if (!update.exec())
3655  LOG(VB_GENERAL, LOG_ERR,
3656  QString("Error updating display profile id %1").arg(ProfileID));
3657  };
3658 
3659  uint id = profile.GetProfileID();
3660  if (!newdecoder.isEmpty())
3661  UpdateData(id, "pref_decoder", newdecoder);
3662  if (!newrender.isEmpty())
3663  UpdateData(id, "pref_videorenderer", newrender);
3664  if (!newdeint0.isEmpty())
3665  UpdateData(id, "pref_deint0", newdeint0);
3666  if (!newdeint1.isEmpty())
3667  UpdateData(id, "pref_deint1", newdeint1);
3668  }
3669  break;
3670  }
3671 
3672  // remove old studio levels keybinding
3673  const char *updates[] = {
3674  "DELETE FROM keybindings WHERE action='TOGGLESTUDIOLEVELS'",
3675  nullptr
3676  };
3677 
3678  if (!performActualUpdate(&updates[0], "1358", dbver))
3679  return false;
3680  }
3681 
3682  if (dbver == "1358")
3683  {
3684  const char *updates[] = {
3685  // Allow videosouce.userid to be NULL as originally intended.
3686  "ALTER TABLE videosource "
3687  " CHANGE COLUMN userid userid VARCHAR(128) NULL DEFAULT NULL",
3688  // And fix any leftover, empty values.
3689  "UPDATE videosource "
3690  " SET userid = NULL "
3691  " WHERE userid = ''",
3692  // Remove potential clear text credentials no longer usable
3693  "UPDATE videosource "
3694  " SET userid = NULL, password = NULL "
3695  " WHERE xmltvgrabber IN ('schedulesdirect1', 'datadirect')",
3696  nullptr
3697  };
3698  if (!performActualUpdate(updates, "1359", dbver))
3699  return false;
3700  }
3701 
3702  return true;
3703 }
3704 
3724 {
3725  MSqlQuery query(MSqlQuery::InitCon());
3726  query.prepare("SHOW TABLES;");
3727 
3728  // check for > 1 table here since the schemalock table should exist
3729  if (query.exec() && query.isActive() && query.size() > 1)
3730  {
3731  QString msg = QString(
3732  "Told to create a NEW database schema, but the database\n"
3733  "already has %1 tables.\n"
3734  "If you are sure this is a good MythTV database, verify\n"
3735  "that the settings table has the DBSchemaVer variable.\n")
3736  .arg(query.size() - 1);
3737  LOG(VB_GENERAL, LOG_ERR, msg);
3738  return false;
3739  }
3740 
3741  LOG(VB_GENERAL, LOG_NOTICE,
3742  "Inserting MythTV initial database information.");
3743 
3744  const char *updates[] = {
3745 "CREATE TABLE capturecard ("
3746 " cardid int(10) unsigned NOT NULL AUTO_INCREMENT,"
3747 " videodevice varchar(128) DEFAULT NULL,"
3748 " audiodevice varchar(128) DEFAULT NULL,"
3749 " vbidevice varchar(128) DEFAULT NULL,"
3750 " cardtype varchar(32) DEFAULT 'V4L',"
3751 " defaultinput varchar(32) DEFAULT 'Television',"
3752 " audioratelimit int(11) DEFAULT NULL,"
3753 " hostname varchar(64) DEFAULT NULL,"
3754 " dvb_swfilter int(11) DEFAULT '0',"
3755 " dvb_sat_type int(11) NOT NULL DEFAULT '0',"
3756 " dvb_wait_for_seqstart int(11) NOT NULL DEFAULT '1',"
3757 " skipbtaudio tinyint(1) DEFAULT '0',"
3758 " dvb_on_demand tinyint(4) NOT NULL DEFAULT '0',"
3759 " dvb_diseqc_type smallint(6) DEFAULT NULL,"
3760 " firewire_speed int(10) unsigned NOT NULL DEFAULT '0',"
3761 " firewire_model varchar(32) DEFAULT NULL,"
3762 " firewire_connection int(10) unsigned NOT NULL DEFAULT '0',"
3763 " signal_timeout int(11) NOT NULL DEFAULT '1000',"
3764 " channel_timeout int(11) NOT NULL DEFAULT '3000',"
3765 " dvb_tuning_delay int(10) unsigned NOT NULL DEFAULT '0',"
3766 " contrast int(11) NOT NULL DEFAULT '0',"
3767 " brightness int(11) NOT NULL DEFAULT '0',"
3768 " colour int(11) NOT NULL DEFAULT '0',"
3769 " hue int(11) NOT NULL DEFAULT '0',"
3770 " diseqcid int(10) unsigned DEFAULT NULL,"
3771 " dvb_eitscan tinyint(1) NOT NULL DEFAULT '1',"
3772 " PRIMARY KEY (cardid)"
3773 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3774 "CREATE TABLE cardinput ("
3775 " cardinputid int(10) unsigned NOT NULL AUTO_INCREMENT,"
3776 " cardid int(10) unsigned NOT NULL DEFAULT '0',"
3777 " sourceid int(10) unsigned NOT NULL DEFAULT '0',"
3778 " inputname varchar(32) NOT NULL DEFAULT '',"
3779 " externalcommand varchar(128) DEFAULT NULL,"
3780 " changer_device varchar(128) DEFAULT NULL,"
3781 " changer_model varchar(128) DEFAULT NULL,"
3782 " tunechan varchar(10) DEFAULT NULL,"
3783 " startchan varchar(10) DEFAULT NULL,"
3784 " displayname varchar(64) NOT NULL DEFAULT '',"
3785 " dishnet_eit tinyint(1) NOT NULL DEFAULT '0',"
3786 " recpriority int(11) NOT NULL DEFAULT '0',"
3787 " quicktune tinyint(4) NOT NULL DEFAULT '0',"
3788 " schedorder int(10) unsigned NOT NULL DEFAULT '0',"
3789 " livetvorder int(10) unsigned NOT NULL DEFAULT '0',"
3790 " PRIMARY KEY (cardinputid)"
3791 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3792 "CREATE TABLE channel ("
3793 " chanid int(10) unsigned NOT NULL DEFAULT '0',"
3794 " channum varchar(10) NOT NULL DEFAULT '',"
3795 " freqid varchar(10) DEFAULT NULL,"
3796 " sourceid int(10) unsigned DEFAULT NULL,"
3797 " callsign varchar(20) NOT NULL DEFAULT '',"
3798 " `name` varchar(64) NOT NULL DEFAULT '',"
3799 " icon varchar(255) NOT NULL DEFAULT '',"
3800 " finetune int(11) DEFAULT NULL,"
3801 " videofilters varchar(255) NOT NULL DEFAULT '',"
3802 " xmltvid varchar(255) NOT NULL DEFAULT '',"
3803 " recpriority int(10) NOT NULL DEFAULT '0',"
3804 " contrast int(11) DEFAULT '32768',"
3805 " brightness int(11) DEFAULT '32768',"
3806 " colour int(11) DEFAULT '32768',"
3807 " hue int(11) DEFAULT '32768',"
3808 " tvformat varchar(10) NOT NULL DEFAULT 'Default',"
3809 " visible tinyint(1) NOT NULL DEFAULT '1',"
3810 " outputfilters varchar(255) NOT NULL DEFAULT '',"
3811 " useonairguide tinyint(1) DEFAULT '0',"
3812 " mplexid smallint(6) DEFAULT NULL,"
3813 " serviceid mediumint(8) unsigned DEFAULT NULL,"
3814 " tmoffset int(11) NOT NULL DEFAULT '0',"
3815 " atsc_major_chan int(10) unsigned NOT NULL DEFAULT '0',"
3816 " atsc_minor_chan int(10) unsigned NOT NULL DEFAULT '0',"
3817 " last_record datetime NOT NULL,"
3818 " default_authority varchar(32) NOT NULL DEFAULT '',"
3819 " commmethod int(11) NOT NULL DEFAULT '-1',"
3820 " iptvid smallint(6) unsigned DEFAULT NULL,"
3821 " PRIMARY KEY (chanid),"
3822 " KEY channel_src (channum,sourceid),"
3823 " KEY sourceid (sourceid,xmltvid,chanid),"
3824 " KEY visible (visible)"
3825 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3826 "CREATE TABLE channelgroup ("
3827 " id int(10) unsigned NOT NULL AUTO_INCREMENT,"
3828 " chanid int(11) unsigned NOT NULL DEFAULT '0',"
3829 " grpid int(11) NOT NULL DEFAULT '1',"
3830 " PRIMARY KEY (id)"
3831 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3832 "CREATE TABLE channelgroupnames ("
3833 " grpid int(10) unsigned NOT NULL AUTO_INCREMENT,"
3834 " `name` varchar(64) NOT NULL DEFAULT '0',"
3835 " PRIMARY KEY (grpid)"
3836 ") ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;",
3837 "CREATE TABLE channelscan ("
3838 " scanid int(3) unsigned NOT NULL AUTO_INCREMENT,"
3839 " cardid int(3) unsigned NOT NULL,"
3840 " sourceid int(3) unsigned NOT NULL,"
3841 " processed tinyint(1) unsigned NOT NULL,"
3842 " scandate datetime NOT NULL,"
3843 " PRIMARY KEY (scanid)"
3844 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3845 "CREATE TABLE channelscan_channel ("
3846 " transportid int(6) unsigned NOT NULL,"
3847 " scanid int(3) unsigned NOT NULL,"
3848 " mplex_id smallint(6) NOT NULL,"
3849 " source_id int(3) unsigned NOT NULL,"
3850 " channel_id int(3) unsigned NOT NULL DEFAULT '0',"
3851 " callsign varchar(20) NOT NULL DEFAULT '',"
3852 " service_name varchar(64) NOT NULL DEFAULT '',"
3853 " chan_num varchar(10) NOT NULL DEFAULT '',"
3854 " service_id mediumint(8) unsigned NOT NULL DEFAULT '0',"
3855 " atsc_major_channel int(4) unsigned NOT NULL DEFAULT '0',"
3856 " atsc_minor_channel int(4) unsigned NOT NULL DEFAULT '0',"
3857 " use_on_air_guide tinyint(1) NOT NULL DEFAULT '0',"
3858 " hidden tinyint(1) NOT NULL DEFAULT '0',"
3859 " hidden_in_guide tinyint(1) NOT NULL DEFAULT '0',"
3860 " freqid varchar(10) NOT NULL DEFAULT '',"
3861 " icon varchar(255) NOT NULL DEFAULT '',"
3862 " tvformat varchar(10) NOT NULL DEFAULT 'Default',"
3863 " xmltvid varchar(64) NOT NULL DEFAULT '',"
3864 " pat_tsid int(5) unsigned NOT NULL DEFAULT '0',"
3865 " vct_tsid int(5) unsigned NOT NULL DEFAULT '0',"
3866 " vct_chan_tsid int(5) unsigned NOT NULL DEFAULT '0',"
3867 " sdt_tsid int(5) unsigned NOT NULL DEFAULT '0',"
3868 " orig_netid int(5) unsigned NOT NULL DEFAULT '0',"
3869 " netid int(5) unsigned NOT NULL DEFAULT '0',"
3870 " si_standard varchar(10) NOT NULL,"
3871 " in_channels_conf tinyint(1) unsigned NOT NULL DEFAULT '0',"
3872 " in_pat tinyint(1) unsigned NOT NULL DEFAULT '0',"
3873 " in_pmt tinyint(1) unsigned NOT NULL DEFAULT '0',"
3874 " in_vct tinyint(1) unsigned NOT NULL DEFAULT '0',"
3875 " in_nit tinyint(1) unsigned NOT NULL DEFAULT '0',"
3876 " in_sdt tinyint(1) unsigned NOT NULL DEFAULT '0',"
3877 " is_encrypted tinyint(1) unsigned NOT NULL DEFAULT '0',"
3878 " is_data_service tinyint(1) unsigned NOT NULL DEFAULT '0',"
3879 " is_audio_service tinyint(1) unsigned NOT NULL DEFAULT '0',"
3880 " is_opencable tinyint(1) unsigned NOT NULL DEFAULT '0',"
3881 " could_be_opencable tinyint(1) unsigned NOT NULL DEFAULT '0',"
3882 " decryption_status smallint(2) unsigned NOT NULL DEFAULT '0',"
3883 " default_authority varchar(32) NOT NULL DEFAULT ''"
3884 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3885 "CREATE TABLE channelscan_dtv_multiplex ("
3886 " transportid int(6) unsigned NOT NULL AUTO_INCREMENT,"
3887 " scanid int(3) unsigned NOT NULL,"
3888 " mplexid smallint(6) unsigned NOT NULL,"
3889 " frequency bigint(12) unsigned NOT NULL,"
3890 " inversion char(1) NOT NULL DEFAULT 'a',"
3891 " symbolrate bigint(12) unsigned NOT NULL DEFAULT '0',"
3892 " fec varchar(10) NOT NULL DEFAULT 'auto',"
3893 " polarity char(1) NOT NULL DEFAULT '',"
3894 " hp_code_rate varchar(10) NOT NULL DEFAULT 'auto',"
3895 " mod_sys varchar(10) DEFAULT NULL,"
3896 " rolloff varchar(4) DEFAULT NULL,"
3897 " lp_code_rate varchar(10) NOT NULL DEFAULT 'auto',"
3898 " modulation varchar(10) NOT NULL DEFAULT 'auto',"
3899 " transmission_mode char(1) NOT NULL DEFAULT 'a',"
3900 " guard_interval varchar(10) NOT NULL DEFAULT 'auto',"
3901 " hierarchy varchar(10) NOT NULL DEFAULT 'auto',"
3902 " bandwidth char(1) NOT NULL DEFAULT 'a',"
3903 " sistandard varchar(10) NOT NULL,"
3904 " tuner_type smallint(2) unsigned NOT NULL,"
3905 " default_authority varchar(32) NOT NULL DEFAULT '',"
3906 " PRIMARY KEY (transportid)"
3907 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3908 "CREATE TABLE codecparams ("
3909 " `profile` int(10) unsigned NOT NULL DEFAULT '0',"
3910 " `name` varchar(128) NOT NULL DEFAULT '',"
3911 " `value` varchar(128) DEFAULT NULL,"
3912 " PRIMARY KEY (`profile`,`name`)"
3913 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3914 "CREATE TABLE credits ("
3915 " person mediumint(8) unsigned NOT NULL DEFAULT '0',"
3916 " chanid int(10) unsigned NOT NULL DEFAULT '0',"
3917 " starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
3918 " role set('actor','director','producer','executive_producer','writer','guest_star','host','adapter','presenter','commentator','guest') NOT NULL DEFAULT '',"
3919 " UNIQUE KEY chanid (chanid,starttime,person,role),"
3920 " KEY person (person,role)"
3921 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3922 "CREATE TABLE customexample ("
3923 " rulename varchar(64) NOT NULL,"
3924 " fromclause varchar(10000) NOT NULL DEFAULT '',"
3925 " whereclause varchar(10000) NOT NULL DEFAULT '',"
3926 " search tinyint(4) NOT NULL DEFAULT '0',"
3927 " PRIMARY KEY (rulename)"
3928 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3929 "CREATE TABLE diseqc_config ("
3930 " cardinputid int(10) unsigned NOT NULL,"
3931 " diseqcid int(10) unsigned NOT NULL,"
3932 " `value` varchar(16) NOT NULL DEFAULT '',"
3933 " KEY id (cardinputid)"
3934 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3935 "CREATE TABLE diseqc_tree ("
3936 " diseqcid int(10) unsigned NOT NULL AUTO_INCREMENT,"
3937 " parentid int(10) unsigned DEFAULT NULL,"
3938 " ordinal tinyint(3) unsigned NOT NULL,"
3939 " `type` varchar(16) NOT NULL DEFAULT '',"
3940 " subtype varchar(16) NOT NULL DEFAULT '',"
3941 " description varchar(32) NOT NULL DEFAULT '',"
3942 " switch_ports tinyint(3) unsigned NOT NULL DEFAULT '0',"
3943 " rotor_hi_speed float NOT NULL DEFAULT '0',"
3944 " rotor_lo_speed float NOT NULL DEFAULT '0',"
3945 " rotor_positions varchar(255) NOT NULL DEFAULT '',"
3946 " lnb_lof_switch int(10) NOT NULL DEFAULT '0',"
3947 " lnb_lof_hi int(10) NOT NULL DEFAULT '0',"
3948 " lnb_lof_lo int(10) NOT NULL DEFAULT '0',"
3949 " cmd_repeat int(11) NOT NULL DEFAULT '1',"
3950 " lnb_pol_inv tinyint(4) NOT NULL DEFAULT '0',"
3951 " address tinyint(3) unsigned NOT NULL DEFAULT '0',"
3952 " PRIMARY KEY (diseqcid),"
3953 " KEY parentid (parentid)"
3954 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3955 "CREATE TABLE displayprofilegroups ("
3956 " `name` varchar(128) NOT NULL,"
3957 " hostname varchar(64) NOT NULL,"
3958 " profilegroupid int(10) unsigned NOT NULL AUTO_INCREMENT,"
3959 " PRIMARY KEY (`name`,hostname),"
3960 " UNIQUE KEY profilegroupid (profilegroupid)"
3961 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3962 "CREATE TABLE displayprofiles ("
3963 " profilegroupid int(10) unsigned NOT NULL,"
3964 " profileid int(10) unsigned NOT NULL AUTO_INCREMENT,"
3965 " `value` varchar(128) NOT NULL,"
3966 " `data` varchar(255) NOT NULL DEFAULT '',"
3967 " KEY profilegroupid (profilegroupid),"
3968 " KEY profileid (profileid,`value`),"
3969 " KEY profileid_2 (profileid)"
3970 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3971 "CREATE TABLE dtv_multiplex ("
3972 " mplexid smallint(6) NOT NULL AUTO_INCREMENT,"
3973 " sourceid smallint(6) DEFAULT NULL,"
3974 " transportid int(11) DEFAULT NULL,"
3975 " networkid int(11) DEFAULT NULL,"
3976 " frequency int(11) DEFAULT NULL,"
3977 " inversion char(1) DEFAULT 'a',"
3978 " symbolrate int(11) DEFAULT NULL,"
3979 " fec varchar(10) DEFAULT 'auto',"
3980 " polarity char(1) DEFAULT NULL,"
3981 " modulation varchar(10) DEFAULT 'auto',"
3982 " bandwidth char(1) DEFAULT 'a',"
3983 " lp_code_rate varchar(10) DEFAULT 'auto',"
3984 " transmission_mode char(1) DEFAULT 'a',"
3985 " guard_interval varchar(10) DEFAULT 'auto',"
3986 " visible smallint(1) NOT NULL DEFAULT '0',"
3987 " constellation varchar(10) DEFAULT 'auto',"
3988 " hierarchy varchar(10) DEFAULT 'auto',"
3989 " hp_code_rate varchar(10) DEFAULT 'auto',"
3990 " mod_sys varchar(10) DEFAULT NULL,"
3991 " rolloff varchar(4) DEFAULT NULL,"
3992 " sistandard varchar(10) DEFAULT 'dvb',"
3993 " serviceversion smallint(6) DEFAULT '33',"
3994 " updatetimestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,"
3995 " default_authority varchar(32) NOT NULL DEFAULT '',"
3996 " PRIMARY KEY (mplexid)"
3997 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
3998 "CREATE TABLE dtv_privatetypes ("
3999 " sitype varchar(4) NOT NULL DEFAULT '',"
4000 " networkid int(11) NOT NULL DEFAULT '0',"
4001 " private_type varchar(20) NOT NULL DEFAULT '',"
4002 " private_value varchar(100) NOT NULL DEFAULT ''"
4003 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4004 "CREATE TABLE dvdbookmark ("
4005 " serialid varchar(16) NOT NULL DEFAULT '',"
4006 " `name` varchar(32) DEFAULT NULL,"
4007 " title smallint(6) NOT NULL DEFAULT '0',"
4008 " audionum tinyint(4) NOT NULL DEFAULT '-1',"
4009 " subtitlenum tinyint(4) NOT NULL DEFAULT '-1',"
4010 " framenum bigint(20) NOT NULL DEFAULT '0',"
4011 " `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,"
4012 " PRIMARY KEY (serialid)"
4013 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4014 "CREATE TABLE dvdinput ("
4015 " intid int(10) unsigned NOT NULL,"
4016 " hsize int(10) unsigned DEFAULT NULL,"
4017 " vsize int(10) unsigned DEFAULT NULL,"
4018 " ar_num int(10) unsigned DEFAULT NULL,"
4019 " ar_denom int(10) unsigned DEFAULT NULL,"
4020 " fr_code int(10) unsigned DEFAULT NULL,"
4021 " letterbox tinyint(1) DEFAULT NULL,"
4022 " v_format varchar(16) DEFAULT NULL,"
4023 " PRIMARY KEY (intid)"
4024 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4025 "CREATE TABLE dvdtranscode ("
4026 " intid int(11) NOT NULL AUTO_INCREMENT,"
4027 " input int(10) unsigned DEFAULT NULL,"
4028 " `name` varchar(128) NOT NULL,"
4029 " sync_mode int(10) unsigned DEFAULT NULL,"
4030 " use_yv12 tinyint(1) DEFAULT NULL,"
4031 " cliptop int(11) DEFAULT NULL,"
4032 " clipbottom int(11) DEFAULT NULL,"
4033 " clipleft int(11) DEFAULT NULL,"
4034 " clipright int(11) DEFAULT NULL,"
4035 " f_resize_h int(11) DEFAULT NULL,"
4036 " f_resize_w int(11) DEFAULT NULL,"
4037 " hq_resize_h int(11) DEFAULT NULL,"
4038 " hq_resize_w int(11) DEFAULT NULL,"
4039 " grow_h int(11) DEFAULT NULL,"
4040 " grow_w int(11) DEFAULT NULL,"
4041 " clip2top int(11) DEFAULT NULL,"
4042 " clip2bottom int(11) DEFAULT NULL,"
4043 " clip2left int(11) DEFAULT NULL,"
4044 " clip2right int(11) DEFAULT NULL,"
4045 " codec varchar(128) NOT NULL,"
4046 " codec_param varchar(128) DEFAULT NULL,"
4047 " bitrate int(11) DEFAULT NULL,"
4048 " a_sample_r int(11) DEFAULT NULL,"
4049 " a_bitrate int(11) DEFAULT NULL,"
4050 " two_pass tinyint(1) DEFAULT NULL,"
4051 " tc_param varchar(128) DEFAULT NULL,"
4052 " PRIMARY KEY (intid)"
4053 ") ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;",
4054 "CREATE TABLE eit_cache ("
4055 " chanid int(10) NOT NULL,"
4056 " eventid int(10) unsigned NOT NULL DEFAULT '0',"
4057 " tableid tinyint(3) unsigned NOT NULL,"
4058 " version tinyint(3) unsigned NOT NULL,"
4059 " endtime int(10) unsigned NOT NULL,"
4060 " `status` tinyint(4) NOT NULL DEFAULT '0',"
4061 " PRIMARY KEY (chanid,eventid,`status`)"
4062 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4063 "CREATE TABLE filemarkup ("
4064 " filename text NOT NULL,"
4065 " mark mediumint(8) unsigned NOT NULL DEFAULT '0',"
4066 " `offset` bigint(20) unsigned DEFAULT NULL,"
4067 " `type` tinyint(4) NOT NULL DEFAULT '0',"
4068 " KEY filename (filename(255))"
4069 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4070 "CREATE TABLE housekeeping ("
4071 " tag varchar(64) NOT NULL DEFAULT '',"
4072 " lastrun datetime DEFAULT NULL,"
4073 " PRIMARY KEY (tag)"
4074 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4075 "CREATE TABLE inputgroup ("
4076 " cardinputid int(10) unsigned NOT NULL,"
4077 " inputgroupid int(10) unsigned NOT NULL,"
4078 " inputgroupname varchar(32) NOT NULL"
4079 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4080 "CREATE TABLE internetcontent ("
4081 " `name` varchar(255) NOT NULL,"
4082 " thumbnail varchar(255) DEFAULT NULL,"
4083 " `type` smallint(3) NOT NULL,"
4084 " author varchar(128) NOT NULL,"
4085 " description text NOT NULL,"
4086 " commandline text NOT NULL,"
4087 " version double NOT NULL,"
4088 " updated datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4089 " search tinyint(1) NOT NULL,"
4090 " tree tinyint(1) NOT NULL,"
4091 " podcast tinyint(1) NOT NULL,"
4092 " download tinyint(1) NOT NULL,"
4093 " `host` varchar(128) DEFAULT NULL"
4094 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4095 "CREATE TABLE internetcontentarticles ("
4096 " feedtitle varchar(255) NOT NULL,"
4097 " path text NOT NULL,"
4098 " paththumb text NOT NULL,"
4099 " title varchar(255) NOT NULL,"
4100 " subtitle varchar(255) NOT NULL,"
4101 " season smallint(5) NOT NULL DEFAULT '0',"
4102 " episode smallint(5) NOT NULL DEFAULT '0',"
4103 " description text NOT NULL,"
4104 " url text NOT NULL,"
4105 " `type` smallint(3) NOT NULL,"
4106 " thumbnail text NOT NULL,"
4107 " mediaURL text NOT NULL,"
4108 " author varchar(255) NOT NULL,"
4109 " `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4110 " `time` int(11) NOT NULL,"
4111 " rating varchar(255) NOT NULL,"
4112 " filesize bigint(20) NOT NULL,"
4113 " player varchar(255) NOT NULL,"
4114 " playerargs text NOT NULL,"
4115 " download varchar(255) NOT NULL,"
4116 " downloadargs text NOT NULL,"
4117 " width smallint(6) NOT NULL,"
4118 " height smallint(6) NOT NULL,"
4119 " `language` varchar(128) NOT NULL,"
4120 " podcast tinyint(1) NOT NULL,"
4121 " downloadable tinyint(1) NOT NULL,"
4122 " customhtml tinyint(1) NOT NULL,"
4123 " countries varchar(255) NOT NULL"
4124 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4125 "CREATE TABLE inuseprograms ("
4126 " chanid int(10) unsigned NOT NULL DEFAULT '0',"
4127 " starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4128 " recusage varchar(128) NOT NULL DEFAULT '',"
4129 " lastupdatetime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4130 " hostname varchar(64) NOT NULL DEFAULT '',"
4131 " rechost varchar(64) NOT NULL,"
4132 " recdir varchar(255) NOT NULL DEFAULT '',"
4133 " KEY chanid (chanid,starttime),"
4134 " KEY recusage (recusage,lastupdatetime)"
4135 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4136 "CREATE TABLE iptv_channel ("
4137 " iptvid smallint(6) unsigned NOT NULL AUTO_INCREMENT,"
4138 " chanid int(10) unsigned NOT NULL,"
4139 " url text NOT NULL,"
4140 " `type` set('data','rfc2733-1','rfc2733-2','rfc5109-1','rfc5109-2','smpte2022-1','smpte2022-2') DEFAULT NULL,"
4141 " bitrate int(10) unsigned NOT NULL,"
4142 " PRIMARY KEY (iptvid)"
4143 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4144 "CREATE TABLE jobqueue ("
4145 " id int(11) NOT NULL AUTO_INCREMENT,"
4146 " chanid int(10) NOT NULL DEFAULT '0',"
4147 " starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4148 " inserttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4149 " `type` int(11) NOT NULL DEFAULT '0',"
4150 " cmds int(11) NOT NULL DEFAULT '0',"
4151 " flags int(11) NOT NULL DEFAULT '0',"
4152 " `status` int(11) NOT NULL DEFAULT '0',"
4153 " statustime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,"
4154 " hostname varchar(64) NOT NULL DEFAULT '',"
4155 " args blob NOT NULL,"
4156 " `comment` varchar(128) NOT NULL DEFAULT '',"
4157 " schedruntime datetime NOT NULL DEFAULT '2007-01-01 00:00:00',"
4158 " PRIMARY KEY (id),"
4159 " UNIQUE KEY chanid (chanid,starttime,`type`,inserttime)"
4160 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4161 "CREATE TABLE jumppoints ("
4162 " destination varchar(128) NOT NULL DEFAULT '',"
4163 " description varchar(255) DEFAULT NULL,"
4164 " keylist varchar(128) DEFAULT NULL,"
4165 " hostname varchar(64) NOT NULL DEFAULT '',"
4166 " PRIMARY KEY (destination,hostname)"
4167 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4168 "CREATE TABLE keybindings ("
4169 " `context` varchar(32) NOT NULL DEFAULT '',"
4170 " `action` varchar(32) NOT NULL DEFAULT '',"
4171 " description varchar(255) DEFAULT NULL,"
4172 " keylist varchar(128) DEFAULT NULL,"
4173 " hostname varchar(64) NOT NULL DEFAULT '',"
4174 " PRIMARY KEY (`context`,`action`,hostname)"
4175 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4176 "CREATE TABLE keyword ("
4177 " phrase varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',"
4178 " searchtype int(10) unsigned NOT NULL DEFAULT '3',"
4179 " UNIQUE KEY phrase (phrase,searchtype)"
4180 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4181 "CREATE TABLE livestream ("
4182 " id int(10) unsigned NOT NULL AUTO_INCREMENT,"
4183 " width int(10) unsigned NOT NULL,"
4184 " height int(10) unsigned NOT NULL,"
4185 " bitrate int(10) unsigned NOT NULL,"
4186 " audiobitrate int(10) unsigned NOT NULL,"
4187 " samplerate int(10) unsigned NOT NULL,"
4188 " audioonlybitrate int(10) unsigned NOT NULL,"
4189 " segmentsize int(10) unsigned NOT NULL DEFAULT '10',"
4190 " maxsegments int(10) unsigned NOT NULL DEFAULT '0',"
4191 " startsegment int(10) unsigned NOT NULL DEFAULT '0',"
4192 " currentsegment int(10) unsigned NOT NULL DEFAULT '0',"
4193 " segmentcount int(10) unsigned NOT NULL DEFAULT '0',"
4194 " percentcomplete int(10) unsigned NOT NULL DEFAULT '0',"
4195 " created datetime NOT NULL,"
4196 " lastmodified datetime NOT NULL,"
4197 " relativeurl varchar(512) NOT NULL,"
4198 " fullurl varchar(1024) NOT NULL,"
4199 " `status` int(10) unsigned NOT NULL DEFAULT '0',"
4200 " statusmessage varchar(256) NOT NULL,"
4201 " sourcefile varchar(512) NOT NULL,"
4202 " sourcehost varchar(64) NOT NULL,"
4203 " sourcewidth int(10) unsigned NOT NULL DEFAULT '0',"
4204 " sourceheight int(10) unsigned NOT NULL DEFAULT '0',"
4205 " outdir varchar(256) NOT NULL,"
4206 " outbase varchar(128) NOT NULL,"
4207 " PRIMARY KEY (id)"
4208 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4209 "CREATE TABLE logging ("
4210 " id bigint(20) unsigned NOT NULL AUTO_INCREMENT,"
4211 " `host` varchar(64) NOT NULL DEFAULT '',"
4212 " application varchar(64) NOT NULL DEFAULT '',"
4213 " pid int(11) NOT NULL DEFAULT '0',"
4214 " tid int(11) NOT NULL DEFAULT '0',"
4215 " thread varchar(64) NOT NULL DEFAULT '',"
4216 " filename varchar(255) NOT NULL DEFAULT '',"
4217 " line int(11) NOT NULL DEFAULT '0',"
4218 " `function` varchar(255) NOT NULL DEFAULT '',"
4219 " msgtime datetime NOT NULL,"
4220 " `level` int(11) NOT NULL DEFAULT '0',"
4221 " message varchar(2048) NOT NULL,"
4222 " PRIMARY KEY (id),"
4223 " KEY `host` (`host`,application,pid,msgtime),"
4224 " KEY msgtime (msgtime),"
4225 " KEY `level` (`level`)"
4226 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4227 "CREATE TABLE mythlog ("
4228 " logid int(10) unsigned NOT NULL AUTO_INCREMENT,"
4229 " module varchar(32) NOT NULL DEFAULT '',"
4230 " priority int(11) NOT NULL DEFAULT '0',"
4231 " acknowledged tinyint(1) DEFAULT '0',"
4232 " logdate datetime DEFAULT NULL,"
4233 " `host` varchar(128) DEFAULT NULL,"
4234 " message varchar(255) NOT NULL DEFAULT '',"
4235 " details varchar(16000) NOT NULL DEFAULT '',"
4236 " PRIMARY KEY (logid),"
4237 " KEY module (module)"
4238 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4239 "CREATE TABLE oldfind ("
4240 " recordid int(11) NOT NULL DEFAULT '0',"
4241 " findid int(11) NOT NULL DEFAULT '0',"
4242 " PRIMARY KEY (recordid,findid)"
4243 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4244 "CREATE TABLE oldprogram ("
4245 " oldtitle varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',"
4246 " airdate datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4247 " PRIMARY KEY (oldtitle)"
4248 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4249 "CREATE TABLE oldrecorded ("
4250 " chanid int(10) unsigned NOT NULL DEFAULT '0',"
4251 " starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4252 " endtime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4253 " title varchar(128) NOT NULL DEFAULT '',"
4254 " subtitle varchar(128) NOT NULL DEFAULT '',"
4255 " description varchar(16000) NOT NULL DEFAULT '',"
4256 " season smallint(5) NOT NULL,"
4257 " episode smallint(5) NOT NULL,"
4258 " category varchar(64) NOT NULL DEFAULT '',"
4259 " seriesid varchar(40) NOT NULL DEFAULT '',"
4260 " programid varchar(40) NOT NULL DEFAULT '',"
4261 " inetref varchar(40) NOT NULL,"
4262 " findid int(11) NOT NULL DEFAULT '0',"
4263 " recordid int(11) NOT NULL DEFAULT '0',"
4264 " station varchar(20) NOT NULL DEFAULT '',"
4265 " rectype int(10) unsigned NOT NULL DEFAULT '0',"
4266 " `duplicate` tinyint(1) NOT NULL DEFAULT '0',"
4267 " recstatus int(11) NOT NULL DEFAULT '0',"
4268 " reactivate smallint(6) NOT NULL DEFAULT '0',"
4269 " generic tinyint(1) NOT NULL,"
4270 " future tinyint(1) NOT NULL DEFAULT '0',"
4271 " PRIMARY KEY (station,starttime,title),"
4272 " KEY endtime (endtime),"
4273 " KEY title (title),"
4274 " KEY seriesid (seriesid),"
4275 " KEY programid (programid),"
4276 " KEY recordid (recordid),"
4277 " KEY recstatus (recstatus,programid,seriesid),"
4278 " KEY recstatus_2 (recstatus,title,subtitle),"
4279 " KEY future (future),"
4280 " KEY chanid (chanid,starttime),"
4281 " KEY subtitle (subtitle),"
4282 " KEY description (description(255))"
4283 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4284 "CREATE TABLE people ("
4285 " person mediumint(8) unsigned NOT NULL AUTO_INCREMENT,"
4286 " `name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',"
4287 " PRIMARY KEY (person),"
4288 " UNIQUE KEY `name` (`name`(41))"
4289 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4290 "CREATE TABLE pidcache ("
4291 " chanid smallint(6) NOT NULL DEFAULT '0',"
4292 " pid int(11) NOT NULL DEFAULT '-1',"
4293 " tableid int(11) NOT NULL DEFAULT '-1',"
4294 " KEY chanid (chanid)"
4295 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4296 "CREATE TABLE playgroup ("
4297 " `name` varchar(32) NOT NULL DEFAULT '',"
4298 " titlematch varchar(255) NOT NULL DEFAULT '',"
4299 " skipahead int(11) NOT NULL DEFAULT '0',"
4300 " skipback int(11) NOT NULL DEFAULT '0',"
4301 " timestretch int(11) NOT NULL DEFAULT '0',"
4302 " jump int(11) NOT NULL DEFAULT '0',"
4303 " PRIMARY KEY (`name`)"
4304 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4305 "CREATE TABLE powerpriority ("
4306 " priorityname varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,"
4307 " recpriority int(10) NOT NULL DEFAULT '0',"
4308 " selectclause varchar(16000) NOT NULL DEFAULT '',"
4309 " PRIMARY KEY (priorityname)"
4310 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4311 "CREATE TABLE profilegroups ("
4312 " id int(10) unsigned NOT NULL AUTO_INCREMENT,"
4313 " `name` varchar(128) DEFAULT NULL,"
4314 " cardtype varchar(32) NOT NULL DEFAULT 'V4L',"
4315 " is_default int(1) DEFAULT '0',"
4316 " hostname varchar(64) DEFAULT NULL,"
4317 " PRIMARY KEY (id),"
4318 " UNIQUE KEY `name` (`name`,hostname),"
4319 " KEY cardtype (cardtype)"
4320 ") ENGINE=MyISAM AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;",
4321 "CREATE TABLE program ("
4322 " chanid int(10) unsigned NOT NULL DEFAULT '0',"
4323 " starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4324 " endtime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4325 " title varchar(128) NOT NULL DEFAULT '',"
4326 " subtitle varchar(128) NOT NULL DEFAULT '',"
4327 " description varchar(16000) NOT NULL DEFAULT '',"
4328 " category varchar(64) NOT NULL DEFAULT '',"
4329 " category_type varchar(64) NOT NULL DEFAULT '',"
4330 " airdate year(4) NOT NULL DEFAULT '0000',"
4331 " stars float NOT NULL DEFAULT '0',"
4332 " previouslyshown tinyint(4) NOT NULL DEFAULT '0',"
4333 " title_pronounce varchar(128) NOT NULL DEFAULT '',"
4334 " stereo tinyint(1) NOT NULL DEFAULT '0',"
4335 " subtitled tinyint(1) NOT NULL DEFAULT '0',"
4336 " hdtv tinyint(1) NOT NULL DEFAULT '0',"
4337 " closecaptioned tinyint(1) NOT NULL DEFAULT '0',"
4338 " partnumber int(11) NOT NULL DEFAULT '0',"
4339 " parttotal int(11) NOT NULL DEFAULT '0',"
4340 " seriesid varchar(64) NOT NULL DEFAULT '',"
4341 " originalairdate date DEFAULT NULL,"
4342 " showtype varchar(30) NOT NULL DEFAULT '',"
4343 " colorcode varchar(20) NOT NULL DEFAULT '',"
4344 " syndicatedepisodenumber varchar(20) NOT NULL DEFAULT '',"
4345 " programid varchar(64) NOT NULL DEFAULT '',"
4346 " manualid int(10) unsigned NOT NULL DEFAULT '0',"
4347 " generic tinyint(1) DEFAULT '0',"
4348 " listingsource int(11) NOT NULL DEFAULT '0',"
4349 " `first` tinyint(1) NOT NULL DEFAULT '0',"
4350 " `last` tinyint(1) NOT NULL DEFAULT '0',"
4351 " audioprop set('STEREO','MONO','SURROUND','DOLBY','HARDHEAR','VISUALIMPAIR') NOT NULL,"
4352 " subtitletypes set('HARDHEAR','NORMAL','ONSCREEN','SIGNED') NOT NULL,"
4353 " videoprop set('HDTV','WIDESCREEN','AVC') NOT NULL,"
4354 " PRIMARY KEY (chanid,starttime,manualid),"
4355 " KEY endtime (endtime),"
4356 " KEY title (title),"
4357 " KEY title_pronounce (title_pronounce),"
4358 " KEY seriesid (seriesid),"
4359 " KEY id_start_end (chanid,starttime,endtime),"
4360 " KEY program_manualid (manualid),"
4361 " KEY previouslyshown (previouslyshown),"
4362 " KEY programid (programid,starttime),"
4363 " KEY starttime (starttime),"
4364 " KEY subtitle (subtitle),"
4365 " KEY description (description(255))"
4366 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4367 "CREATE TABLE programgenres ("
4368 " chanid int(10) unsigned NOT NULL DEFAULT '0',"
4369 " starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4370 " relevance char(1) NOT NULL DEFAULT '',"
4371 " genre varchar(30) DEFAULT NULL,"
4372 " PRIMARY KEY (chanid,starttime,relevance),"
4373 " KEY genre (genre)"
4374 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4375 "CREATE TABLE programrating ("
4376 " chanid int(10) unsigned NOT NULL DEFAULT '0',"
4377 " starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4378 " `system` varchar(8) DEFAULT NULL,"
4379 " rating varchar(16) DEFAULT NULL,"
4380 " UNIQUE KEY chanid (chanid,starttime,`system`,rating),"
4381 " KEY starttime (starttime,`system`)"
4382 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4383 "CREATE TABLE recgrouppassword ("
4384 " recgroup varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',"
4385 " `password` varchar(10) NOT NULL DEFAULT '',"
4386 " PRIMARY KEY (recgroup)"
4387 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4388 "CREATE TABLE record ("
4389 " recordid int(10) unsigned NOT NULL AUTO_INCREMENT,"
4390 " `type` int(10) unsigned NOT NULL DEFAULT '0',"
4391 " chanid int(10) unsigned DEFAULT NULL,"
4392 " starttime time NOT NULL DEFAULT '00:00:00',"
4393 " startdate date NOT NULL DEFAULT '0000-00-00',"
4394 " endtime time NOT NULL DEFAULT '00:00:00',"
4395 " enddate date NOT NULL DEFAULT '0000-00-00',"
4396 " title varchar(128) NOT NULL DEFAULT '',"
4397 " subtitle varchar(128) NOT NULL DEFAULT '',"
4398 " description varchar(16000) NOT NULL DEFAULT '',"
4399 " season smallint(5) NOT NULL,"
4400 " episode smallint(5) NOT NULL,"
4401 " category varchar(64) NOT NULL DEFAULT '',"
4402 " `profile` varchar(128) NOT NULL DEFAULT 'Default',"
4403 " recpriority int(10) NOT NULL DEFAULT '0',"
4404 " autoexpire int(11) NOT NULL DEFAULT '0',"
4405 " maxepisodes int(11) NOT NULL DEFAULT '0',"
4406 " maxnewest int(11) NOT NULL DEFAULT '0',"
4407 " startoffset int(11) NOT NULL DEFAULT '0',"
4408 " endoffset int(11) NOT NULL DEFAULT '0',"
4409 " recgroup varchar(32) NOT NULL DEFAULT 'Default',"
4410 " dupmethod int(11) NOT NULL DEFAULT '6',"
4411 " dupin int(11) NOT NULL DEFAULT '15',"
4412 " station varchar(20) NOT NULL DEFAULT '',"
4413 " seriesid varchar(40) NOT NULL DEFAULT '',"
4414 " programid varchar(40) NOT NULL DEFAULT '',"
4415 " inetref varchar(40) NOT NULL,"
4416 " search int(10) unsigned NOT NULL DEFAULT '0',"
4417 " autotranscode tinyint(1) NOT NULL DEFAULT '0',"
4418 " autocommflag tinyint(1) NOT NULL DEFAULT '0',"
4419 " autouserjob1 tinyint(1) NOT NULL DEFAULT '0',"
4420 " autouserjob2 tinyint(1) NOT NULL DEFAULT '0',"
4421 " autouserjob3 tinyint(1) NOT NULL DEFAULT '0',"
4422 " autouserjob4 tinyint(1) NOT NULL DEFAULT '0',"
4423 " autometadata tinyint(1) NOT NULL DEFAULT '0',"
4424 " findday tinyint(4) NOT NULL DEFAULT '0',"
4425 " findtime time NOT NULL DEFAULT '00:00:00',"
4426 " findid int(11) NOT NULL DEFAULT '0',"
4427 " inactive tinyint(1) NOT NULL DEFAULT '0',"
4428 " parentid int(11) NOT NULL DEFAULT '0',"
4429 " transcoder int(11) NOT NULL DEFAULT '0',"
4430 " playgroup varchar(32) NOT NULL DEFAULT 'Default',"
4431 " prefinput int(10) NOT NULL DEFAULT '0',"
4432 " next_record datetime NOT NULL,"
4433 " last_record datetime NOT NULL,"
4434 " last_delete datetime NOT NULL,"
4435 " storagegroup varchar(32) NOT NULL DEFAULT 'Default',"
4436 " avg_delay int(11) NOT NULL DEFAULT '100',"
4437 " filter int(10) unsigned NOT NULL DEFAULT '0',"
4438 " PRIMARY KEY (recordid),"
4439 " KEY chanid (chanid,starttime),"
4440 " KEY title (title),"
4441 " KEY seriesid (seriesid),"
4442 " KEY programid (programid),"
4443 " KEY maxepisodes (maxepisodes),"
4444 " KEY search (search),"
4445 " KEY `type` (`type`)"
4446 ") ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;",
4447 "CREATE TABLE recorded ("
4448 " chanid int(10) unsigned NOT NULL DEFAULT '0',"
4449 " starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4450 " endtime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4451 " title varchar(128) NOT NULL DEFAULT '',"
4452 " subtitle varchar(128) NOT NULL DEFAULT '',"
4453 " description varchar(16000) NOT NULL DEFAULT '',"
4454 " season smallint(5) NOT NULL,"
4455 " episode smallint(5) NOT NULL,"
4456 " category varchar(64) NOT NULL DEFAULT '',"
4457 " hostname varchar(64) NOT NULL DEFAULT '',"
4458 " bookmark tinyint(1) NOT NULL DEFAULT '0',"
4459 " editing int(10) unsigned NOT NULL DEFAULT '0',"
4460 " cutlist tinyint(1) NOT NULL DEFAULT '0',"
4461 " autoexpire int(11) NOT NULL DEFAULT '0',"
4462 " commflagged int(10) unsigned NOT NULL DEFAULT '0',"
4463 " recgroup varchar(32) NOT NULL DEFAULT 'Default',"
4464 " recordid int(11) DEFAULT NULL,"
4465 " seriesid varchar(40) NOT NULL DEFAULT '',"
4466 " programid varchar(40) NOT NULL DEFAULT '',"
4467 " inetref varchar(40) NOT NULL,"
4468 " lastmodified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,"
4469 " filesize bigint(20) NOT NULL DEFAULT '0',"
4470 " stars float NOT NULL DEFAULT '0',"
4471 " previouslyshown tinyint(1) DEFAULT '0',"
4472 " originalairdate date DEFAULT NULL,"
4473 " `preserve` tinyint(1) NOT NULL DEFAULT '0',"
4474 " findid int(11) NOT NULL DEFAULT '0',"
4475 " deletepending tinyint(1) NOT NULL DEFAULT '0',"
4476 " transcoder int(11) NOT NULL DEFAULT '0',"
4477 " timestretch float NOT NULL DEFAULT '1',"
4478 " recpriority int(11) NOT NULL DEFAULT '0',"
4479 " basename varchar(255) NOT NULL,"
4480 " progstart datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4481 " progend datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4482 " playgroup varchar(32) NOT NULL DEFAULT 'Default',"
4483 " `profile` varchar(32) NOT NULL DEFAULT '',"
4484 " `duplicate` tinyint(1) NOT NULL DEFAULT '0',"
4485 " transcoded tinyint(1) NOT NULL DEFAULT '0',"
4486 " watched tinyint(4) NOT NULL DEFAULT '0',"
4487 " storagegroup varchar(32) NOT NULL DEFAULT 'Default',"
4488 " bookmarkupdate timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',"
4489 " PRIMARY KEY (chanid,starttime),"
4490 " KEY endtime (endtime),"
4491 " KEY seriesid (seriesid),"
4492 " KEY programid (programid),"
4493 " KEY title (title),"
4494 " KEY recordid (recordid),"
4495 " KEY deletepending (deletepending,lastmodified),"
4496 " KEY recgroup (recgroup,endtime)"
4497 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4498 "CREATE TABLE recordedartwork ("
4499 " inetref varchar(255) NOT NULL,"
4500 " season smallint(5) NOT NULL,"
4501 " `host` text NOT NULL,"
4502 " coverart text NOT NULL,"
4503 " fanart text NOT NULL,"
4504 " banner text NOT NULL"
4505 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4506 "CREATE TABLE recordedcredits ("
4507 " person mediumint(8) unsigned NOT NULL DEFAULT '0',"
4508 " chanid int(10) unsigned NOT NULL DEFAULT '0',"
4509 " starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4510 " role set('actor','director','producer','executive_producer','writer','guest_star','host','adapter','presenter','commentator','guest') NOT NULL DEFAULT '',"
4511 " UNIQUE KEY chanid (chanid,starttime,person,role),"
4512 " KEY person (person,role)"
4513 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4514 "CREATE TABLE recordedfile ("
4515 " chanid int(10) unsigned NOT NULL DEFAULT '0',"
4516 " starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4517 " basename varchar(128) NOT NULL DEFAULT '',"
4518 " filesize bigint(20) NOT NULL DEFAULT '0',"
4519 " width smallint(5) unsigned NOT NULL DEFAULT '0',"
4520 " height smallint(5) unsigned NOT NULL DEFAULT '0',"
4521 " fps float(6,3) NOT NULL DEFAULT '0.000',"
4522 " aspect float(8,6) NOT NULL DEFAULT '0.000000',"
4523 " audio_sample_rate smallint(5) unsigned NOT NULL DEFAULT '0',"
4524 " audio_bits_per_sample smallint(5) unsigned NOT NULL DEFAULT '0',"
4525 " audio_channels tinyint(3) unsigned NOT NULL DEFAULT '0',"
4526 " audio_type varchar(255) NOT NULL DEFAULT '',"
4527 " video_type varchar(255) NOT NULL DEFAULT '',"
4528 " `comment` varchar(255) NOT NULL DEFAULT '',"
4529 " hostname varchar(64) NOT NULL,"
4530 " storagegroup varchar(32) NOT NULL,"
4531 " id int(11) NOT NULL AUTO_INCREMENT,"
4532 " PRIMARY KEY (id),"
4533 " UNIQUE KEY chanid (chanid,starttime,basename),"
4534 " KEY basename (basename)"
4535 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4536 "CREATE TABLE recordedmarkup ("
4537 " chanid int(10) unsigned NOT NULL DEFAULT '0',"
4538 " starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4539 " mark mediumint(8) unsigned NOT NULL DEFAULT '0',"
4540 " `type` tinyint(4) NOT NULL DEFAULT '0',"
4541 " `data` int(11) unsigned DEFAULT NULL,"
4542 " PRIMARY KEY (chanid,starttime,`type`,mark)"
4543 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4544 "CREATE TABLE recordedprogram ("
4545 " chanid int(10) unsigned NOT NULL DEFAULT '0',"
4546 " starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4547 " endtime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4548 " title varchar(128) NOT NULL DEFAULT '',"
4549 " subtitle varchar(128) NOT NULL DEFAULT '',"
4550 " description varchar(16000) NOT NULL DEFAULT '',"
4551 " category varchar(64) NOT NULL DEFAULT '',"
4552 " category_type varchar(64) NOT NULL DEFAULT '',"
4553 " airdate year(4) NOT NULL DEFAULT '0000',"
4554 " stars float unsigned NOT NULL DEFAULT '0',"
4555 " previouslyshown tinyint(4) NOT NULL DEFAULT '0',"
4556 " title_pronounce varchar(128) NOT NULL DEFAULT '',"
4557 " stereo tinyint(1) NOT NULL DEFAULT '0',"
4558 " subtitled tinyint(1) NOT NULL DEFAULT '0',"
4559 " hdtv tinyint(1) NOT NULL DEFAULT '0',"
4560 " closecaptioned tinyint(1) NOT NULL DEFAULT '0',"
4561 " partnumber int(11) NOT NULL DEFAULT '0',"
4562 " parttotal int(11) NOT NULL DEFAULT '0',"
4563 " seriesid varchar(40) NOT NULL DEFAULT '',"
4564 " originalairdate date DEFAULT NULL,"
4565 " showtype varchar(30) NOT NULL DEFAULT '',"
4566 " colorcode varchar(20) NOT NULL DEFAULT '',"
4567 " syndicatedepisodenumber varchar(20) NOT NULL DEFAULT '',"
4568 " programid varchar(40) NOT NULL DEFAULT '',"
4569 " manualid int(10) unsigned NOT NULL DEFAULT '0',"
4570 " generic tinyint(1) DEFAULT '0',"
4571 " listingsource int(11) NOT NULL DEFAULT '0',"
4572 " `first` tinyint(1) NOT NULL DEFAULT '0',"
4573 " `last` tinyint(1) NOT NULL DEFAULT '0',"
4574 " audioprop set('STEREO','MONO','SURROUND','DOLBY','HARDHEAR','VISUALIMPAIR') NOT NULL,"
4575 " subtitletypes set('HARDHEAR','NORMAL','ONSCREEN','SIGNED') NOT NULL,"
4576 " videoprop set('HDTV','WIDESCREEN','AVC','720','1080','DAMAGED') NOT NULL,"
4577 " PRIMARY KEY (chanid,starttime,manualid),"
4578 " KEY endtime (endtime),"
4579 " KEY title (title),"
4580 " KEY title_pronounce (title_pronounce),"
4581 " KEY seriesid (seriesid),"
4582 " KEY programid (programid),"
4583 " KEY id_start_end (chanid,starttime,endtime)"
4584 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4585 "CREATE TABLE recordedrating ("
4586 " chanid int(10) unsigned NOT NULL DEFAULT '0',"
4587 " starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4588 " `system` varchar(8) DEFAULT NULL,"
4589 " rating varchar(16) DEFAULT NULL,"
4590 " UNIQUE KEY chanid (chanid,starttime,`system`,rating),"
4591 " KEY starttime (starttime,`system`)"
4592 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4593 "CREATE TABLE recordedseek ("
4594 " chanid int(10) unsigned NOT NULL DEFAULT '0',"
4595 " starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4596 " mark mediumint(8) unsigned NOT NULL DEFAULT '0',"
4597 " `offset` bigint(20) unsigned NOT NULL,"
4598 " `type` tinyint(4) NOT NULL DEFAULT '0',"
4599 " PRIMARY KEY (chanid,starttime,`type`,mark)"
4600 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4601 "CREATE TABLE recordfilter ("
4602 " filterid int(10) unsigned NOT NULL,"
4603 " description varchar(64) DEFAULT NULL,"
4604 " clause varchar(256) DEFAULT NULL,"
4605 " newruledefault tinyint(1) DEFAULT '0',"
4606 " PRIMARY KEY (filterid)"
4607 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4608 "CREATE TABLE recordingprofiles ("
4609 " id int(10) unsigned NOT NULL AUTO_INCREMENT,"
4610 " `name` varchar(128) DEFAULT NULL,"
4611 " videocodec varchar(128) DEFAULT NULL,"
4612 " audiocodec varchar(128) DEFAULT NULL,"
4613 " profilegroup int(10) unsigned NOT NULL DEFAULT '0',"
4614 " PRIMARY KEY (id),"
4615 " KEY profilegroup (profilegroup)"
4616 ") ENGINE=MyISAM AUTO_INCREMENT=70 DEFAULT CHARSET=utf8;",
4617 "CREATE TABLE recordmatch ("
4618 " recordid int(10) unsigned NOT NULL,"
4619 " chanid int(10) unsigned NOT NULL,"
4620 " starttime datetime NOT NULL,"
4621 " manualid int(10) unsigned NOT NULL,"
4622 " oldrecduplicate tinyint(1) DEFAULT NULL,"
4623 " recduplicate tinyint(1) DEFAULT NULL,"
4624 " findduplicate tinyint(1) DEFAULT NULL,"
4625 " oldrecstatus int(11) DEFAULT NULL,"
4626 " findid int(11) NOT NULL DEFAULT '0',"
4627 " UNIQUE KEY recordid (recordid,chanid,starttime),"
4628 " KEY chanid (chanid,starttime,manualid),"
4629 " KEY recordid_2 (recordid,findid)"
4630 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4631 "CREATE TABLE scannerfile ("
4632 " fileid bigint(20) unsigned NOT NULL AUTO_INCREMENT,"
4633 " filesize bigint(20) unsigned NOT NULL DEFAULT '0',"
4634 " filehash varchar(64) NOT NULL DEFAULT '',"
4635 " added timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,"
4636 " PRIMARY KEY (fileid),"
4637 " UNIQUE KEY filehash (filehash)"
4638 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4639 "CREATE TABLE scannerpath ("
4640 " fileid bigint(20) unsigned NOT NULL,"
4641 " hostname varchar(64) NOT NULL DEFAULT 'localhost',"
4642 " storagegroup varchar(32) NOT NULL DEFAULT 'Default',"
4643 " filename varchar(255) NOT NULL DEFAULT '',"
4644 " PRIMARY KEY (fileid)"
4645 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4646 "CREATE TABLE settings ("
4647 " `value` varchar(128) NOT NULL DEFAULT '',"
4648 " `data` varchar(16000) NOT NULL DEFAULT '',"
4649 " hostname varchar(64) DEFAULT NULL,"
4650 " KEY `value` (`value`,hostname)"
4651 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4652 "CREATE TABLE storagegroup ("
4653 " id int(11) NOT NULL AUTO_INCREMENT,"
4654 " groupname varchar(32) NOT NULL,"
4655 " hostname varchar(64) NOT NULL DEFAULT '',"
4656 " dirname varchar(235) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',"
4657 " PRIMARY KEY (id),"
4658 " UNIQUE KEY grouphostdir (groupname,hostname,dirname),"
4659 " KEY hostname (hostname)"
4660 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4661 "CREATE TABLE tvchain ("
4662 " chanid int(10) unsigned NOT NULL DEFAULT '0',"
4663 " starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4664 " chainid varchar(128) NOT NULL DEFAULT '',"
4665 " chainpos int(10) NOT NULL DEFAULT '0',"
4666 " discontinuity tinyint(1) NOT NULL DEFAULT '0',"
4667 " watching int(10) NOT NULL DEFAULT '0',"
4668 " hostprefix varchar(128) NOT NULL DEFAULT '',"
4669 " cardtype varchar(32) NOT NULL DEFAULT 'V4L',"
4670 " input varchar(32) NOT NULL DEFAULT '',"
4671 " channame varchar(32) NOT NULL DEFAULT '',"
4672 " endtime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
4673 " PRIMARY KEY (chanid,starttime)"
4674 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4675 "CREATE TABLE tvosdmenu ("
4676 " osdcategory varchar(32) NOT NULL,"
4677 " livetv tinyint(4) NOT NULL DEFAULT '0',"
4678 " recorded tinyint(4) NOT NULL DEFAULT '0',"
4679 " video tinyint(4) NOT NULL DEFAULT '0',"
4680 " dvd tinyint(4) NOT NULL DEFAULT '0',"
4681 " description varchar(32) NOT NULL,"
4682 " PRIMARY KEY (osdcategory)"
4683 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4684 "CREATE TABLE upnpmedia ("
4685 " intid int(10) unsigned NOT NULL DEFAULT '0',"
4686 " class varchar(64) NOT NULL DEFAULT '',"
4687 " itemtype varchar(128) NOT NULL DEFAULT '',"
4688 " parentid int(10) unsigned NOT NULL DEFAULT '0',"
4689 " itemproperties varchar(255) NOT NULL DEFAULT '',"
4690 " filepath varchar(512) NOT NULL DEFAULT '',"
4691 " title varchar(255) NOT NULL DEFAULT '',"
4692 " filename varchar(512) NOT NULL DEFAULT '',"
4693 " coverart varchar(512) NOT NULL DEFAULT '',"
4694 " PRIMARY KEY (intid),"
4695 " KEY class (class),"
4696 " KEY filepath (filepath(333)),"
4697 " KEY parentid (parentid)"
4698 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4699 "CREATE TABLE videocast ("
4700 " intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
4701 " cast varchar(128) NOT NULL,"
4702 " PRIMARY KEY (intid)"
4703 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4704 "CREATE TABLE videocategory ("
4705 " intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
4706 " category varchar(128) NOT NULL,"
4707 " PRIMARY KEY (intid)"
4708 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4709 "CREATE TABLE videocollection ("
4710 " intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
4711 " title varchar(256) NOT NULL,"
4712 " contenttype set('MOVIE','TELEVISION','ADULT','MUSICVIDEO','HOMEVIDEO') NOT NULL DEFAULT '',"
4713 " plot text,"
4714 " network varchar(128) DEFAULT NULL,"
4715 " collectionref varchar(128) NOT NULL,"
4716 " certification varchar(128) DEFAULT NULL,"
4717 " genre varchar(128) DEFAULT '',"
4718 " releasedate date DEFAULT NULL,"
4719 " `language` varchar(10) DEFAULT NULL,"
4720 " `status` varchar(64) DEFAULT NULL,"
4721 " rating float DEFAULT '0',"
4722 " ratingcount int(10) DEFAULT '0',"
4723 " runtime smallint(5) unsigned DEFAULT '0',"
4724 " banner text,"
4725 " fanart text,"
4726 " coverart text,"
4727 " PRIMARY KEY (intid),"
4728 " KEY title (title)"
4729 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4730 "CREATE TABLE videocountry ("
4731 " intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
4732 " country varchar(128) NOT NULL,"
4733 " PRIMARY KEY (intid)"
4734 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4735 "CREATE TABLE videogenre ("
4736 " intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
4737 " genre varchar(128) NOT NULL,"
4738 " PRIMARY KEY (intid)"
4739 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4740 "CREATE TABLE videometadata ("
4741 " intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
4742 " title varchar(128) NOT NULL,"
4743 " subtitle text NOT NULL,"
4744 " tagline varchar(255) DEFAULT NULL,"
4745 " director varchar(128) NOT NULL,"
4746 " studio varchar(128) DEFAULT NULL,"
4747 " plot text,"
4748 " rating varchar(128) NOT NULL,"
4749 " inetref varchar(255) NOT NULL,"
4750 " collectionref int(10) NOT NULL DEFAULT '-1',"
4751 " homepage text NOT NULL,"
4752 " `year` int(10) unsigned NOT NULL,"
4753 " releasedate date NOT NULL,"
4754 " userrating float NOT NULL,"
4755 " length int(10) unsigned NOT NULL,"
4756 " playcount int(10) NOT NULL DEFAULT '0',"
4757 " season smallint(5) unsigned NOT NULL DEFAULT '0',"
4758 " episode smallint(5) unsigned NOT NULL DEFAULT '0',"
4759 " showlevel int(10) unsigned NOT NULL,"
4760 " filename text NOT NULL,"
4761 " `hash` varchar(128) NOT NULL,"
4762 " coverfile text NOT NULL,"
4763 " childid int(11) NOT NULL DEFAULT '-1',"
4764 " browse tinyint(1) NOT NULL DEFAULT '1',"
4765 " watched tinyint(1) NOT NULL DEFAULT '0',"
4766 " processed tinyint(1) NOT NULL DEFAULT '0',"
4767 " playcommand varchar(255) DEFAULT NULL,"
4768 " category int(10) unsigned NOT NULL DEFAULT '0',"
4769 " trailer text,"
4770 " `host` text NOT NULL,"
4771 " screenshot text,"
4772 " banner text,"
4773 " fanart text,"
4774 " insertdate timestamp NULL DEFAULT CURRENT_TIMESTAMP,"
4775 " contenttype set('MOVIE','TELEVISION','ADULT','MUSICVIDEO','HOMEVIDEO') NOT NULL DEFAULT '',"
4776 " PRIMARY KEY (intid),"
4777 " KEY director (director),"
4778 " KEY title (title)"
4779 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4780 "CREATE TABLE videometadatacast ("
4781 " idvideo int(10) unsigned NOT NULL,"
4782 " idcast int(10) unsigned NOT NULL,"
4783 " UNIQUE KEY idvideo (idvideo,idcast)"
4784 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4785 "CREATE TABLE videometadatacountry ("
4786 " idvideo int(10) unsigned NOT NULL,"
4787 " idcountry int(10) unsigned NOT NULL,"
4788 " UNIQUE KEY idvideo_2 (idvideo,idcountry),"
4789 " KEY idvideo (idvideo),"
4790 " KEY idcountry (idcountry)"
4791 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4792 "CREATE TABLE videometadatagenre ("
4793 " idvideo int(10) unsigned NOT NULL,"
4794 " idgenre int(10) unsigned NOT NULL,"
4795 " UNIQUE KEY idvideo_2 (idvideo,idgenre),"
4796 " KEY idvideo (idvideo),"
4797 " KEY idgenre (idgenre)"
4798 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4799 "CREATE TABLE videopart ("
4800 " fileid bigint(20) unsigned NOT NULL,"
4801 " videoid int(10) unsigned NOT NULL,"
4802 " `order` smallint(5) unsigned NOT NULL DEFAULT '1',"
4803 " PRIMARY KEY (videoid,`order`)"
4804 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4805 "CREATE TABLE videopathinfo ("
4806 " intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
4807 " path text,"
4808 " contenttype set('MOVIE','TELEVISION','ADULT','MUSICVIDEO','HOMEVIDEO') NOT NULL DEFAULT '',"
4809 " collectionref int(10) DEFAULT '0',"
4810 " recurse tinyint(1) DEFAULT '0',"
4811 " PRIMARY KEY (intid)"
4812 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4813 "CREATE TABLE videosource ("
4814 " sourceid int(10) unsigned NOT NULL AUTO_INCREMENT,"
4815 " `name` varchar(128) NOT NULL DEFAULT '',"
4816 " xmltvgrabber varchar(128) DEFAULT NULL,"
4817 " userid varchar(128) NOT NULL DEFAULT '',"
4818 " freqtable varchar(16) NOT NULL DEFAULT 'default',"
4819 " lineupid varchar(64) DEFAULT NULL,"
4820 " `password` varchar(64) DEFAULT NULL,"
4821 " useeit smallint(6) NOT NULL DEFAULT '0',"
4822 " configpath varchar(4096) DEFAULT NULL,"
4823 " dvb_nit_id int(6) DEFAULT '-1',"
4824 " PRIMARY KEY (sourceid),"
4825 " UNIQUE KEY `name` (`name`)"
4826 ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
4827 "CREATE TABLE videotypes ("
4828 " intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
4829 " extension varchar(128) NOT NULL,"
4830 " playcommand varchar(255) NOT NULL,"
4831 " f_ignore tinyint(1) DEFAULT NULL,"
4832 " use_default tinyint(1) DEFAULT NULL,"
4833 " PRIMARY KEY (intid)"
4834 ") ENGINE=MyISAM AUTO_INCREMENT=33 DEFAULT CHARSET=utf8;",
4835 
4836 "INSERT INTO channelgroupnames VALUES (1,'Favorites');",
4837 "INSERT INTO customexample VALUES ('New Flix','','program.category_type = \\'movie\\' AND program.airdate >= \\n YEAR(DATE_SUB(NOW(), INTERVAL 1 YEAR)) \\nAND program.stars > 0.5 ',1);",
4838 "INSERT INTO dtv_privatetypes VALUES ('dvb',9018,'channel_numbers','131');",
4839 "INSERT INTO dtv_privatetypes VALUES ('dvb',9018,'guide_fixup','2');",
4840 "INSERT INTO dtv_privatetypes VALUES ('dvb',256,'guide_fixup','1');",
4841 "INSERT INTO dtv_privatetypes VALUES ('dvb',257,'guide_fixup','1');",
4842 "INSERT INTO dtv_privatetypes VALUES ('dvb',256,'tv_types','1,150,134,133');",
4843 "INSERT INTO dtv_privatetypes VALUES ('dvb',257,'tv_types','1,150,134,133');",
4844 "INSERT INTO dtv_privatetypes VALUES ('dvb',4100,'sdt_mapping','1');",
4845 "INSERT INTO dtv_privatetypes VALUES ('dvb',4101,'sdt_mapping','1');",
4846 "INSERT INTO dtv_privatetypes VALUES ('dvb',4102,'sdt_mapping','1');",
4847 "INSERT INTO dtv_privatetypes VALUES ('dvb',4103,'sdt_mapping','1');",
4848 "INSERT INTO dtv_privatetypes VALUES ('dvb',4104,'sdt_mapping','1');",
4849 "INSERT INTO dtv_privatetypes VALUES ('dvb',4105,'sdt_mapping','1');",
4850 "INSERT INTO dtv_privatetypes VALUES ('dvb',4106,'sdt_mapping','1');",
4851 "INSERT INTO dtv_privatetypes VALUES ('dvb',4107,'sdt_mapping','1');",
4852 "INSERT INTO dtv_privatetypes VALUES ('dvb',4097,'sdt_mapping','1');",
4853 "INSERT INTO dtv_privatetypes VALUES ('dvb',4098,'sdt_mapping','1');",
4854 "INSERT INTO dtv_privatetypes VALUES ('dvb',4100,'tv_types','1,145,154');",
4855 "INSERT INTO dtv_privatetypes VALUES ('dvb',4101,'tv_types','1,145,154');",
4856 "INSERT INTO dtv_privatetypes VALUES ('dvb',4102,'tv_types','1,145,154');",
4857 "INSERT INTO dtv_privatetypes VALUES ('dvb',4103,'tv_types','1,145,154');",
4858 "INSERT INTO dtv_privatetypes VALUES ('dvb',4104,'tv_types','1,145,154');",
4859 "INSERT INTO dtv_privatetypes VALUES ('dvb',4105,'tv_types','1,145,154');",
4860 "INSERT INTO dtv_privatetypes VALUES ('dvb',4106,'tv_types','1,145,154');",
4861 "INSERT INTO dtv_privatetypes VALUES ('dvb',4107,'tv_types','1,145,154');",
4862 "INSERT INTO dtv_privatetypes VALUES ('dvb',4097,'tv_types','1,145,154');",
4863 "INSERT INTO dtv_privatetypes VALUES ('dvb',4098,'tv_types','1,145,154');",
4864 "INSERT INTO dtv_privatetypes VALUES ('dvb',4100,'guide_fixup','1');",
4865 "INSERT INTO dtv_privatetypes VALUES ('dvb',4101,'guide_fixup','1');",
4866 "INSERT INTO dtv_privatetypes VALUES ('dvb',4102,'guide_fixup','1');",
4867 "INSERT INTO dtv_privatetypes VALUES ('dvb',4103,'guide_fixup','1');",
4868 "INSERT INTO dtv_privatetypes VALUES ('dvb',4104,'guide_fixup','1');",
4869 "INSERT INTO dtv_privatetypes VALUES ('dvb',4105,'guide_fixup','1');",
4870 "INSERT INTO dtv_privatetypes VALUES ('dvb',4106,'guide_fixup','1');",
4871 "INSERT INTO dtv_privatetypes VALUES ('dvb',4107,'guide_fixup','1');",
4872 "INSERT INTO dtv_privatetypes VALUES ('dvb',4096,'guide_fixup','5');",
4873 "INSERT INTO dtv_privatetypes VALUES ('dvb',4097,'guide_fixup','1');",
4874 "INSERT INTO dtv_privatetypes VALUES ('dvb',4098,'guide_fixup','1');",
4875 "INSERT INTO dtv_privatetypes VALUES ('dvb',94,'tv_types','1,128');",
4876 "INSERT INTO dtv_privatetypes VALUES ('atsc',1793,'guide_fixup','3');",
4877 "INSERT INTO dtv_privatetypes VALUES ('dvb',40999,'guide_fixup','4');",
4878 "INSERT INTO dtv_privatetypes VALUES ('dvb',70,'force_guide_present','yes');",
4879 "INSERT INTO dtv_privatetypes VALUES ('dvb',70,'guide_ranges','80,80,96,96');",
4880 "INSERT INTO dtv_privatetypes VALUES ('dvb',4112,'channel_numbers','131');",
4881 "INSERT INTO dtv_privatetypes VALUES ('dvb',4115,'channel_numbers','131');",
4882 "INSERT INTO dtv_privatetypes VALUES ('dvb',4116,'channel_numbers','131');",
4883 "INSERT INTO dtv_privatetypes VALUES ('dvb',12802,'channel_numbers','131');",
4884 "INSERT INTO dtv_privatetypes VALUES ('dvb',12803,'channel_numbers','131');",
4885 "INSERT INTO dtv_privatetypes VALUES ('dvb',12829,'channel_numbers','131');",
4886 "INSERT INTO dtv_privatetypes VALUES ('dvb',40999,'parse_subtitle_list','1070,1308,1041,1306,1307,1030,1016,1131,1068,1069');",
4887 "INSERT INTO dtv_privatetypes VALUES ('dvb',4096,'guide_fixup','5');",
4888 "INSERT INTO dvdinput VALUES (1,720,480,16,9,1,1,'ntsc');",
4889 "INSERT INTO dvdinput VALUES (2,720,480,16,9,1,0,'ntsc');",
4890 "INSERT INTO dvdinput VALUES (3,720,480,4,3,1,1,'ntsc');",
4891 "INSERT INTO dvdinput VALUES (4,720,480,4,3,1,0,'ntsc');",
4892 "INSERT INTO dvdinput VALUES (5,720,576,16,9,3,1,'pal');",
4893 "INSERT INTO dvdinput VALUES (6,720,576,16,9,3,0,'pal');",
4894 "INSERT INTO dvdinput VALUES (7,720,576,4,3,3,1,'pal');",
4895 "INSERT INTO dvdinput VALUES (8,720,576,4,3,3,0,'pal');",
4896 "INSERT INTO dvdtranscode VALUES (1,1,'Good',2,1,16,16,0,0,2,0,0,0,0,0,32,32,8,8,'divx5',NULL,1618,NULL,NULL,0,NULL);",
4897 "INSERT INTO dvdtranscode VALUES (2,2,'Excellent',2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'divx5',NULL,0,NULL,NULL,1,NULL);",
4898 "INSERT INTO dvdtranscode VALUES (3,2,'Good',2,1,0,0,8,8,0,0,0,0,0,0,0,0,0,0,'divx5',NULL,1618,NULL,NULL,0,NULL);",
4899 "INSERT INTO dvdtranscode VALUES (4,2,'Medium',2,1,0,0,8,8,5,5,0,0,0,0,0,0,0,0,'divx5',NULL,1200,NULL,NULL,0,NULL);",
4900 "INSERT INTO dvdtranscode VALUES (5,3,'Good',2,1,0,0,0,0,0,0,0,0,2,0,80,80,8,8,'divx5',NULL,0,NULL,NULL,0,NULL);",
4901 "INSERT INTO dvdtranscode VALUES (6,4,'Excellent',2,1,0,0,0,0,0,0,0,0,2,0,0,0,0,0,'divx5',NULL,0,NULL,NULL,1,NULL);",
4902 "INSERT INTO dvdtranscode VALUES (7,4,'Good',2,1,0,0,8,8,0,2,0,0,0,0,0,0,0,0,'divx5',NULL,1618,NULL,NULL,0,NULL);",
4903 "INSERT INTO dvdtranscode VALUES (8,5,'Good',1,1,16,16,0,0,5,0,0,0,0,0,40,40,8,8,'divx5',NULL,1618,NULL,NULL,0,NULL);",
4904 "INSERT INTO dvdtranscode VALUES (9,6,'Good',1,1,0,0,16,16,5,0,0,0,0,0,0,0,0,0,'divx5',NULL,1618,NULL,NULL,0,NULL);",
4905 "INSERT INTO dvdtranscode VALUES (10,7,'Good',1,1,0,0,0,0,1,0,0,0,0,0,76,76,8,8,'divx5',NULL,1618,NULL,NULL,0,NULL);",
4906 "INSERT INTO dvdtranscode VALUES (11,8,'Good',1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,'divx5',NULL,1618,NULL,NULL,0,NULL);",
4907 "INSERT INTO playgroup VALUES ('Default','',30,5,100,0);",
4908 "INSERT INTO profilegroups VALUES (1,'Software Encoders (v4l based)','V4L',1,NULL);",
4909 "INSERT INTO profilegroups VALUES (2,'IVTV MPEG-2 Encoders','MPEG',1,NULL);",
4910 "INSERT INTO profilegroups VALUES (3,'Hardware MJPEG Encoders (Matrox G200-TV, Miro DC10, etc)','MJPEG',1,NULL);",
4911 "INSERT INTO profilegroups VALUES (4,'Hardware HDTV','HDTV',1,NULL);",
4912 "INSERT INTO profilegroups VALUES (5,'Hardware DVB Encoders','DVB',1,NULL);",
4913 "INSERT INTO profilegroups VALUES (6,'Transcoders','TRANSCODE',1,NULL);",
4914 "INSERT INTO profilegroups VALUES (7,'FireWire Input','FIREWIRE',1,NULL);",
4915 "INSERT INTO profilegroups VALUES (8,'USB Mpeg-4 Encoder (Plextor ConvertX, etc)','GO7007',1,NULL);",
4916 "INSERT INTO profilegroups VALUES (14,'Import Recorder','IMPORT',1,NULL);",
4917 "INSERT INTO profilegroups VALUES (10,'Freebox Input','Freebox',1,NULL);",
4918 "INSERT INTO profilegroups VALUES (11,'HDHomeRun Recorders','HDHOMERUN',1,NULL);",
4919 "INSERT INTO profilegroups VALUES (12,'CRC IP Recorders','CRC_IP',1,NULL);",
4920 "INSERT INTO profilegroups VALUES (13,'HD-PVR Recorders','HDPVR',1,NULL);",
4921 "INSERT INTO profilegroups VALUES (15,'ASI Recorder (DVEO)','ASI',1,NULL);",
4922 "INSERT INTO profilegroups VALUES (16,'OCUR Recorder (CableLabs)','OCUR',1,NULL);",
4923 "INSERT INTO profilegroups VALUES (17,'Ceton Recorder','CETON',1,NULL);",
4924 "INSERT INTO record VALUES (1,11,0,'21:57:44','2012-08-11','21:57:44','2012-08-11','Default (Template)','','',0,0,'Default','Default',0,0,0,0,0,0,'Default',6,15,'','','','',0,0,1,0,0,0,0,1,-1,'00:00:00',735091,0,0,0,'Default',0,'0000-00-00 00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','Default',100,0);",
4925 "INSERT INTO recordfilter VALUES (0,'New episode','program.previouslyshown = 0',0);",
4926 "INSERT INTO recordfilter VALUES (1,'Identifiable episode','program.generic = 0',0);",
4927 "INSERT INTO recordfilter VALUES (2,'First showing','program.first > 0',0);",
4928 "INSERT INTO recordfilter VALUES (3,'Prime time','HOUR(CONVERT_TZ(program.starttime, \\'Etc/UTC\\', \\'SYSTEM\\')) >= 19 AND HOUR(CONVERT_TZ(program.starttime, \\'Etc/UTC\\', \\'SYSTEM\\')) < 22',0);",
4929 "INSERT INTO recordfilter VALUES (4,'Commercial free','channel.commmethod = -2',0);",
4930 "INSERT INTO recordfilter VALUES (5,'High definition','program.hdtv > 0',0);",
4931 "INSERT INTO recordfilter VALUES (6,'This episode','(RECTABLE.programid <> \\'\\' AND program.programid = RECTABLE.programid) OR (RECTABLE.programid = \\'\\' AND program.subtitle = RECTABLE.subtitle AND program.description = RECTABLE.description)',0);",
4932 "INSERT INTO recordfilter VALUES (7,'This series','(RECTABLE.seriesid <> \\'\\' AND program.seriesid = RECTABLE.seriesid)',0);",
4933 "INSERT INTO recordingprofiles VALUES (1,'Default',NULL,NULL,1);",
4934 "INSERT INTO recordingprofiles VALUES (2,'Live TV',NULL,NULL,1);",
4935 "INSERT INTO recordingprofiles VALUES (3,'High Quality',NULL,NULL,1);",
4936 "INSERT INTO recordingprofiles VALUES (4,'Low Quality',NULL,NULL,1);",
4937 "INSERT INTO recordingprofiles VALUES (5,'Default',NULL,NULL,2);",
4938 "INSERT INTO recordingprofiles VALUES (6,'Live TV',NULL,NULL,2);",
4939 "INSERT INTO recordingprofiles VALUES (7,'High Quality',NULL,NULL,2);",
4940 "INSERT INTO recordingprofiles VALUES (8,'Low Quality',NULL,NULL,2);",
4941 "INSERT INTO recordingprofiles VALUES (9,'Default',NULL,NULL,3);",
4942 "INSERT INTO recordingprofiles VALUES (10,'Live TV',NULL,NULL,3);",
4943 "INSERT INTO recordingprofiles VALUES (11,'High Quality',NULL,NULL,3);",
4944 "INSERT INTO recordingprofiles VALUES (12,'Low Quality',NULL,NULL,3);",
4945 "INSERT INTO recordingprofiles VALUES (13,'Default',NULL,NULL,4);",
4946 "INSERT INTO recordingprofiles VALUES (14,'Live TV',NULL,NULL,4);",
4947 "INSERT INTO recordingprofiles VALUES (15,'High Quality',NULL,NULL,4);",
4948 "INSERT INTO recordingprofiles VALUES (16,'Low Quality',NULL,NULL,4);",
4949 "INSERT INTO recordingprofiles VALUES (17,'Default',NULL,NULL,5);",
4950 "INSERT INTO recordingprofiles VALUES (18,'Live TV',NULL,NULL,5);",
4951 "INSERT INTO recordingprofiles VALUES (19,'High Quality',NULL,NULL,5);",
4952 "INSERT INTO recordingprofiles VALUES (20,'Low Quality',NULL,NULL,5);",
4953 "INSERT INTO recordingprofiles VALUES (21,'RTjpeg/MPEG4',NULL,NULL,6);",
4954 "INSERT INTO recordingprofiles VALUES (22,'MPEG2',NULL,NULL,6);",
4955 "INSERT INTO recordingprofiles VALUES (23,'Default',NULL,NULL,8);",
4956 "INSERT INTO recordingprofiles VALUES (24,'Live TV',NULL,NULL,8);",
4957 "INSERT INTO recordingprofiles VALUES (25,'High Quality',NULL,NULL,8);",
4958 "INSERT INTO recordingprofiles VALUES (26,'Low Quality',NULL,NULL,8);",
4959 "INSERT INTO recordingprofiles VALUES (27,'High Quality',NULL,NULL,6);",
4960 "INSERT INTO recordingprofiles VALUES (28,'Medium Quality',NULL,NULL,6);",
4961 "INSERT INTO recordingprofiles VALUES (29,'Low Quality',NULL,NULL,6);",
4962 "INSERT INTO recordingprofiles VALUES (30,'Default',NULL,NULL,10);",
4963 "INSERT INTO recordingprofiles VALUES (31,'Live TV',NULL,NULL,10);",
4964 "INSERT INTO recordingprofiles VALUES (32,'High Quality',NULL,NULL,10);",
4965 "INSERT INTO recordingprofiles VALUES (33,'Low Quality',NULL,NULL,10);",
4966 "INSERT INTO recordingprofiles VALUES (34,'Default',NULL,NULL,11);",
4967 "INSERT INTO recordingprofiles VALUES (35,'Live TV',NULL,NULL,11);",
4968 "INSERT INTO recordingprofiles VALUES (36,'High Quality',NULL,NULL,11);",
4969 "INSERT INTO recordingprofiles VALUES (37,'Low Quality',NULL,NULL,11);",
4970 "INSERT INTO recordingprofiles VALUES (38,'Default',NULL,NULL,12);",
4971 "INSERT INTO recordingprofiles VALUES (39,'Live TV',NULL,NULL,12);",
4972 "INSERT INTO recordingprofiles VALUES (40,'High Quality',NULL,NULL,12);",
4973 "INSERT INTO recordingprofiles VALUES (41,'Low Quality',NULL,NULL,12);",
4974 "INSERT INTO recordingprofiles VALUES (42,'Default',NULL,NULL,7);",
4975 "INSERT INTO recordingprofiles VALUES (43,'Live TV',NULL,NULL,7);",
4976 "INSERT INTO recordingprofiles VALUES (44,'High Quality',NULL,NULL,7);",
4977 "INSERT INTO recordingprofiles VALUES (45,'Low Quality',NULL,NULL,7);",
4978 "INSERT INTO recordingprofiles VALUES (46,'Default',NULL,NULL,9);",
4979 "INSERT INTO recordingprofiles VALUES (47,'Live TV',NULL,NULL,9);",
4980 "INSERT INTO recordingprofiles VALUES (48,'High Quality',NULL,NULL,9);",
4981 "INSERT INTO recordingprofiles VALUES (49,'Low Quality',NULL,NULL,9);",
4982 "INSERT INTO recordingprofiles VALUES (50,'Default',NULL,NULL,13);",
4983 "INSERT INTO recordingprofiles VALUES (51,'Live TV',NULL,NULL,13);",
4984 "INSERT INTO recordingprofiles VALUES (52,'High Quality',NULL,NULL,13);",
4985 "INSERT INTO recordingprofiles VALUES (53,'Low Quality',NULL,NULL,13);",
4986 "INSERT INTO recordingprofiles VALUES (54,'Default',NULL,NULL,14);",
4987 "INSERT INTO recordingprofiles VALUES (55,'Live TV',NULL,NULL,14);",
4988 "INSERT INTO recordingprofiles VALUES (56,'High Quality',NULL,NULL,14);",
4989 "INSERT INTO recordingprofiles VALUES (57,'Low Quality',NULL,NULL,14);",
4990 "INSERT INTO recordingprofiles VALUES (58,'Default',NULL,NULL,15);",
4991 "INSERT INTO recordingprofiles VALUES (59,'Live TV',NULL,NULL,15);",
4992 "INSERT INTO recordingprofiles VALUES (60,'High Quality',NULL,NULL,15);",
4993 "INSERT INTO recordingprofiles VALUES (61,'Low Quality',NULL,NULL,15);",
4994 "INSERT INTO recordingprofiles VALUES (62,'Default',NULL,NULL,16);",
4995 "INSERT INTO recordingprofiles VALUES (63,'Live TV',NULL,NULL,16);",
4996 "INSERT INTO recordingprofiles VALUES (64,'High Quality',NULL,NULL,16);",
4997 "INSERT INTO recordingprofiles VALUES (65,'Low Quality',NULL,NULL,16);",
4998 "INSERT INTO recordingprofiles VALUES (66,'Default',NULL,NULL,17);",
4999 "INSERT INTO recordingprofiles VALUES (67,'Live TV',NULL,NULL,17);",
5000 "INSERT INTO recordingprofiles VALUES (68,'High Quality',NULL,NULL,17);",
5001 "INSERT INTO recordingprofiles VALUES (69,'Low Quality',NULL,NULL,17);",
5002 "INSERT INTO settings VALUES ('mythfilldatabaseLastRunStart','',NULL);",
5003 "INSERT INTO settings VALUES ('mythfilldatabaseLastRunEnd','',NULL);",
5004 "INSERT INTO settings VALUES ('mythfilldatabaseLastRunStatus','',NULL);",
5005 "INSERT INTO settings VALUES ('DataDirectMessage','',NULL);",
5006 "INSERT INTO settings VALUES ('HaveRepeats','0',NULL);",
5007 "INSERT INTO settings VALUES ('DBSchemaVer','1307',NULL);",
5008 "INSERT INTO settings VALUES ('DefaultTranscoder','0',NULL);",
5009 "INSERT INTO videotypes VALUES (1,'txt','',1,0);",
5010 "INSERT INTO videotypes VALUES (2,'log','',1,0);",
5011 "INSERT INTO videotypes VALUES (3,'mpg','Internal',0,0);",
5012 "INSERT INTO videotypes VALUES (4,'avi','',0,1);",
5013 "INSERT INTO videotypes VALUES (5,'vob','Internal',0,0);",
5014 "INSERT INTO videotypes VALUES (6,'mpeg','Internal',0,0);",
5015 "INSERT INTO videotypes VALUES (8,'iso','Internal',0,0);",
5016 "INSERT INTO videotypes VALUES (9,'img','Internal',0,0);",
5017 "INSERT INTO videotypes VALUES (10,'mkv','Internal',0,0);",
5018 "INSERT INTO videotypes VALUES (11,'mp4','Internal',0,0);",
5019 "INSERT INTO videotypes VALUES (12,'m2ts','Internal',0,0);",
5020 "INSERT INTO videotypes VALUES (13,'evo','Internal',0,0);",
5021 "INSERT INTO videotypes VALUES (14,'divx','Internal',0,0);",
5022 "INSERT INTO videotypes VALUES (15,'mov','Internal',0,0);",
5023 "INSERT INTO videotypes VALUES (16,'qt','Internal',0,0);",
5024 "INSERT INTO videotypes VALUES (17,'wmv','Internal',0,0);",
5025 "INSERT INTO videotypes VALUES (18,'3gp','Internal',0,0);",
5026 "INSERT INTO videotypes VALUES (19,'asf','Internal',0,0);",
5027 "INSERT INTO videotypes VALUES (20,'ogg','Internal',0,0);",
5028 "INSERT INTO videotypes VALUES (21,'ogm','Internal',0,0);",
5029 "INSERT INTO videotypes VALUES (22,'flv','Internal',0,0);",
5030 "INSERT INTO videotypes VALUES (23,'ogv','Internal',0,0);",
5031 "INSERT INTO videotypes VALUES (25,'nut','Internal',0,0);",
5032 "INSERT INTO videotypes VALUES (26,'mxf','Internal',0,0);",
5033 "INSERT INTO videotypes VALUES (27,'m4v','Internal',0,0);",
5034 "INSERT INTO videotypes VALUES (28,'rm','Internal',0,0);",
5035 "INSERT INTO videotypes VALUES (29,'ts','Internal',0,0);",
5036 "INSERT INTO videotypes VALUES (30,'swf','Internal',0,0);",
5037 "INSERT INTO videotypes VALUES (31,'f4v','Internal',0,0);",
5038 "INSERT INTO videotypes VALUES (32,'nuv','Internal',0,0);",
5039 nullptr
5040 };
5041 
5042  QString dbver = "";
5043  if (!performActualUpdate(updates, "1307", dbver))
5044  return false;
5045 
5046  GetMythDB()->SetHaveSchema(true);
5047 
5048  return true;
5049 }
5050 
5051 /* vim: set expandtab tabstop=4 shiftwidth=4: */
QString m_fileName
Definition: recordingfile.h:44
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:781
Provides UI and helper functions for DB Schema updates.
Definition: schemawizard.h:25
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:862
bool UpgradeTVDatabaseSchema(const bool upgradeAllowed, const bool upgradeIfNoUI, const bool informSystemd)
Called from outside dbcheck.cpp to update the schema.
QString dbName
database name
Definition: mythdbparams.h:26
static uint CreateInputGroup(const QString &name)
Definition: cardutil.cpp:1854
static bool performActualUpdate(const char **updates, const char *version, QString &dbver)
Runs a number of SQL commands, and updates the schema version.
QSize m_videoResolution
Definition: recordingfile.h:50
static bool UpdateDBVersionNumber(const QString &newnumber, QString &dbver)
Updates the schema version stored in the database.
#define DEINT_QUALITY_SHADER
QString m_storageGroup
Definition: recordingfile.h:41
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:125
static bool performUpdateSeries(const char **updates)
Runs a number of SQL commands.
int size(void) const
Definition: mythdbcon.h:203
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:34
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
RecordingType m_type
RecordingDupMethodType m_dupMethod
#define DEINT_QUALITY_DRIVER
#define DEINT_QUALITY_HIGH
bool doUpgradeVideoDatabaseSchema(void)
static bool doUpgradeTVDatabaseSchema(void)
This is called by UpgradeTVDatabaseSchema() to actually upgrade the schema to what MythTV expects.
enum MythSchemaUpgrade PromptForUpgrade(const char *name, const bool upgradeAllowed, const bool upgradeIfNoUI, const int minDBMSmajor=0, const int minDBMSminor=0, const int minDBMSpoint=0)
Query user, to prevent silent, automatic database upgrades.
QVariant value(int i) const
Definition: mythdbcon.h:198
bool Save(bool sendSig=true)
static SchemaUpgradeWizard * Get(const QString &DBSchemaSetting, const QString &appName, const QString &upgradeSchemaVal)
Instead of creating a new wizard, use the existing one for its DB backup file & results and expert se...
QSqlError lastError(void) const
Definition: mythdbcon.h:202
QVariant lastInsertId()
Return the id of the last inserted row.
Definition: mythdbcon.cpp:886
QString m_storageDeviceID
Definition: recordingfile.h:40
void Set(const QString &Value, const QString &Data)
bool m_autoMetadataLookup
QString GetSetting(const QString &key, const QString &defaultval="")
int Compare(void)
How many schema versions old is the DB?
static const uint TranscoderAutodetect
sentinel value
bool isActive(void) const
Definition: mythdbcon.h:204
double m_videoFrameRate
Definition: recordingfile.h:52
void SetProfileID(uint Id)
string hostname
Definition: caa.py:17
unsigned int uint
Definition: compat.h:140
static bool UnlinkInputGroup(uint inputid, uint inputgroupid)
Definition: cardutil.cpp:1973
static MSqlQueryInfo InitCon(ConnectionReuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:534
Internal representation of a recording rule, mirrors the record table.
Definition: recordingrule.h:32
double m_videoAspectRatio
Definition: recordingfile.h:51
Holds information on a recording file and it's video and audio streams.
Definition: recordingfile.h:29
static unsigned GetDefaultFilter(void)
bool IsMasterHost(void)
is this the same host as the master
bool MakeTemplate(QString category)
int GetNumSetting(const QString &key, int defaultval=0)
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:806
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
bool GetBoolSetting(const QString &key, bool defaultval=false)
DatabaseParams GetDatabaseParams(void)
const QString currentDatabaseVersion
static void UnlockSchema(MSqlQuery &)
Definition: dbutil.cpp:856
unsigned m_filter
static QString DBErrorMessage(const QSqlError &err)
Definition: mythdb.cpp:184
static bool TryLockSchema(MSqlQuery &, uint timeout_secs)
Try to get a lock on the table schemalock.
Definition: dbutil.cpp:849
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:602
MythDB * GetMythDB(void)
Definition: mythdb.cpp:46
bool SaveSettingOnHost(const QString &key, const QString &newValue, const QString &host)
static bool LinkInputGroup(uint inputid, uint inputgroupid)
Definition: cardutil.cpp:1933
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:179
#define DEINT_QUALITY_MEDIUM
void ActivateSettingsCache(bool activate=true)
#define DEINT_QUALITY_LOW
deprecated, it is only 1:1 sample aspect ratio
Definition: programtypes.h:65
#define db_sd_notify(x)
QString GetHostName(void)
#define MINIMUM_DBMS_VERSION
static bool IsNewDatabase(void)
Returns true for a new (empty) database.
Definition: dbutil.cpp:83
bool InitializeMythSchema(void)
command to get the the initial database layout from an empty database:
#define MYTH_DATABASE_VERSION
Increment this whenever the MythTV core database schema changes.
Definition: mythversion.h:78
uint64_t m_fileSize
Definition: recordingfile.h:45