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