Ticket #4760: mythtv-database_backup_using_script.patch

File mythtv-database_backup_using_script.patch, 8.8 KB (added by sphery <mtdean@…>, 16 years ago)
  • libs/libmyth/dbutil.h

     
    4242                                 QString extension = ".sql");
    4343    QString GetBackupDirectory();
    4444
    45     bool DoBackup(QString &filename);
     45    bool DoBackup(QString backupScript, QString &filename);
    4646
    4747    QString m_versionString;
    4848
  • 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 *
    160166 *   Care should be taken in calling this function.  It has the potential to
    161167 *   corrupt in-progress recordings or interfere with playback.
    162168 */
    163169bool DBUtil::BackupDB(QString &filename)
    164170{
     171    QString backupScript = gContext->GetSetting("DatabaseBackupScript",
     172                   gContext->GetShareDir() + "database_mythconverg_backup.sh");
     173
     174    if (!QFile::exists(backupScript))
     175    {
     176        VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Database backup script does "
     177                              "not exist: %1").arg(backupScript));
     178        return false;
     179    }
     180
    165181    bool result = false;
    166182    MSqlQuery query(MSqlQuery::InitCon());
    167183
     
    169185                                QDateTime::currentDateTime()
    170186                                .toString("yyyy-MM-dd hh:mm:ss"), NULL);
    171187
    172     result = DoBackup(filename);
     188    result = DoBackup(backupScript, filename);
    173189
    174190    gContext->SaveSettingOnHost("BackupDBLastRunEnd",
    175191                                QDateTime::currentDateTime()
     
    288304    return directory;
    289305}
    290306
    291 /** \fn DBUtil::DoBackup(QString)
    292  *  \brief Creates a backup of the database.
     307/** \fn DBUtil::DoBackup(QString, QString)
     308 *  \brief Creates a backup of the database by executing the backupScript.
    293309 */
    294 bool DBUtil::DoBackup(QString &filename)
     310bool DBUtil::DoBackup(QString backupScript, QString &filename)
    295311{
    296312    DatabaseParams dbParams = gContext->GetDatabaseParams();
    297313    QString     dbSchemaVer = gContext->GetSetting("DBSchemaVer");
    298314    QString backupDirectory = GetBackupDirectory();
     315    QString  backupFilename = CreateBackupFilename(dbParams.dbName + "-" +
     316                                                   dbSchemaVer, ".sql");
    299317
    300     /* So we don't have to specify the password on the command line, use
    301        --defaults-extra-file to specify a temporary file with a [client] and
    302        [mysqldump] section that provides the password.  This will fail if the
    303        user's ~/.my.cnf (which is read after the --defaults-extra-file)
    304        specifies a different password that's incorrect for dbUserName */
    305     QString tempExtraConfFile = QDeepCopy<QString>(
     318    // Create a temporary file containing the database information
     319    QString tempDatabaseConfFile = QDeepCopy<QString>(
    306320                    createTempFile("/tmp/mythtv_db_backup_conf_XXXXXX"));
    307321    FILE *fp;
    308     if (!(fp = fopen(tempExtraConfFile.ascii(), "w")))
     322    if (!(fp = fopen(tempDatabaseConfFile.ascii(), "w")))
    309323    {
    310324        VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Unable to create temporary "
    311325                "configuration file for creating DB backup: %1")
    312                 .arg(tempExtraConfFile.ascii()));
    313         VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Attempting backup, anyway. "
    314                 "If the backup fails, please add the %1 user's database "
    315                 "password to your MySQL option file.")
    316                 .arg(dbParams.dbUserName));
     326                .arg(tempDatabaseConfFile.ascii()));
     327        VERBOSE(VB_IMPORTANT, LOC_ERR + "Attempting backup, anyway.");
     328        tempDatabaseConfFile = "";
    317329    }
    318330    else
    319331    {
    320         chmod(tempExtraConfFile.ascii(), S_IRUSR);
    321         fprintf(fp, QString("[client]\npassword=%1\n"
    322                             "[mysqldump]\npassword=%2\n")
    323                             .arg(dbParams.dbPassword).arg(dbParams.dbPassword));
     332        chmod(tempDatabaseConfFile.ascii(), S_IRUSR);
     333        fprintf(fp, QString("DBHostName=%1\n"
     334                            "DBPort=%2\n")
     335                            .arg(dbParams.dbHostName).arg(dbParams.dbPort));
     336        fprintf(fp, QString("DBUserName=%1\n"
     337                            "DBPassword=%2\n")
     338                            .arg(dbParams.dbUserName).arg(dbParams.dbPassword));
     339        fprintf(fp, QString("DBName=%1\n"
     340                            "DBSchemaVer=%2\n")
     341                            .arg(dbParams.dbName).arg(dbSchemaVer));
     342        fprintf(fp, QString("DBBackupDirectory=%1\n"
     343                            "DBBackupFilename=%2\n")
     344                            .arg(backupDirectory)
     345                            .arg(backupFilename));
    324346        if (fclose(fp))
    325347            VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Error closing %1: %2")
    326                     .arg(tempExtraConfFile.ascii()).arg(strerror(errno)));
     348                    .arg(tempDatabaseConfFile.ascii()).arg(strerror(errno)));
    327349    }
    328350
    329     QString command;
    330     QString compressCommand("");
    331     QString extension = ".sql";
    332     if (QFile::exists("/bin/gzip"))
    333         compressCommand = "/bin/gzip";
    334     else if (QFile::exists("/usr/bin/gzip"))
    335         compressCommand = "/usr/bin/gzip";
    336     else
    337         VERBOSE(VB_IMPORTANT, "Neither /bin/gzip nor /usr/bin/gzip exist. "
    338                               "The database backup will be uncompressed.");
    339 
    340     QString backupPathname = backupDirectory + "/" +
    341                              CreateBackupFilename(dbParams.dbName + "-" +
    342                                                   dbSchemaVer, extension);
    343     command = QString("mysqldump --defaults-extra-file='%1' --host='%2'"
    344                       " --user='%3' --add-drop-table --add-locks"
    345                       " --allow-keywords --complete-insert"
    346                       " --extended-insert --lock-tables --no-create-db --quick"
    347                       " '%4' > '%5' 2>/dev/null")
    348                       .arg(tempExtraConfFile).arg(dbParams.dbHostName)
    349                       .arg(dbParams.dbUserName).arg(dbParams.dbName)
    350                       .arg(backupPathname);
    351     VERBOSE(VB_FILE, QString("Backing up database with command: %1")
    352                              .arg(command.ascii()));
    353     VERBOSE(VB_IMPORTANT, QString("Backing up database to file: %1")
    354             .arg(backupPathname.ascii()));
     351    QString command = backupScript + " " + tempDatabaseConfFile;
     352    VERBOSE(VB_IMPORTANT, QString("Backing up database with script: %1")
     353            .arg(backupScript));
    355354    uint status = system(command.ascii());
    356355
    357     unlink(tempExtraConfFile.ascii());
     356    unlink(tempDatabaseConfFile.ascii());
    358357
    359358    if (status)
    360359    {
     
    365364        return false;
    366365    }
    367366
    368     if (compressCommand != "")
     367    VERBOSE(VB_IMPORTANT, "Database Backup complete.");
     368
     369    QDir dir(backupDirectory, backupFilename + "*");
     370    uint numfiles = dir.count();
     371    if (numfiles < 1)
    369372    {
    370         VERBOSE(VB_IMPORTANT, "Compressing database backup file.");
    371         compressCommand += " " + backupPathname;
    372         status = system(compressCommand.ascii());
    373 
    374         if (status)
    375         {
    376             VERBOSE(VB_IMPORTANT,
    377                    "Compression failed, backup file will remain uncompressed.");
    378         }
    379         else
    380         {
    381             backupPathname += ".gz";
    382 
    383             VERBOSE(VB_IMPORTANT, QString("Database Backup filename: %1")
    384                     .arg(backupPathname.ascii()));
    385         }
     373        // If no file begins with the suggested filename, don't show the backup
     374        // filename in the GUI message
     375        filename = "";
     376        VERBOSE(VB_FILE, LOC_ERR + QString("No files beginning with the "
     377                "suggested database backup filename (%1) were found in %2.")
     378                .arg(backupFilename).arg(backupDirectory));
    386379    }
    387 
    388     VERBOSE(VB_IMPORTANT, "Database Backup complete.");
    389 
    390     filename = backupPathname;
     380    else
     381    {
     382        filename = dir.path() + "/" + dir[0];;
     383        if (numfiles > 1)
     384            VERBOSE(VB_FILE, LOC_ERR + QString("Multiple files beginning with "
     385                    "the suggested database backup filename (%1) were found "
     386                    "in %2.  Assuming the first is the backup.")
     387                    .arg(backupFilename).arg(backupDirectory));
     388    }
     389    if (!filename.isEmpty())
     390        VERBOSE(VB_IMPORTANT, QString("Backed up database to file: %1")
     391                .arg(filename));
    391392    return true;
    392393}
    393394