Ticket #4760: mythtv-4760-database_backup_using_script-20080627.patch

File mythtv-4760-database_backup_using_script-20080627.patch, 6.7 KB (added by sphery <mtdean@…>, 13 years ago)

Updated patch (for changes to trunk)

  • libs/libmyth/dbutil.h

     
    4444                                 QString extension = ".sql");
    4545    QString GetBackupDirectory();
    4646
     47    bool DoBackup(QString backupScript, QString &filename);
    4748    bool DoBackup(QString &filename);
    4849
    4950    QString m_versionString;
  • libs/libmyth/dbutil.cpp

     
    157157/** \fn DBUtil::BackupDB(QString)
    158158 *  \brief Requests a backup of the database.
    159159 *
     160 *   If the DatabaseBackupScript exists in the ShareDir, it will be executed.
     161 *   All required database information will be made available as name=value
     162 *   pairs in a temporary file whose filename will be passed to the backup
     163 *   script.  The script may parse this file to obtain the required information
     164 *   to run a backup program, such as mysqldump or mysqlhotcopy.
     165 *
     166 *   If the DatabaseBackupScript does not exist, a backup will be performed
     167 *   using mysqldump directly.  The database password will be passed in a
     168 *   temporary file so it does not have to be specified on the command line.
     169 *
    160170 *   Care should be taken in calling this function.  It has the potential to
    161171 *   corrupt in-progress recordings or interfere with playback.
    162172 */
     
    169179        return true;
    170180    }
    171181
     182    QString backupScript = gContext->GetSetting("DatabaseBackupScript",
     183                   gContext->GetShareDir() + "database_mythconverg_backup.pl");
     184
     185    if (!QFile::exists(backupScript))
     186    {
     187        VERBOSE(VB_IMPORTANT, QString("Database backup script does "
     188                              "not exist: %1").arg(backupScript));
     189        backupScript = QString::null;
     190    }
     191
    172192    bool result = false;
    173193    MSqlQuery query(MSqlQuery::InitCon());
    174194
     
    176196                                QDateTime::currentDateTime()
    177197                                .toString("yyyy-MM-dd hh:mm:ss"), NULL);
    178198
    179     result = DoBackup(filename);
     199    if (backupScript.isEmpty())
     200        result = DoBackup(filename);
     201    else
     202        result = DoBackup(backupScript, filename);
    180203
    181204    gContext->SaveSettingOnHost("BackupDBLastRunEnd",
    182205                                QDateTime::currentDateTime()
     
    295318    return directory;
    296319}
    297320
     321/** \fn DBUtil::DoBackup(QString, QString)
     322 *  \brief Creates a backup of the database by executing the backupScript.
     323 *
     324 *   This function executes the specified backup script to create a database
     325 *   backup.  This is the preferred approach for creating the backup.
     326 */
     327bool DBUtil::DoBackup(QString backupScript, QString &filename)
     328{
     329    DatabaseParams dbParams = gContext->GetDatabaseParams();
     330    QString     dbSchemaVer = gContext->GetSetting("DBSchemaVer");
     331    QString backupDirectory = GetBackupDirectory();
     332    QString  backupFilename = CreateBackupFilename(dbParams.dbName + "-" +
     333                                                   dbSchemaVer, ".sql");
     334    QString      scriptArgs = gContext->GetSetting("BackupDBScriptArgs");
     335
     336    // Create a temporary file containing the database information
     337    QString tempDatabaseConfFile = createTempFile(
     338                                         "/tmp/mythtv_db_backup_conf_XXXXXX");
     339    FILE *fp;
     340    if (!(fp = fopen(tempDatabaseConfFile.ascii(), "w")))
     341    {
     342        VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Unable to create temporary "
     343                "configuration file for creating DB backup: %1")
     344                .arg(tempDatabaseConfFile.ascii()));
     345        VERBOSE(VB_IMPORTANT, LOC_ERR + "Attempting backup, anyway.");
     346        tempDatabaseConfFile = "";
     347    }
     348    else
     349    {
     350        chmod(tempDatabaseConfFile.ascii(), S_IRUSR);
     351        fprintf(fp, QString("DBHostName=%1\n"
     352                            "DBPort=%2\n")
     353                            .arg(dbParams.dbHostName).arg(dbParams.dbPort));
     354        fprintf(fp, QString("DBUserName=%1\n"
     355                            "DBPassword=%2\n")
     356                            .arg(dbParams.dbUserName).arg(dbParams.dbPassword));
     357        fprintf(fp, QString("DBName=%1\n"
     358                            "DBSchemaVer=%2\n")
     359                            .arg(dbParams.dbName).arg(dbSchemaVer));
     360        fprintf(fp, QString("DBBackupDirectory=%1\n"
     361                            "DBBackupFilename=%2\n")
     362                            .arg(backupDirectory)
     363                            .arg(backupFilename));
     364        if (fclose(fp))
     365            VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Error closing %1: %2")
     366                    .arg(tempDatabaseConfFile.ascii()).arg(strerror(errno)));
     367    }
     368
     369    if (!scriptArgs.isEmpty())
     370    {
     371        scriptArgs.prepend(" ");
     372    }
     373
     374    QString command = backupScript + scriptArgs + " " + tempDatabaseConfFile;
     375    VERBOSE(VB_IMPORTANT, QString("Backing up database with script: %1")
     376            .arg(backupScript));
     377    uint status = system(command.ascii());
     378
     379    unlink(tempDatabaseConfFile.ascii());
     380
     381    if (status)
     382    {
     383        VERBOSE(VB_IMPORTANT, LOC_ERR +
     384                QString("Error backing up database: %1 (%2)")
     385                .arg(command.ascii()).arg(status));
     386        filename = "__FAILED__";
     387        return false;
     388    }
     389
     390    VERBOSE(VB_IMPORTANT, "Database Backup complete.");
     391
     392    QDir dir(backupDirectory, backupFilename + "*");
     393    uint numfiles = dir.count();
     394    if (numfiles < 1)
     395    {
     396        // If no file begins with the suggested filename, don't show the backup
     397        // filename in the GUI message -- the script probably used some other
     398        // filename
     399        filename = "";
     400        VERBOSE(VB_FILE, LOC_ERR + QString("No files beginning with the "
     401                "suggested database backup filename (%1) were found in %2.")
     402                .arg(backupFilename).arg(backupDirectory));
     403    }
     404    else
     405    {
     406        filename = dir.path() + "/" + dir[0];;
     407        if (numfiles > 1)
     408            VERBOSE(VB_FILE, LOC_ERR + QString("Multiple files beginning with "
     409                    "the suggested database backup filename (%1) were found "
     410                    "in %2.  Assuming the first is the backup.")
     411                    .arg(backupFilename).arg(backupDirectory));
     412    }
     413    if (!filename.isEmpty())
     414        VERBOSE(VB_IMPORTANT, QString("Backed up database to file: %1")
     415                .arg(filename));
     416    return true;
     417}
     418
    298419/** \fn DBUtil::DoBackup(QString)
    299420 *  \brief Creates a backup of the database.
     421 *
     422 *   This fallback function is used only if the database backup script cannot
     423 *   be found.
    300424 */
    301425bool DBUtil::DoBackup(QString &filename)
    302426{