#include "mythconfig.h"

#include <cstdio>
#include <iostream>
using namespace std;

#include <QString>
#include <QSqlError>
#include "dbcheck.h"

#include "mythversion.h"
#include "dbutil.h"
#include "mythcorecontext.h"
#include "schemawizard.h"
#include "mythdb.h"
#include "mythlogging.h"
#include "videodbcheck.h" // for 1267
#include "compat.h"
#include "recordingrule.h"
#include "recordingprofile.h"
#include "recordinginfo.h"
#include "cardutil.h"

// TODO convert all dates to UTC

#define MINIMUM_DBMS_VERSION 5,0,15

const QString currentDatabaseVersion = MYTH_DATABASE_VERSION;

static bool UpdateDBVersionNumber(const QString &newnumber, QString &dbver);
static bool performActualUpdate(
    const char **updates, const char *version, QString &dbver);
static bool doUpgradeTVDatabaseSchema(void);

#if CONFIG_SYSTEMD_NOTIFY
#include <systemd/sd-daemon.h>
#define db_sd_notify(x) \
    if (informSystemd) \
        (void)sd_notify(0, "STATUS=Database update " x);
#else
#define db_sd_notify(x)
#endif

/** \defgroup db_schema MythTV Database Schema

\section db_intro Introduction

\verbatim
The schema contains the following tables:
\endverbatim

\htmlonly
<table>
<tr><td>capturecard                <td>pk(cardid)
<tr><td>cardinput                  <td>pk(cardinputid)
<tr><td>channel                    <td>pk(chanid) k(channum,sourceid)
<tr><td>channelgroup               <td>pk(id)
<tr><td>channelgroupnames          <td>pk(grpid)
<tr><td>codecparams                <td>pk(profile,name)
<tr><td>conflictresolutionany      <td>k(prefertitle) k(disliketitle)
<tr><td>conflictresolutionoverride <td>k(chanid,starttime) k(endtime)
<tr><td>conflictresolutionsingle   <td>k(preferchanid,preferstarttime) k(preferendtime)
<tr><td>credits                    <td>uk(chanid,starttime,person,role) k(person,role)
<tr><td>dtv_multiplex              <td>pk(mplexid)
<tr><td>dtv_privatetypes
<tr><td>dvb_signal_quality         <td>pk(id) k(sampletime,cardid)
<tr><td>housekeeping               <td>pk(tag)
<tr><td>jobqueue                   <td>pk(id) uk(chanid,starttime,type,inserttime)
<tr><td>jumppoints                 <td>pk(destination,hostname)
<tr><td>keybindings                <td>pk(context,action,hostname)
<tr><td>keyword                    <td>uk(phrase,searchtype)
<tr><td>mythlog                    <td>pk(logid)
<tr><td>oldprogram                 <td>pk(oldtitle)
<tr><td>oldrecorded                <td>k(endtime) k(title) k(seriesid) k(programid)
                                       pk(station,starttime,title)
<tr><td>people                     <td>pk(person) uk(name)
<tr><td>pidcache                   <td>
<tr><td>profilegroups              <td>pk(id) uk(name,hostname)
<tr><td>program                    <td>k(endtime) k(title_pronounce) k(seriesid)
                                       k(programid,starttime) k(chanid,starttime,endtime)
                                       k(title,subtitle,starttime)
<tr><td>programgenres              <td>pk(chanid,starttime,relevance)
<tr><td>programrating              <td>uk(chanid,starttime,system,rating)
                                       k(starttime,system)
<tr><td>recgrouppassword           <td>pk(recgroup) uk(recgroup)
<tr><td>record                     <td>pk(recordid) k(chanid,starttime) k(title)
                                       k(seriesid) k(programid)
<tr><td>recorded                   <td>k(endtime) k(seriesid) k(programid)
<tr><td>recordedmarkup             <td>pk(chanid,starttime,mark,type)
<tr><td>recordingprofiles          <td>pk(id)
<tr><td>recordoverride             <td>
<tr><td>settings                   <td>k(value,hostname)
<tr><td>videosource                <td>pk(sourceid) uk(name)
<tr><td>displayprofilegroups       <td>pk(name, host), uk(profileid)
<tr><td>displayprofiles            <td>pk(profileid),
</table>
\endhtmlonly

Where pk means PRIMARY KEY, uk means "UNIQUE KEY", and k means "KEY".
BUSQ refers to the Big Ugly SQL Query in scheduler.cpp

\section capturecard_table Capture Card Table (capturecard)
This table describes the attributes of a capture card used by MythTV.

The primary key 'cardid' is automatically generated by the database.

The 'videodevice' field normally points to a device used to capture
the video, but for DVB where multiple devices are used it is simply
a number indicating which set of devices to use. The 'audiodevice'
is only used by framegrabber cards, encoding cards like the Hauppauge
PVR line encode the audio as part of the video stream, while DTV
cards like the various ATSC and DVB cards receive the audio as part
of the video stream. The same applies to the 'vbidevice', PVR and
DTV cards have captions encoded in the digital stream, while
framegrabber cards use this device to provide caption and other
data to MythTV.

The 'audioratelimit' field is used to set the audio capture rate
when using the 'audiodevice' field. This is mostly useful for
V4L cards that have troublesome on-board audio, such as some
cards supported by the bttv driver.


The 'cardtype' is an important field for all cards as it guides the
interpretation of the rest of the fields, it has several possible
values: "V4L", "MJPEG", "DVB", "MPEG", "FIREWIRE", and "GO7007".
"V4L" indicates a V4L compatible device, this could be a
true V4L device or something like a Firewire camera with the
"firewire->v4l" driver.
"MJPEG" describes a Matrox G200 or DC10 card which captures
individual frames as JPEG images.
"DVB" can describe any card supported by the Linux DVB
drivers, including the pcHDTV and other ATSC cards.
The "MPEG" type describes a device using the ivtv drivers such as
the Hauppauge PVR[150,250,350,500]s +Freestyle cards, the Yuan MPEG
series, the Avermedia M179, and the Adaptec VideOh! AVC-2410.
The "FIREWIRE" card type does not describe Firewire cameras or
capture cards but instead describes the Firewire port required by
law in the USA on cable boxes for subscribers who receive HDTV
channels and request the Firewire port feature. This port lets
you communicate with your cable box without needing to build an
IR transmitter; in some cases, it also allows you to digitally
capture video.
The "GO7007" card type describes a USB MPEG-4 encoder such
as the Plextor ConvertX.

The 'hostname' field is another important field for all cards
as it specifies which backend the capture card is connected to.

The 'signal_timeout' and 'channel_timeout' indicate in
milliseconds how long it should take to get a signal and
channel lock respectively.

The 'dvb_swfilter', 'dvb_sat_type', 'dvb_wait_for_seqstart',
'skipbtaudio', 'dvb_on_demand', and 'dvb_diseqc_type' columns
are all "DVB" specific configuration parameters.

Both 'dvb_recordts' and 'dvb_hw_decoder' are unused, and
will be dropped in future versions of MythTV.

The 'firewire_port', 'firewire_node', 'firewire_speed',
'firewire_model', 'firewire_connection' are all "FIREWIRE" specific
configuration parameters. The first three define the connection,
and function much like 'videodevice' does for other capture "cards".
The 'firewire_model' describes the cable box model, for example
"DCT-6000" describes a box that communicates using the same protocol
as the Motorola DCT-6000. The 'firewire_connection' field describes
the overall communication protocol, i.e. are we using "Broadcast"
or "Point-to-Point" communication.

\section dtv_multiplex_table Digital Television Multiplex Table (dtv_multiplex)
This table contains the information needed to tune to a particular
frequency on a particular input.

The primary key, 'mplexid', is automatically generated by the database.
The most important field is the 'frequency' field which contains the
transmission frequency in Hertz. The 'sourceid' which tells us which
card and on what input of that card this multiplex applies to according
to the \ref videosource_table. Along with a channel number 'sourceid'
also uniquely identifies a channel in the \ref channel_table. The
'modulation' field tells us whether the modulation mode is "qpsk",
"qam_16", "qam_32", "qam_64", "qam_128", "qam_256", "8vsb", "16vsb",
or "auto". Finally, the 'sistandard' field is the last field which
applies to both DVB and ATSC, it contains on of four strings, "dvb",
"atsc", "mpeg" or "opencable".

When describing a DVB Multiplex, the networkid, and transportid are
used along with the serviceid in the \ref channel_table to tune to
a particular MPEG stream in DVBChannel.

When describing an ATSC Multiplex, the \ref channel_table contains
the major and minor channels used to tune to a particular stream.

Other fields are used by different DVBx implementations to tune to a
a particular type of service and MythTV just passes them along to the
drivers to take care of.



\section dtv_privatetypes_table Digital Television Private Types Table (dtv_privatetypes)
This table contains free form data pertaining to DVB services, it is
like a settings table for DVB.



\section videosource_table Video Source Table (videosource)
This table tells us about a particular input on a video capture card.

The primary key, 'sourceid', is automatically generated by the database.
The 'name' field gives the input name as passed to the video capture card
driver. The 'xmltvgrabber' field tells us where we get our listings from.
The 'userid' and 'password' fields are optionally used to log in to a
listings service, with the 'lineupid' being used to select a particular
lineup available from the listings service. Finally, the 'freqtable'
tells us which channel number to frequency mapping to use with
analog channels, us, us-cable, pal, etc.



\section channel_table Channel Table (channel)
The primary key, 'chanid' is generated by multiplying the sourceid times
1000 and adding the channel number to create a unique chanid.
See also ChannelUtil::CreateChanId() .

The 'channum' field contains the channel number to be input to jump
to a channel.

The 'sourceid' field contains the \ref videosource_table key, which
specifies which listings service to use and which input on which video
capture card to find this channel.

The 'callsign' field contains the government mandated license number
of the channel's broadcaster if this is an over-the-air channel.

The 'name' field provides the alphanumeric name of this channel for
use in the %MythTV user interface.

The 'icon' field provides the path to an optional channel icon for this
channel.

The 'freqid' field provides the channel number to tune to, as
differentiated from the 'channum' used in the %MythTV user interface.
When the 'mplexid' is set it is used instead. And the 'finetune' field
is used to adjust the frequency provided by the combination of 'freqid'
and 'tvformat', this can be used when there is carrier drift in a cable
system.

The 'xmltvid' field is used to identify this channel to the listings
provider.

The 'tmoffset' field is used to apply an offset (in minutes) from the listings
provided by the provider to a new time in the MythTV program guide database.
This is very handy when the listings provider has listings which are offset
by a few hours on individual channels with the rest of them being correct.

The 'recpriority' field is used tell the scheduler from which of two
otherwise equivalent programs on two different channels should be
preferred, a higher number means this channel is more preferred.

The 'tvformat' is one of "ntsc", "ntsc-jp", "pal", "atsc", etc and is used
for various purposes, such as translating a channel number to a frequency,
setting the recording frame size, etc.

'commfree' tells us whether this is a commercial free channel, such as
those on the BBC and CBC networks. On commercial free channels we
do not need to run the commercial detector.

'commmethod' tells us which commercial flagger to use on the channel, the
default is to use the global setting

'visible' tells us whether we should show this channel in the channel
guide.

'outputfilters' contains a list of filters that should be applied
when playing recordings from this channel.

The 'contrast' 'brightness', 'colour', and 'hue' fields are used by frame
grabbing recorders to adjust the picture before encoding each frame.
And, 'videofilters' contains a list of filters that should be applied
when recording from channel using a frame grabbing recorder.

For digital television, the 'mplexid' field contains the
\ref dtv_multiplex_table key for determining additional digital tuning
parameters. The 'serviceid' field contains the MPEG program number when
describing a DVB service. The 'useonairguide' field is used by DVB to
determine whether to use the on-air-guide data from this channel to
update the listings.

\section program_table Program Entry Table (program)
'category_type' holds one of these exact four strings:
"movie", "series", "sports" or "tvshow".

'airdate' is a string representing the year of release for movies and
may have no meaning for other types of shows.

'stars' is a floating point number from 0.0 to 1.0. On a four star scale,
1.0 would be four stars, 0.75 would be three stars and so on.

'originalairdate' if provided is the date when a show was, or will be,
first televised.

'previouslyshown' is a field created by MythTV to try to determine if
a showing is more than 14 days after its original air date or if the
show was marked as a repeat and did not have a date for the first
airing. If this is "0" it usually means that this is a brand new show
or a rebroadcast within the first two weeks.

'programid' is the Tribune Media Service database record identifier
for each program description. In general, these start with a two
letter prefix, MV, EP, SP or SH that equate to the 'category_type'.
For most, the last four digits are "0000" except EP where the last
four digits are the episode number in the series. Note that these
are generated by TMS and not the show's producers but they are
usually in the same order as the original air dates for the episodes.
Detailed information can be found in the Data Direct documentation
at http://labs.zap2it.com/ .

\section oldrecorded_table Old Recorded Table (oldrecorded)

oldrecorded imposes the restriction of one entry per
title, starttime and callsign.  The scheduler relies on this when
restoring any previous status for programs that aren't currently
recording and for catching reactivation requests.

The duplicate field is used to indicate if this record should be used
to check for duplicates in the BUSQ

\section oldfind_table Old Find Table (oldfind)

If a matching entry exists in
the oldfind table, the program is considered a duplicate regardless of
the duplicate setting in recorded and oldrecorded.  oldfind is an
imperfect optimization to avoid greatly increasing the time needed for
the big scheduler query.

But the real reason for oldfind is that a search
rule may not be able to match by title. For instance, a FindWeekly
"Bill Murray (People Search)" needs to know that "Meatballs" is a
duplicate for this week if "Stripes" has already been recorded. Oldfind
tracks if the rule (recordid) has recorded in the current time
interval (findid). When a recording has a findid, ForgetHistory()
and DeleteHistory() update oldfind while updating oldrecorded.

\section recorded_table Recorded Table (recorded

The duplicate field is used to indicate if this record should be used
to check for duplicates in the BUSQ
 */

/** \fn UpdateDBVersionNumber(const QString&, QString&)
 *  \brief Updates the schema version stored in the database.
 *
 *   Updates "DBSchemaVer" property in the settings table.
 *  \param newnumber New schema version.
 *  \param dbver the database version at the end of the function is returned
 *               in this parameter, if things go well this will be 'newnumber'.
 */
static bool UpdateDBVersionNumber(const QString &newnumber, QString &dbver)
{
    // delete old schema version
    MSqlQuery query(MSqlQuery::InitCon());

    QString thequery = "DELETE FROM settings WHERE value='DBSchemaVer';";
    query.prepare(thequery);

    if (!query.exec())
    {
        QString msg =
            QString("DB Error (Deleting old DB version number): \n"
                    "Query was: %1 \nError was: %2 \nnew version: %3")
            .arg(thequery)
            .arg(MythDB::DBErrorMessage(query.lastError()))
            .arg(newnumber);
        LOG(VB_GENERAL, LOG_ERR, msg);
        return false;
    }

    // set new schema version
    thequery = QString("INSERT INTO settings (value, data, hostname) "
                       "VALUES ('DBSchemaVer', %1, NULL);").arg(newnumber);
    query.prepare(thequery);

    if (!query.exec())
    {
        QString msg =
            QString("DB Error (Setting new DB version number): \n"
                    "Query was: %1 \nError was: %2 \nnew version: %3")
            .arg(thequery)
            .arg(MythDB::DBErrorMessage(query.lastError()))
            .arg(newnumber);
        LOG(VB_GENERAL, LOG_ERR, msg);
        return false;
    }

    dbver = newnumber;

    return true;
}

/** \fn performUpdateSeries(const char **)
 *  \brief Runs a number of SQL commands.
 *
 *  \param updates  array of SQL commands to issue, terminated by a NULL string.
 *  \return true on success, false on failure
 */
static bool performUpdateSeries(const char **updates)
{
    MSqlQuery query(MSqlQuery::InitCon());

    int counter = 0;
    const char *thequery = updates[counter];

    while (thequery != nullptr)
    {
        if (strlen(thequery) && !query.exec(thequery))
        {
            QString msg =
                QString("DB Error (Performing database upgrade): \n"
                        "Query was: %1 \nError was: %2")
                .arg(thequery)
                .arg(MythDB::DBErrorMessage(query.lastError()));
            LOG(VB_GENERAL, LOG_ERR, msg);
            return false;
        }

        counter++;
        thequery = updates[counter];
    }

    return true;
}

/** \fn performActualUpdate(const char **, const char*, QString&)
 *  \brief Runs a number of SQL commands, and updates the schema version.
 *
 *  \param updates  array of SQL commands to issue, terminated by a NULL string.
 *  \param version  version we are updating db to.
 *  \param dbver    the database version at the end of the function is returned
 *                  in this parameter, if things go well this will be 'version'.
 *  \return true on success, false on failure
 */
static bool performActualUpdate(
    const char **updates, const char *version, QString &dbver)
{
    MSqlQuery query(MSqlQuery::InitCon());

    LOG(VB_GENERAL, LOG_CRIT, QString("Upgrading to MythTV schema version ") +
            version);

    if (!performUpdateSeries(updates))
        return false;

    if (!UpdateDBVersionNumber(version, dbver))
        return false;

    return true;
}

/**
 *  \brief Called from outside dbcheck.cpp to update the schema.
 *
 *   If the "DBSchemaVer" property equals the currentDatabase version this
 *   returns true immediately. If not, we try to do a database backup,
 *   if interactive prompt the user for permission to do the upgrade,
 *   and if permitted or non-interactive with a successful backup
 *   do the actual update.
 *
 *   If the program running this function is killed while
 *   this is running then the schema may be corrupted.
 *
 *  \return false on failure, error, or if the user selected "Exit."
 */
bool UpgradeTVDatabaseSchema(const bool upgradeAllowed,
                             const bool upgradeIfNoUI,
                             const bool informSystemd)
{
#ifdef IGNORE_SCHEMA_VER_MISMATCH
    return true;
#endif
#if CONFIG_SYSTEMD_NOTIFY == 0
    Q_UNUSED(informSystemd);
#endif
    SchemaUpgradeWizard *schema_wizard = nullptr;

    // Suppress DB messages and turn of the settings cache,
    // These are likely to confuse the users and the code, respectively.
    GetMythDB()->SetSuppressDBMessages(true);
    gCoreContext->ActivateSettingsCache(false);

    // Get the schema upgrade lock
    MSqlQuery query(MSqlQuery::InitCon());
    bool locked = DBUtil::TryLockSchema(query, 1);
    for (uint i = 0; i < 2*60 && !locked; i++)
    {
        db_sd_notify("waiting for lock");
        LOG(VB_GENERAL, LOG_INFO, "Waiting for database schema upgrade lock");
        locked = DBUtil::TryLockSchema(query, 1);
        if (locked)
            LOG(VB_GENERAL, LOG_INFO, "Got schema upgrade lock");
    }
    if (!locked)
    {
        LOG(VB_GENERAL, LOG_INFO, "Failed to get schema upgrade lock");
        goto upgrade_error_exit;
    }

    // Determine if an upgrade is needed
    schema_wizard = SchemaUpgradeWizard::Get(
        "DBSchemaVer", "MythTV", currentDatabaseVersion);
    if (schema_wizard->Compare() == 0) // DB schema is what we need it to be..
        goto upgrade_ok_exit;

    if (!upgradeAllowed)
        LOG(VB_GENERAL, LOG_WARNING, "Not allowed to upgrade the database.");

    db_sd_notify("waiting for user input");
    // Pop up messages, questions, warnings, etc.
    switch (schema_wizard->PromptForUpgrade(
                "TV", upgradeAllowed, upgradeIfNoUI, MINIMUM_DBMS_VERSION))
    {
        case MYTH_SCHEMA_USE_EXISTING:
            goto upgrade_ok_exit;
        case MYTH_SCHEMA_ERROR:
        case MYTH_SCHEMA_EXIT:
            goto upgrade_error_exit;
        case MYTH_SCHEMA_UPGRADE:
            break;
    }

    LOG(VB_GENERAL, LOG_DEBUG, QString("Newest MythTV Schema Version : %1")
        .arg(currentDatabaseVersion));

    // Upgrade the schema
    db_sd_notify("upgrading database");
    if (!doUpgradeTVDatabaseSchema())
    {
        LOG(VB_GENERAL, LOG_ERR, "Database schema upgrade failed.");
        goto upgrade_error_exit;
    }

    LOG(VB_GENERAL, LOG_INFO, "Database schema upgrade complete.");

    // On any exit we want to re-enable the DB messages so errors
    // are reported and we want to make sure the setting cache is
    // enabled for good performance and we must unlock the schema
    // lock. We use gotos with labels so it's impossible to miss
    // these steps.
  upgrade_ok_exit:
    db_sd_notify("success");
    GetMythDB()->SetSuppressDBMessages(false);
    gCoreContext->ActivateSettingsCache(true);
    if (locked)
        DBUtil::UnlockSchema(query);
    return true;

  upgrade_error_exit:
    db_sd_notify("failed");
    GetMythDB()->SetSuppressDBMessages(false);
    gCoreContext->ActivateSettingsCache(true);
    if (locked)
        DBUtil::UnlockSchema(query);
    return false;
}

/** \fn doUpgradeTVDatabaseSchema(void)
 *  \brief This is called by UpgradeTVDatabaseSchema() to actually upgrade
 *         the schema to what MythTV expects.
 *
 *   This function Initializes the database if the "DBSchemaVer" property
 *   does not exist in the database. Otherwise it upgrades the schema
 *   from the one in that property to the currentDatabaseVersion, by
 *   running the SQL commands needed for each upgrade between the two
 *   versions. This will only upgrade the schema, so bad things may
 *   happen if you upgrade and then downgrade MythTV across DB Schema
 *   versions.
 *
 */
static bool doUpgradeTVDatabaseSchema(void)
{
    QString dbver = gCoreContext->GetSetting("DBSchemaVer");

    if (dbver == currentDatabaseVersion)
    {
        return true;
    }

    // Don't rely on this, please specify these when creating the database.
    {
        MSqlQuery query(MSqlQuery::InitCon());
        if (!query.exec(QString("ALTER DATABASE %1 DEFAULT "
                                "CHARACTER SET utf8 COLLATE utf8_general_ci;")
                        .arg(gCoreContext->GetDatabaseParams().dbName)))
        {
            MythDB::DBError("UpgradeTVDatabaseSchema -- alter charset", query);
        }
    }

    if (DBUtil::IsNewDatabase())
    {
        if (!InitializeMythSchema())
            return false;
        dbver = gCoreContext->GetSetting("DBSchemaVer");
    }

    if (dbver.isEmpty() || dbver.toInt() <  1027)
    {
        LOG(VB_GENERAL, LOG_ERR, "Unrecognized database schema version. "
                                 "Unable to upgrade database.");
        return false;
    }
    else if (dbver.toInt() <  1244)
    {
        LOG(VB_GENERAL, LOG_ERR, "Your database version is too old to upgrade "
                                 "with this version of MythTV. You will need "
                                 "to use mythtv-setup from MythTV 0.22, 0.23, "
                                 "or 0.24 to upgrade your database before "
                                 "upgrading to this version of MythTV.");
        return false;
    }

    if (dbver == "1244")
    {
       const char *updates[] = {
"ALTER TABLE cardinput DROP COLUMN freetoaironly;",
"ALTER TABLE cardinput DROP COLUMN radioservices;",
nullptr
};
        if (!performActualUpdate(updates, "1245", dbver))
            return false;
    }

    if (dbver == "1245")
    {
       const char *updates[] = {
"DELETE FROM capturecard WHERE cardtype = 'DBOX2';",
"DELETE FROM profilegroups WHERE cardtype = 'DBOX2';",
"ALTER TABLE capturecard DROP COLUMN dbox2_port;",
"ALTER TABLE capturecard DROP COLUMN dbox2_httpport;",
"ALTER TABLE capturecard DROP COLUMN dbox2_host;",
nullptr
};
       if (!performActualUpdate(updates, "1246", dbver))
            return false;
    }

    if (dbver == "1246")
    {
       const char *updates[] = {
"ALTER TABLE recorded ADD COLUMN bookmarkupdate timestamp default 0 NOT NULL",
"UPDATE recorded SET bookmarkupdate = lastmodified+1 WHERE bookmark = 1",
"UPDATE recorded SET bookmarkupdate = lastmodified WHERE bookmark = 0",
nullptr
};
       if (!performActualUpdate(updates, "1247", dbver))
            return false;
    }

    if (dbver == "1247")
    {
        const char *updates[] = {
"INSERT INTO profilegroups SET name = \"Import Recorder\", cardtype = 'IMPORT', is_default = 1;",
"INSERT INTO recordingprofiles SET name = \"Default\", profilegroup = 14;",
"INSERT INTO recordingprofiles SET name = \"Live TV\", profilegroup = 14;",
"INSERT INTO recordingprofiles SET name = \"High Quality\", profilegroup = 14;",
"INSERT INTO recordingprofiles SET name = \"Low Quality\", profilegroup = 14;",
nullptr
};
        if (!performActualUpdate(updates, "1248", dbver))
            return false;
    }

    if (dbver == "1248")
    {
       const char *updates[] = {
"DELETE FROM keybindings WHERE action = 'CUSTOMEDIT' "
   "AND context = 'TV Frontend' AND keylist = 'E';",
nullptr
};
        if (!performActualUpdate(updates, "1249", dbver))
            return false;
    }

    if (dbver == "1249")
    {
        LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1250");

        MSqlQuery select(MSqlQuery::InitCon());
        select.prepare("SELECT hostname, data FROM settings "
                       " WHERE value = 'StickyKeys'");

        if (!select.exec())
        {
            MythDB::DBError("Unable to retrieve StickyKeys values.", select);
        }
        else
        {
            MSqlQuery update(MSqlQuery::InitCon());
            while (select.next())
            {
                QString hostname = select.value(0).toString();
                QString sticky_keys = select.value(1).toString();

                if ("1" == sticky_keys)
                {
                    // Only remap the keys if they're currently set to defaults
                    update.prepare("UPDATE keybindings "
                                   "   SET keylist  = :KEYS "
                                   " WHERE context  = 'TV Playback' AND "
                                   "       action   = :ACTION AND "
                                   "       hostname = :HOSTNAME AND "
                                   "       keylist  = :DEFAULT_KEYS");

                    QString keylist = "";
                    QString action = "SEEKFFWD";
                    QString default_keys = "Right";

                    update.bindValue(":KEYS", keylist);
                    update.bindValue(":ACTION", action);
                    update.bindValue(":HOSTNAME", hostname);
                    update.bindValue(":DEFAULT_KEYS", default_keys);
                    if (!update.exec())
                         MythDB::DBError("Unable to update keybindings",
                                         update);

                    keylist = "";
                    action = "SEEKRWND";
                    default_keys = "Left";

                    update.bindValue(":KEYS", keylist);
                    update.bindValue(":ACTION", action);
                    update.bindValue(":HOSTNAME", hostname);
                    update.bindValue(":DEFAULT_KEYS", default_keys);
                    if (!update.exec())
                         MythDB::DBError("Unable to update keybindings",
                                         update);

                    keylist = ">,.,Right";
                    action = "FFWDSTICKY";
                    default_keys = ">,.";

                    update.bindValue(":KEYS", keylist);
                    update.bindValue(":ACTION", action);
                    update.bindValue(":HOSTNAME", hostname);
                    update.bindValue(":DEFAULT_KEYS", default_keys);
                    if (!update.exec())
                         MythDB::DBError("Unable to update keybindings",
                                         update);

                    keylist = ",,<,Left";
                    action = "RWNDSTICKY";
                    default_keys = ",,<";

                    update.bindValue(":KEYS", keylist);
                    update.bindValue(":ACTION", action);
                    update.bindValue(":HOSTNAME", hostname);
                    update.bindValue(":DEFAULT_KEYS", default_keys);
                    if (!update.exec())
                         MythDB::DBError("Unable to update keybindings",
                                         update);
                }
            }
        }

        if (!UpdateDBVersionNumber("1250", dbver))
            return false;
    }

    if (dbver == "1250")
    {
       const char *updates[] = {
"UPDATE recorded SET bookmark = 1 WHERE bookmark != 0;",
nullptr
};
        if (!performActualUpdate(updates, "1251", dbver))
            return false;
    }

    if (dbver == "1251")
    {
        LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1252");

        MSqlQuery query(MSqlQuery::InitCon());
        query.prepare("SHOW INDEX FROM recgrouppassword");

        if (!query.exec())
        {
            MythDB::DBError("Unable to retrieve current indices on "
                            "recgrouppassword.", query);
        }
        else
        {
            while (query.next())
            {
                QString index_name = query.value(2).toString();

                if ("recgroup" == index_name)
                {
                    MSqlQuery update(MSqlQuery::InitCon());
                    update.prepare("ALTER TABLE recgrouppassword "
                                   " DROP INDEX recgroup");

                    if (!update.exec())
                         MythDB::DBError("Unable to drop duplicate index on "
                                         "recgrouppassword. Ignoring.",
                                         update);
                    break;
                }
            }
        }

        if (!UpdateDBVersionNumber("1252", dbver))
            return false;
    }

    if (dbver == "1252")
    {
        LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1253");

        MSqlQuery select(MSqlQuery::InitCon());
        select.prepare("SELECT hostname, data FROM settings "
                       " WHERE value = 'StickyKeys'");

        if (!select.exec())
        {
            MythDB::DBError("Unable to retrieve StickyKeys values.", select);
        }
        else
        {
            MSqlQuery update(MSqlQuery::InitCon());
            while (select.next())
            {
                QString hostname = select.value(0).toString();
                QString sticky_keys = select.value(1).toString();

                if ("1" == sticky_keys)
                {
                    // Only remap the keys if they're currently set to defaults
                    update.prepare("UPDATE keybindings "
                                   "   SET keylist  = :KEYS "
                                   " WHERE context  = 'TV Playback' AND "
                                   "       action   = :ACTION AND "
                                   "       hostname = :HOSTNAME AND "
                                   "       keylist  = :DEFAULT_KEYS");

                    QString keylist = ">,.";
                    QString action = "FFWDSTICKY";
                    QString default_keys = ">,.,Right";

                    update.bindValue(":KEYS", keylist);
                    update.bindValue(":ACTION", action);
                    update.bindValue(":HOSTNAME", hostname);
                    update.bindValue(":DEFAULT_KEYS", default_keys);
                    if (!update.exec())
                         MythDB::DBError("Unable to update keybindings",
                                         update);

                    keylist = ",,<";
                    action = "RWNDSTICKY";
                    default_keys = ",,<,Left";

                    update.bindValue(":KEYS", keylist);
                    update.bindValue(":ACTION", action);
                    update.bindValue(":HOSTNAME", hostname);
                    update.bindValue(":DEFAULT_KEYS", default_keys);
                    if (!update.exec())
                         MythDB::DBError("Unable to update keybindings",
                                         update);
                }
            }
        }

        if (!UpdateDBVersionNumber("1253", dbver))
            return false;
    }

    if (dbver == "1253")
    {
        if (gCoreContext->GetNumSetting("have-nit-fix") == 1)
        {
            // User has previously applied patch from ticket #7486.
            LOG(VB_GENERAL, LOG_CRIT,
                "Upgrading to MythTV schema version 1254");
            if (!UpdateDBVersionNumber("1254", dbver))
                return false;
        }
        else
        {
            const char *updates[] = {
                "ALTER TABLE videosource ADD dvb_nit_id INT(6) DEFAULT -1;",
                nullptr
            };
            if (!performActualUpdate(updates, "1254", dbver))
                return false;
        }
    }

    if (dbver == "1254")
    {
       const char *updates[] = {
"ALTER TABLE cardinput DROP COLUMN shareable;",
nullptr
};
        if (!performActualUpdate(updates, "1255", dbver))
            return false;
    }

    if (dbver == "1255")
    {
        const char *updates[] = {
"INSERT INTO keybindings (SELECT 'Main Menu', 'EXIT', 'System Exit', "
    "(CASE data WHEN '1' THEN 'Ctrl+Esc' WHEN '2' THEN 'Meta+Esc' "
    "WHEN '3' THEN 'Alt+Esc' WHEN '4' THEN 'Esc' ELSE '' END), hostname "
    "FROM settings WHERE value = 'AllowQuitShutdown' GROUP BY hostname) "
    "ON DUPLICATE KEY UPDATE keylist = VALUES(keylist);",
nullptr
};
        if (!performActualUpdate(updates, "1256", dbver))
            return false;
    }

    if (dbver == "1256")
    {
        const char *updates[] = {
"ALTER TABLE record DROP COLUMN tsdefault;",
nullptr
};
        if (!performActualUpdate(updates, "1257", dbver))
            return false;
    }

    if (dbver == "1257")
    {
        const char *updates[] = {
"CREATE TABLE internetcontent "
"( name VARCHAR(255) NOT NULL,"
"  thumbnail VARCHAR(255),"
"  type SMALLINT(3) NOT NULL,"
"  author VARCHAR(128) NOT NULL,"
"  description TEXT NOT NULL,"
"  commandline TEXT NOT NULL,"
"  version DOUBLE NOT NULL,"
"  updated DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  search BOOL NOT NULL,"
"  tree BOOL NOT NULL,"
"  podcast BOOL NOT NULL,"
"  download BOOL NOT NULL,"
"  host  VARCHAR(128)) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE internetcontentarticles "
"( feedtitle VARCHAR(255) NOT NULL,"
"  path TEXT NOT NULL,"
"  paththumb TEXT NOT NULL,"
"  title VARCHAR(255) NOT NULL,"
"  subtitle VARCHAR(255) NOT NULL,"
"  season SMALLINT(5) NOT NULL DEFAULT '0',"
"  episode SMALLINT(5) NOT NULL DEFAULT '0',"
"  description TEXT NOT NULL,"
"  url TEXT NOT NULL,"
"  type SMALLINT(3) NOT NULL,"
"  thumbnail TEXT NOT NULL,"
"  mediaURL TEXT NOT NULL,"
"  author VARCHAR(255) NOT NULL,"
"  date DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  time INT NOT NULL,"
"  rating VARCHAR(255) NOT NULL,"
"  filesize BIGINT NOT NULL,"
"  player VARCHAR(255) NOT NULL,"
"  playerargs TEXT NOT NULL,"
"  download VARCHAR(255) NOT NULL,"
"  downloadargs TEXT NOT NULL,"
"  width SMALLINT NOT NULL,"
"  height SMALLINT NOT NULL,"
"  language VARCHAR(128) NOT NULL,"
"  podcast BOOL NOT NULL,"
"  downloadable BOOL NOT NULL,"
"  customhtml BOOL NOT NULL,"
"  countries VARCHAR(255) NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
nullptr
};
        if (!performActualUpdate(updates, "1258", dbver))
            return false;
    }

    if (dbver == "1258")
    {
        LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1259");

        MSqlQuery select(MSqlQuery::InitCon());
        select.prepare("SELECT hostname, data FROM settings "
                       " WHERE value = 'IndividualMuteControl'");

        if (!select.exec())
        {
            MythDB::DBError("Unable to retrieve IndividualMuteControl values.",
                            select);
            return false;
        }
        else
        {
            MSqlQuery update(MSqlQuery::InitCon());
            while (select.next())
            {
                QString hostname = select.value(0).toString();
                QString individual_mute = select.value(1).toString();

                if ("1" == individual_mute)
                {
                    update.prepare("DELETE FROM keybindings "
                                   " WHERE action = 'CYCLEAUDIOCHAN' AND "
                                   "       hostname = :HOSTNAME AND "
                                   "       context IN ('TV Frontend', "
                                   "                   'TV Playback')");

                    update.bindValue(":HOSTNAME", hostname);

                    if (!update.exec())
                    {
                        MythDB::DBError("Unable to update keybindings",
                                         update);
                        return false;
                    }

                    update.prepare("UPDATE keybindings "
                                   "   SET action = 'CYCLEAUDIOCHAN', "
                                   "       description = 'Cycle audio channels'"
                                   " WHERE action = 'MUTE' AND "
                                   "       hostname = :HOSTNAME AND "
                                   "       context IN ('TV Frontend', "
                                   "                   'TV Playback')");

                    update.bindValue(":HOSTNAME", hostname);

                    if (!update.exec())
                    {
                        MythDB::DBError("Unable to update keybindings",
                                         update);
                        return false;
                    }

                    update.prepare("REPLACE INTO keybindings "
                                   " VALUES (:CONTEXT, 'MUTE', 'Mute', "
                                   "         '', :HOSTNAME)");

                    update.bindValue(":CONTEXT", "TV Playback");
                    update.bindValue(":HOSTNAME", hostname);
                    if (!update.exec())
                    {
                        MythDB::DBError("Unable to update keybindings",
                                         update);
                        return false;
                    }
                    update.bindValue(":CONTEXT", "TV Frontend");
                    update.bindValue(":HOSTNAME", hostname);
                    if (!update.exec())
                    {
                        MythDB::DBError("Unable to update keybindings",
                                         update);
                        return false;
                    }

                }
            }
        }

        if (!UpdateDBVersionNumber("1259", dbver))
            return false;
    }

    if (dbver == "1259")
    {
        LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1260");

        MSqlQuery query(MSqlQuery::InitCon());
        query.prepare("DELETE FROM keybindings WHERE "
                      "action IN ('PAGEUP','PAGEDOWN') AND "
                      "context = 'TV FRONTEND'");
        if (!query.exec())
        {
            MythDB::DBError("Unable to update keybindings", query);
            return false;
        }

        query.prepare("SELECT data FROM settings "
                       " WHERE value = 'EPGEnableJumpToChannel'");

        if (!query.exec())
        {
            MythDB::DBError("Unable to retrieve EPGEnableJumpToChannel values.",
                            query);
            return false;
        }
        else
        {
            MSqlQuery bindings(MSqlQuery::InitCon());
            while (query.next())
            {
                QString EPGEnableJumpToChannel = query.value(0).toString();

                if ("1" == EPGEnableJumpToChannel)
                {
                    bindings.prepare("SELECT action, context, hostname, keylist "
                                     " FROM keybindings "
                                     " WHERE action IN ('DAYLEFT', "
                                     " 'DAYRIGHT', 'TOGGLEEPGORDER') AND "
                                     " context IN ('TV Frontend', "
                                     " 'TV Playback')");

                    if (!bindings.exec())
                    {
                        MythDB::DBError("Unable to update keybindings",
                                         bindings);
                        return false;
                    }
                    else
                    {
                        while (bindings.next())
                        {
                            QString action = bindings.value(0).toString();
                            QString context = bindings.value(1).toString();
                            QString hostname = bindings.value(2).toString();
                            QStringList oldKeylist = bindings.value(3).toString().split(',');
                            QStringList newKeyList;

                            QStringList::iterator it;
                            for (it = oldKeylist.begin(); it != oldKeylist.end();++it)
                            {
                                bool ok = false;
                                int num = (*it).toInt(&ok);
                                if (!ok && num >= 0 && num <= 9)
                                    newKeyList << (*it);
                            }
                            QString keyList = newKeyList.join(",");

                            MSqlQuery update(MSqlQuery::InitCon());
                            update.prepare("UPDATE keybindings "
                                           "   SET keylist = :KEYLIST "
                                           " WHERE action = :ACTION "
                                           " AND   context = :CONTEXT "
                                           " AND   hostname = :HOSTNAME");

                            update.bindValue(":KEYLIST", keyList);
                            update.bindValue(":ACTION", action);
                            update.bindValue(":CONTEXT", context);
                            update.bindValue(":HOSTNAME", hostname);

                            if (!update.exec())
                            {
                                MythDB::DBError("Unable to update keybindings",
                                                update);
                                return false;
                            }
                        }
                    }

                }
            }
        }

        if (!UpdateDBVersionNumber("1260", dbver))
            return false;
    }

    if (dbver == "1260")
    {
        if (gCoreContext->GetBoolSetting("MythFillFixProgramIDsHasRunOnce", false))
        {
            LOG(VB_GENERAL, LOG_CRIT,
                "Upgrading to MythTV schema version 1261");
            if (!UpdateDBVersionNumber("1261", dbver))
                return false;
        }
        else
        {

            const char *updates[] = {
"UPDATE recorded SET programid=CONCAT(SUBSTRING(programid, 1, 2), '00', "
"       SUBSTRING(programid, 3)) WHERE length(programid) = 12;",
"UPDATE oldrecorded SET programid=CONCAT(SUBSTRING(programid, 1, 2), '00', "
"       SUBSTRING(programid, 3)) WHERE length(programid) = 12;",
"UPDATE program SET programid=CONCAT(SUBSTRING(programid, 1, 2), '00', "
"       SUBSTRING(programid, 3)) WHERE length(programid) = 12;",
nullptr
};
            if (!performActualUpdate(updates, "1261", dbver))
                return false;
        }
    }

    if (dbver == "1261")
    {
        const char *updates[] = {
"UPDATE program SET description = '' WHERE description IS NULL;",
"UPDATE record SET description = '' WHERE description IS NULL;",
"UPDATE recorded SET description = '' WHERE description IS NULL;",
"UPDATE recordedprogram SET description = '' WHERE description IS NULL;",
"UPDATE oldrecorded SET description = '' WHERE description IS NULL;",
"UPDATE mythlog SET details = '' WHERE details IS NULL;",
"UPDATE settings SET data = '' WHERE data IS NULL;",
"UPDATE powerpriority SET selectclause = '' WHERE selectclause IS NULL;",
"UPDATE customexample SET fromclause = '' WHERE fromclause IS NULL;",
"UPDATE customexample SET whereclause = '' WHERE whereclause IS NULL;",
"ALTER TABLE program MODIFY COLUMN description VARCHAR(16000) "
"    NOT NULL default '';",
"ALTER TABLE record MODIFY COLUMN description VARCHAR(16000) "
"    NOT NULL default '';",
"ALTER TABLE recorded MODIFY COLUMN description VARCHAR(16000) "
"    NOT NULL default '';",
"ALTER TABLE recordedprogram MODIFY COLUMN description VARCHAR(16000) "
"    NOT NULL default '';",
"ALTER TABLE oldrecorded MODIFY COLUMN description VARCHAR(16000) "
"    NOT NULL default '';",
"ALTER TABLE mythlog MODIFY COLUMN details VARCHAR(16000) "
"    NOT NULL default '';",
"ALTER TABLE settings MODIFY COLUMN data VARCHAR(16000) "
"    NOT NULL default '';",
"ALTER TABLE powerpriority MODIFY COLUMN selectclause VARCHAR(16000) "
"    NOT NULL default '';",
"ALTER TABLE customexample MODIFY COLUMN fromclause VARCHAR(10000) "
"    NOT NULL default '';",
"ALTER TABLE customexample MODIFY COLUMN whereclause VARCHAR(10000) "
"    NOT NULL default '';",
nullptr
};
        if (!performActualUpdate(updates, "1262", dbver))
            return false;
    }

    if (dbver == "1262")
    {
        const char *updates[] = {
"INSERT INTO recgrouppassword (recgroup, password) SELECT 'All Programs',data FROM settings WHERE value='AllRecGroupPassword' LIMIT 1;",
"DELETE FROM settings WHERE value='AllRecGroupPassword';",
nullptr
};
        if (!performActualUpdate(updates, "1263", dbver))
            return false;
    }

    if (dbver == "1263")
    {
        const char *updates[] = {
"UPDATE settings SET hostname = NULL WHERE value='ISO639Language0' AND data != 'aar' AND hostname IS NOT NULL LIMIT 1;",
"UPDATE settings SET hostname = NULL WHERE value='ISO639Language1' AND data != 'aar' AND hostname IS NOT NULL LIMIT 1;",
"DELETE FROM settings WHERE value='ISO639Language0' AND hostname IS NOT NULL;",
"DELETE FROM settings WHERE value='ISO639Language1' AND hostname IS NOT NULL;",
nullptr
};
        if (!performActualUpdate(updates, "1264", dbver))
            return false;
    }

    if (dbver == "1264")
    {
        const char *updates[] = {
"DELETE FROM displayprofiles WHERE profilegroupid IN "
"  (SELECT profilegroupid FROM displayprofilegroups "
"    WHERE name IN ('CPU++', 'CPU+', 'CPU--'))",
"DELETE FROM displayprofilegroups WHERE name IN ('CPU++', 'CPU+', 'CPU--')",
"DELETE FROM settings WHERE value = 'DefaultVideoPlaybackProfile' "
"   AND data IN ('CPU++', 'CPU+', 'CPU--')",
"UPDATE displayprofiles SET data = 'ffmpeg' WHERE data = 'libmpeg2'",
"UPDATE displayprofiles SET data = 'ffmpeg' WHERE data = 'xvmc'",
"UPDATE displayprofiles SET data = 'xv-blit' WHERE data = 'xvmc-blit'",
"UPDATE displayprofiles SET data = 'softblend' WHERE data = 'ia44blend'",
nullptr
};
        if (!performActualUpdate(updates, "1265", dbver))
            return false;
    }

    if (dbver == "1265")
    {
        const char *updates[] = {
"ALTER TABLE dtv_multiplex MODIFY COLUMN updatetimestamp "
"  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;",
"ALTER TABLE dvdbookmark MODIFY COLUMN `timestamp` "
"  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;",
"ALTER TABLE jobqueue MODIFY COLUMN statustime "
"  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;",
"ALTER TABLE recorded MODIFY COLUMN lastmodified "
"  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;",
nullptr
};
        if (!performActualUpdate(updates, "1266", dbver))
            return false;
    }

    if (dbver == "1266")
    {
        if (!doUpgradeVideoDatabaseSchema())
            return false;

        const char *updates[] = {
"DELETE FROM settings WHERE value = 'mythvideo.DBSchemaVer'",
nullptr
};
        if (!performActualUpdate(updates, "1267", dbver))
            return false;
    }

    if (dbver == "1267")
    {
        const char *updates[] = {
"ALTER TABLE channel MODIFY xmltvid VARCHAR(255) NOT NULL DEFAULT '';",
nullptr
};
        if (!performActualUpdate(updates, "1268", dbver))
            return false;
    }

    if (dbver == "1268")
    {

        const char *updates[] = {
"DELETE FROM keybindings WHERE action='PREVSOURCE' AND keylist='Ctrl+Y';",
nullptr
};
        if (!performActualUpdate(updates, "1269", dbver))
            return false;
    }

    if (dbver == "1269")
    {
        const char *updates[] = {
"DELETE FROM profilegroups WHERE id >= 15;",
"DELETE FROM recordingprofiles WHERE profilegroup >= 15;",
"INSERT INTO profilegroups SET id = '15', name = 'ASI Recorder (DVEO)',"
" cardtype = 'ASI', is_default = 1;",
"INSERT INTO recordingprofiles SET name = \"Default\", profilegroup = 15;",
"INSERT INTO recordingprofiles SET name = \"Live TV\", profilegroup = 15;",
"INSERT INTO recordingprofiles SET name = \"High Quality\", profilegroup = 15;",
"INSERT INTO recordingprofiles SET name = \"Low Quality\", profilegroup = 15;",
"INSERT INTO profilegroups SET id = '16', name = 'OCUR Recorder (CableLabs)',"
" cardtype = 'OCUR', is_default = 1;",
"INSERT INTO recordingprofiles SET name = \"Default\", profilegroup = 16;",
"INSERT INTO recordingprofiles SET name = \"Live TV\", profilegroup = 16;",
"INSERT INTO recordingprofiles SET name = \"High Quality\", profilegroup = 16;",
"INSERT INTO recordingprofiles SET name = \"Low Quality\", profilegroup = 16;",
nullptr
};
        if (!performActualUpdate(updates, "1270", dbver))
            return false;
    }

    if (dbver == "1270")
    {
        const char *updates[] = {
"ALTER TABLE oldrecorded ADD future TINYINT(1) NOT NULL DEFAULT 0;",
"UPDATE oldrecorded SET future=0;",
nullptr
};
        if (!performActualUpdate(updates, "1271", dbver))
            return false;
    }

    if (dbver == "1271")
    {
        const char *updates[] = {
"ALTER TABLE recordmatch MODIFY recordid INT UNSIGNED NOT NULL;",
"ALTER TABLE recordmatch MODIFY chanid INT UNSIGNED NOT NULL;",
"ALTER TABLE recordmatch MODIFY starttime DATETIME NOT NULL;",
"ALTER TABLE recordmatch MODIFY manualid INT UNSIGNED NOT NULL;",
"ALTER TABLE recordmatch ADD INDEX (starttime, chanid);",
"ALTER TABLE oldrecorded MODIFY generic TINYINT(1) NOT NULL;",
"ALTER TABLE oldrecorded ADD INDEX (future);",
"ALTER TABLE oldrecorded ADD INDEX (starttime, chanid);",
nullptr
};
        if (!performActualUpdate(updates, "1272", dbver))
            return false;
    }

    if (dbver == "1272")
    {
        const char *updates[] = {
"DROP INDEX starttime ON recordmatch;",
"DROP INDEX starttime ON oldrecorded;",
"ALTER TABLE recordmatch ADD INDEX (chanid, starttime, manualid);",
"ALTER TABLE oldrecorded ADD INDEX (chanid, starttime);",
nullptr
};
        if (!performActualUpdate(updates, "1273", dbver))
            return false;
    }

    if (dbver == "1273")
    {
        const char *updates[] = {
"ALTER TABLE internetcontent MODIFY COLUMN updated "
"  DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00';",
"ALTER TABLE internetcontentarticles MODIFY COLUMN `date` "
"  DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00';",
nullptr
};

        if (!performActualUpdate(updates, "1274", dbver))
            return false;
    }

    if (dbver == "1274")
    {
        const char *updates[] = {
"UPDATE cardinput SET tunechan=NULL"
"  WHERE inputname='DVBInput' OR inputname='MPEG2TS';"
"UPDATE dtv_multiplex SET symbolrate = NULL"
"  WHERE modulation LIKE 't%' OR modulation LIKE '%t';",
"UPDATE dtv_multiplex"
"  SET bandwidth=SUBSTR(modulation,2,1)"
"  WHERE SUBSTR(modulation,3,3)='qam' OR"
"        SUBSTR(modulation,3,4)='qpsk';",
"UPDATE dtv_multiplex"
"  SET bandwidth=SUBSTR(modulation,5,1)"
"  WHERE SUBSTR(modulation,1,4)='auto' AND"
"        LENGTH(modulation)=6;",
"UPDATE dtv_multiplex SET modulation='auto'"
"  WHERE modulation LIKE 'auto%';",
"UPDATE dtv_multiplex SET modulation='qam_16'"
"  WHERE modulation LIKE '%qam16%';",
"UPDATE dtv_multiplex SET modulation='qam_32'"
"  WHERE modulation LIKE '%qam32%';",
"UPDATE dtv_multiplex SET modulation='qam_64'"
"  WHERE modulation LIKE '%qam64%';",
"UPDATE dtv_multiplex SET modulation='qam_128'"
"  WHERE modulation LIKE '%qam128%';",
"UPDATE dtv_multiplex SET modulation='qam_256'"
"  WHERE modulation LIKE '%qam256%';",
nullptr
};
        if (!performActualUpdate(updates, "1275", dbver))
            return false;
    }

    if (dbver == "1275")
    {
        const char *updates[] = {
"DROP TABLE IF EXISTS `logging`;",
"CREATE TABLE `logging` ( "
"  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, "
"  `host` varchar(64) NOT NULL, "
"  `application` varchar(64) NOT NULL, "
"  `pid` int(11) NOT NULL, "
"  `thread` varchar(64) NOT NULL, "
"  `msgtime` datetime NOT NULL, "
"  `level` int(11) NOT NULL, "
"  `message` varchar(2048) NOT NULL, "
"  PRIMARY KEY (`id`), "
"  KEY `host` (`host`,`application`,`pid`,`msgtime`), "
"  KEY `msgtime` (`msgtime`), "
"  KEY `level` (`level`) "
") ENGINE=MyISAM DEFAULT CHARSET=utf8; ",
nullptr
};
        if (!performActualUpdate(updates, "1276", dbver))
            return false;
    }

    if (dbver == "1276")
    {
        const char *updates[] = {
"ALTER TABLE record ADD COLUMN filter INT UNSIGNED NOT NULL DEFAULT 0;",
"CREATE TABLE IF NOT EXISTS recordfilter ("
"    filterid INT UNSIGNED NOT NULL PRIMARY KEY,"
"    description VARCHAR(64) DEFAULT NULL,"
"    clause VARCHAR(256) DEFAULT NULL,"
"    newruledefault TINYINT(1) DEFAULT 0) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"INSERT INTO recordfilter (filterid, description, clause, newruledefault) "
"    VALUES (0, 'New episode', 'program.previouslyshown = 0', 0);",
"INSERT INTO recordfilter (filterid, description, clause, newruledefault) "
"    VALUES (1, 'Identifiable episode', 'program.generic = 0', 0);",
"INSERT INTO recordfilter (filterid, description, clause, newruledefault) "
"    VALUES (2, 'First showing', 'program.first > 0', 0);",
"INSERT INTO recordfilter (filterid, description, clause, newruledefault) "
"    VALUES (3, 'Primetime', 'HOUR(program.starttime) >= 19 AND HOUR(program.starttime) < 23', 0);",
"INSERT INTO recordfilter (filterid, description, clause, newruledefault) "
"    VALUES (4, 'Commercial free', 'channel.commmethod = -2', 0);",
"INSERT INTO recordfilter (filterid, description, clause, newruledefault) "
"    VALUES (5, 'High definition', 'program.hdtv > 0', 0);",
nullptr
};

        if (!performActualUpdate(updates, "1277", dbver))
            return false;
    }

    if (dbver == "1277")
    {
        const char *updates[] = {
"ALTER TABLE record ADD autometadata TINYINT(1) NOT NULL DEFAULT "
"    0 AFTER autouserjob4;",
"ALTER TABLE record ADD inetref VARCHAR(40) NOT NULL AFTER programid;",
"ALTER TABLE record ADD season SMALLINT(5) NOT NULL AFTER description;",
"ALTER TABLE record ADD episode SMALLINT(5) NOT NULL AFTER season;",
"ALTER TABLE recorded ADD inetref VARCHAR(40) NOT NULL AFTER programid;",
"ALTER TABLE recorded ADD season SMALLINT(5) NOT NULL AFTER description;",
"ALTER TABLE recorded ADD episode SMALLINT(5) NOT NULL AFTER season;",
"ALTER TABLE oldrecorded ADD inetref VARCHAR(40) NOT NULL AFTER programid;",
"ALTER TABLE oldrecorded ADD season SMALLINT(5) NOT NULL AFTER description;",
"ALTER TABLE oldrecorded ADD episode SMALLINT(5) NOT NULL AFTER season;",
nullptr
};
        if (!performActualUpdate(updates, "1278", dbver))
            return false;
    }

    if (dbver == "1278")
    {
        const char *updates[] = {
"CREATE TABLE recordedartwork ( "
"    inetref VARCHAR(255) NOT NULL, "
"    season SMALLINT(5) NOT NULL, "
"    host TEXT NOT NULL, "
"    coverart TEXT NOT NULL, "
"    fanart TEXT NOT NULL, "
"    banner TEXT NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
nullptr
};
        if (!performActualUpdate(updates, "1279", dbver))
            return false;
    }

    if (dbver == "1279")
    {
        LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1280");

        MSqlQuery select(MSqlQuery::InitCon());
        // New DBs/hosts will not have a NoPromptOnExit, so they'll get defaults
        select.prepare("SELECT hostname, data FROM settings "
                       " WHERE value = 'NoPromptOnExit'");
        if (!select.exec())
        {
            MythDB::DBError("Unable to retrieve confirm exit values.", select);
        }
        else
        {
            MSqlQuery update(MSqlQuery::InitCon());
            while (select.next())
            {
                QString hostname = select.value(0).toString();
                // Yes, enabled NoPromptOnExit meant to prompt on exit
                QString prompt_on_exit = select.value(1).toString();
                // Default EXITPROMPT is wrong for all upgrades
                update.prepare("DELETE FROM keybindings "
                               " WHERE action = 'EXITPROMPT' "
                               "   AND context = 'Main Menu' "
                               "   AND hostname = :HOSTNAME ;");
                update.bindValue(":HOSTNAME", hostname);
                if (!update.exec())
                     MythDB::DBError("Unable to delete EXITPROMPT binding",
                                     update);

                if ("0" == prompt_on_exit)
                {
                    // EXIT is already mapped appropriately, so just create a
                    // no-keylist mapping for EXITPROMPT to prevent conflict
                    update.prepare("INSERT INTO keybindings (context, action, "
                                   "        description, keylist, hostname) "
                                   "VALUES ('Main Menu', 'EXITPROMPT', '', "
                                   "        '', :HOSTNAME );");
                    update.bindValue(":HOSTNAME", hostname);
                    if (!update.exec())
                         MythDB::DBError("Unable to create EXITPROMPT binding",
                                         update);
                }
                else
                {
                    // EXIT must be changed to EXITPROMPT
                    update.prepare("UPDATE keybindings "
                                   "   SET action = 'EXITPROMPT' "
                                   " WHERE action = 'EXIT' "
                                   "   AND context = 'Main Menu' "
                                   "   AND hostname = :HOSTNAME ;");
                    update.bindValue(":HOSTNAME", hostname);
                    if (!update.exec())
                         MythDB::DBError("Unable to update EXITPROMPT binding",
                                         update);
                }
            }
        }

        if (!UpdateDBVersionNumber("1280", dbver))
            return false;
    }

    if (dbver == "1280")
    {
        const char *updates[] = {
"ALTER TABLE program ADD INDEX (subtitle);",
"ALTER TABLE program ADD INDEX (description(255));",
"ALTER TABLE oldrecorded ADD INDEX (subtitle);",
"ALTER TABLE oldrecorded ADD INDEX (description(255));",
nullptr
};
        if (!performActualUpdate(updates, "1281", dbver))
            return false;
    }

    if (dbver == "1281")
    {
        const char *updates[] = {
"ALTER TABLE cardinput ADD changer_device VARCHAR(128) "
"AFTER externalcommand;",
"ALTER TABLE cardinput ADD changer_model VARCHAR(128) "
"AFTER changer_device;",
nullptr
};
        if (!performActualUpdate(updates, "1282", dbver))
            return false;
    }

    if (dbver == "1282")
    {
        const char *updates[] = {
"UPDATE settings"
"   SET data = SUBSTR(data, INSTR(data, 'share/mythtv/metadata')+13)"
" WHERE value "
"    IN ('TelevisionGrabber', "
"        'MovieGrabber', "
"        'mythgame.MetadataGrabber');",
nullptr
};

        if (!performActualUpdate(updates, "1283", dbver))
            return false;
    }

    if (dbver == "1283")
    {
        const char *updates[] = {
"UPDATE record SET filter = filter | 1 WHERE record.dupin & 0x20",
"UPDATE record SET filter = filter | 2 WHERE record.dupin & 0x40",
"UPDATE record SET filter = filter | 5 WHERE record.dupin & 0x80",
"UPDATE record SET dupin = dupin & ~0xe0",
"INSERT INTO recordfilter (filterid, description, clause, newruledefault) "
"    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);",
nullptr
};

        if (!performActualUpdate(updates, "1284", dbver))
            return false;
    }

    if (dbver == "1284")
    {
        const char *updates[] = {
"REPLACE INTO recordfilter (filterid, description, clause, newruledefault) "
"    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);",
nullptr
};

        if (!performActualUpdate(updates, "1285", dbver))
            return false;
    }

    if (dbver == "1285")
    {
        const char *updates[] = {
"DELETE FROM profilegroups WHERE id >= 17;",
"DELETE FROM recordingprofiles WHERE profilegroup >= 17;",
"INSERT INTO profilegroups SET id = '17', name = 'Ceton Recorder',"
" cardtype = 'CETON', is_default = 1;",
"INSERT INTO recordingprofiles SET name = \"Default\", profilegroup = 17;",
"INSERT INTO recordingprofiles SET name = \"Live TV\", profilegroup = 17;",
"INSERT INTO recordingprofiles SET name = \"High Quality\", profilegroup = 17;",
"INSERT INTO recordingprofiles SET name = \"Low Quality\", profilegroup = 17;",
nullptr
};
        if (!performActualUpdate(updates, "1286", dbver))
            return false;
    }

    if (dbver == "1286")
    {
        LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1287");
        MSqlQuery query(MSqlQuery::InitCon());
        query.prepare("SELECT cardid, videodevice "
                      "FROM capturecard "
                      "WHERE cardtype='CETON'");
        if (!query.exec())
        {
            LOG(VB_GENERAL, LOG_ERR,
                "Unable to query capturecard table for upgrade to 1287.");
            return false;
        }

        MSqlQuery update(MSqlQuery::InitCon());
        update.prepare("UPDATE capturecard SET videodevice=:VIDDEV "
                       "WHERE cardid=:CARDID");
        while (query.next())
        {
            uint cardid = query.value(0).toUInt();
            QString videodevice = query.value(1).toString();
            QStringList parts = videodevice.split("-");
            if (parts.size() != 2)
            {
                LOG(VB_GENERAL, LOG_ERR,
                    "Unable to parse videodevice in upgrade to 1287.");
                return false;
            }
            if (parts[1].contains("."))
                continue; // already in new format, skip it..

            int input = max(parts[1].toInt() - 1, 0);
            videodevice = parts[0] + QString("-0.%1").arg(input);
            update.bindValue(":CARDID", cardid);
            update.bindValue(":VIDDEV", videodevice);
            if (!update.exec())
            {
                LOG(VB_GENERAL, LOG_ERR,
                    "Failed to update videodevice in upgrade to 1287.");
                return false;
            }
        }

        if (!UpdateDBVersionNumber("1287", dbver))
            return false;
    }

    if (dbver == "1287")
    {
        const char *updates[] = {
"CREATE TABLE IF NOT EXISTS livestream ( "
"    id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, "
"    width INT UNSIGNED NOT NULL, "
"    height INT UNSIGNED NOT NULL, "
"    bitrate INT UNSIGNED NOT NULL, "
"    audiobitrate INT UNSIGNED NOT NULL, "
"    samplerate INT UNSIGNED NOT NULL, "
"    audioonlybitrate INT UNSIGNED NOT NULL, "
"    segmentsize INT UNSIGNED NOT NULL DEFAULT 10, "
"    maxsegments INT UNSIGNED NOT NULL DEFAULT 0, "
"    startsegment INT UNSIGNED NOT NULL DEFAULT 0, "
"    currentsegment INT UNSIGNED NOT NULL DEFAULT 0, "
"    segmentcount INT UNSIGNED NOT NULL DEFAULT 0, "
"    percentcomplete INT UNSIGNED NOT NULL DEFAULT 0, "
"    created DATETIME NOT NULL, "
"    lastmodified DATETIME NOT NULL, "
"    relativeurl VARCHAR(512) NOT NULL, "
"    fullurl VARCHAR(1024) NOT NULL, "
"    status INT UNSIGNED NOT NULL DEFAULT 0, "
"    statusmessage VARCHAR(256) NOT NULL, "
"    sourcefile VARCHAR(512) NOT NULL, "
"    sourcehost VARCHAR(64) NOT NULL, "
"    sourcewidth INT UNSIGNED NOT NULL DEFAULT 0, "
"    sourceheight INT UNSIGNED NOT NULL DEFAULT 0, "
"    outdir VARCHAR(256) NOT NULL, "
"    outbase VARCHAR(128) NOT NULL "
") ENGINE=MyISAM DEFAULT CHARSET=utf8; ",
nullptr
};

        if (!performActualUpdate(updates, "1288", dbver))
            return false;
    }

    if (dbver == "1288")
    {
        const char *updates[] = {
"ALTER TABLE recordedprogram CHANGE COLUMN videoprop videoprop "
"    SET('HDTV', 'WIDESCREEN', 'AVC', '720', '1080', 'DAMAGED') NOT NULL; ",
nullptr
};
        if (!performActualUpdate(updates, "1289", dbver))
            return false;
    }

    if (dbver == "1289")
    {
        const char *updates[] = {
"DROP TABLE IF EXISTS netvisionrssitems;",
"DROP TABLE IF EXISTS netvisionsearchgrabbers;",
"DROP TABLE IF EXISTS netvisionsites;",
"DROP TABLE IF EXISTS netvisiontreegrabbers;",
"DROP TABLE IF EXISTS netvisiontreeitems;",
nullptr
};

        if (!performActualUpdate(updates, "1290", dbver))
            return false;
    }

    if (dbver == "1290")
    {
        const char *updates[] = {
"ALTER TABLE logging "
" ALTER COLUMN host SET DEFAULT '', "
" ALTER COLUMN application SET DEFAULT '', "
" ALTER COLUMN pid SET DEFAULT '0', "
" ALTER COLUMN thread SET DEFAULT '', "
" ALTER COLUMN level SET DEFAULT '0';",
"ALTER TABLE logging "
" ADD COLUMN tid INT(11) NOT NULL DEFAULT '0' AFTER pid, "
" ADD COLUMN filename VARCHAR(255) NOT NULL DEFAULT '' AFTER thread, "
" ADD COLUMN line INT(11) NOT NULL DEFAULT '0' AFTER filename, "
" ADD COLUMN function VARCHAR(255) NOT NULL DEFAULT '' AFTER line;",
nullptr
};

        if (!performActualUpdate(updates, "1291", dbver))
            return false;
    }

    if (dbver == "1291")
    {
        const char *updates[] = {
"UPDATE recorded r, recordedprogram rp SET r.duplicate=0 "
"   WHERE r.chanid=rp.chanid AND r.progstart=rp.starttime AND "
"      FIND_IN_SET('DAMAGED', rp.videoprop);",
nullptr
};

        if (!performActualUpdate(updates, "1292", dbver))
            return false;
    }

    if (dbver == "1292")
    {
        const char *updates[] = {
"ALTER TABLE cardinput "
"  ADD COLUMN schedorder INT(10) UNSIGNED NOT NULL DEFAULT '0', "
"  ADD COLUMN livetvorder INT(10) UNSIGNED NOT NULL DEFAULT '0';",
"UPDATE cardinput SET schedorder = cardinputid;",
"UPDATE cardinput SET livetvorder = cardid;",
nullptr
};

        if (gCoreContext->GetBoolSetting("LastFreeCard", false))
        {
            updates[2] =
                "UPDATE cardinput SET livetvorder = "
                "  (SELECT MAX(cardid) FROM capturecard) - cardid + 1;";
        }

        if (!performActualUpdate(updates, "1293", dbver))
            return false;
    }

    if (dbver == "1293")
    {
        const char *updates[] = {
"TRUNCATE TABLE recordmatch",
"ALTER TABLE recordmatch DROP INDEX recordid",
"ALTER TABLE recordmatch ADD UNIQUE INDEX (recordid, chanid, starttime)",
"UPDATE recordfilter SET description='Prime time' WHERE filterid=3",
"UPDATE recordfilter SET description='This episode' WHERE filterid=6",
"REPLACE INTO recordfilter (filterid, description, clause, newruledefault) "
"    VALUES (7, 'This series', '(RECTABLE.seriesid <> '''' AND program.seriesid = RECTABLE.seriesid)', 0);",
nullptr
};

        if (!performActualUpdate(updates, "1294", dbver))
            return false;
    }

    if (dbver == "1294")
    {
        const char *updates[] = {
"CREATE TABLE videocollection ("
"  intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  title varchar(256) NOT NULL,"
"  contenttype set('MOVIE', 'TELEVISION', 'ADULT', 'MUSICVIDEO', 'HOMEVIDEO') NOT NULL default '',"
"  plot text,"
"  network varchar(128) DEFAULT NULL,"
"  inetref varchar(128) NOT NULL,"
"  certification varchar(128) DEFAULT NULL,"
"  genre int(10) unsigned DEFAULT '0',"
"  releasedate date DEFAULT NULL,"
"  language varchar(10) DEFAULT NULL,"
"  status varchar(64) DEFAULT NULL,"
"  rating float DEFAULT 0,"
"  ratingcount int(10) DEFAULT 0,"
"  runtime smallint(5) unsigned DEFAULT '0',"
"  banner text,"
"  fanart text,"
"  coverart text,"
"  PRIMARY KEY (intid),"
"  KEY title (title)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE videopathinfo ("
"  intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  path text,"
"  contenttype set('MOVIE', 'TELEVISION', 'ADULT', 'MUSICVIDEO', 'HOMEVIDEO') NOT NULL default '',"
"  collectionref int(10) default '0',"
"  recurse tinyint(1) default '0',"
"  PRIMARY KEY (intid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"ALTER TABLE videometadata ADD collectionref int(10) NOT NULL DEFAULT '0' AFTER inetref;",
"ALTER TABLE videometadata ADD playcount int(10) NOT NULL DEFAULT '0' AFTER length;",
"ALTER TABLE videometadata ADD contenttype set('MOVIE', 'TELEVISION', 'ADULT', 'MUSICVIDEO', 'HOMEVIDEO') NOT NULL default ''",
"UPDATE videometadata SET contenttype = 'MOVIE';",
"UPDATE videometadata SET contenttype = 'TELEVISION' WHERE season > 0 OR episode > 0;",
nullptr
};

        if (!performActualUpdate(updates, "1295", dbver))
            return false;
    }

    if (dbver == "1295")
    {
        LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1296");
        MSqlQuery query(MSqlQuery::InitCon());
        query.prepare("SELECT data, hostname "
                      "FROM settings "
                      "WHERE value='BackendServerIP'");
        if (!query.exec())
        {
            LOG(VB_GENERAL, LOG_ERR,
                "Unable to repair IP addresses for IPv4/IPv6 split.");
            return false;
        }

        MSqlQuery update(MSqlQuery::InitCon()), insert(MSqlQuery::InitCon());
        update.prepare("UPDATE settings "
                          "SET data=:IP4ADDY "
                       "WHERE value='BackendServerIP' "
                      "AND hostname=:HOSTNAME");
        insert.prepare("INSERT INTO settings "
                       "SET value='BackendServerIP6',"
                            "data=:IP6ADDY,"
                        "hostname=:HOSTNAME");
        while (query.next())
        {
            QHostAddress oldaddr(query.value(0).toString());
            QString hostname = query.value(1).toString();

            update.bindValue(":HOSTNAME", hostname);
            insert.bindValue(":HOSTNAME", hostname);

            if (oldaddr.protocol() == QAbstractSocket::IPv6Protocol)
            {
                update.bindValue(":IP4ADDY", "127.0.0.1");
                insert.bindValue(":IP6ADDY", query.value(0).toString());
            }
            else if (oldaddr.protocol() == QAbstractSocket::IPv4Protocol)
            {
                update.bindValue(":IP4ADDY", query.value(0).toString());
                insert.bindValue(":IP6ADDY", "::1");
            }
            else
            {
                update.bindValue(":IP4ADDY", "127.0.0.1");
                insert.bindValue(":IP6ADDY", "::1");
                LOG(VB_GENERAL, LOG_CRIT,
                    QString("Invalid address string '%1' found on %2. "
                            "Reverting to localhost defaults.")
                        .arg(query.value(0).toString()).arg(hostname));
            }

            if (!update.exec() || !insert.exec())
            {
                LOG(VB_GENERAL, LOG_ERR, QString("Failed to separate IPv4 "
                          "and IPv6 addresses for %1").arg(hostname));
                return false;
            }

        }

        if (!UpdateDBVersionNumber("1296", dbver))
            return false;
    }

    if (dbver == "1296")
    {
        const char *updates[] = {
"ALTER TABLE videocollection CHANGE inetref collectionref "
"VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci "
"NOT NULL",
"ALTER TABLE videocollection CHANGE genre genre VARCHAR(128) NULL DEFAULT ''",
nullptr
};

        if (!performActualUpdate(updates, "1297", dbver))
            return false;
    }

    if (dbver == "1297")
    {
        const char *updates[] = {
"ALTER TABLE videometadata CHANGE collectionref collectionref INT(10) "
"NOT NULL DEFAULT -1",
"UPDATE videometadata SET collectionref = '-1'",
nullptr
};

        if (!performActualUpdate(updates, "1298", dbver))
            return false;
    }

    if (dbver == "1298")
    {
        LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1299");

        // DeletedMaxAge setting only exists if the user ever triggered the
        // DeletedExpireOptions TriggeredConfigurationGroup (enabled
        // AutoExpireInsteadOfDelete) and changed DeletedMaxAge from its
        // default of zero, so "reset" it to ensure it's in the database before
        // the update
        QString deletedMaxAge = gCoreContext->GetSetting("DeletedMaxAge", "0");
        gCoreContext->SaveSettingOnHost("DeletedMaxAge", deletedMaxAge, nullptr);

        QString queryStr;
        if (gCoreContext->GetBoolSetting("AutoExpireInsteadOfDelete", false))
        {
            queryStr = "UPDATE settings SET data='-1' WHERE "
                       "value='DeletedMaxAge' AND data='0'";
        }
        else
        {
            queryStr = "UPDATE settings SET data='0' WHERE "
                       "value='DeletedMaxAge'";
        }

        MSqlQuery query(MSqlQuery::InitCon());
        query.prepare(queryStr);
        if (!query.exec())
        {
            MythDB::DBError("Could not perform update for '1299'", query);
            return false;
        }

        if (!UpdateDBVersionNumber("1299", dbver))
            return false;
    }

    if (dbver == "1299")
    {
        const char *updates[] = {
"ALTER TABLE recordmatch ADD COLUMN findid INT NOT NULL DEFAULT 0",
"ALTER TABLE recordmatch ADD INDEX (recordid, findid)",
nullptr
};

        if (!performActualUpdate(updates, "1300", dbver))
            return false;
    }

    if (dbver == "1300")
    {
        const char *updates[] = {
"ALTER TABLE channel ADD COLUMN iptvid SMALLINT(6) UNSIGNED;",
"CREATE TABLE iptv_channel ("
"  iptvid SMALLINT(6) UNSIGNED NOT NULL auto_increment,"
"  chanid INT(10) UNSIGNED NOT NULL,"
"  url TEXT NOT NULL,"
"  type set('data', "
"           'rfc2733-1','rfc2733-2', "
"           'rfc5109-1','rfc5109-2', "
"           'smpte2022-1','smpte2022-2'),"
"  bitrate INT(10) UNSIGNED NOT NULL,"
"  PRIMARY KEY (iptvid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
nullptr
};

        if (!performActualUpdate(updates, "1301", dbver))
            return false;
    }

    if (dbver == "1301")
    {
        LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1302");
        // Create the Default recording rule template
        RecordingRule record;
        record.MakeTemplate("Default");
        record.m_type = kTemplateRecord;
        // Take some defaults from now obsoleted settings.
        record.m_startOffset =
            gCoreContext->GetNumSetting("DefaultStartOffset", 0);
        record.m_endOffset =
            gCoreContext->GetNumSetting("DefaultEndOffset", 0);
        record.m_dupMethod =
            static_cast<RecordingDupMethodType>(
                gCoreContext->GetNumSetting(
                    "prefDupMethod", kDupCheckSubDesc));
        record.m_filter = RecordingRule::GetDefaultFilter();
        record.m_autoExpire =
            gCoreContext->GetBoolSetting("AutoExpireDefault", false);
        record.m_autoCommFlag =
            gCoreContext->GetBoolSetting("AutoCommercialFlag", true);
        record.m_autoTranscode =
            gCoreContext->GetBoolSetting("AutoTranscode", false);
        record.m_transcoder =
            gCoreContext->GetNumSetting(
                "DefaultTranscoder", static_cast<int>(RecordingProfile::TranscoderAutodetect));
        record.m_autoUserJob1 =
            gCoreContext->GetBoolSetting("AutoRunUserJob1", false);
        record.m_autoUserJob2 =
            gCoreContext->GetBoolSetting("AutoRunUserJob2", false);
        record.m_autoUserJob3 =
            gCoreContext->GetBoolSetting("AutoRunUserJob3", false);
        record.m_autoUserJob4 =
            gCoreContext->GetBoolSetting("AutoRunUserJob4", false);
        record.m_autoMetadataLookup =
            gCoreContext->GetBoolSetting("AutoMetadataLookup", true);
        record.Save(false);

        if (!UpdateDBVersionNumber("1302", dbver))
            return false;
    }

    if (dbver == "1302")
    {
        QDateTime loc = QDateTime::currentDateTime();
        QDateTime utc = loc.toUTC();
        loc = QDateTime(loc.date(), loc.time(), Qt::UTC);
        int utc_offset = loc.secsTo(utc) / 60;

        QList<QByteArray> updates_ba;

        // Convert DATE and TIME in record into DATETIME
        const char *pre_sql[] = {
            "CREATE TEMPORARY TABLE recordupdate ("
            "recid INT, starttime DATETIME, endtime DATETIME)",
            "INSERT INTO recordupdate (recid, starttime, endtime) "
            "SELECT recordid, "
            "       CONCAT(startdate, ' ', starttime), "
            "       CONCAT(enddate, ' ', endtime) FROM record",
        };
        for (uint i = 0; i < sizeof(pre_sql)/sizeof(char*); i++)
            updates_ba.push_back(QByteArray(pre_sql[i]));

        // Convert various DATETIME fields from local time to UTC
        if (0 != utc_offset)
        {
            const char *with_endtime[] = {
                "program", "recorded", "oldrecorded", "recordupdate",
            };
            const char *without_endtime[] = {
                "programgenres", "programrating", "credits",
                "jobqueue",
            };
            QString order = (utc_offset > 0) ? "-starttime" : "starttime";

            for (uint i = 0; i < sizeof(with_endtime)/sizeof(char*); i++)
            {
                updates_ba.push_back(
                         QString("UPDATE %1 "
                                 "SET starttime = "
                                 "    CONVERT_TZ(starttime, 'SYSTEM', 'Etc/UTC'), "
                                 "    endtime   = "
                                 "    CONVERT_TZ(endtime, 'SYSTEM', 'Etc/UTC') "
                                 "ORDER BY %4")
                         .arg(with_endtime[i])
                         .arg(order).toLocal8Bit());
            }

            for (uint i = 0; i < sizeof(without_endtime)/sizeof(char*); i++)
            {
                updates_ba.push_back(
                          QString("UPDATE %1 "
                                  "SET starttime = "
                                  "    CONVERT_TZ(starttime, 'SYSTEM', 'Etc/UTC') "
                                  "ORDER BY %3")
                          .arg(without_endtime[i]).arg(order)
                          .toLocal8Bit());
            }

            updates_ba.push_back(
                         QString("UPDATE oldprogram "
                                 "SET airdate = "
                                 "    CONVERT_TZ(airdate, 'SYSTEM', 'Etc/UTC') "
                                 "ORDER BY %3")
                         .arg((utc_offset > 0) ? "-airdate" :
                              "airdate").toLocal8Bit());

            updates_ba.push_back(
                         QString("UPDATE recorded "
                                 "set progstart = "
                                 "    CONVERT_TZ(progstart, 'SYSTEM', 'Etc/UTC'), "
                                 "    progend   = "
                                 "    CONVERT_TZ(progend, 'SYSTEM', 'Etc/UTC') ")
                         .toLocal8Bit());
        }

        // Convert DATETIME back to separate DATE and TIME in record table
        const char *post_sql[] = {
            "UPDATE record, recordupdate "
            "SET record.startdate = DATE(recordupdate.starttime), "
            "    record.starttime = TIME(recordupdate.starttime), "
            "    record.enddate = DATE(recordupdate.endtime), "
            "    record.endtime = TIME(recordupdate.endtime), "
            "    record.last_record = "
            "        CONVERT_TZ(last_record, 'SYSTEM', 'Etc/UTC'), "
            "    record.last_delete = "
            "        CONVERT_TZ(last_delete, 'SYSTEM', 'Etc/UTC') "
            "WHERE recordid = recid",
            "DROP TABLE recordupdate",
        };

        for (uint i = 0; i < sizeof(post_sql)/sizeof(char*); i++)
            updates_ba.push_back(QByteArray(post_sql[i]));

        // Convert update ByteArrays to NULL terminated char**
        QList<QByteArray>::const_iterator it = updates_ba.begin();
        vector<const char*> updates;
        for (; it != updates_ba.end(); ++it)
            updates.push_back((*it).constData());
        updates.push_back(nullptr);

        // do the actual update
        if (!performActualUpdate(&updates[0], "1303", dbver))
            return false;
    }

    if (dbver == "1303")
    {
        QDateTime loc = QDateTime::currentDateTime();
        QDateTime utc = loc.toUTC();
        loc = QDateTime(loc.date(), loc.time(), Qt::UTC);
        int utc_offset = loc.secsTo(utc) / 60;

        QList<QByteArray> updates_ba;

        // Convert various DATETIME fields from local time to UTC
        if (0 != utc_offset)
        {
            const char *with_endtime[] = {
                "recordedprogram",
            };
            const char *without_endtime[] = {
                "recordedseek", "recordedmarkup", "recordedrating",
                "recordedcredits",
            };
            QString order = (utc_offset > 0) ? "-starttime" : "starttime";

            for (uint i = 0; i < sizeof(with_endtime)/sizeof(char*); i++)
            {
                updates_ba.push_back(
                     QString("UPDATE %1 "
                     "SET starttime = CONVERT_TZ(starttime, 'SYSTEM', 'Etc/UTC'), "
                     "    endtime   = CONVERT_TZ(endtime, 'SYSTEM', 'Etc/UTC') "
                     "ORDER BY %4")
                     .arg(with_endtime[i]).arg(order).toLocal8Bit());
            }

            for (uint i = 0; i < sizeof(without_endtime)/sizeof(char*); i++)
            {
                updates_ba.push_back(
                      QString("UPDATE %1 "
                      "SET starttime = CONVERT_TZ(starttime, 'SYSTEM', 'Etc/UTC') "
                      "ORDER BY %3")
                      .arg(without_endtime[i]).arg(order).toLocal8Bit());
            }
        }

        // Convert update ByteArrays to NULL terminated char**
        QList<QByteArray>::const_iterator it = updates_ba.begin();
        vector<const char*> updates;
        for (; it != updates_ba.end(); ++it)
            updates.push_back((*it).constData());
        updates.push_back(nullptr);

        // do the actual update
        if (!performActualUpdate(&updates[0], "1304", dbver))
            return false;
    }

    if (dbver == "1304")
    {
        QList<QByteArray> updates_ba;

        updates_ba.push_back(
"UPDATE recordfilter SET clause="
"'HOUR(CONVERT_TZ(program.starttime, ''Etc/UTC'', ''SYSTEM'')) >= 19 AND "
"HOUR(CONVERT_TZ(program.starttime, ''Etc/UTC'', ''SYSTEM'')) < 22' "
"WHERE filterid=3");

        updates_ba.push_back(QString(
"UPDATE record SET findday = "
"    DAYOFWEEK(CONVERT_TZ(ADDTIME('2012-06-02 00:00:00', findtime), "
"                         'SYSTEM', 'Etc/UTC') + INTERVAL findday DAY) "
"WHERE findday > 0").toLocal8Bit());

        updates_ba.push_back(QString(
"UPDATE record SET findtime = "
"    TIME(CONVERT_TZ(ADDTIME('2012-06-02 00:00:00', findtime), "
"                    'SYSTEM', 'Etc/UTC')) ")
                             .toLocal8Bit());

        // Convert update ByteArrays to NULL terminated char**
        QList<QByteArray>::const_iterator it = updates_ba.begin();
        vector<const char*> updates;
        for (; it != updates_ba.end(); ++it)
            updates.push_back((*it).constData());
        updates.push_back(nullptr);

        if (!performActualUpdate(&updates[0], "1305", dbver))
            return false;
    }

    if (dbver == "1305")
    {
        // Reverse the findday/findtime changes from above since those
        // values need to be kept in local time.

        QList<QByteArray> updates_ba;

        updates_ba.push_back(QString(
"UPDATE record SET findday = "
"    DAYOFWEEK(CONVERT_TZ(ADDTIME('2012-06-02 00:00:00', findtime), "
"                         'Etc/UTC', 'SYSTEM') + INTERVAL findday DAY) "
"WHERE findday > 0").toLocal8Bit());

        updates_ba.push_back(QString(
"UPDATE record SET findtime = "
"    TIME(CONVERT_TZ(ADDTIME('2012-06-02 00:00:00', findtime), "
"                    'Etc/UTC', 'SYSTEM')) ").toLocal8Bit());

        // Convert update ByteArrays to NULL terminated char**
        QList<QByteArray>::const_iterator it = updates_ba.begin();
        vector<const char*> updates;
        for (; it != updates_ba.end(); ++it)
            updates.push_back((*it).constData());
        updates.push_back(nullptr);

        if (!performActualUpdate(&updates[0], "1306", dbver))
            return false;
    }

    if (dbver == "1306")
    {
        // staging temporary tables to use with rewritten file scanner
        // due to be replaced by finalized RecordedFile changes

        const char *updates[] = {
"CREATE TABLE scannerfile ("
"  `fileid`         BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,"
"  `filesize`       BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,"
"  `filehash`       VARCHAR(64) NOT NULL DEFAULT '',"
"  `added`          TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,"
"  PRIMARY KEY (`fileid`),"
"  UNIQUE KEY filehash (`filehash`)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE scannerpath ("
"  `fileid`         BIGINT(20) UNSIGNED NOT NULL,"
"  `hostname`       VARCHAR(64) NOT NULL DEFAULT 'localhost',"
"  `storagegroup`   VARCHAR(32) NOT NULL DEFAULT 'Default',"
"  `filename`       VARCHAR(255) NOT NULL DEFAULT '',"
"  PRIMARY KEY (`fileid`)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE videopart ("
"  `fileid`         BIGINT(20) UNSIGNED NOT NULL,"
"  `videoid`        INT(10) UNSIGNED NOT NULL,"
"  `order`          SMALLINT UNSIGNED NOT NULL DEFAULT 1,"
"  PRIMARY KEY `part` (`videoid`, `order`)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
nullptr
};

// removed "UNIQUE KEY path (`storagegroup`, `hostname`, `filename`)" from
// scannerpath as a quick fix for key length constraints

        if (!performActualUpdate(updates, "1307", dbver))
            return false;
    }

    if (dbver == "1307")
    {
        const char *updates[] = {
"ALTER TABLE channel MODIFY COLUMN icon varchar(255) NOT NULL DEFAULT '';",
"UPDATE channel SET icon='' WHERE icon='none';",
nullptr
};
        if (!performActualUpdate(updates, "1308", dbver))
            return false;
    }

    if (dbver == "1308")
    {
        const char *updates[] = {
// Add this time filter
"REPLACE INTO recordfilter (filterid, description, clause, newruledefault) "
"  VALUES (8, 'This time', 'ABS(TIMESTAMPDIFF(MINUTE, CONVERT_TZ("
"  ADDTIME(RECTABLE.startdate, RECTABLE.starttime), ''Etc/UTC'', ''SYSTEM''), "
"  CONVERT_TZ(program.starttime, ''Etc/UTC'', ''SYSTEM''))) MOD 1440 <= 10', 0)",
// Add this day and time filter
"REPLACE INTO recordfilter (filterid, description, clause, newruledefault) "
"  VALUES (9, 'This day and time', 'ABS(TIMESTAMPDIFF(MINUTE, CONVERT_TZ("
"  ADDTIME(RECTABLE.startdate, RECTABLE.starttime), ''Etc/UTC'', ''SYSTEM''), "
"  CONVERT_TZ(program.starttime, ''Etc/UTC'', ''SYSTEM''))) MOD 10080 <= 10', 0)",
// Convert old, normal Timeslot rules to Channel with time filter
"UPDATE record SET type = 3, filter = filter|256 "
"  WHERE type = 2 AND search = 0",
// Convert old, normal Weekslot rules to Channel with day and time filter
"UPDATE record SET type = 3, filter = filter|512 "
"  WHERE type = 5 AND search = 0",
// Convert old, normal find daily to new, power search, find daily
"UPDATE record SET type = 2, search = 1, chanid = 0, station = '', "
"  subtitle = '', description = CONCAT('program.title = ''', "
"  REPLACE(title, '''', ''''''), ''''), "
"  title = CONCAT(title, ' (Power Search)') WHERE type = 9 AND search = 0",
// Convert old, normal find weekly to new, power search, find weekly
"UPDATE record SET type = 5, search = 1, chanid = 0, station = '', "
"  subtitle = '', description = CONCAT('program.title = ''', "
"  REPLACE(title, '''', ''''''), ''''), "
"  title = CONCAT(title, ' (Power Search)') WHERE type = 10 AND search = 0",
// Convert old, find daily to new, find daily
"UPDATE record SET type = 2 WHERE type = 9",
// Convert old, find weekly to new, find weekly
"UPDATE record SET type = 5 WHERE type = 10",
nullptr
};
        if (!performActualUpdate(updates, "1309", dbver))
            return false;
    }

    if (dbver == "1309")
    {
        const char *updates[] = {
// Add this channel filter
"REPLACE INTO recordfilter (filterid, description, clause, newruledefault) "
"  VALUES (10, 'This channel', 'channel.callsign = RECTABLE.station', 0)",
// Convert old, Channel rules to All with channel filter
"UPDATE record SET type = 4, filter = filter|1024 WHERE type = 3",
nullptr
};
        if (!performActualUpdate(updates, "1310", dbver))
            return false;
    }

    if (dbver == "1310")
    {
        const char *updates[] = {
// Move old table temporarily
"RENAME TABLE `housekeeping` TO `oldhousekeeping`;",
// Create new table in its place
"CREATE TABLE `housekeeping` ("
"  `tag`        VARCHAR(64) NOT NULL,"
"  `hostname`   VARCHAR(64),"
"  `lastrun`    DATETIME,"
"  UNIQUE KEY `task` (`tag`, `hostname`)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
// Migrate old data over
"INSERT INTO `housekeeping` (`tag`, `hostname`, `lastrun`)"
"   SELECT SUBSTRING_INDEX(`tag`, '-', 1) AS `tag`,"
"          IF(LOCATE('-', `tag`) > 0,"
"             SUBSTRING(`tag` FROM LENGTH(SUBSTRING_INDEX(`tag`, '-', 1)) +2),"
"             NULL) AS `hostname`,"
"          `lastrun`"
"     FROM `oldhousekeeping`;",
// Delete old data
"DROP TABLE `oldhousekeeping`;",
nullptr
};

        if (!performActualUpdate(updates, "1311", dbver))
            return false;
    }

    if (dbver == "1311")
    {
        const char *updates[] = {
// Create a global enable/disable instead of one per-host
// Any hosts previously running it mean all hosts do now
"INSERT INTO `settings` (`value`, `hostname`, `data`)"
"   SELECT 'HardwareProfileEnabled',"
"          NULL,"
"          IF((SELECT COUNT(1)"
"                FROM `settings`"
"               WHERE `value` = 'HardwareProfileLastUpdated' > 0),"
"             1, 0);",
// Create 'lastrun' times using existing data in settings
"INSERT INTO `housekeeping` (`tag`, `hostname`, `lastrun`)"
"   SELECT 'HardwareProfiler',"
"          `hostname`,"
"          `data`"
"     FROM `settings`"
"    WHERE `value` = 'HardwareProfileLastUpdated';",
// Clear out old settings
"DELETE FROM `settings` WHERE `value` = 'HardwareProfileLastUpdated';",
nullptr
};
        if (!performActualUpdate(updates, "1312", dbver))
            return false;
    }

    if (dbver == "1312")
    {
        const char *updates[] = {
// DVD bookmark updates
"DELETE FROM `dvdbookmark` WHERE `framenum` = 0;",
"ALTER TABLE dvdbookmark ADD COLUMN dvdstate varchar(1024) NOT NULL DEFAULT '';",
nullptr
};
        if (!performActualUpdate(updates, "1313", dbver))
            return false;
    }

    if (dbver == "1313")
    {
        // Make sure channel timeouts are long enough.  No actual
        // schema change.
        const char *updates[] = {
            "UPDATE capturecard SET channel_timeout = 3000 WHERE "
            "cardtype = \"DVB\" AND channel_timeout < 3000;",
            "UPDATE capturecard SET channel_timeout = 30000 WHERE "
            "cardtype = \"FREEBOX\" AND channel_timeout < 30000;",
            "UPDATE capturecard SET channel_timeout = 9000 WHERE "
            "cardtype = \"FIREWIRE\" AND channel_timeout < 9000;",
            "UPDATE capturecard SET channel_timeout = 3000 WHERE "
            "cardtype = \"HDHOMERUN\" AND channel_timeout < 3000;",
            "UPDATE capturecard SET channel_timeout = 15000 WHERE "
            "cardtype = \"HDPVR\" AND channel_timeout < 15000;",
            "UPDATE capturecard SET channel_timeout = 12000 WHERE "
            "cardtype = \"MPEG\" AND channel_timeout < 12000;",
            nullptr
        };
        if (!performActualUpdate(updates, "1314", dbver))
            return false;
    }

    if (dbver == "1314")
    {
        // Migrate users from tmdb.py to tmdb3.py
        // The web interface tmdb.py uses will be shut down 2013-09-15
        const char *updates[] = {
            "UPDATE settings SET data=REPLACE(data, 'tmdb.py', 'tmdb3.py') "
             "WHERE value='MovieGrabber'",
            nullptr
        };
        if (!performActualUpdate(updates, "1315", dbver))
            return false;
    }

    if (dbver == "1315")
    {
        const char *updates[] = {
"ALTER TABLE program ADD INDEX title_subtitle_start (title, subtitle, starttime);",
"ALTER TABLE program DROP INDEX title;",
nullptr
};
        if (!performActualUpdate(updates, "1316", dbver))
            return false;
    }

    if (dbver == "1316")
    {
        const char *updates[] = {
// adjust programid type in various tables to match the program table
"ALTER TABLE oldrecorded CHANGE COLUMN programid programid varchar(64);",
"ALTER TABLE oldrecorded CHANGE COLUMN seriesid seriesid varchar(64);",
"ALTER TABLE record CHANGE COLUMN programid programid varchar(64);",
"ALTER TABLE record CHANGE COLUMN seriesid seriesid varchar(64);",
"ALTER TABLE recorded CHANGE COLUMN programid programid varchar(64);",
"ALTER TABLE recorded CHANGE COLUMN seriesid seriesid varchar(64);",
"ALTER TABLE recordedprogram CHANGE COLUMN programid programid varchar(64);",
"ALTER TABLE recordedprogram CHANGE COLUMN seriesid seriesid varchar(64);",
nullptr
};
        if (!performActualUpdate(updates, "1317", dbver))
            return false;
    }

    if (dbver == "1317")
    {
        const char *updates[] = {
            "CREATE TABLE IF NOT EXISTS gallery_directories ("
            "  dir_id       INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,"
            "  filename     VARCHAR(255) NOT NULL,"
            "  name         VARCHAR(255) NOT NULL,"
            "  path         VARCHAR(255) NOT NULL,"
            "  parent_id    INT(11) NOT NULL,"
            "  dir_count    INT(11) NOT NULL DEFAULT '0',"
            "  file_count   INT(11) NOT NULL DEFAULT '0',"
            "  hidden       TINYINT(1) NOT NULL DEFAULT '0'"
            ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
            "CREATE TABLE IF NOT EXISTS gallery_files ("
            "  file_id      INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,"
            "  filename     VARCHAR(255) NOT NULL,"
            "  name         VARCHAR(255) NOT NULL,"
            "  path         VARCHAR(255) NOT NULL,"
            "  dir_id       INT(11) NOT NULL DEFAULT '0',"
            "  type         INT(11) NOT NULL DEFAULT '0',"
            "  modtime      INT(11) NOT NULL DEFAULT '0',"
            "  size         INT(11) NOT NULL DEFAULT '0',"
            "  extension    VARCHAR(255) NOT NULL,"
            "  angle        INT(11) NOT NULL DEFAULT '0',"
            "  date         INT(11) NOT NULL DEFAULT '0',"
            "  zoom         INT(11) NOT NULL DEFAULT '0',"
            "  hidden       TINYINT(1) NOT NULL DEFAULT '0',"
            "  orientation  INT(11) NOT NULL DEFAULT '0'"
            ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
            "INSERT INTO settings VALUES ('ImageStorageGroupName', 'Images', NULL);",
            "INSERT INTO settings VALUES ('ImageSortOrder', 0, NULL);",
            "INSERT INTO settings VALUES ('ImageShowHiddenFiles', 0, NULL);",
            "INSERT INTO settings VALUES ('ImageSlideShowTime', 3500, NULL);",
            "INSERT INTO settings VALUES ('ImageTransitionType', 1, NULL);",
            "INSERT INTO settings VALUES ('ImageTransitionTime', 1000, NULL);",
            nullptr
        };

        if (!performActualUpdate(&updates[0], "1318", dbver))
            return false;
    }

    if (dbver == "1318")
    {
        const char *updates[] = {
            "ALTER TABLE program "
            " ADD COLUMN season INT(4) NOT NULL DEFAULT '0', "
            " ADD COLUMN episode INT(4) NOT NULL DEFAULT '0';",
            "ALTER TABLE recordedprogram "
            " ADD COLUMN season INT(4) NOT NULL DEFAULT '0', "
            " ADD COLUMN episode INT(4) NOT NULL DEFAULT '0';",
            nullptr
        };

        if (!performActualUpdate(&updates[0], "1319", dbver))
            return false;
    }

    if (dbver == "1319")
    {
        // Total number of episodes in the series (season)
        const char *updates[] = {
            "ALTER TABLE program "
            " ADD COLUMN totalepisodes INT(4) NOT NULL DEFAULT '0';",
            "ALTER TABLE recordedprogram "
            " ADD COLUMN totalepisodes INT(4) NOT NULL DEFAULT '0';",
            nullptr
        };

        if (!performActualUpdate(&updates[0], "1320", dbver))
            return false;
    }

    if (dbver == "1320")
    {
        const char *updates[] = {
            "CREATE TABLE IF NOT EXISTS recgroups ("
                "recgroupid  SMALLINT(4) NOT NULL AUTO_INCREMENT, "
                "recgroup    VARCHAR(64) NOT NULL DEFAULT '', "
                "displayname VARCHAR(64) NOT NULL DEFAULT '', "
                "password    VARCHAR(40) NOT NULL DEFAULT '', "
                "special     TINYINT(1) NOT NULL DEFAULT '0',"
                "PRIMARY KEY (recgroupid), "
                "UNIQUE KEY recgroup ( recgroup )"
                ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
            // Create the built-in, 'special', groups
            "INSERT INTO recgroups ( recgroupid, recgroup, special ) VALUES ( 1, 'Default', '1' );",
            "INSERT INTO recgroups ( recgroupid, recgroup, special ) VALUES ( 2, 'LiveTV', '1' );",
            "INSERT INTO recgroups ( recgroupid, recgroup, special ) VALUES ( 3, 'Deleted', '1' );",
            // Copy in the passwords for the built-in groups
            "DELETE FROM recgrouppassword WHERE password = '';",
            "UPDATE recgroups r, recgrouppassword p SET r.password = p.password WHERE r.recgroup = p.recgroup;",
            // Copy over all existing recording groups, this information may be split over three tables!
            "INSERT IGNORE INTO recgroups ( recgroup, displayname, password ) SELECT DISTINCT recgroup, recgroup, password FROM recgrouppassword;",
            "INSERT IGNORE INTO recgroups ( recgroup, displayname ) SELECT DISTINCT recgroup, recgroup FROM record;",
            "INSERT IGNORE INTO recgroups ( recgroup, displayname ) SELECT DISTINCT recgroup, recgroup FROM recorded;",
            // Create recgroupid columns in record and recorded tables
            "ALTER TABLE record ADD COLUMN recgroupid SMALLINT(4) NOT NULL DEFAULT '1', ADD INDEX ( recgroupid );",
            "ALTER TABLE recorded ADD COLUMN recgroupid SMALLINT(4) NOT NULL DEFAULT '1', ADD INDEX ( recgroupid );",
            // Populate those columns with the corresponding recgroupid from the new recgroups table
            "UPDATE recorded, recgroups SET recorded.recgroupid = recgroups.recgroupid WHERE recorded.recgroup = recgroups.recgroup;",
            "UPDATE record, recgroups SET record.recgroupid = recgroups.recgroupid WHERE record.recgroup = recgroups.recgroup;",
            nullptr
        };



        if (!performActualUpdate(&updates[0], "1321", dbver))
            return false;
    }

    if (dbver == "1321")
    {
        const char *updates[] = {
            "ALTER TABLE `housekeeping` ADD COLUMN `lastsuccess` DATETIME;",
            "UPDATE `housekeeping` SET `lastsuccess`=`lastrun`;",
            nullptr
        };

        if (!performActualUpdate(&updates[0], "1322", dbver))
            return false;
    }

    if (dbver == "1322")
    {
        const char *updates[] = {
        // add inetref to (recorded)program before season/episode
            "ALTER TABLE program "
            " ADD COLUMN inetref varchar(40) DEFAULT '' AFTER videoprop;",
            "ALTER TABLE recordedprogram "
            " ADD COLUMN inetref varchar(40) DEFAULT '' AFTER videoprop;",
            "DELETE FROM settings WHERE value='DefaultStartOffset';",
            "DELETE FROM settings WHERE value='DefaultEndOffset';",
            "DELETE FROM settings WHERE value='AutoExpireDefault';",
            "DELETE FROM settings WHERE value='AutoCommercialFlag';",
            "DELETE FROM settings WHERE value='AutoTranscode';",
            "DELETE FROM settings WHERE value='DefaultTranscoder';",
            "DELETE FROM settings WHERE value='AutoRunUserJob1';",
            "DELETE FROM settings WHERE value='AutoRunUserJob2';",
            "DELETE FROM settings WHERE value='AutoRunUserJob3';",
            "DELETE FROM settings WHERE value='AutoRunUserJob4';",
            "DELETE FROM settings WHERE value='AutoMetadataLookup';",
            "DELETE FROM housekeeping WHERE tag='DailyCleanup';",
            "DELETE FROM housekeeping WHERE tag='ThemeChooserInfoCacheUpdate';",
            nullptr
        };
        if (!performActualUpdate(updates, "1323", dbver))
            return false;
    }

    if (dbver == "1323")
    {
        const char *updates[] = {
        // add columns for Unicable related configuration data, see #9726
            "ALTER TABLE diseqc_tree "
            " ADD COLUMN scr_userband INTEGER UNSIGNED NOT NULL DEFAULT 0 AFTER address, "
            " ADD COLUMN scr_frequency INTEGER UNSIGNED NOT NULL DEFAULT 1400 AFTER scr_userband, "
            " ADD COLUMN scr_pin INTEGER  NOT NULL DEFAULT '-1' AFTER scr_frequency;",
            nullptr
        };

        if (!performActualUpdate(updates, "1324", dbver))
            return false;
    }

    if (dbver == "1324")
    {
        const char *updates[] = {
            "ALTER TABLE recorded "
            " DROP PRIMARY KEY, "
            " ADD recordedid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, "
            " ADD UNIQUE KEY (chanid, starttime) ;",
            nullptr
        };

        if (!performActualUpdate(updates, "1325", dbver))
            return false;
    }

    if (dbver == "1325")
    {
        const char *updates[] = {
            "ALTER TABLE recorded ADD inputname VARCHAR(32);",
            nullptr
        };

        if (!performActualUpdate(&updates[0], "1326", dbver))
            return false;
    }

    if (dbver == "1326")
    {
        const char *updates[] = {
// Add this time filter
"REPLACE INTO recordfilter (filterid, description, clause, newruledefault) "
"  VALUES (8, 'This time', 'ABS(TIMESTAMPDIFF(MINUTE, CONVERT_TZ("
"  ADDTIME(RECTABLE.startdate, RECTABLE.starttime), ''Etc/UTC'', ''SYSTEM''), "
"  CONVERT_TZ(program.starttime, ''Etc/UTC'', ''SYSTEM''))) MOD 1440 "
"  NOT BETWEEN 11 AND 1429', 0)",
// Add this day and time filter
"REPLACE INTO recordfilter (filterid, description, clause, newruledefault) "
"  VALUES (9, 'This day and time', 'ABS(TIMESTAMPDIFF(MINUTE, CONVERT_TZ("
"  ADDTIME(RECTABLE.startdate, RECTABLE.starttime), ''Etc/UTC'', ''SYSTEM''), "
"  CONVERT_TZ(program.starttime, ''Etc/UTC'', ''SYSTEM''))) MOD 10080 "
"  NOT BETWEEN 11 AND 10069', 0)",
nullptr
};
        if (!performActualUpdate(updates, "1327", dbver))
            return false;
    }

    if (dbver == "1327")
    {
        const char *updates[] = {
            "DELETE r1 FROM record r1, record r2 "
            "  WHERE r1.chanid = r2.chanid AND "
            "        r1.starttime = r2.starttime AND "
            "        r1.startdate = r2.startdate AND "
            "        r1.title = r2.title AND "
            "        r1.type = r2.type AND "
            "        r1.recordid > r2.recordid",
            "ALTER TABLE record DROP INDEX chanid",
            "ALTER TABLE record ADD UNIQUE INDEX "
            " (chanid, starttime, startdate, title, type)",
            nullptr
        };
        if (!performActualUpdate(updates, "1328", dbver))
            return false;
    }

    if (dbver == "1328")
    {
        const char *updates[] = {
            "ALTER TABLE recordedfile "
            "DROP KEY `chanid`, "
            "DROP COLUMN `chanid`, "
            "DROP COLUMN `starttime`;",
            "ALTER TABLE recordedfile "
            "ADD COLUMN recordedid int(10) unsigned NOT NULL, "
            "ADD UNIQUE KEY `recordedid` (recordedid);",
            "ALTER TABLE recordedfile "
            "CHANGE audio_type audio_codec varchar(255) NOT NULL DEFAULT '';"
            "ALTER TABLE recordedfile "
            "CHANGE video_type video_codec varchar(255) NOT NULL DEFAULT '';",
            nullptr
        };
        if (!performActualUpdate(updates, "1329", dbver))
            return false;
    }

    if (dbver == "1329")
    {
        const char *updates[] = {
            "ALTER TABLE recordedfile "
            "DROP COLUMN audio_bits_per_sample ;", // Instead create two columns for avg and max bitrates
            "ALTER TABLE recordedfile "
            "ADD COLUMN container VARCHAR(255) NOT NULL DEFAULT '', "
            "ADD COLUMN total_bitrate MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, " // Kbps
            "ADD COLUMN video_avg_bitrate MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, " // Kbps
            "ADD COLUMN video_max_bitrate MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, " // Kbps
            "ADD COLUMN audio_avg_bitrate MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, " // Kbps
            "ADD COLUMN audio_max_bitrate MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 ;", // Kbps
           nullptr
        };
        if (!performActualUpdate(updates, "1330", dbver))
            return false;
    }

    if (dbver == "1330")
    {
        MSqlQuery query(MSqlQuery::InitCon());
        query.prepare("SELECT recordedid FROM recorded");
        query.exec();
        while (query.next())
        {
            int recordingID = query.value(0).toInt();
            RecordingInfo *recInfo = new RecordingInfo(recordingID);
            RecordingFile *recFile = recInfo->GetRecordingFile();
            recFile->m_fileName = recInfo->GetBasename();
            recFile->m_fileSize = recInfo->GetFilesize();
            recFile->m_storageGroup = recInfo->GetStorageGroup();
            recFile->m_storageDeviceID = recInfo->GetHostname();
            switch (recInfo->QueryAverageAspectRatio())
            {
                case MARK_ASPECT_1_1 :
                    recFile->m_videoAspectRatio = 1.0;
                    break;
                case MARK_ASPECT_4_3:
                    recFile->m_videoAspectRatio = 1.33333333333;
                    break;
                case MARK_ASPECT_16_9:
                    recFile->m_videoAspectRatio = 1.77777777777;
                    break;
                case MARK_ASPECT_2_21_1:
                    recFile->m_videoAspectRatio = 2.21;
                    break;
                default:
                    break;
            }
            QSize resolution(recInfo->QueryAverageWidth(),
                            recInfo->QueryAverageHeight());
            recFile->m_videoResolution = resolution;
            recFile->m_videoFrameRate = (double)recInfo->QueryAverageFrameRate() / 1000.0;
            recFile->Save();
            delete recInfo;
        }

        if (!UpdateDBVersionNumber("1331", dbver))
            return false;
    }

    if (dbver == "1331")
    {
        LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1332");
        MSqlQuery select(MSqlQuery::InitCon());
        MSqlQuery update(MSqlQuery::InitCon());

        // Find all second or higher inputs using the same card.
        select.prepare("SELECT DISTINCT i1.cardid, i1.cardinputid "
                       "FROM cardinput i1, cardinput i2 "
                       "WHERE i1.cardid = i2.cardid AND "
                       "       i1.cardinputid > i2.cardinputid "
                       "ORDER BY i1.cardid, i1.cardinputid");
        if (!select.exec())
        {
            MythDB::DBError("Unable to retrieve cardinputids.", select);
            return false;
        }

        while (select.next())
        {
            int cardid = select.value(0).toInt();
            int inputid = select.value(1).toInt();

            // Create a new card for this input.
            update.prepare("INSERT INTO capturecard "
                           "     ( videodevice, audiodevice, vbidevice, "
                           "       cardtype, defaultinput, audioratelimit, "
                           "       hostname, dvb_swfilter, dvb_sat_type, "
                           "       dvb_wait_for_seqstart, skipbtaudio, "
                           "       dvb_on_demand, dvb_diseqc_type, "
                           "       firewire_speed, firewire_model, "
                           "       firewire_connection, signal_timeout, "
                           "       channel_timeout, dvb_tuning_delay, "
                           "       contrast, brightness, colour, hue, "
                           "       diseqcid, dvb_eitscan ) "
                           "SELECT videodevice, audiodevice, vbidevice, "
                           "       cardtype, defaultinput, audioratelimit, "
                           "       hostname, dvb_swfilter, dvb_sat_type, "
                           "       dvb_wait_for_seqstart, skipbtaudio, "
                           "       dvb_on_demand, dvb_diseqc_type, "
                           "       firewire_speed, firewire_model, "
                           "       firewire_connection, signal_timeout, "
                           "       channel_timeout, dvb_tuning_delay, "
                           "       contrast, brightness, colour, hue, "
                           "       diseqcid, dvb_eitscan "
                           "FROM capturecard c "
                           "WHERE c.cardid = :CARDID");
            update.bindValue(":CARDID", cardid);
            if (!update.exec())
            {
                MythDB::DBError("Unable to insert new card.", update);
                return false;
            }
            int newcardid = update.lastInsertId().toInt();

            // Now attach the input to the new card.
            update.prepare("UPDATE cardinput "
                           "SET cardid = :NEWCARDID "
                           "WHERE cardinputid = :INPUTID");
            update.bindValue(":NEWCARDID", newcardid);
            update.bindValue(":INPUTID", inputid);
            if (!update.exec())
            {
                MythDB::DBError("Unable to update input.", update);
                return false;
            }
        }

        const char *updates[] = {
            // Delete old, automatically created inputgroups.
            "DELETE FROM inputgroup WHERE inputgroupname LIKE 'DVB_%'",
            "DELETE FROM inputgroup WHERE inputgroupname LIKE 'CETON_%'",
            "DELETE FROM inputgroup WHERE inputgroupname LIKE 'HDHOMERUN_%'",
            // Increase the size of inputgroup.inputgroupname.
            "ALTER TABLE inputgroup "
            "    MODIFY COLUMN inputgroupname VARCHAR(48)",
            // Rename remaining inputgroups to have 'user:' prefix.
            "UPDATE inputgroup "
            "    SET inputgroupname = CONCAT('user:', inputgroupname)",
            // Change inputgroup.inputid to equal cardid.
            "UPDATE inputgroup ig "
            "    JOIN cardinput i ON ig.cardinputid = i.cardinputid "
            "    SET ig.cardinputid = i.cardid",
            // Change record.prefinput to equal cardid.
            "UPDATE record r "
            "    JOIN cardinput i ON r.prefinput = i.cardinputid "
            "    SET r.prefinput = i.cardid",
            // Change diseqc_config.cardinputid to equal cardid.
            "UPDATE diseqc_config dc "
            "    JOIN cardinput i ON dc.cardinputid = i.cardinputid "
            "    SET dc.cardinputid = i.cardid",
            // Change cardinput.cardinputid to equal cardid.  Do in
            // multiple steps to avoid duplicate ids.
            "SELECT MAX(cardid) INTO @maxcardid FROM capturecard",
            "SELECT MAX(cardinputid) INTO @maxcardinputid FROM cardinput",
            "UPDATE cardinput i "
            "    SET i.cardinputid = i.cardid + @maxcardid + @maxcardinputid",
            "UPDATE cardinput i "
            "    SET i.cardinputid = i.cardid",
            nullptr
        };

        if (!performUpdateSeries(updates))
            return false;

        // Create an automatically generated inputgroup for each card.
        select.prepare("SELECT cardid, hostname, videodevice "
                       "FROM capturecard c "
                       "ORDER BY c.cardid");
        if (!select.exec())
        {
            MythDB::DBError("Unable to retrieve cardtids.", select);
            return false;
        }

        while (select.next())
        {
            uint cardid = select.value(0).toUInt();
            QString host = select.value(1).toString();
            QString device = select.value(2).toString();
            QString name = host + "|" + device;
            uint groupid = CardUtil::CreateInputGroup(name);
            if (!groupid)
                return false;
            if (!CardUtil::LinkInputGroup(cardid, groupid))
                return false;
        }

        // Remove orphan and administrative inputgroup entries.
        if (!CardUtil::UnlinkInputGroup(0, 0))
            return false;

        if (!UpdateDBVersionNumber("1332", dbver))
            return false;
    }

    if (dbver == "1332")
    {
        const char *updates[] = {
            // Move contents of cardinput to capturecard.
            "ALTER TABLE capturecard "
            "    ADD COLUMN inputname VARCHAR(32) NOT NULL DEFAULT '', "
            "    ADD COLUMN sourceid INT(10) UNSIGNED NOT NULL DEFAULT 0, "
            "    ADD COLUMN externalcommand VARCHAR(128), "
            "    ADD COLUMN changer_device VARCHAR(128), "
            "    ADD COLUMN changer_model VARCHAR(128), "
            "    ADD COLUMN tunechan VARCHAR(10), "
            "    ADD COLUMN startchan VARCHAR(10), "
            "    ADD COLUMN displayname VARCHAR(64) NOT NULL DEFAULT '', "
            "    ADD COLUMN dishnet_eit TINYINT(1) NOT NULL DEFAULT 0, "
            "    ADD COLUMN recpriority INT(11) NOT NULL DEFAULT 0, "
            "    ADD COLUMN quicktune TINYINT(4) NOT NULL DEFAULT 0, "
            "    ADD COLUMN schedorder INT(10) UNSIGNED NOT NULL DEFAULT 0, "
            "    ADD COLUMN livetvorder INT(10) UNSIGNED NOT NULL DEFAULT 0",
            "UPDATE capturecard c "
            "    JOIN cardinput i ON c.cardid = i.cardinputid "
            "    SET c.inputname = i.inputname, "
            "        c.sourceid = i.sourceid, "
            "        c.externalcommand = i.externalcommand, "
            "        c.changer_device = i.changer_device, "
            "        c.changer_model = i.changer_model, "
            "        c.tunechan = i.tunechan, "
            "        c.startchan = i.startchan, "
            "        c.displayname = i.displayname, "
            "        c.dishnet_eit = i.dishnet_eit, "
            "        c.recpriority = i.recpriority, "
            "        c.quicktune = i.quicktune, "
            "        c.schedorder = i.schedorder, "
            "        c.livetvorder = i.livetvorder",
            "TRUNCATE cardinput",
            nullptr
        };
        if (!performActualUpdate(updates, "1333", dbver))
            return false;
    }

    if (dbver == "1333")
    {
        const char *updates[] = {
            // Fix default value of capturecard.inputname.
            "ALTER TABLE capturecard "
            "    MODIFY COLUMN inputname VARCHAR(32) NOT NULL DEFAULT 'None'",
            "UPDATE capturecard c "
            "    SET inputname = 'None' WHERE inputname = '' ",
            nullptr
        };
        if (!performActualUpdate(updates, "1334", dbver))
            return false;
    }

    if (dbver == "1334")
    {
        const char *updates[] = {
            // Change the default sched/livetvorder from 0 to 1.
            "ALTER TABLE capturecard "
            "    MODIFY COLUMN schedorder INT(10) UNSIGNED "
            "        NOT NULL DEFAULT 1, "
            "    MODIFY COLUMN livetvorder INT(10) UNSIGNED "
            "        NOT NULL DEFAULT 1",
            nullptr
        };
        if (!performActualUpdate(updates, "1335", dbver))
            return false;
    }

    if (dbver == "1335")
    {
        const char *updates[] = {
            // Fix custom record and custom priority references to
            // cardinput and cardinputid.
            "UPDATE record SET description = "
            "    replace(description, 'cardinputid', 'cardid') "
            "    WHERE search = 1",
            "UPDATE record SET description = "
            "    replace(description, 'cardinput', 'capturecard') "
            "    WHERE search = 1",
            "UPDATE powerpriority SET selectclause = "
            "    replace(selectclause, 'cardinputid', 'cardid')",
            "UPDATE powerpriority SET selectclause = "
            "    replace(selectclause, 'cardinput', 'capturecard')",
            nullptr
        };
        if (!performActualUpdate(updates, "1336", dbver))
            return false;
    }

    if (dbver == "1336")
    {
        const char *updates[] = {
            // Add a parentid columne to capturecard.
            "ALTER TABLE capturecard "
            "    ADD parentid INT UNSIGNED NOT NULL DEFAULT 0 AFTER cardid",
            "UPDATE capturecard c, "
            "       (SELECT min(cardid) cardid, hostname, videodevice, "
            "               inputname, cardtype "
            "        FROM capturecard "
            "        WHERE cardtype NOT IN "
            "              ('FREEBOX', 'IMPORT', 'DEMO', 'EXTERNAL') "
            "        GROUP BY hostname, videodevice, inputname) mins "
            "SET c.parentid = mins.cardid "
            "WHERE c.hostname = mins.hostname and "
            "      c.videodevice = mins.videodevice and "
            "      c.inputname = mins.inputname and "
            "      c.cardid <> mins.cardid",
            nullptr
        };
        if (!performActualUpdate(updates, "1337", dbver))
            return false;
    }

    if (dbver == "1337")
    {
        const char *updates[] = {
            // All next_record, last_record and last_delete to be NULL.
            "ALTER TABLE record MODIFY next_record DATETIME NULL",
            "UPDATE record SET next_record = NULL "
            "    WHERE next_record = '0000-00-00 00:00:00'",
            "ALTER TABLE record MODIFY last_record DATETIME NULL",
            "UPDATE record SET last_record = NULL "
            "    WHERE last_record = '0000-00-00 00:00:00'",
            "ALTER TABLE record MODIFY last_delete DATETIME NULL",
            "UPDATE record SET last_delete = NULL "
            "    WHERE last_delete = '0000-00-00 00:00:00'",
            nullptr
        };
        if (!performActualUpdate(updates, "1338", dbver))
            return false;
    }

    if (dbver == "1338")
    {
        const char *updates[] = {
            "CREATE TABLE users ("
            " userid int(5) unsigned NOT NULL AUTO_INCREMENT,"
            " username varchar(128) NOT NULL DEFAULT '',"
            " password_digest varchar(32) NOT NULL DEFAULT '',"
            " lastlogin datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
            " PRIMARY KEY (userid),"
            " KEY username (username)"
            " ) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
            "CREATE TABLE user_permissions ("
            " userid int(5) unsigned NOT NULL,"
            " permission varchar(128) NOT NULL DEFAULT '',"
            " PRIMARY KEY (userid)"
            " ) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
            "CREATE TABLE user_sessions ("
            " sessiontoken varchar(40) NOT NULL DEFAULT ''," // SHA1
            " userid int(5) unsigned NOT NULL,"
            " client varchar(128) NOT NULL, "
            " created datetime NOT NULL,"
            " lastactive datetime NOT NULL,"
            " expires datetime NOT NULL,"
            " PRIMARY KEY (sessionToken),"
            " UNIQUE KEY userid_client (userid,client)"
            " ) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
            "INSERT INTO users SET username='admin'," // Temporary default account
            " password_digest='bcd911b2ecb15ffbd6d8e6e744d60cf6';",
            nullptr
        };
        if (!performActualUpdate(updates, "1339", dbver))
            return false;
    }

    if (dbver == "1339")
    {
        MSqlQuery query(MSqlQuery::InitCon());

        // insert a new profile group for the VBox
        query.prepare("INSERT INTO profilegroups SET name = 'VBox Recorder', "
                       "cardtype = 'VBOX', is_default = 1;");
        if (!query.exec())
        {
            MythDB::DBError("Unable to insert vbox profilegroup.", query);
            return false;
        }

        // get the id of the new profile group
        int groupid = query.lastInsertId().toInt();

        // insert the recording profiles
        query.prepare("INSERT INTO recordingprofiles SET name = \"Default\", profilegroup = :GROUPID;");
        query.bindValue(":GROUPID", groupid);
        if (!query.exec())
        {
            MythDB::DBError("Unable to insert 'Default' recordingprofile.", query);
            return false;
        }

        query.prepare("INSERT INTO recordingprofiles SET name = \"Live TV\", profilegroup = :GROUPID;");
        query.bindValue(":GROUPID", groupid);
        if (!query.exec())
        {
            MythDB::DBError("Unable to insert 'Live TV' recordingprofile.", query);
            return false;
        }

        query.prepare("INSERT INTO recordingprofiles SET name = \"High Quality\", profilegroup = :GROUPID;");
        query.bindValue(":GROUPID", groupid);
        if (!query.exec())
        {
            MythDB::DBError("Unable to insert 'High Quality' recordingprofile.", query);
            return false;
        }

        query.prepare("INSERT INTO recordingprofiles SET name = \"Low Quality\", profilegroup = :GROUPID;");
        query.bindValue(":GROUPID", groupid);
        if (!query.exec())
        {
            MythDB::DBError("Unable to insert 'Low Quality' recordingprofile.", query);
            return false;
        }

        if (!UpdateDBVersionNumber("1340", dbver))
            return false;
    }

    if (dbver == "1340")
    {
        const char *updates[] = {
            // Add filter to ignore episodes (e.g. in a person search)
            "REPLACE INTO recordfilter (filterid, description, clause, newruledefault) "
            "  VALUES (11, 'No episodes', 'program.category_type <> ''series''', 0)",
            nullptr
        };
        if (!performActualUpdate(updates, "1341", dbver))
            return false;
    }

    if (dbver == "1341")
    {
        const char *updates[] = {
            "UPDATE profilegroups SET cardtype='FREEBOX' WHERE cardtype='Freebox'",
            nullptr
        };
        if (!performActualUpdate(updates, "1342", dbver))
            return false;
    }

    if (dbver == "1342")
    {
        LOG(VB_GENERAL, LOG_CRIT, "Upgrading to MythTV schema version 1343");
        MSqlQuery select(MSqlQuery::InitCon());
        MSqlQuery update(MSqlQuery::InitCon());

        const char *updates[] = {
            // Delete automatically created inputgroups.
            "DELETE FROM inputgroup WHERE inputgroupname REGEXP '^[a-z_-]*\\\\|'",
            // Increase the size of inputgroup.inputgroupname.
            "ALTER TABLE inputgroup "
            "    MODIFY COLUMN inputgroupname VARCHAR(128)",
            nullptr
        };

        if (!performUpdateSeries(updates))
            return false;

        // Recreate automatically generated inputgroup for each card.
        select.prepare("SELECT cardid, parentid, cardtype, hostname, "
                       "       videodevice "
                       "FROM capturecard c "
                       "ORDER BY c.cardid");
        if (!select.exec())
        {
            MythDB::DBError("Unable to retrieve cardtids.", select);
            return false;
        }

        while (select.next())
        {
            uint cardid = select.value(0).toUInt();
            uint parentid = select.value(1).toUInt();
            QString type = select.value(2).toString();
            QString host = select.value(3).toString();
            QString device = select.value(4).toString();
            QString name = host + "|" + device;
            if (type == "FREEBOX" || type == "IMPORT" ||
                type == "DEMO"    || type == "EXTERNAL")
                name += QString("|%1").arg(parentid ? parentid : cardid);
            uint groupid = CardUtil::CreateInputGroup(name);
            if (!groupid)
                return false;
            if (!CardUtil::LinkInputGroup(cardid, groupid))
                return false;
        }

        // Remove orphan and administrative inputgroup entries.
        if (!CardUtil::UnlinkInputGroup(0, 0))
            return false;

        if (!UpdateDBVersionNumber("1343", dbver))
            return false;
    }

    if (dbver == "1343")
    {
        const char *updates[] = {
            "DROP TABLE IF EXISTS bdbookmark;",
            "CREATE TABLE bdbookmark ("
            "  serialid varchar(40) NOT NULL DEFAULT '',"
            "  `name` varchar(128) DEFAULT NULL,"
            "  bdstate varchar(4096) NOT NULL DEFAULT '',"
            "  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,"
            "  PRIMARY KEY (serialid)"
            ") ENGINE=MyISAM DEFAULT CHARSET=utf8;",

            // #12612 strip \0 characters from channel/channelscan_channel callsign and name
            "UPDATE channel SET callsign=REPLACE(callsign,'\\0',''),"
            "name=REPLACE(name,'\\0','');",

            // "BackendWSPort" was removed in caaaeef8166722888012f4ecaf3e9b0f09df512a
            "DELETE FROM settings WHERE value='BackendWSPort';",
            nullptr
        };

        if (!performActualUpdate(&updates[0], "1344", dbver))
            return false;
    }

    if (dbver == "1344")
    {
        const char *updates[] = {
            "ALTER TABLE capturecard ADD COLUMN "
            "    reclimit INT UNSIGNED DEFAULT 1 NOT NULL",
            "UPDATE capturecard cc, "
            "       ( SELECT IF(parentid>0, parentid, cardid) cardid, "
            "                count(*) cnt "
            "         FROM capturecard "
            "         GROUP BY if(parentid>0, parentid, cardid) "
            "       ) p "
            "SET cc.reclimit = p.cnt "
            "WHERE cc.cardid = p.cardid OR cc.parentid = p.cardid",
            nullptr
        };

        if (!performActualUpdate(&updates[0], "1345", dbver))
            return false;
    }

    if (dbver == "1345")
    {
        const char *updates[] = {
            "ALTER TABLE capturecard ADD COLUMN "
            "    schedgroup TINYINT(1) DEFAULT 0 NOT NULL",
            nullptr
        };

        if (!performActualUpdate(&updates[0], "1346", dbver))
            return false;
    }

    /*
     * TODO the following settings are no more, clean them up with the next schema change
     * to avoid confusion by stale settings in the database
     *
     * WatchTVGuide
     */

    if (dbver == "1346")
    {
        QString master;
        // Create new MasterServerName setting
        if (gCoreContext->IsMasterHost())
            master =
            "insert into settings (value,data,hostname) "
            "values('MasterServerName','"
                + gCoreContext->GetHostName() + "', null);";
        else
            master =
            "insert into settings (value,data,hostname) "
            "select 'MasterServerName', b.hostname, null "
            "from settings a, settings b "
            "where a.value = 'MasterServerIP' "
            "and b.value in ('BackendServerIP','BackendServerIP6')"
            "and a.data = b.data;";

        const char *updates[] = {
            // Create new MasterServerName setting
            master.toLocal8Bit().constData(),
            // Create new BackendServerAddr setting for each backend server
            // Assume using IPV4 value.
            "insert into settings (value,data,hostname) "
                "select 'BackendServerAddr', data,hostname from settings "
                "where value = 'BackendServerIP';",
            // Update BackendServerAddr setting for cases where IPV6 is used
            "update settings a, settings b "
                "set b.data = a.data "
                "where a.value = 'BackendServerIP6' "
                "and b.hostname = a.hostname "
                "and b.value = 'BackendServerAddr' "
                "and b.data = '127.0.0.1' "
                "and a.data != '::1' "
                "and a.data is not null "
                "and a.data != ''; ",
            // Update BackendServerAddr setting for master backend to
            // conform to MasterServerIP setting
            "update settings a, settings b, settings c "
                "set c.data = a.data "
                "where a.value = 'MasterServerIP' "  // 1 row
                "and b.value = 'MasterServerName' "  // 1 row
                "and c.value = 'BackendServerAddr' " // 1 row per BE
                "and c.hostname = b.data;",          // restrict to master
            // Delete obsolete settings
            "delete from settings "
                "where value in ('WatchTVGuide');",
            nullptr
        };

        if (!performActualUpdate(&updates[0], "1347", dbver))
            return false;
    }

    if (dbver == "1347")
    {
        const char *updates[] = {
            "ALTER TABLE record MODIFY COLUMN startdate DATE DEFAULT NULL",
            "ALTER TABLE record MODIFY COLUMN enddate DATE DEFAULT NULL",
            "ALTER TABLE record MODIFY COLUMN starttime TIME DEFAULT NULL",
            "ALTER TABLE record MODIFY COLUMN endtime TIME DEFAULT NULL",
            nullptr
        };
        if (!performActualUpdate(updates, "1348", dbver))
            return false;
    }

    if (dbver == "1348")
    {
        const char *updates[] = {
            "update capturecard "
            "    set videodevice=left(videodevice, "
            "                         locate('-', videodevice)-1) "
            "    where cardtype='HDHOMERUN' "
            "          and videodevice like '%-%'",
            nullptr
        };
        if (!performActualUpdate(updates, "1349", dbver))
            return false;
    }

    if (dbver == "1349")
    {
        const char *updates[] = {
            // Incorrect DB update removed
            nullptr
        };
        if (!performActualUpdate(updates, "1350", dbver))
            return false;
    }

    return true;
}

/**
 * command to get the the initial database layout from an empty database:
 *
 * mysqldump \
 *     --skip-comments --skip-opt --compact --skip-quote-names \
 *     --create-options --ignore-table=mythconverg.schemalock mythconverg | \
 *   sed '/^\(SET\|INS\).*;$/d;/^\/\*!40101.*$/d;s/^.*[^;]$/"&"/;s/^).*;$/"&",/'
 *
 * command to get the initial data:
 *
 * mysqldump \
 *     --skip-comments --skip-opt --compact --skip-quote-names -t \
 *     --ignore-table=mythconverg.logging mythconverg |
 *   sed -e 's/^.*$/"&",/' -e 's#\\#\\\\#g'
 *
 * don't forget to delete host specific data
 *
 */
bool InitializeMythSchema(void)
{
    MSqlQuery query(MSqlQuery::InitCon());
    query.prepare("SHOW TABLES;");

    // check for > 1 table here since the schemalock table should exist
    if (query.exec() && query.isActive() && query.size() > 1)
    {
        QString msg = QString(
            "Told to create a NEW database schema, but the database\n"
            "already has %1 tables.\n"
            "If you are sure this is a good MythTV database, verify\n"
            "that the settings table has the DBSchemaVer variable.\n")
            .arg(query.size() - 1);
        LOG(VB_GENERAL, LOG_ERR, msg);
        return false;
    }

    LOG(VB_GENERAL, LOG_NOTICE,
        "Inserting MythTV initial database information.");

    const char *updates[] = {
"CREATE TABLE capturecard ("
"  cardid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  videodevice varchar(128) DEFAULT NULL,"
"  audiodevice varchar(128) DEFAULT NULL,"
"  vbidevice varchar(128) DEFAULT NULL,"
"  cardtype varchar(32) DEFAULT 'V4L',"
"  defaultinput varchar(32) DEFAULT 'Television',"
"  audioratelimit int(11) DEFAULT NULL,"
"  hostname varchar(64) DEFAULT NULL,"
"  dvb_swfilter int(11) DEFAULT '0',"
"  dvb_sat_type int(11) NOT NULL DEFAULT '0',"
"  dvb_wait_for_seqstart int(11) NOT NULL DEFAULT '1',"
"  skipbtaudio tinyint(1) DEFAULT '0',"
"  dvb_on_demand tinyint(4) NOT NULL DEFAULT '0',"
"  dvb_diseqc_type smallint(6) DEFAULT NULL,"
"  firewire_speed int(10) unsigned NOT NULL DEFAULT '0',"
"  firewire_model varchar(32) DEFAULT NULL,"
"  firewire_connection int(10) unsigned NOT NULL DEFAULT '0',"
"  signal_timeout int(11) NOT NULL DEFAULT '1000',"
"  channel_timeout int(11) NOT NULL DEFAULT '3000',"
"  dvb_tuning_delay int(10) unsigned NOT NULL DEFAULT '0',"
"  contrast int(11) NOT NULL DEFAULT '0',"
"  brightness int(11) NOT NULL DEFAULT '0',"
"  colour int(11) NOT NULL DEFAULT '0',"
"  hue int(11) NOT NULL DEFAULT '0',"
"  diseqcid int(10) unsigned DEFAULT NULL,"
"  dvb_eitscan tinyint(1) NOT NULL DEFAULT '1',"
"  PRIMARY KEY (cardid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE cardinput ("
"  cardinputid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  cardid int(10) unsigned NOT NULL DEFAULT '0',"
"  sourceid int(10) unsigned NOT NULL DEFAULT '0',"
"  inputname varchar(32) NOT NULL DEFAULT '',"
"  externalcommand varchar(128) DEFAULT NULL,"
"  changer_device varchar(128) DEFAULT NULL,"
"  changer_model varchar(128) DEFAULT NULL,"
"  tunechan varchar(10) DEFAULT NULL,"
"  startchan varchar(10) DEFAULT NULL,"
"  displayname varchar(64) NOT NULL DEFAULT '',"
"  dishnet_eit tinyint(1) NOT NULL DEFAULT '0',"
"  recpriority int(11) NOT NULL DEFAULT '0',"
"  quicktune tinyint(4) NOT NULL DEFAULT '0',"
"  schedorder int(10) unsigned NOT NULL DEFAULT '0',"
"  livetvorder int(10) unsigned NOT NULL DEFAULT '0',"
"  PRIMARY KEY (cardinputid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE channel ("
"  chanid int(10) unsigned NOT NULL DEFAULT '0',"
"  channum varchar(10) NOT NULL DEFAULT '',"
"  freqid varchar(10) DEFAULT NULL,"
"  sourceid int(10) unsigned DEFAULT NULL,"
"  callsign varchar(20) NOT NULL DEFAULT '',"
"  `name` varchar(64) NOT NULL DEFAULT '',"
"  icon varchar(255) NOT NULL DEFAULT '',"
"  finetune int(11) DEFAULT NULL,"
"  videofilters varchar(255) NOT NULL DEFAULT '',"
"  xmltvid varchar(255) NOT NULL DEFAULT '',"
"  recpriority int(10) NOT NULL DEFAULT '0',"
"  contrast int(11) DEFAULT '32768',"
"  brightness int(11) DEFAULT '32768',"
"  colour int(11) DEFAULT '32768',"
"  hue int(11) DEFAULT '32768',"
"  tvformat varchar(10) NOT NULL DEFAULT 'Default',"
"  visible tinyint(1) NOT NULL DEFAULT '1',"
"  outputfilters varchar(255) NOT NULL DEFAULT '',"
"  useonairguide tinyint(1) DEFAULT '0',"
"  mplexid smallint(6) DEFAULT NULL,"
"  serviceid mediumint(8) unsigned DEFAULT NULL,"
"  tmoffset int(11) NOT NULL DEFAULT '0',"
"  atsc_major_chan int(10) unsigned NOT NULL DEFAULT '0',"
"  atsc_minor_chan int(10) unsigned NOT NULL DEFAULT '0',"
"  last_record datetime NOT NULL,"
"  default_authority varchar(32) NOT NULL DEFAULT '',"
"  commmethod int(11) NOT NULL DEFAULT '-1',"
"  iptvid smallint(6) unsigned DEFAULT NULL,"
"  PRIMARY KEY (chanid),"
"  KEY channel_src (channum,sourceid),"
"  KEY sourceid (sourceid,xmltvid,chanid),"
"  KEY visible (visible)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE channelgroup ("
"  id int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  chanid int(11) unsigned NOT NULL DEFAULT '0',"
"  grpid int(11) NOT NULL DEFAULT '1',"
"  PRIMARY KEY (id)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE channelgroupnames ("
"  grpid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  `name` varchar(64) NOT NULL DEFAULT '0',"
"  PRIMARY KEY (grpid)"
") ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;",
"CREATE TABLE channelscan ("
"  scanid int(3) unsigned NOT NULL AUTO_INCREMENT,"
"  cardid int(3) unsigned NOT NULL,"
"  sourceid int(3) unsigned NOT NULL,"
"  processed tinyint(1) unsigned NOT NULL,"
"  scandate datetime NOT NULL,"
"  PRIMARY KEY (scanid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE channelscan_channel ("
"  transportid int(6) unsigned NOT NULL,"
"  scanid int(3) unsigned NOT NULL,"
"  mplex_id smallint(6) NOT NULL,"
"  source_id int(3) unsigned NOT NULL,"
"  channel_id int(3) unsigned NOT NULL DEFAULT '0',"
"  callsign varchar(20) NOT NULL DEFAULT '',"
"  service_name varchar(64) NOT NULL DEFAULT '',"
"  chan_num varchar(10) NOT NULL DEFAULT '',"
"  service_id mediumint(8) unsigned NOT NULL DEFAULT '0',"
"  atsc_major_channel int(4) unsigned NOT NULL DEFAULT '0',"
"  atsc_minor_channel int(4) unsigned NOT NULL DEFAULT '0',"
"  use_on_air_guide tinyint(1) NOT NULL DEFAULT '0',"
"  hidden tinyint(1) NOT NULL DEFAULT '0',"
"  hidden_in_guide tinyint(1) NOT NULL DEFAULT '0',"
"  freqid varchar(10) NOT NULL DEFAULT '',"
"  icon varchar(255) NOT NULL DEFAULT '',"
"  tvformat varchar(10) NOT NULL DEFAULT 'Default',"
"  xmltvid varchar(64) NOT NULL DEFAULT '',"
"  pat_tsid int(5) unsigned NOT NULL DEFAULT '0',"
"  vct_tsid int(5) unsigned NOT NULL DEFAULT '0',"
"  vct_chan_tsid int(5) unsigned NOT NULL DEFAULT '0',"
"  sdt_tsid int(5) unsigned NOT NULL DEFAULT '0',"
"  orig_netid int(5) unsigned NOT NULL DEFAULT '0',"
"  netid int(5) unsigned NOT NULL DEFAULT '0',"
"  si_standard varchar(10) NOT NULL,"
"  in_channels_conf tinyint(1) unsigned NOT NULL DEFAULT '0',"
"  in_pat tinyint(1) unsigned NOT NULL DEFAULT '0',"
"  in_pmt tinyint(1) unsigned NOT NULL DEFAULT '0',"
"  in_vct tinyint(1) unsigned NOT NULL DEFAULT '0',"
"  in_nit tinyint(1) unsigned NOT NULL DEFAULT '0',"
"  in_sdt tinyint(1) unsigned NOT NULL DEFAULT '0',"
"  is_encrypted tinyint(1) unsigned NOT NULL DEFAULT '0',"
"  is_data_service tinyint(1) unsigned NOT NULL DEFAULT '0',"
"  is_audio_service tinyint(1) unsigned NOT NULL DEFAULT '0',"
"  is_opencable tinyint(1) unsigned NOT NULL DEFAULT '0',"
"  could_be_opencable tinyint(1) unsigned NOT NULL DEFAULT '0',"
"  decryption_status smallint(2) unsigned NOT NULL DEFAULT '0',"
"  default_authority varchar(32) NOT NULL DEFAULT ''"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE channelscan_dtv_multiplex ("
"  transportid int(6) unsigned NOT NULL AUTO_INCREMENT,"
"  scanid int(3) unsigned NOT NULL,"
"  mplexid smallint(6) unsigned NOT NULL,"
"  frequency bigint(12) unsigned NOT NULL,"
"  inversion char(1) NOT NULL DEFAULT 'a',"
"  symbolrate bigint(12) unsigned NOT NULL DEFAULT '0',"
"  fec varchar(10) NOT NULL DEFAULT 'auto',"
"  polarity char(1) NOT NULL DEFAULT '',"
"  hp_code_rate varchar(10) NOT NULL DEFAULT 'auto',"
"  mod_sys varchar(10) DEFAULT NULL,"
"  rolloff varchar(4) DEFAULT NULL,"
"  lp_code_rate varchar(10) NOT NULL DEFAULT 'auto',"
"  modulation varchar(10) NOT NULL DEFAULT 'auto',"
"  transmission_mode char(1) NOT NULL DEFAULT 'a',"
"  guard_interval varchar(10) NOT NULL DEFAULT 'auto',"
"  hierarchy varchar(10) NOT NULL DEFAULT 'auto',"
"  bandwidth char(1) NOT NULL DEFAULT 'a',"
"  sistandard varchar(10) NOT NULL,"
"  tuner_type smallint(2) unsigned NOT NULL,"
"  default_authority varchar(32) NOT NULL DEFAULT '',"
"  PRIMARY KEY (transportid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE codecparams ("
"  `profile` int(10) unsigned NOT NULL DEFAULT '0',"
"  `name` varchar(128) NOT NULL DEFAULT '',"
"  `value` varchar(128) DEFAULT NULL,"
"  PRIMARY KEY (`profile`,`name`)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE credits ("
"  person mediumint(8) unsigned NOT NULL DEFAULT '0',"
"  chanid int(10) unsigned NOT NULL DEFAULT '0',"
"  starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  role set('actor','director','producer','executive_producer','writer','guest_star','host','adapter','presenter','commentator','guest') NOT NULL DEFAULT '',"
"  UNIQUE KEY chanid (chanid,starttime,person,role),"
"  KEY person (person,role)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE customexample ("
"  rulename varchar(64) NOT NULL,"
"  fromclause varchar(10000) NOT NULL DEFAULT '',"
"  whereclause varchar(10000) NOT NULL DEFAULT '',"
"  search tinyint(4) NOT NULL DEFAULT '0',"
"  PRIMARY KEY (rulename)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE diseqc_config ("
"  cardinputid int(10) unsigned NOT NULL,"
"  diseqcid int(10) unsigned NOT NULL,"
"  `value` varchar(16) NOT NULL DEFAULT '',"
"  KEY id (cardinputid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE diseqc_tree ("
"  diseqcid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  parentid int(10) unsigned DEFAULT NULL,"
"  ordinal tinyint(3) unsigned NOT NULL,"
"  `type` varchar(16) NOT NULL DEFAULT '',"
"  subtype varchar(16) NOT NULL DEFAULT '',"
"  description varchar(32) NOT NULL DEFAULT '',"
"  switch_ports tinyint(3) unsigned NOT NULL DEFAULT '0',"
"  rotor_hi_speed float NOT NULL DEFAULT '0',"
"  rotor_lo_speed float NOT NULL DEFAULT '0',"
"  rotor_positions varchar(255) NOT NULL DEFAULT '',"
"  lnb_lof_switch int(10) NOT NULL DEFAULT '0',"
"  lnb_lof_hi int(10) NOT NULL DEFAULT '0',"
"  lnb_lof_lo int(10) NOT NULL DEFAULT '0',"
"  cmd_repeat int(11) NOT NULL DEFAULT '1',"
"  lnb_pol_inv tinyint(4) NOT NULL DEFAULT '0',"
"  address tinyint(3) unsigned NOT NULL DEFAULT '0',"
"  PRIMARY KEY (diseqcid),"
"  KEY parentid (parentid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE displayprofilegroups ("
"  `name` varchar(128) NOT NULL,"
"  hostname varchar(64) NOT NULL,"
"  profilegroupid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  PRIMARY KEY (`name`,hostname),"
"  UNIQUE KEY profilegroupid (profilegroupid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE displayprofiles ("
"  profilegroupid int(10) unsigned NOT NULL,"
"  profileid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  `value` varchar(128) NOT NULL,"
"  `data` varchar(255) NOT NULL DEFAULT '',"
"  KEY profilegroupid (profilegroupid),"
"  KEY profileid (profileid,`value`),"
"  KEY profileid_2 (profileid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE dtv_multiplex ("
"  mplexid smallint(6) NOT NULL AUTO_INCREMENT,"
"  sourceid smallint(6) DEFAULT NULL,"
"  transportid int(11) DEFAULT NULL,"
"  networkid int(11) DEFAULT NULL,"
"  frequency int(11) DEFAULT NULL,"
"  inversion char(1) DEFAULT 'a',"
"  symbolrate int(11) DEFAULT NULL,"
"  fec varchar(10) DEFAULT 'auto',"
"  polarity char(1) DEFAULT NULL,"
"  modulation varchar(10) DEFAULT 'auto',"
"  bandwidth char(1) DEFAULT 'a',"
"  lp_code_rate varchar(10) DEFAULT 'auto',"
"  transmission_mode char(1) DEFAULT 'a',"
"  guard_interval varchar(10) DEFAULT 'auto',"
"  visible smallint(1) NOT NULL DEFAULT '0',"
"  constellation varchar(10) DEFAULT 'auto',"
"  hierarchy varchar(10) DEFAULT 'auto',"
"  hp_code_rate varchar(10) DEFAULT 'auto',"
"  mod_sys varchar(10) DEFAULT NULL,"
"  rolloff varchar(4) DEFAULT NULL,"
"  sistandard varchar(10) DEFAULT 'dvb',"
"  serviceversion smallint(6) DEFAULT '33',"
"  updatetimestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,"
"  default_authority varchar(32) NOT NULL DEFAULT '',"
"  PRIMARY KEY (mplexid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE dtv_privatetypes ("
"  sitype varchar(4) NOT NULL DEFAULT '',"
"  networkid int(11) NOT NULL DEFAULT '0',"
"  private_type varchar(20) NOT NULL DEFAULT '',"
"  private_value varchar(100) NOT NULL DEFAULT ''"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE dvdbookmark ("
"  serialid varchar(16) NOT NULL DEFAULT '',"
"  `name` varchar(32) DEFAULT NULL,"
"  title smallint(6) NOT NULL DEFAULT '0',"
"  audionum tinyint(4) NOT NULL DEFAULT '-1',"
"  subtitlenum tinyint(4) NOT NULL DEFAULT '-1',"
"  framenum bigint(20) NOT NULL DEFAULT '0',"
"  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,"
"  PRIMARY KEY (serialid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE dvdinput ("
"  intid int(10) unsigned NOT NULL,"
"  hsize int(10) unsigned DEFAULT NULL,"
"  vsize int(10) unsigned DEFAULT NULL,"
"  ar_num int(10) unsigned DEFAULT NULL,"
"  ar_denom int(10) unsigned DEFAULT NULL,"
"  fr_code int(10) unsigned DEFAULT NULL,"
"  letterbox tinyint(1) DEFAULT NULL,"
"  v_format varchar(16) DEFAULT NULL,"
"  PRIMARY KEY (intid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE dvdtranscode ("
"  intid int(11) NOT NULL AUTO_INCREMENT,"
"  input int(10) unsigned DEFAULT NULL,"
"  `name` varchar(128) NOT NULL,"
"  sync_mode int(10) unsigned DEFAULT NULL,"
"  use_yv12 tinyint(1) DEFAULT NULL,"
"  cliptop int(11) DEFAULT NULL,"
"  clipbottom int(11) DEFAULT NULL,"
"  clipleft int(11) DEFAULT NULL,"
"  clipright int(11) DEFAULT NULL,"
"  f_resize_h int(11) DEFAULT NULL,"
"  f_resize_w int(11) DEFAULT NULL,"
"  hq_resize_h int(11) DEFAULT NULL,"
"  hq_resize_w int(11) DEFAULT NULL,"
"  grow_h int(11) DEFAULT NULL,"
"  grow_w int(11) DEFAULT NULL,"
"  clip2top int(11) DEFAULT NULL,"
"  clip2bottom int(11) DEFAULT NULL,"
"  clip2left int(11) DEFAULT NULL,"
"  clip2right int(11) DEFAULT NULL,"
"  codec varchar(128) NOT NULL,"
"  codec_param varchar(128) DEFAULT NULL,"
"  bitrate int(11) DEFAULT NULL,"
"  a_sample_r int(11) DEFAULT NULL,"
"  a_bitrate int(11) DEFAULT NULL,"
"  two_pass tinyint(1) DEFAULT NULL,"
"  tc_param varchar(128) DEFAULT NULL,"
"  PRIMARY KEY (intid)"
") ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;",
"CREATE TABLE eit_cache ("
"  chanid int(10) NOT NULL,"
"  eventid int(10) unsigned NOT NULL DEFAULT '0',"
"  tableid tinyint(3) unsigned NOT NULL,"
"  version tinyint(3) unsigned NOT NULL,"
"  endtime int(10) unsigned NOT NULL,"
"  `status` tinyint(4) NOT NULL DEFAULT '0',"
"  PRIMARY KEY (chanid,eventid,`status`)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE filemarkup ("
"  filename text NOT NULL,"
"  mark mediumint(8) unsigned NOT NULL DEFAULT '0',"
"  `offset` bigint(20) unsigned DEFAULT NULL,"
"  `type` tinyint(4) NOT NULL DEFAULT '0',"
"  KEY filename (filename(255))"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE housekeeping ("
"  tag varchar(64) NOT NULL DEFAULT '',"
"  lastrun datetime DEFAULT NULL,"
"  PRIMARY KEY (tag)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE inputgroup ("
"  cardinputid int(10) unsigned NOT NULL,"
"  inputgroupid int(10) unsigned NOT NULL,"
"  inputgroupname varchar(32) NOT NULL"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE internetcontent ("
"  `name` varchar(255) NOT NULL,"
"  thumbnail varchar(255) DEFAULT NULL,"
"  `type` smallint(3) NOT NULL,"
"  author varchar(128) NOT NULL,"
"  description text NOT NULL,"
"  commandline text NOT NULL,"
"  version double NOT NULL,"
"  updated datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  search tinyint(1) NOT NULL,"
"  tree tinyint(1) NOT NULL,"
"  podcast tinyint(1) NOT NULL,"
"  download tinyint(1) NOT NULL,"
"  `host` varchar(128) DEFAULT NULL"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE internetcontentarticles ("
"  feedtitle varchar(255) NOT NULL,"
"  path text NOT NULL,"
"  paththumb text NOT NULL,"
"  title varchar(255) NOT NULL,"
"  subtitle varchar(255) NOT NULL,"
"  season smallint(5) NOT NULL DEFAULT '0',"
"  episode smallint(5) NOT NULL DEFAULT '0',"
"  description text NOT NULL,"
"  url text NOT NULL,"
"  `type` smallint(3) NOT NULL,"
"  thumbnail text NOT NULL,"
"  mediaURL text NOT NULL,"
"  author varchar(255) NOT NULL,"
"  `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  `time` int(11) NOT NULL,"
"  rating varchar(255) NOT NULL,"
"  filesize bigint(20) NOT NULL,"
"  player varchar(255) NOT NULL,"
"  playerargs text NOT NULL,"
"  download varchar(255) NOT NULL,"
"  downloadargs text NOT NULL,"
"  width smallint(6) NOT NULL,"
"  height smallint(6) NOT NULL,"
"  `language` varchar(128) NOT NULL,"
"  podcast tinyint(1) NOT NULL,"
"  downloadable tinyint(1) NOT NULL,"
"  customhtml tinyint(1) NOT NULL,"
"  countries varchar(255) NOT NULL"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE inuseprograms ("
"  chanid int(10) unsigned NOT NULL DEFAULT '0',"
"  starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  recusage varchar(128) NOT NULL DEFAULT '',"
"  lastupdatetime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  hostname varchar(64) NOT NULL DEFAULT '',"
"  rechost varchar(64) NOT NULL,"
"  recdir varchar(255) NOT NULL DEFAULT '',"
"  KEY chanid (chanid,starttime),"
"  KEY recusage (recusage,lastupdatetime)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE iptv_channel ("
"  iptvid smallint(6) unsigned NOT NULL AUTO_INCREMENT,"
"  chanid int(10) unsigned NOT NULL,"
"  url text NOT NULL,"
"  `type` set('data','rfc2733-1','rfc2733-2','rfc5109-1','rfc5109-2','smpte2022-1','smpte2022-2') DEFAULT NULL,"
"  bitrate int(10) unsigned NOT NULL,"
"  PRIMARY KEY (iptvid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE jobqueue ("
"  id int(11) NOT NULL AUTO_INCREMENT,"
"  chanid int(10) NOT NULL DEFAULT '0',"
"  starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  inserttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  `type` int(11) NOT NULL DEFAULT '0',"
"  cmds int(11) NOT NULL DEFAULT '0',"
"  flags int(11) NOT NULL DEFAULT '0',"
"  `status` int(11) NOT NULL DEFAULT '0',"
"  statustime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,"
"  hostname varchar(64) NOT NULL DEFAULT '',"
"  args blob NOT NULL,"
"  `comment` varchar(128) NOT NULL DEFAULT '',"
"  schedruntime datetime NOT NULL DEFAULT '2007-01-01 00:00:00',"
"  PRIMARY KEY (id),"
"  UNIQUE KEY chanid (chanid,starttime,`type`,inserttime)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE jumppoints ("
"  destination varchar(128) NOT NULL DEFAULT '',"
"  description varchar(255) DEFAULT NULL,"
"  keylist varchar(128) DEFAULT NULL,"
"  hostname varchar(64) NOT NULL DEFAULT '',"
"  PRIMARY KEY (destination,hostname)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE keybindings ("
"  `context` varchar(32) NOT NULL DEFAULT '',"
"  `action` varchar(32) NOT NULL DEFAULT '',"
"  description varchar(255) DEFAULT NULL,"
"  keylist varchar(128) DEFAULT NULL,"
"  hostname varchar(64) NOT NULL DEFAULT '',"
"  PRIMARY KEY (`context`,`action`,hostname)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE keyword ("
"  phrase varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',"
"  searchtype int(10) unsigned NOT NULL DEFAULT '3',"
"  UNIQUE KEY phrase (phrase,searchtype)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE livestream ("
"  id int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  width int(10) unsigned NOT NULL,"
"  height int(10) unsigned NOT NULL,"
"  bitrate int(10) unsigned NOT NULL,"
"  audiobitrate int(10) unsigned NOT NULL,"
"  samplerate int(10) unsigned NOT NULL,"
"  audioonlybitrate int(10) unsigned NOT NULL,"
"  segmentsize int(10) unsigned NOT NULL DEFAULT '10',"
"  maxsegments int(10) unsigned NOT NULL DEFAULT '0',"
"  startsegment int(10) unsigned NOT NULL DEFAULT '0',"
"  currentsegment int(10) unsigned NOT NULL DEFAULT '0',"
"  segmentcount int(10) unsigned NOT NULL DEFAULT '0',"
"  percentcomplete int(10) unsigned NOT NULL DEFAULT '0',"
"  created datetime NOT NULL,"
"  lastmodified datetime NOT NULL,"
"  relativeurl varchar(512) NOT NULL,"
"  fullurl varchar(1024) NOT NULL,"
"  `status` int(10) unsigned NOT NULL DEFAULT '0',"
"  statusmessage varchar(256) NOT NULL,"
"  sourcefile varchar(512) NOT NULL,"
"  sourcehost varchar(64) NOT NULL,"
"  sourcewidth int(10) unsigned NOT NULL DEFAULT '0',"
"  sourceheight int(10) unsigned NOT NULL DEFAULT '0',"
"  outdir varchar(256) NOT NULL,"
"  outbase varchar(128) NOT NULL,"
"  PRIMARY KEY (id)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE logging ("
"  id bigint(20) unsigned NOT NULL AUTO_INCREMENT,"
"  `host` varchar(64) NOT NULL DEFAULT '',"
"  application varchar(64) NOT NULL DEFAULT '',"
"  pid int(11) NOT NULL DEFAULT '0',"
"  tid int(11) NOT NULL DEFAULT '0',"
"  thread varchar(64) NOT NULL DEFAULT '',"
"  filename varchar(255) NOT NULL DEFAULT '',"
"  line int(11) NOT NULL DEFAULT '0',"
"  `function` varchar(255) NOT NULL DEFAULT '',"
"  msgtime datetime NOT NULL,"
"  `level` int(11) NOT NULL DEFAULT '0',"
"  message varchar(2048) NOT NULL,"
"  PRIMARY KEY (id),"
"  KEY `host` (`host`,application,pid,msgtime),"
"  KEY msgtime (msgtime),"
"  KEY `level` (`level`)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE mythlog ("
"  logid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  module varchar(32) NOT NULL DEFAULT '',"
"  priority int(11) NOT NULL DEFAULT '0',"
"  acknowledged tinyint(1) DEFAULT '0',"
"  logdate datetime DEFAULT NULL,"
"  `host` varchar(128) DEFAULT NULL,"
"  message varchar(255) NOT NULL DEFAULT '',"
"  details varchar(16000) NOT NULL DEFAULT '',"
"  PRIMARY KEY (logid),"
"  KEY module (module)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE oldfind ("
"  recordid int(11) NOT NULL DEFAULT '0',"
"  findid int(11) NOT NULL DEFAULT '0',"
"  PRIMARY KEY (recordid,findid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE oldprogram ("
"  oldtitle varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',"
"  airdate datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  PRIMARY KEY (oldtitle)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE oldrecorded ("
"  chanid int(10) unsigned NOT NULL DEFAULT '0',"
"  starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  endtime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  title varchar(128) NOT NULL DEFAULT '',"
"  subtitle varchar(128) NOT NULL DEFAULT '',"
"  description varchar(16000) NOT NULL DEFAULT '',"
"  season smallint(5) NOT NULL,"
"  episode smallint(5) NOT NULL,"
"  category varchar(64) NOT NULL DEFAULT '',"
"  seriesid varchar(40) NOT NULL DEFAULT '',"
"  programid varchar(40) NOT NULL DEFAULT '',"
"  inetref varchar(40) NOT NULL,"
"  findid int(11) NOT NULL DEFAULT '0',"
"  recordid int(11) NOT NULL DEFAULT '0',"
"  station varchar(20) NOT NULL DEFAULT '',"
"  rectype int(10) unsigned NOT NULL DEFAULT '0',"
"  `duplicate` tinyint(1) NOT NULL DEFAULT '0',"
"  recstatus int(11) NOT NULL DEFAULT '0',"
"  reactivate smallint(6) NOT NULL DEFAULT '0',"
"  generic tinyint(1) NOT NULL,"
"  future tinyint(1) NOT NULL DEFAULT '0',"
"  PRIMARY KEY (station,starttime,title),"
"  KEY endtime (endtime),"
"  KEY title (title),"
"  KEY seriesid (seriesid),"
"  KEY programid (programid),"
"  KEY recordid (recordid),"
"  KEY recstatus (recstatus,programid,seriesid),"
"  KEY recstatus_2 (recstatus,title,subtitle),"
"  KEY future (future),"
"  KEY chanid (chanid,starttime),"
"  KEY subtitle (subtitle),"
"  KEY description (description(255))"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE people ("
"  person mediumint(8) unsigned NOT NULL AUTO_INCREMENT,"
"  `name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',"
"  PRIMARY KEY (person),"
"  UNIQUE KEY `name` (`name`(41))"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE pidcache ("
"  chanid smallint(6) NOT NULL DEFAULT '0',"
"  pid int(11) NOT NULL DEFAULT '-1',"
"  tableid int(11) NOT NULL DEFAULT '-1',"
"  KEY chanid (chanid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE playgroup ("
"  `name` varchar(32) NOT NULL DEFAULT '',"
"  titlematch varchar(255) NOT NULL DEFAULT '',"
"  skipahead int(11) NOT NULL DEFAULT '0',"
"  skipback int(11) NOT NULL DEFAULT '0',"
"  timestretch int(11) NOT NULL DEFAULT '0',"
"  jump int(11) NOT NULL DEFAULT '0',"
"  PRIMARY KEY (`name`)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE powerpriority ("
"  priorityname varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,"
"  recpriority int(10) NOT NULL DEFAULT '0',"
"  selectclause varchar(16000) NOT NULL DEFAULT '',"
"  PRIMARY KEY (priorityname)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE profilegroups ("
"  id int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  `name` varchar(128) DEFAULT NULL,"
"  cardtype varchar(32) NOT NULL DEFAULT 'V4L',"
"  is_default int(1) DEFAULT '0',"
"  hostname varchar(64) DEFAULT NULL,"
"  PRIMARY KEY (id),"
"  UNIQUE KEY `name` (`name`,hostname),"
"  KEY cardtype (cardtype)"
") ENGINE=MyISAM AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;",
"CREATE TABLE program ("
"  chanid int(10) unsigned NOT NULL DEFAULT '0',"
"  starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  endtime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  title varchar(128) NOT NULL DEFAULT '',"
"  subtitle varchar(128) NOT NULL DEFAULT '',"
"  description varchar(16000) NOT NULL DEFAULT '',"
"  category varchar(64) NOT NULL DEFAULT '',"
"  category_type varchar(64) NOT NULL DEFAULT '',"
"  airdate year(4) NOT NULL DEFAULT '0000',"
"  stars float NOT NULL DEFAULT '0',"
"  previouslyshown tinyint(4) NOT NULL DEFAULT '0',"
"  title_pronounce varchar(128) NOT NULL DEFAULT '',"
"  stereo tinyint(1) NOT NULL DEFAULT '0',"
"  subtitled tinyint(1) NOT NULL DEFAULT '0',"
"  hdtv tinyint(1) NOT NULL DEFAULT '0',"
"  closecaptioned tinyint(1) NOT NULL DEFAULT '0',"
"  partnumber int(11) NOT NULL DEFAULT '0',"
"  parttotal int(11) NOT NULL DEFAULT '0',"
"  seriesid varchar(64) NOT NULL DEFAULT '',"
"  originalairdate date DEFAULT NULL,"
"  showtype varchar(30) NOT NULL DEFAULT '',"
"  colorcode varchar(20) NOT NULL DEFAULT '',"
"  syndicatedepisodenumber varchar(20) NOT NULL DEFAULT '',"
"  programid varchar(64) NOT NULL DEFAULT '',"
"  manualid int(10) unsigned NOT NULL DEFAULT '0',"
"  generic tinyint(1) DEFAULT '0',"
"  listingsource int(11) NOT NULL DEFAULT '0',"
"  `first` tinyint(1) NOT NULL DEFAULT '0',"
"  `last` tinyint(1) NOT NULL DEFAULT '0',"
"  audioprop set('STEREO','MONO','SURROUND','DOLBY','HARDHEAR','VISUALIMPAIR') NOT NULL,"
"  subtitletypes set('HARDHEAR','NORMAL','ONSCREEN','SIGNED') NOT NULL,"
"  videoprop set('HDTV','WIDESCREEN','AVC') NOT NULL,"
"  PRIMARY KEY (chanid,starttime,manualid),"
"  KEY endtime (endtime),"
"  KEY title (title),"
"  KEY title_pronounce (title_pronounce),"
"  KEY seriesid (seriesid),"
"  KEY id_start_end (chanid,starttime,endtime),"
"  KEY program_manualid (manualid),"
"  KEY previouslyshown (previouslyshown),"
"  KEY programid (programid,starttime),"
"  KEY starttime (starttime),"
"  KEY subtitle (subtitle),"
"  KEY description (description(255))"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE programgenres ("
"  chanid int(10) unsigned NOT NULL DEFAULT '0',"
"  starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  relevance char(1) NOT NULL DEFAULT '',"
"  genre varchar(30) DEFAULT NULL,"
"  PRIMARY KEY (chanid,starttime,relevance),"
"  KEY genre (genre)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE programrating ("
"  chanid int(10) unsigned NOT NULL DEFAULT '0',"
"  starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  `system` varchar(8) DEFAULT NULL,"
"  rating varchar(16) DEFAULT NULL,"
"  UNIQUE KEY chanid (chanid,starttime,`system`,rating),"
"  KEY starttime (starttime,`system`)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE recgrouppassword ("
"  recgroup varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',"
"  `password` varchar(10) NOT NULL DEFAULT '',"
"  PRIMARY KEY (recgroup)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE record ("
"  recordid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  `type` int(10) unsigned NOT NULL DEFAULT '0',"
"  chanid int(10) unsigned DEFAULT NULL,"
"  starttime time NOT NULL DEFAULT '00:00:00',"
"  startdate date NOT NULL DEFAULT '0000-00-00',"
"  endtime time NOT NULL DEFAULT '00:00:00',"
"  enddate date NOT NULL DEFAULT '0000-00-00',"
"  title varchar(128) NOT NULL DEFAULT '',"
"  subtitle varchar(128) NOT NULL DEFAULT '',"
"  description varchar(16000) NOT NULL DEFAULT '',"
"  season smallint(5) NOT NULL,"
"  episode smallint(5) NOT NULL,"
"  category varchar(64) NOT NULL DEFAULT '',"
"  `profile` varchar(128) NOT NULL DEFAULT 'Default',"
"  recpriority int(10) NOT NULL DEFAULT '0',"
"  autoexpire int(11) NOT NULL DEFAULT '0',"
"  maxepisodes int(11) NOT NULL DEFAULT '0',"
"  maxnewest int(11) NOT NULL DEFAULT '0',"
"  startoffset int(11) NOT NULL DEFAULT '0',"
"  endoffset int(11) NOT NULL DEFAULT '0',"
"  recgroup varchar(32) NOT NULL DEFAULT 'Default',"
"  dupmethod int(11) NOT NULL DEFAULT '6',"
"  dupin int(11) NOT NULL DEFAULT '15',"
"  station varchar(20) NOT NULL DEFAULT '',"
"  seriesid varchar(40) NOT NULL DEFAULT '',"
"  programid varchar(40) NOT NULL DEFAULT '',"
"  inetref varchar(40) NOT NULL,"
"  search int(10) unsigned NOT NULL DEFAULT '0',"
"  autotranscode tinyint(1) NOT NULL DEFAULT '0',"
"  autocommflag tinyint(1) NOT NULL DEFAULT '0',"
"  autouserjob1 tinyint(1) NOT NULL DEFAULT '0',"
"  autouserjob2 tinyint(1) NOT NULL DEFAULT '0',"
"  autouserjob3 tinyint(1) NOT NULL DEFAULT '0',"
"  autouserjob4 tinyint(1) NOT NULL DEFAULT '0',"
"  autometadata tinyint(1) NOT NULL DEFAULT '0',"
"  findday tinyint(4) NOT NULL DEFAULT '0',"
"  findtime time NOT NULL DEFAULT '00:00:00',"
"  findid int(11) NOT NULL DEFAULT '0',"
"  inactive tinyint(1) NOT NULL DEFAULT '0',"
"  parentid int(11) NOT NULL DEFAULT '0',"
"  transcoder int(11) NOT NULL DEFAULT '0',"
"  playgroup varchar(32) NOT NULL DEFAULT 'Default',"
"  prefinput int(10) NOT NULL DEFAULT '0',"
"  next_record datetime NOT NULL,"
"  last_record datetime NOT NULL,"
"  last_delete datetime NOT NULL,"
"  storagegroup varchar(32) NOT NULL DEFAULT 'Default',"
"  avg_delay int(11) NOT NULL DEFAULT '100',"
"  filter int(10) unsigned NOT NULL DEFAULT '0',"
"  PRIMARY KEY (recordid),"
"  KEY chanid (chanid,starttime),"
"  KEY title (title),"
"  KEY seriesid (seriesid),"
"  KEY programid (programid),"
"  KEY maxepisodes (maxepisodes),"
"  KEY search (search),"
"  KEY `type` (`type`)"
") ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;",
"CREATE TABLE recorded ("
"  chanid int(10) unsigned NOT NULL DEFAULT '0',"
"  starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  endtime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  title varchar(128) NOT NULL DEFAULT '',"
"  subtitle varchar(128) NOT NULL DEFAULT '',"
"  description varchar(16000) NOT NULL DEFAULT '',"
"  season smallint(5) NOT NULL,"
"  episode smallint(5) NOT NULL,"
"  category varchar(64) NOT NULL DEFAULT '',"
"  hostname varchar(64) NOT NULL DEFAULT '',"
"  bookmark tinyint(1) NOT NULL DEFAULT '0',"
"  editing int(10) unsigned NOT NULL DEFAULT '0',"
"  cutlist tinyint(1) NOT NULL DEFAULT '0',"
"  autoexpire int(11) NOT NULL DEFAULT '0',"
"  commflagged int(10) unsigned NOT NULL DEFAULT '0',"
"  recgroup varchar(32) NOT NULL DEFAULT 'Default',"
"  recordid int(11) DEFAULT NULL,"
"  seriesid varchar(40) NOT NULL DEFAULT '',"
"  programid varchar(40) NOT NULL DEFAULT '',"
"  inetref varchar(40) NOT NULL,"
"  lastmodified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,"
"  filesize bigint(20) NOT NULL DEFAULT '0',"
"  stars float NOT NULL DEFAULT '0',"
"  previouslyshown tinyint(1) DEFAULT '0',"
"  originalairdate date DEFAULT NULL,"
"  `preserve` tinyint(1) NOT NULL DEFAULT '0',"
"  findid int(11) NOT NULL DEFAULT '0',"
"  deletepending tinyint(1) NOT NULL DEFAULT '0',"
"  transcoder int(11) NOT NULL DEFAULT '0',"
"  timestretch float NOT NULL DEFAULT '1',"
"  recpriority int(11) NOT NULL DEFAULT '0',"
"  basename varchar(255) NOT NULL,"
"  progstart datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  progend datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  playgroup varchar(32) NOT NULL DEFAULT 'Default',"
"  `profile` varchar(32) NOT NULL DEFAULT '',"
"  `duplicate` tinyint(1) NOT NULL DEFAULT '0',"
"  transcoded tinyint(1) NOT NULL DEFAULT '0',"
"  watched tinyint(4) NOT NULL DEFAULT '0',"
"  storagegroup varchar(32) NOT NULL DEFAULT 'Default',"
"  bookmarkupdate timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  PRIMARY KEY (chanid,starttime),"
"  KEY endtime (endtime),"
"  KEY seriesid (seriesid),"
"  KEY programid (programid),"
"  KEY title (title),"
"  KEY recordid (recordid),"
"  KEY deletepending (deletepending,lastmodified),"
"  KEY recgroup (recgroup,endtime)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE recordedartwork ("
"  inetref varchar(255) NOT NULL,"
"  season smallint(5) NOT NULL,"
"  `host` text NOT NULL,"
"  coverart text NOT NULL,"
"  fanart text NOT NULL,"
"  banner text NOT NULL"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE recordedcredits ("
"  person mediumint(8) unsigned NOT NULL DEFAULT '0',"
"  chanid int(10) unsigned NOT NULL DEFAULT '0',"
"  starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  role set('actor','director','producer','executive_producer','writer','guest_star','host','adapter','presenter','commentator','guest') NOT NULL DEFAULT '',"
"  UNIQUE KEY chanid (chanid,starttime,person,role),"
"  KEY person (person,role)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE recordedfile ("
"  chanid int(10) unsigned NOT NULL DEFAULT '0',"
"  starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  basename varchar(128) NOT NULL DEFAULT '',"
"  filesize bigint(20) NOT NULL DEFAULT '0',"
"  width smallint(5) unsigned NOT NULL DEFAULT '0',"
"  height smallint(5) unsigned NOT NULL DEFAULT '0',"
"  fps float(6,3) NOT NULL DEFAULT '0.000',"
"  aspect float(8,6) NOT NULL DEFAULT '0.000000',"
"  audio_sample_rate smallint(5) unsigned NOT NULL DEFAULT '0',"
"  audio_bits_per_sample smallint(5) unsigned NOT NULL DEFAULT '0',"
"  audio_channels tinyint(3) unsigned NOT NULL DEFAULT '0',"
"  audio_type varchar(255) NOT NULL DEFAULT '',"
"  video_type varchar(255) NOT NULL DEFAULT '',"
"  `comment` varchar(255) NOT NULL DEFAULT '',"
"  hostname varchar(64) NOT NULL,"
"  storagegroup varchar(32) NOT NULL,"
"  id int(11) NOT NULL AUTO_INCREMENT,"
"  PRIMARY KEY (id),"
"  UNIQUE KEY chanid (chanid,starttime,basename),"
"  KEY basename (basename)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE recordedmarkup ("
"  chanid int(10) unsigned NOT NULL DEFAULT '0',"
"  starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  mark mediumint(8) unsigned NOT NULL DEFAULT '0',"
"  `type` tinyint(4) NOT NULL DEFAULT '0',"
"  `data` int(11) unsigned DEFAULT NULL,"
"  PRIMARY KEY (chanid,starttime,`type`,mark)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE recordedprogram ("
"  chanid int(10) unsigned NOT NULL DEFAULT '0',"
"  starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  endtime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  title varchar(128) NOT NULL DEFAULT '',"
"  subtitle varchar(128) NOT NULL DEFAULT '',"
"  description varchar(16000) NOT NULL DEFAULT '',"
"  category varchar(64) NOT NULL DEFAULT '',"
"  category_type varchar(64) NOT NULL DEFAULT '',"
"  airdate year(4) NOT NULL DEFAULT '0000',"
"  stars float unsigned NOT NULL DEFAULT '0',"
"  previouslyshown tinyint(4) NOT NULL DEFAULT '0',"
"  title_pronounce varchar(128) NOT NULL DEFAULT '',"
"  stereo tinyint(1) NOT NULL DEFAULT '0',"
"  subtitled tinyint(1) NOT NULL DEFAULT '0',"
"  hdtv tinyint(1) NOT NULL DEFAULT '0',"
"  closecaptioned tinyint(1) NOT NULL DEFAULT '0',"
"  partnumber int(11) NOT NULL DEFAULT '0',"
"  parttotal int(11) NOT NULL DEFAULT '0',"
"  seriesid varchar(40) NOT NULL DEFAULT '',"
"  originalairdate date DEFAULT NULL,"
"  showtype varchar(30) NOT NULL DEFAULT '',"
"  colorcode varchar(20) NOT NULL DEFAULT '',"
"  syndicatedepisodenumber varchar(20) NOT NULL DEFAULT '',"
"  programid varchar(40) NOT NULL DEFAULT '',"
"  manualid int(10) unsigned NOT NULL DEFAULT '0',"
"  generic tinyint(1) DEFAULT '0',"
"  listingsource int(11) NOT NULL DEFAULT '0',"
"  `first` tinyint(1) NOT NULL DEFAULT '0',"
"  `last` tinyint(1) NOT NULL DEFAULT '0',"
"  audioprop set('STEREO','MONO','SURROUND','DOLBY','HARDHEAR','VISUALIMPAIR') NOT NULL,"
"  subtitletypes set('HARDHEAR','NORMAL','ONSCREEN','SIGNED') NOT NULL,"
"  videoprop set('HDTV','WIDESCREEN','AVC','720','1080','DAMAGED') NOT NULL,"
"  PRIMARY KEY (chanid,starttime,manualid),"
"  KEY endtime (endtime),"
"  KEY title (title),"
"  KEY title_pronounce (title_pronounce),"
"  KEY seriesid (seriesid),"
"  KEY programid (programid),"
"  KEY id_start_end (chanid,starttime,endtime)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE recordedrating ("
"  chanid int(10) unsigned NOT NULL DEFAULT '0',"
"  starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  `system` varchar(8) DEFAULT NULL,"
"  rating varchar(16) DEFAULT NULL,"
"  UNIQUE KEY chanid (chanid,starttime,`system`,rating),"
"  KEY starttime (starttime,`system`)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE recordedseek ("
"  chanid int(10) unsigned NOT NULL DEFAULT '0',"
"  starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  mark mediumint(8) unsigned NOT NULL DEFAULT '0',"
"  `offset` bigint(20) unsigned NOT NULL,"
"  `type` tinyint(4) NOT NULL DEFAULT '0',"
"  PRIMARY KEY (chanid,starttime,`type`,mark)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE recordfilter ("
"  filterid int(10) unsigned NOT NULL,"
"  description varchar(64) DEFAULT NULL,"
"  clause varchar(256) DEFAULT NULL,"
"  newruledefault tinyint(1) DEFAULT '0',"
"  PRIMARY KEY (filterid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE recordingprofiles ("
"  id int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  `name` varchar(128) DEFAULT NULL,"
"  videocodec varchar(128) DEFAULT NULL,"
"  audiocodec varchar(128) DEFAULT NULL,"
"  profilegroup int(10) unsigned NOT NULL DEFAULT '0',"
"  PRIMARY KEY (id),"
"  KEY profilegroup (profilegroup)"
") ENGINE=MyISAM AUTO_INCREMENT=70 DEFAULT CHARSET=utf8;",
"CREATE TABLE recordmatch ("
"  recordid int(10) unsigned NOT NULL,"
"  chanid int(10) unsigned NOT NULL,"
"  starttime datetime NOT NULL,"
"  manualid int(10) unsigned NOT NULL,"
"  oldrecduplicate tinyint(1) DEFAULT NULL,"
"  recduplicate tinyint(1) DEFAULT NULL,"
"  findduplicate tinyint(1) DEFAULT NULL,"
"  oldrecstatus int(11) DEFAULT NULL,"
"  findid int(11) NOT NULL DEFAULT '0',"
"  UNIQUE KEY recordid (recordid,chanid,starttime),"
"  KEY chanid (chanid,starttime,manualid),"
"  KEY recordid_2 (recordid,findid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE scannerfile ("
"  fileid bigint(20) unsigned NOT NULL AUTO_INCREMENT,"
"  filesize bigint(20) unsigned NOT NULL DEFAULT '0',"
"  filehash varchar(64) NOT NULL DEFAULT '',"
"  added timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,"
"  PRIMARY KEY (fileid),"
"  UNIQUE KEY filehash (filehash)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE scannerpath ("
"  fileid bigint(20) unsigned NOT NULL,"
"  hostname varchar(64) NOT NULL DEFAULT 'localhost',"
"  storagegroup varchar(32) NOT NULL DEFAULT 'Default',"
"  filename varchar(255) NOT NULL DEFAULT '',"
"  PRIMARY KEY (fileid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE settings ("
"  `value` varchar(128) NOT NULL DEFAULT '',"
"  `data` varchar(16000) NOT NULL DEFAULT '',"
"  hostname varchar(64) DEFAULT NULL,"
"  KEY `value` (`value`,hostname)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE storagegroup ("
"  id int(11) NOT NULL AUTO_INCREMENT,"
"  groupname varchar(32) NOT NULL,"
"  hostname varchar(64) NOT NULL DEFAULT '',"
"  dirname varchar(235) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',"
"  PRIMARY KEY (id),"
"  UNIQUE KEY grouphostdir (groupname,hostname,dirname),"
"  KEY hostname (hostname)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE tvchain ("
"  chanid int(10) unsigned NOT NULL DEFAULT '0',"
"  starttime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  chainid varchar(128) NOT NULL DEFAULT '',"
"  chainpos int(10) NOT NULL DEFAULT '0',"
"  discontinuity tinyint(1) NOT NULL DEFAULT '0',"
"  watching int(10) NOT NULL DEFAULT '0',"
"  hostprefix varchar(128) NOT NULL DEFAULT '',"
"  cardtype varchar(32) NOT NULL DEFAULT 'V4L',"
"  input varchar(32) NOT NULL DEFAULT '',"
"  channame varchar(32) NOT NULL DEFAULT '',"
"  endtime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',"
"  PRIMARY KEY (chanid,starttime)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE tvosdmenu ("
"  osdcategory varchar(32) NOT NULL,"
"  livetv tinyint(4) NOT NULL DEFAULT '0',"
"  recorded tinyint(4) NOT NULL DEFAULT '0',"
"  video tinyint(4) NOT NULL DEFAULT '0',"
"  dvd tinyint(4) NOT NULL DEFAULT '0',"
"  description varchar(32) NOT NULL,"
"  PRIMARY KEY (osdcategory)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE upnpmedia ("
"  intid int(10) unsigned NOT NULL DEFAULT '0',"
"  class varchar(64) NOT NULL DEFAULT '',"
"  itemtype varchar(128) NOT NULL DEFAULT '',"
"  parentid int(10) unsigned NOT NULL DEFAULT '0',"
"  itemproperties varchar(255) NOT NULL DEFAULT '',"
"  filepath varchar(512) NOT NULL DEFAULT '',"
"  title varchar(255) NOT NULL DEFAULT '',"
"  filename varchar(512) NOT NULL DEFAULT '',"
"  coverart varchar(512) NOT NULL DEFAULT '',"
"  PRIMARY KEY (intid),"
"  KEY class (class),"
"  KEY filepath (filepath(333)),"
"  KEY parentid (parentid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE videocast ("
"  intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  cast varchar(128) NOT NULL,"
"  PRIMARY KEY (intid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE videocategory ("
"  intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  category varchar(128) NOT NULL,"
"  PRIMARY KEY (intid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE videocollection ("
"  intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  title varchar(256) NOT NULL,"
"  contenttype set('MOVIE','TELEVISION','ADULT','MUSICVIDEO','HOMEVIDEO') NOT NULL DEFAULT '',"
"  plot text,"
"  network varchar(128) DEFAULT NULL,"
"  collectionref varchar(128) NOT NULL,"
"  certification varchar(128) DEFAULT NULL,"
"  genre varchar(128) DEFAULT '',"
"  releasedate date DEFAULT NULL,"
"  `language` varchar(10) DEFAULT NULL,"
"  `status` varchar(64) DEFAULT NULL,"
"  rating float DEFAULT '0',"
"  ratingcount int(10) DEFAULT '0',"
"  runtime smallint(5) unsigned DEFAULT '0',"
"  banner text,"
"  fanart text,"
"  coverart text,"
"  PRIMARY KEY (intid),"
"  KEY title (title)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE videocountry ("
"  intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  country varchar(128) NOT NULL,"
"  PRIMARY KEY (intid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE videogenre ("
"  intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  genre varchar(128) NOT NULL,"
"  PRIMARY KEY (intid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE videometadata ("
"  intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  title varchar(128) NOT NULL,"
"  subtitle text NOT NULL,"
"  tagline varchar(255) DEFAULT NULL,"
"  director varchar(128) NOT NULL,"
"  studio varchar(128) DEFAULT NULL,"
"  plot text,"
"  rating varchar(128) NOT NULL,"
"  inetref varchar(255) NOT NULL,"
"  collectionref int(10) NOT NULL DEFAULT '-1',"
"  homepage text NOT NULL,"
"  `year` int(10) unsigned NOT NULL,"
"  releasedate date NOT NULL,"
"  userrating float NOT NULL,"
"  length int(10) unsigned NOT NULL,"
"  playcount int(10) NOT NULL DEFAULT '0',"
"  season smallint(5) unsigned NOT NULL DEFAULT '0',"
"  episode smallint(5) unsigned NOT NULL DEFAULT '0',"
"  showlevel int(10) unsigned NOT NULL,"
"  filename text NOT NULL,"
"  `hash` varchar(128) NOT NULL,"
"  coverfile text NOT NULL,"
"  childid int(11) NOT NULL DEFAULT '-1',"
"  browse tinyint(1) NOT NULL DEFAULT '1',"
"  watched tinyint(1) NOT NULL DEFAULT '0',"
"  processed tinyint(1) NOT NULL DEFAULT '0',"
"  playcommand varchar(255) DEFAULT NULL,"
"  category int(10) unsigned NOT NULL DEFAULT '0',"
"  trailer text,"
"  `host` text NOT NULL,"
"  screenshot text,"
"  banner text,"
"  fanart text,"
"  insertdate timestamp NULL DEFAULT CURRENT_TIMESTAMP,"
"  contenttype set('MOVIE','TELEVISION','ADULT','MUSICVIDEO','HOMEVIDEO') NOT NULL DEFAULT '',"
"  PRIMARY KEY (intid),"
"  KEY director (director),"
"  KEY title (title)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE videometadatacast ("
"  idvideo int(10) unsigned NOT NULL,"
"  idcast int(10) unsigned NOT NULL,"
"  UNIQUE KEY idvideo (idvideo,idcast)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE videometadatacountry ("
"  idvideo int(10) unsigned NOT NULL,"
"  idcountry int(10) unsigned NOT NULL,"
"  UNIQUE KEY idvideo_2 (idvideo,idcountry),"
"  KEY idvideo (idvideo),"
"  KEY idcountry (idcountry)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE videometadatagenre ("
"  idvideo int(10) unsigned NOT NULL,"
"  idgenre int(10) unsigned NOT NULL,"
"  UNIQUE KEY idvideo_2 (idvideo,idgenre),"
"  KEY idvideo (idvideo),"
"  KEY idgenre (idgenre)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE videopart ("
"  fileid bigint(20) unsigned NOT NULL,"
"  videoid int(10) unsigned NOT NULL,"
"  `order` smallint(5) unsigned NOT NULL DEFAULT '1',"
"  PRIMARY KEY (videoid,`order`)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE videopathinfo ("
"  intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  path text,"
"  contenttype set('MOVIE','TELEVISION','ADULT','MUSICVIDEO','HOMEVIDEO') NOT NULL DEFAULT '',"
"  collectionref int(10) DEFAULT '0',"
"  recurse tinyint(1) DEFAULT '0',"
"  PRIMARY KEY (intid)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE videosource ("
"  sourceid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  `name` varchar(128) NOT NULL DEFAULT '',"
"  xmltvgrabber varchar(128) DEFAULT NULL,"
"  userid varchar(128) NOT NULL DEFAULT '',"
"  freqtable varchar(16) NOT NULL DEFAULT 'default',"
"  lineupid varchar(64) DEFAULT NULL,"
"  `password` varchar(64) DEFAULT NULL,"
"  useeit smallint(6) NOT NULL DEFAULT '0',"
"  configpath varchar(4096) DEFAULT NULL,"
"  dvb_nit_id int(6) DEFAULT '-1',"
"  PRIMARY KEY (sourceid),"
"  UNIQUE KEY `name` (`name`)"
") ENGINE=MyISAM DEFAULT CHARSET=utf8;",
"CREATE TABLE videotypes ("
"  intid int(10) unsigned NOT NULL AUTO_INCREMENT,"
"  extension varchar(128) NOT NULL,"
"  playcommand varchar(255) NOT NULL,"
"  f_ignore tinyint(1) DEFAULT NULL,"
"  use_default tinyint(1) DEFAULT NULL,"
"  PRIMARY KEY (intid)"
") ENGINE=MyISAM AUTO_INCREMENT=33 DEFAULT CHARSET=utf8;",

"INSERT INTO channelgroupnames VALUES (1,'Favorites');",
"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);",
"INSERT INTO dtv_privatetypes VALUES ('dvb',9018,'channel_numbers','131');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',9018,'guide_fixup','2');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',256,'guide_fixup','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',257,'guide_fixup','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',256,'tv_types','1,150,134,133');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',257,'tv_types','1,150,134,133');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4100,'sdt_mapping','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4101,'sdt_mapping','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4102,'sdt_mapping','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4103,'sdt_mapping','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4104,'sdt_mapping','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4105,'sdt_mapping','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4106,'sdt_mapping','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4107,'sdt_mapping','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4097,'sdt_mapping','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4098,'sdt_mapping','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4100,'tv_types','1,145,154');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4101,'tv_types','1,145,154');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4102,'tv_types','1,145,154');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4103,'tv_types','1,145,154');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4104,'tv_types','1,145,154');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4105,'tv_types','1,145,154');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4106,'tv_types','1,145,154');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4107,'tv_types','1,145,154');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4097,'tv_types','1,145,154');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4098,'tv_types','1,145,154');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4100,'guide_fixup','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4101,'guide_fixup','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4102,'guide_fixup','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4103,'guide_fixup','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4104,'guide_fixup','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4105,'guide_fixup','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4106,'guide_fixup','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4107,'guide_fixup','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4096,'guide_fixup','5');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4097,'guide_fixup','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4098,'guide_fixup','1');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',94,'tv_types','1,128');",
"INSERT INTO dtv_privatetypes VALUES ('atsc',1793,'guide_fixup','3');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',40999,'guide_fixup','4');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',70,'force_guide_present','yes');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',70,'guide_ranges','80,80,96,96');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4112,'channel_numbers','131');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4115,'channel_numbers','131');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4116,'channel_numbers','131');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',12802,'channel_numbers','131');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',12803,'channel_numbers','131');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',12829,'channel_numbers','131');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',40999,'parse_subtitle_list','1070,1308,1041,1306,1307,1030,1016,1131,1068,1069');",
"INSERT INTO dtv_privatetypes VALUES ('dvb',4096,'guide_fixup','5');",
"INSERT INTO dvdinput VALUES (1,720,480,16,9,1,1,'ntsc');",
"INSERT INTO dvdinput VALUES (2,720,480,16,9,1,0,'ntsc');",
"INSERT INTO dvdinput VALUES (3,720,480,4,3,1,1,'ntsc');",
"INSERT INTO dvdinput VALUES (4,720,480,4,3,1,0,'ntsc');",
"INSERT INTO dvdinput VALUES (5,720,576,16,9,3,1,'pal');",
"INSERT INTO dvdinput VALUES (6,720,576,16,9,3,0,'pal');",
"INSERT INTO dvdinput VALUES (7,720,576,4,3,3,1,'pal');",
"INSERT INTO dvdinput VALUES (8,720,576,4,3,3,0,'pal');",
"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);",
"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);",
"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);",
"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);",
"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);",
"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);",
"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);",
"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);",
"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);",
"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);",
"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);",
"INSERT INTO playgroup VALUES ('Default','',30,5,100,0);",
"INSERT INTO profilegroups VALUES (1,'Software Encoders (v4l based)','V4L',1,NULL);",
"INSERT INTO profilegroups VALUES (2,'IVTV MPEG-2 Encoders','MPEG',1,NULL);",
"INSERT INTO profilegroups VALUES (3,'Hardware MJPEG Encoders (Matrox G200-TV, Miro DC10, etc)','MJPEG',1,NULL);",
"INSERT INTO profilegroups VALUES (4,'Hardware HDTV','HDTV',1,NULL);",
"INSERT INTO profilegroups VALUES (5,'Hardware DVB Encoders','DVB',1,NULL);",
"INSERT INTO profilegroups VALUES (6,'Transcoders','TRANSCODE',1,NULL);",
"INSERT INTO profilegroups VALUES (7,'FireWire Input','FIREWIRE',1,NULL);",
"INSERT INTO profilegroups VALUES (8,'USB Mpeg-4 Encoder (Plextor ConvertX, etc)','GO7007',1,NULL);",
"INSERT INTO profilegroups VALUES (14,'Import Recorder','IMPORT',1,NULL);",
"INSERT INTO profilegroups VALUES (10,'Freebox Input','Freebox',1,NULL);",
"INSERT INTO profilegroups VALUES (11,'HDHomeRun Recorders','HDHOMERUN',1,NULL);",
"INSERT INTO profilegroups VALUES (12,'CRC IP Recorders','CRC_IP',1,NULL);",
"INSERT INTO profilegroups VALUES (13,'HD-PVR Recorders','HDPVR',1,NULL);",
"INSERT INTO profilegroups VALUES (15,'ASI Recorder (DVEO)','ASI',1,NULL);",
"INSERT INTO profilegroups VALUES (16,'OCUR Recorder (CableLabs)','OCUR',1,NULL);",
"INSERT INTO profilegroups VALUES (17,'Ceton Recorder','CETON',1,NULL);",
"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);",
"INSERT INTO recordfilter VALUES (0,'New episode','program.previouslyshown = 0',0);",
"INSERT INTO recordfilter VALUES (1,'Identifiable episode','program.generic = 0',0);",
"INSERT INTO recordfilter VALUES (2,'First showing','program.first > 0',0);",
"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);",
"INSERT INTO recordfilter VALUES (4,'Commercial free','channel.commmethod = -2',0);",
"INSERT INTO recordfilter VALUES (5,'High definition','program.hdtv > 0',0);",
"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);",
"INSERT INTO recordfilter VALUES (7,'This series','(RECTABLE.seriesid <> \\'\\' AND program.seriesid = RECTABLE.seriesid)',0);",
"INSERT INTO recordingprofiles VALUES (1,'Default',NULL,NULL,1);",
"INSERT INTO recordingprofiles VALUES (2,'Live TV',NULL,NULL,1);",
"INSERT INTO recordingprofiles VALUES (3,'High Quality',NULL,NULL,1);",
"INSERT INTO recordingprofiles VALUES (4,'Low Quality',NULL,NULL,1);",
"INSERT INTO recordingprofiles VALUES (5,'Default',NULL,NULL,2);",
"INSERT INTO recordingprofiles VALUES (6,'Live TV',NULL,NULL,2);",
"INSERT INTO recordingprofiles VALUES (7,'High Quality',NULL,NULL,2);",
"INSERT INTO recordingprofiles VALUES (8,'Low Quality',NULL,NULL,2);",
"INSERT INTO recordingprofiles VALUES (9,'Default',NULL,NULL,3);",
"INSERT INTO recordingprofiles VALUES (10,'Live TV',NULL,NULL,3);",
"INSERT INTO recordingprofiles VALUES (11,'High Quality',NULL,NULL,3);",
"INSERT INTO recordingprofiles VALUES (12,'Low Quality',NULL,NULL,3);",
"INSERT INTO recordingprofiles VALUES (13,'Default',NULL,NULL,4);",
"INSERT INTO recordingprofiles VALUES (14,'Live TV',NULL,NULL,4);",
"INSERT INTO recordingprofiles VALUES (15,'High Quality',NULL,NULL,4);",
"INSERT INTO recordingprofiles VALUES (16,'Low Quality',NULL,NULL,4);",
"INSERT INTO recordingprofiles VALUES (17,'Default',NULL,NULL,5);",
"INSERT INTO recordingprofiles VALUES (18,'Live TV',NULL,NULL,5);",
"INSERT INTO recordingprofiles VALUES (19,'High Quality',NULL,NULL,5);",
"INSERT INTO recordingprofiles VALUES (20,'Low Quality',NULL,NULL,5);",
"INSERT INTO recordingprofiles VALUES (21,'RTjpeg/MPEG4',NULL,NULL,6);",
"INSERT INTO recordingprofiles VALUES (22,'MPEG2',NULL,NULL,6);",
"INSERT INTO recordingprofiles VALUES (23,'Default',NULL,NULL,8);",
"INSERT INTO recordingprofiles VALUES (24,'Live TV',NULL,NULL,8);",
"INSERT INTO recordingprofiles VALUES (25,'High Quality',NULL,NULL,8);",
"INSERT INTO recordingprofiles VALUES (26,'Low Quality',NULL,NULL,8);",
"INSERT INTO recordingprofiles VALUES (27,'High Quality',NULL,NULL,6);",
"INSERT INTO recordingprofiles VALUES (28,'Medium Quality',NULL,NULL,6);",
"INSERT INTO recordingprofiles VALUES (29,'Low Quality',NULL,NULL,6);",
"INSERT INTO recordingprofiles VALUES (30,'Default',NULL,NULL,10);",
"INSERT INTO recordingprofiles VALUES (31,'Live TV',NULL,NULL,10);",
"INSERT INTO recordingprofiles VALUES (32,'High Quality',NULL,NULL,10);",
"INSERT INTO recordingprofiles VALUES (33,'Low Quality',NULL,NULL,10);",
"INSERT INTO recordingprofiles VALUES (34,'Default',NULL,NULL,11);",
"INSERT INTO recordingprofiles VALUES (35,'Live TV',NULL,NULL,11);",
"INSERT INTO recordingprofiles VALUES (36,'High Quality',NULL,NULL,11);",
"INSERT INTO recordingprofiles VALUES (37,'Low Quality',NULL,NULL,11);",
"INSERT INTO recordingprofiles VALUES (38,'Default',NULL,NULL,12);",
"INSERT INTO recordingprofiles VALUES (39,'Live TV',NULL,NULL,12);",
"INSERT INTO recordingprofiles VALUES (40,'High Quality',NULL,NULL,12);",
"INSERT INTO recordingprofiles VALUES (41,'Low Quality',NULL,NULL,12);",
"INSERT INTO recordingprofiles VALUES (42,'Default',NULL,NULL,7);",
"INSERT INTO recordingprofiles VALUES (43,'Live TV',NULL,NULL,7);",
"INSERT INTO recordingprofiles VALUES (44,'High Quality',NULL,NULL,7);",
"INSERT INTO recordingprofiles VALUES (45,'Low Quality',NULL,NULL,7);",
"INSERT INTO recordingprofiles VALUES (46,'Default',NULL,NULL,9);",
"INSERT INTO recordingprofiles VALUES (47,'Live TV',NULL,NULL,9);",
"INSERT INTO recordingprofiles VALUES (48,'High Quality',NULL,NULL,9);",
"INSERT INTO recordingprofiles VALUES (49,'Low Quality',NULL,NULL,9);",
"INSERT INTO recordingprofiles VALUES (50,'Default',NULL,NULL,13);",
"INSERT INTO recordingprofiles VALUES (51,'Live TV',NULL,NULL,13);",
"INSERT INTO recordingprofiles VALUES (52,'High Quality',NULL,NULL,13);",
"INSERT INTO recordingprofiles VALUES (53,'Low Quality',NULL,NULL,13);",
"INSERT INTO recordingprofiles VALUES (54,'Default',NULL,NULL,14);",
"INSERT INTO recordingprofiles VALUES (55,'Live TV',NULL,NULL,14);",
"INSERT INTO recordingprofiles VALUES (56,'High Quality',NULL,NULL,14);",
"INSERT INTO recordingprofiles VALUES (57,'Low Quality',NULL,NULL,14);",
"INSERT INTO recordingprofiles VALUES (58,'Default',NULL,NULL,15);",
"INSERT INTO recordingprofiles VALUES (59,'Live TV',NULL,NULL,15);",
"INSERT INTO recordingprofiles VALUES (60,'High Quality',NULL,NULL,15);",
"INSERT INTO recordingprofiles VALUES (61,'Low Quality',NULL,NULL,15);",
"INSERT INTO recordingprofiles VALUES (62,'Default',NULL,NULL,16);",
"INSERT INTO recordingprofiles VALUES (63,'Live TV',NULL,NULL,16);",
"INSERT INTO recordingprofiles VALUES (64,'High Quality',NULL,NULL,16);",
"INSERT INTO recordingprofiles VALUES (65,'Low Quality',NULL,NULL,16);",
"INSERT INTO recordingprofiles VALUES (66,'Default',NULL,NULL,17);",
"INSERT INTO recordingprofiles VALUES (67,'Live TV',NULL,NULL,17);",
"INSERT INTO recordingprofiles VALUES (68,'High Quality',NULL,NULL,17);",
"INSERT INTO recordingprofiles VALUES (69,'Low Quality',NULL,NULL,17);",
"INSERT INTO settings VALUES ('mythfilldatabaseLastRunStart','',NULL);",
"INSERT INTO settings VALUES ('mythfilldatabaseLastRunEnd','',NULL);",
"INSERT INTO settings VALUES ('mythfilldatabaseLastRunStatus','',NULL);",
"INSERT INTO settings VALUES ('DataDirectMessage','',NULL);",
"INSERT INTO settings VALUES ('HaveRepeats','0',NULL);",
"INSERT INTO settings VALUES ('DBSchemaVer','1307',NULL);",
"INSERT INTO settings VALUES ('DefaultTranscoder','0',NULL);",
"INSERT INTO videotypes VALUES (1,'txt','',1,0);",
"INSERT INTO videotypes VALUES (2,'log','',1,0);",
"INSERT INTO videotypes VALUES (3,'mpg','Internal',0,0);",
"INSERT INTO videotypes VALUES (4,'avi','',0,1);",
"INSERT INTO videotypes VALUES (5,'vob','Internal',0,0);",
"INSERT INTO videotypes VALUES (6,'mpeg','Internal',0,0);",
"INSERT INTO videotypes VALUES (8,'iso','Internal',0,0);",
"INSERT INTO videotypes VALUES (9,'img','Internal',0,0);",
"INSERT INTO videotypes VALUES (10,'mkv','Internal',0,0);",
"INSERT INTO videotypes VALUES (11,'mp4','Internal',0,0);",
"INSERT INTO videotypes VALUES (12,'m2ts','Internal',0,0);",
"INSERT INTO videotypes VALUES (13,'evo','Internal',0,0);",
"INSERT INTO videotypes VALUES (14,'divx','Internal',0,0);",
"INSERT INTO videotypes VALUES (15,'mov','Internal',0,0);",
"INSERT INTO videotypes VALUES (16,'qt','Internal',0,0);",
"INSERT INTO videotypes VALUES (17,'wmv','Internal',0,0);",
"INSERT INTO videotypes VALUES (18,'3gp','Internal',0,0);",
"INSERT INTO videotypes VALUES (19,'asf','Internal',0,0);",
"INSERT INTO videotypes VALUES (20,'ogg','Internal',0,0);",
"INSERT INTO videotypes VALUES (21,'ogm','Internal',0,0);",
"INSERT INTO videotypes VALUES (22,'flv','Internal',0,0);",
"INSERT INTO videotypes VALUES (23,'ogv','Internal',0,0);",
"INSERT INTO videotypes VALUES (25,'nut','Internal',0,0);",
"INSERT INTO videotypes VALUES (26,'mxf','Internal',0,0);",
"INSERT INTO videotypes VALUES (27,'m4v','Internal',0,0);",
"INSERT INTO videotypes VALUES (28,'rm','Internal',0,0);",
"INSERT INTO videotypes VALUES (29,'ts','Internal',0,0);",
"INSERT INTO videotypes VALUES (30,'swf','Internal',0,0);",
"INSERT INTO videotypes VALUES (31,'f4v','Internal',0,0);",
"INSERT INTO videotypes VALUES (32,'nuv','Internal',0,0);",
nullptr
};

    QString dbver = "";
    if (!performActualUpdate(updates, "1307", dbver))
        return false;

    GetMythDB()->SetHaveSchema(true);

    return true;
}

/* vim: set expandtab tabstop=4 shiftwidth=4: */
