Ticket #10305: 10305-v1.patch

File 10305-v1.patch, 39.1 KB (added by danielk, 9 years ago)

Removes mysql.txt support, makes config.xml saves safer and only does them when necessary; does not add the needed mysql.txt config values to config.xml.

  • mythtv/docs/doxygen-architecture-document.cpp

    diff --git a/mythtv/docs/doxygen-architecture-document.cpp b/mythtv/docs/doxygen-architecture-document.cpp
    index 464a5f4..8b8e90fa 100644
    a b Most MythTV programs follow a common sequence: 
    576576  <li>Initialise the MythContext, which:</li>
    577577  <ul>
    578578    <li>Tries to find a database on localhost,
    579         or on the host specified in mysql.txt,</li>
     579        or on the host specified in config.xml,</li>
    580580    <li>Tries to locate exactly one backend host via UPnP,
    581581        to find its database,</li>
    582582    <li>If possible, displays a list of all backends located via UPnP
  • mythtv/libs/libmyth/langsettings.cpp

    diff --git a/mythtv/libs/libmyth/langsettings.cpp b/mythtv/libs/libmyth/langsettings.cpp
    index 5cbe870..70ccd7f 100644
    a b void LanguageSelection::Save(void) 
    187187    MythUIButtonListItem *item = m_languageList->GetItemCurrent();
    188188
    189189    QString langCode = item->GetData().toString();
    190     gCoreContext->SetSetting("Language", langCode);
    191190    gCoreContext->SaveSetting("Language", langCode);
    192191
    193192    item = m_countryList->GetItemCurrent();
    194193
    195194    QString countryCode = item->GetData().toString();
    196     gCoreContext->SetSetting("Country", countryCode);
    197195    gCoreContext->SaveSetting("Country", countryCode);
    198196
    199197    if (m_language != langCode)
  • mythtv/libs/libmyth/mythcontext.cpp

    diff --git a/mythtv/libs/libmyth/mythcontext.cpp b/mythtv/libs/libmyth/mythcontext.cpp
    index ea8c07d..b169b29 100644
    a b using namespace std; 
    1414#include "config.h"
    1515#include "mythcontext.h"
    1616#include "exitcodes.h"
    17 #include "oldsettings.h"
    1817#include "util.h"
    1918#include "remotefile.h"
    2019#include "mythplugin.h"
    class MythContextPrivate : public QObject 
    6665    void EndTempWindow(void);
    6766
    6867    bool LoadDatabaseSettings(void);
     68    bool SaveDatabaseParams(const DatabaseParams &params, bool force);
    6969
    7070    bool    PromptForDatabaseParams(const QString &error);
    7171    QString TestDBconnection(void);
    class MythContextPrivate : public QObject 
    7575
    7676    int     ChooseBackend(const QString &error);
    7777    int     UPnPautoconf(const int milliSeconds = 2000);
    78     void    StoreConnectionInfo(void);
    7978    bool    DefaultUPnP(QString &error);
    8079    bool    UPnPconnect(const DeviceLocation *device, const QString &PIN);
    8180
    class MythContextPrivate : public QObject 
    9998    DatabaseParams  m_DBparams;  ///< Current database host & WOL details
    10099    QString         m_DBhostCp;  ///< dbHostName backup
    101100
    102     Configuration    *m_pConfig;
     101    Configuration    *m_XMLConfig;
    103102
    104103    bool disableeventpopup;
    105104    bool disablelibrarypopup;
    static void eject_cb(void) 
    203202MythContextPrivate::MythContextPrivate(MythContext *lparent)
    204203    : parent(lparent),
    205204      m_gui(false),
    206       m_pConfig(NULL),
     205      m_XMLConfig(NULL),
    207206      disableeventpopup(false),
    208207      disablelibrarypopup(false),
    209208      pluginmanager(NULL),
    void MythContextPrivate::TempMainWindow(bool languagePrompt) 
    240239
    241240    SilenceDBerrors();
    242241
    243     gCoreContext->SetSetting("Theme", DEFAULT_UI_THEME);
     242    gCoreContext->OverrideSettingForSession("Theme", DEFAULT_UI_THEME);
    244243#ifdef Q_WS_MACX
    245244    // Qt 4.4 has window-focus problems
    246     gCoreContext->SetSetting("RunFrontendInWindow", "1");
     245    gCoreContext->OverrideSettingForSession("RunFrontendInWindow", "1");
    247246#endif
    248247    GetMythUI()->LoadQtConfig();
    249248
    void MythContextPrivate::TempMainWindow(bool languagePrompt) 
    261260void MythContextPrivate::EndTempWindow(void)
    262261{
    263262    DestroyMythMainWindow();
     263    gCoreContext->ClearOverrideSettingForSession("Theme");
    264264    EnableDBerrors();
    265265}
    266266
    bool MythContextPrivate::Init(const bool gui, 
    273273    m_gui = gui;
    274274
    275275    // We don't have a database yet, so lets use the config.xml file.
    276 
    277     m_pConfig = UPnp::GetConfiguration();
     276    m_XMLConfig = UPnp::GetConfiguration();
    278277
    279278    // Creates screen saver control if we will have a GUI
    280279    if (gui)
    bool MythContextPrivate::FindDatabase(const bool prompt, const bool noPrompt) 
    333332
    334333    QString failure;
    335334
    336     // 1. Load either mysql.txt, or use sensible "localhost" defaults:
     335    // 1. Load either config.xml, or use sensible "localhost" defaults:
    337336    bool loaded = LoadDatabaseSettings();
     337    DatabaseParams dbParamsFromFile = m_DBparams;
    338338
    339339    // In addition to the UI chooser, we can also try to autoSelect later,
    340     // but only if we're not doing manualSelect and there was no mysql.txt
     340    // but only if we're not doing manualSelect and there was no
     341    // valid config.xml
    341342    bool autoSelect = !manualSelect && !loaded;
    342343
    343344    // 2. If the user isn't forcing up the chooser UI, look for a default
    bool MythContextPrivate::FindDatabase(const bool prompt, const bool noPrompt) 
    424425    }
    425426
    426427DBfound:
    427 #if 0
    428428    LOG(VB_GENERAL, LOG_DEBUG, "FindDatabase() - Success!");
    429 #endif
    430     StoreConnectionInfo();
     429    SaveDatabaseParams(m_DBparams, !loaded || dbParamsFromFile != m_DBparams);
    431430    EnableDBerrors();
    432431    ResetDatabase();
    433432    return true;
    434433
    435434NoDBfound:
    436 #if 0
    437435    LOG(VB_GENERAL, LOG_DEBUG, "FindDatabase() - failed");
    438 #endif
    439436    return false;
    440437}
    441438
    442 /** Load database and host settings from mysql.txt or config.xml,
    443  *  or set some defaults.
    444  *  \return true if mysql.txt or config.xml was parsed
     439/** Load database and host settings from config.xml, or set some defaults.
     440 *  \return true if  config.xml was parsed
    445441 */
    446442bool MythContextPrivate::LoadDatabaseSettings(void)
    447443{
    448     bool ok = MythDB::LoadDatabaseParamsFromDisk(m_DBparams);
     444    XmlConfiguration cfg("config.xml");
     445    m_DBparams.LoadDefaults();
     446    m_DBparams.dbHostName = cfg.GetValue(kDefaultBE + "DBHostName", "");
     447    m_DBparams.dbUserName = cfg.GetValue(kDefaultBE + "DBUserName", "");
     448    m_DBparams.dbPassword = cfg.GetValue(kDefaultBE + "DBPassword", "");
     449    m_DBparams.dbName     = cfg.GetValue(kDefaultBE + "DBName", "");
     450    m_DBparams.dbPort     = cfg.GetValue(kDefaultBE + "DBPort", 0);
     451    bool ok = m_DBparams.IsValid("config.xml");
    449452    if (!ok)
    450     {
    451         XmlConfiguration cfg("config.xml");
    452         MythDB::LoadDefaultDatabaseParams(m_DBparams);
    453         m_DBparams.dbHostName = cfg.GetValue(kDefaultBE + "DBHostName", "");
    454         m_DBparams.dbUserName = cfg.GetValue(kDefaultBE + "DBUserName", "");
    455         m_DBparams.dbPassword = cfg.GetValue(kDefaultBE + "DBPassword", "");
    456         m_DBparams.dbName     = cfg.GetValue(kDefaultBE + "DBName", "");
    457         m_DBparams.dbPort     = cfg.GetValue(kDefaultBE + "DBPort", 0);
    458         ok = MythDB::ValidateDatabaseParams(m_DBparams, "config.xml");
    459     }
    460     if (!ok)
    461         MythDB::LoadDefaultDatabaseParams(m_DBparams);
     453        m_DBparams.LoadDefaults();
    462454
    463455    gCoreContext->GetDB()->SetDatabaseParams(m_DBparams);
    464456
    bool MythContextPrivate::LoadDatabaseSettings(void) 
    484476    return ok;
    485477}
    486478
     479bool MythContextPrivate::SaveDatabaseParams(
     480    const DatabaseParams &params, bool force)
     481{
     482    bool ret = true;
     483
     484    // only rewrite file if it has changed
     485    if (params != m_DBparams || force)
     486    {
     487        if (m_XMLConfig)
     488        {
     489            m_XMLConfig->SetValue(
     490                kDefaultBE + "DBHostName", params.dbHostName);
     491            m_XMLConfig->SetValue(
     492                kDefaultBE + "DBUserName", params.dbUserName);
     493            m_XMLConfig->SetValue(
     494                kDefaultBE + "DBPassword", params.dbPassword);
     495            m_XMLConfig->SetValue(
     496                kDefaultBE + "DBName",     params.dbName);
     497            m_XMLConfig->SetValue(
     498                kDefaultBE + "DBPort",     params.dbPort);
     499            m_XMLConfig->Save();
     500        }
     501
     502        // Save the new settings:
     503        m_DBparams = params;
     504        gCoreContext->GetDB()->SetDatabaseParams(m_DBparams);
     505
     506        // If database has changed, force its use:
     507        ResetDatabase();
     508    }
     509    return ret;
     510}
     511
    487512bool MythContextPrivate::PromptForDatabaseParams(const QString &error)
    488513{
    489514    bool accepted = false;
    int MythContextPrivate::ChooseBackend(const QString &error) 
    698723
    699724    LOG(VB_GENERAL, LOG_INFO, "Putting up the UPnP backend chooser");
    700725
    701     BackendSelection::prompt(&m_DBparams, m_pConfig);
     726    BackendSelection::prompt(&m_DBparams, m_XMLConfig);
    702727
    703728    EndTempWindow();
    704729
    int MythContextPrivate::ChooseBackend(const QString &error) 
    706731}
    707732
    708733/**
    709  * Try to store the current location of this backend in config.xml
    710  *
    711  * This is intended as a last resort for future connections
    712  * (e.g. Perl scripts, backend not running).
    713  *
    714  * Note that the Save() may fail (e.g. non writable ~/.mythtv)
    715  */
    716 void MythContextPrivate::StoreConnectionInfo(void)
    717 {
    718     if (!m_pConfig)
    719         return;
    720 
    721     m_pConfig->SetValue(kDefaultBE + "DBHostName", m_DBparams.dbHostName);
    722     m_pConfig->SetValue(kDefaultBE + "DBUserName", m_DBparams.dbUserName);
    723     m_pConfig->SetValue(kDefaultBE + "DBPassword", m_DBparams.dbPassword);
    724     m_pConfig->SetValue(kDefaultBE + "DBName",     m_DBparams.dbName);
    725     m_pConfig->SetValue(kDefaultBE + "DBPort",     m_DBparams.dbPort);
    726     m_pConfig->Save();
    727 }
    728 
    729 /**
    730734 * If there is only a single UPnP backend, use it.
    731735 *
    732736 * This does <i>not</i> prompt for PIN entry. If the backend requires one,
    DatabaseParams MythContext::GetDatabaseParams(void) 
    11761180
    11771181bool MythContext::SaveDatabaseParams(const DatabaseParams &params)
    11781182{
    1179     bool ret = true;
    1180     DatabaseParams cur_params = GetDatabaseParams();
    1181 
    1182     // only rewrite file if it has changed
    1183     if (params.dbHostName   != cur_params.dbHostName          ||
    1184         params.dbHostPing   != cur_params.dbHostPing          ||
    1185         params.dbPort       != cur_params.dbPort              ||
    1186         params.dbUserName   != cur_params.dbUserName          ||
    1187         params.dbPassword   != cur_params.dbPassword          ||
    1188         params.dbName       != cur_params.dbName              ||
    1189         params.dbType       != cur_params.dbType              ||
    1190         params.localEnabled != cur_params.localEnabled        ||
    1191         params.wolEnabled   != cur_params.wolEnabled          ||
    1192         (params.localEnabled &&
    1193          (params.localHostName != cur_params.localHostName))  ||
    1194         (params.wolEnabled &&
    1195          (params.wolReconnect  != cur_params.wolReconnect ||
    1196           params.wolRetry      != cur_params.wolRetry     ||
    1197           params.wolCommand    != cur_params.wolCommand)))
    1198     {
    1199         ret = MythDB::SaveDatabaseParamsToDisk(params, GetConfDir(), true);
    1200         if (ret)
    1201         {
    1202             // Save the new settings:
    1203             d->m_DBparams = params;
    1204             gCoreContext->GetDB()->SetDatabaseParams(d->m_DBparams);
    1205 
    1206             // If database has changed, force its use:
    1207             d->ResetDatabase();
    1208         }
    1209     }
    1210     return ret;
     1183    return d->SaveDatabaseParams(params, false);
    12111184}
    12121185
    12131186/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • mythtv/libs/libmythbase/libmythbase.pro

    diff --git a/mythtv/libs/libmythbase/libmythbase.pro b/mythtv/libs/libmythbase/libmythbase.pro
    index 7049ebe..b87a51a 100644
    a b HEADERS += mythscheduler.h filesysteminfo.h hardwareprofile.h 
    2727
    2828SOURCES += mthread.cpp mthreadpool.cpp
    2929SOURCES += mythsocket.cpp mythsocketthread.cpp msocketdevice.cpp
    30 SOURCES += mythdbcon.cpp mythdb.cpp oldsettings.cpp
     30SOURCES += mythdbcon.cpp mythdb.cpp mythdbparams.cpp oldsettings.cpp
    3131SOURCES += mythobservable.cpp mythevent.cpp httpcomms.cpp mcodecs.cpp
    3232SOURCES += mythdirs.cpp mythsignalingtimer.cpp
    3333SOURCES += lcddevice.cpp mythstorage.cpp remotefile.cpp
  • mythtv/libs/libmythbase/mythcorecontext.cpp

    diff --git a/mythtv/libs/libmythbase/mythcorecontext.cpp b/mythtv/libs/libmythbase/mythcorecontext.cpp
    index 5f1b84c..17033d7 100644
    a b class MythCoreContextPrivate : public QObject 
    5555    QString          m_appBinaryVersion;
    5656
    5757    QMutex  m_hostnameLock;      ///< Locking for thread-safe copying of:
    58     QString m_localHostname;     ///< hostname from mysql.txt or gethostname()
     58    QString m_localHostname;     ///< hostname from config.xml or gethostname()
    5959    QString m_masterHostname;    ///< master backend hostname
    6060
    6161    QMutex      m_sockLock;      ///< protects both m_serverSock and m_eventSock
    double MythCoreContext::GetFloatSettingOnHost(const QString &key, 
    839839    return d->m_database->GetFloatSettingOnHost(key, host, defaultval);
    840840}
    841841
    842 void MythCoreContext::SetSetting(const QString &key, const QString &newValue)
    843 {
    844     d->m_database->SetSetting(key, newValue);
    845 }
    846 
    847842void MythCoreContext::OverrideSettingForSession(const QString &key,
    848843                                                const QString &value)
    849844{
    850845    d->m_database->OverrideSettingForSession(key, value);
    851846}
    852847
     848void MythCoreContext::ClearOverrideSettingForSession(const QString &key)
     849{
     850    d->m_database->ClearOverrideSettingForSession(key);
     851}
     852
    853853bool MythCoreContext::IsUIThread(void)
    854854{
    855855    return is_current_thread(d->m_UIThread);
  • mythtv/libs/libmythbase/mythcorecontext.h

    diff --git a/mythtv/libs/libmythbase/mythcorecontext.h b/mythtv/libs/libmythbase/mythcorecontext.h
    index ca2e0c2..824457c 100644
    a b class MBASE_PUBLIC MythCoreContext : public MythObservable, public MythSocketCBs 
    145145    double GetFloatSettingOnHost(const QString &key, const QString &host,
    146146                                 double defaultval = 0.0);
    147147
    148     void SetSetting(const QString &key, const QString &newValue);
    149 
    150148    void ClearSettingsCache(const QString &myKey = QString(""));
    151149    void ActivateSettingsCache(bool activate = true);
    152150    void OverrideSettingForSession(const QString &key, const QString &value);
     151    void ClearOverrideSettingForSession(const QString &key);
    153152
    154153    void dispatch(const MythEvent &event);
    155154    void dispatchNow(const MythEvent &event) MDEPRECATED;
  • mythtv/libs/libmythbase/mythdb.cpp

    diff --git a/mythtv/libs/libmythbase/mythdb.cpp b/mythtv/libs/libmythbase/mythdb.cpp
    index adfe3c5..b871b88 100644
    a b using namespace std; 
    1212#include "mythdb.h"
    1313#include "mythdbcon.h"
    1414#include "mythlogging.h"
    15 #include "oldsettings.h"
    1615#include "mythdirs.h"
    1716#include "mythcorecontext.h"
    1817
    class MythDBPrivate 
    7271    QString m_localhostname;
    7372    MDBManager m_dbmanager;
    7473
    75     Settings *m_settings;
    76 
    7774    bool ignoreDatabase;
    7875    bool suppressDBMessages;
    7976
    class MythDBPrivate 
    9390
    9491static const int settings_reserve = 61;
    9592
    96 MythDBPrivate::MythDBPrivate()
    97     : m_settings(new Settings()),
    98       ignoreDatabase(false), suppressDBMessages(true), useSettingsCache(false),
    99       haveDBConnection(false), haveSchema(false)
     93MythDBPrivate::MythDBPrivate() :
     94    ignoreDatabase(false), suppressDBMessages(true), useSettingsCache(false),
     95    haveDBConnection(false), haveSchema(false)
    10096{
    10197    m_localhostname.clear();
    10298    settingsCache.reserve(settings_reserve);
    MythDBPrivate::MythDBPrivate() 
    105101MythDBPrivate::~MythDBPrivate()
    106102{
    107103    LOG(VB_DATABASE, LOG_INFO, "Destroying MythDBPrivate");
    108     delete m_settings;
    109104}
    110105
    111106MythDB::MythDB()
    MDBManager *MythDB::GetDBManager(void) 
    123118    return &(d->m_dbmanager);
    124119}
    125120
    126 Settings *MythDB::GetOldSettings(void)
    127 {
    128     return d->m_settings;
    129 }
    130 
    131121QString MythDB::toCommaList(const QMap<QString, QVariant> &bindings,
    132122                            uint indent, uint maxColumn)
    133123{
    QString MythDB::GetSetting(const QString &_key, const QString &defaultval) 
    375365        return value;
    376366
    377367    MSqlQuery query(MSqlQuery::InitCon());
    378     if (!query.isConnected())
    379     {
    380         if (!d->suppressDBMessages)
    381             LOG(VB_GENERAL, LOG_ERR,
    382                 QString("Database not open while trying to load setting: %1")
    383                 .arg(key));
    384         return d->m_settings->GetSetting(key, defaultval);
    385     }
    386 
    387368    query.prepare(
    388369        "SELECT data "
    389370        "FROM settings "
    QString MythDB::GetSetting(const QString &_key, const QString &defaultval) 
    407388        {
    408389            value = query.value(0).toString();
    409390        }
    410         else
    411         {
    412             value = d->m_settings->GetSetting(key, defaultval);
    413         }
    414391    }
    415392
    416393    if (d->useSettingsCache && value != kSentinelValue)
    double MythDB::GetFloatSettingOnHost(const QString &key, const QString &host) 
    697674    return (retval == sentinel) ? 0.0 : retval.toDouble();
    698675}
    699676
    700 void MythDB::SetSetting(const QString &key, const QString &newValueRaw)
    701 {
    702     QString newValue = (newValueRaw.isNull()) ? "" : newValueRaw;
    703     d->m_settings->SetSetting(key, newValue);
    704     ClearSettingsCache(key);
    705 }
    706 
    707677void MythDB::GetResolutionSetting(const QString &type,
    708678                                       int &width, int &height,
    709679                                       double &forced_aspect,
    void MythDB::OverrideSettingForSession( 
    798768    d->settingsCacheLock.unlock();
    799769}
    800770
     771/// \brief Clears session Overrides for the given setting.
     772void MythDB::ClearOverrideSettingForSession(const QString &key)
     773{
     774    QString mk = key.toLower();
     775    QString mk2 = d->m_localhostname + ' ' + mk;
     776
     777    d->settingsCacheLock.lockForWrite();
     778
     779    SettingsMap::iterator oit = d->overriddenSettings.find(mk);
     780    if (oit != d->overriddenSettings.end())
     781        d->overriddenSettings.erase(oit);
     782
     783    SettingsMap::iterator sit = d->settingsCache.find(mk);
     784    if (sit != d->settingsCache.end())
     785        d->settingsCache.erase(sit);
     786
     787    sit = d->settingsCache.find(mk2);
     788    if (sit != d->settingsCache.end())
     789        d->settingsCache.erase(sit);
     790
     791    d->settingsCacheLock.unlock();
     792}
     793
    801794static void clear(
    802795    SettingsMap &cache, SettingsMap &overrides, const QString &myKey)
    803796{
    void MythDB::ActivateSettingsCache(bool activate) 
    866859    ClearSettingsCache();
    867860}
    868861
    869 bool MythDB::LoadDatabaseParamsFromDisk(DatabaseParams &params)
    870 {
    871     Settings settings;
    872     if (!settings.LoadSettingsFiles(
    873             "mysql.txt", GetInstallPrefix(), GetConfDir()))
    874     {
    875         LOG(VB_GENERAL, LOG_ERR, "Unable to read configuration file mysql.txt");
    876         return false;
    877     }
    878 
    879     params.dbHostName = settings.GetSetting("DBHostName");
    880     params.dbHostPing = settings.GetSetting("DBHostPing") != "no";
    881     params.dbPort     = settings.GetNumSetting("DBPort", 3306);
    882     params.dbUserName = settings.GetSetting("DBUserName");
    883     params.dbPassword = settings.GetSetting("DBPassword");
    884     params.dbName     = settings.GetSetting("DBName");
    885     params.dbType     = settings.GetSetting("DBType");
    886 
    887     params.localHostName = settings.GetSetting("LocalHostName");
    888     params.localEnabled  = !params.localHostName.isEmpty();
    889 
    890     params.wolReconnect  =
    891         settings.GetNumSetting("WOLsqlReconnectWaitTime");
    892     params.wolEnabled = params.wolReconnect > 0;
    893 
    894     params.wolRetry   = settings.GetNumSetting("WOLsqlConnectRetry");
    895     params.wolCommand = settings.GetSetting("WOLsqlCommand");
    896 
    897     return ValidateDatabaseParams(params, "mysql.txt");
    898 }
    899 
    900 bool MythDB::ValidateDatabaseParams(
    901     const DatabaseParams &params, const QString &source)
    902 {
    903     // Print some warnings if things look fishy..
    904     QString msg = QString(" is not set in %1").arg(source);
    905 
    906     if (params.dbHostName.isEmpty())
    907     {
    908         LOG(VB_GENERAL, LOG_ERR, "DBHostName" + msg);
    909         return false;
    910     }
    911     if (params.dbUserName.isEmpty())
    912     {
    913         LOG(VB_GENERAL, LOG_ERR, "DBUserName" + msg);
    914         return false;
    915     }
    916     if (params.dbPassword.isEmpty())
    917     {
    918         LOG(VB_GENERAL, LOG_ERR, "DBPassword" + msg);
    919         return false;
    920     }
    921     if (params.dbName.isEmpty())
    922     {
    923         LOG(VB_GENERAL, LOG_ERR, "DBName" + msg);
    924         return false;
    925     }
    926 
    927     return true;
    928 }
    929 
    930 // Sensible connection defaults.
    931 void MythDB::LoadDefaultDatabaseParams(DatabaseParams &params)
    932 {
    933     params.dbHostName    = "localhost";
    934     params.dbHostPing    = true;
    935     params.dbPort        = 3306;
    936     params.dbUserName    = "mythtv";
    937     params.dbPassword    = "mythtv";
    938     params.dbName        = "mythconverg";
    939     params.dbType        = "QMYSQL";
    940     params.localEnabled  = false;
    941     params.localHostName = "my-unique-identifier-goes-here";
    942     params.wolEnabled    = false;
    943     params.wolReconnect  = 0;
    944     params.wolRetry      = 5;
    945     params.wolCommand    = "echo 'WOLsqlServerCommand not set'";
    946 }
    947 
    948 bool MythDB::SaveDatabaseParamsToDisk(
    949     const DatabaseParams &params, const QString &confdir, bool overwrite)
    950 {
    951     QString path = confdir + "/mysql.txt";
    952     QFile   * f  = new QFile(path);
    953 
    954     if (!overwrite && f->exists())
    955     {
    956         return false;
    957     }
    958 
    959     QString dirpath = confdir;
    960     QDir createDir(dirpath);
    961 
    962     if (!createDir.exists())
    963     {
    964         if (!createDir.mkdir(dirpath))
    965         {
    966             LOG(VB_GENERAL, LOG_ERR,
    967                 QString("Could not create %1").arg(dirpath));
    968             return false;
    969         }
    970     }
    971 
    972     if (!f->open(QIODevice::WriteOnly))
    973     {
    974         LOG(VB_GENERAL, LOG_ERR, QString("Could not open settings file %1 "
    975                                          "for writing").arg(path));
    976         return false;
    977     }
    978 
    979     LOG(VB_GENERAL, LOG_NOTICE, QString("Writing settings file %1").arg(path));
    980     QTextStream s(f);
    981     s << "DBHostName=" << params.dbHostName << endl;
    982 
    983     s << "\n"
    984       << "# By default, Myth tries to ping the DB host to see if it exists.\n"
    985       << "# If your DB host or network doesn't accept pings, set this to no:\n"
    986       << "#\n";
    987 
    988     if (params.dbHostPing)
    989         s << "#DBHostPing=no" << endl << endl;
    990     else
    991         s << "DBHostPing=no" << endl << endl;
    992 
    993     if (params.dbPort)
    994         s << "DBPort=" << params.dbPort << endl;
    995 
    996     s << "DBUserName=" << params.dbUserName << endl
    997       << "DBPassword=" << params.dbPassword << endl
    998       << "DBName="     << params.dbName     << endl
    999       << "DBType="     << params.dbType     << endl
    1000       << endl
    1001       << "# Set the following if you want to use something other than this\n"
    1002       << "# machine's real hostname for identifying settings in the database.\n"
    1003       << "# This is useful if your hostname changes often, as otherwise you\n"
    1004       << "# will need to reconfigure mythtv every time.\n"
    1005       << "# NO TWO HOSTS MAY USE THE SAME VALUE\n"
    1006       << "#\n";
    1007 
    1008     if (params.localEnabled)
    1009         s << "LocalHostName=" << params.localHostName << endl;
    1010     else
    1011         s << "#LocalHostName=my-unique-identifier-goes-here\n";
    1012 
    1013     s << endl
    1014       << "# If you want your frontend to be able to wake your MySQL server\n"
    1015       << "# using WakeOnLan, have a look at the following settings:\n"
    1016       << "#\n"
    1017       << "#\n"
    1018       << "# The time the frontend waits (in seconds) between reconnect tries.\n"
    1019       << "# This should be the rough time your MySQL server needs for startup\n"
    1020       << "#\n";
    1021 
    1022     if (params.wolEnabled)
    1023         s << "WOLsqlReconnectWaitTime=" << params.wolReconnect << endl;
    1024     else
    1025         s << "#WOLsqlReconnectWaitTime=0\n";
    1026 
    1027     s << "#\n"
    1028       << "#\n"
    1029       << "# This is the number of retries to wake the MySQL server\n"
    1030       << "# until the frontend gives up\n"
    1031       << "#\n";
    1032 
    1033     if (params.wolEnabled)
    1034         s << "WOLsqlConnectRetry=" << params.wolRetry << endl;
    1035     else
    1036         s << "#WOLsqlConnectRetry=5\n";
    1037 
    1038     s << "#\n"
    1039       << "#\n"
    1040       << "# This is the command executed to wake your MySQL server.\n"
    1041       << "#\n";
    1042 
    1043     if (params.wolEnabled)
    1044         s << "WOLsqlCommand=" << params.wolCommand << endl;
    1045     else
    1046         s << "#WOLsqlCommand=echo 'WOLsqlServerCommand not set'\n";
    1047 
    1048     f->close();
    1049     return true;
    1050 }
    1051 
    1052862void MythDB::WriteDelayedSettings(void)
    1053863{
    1054864    if (!HaveValidDatabase())
  • mythtv/libs/libmythbase/mythdb.h

    diff --git a/mythtv/libs/libmythbase/mythdb.h b/mythtv/libs/libmythbase/mythdb.h
    index 79abe56..255511f 100644
    a b  
    99#include "mythdbparams.h"
    1010
    1111class MythDBPrivate;
    12 class Settings;
    1312class MDBManager;
    1413
    1514class MBASE_PUBLIC MythDB
    class MBASE_PUBLIC MythDB 
    1716    friend class MSqlQuery;
    1817  public:
    1918    MDBManager *GetDBManager(void);
    20     Settings *GetOldSettings(void);
    2119
    2220    static QString GetError(const QString &where, const MSqlQuery &query);
    2321    static void DBError(const QString &where, const MSqlQuery &query);
    class MBASE_PUBLIC MythDB 
    3836    void ClearSettingsCache(const QString &key = QString());
    3937    void ActivateSettingsCache(bool activate = true);
    4038    void OverrideSettingForSession(const QString &key, const QString &newValue);
     39    void ClearOverrideSettingForSession(const QString &key);
    4140
    4241    void SaveSetting(const QString &key, int newValue);
    4342    void SaveSetting(const QString &key, const QString &newValue);
    class MBASE_PUBLIC MythDB 
    7170    void GetResolutionSetting(const QString &type, int &width, int &height,
    7271                              int index=-1);
    7372
    74     void SetSetting(const QString &key, const QString &newValue);
    75 
    7673    void WriteDelayedSettings(void);
    7774
    7875    void SetHaveDBConnection(bool connected);
    class MBASE_PUBLIC MythDB 
    8582    static QString toCommaList(const QMap<QString, QVariant> &bindings,
    8683                               uint indent = 0, uint softMaxColumn = 80);
    8784
    88     static bool LoadDatabaseParamsFromDisk(DatabaseParams &params);
    89     static bool ValidateDatabaseParams(
    90         const DatabaseParams &params, const QString &source);
    91     static void LoadDefaultDatabaseParams(DatabaseParams &params);
    92     static bool SaveDatabaseParamsToDisk(
    93         const DatabaseParams &params, const QString &confdir, bool overwrite);
    94 
    9585  protected:
    9686    MythDB();
    9787   ~MythDB();
  • new file mythtv/libs/libmythbase/mythdbparams.cpp

    diff --git a/mythtv/libs/libmythbase/mythdbparams.cpp b/mythtv/libs/libmythbase/mythdbparams.cpp
    new file mode 100644
    index 0000000..1290221
    - +  
     1#include "mythdbparams.h"
     2#include "mythlogging.h"
     3
     4/// Load sensible connection defaults.
     5void DatabaseParams::LoadDefaults(void)
     6{
     7    LOG(VB_GENERAL, LOG_INFO, "DatabaseParams::LoadDefaults()");
     8    dbHostName    = "localhost";
     9    dbHostPing    = true;
     10    dbPort        = 3306;
     11    dbUserName    = "mythtv";
     12    dbPassword    = "mythtv";
     13    dbName        = "mythconverg";
     14    dbType        = "QMYSQL";
     15
     16    localEnabled  = false;
     17    localHostName = "my-unique-identifier-goes-here";
     18
     19    wolEnabled    = false;
     20    wolReconnect  = 0;
     21    wolRetry      = 5;
     22    wolCommand    = "echo 'WOLsqlServerCommand not set'";
     23
     24    verVersion.clear();
     25    verBranch.clear();
     26    verProtocol.clear();
     27    verBinary.clear();
     28    verSchema.clear();
     29}
     30
     31bool DatabaseParams::IsValid(const QString &source) const
     32{
     33    // Print some warnings if things look fishy..
     34    QString msg = QString(" is not set in %1").arg(source);
     35
     36    if (dbHostName.isEmpty())
     37    {
     38        LOG(VB_GENERAL, LOG_ERR, "DBHostName" + msg);
     39        return false;
     40    }
     41    if (dbUserName.isEmpty())
     42    {
     43        LOG(VB_GENERAL, LOG_ERR, "DBUserName" + msg);
     44        return false;
     45    }
     46    if (dbPassword.isEmpty())
     47    {
     48        LOG(VB_GENERAL, LOG_ERR, "DBPassword" + msg);
     49        return false;
     50    }
     51    if (dbName.isEmpty())
     52    {
     53        LOG(VB_GENERAL, LOG_ERR, "DBName" + msg);
     54        return false;
     55    }
     56
     57    return true;
     58}
     59
     60bool DatabaseParams::operator==(const DatabaseParams &other) const
     61{
     62    return
     63        dbHostName   == other.dbHostName     &&
     64        dbHostPing   == other.dbHostPing     &&
     65        dbPort       == other.dbPort         &&
     66        dbUserName   == other.dbUserName     &&
     67        dbPassword   == other.dbPassword     &&
     68        dbName       == other.dbName         &&
     69        dbType       == other.dbType         &&
     70        localEnabled == other.localEnabled   &&
     71        wolEnabled   == other.wolEnabled     &&
     72        (!localEnabled || (localHostName == other.localHostName)) &&
     73        (!wolEnabled ||
     74         (wolReconnect == other.wolReconnect &&
     75          wolRetry     == other.wolRetry     &&
     76          wolCommand   == other.wolCommand));
     77}
  • mythtv/libs/libmythbase/mythdbparams.h

    diff --git a/mythtv/libs/libmythbase/mythdbparams.h b/mythtv/libs/libmythbase/mythdbparams.h
    index a60f576..bb0728b 100644
    a b  
    11#ifndef MYTHDBPARAMS_H_
    22#define MYTHDBPARAMS_H_
    33
     4#include <QString>
     5
    46#include "mythbaseexp.h"
    57
    68/// Structure containing the basic Database parameters
    7 struct MBASE_PUBLIC DatabaseParams
     9class MBASE_PUBLIC DatabaseParams
    810{
     11  public:
     12    DatabaseParams() { LoadDefaults(); }
     13
     14    void LoadDefaults(void);
     15    bool IsValid(const QString &source = QString("Unknown")) const;
     16
     17    bool operator==(const DatabaseParams &other) const;
     18    bool operator!=(const DatabaseParams &other) const
     19        { return !((*this)==other); }
     20
    921    QString dbHostName;         ///< database server
    1022    bool    dbHostPing;         ///< Can we test connectivity using ping?
    1123    int     dbPort;             ///< database port
  • mythtv/libs/libmythbase/mythlocale.cpp

    diff --git a/mythtv/libs/libmythbase/mythlocale.cpp b/mythtv/libs/libmythbase/mythlocale.cpp
    index e22d55c..9142bb8 100644
    a b void MythLocale::SaveLocaleDefaults(bool overwrite) 
    168168    {
    169169        MythDB *mythDB = MythDB::getMythDB();
    170170        if (overwrite || mythDB->GetSetting(it.key()).isEmpty())
    171         {
    172             mythDB->SetSetting(it.key(), it.value());
    173171            mythDB->SaveSettingOnHost(it.key(), it.value(), "");
    174         }
    175172    }
    176173
    177174    for (it = m_hostSettings.begin(); it != m_hostSettings.end(); ++it)
    178175    {
    179176        MythDB *mythDB = MythDB::getMythDB();
    180177        if (overwrite || mythDB->GetSetting(it.key()).isEmpty())
    181         {
    182             mythDB->SetSetting(it.key(), it.value());
    183178            mythDB->SaveSetting(it.key(), it.value());
    184         }
    185179    }
    186180}
    187181
  • mythtv/libs/libmythbase/mythtranslation.cpp

    diff --git a/mythtv/libs/libmythbase/mythtranslation.cpp b/mythtv/libs/libmythbase/mythtranslation.cpp
    index 46adf08..6690cf9 100644
    a b void MythTranslation::load(const QString &module_name) 
    5252
    5353    if (lang == "en")
    5454    {
    55         gCoreContext->SetSetting("Language", "en_US");
    5655        gCoreContext->SaveSetting("Language", "en_US");
    5756        lang = "en_us";
    5857    }
  • mythtv/libs/libmythmetadata/parentalcontrols.cpp

    diff --git a/mythtv/libs/libmythmetadata/parentalcontrols.cpp b/mythtv/libs/libmythmetadata/parentalcontrols.cpp
    index 74b2054..124c832 100644
    a b class ParentalLevelChangeCheckerPrivate : public QObject 
    277277            {
    278278                // Two minute window
    279279                last_time_stamp = curr_time.toString(Qt::ISODate);
    280                 gCoreContext->SetSetting("VideoPasswordTime", last_time_stamp);
    281280                gCoreContext->SaveSetting("VideoPasswordTime", last_time_stamp);
    282281                return true;
    283282            }
  • mythtv/libs/libmythui/myththemedmenu.cpp

    diff --git a/mythtv/libs/libmythui/myththemedmenu.cpp b/mythtv/libs/libmythui/myththemedmenu.cpp
    index bfd5429..8b1f6fa 100644
    a b void MythThemedMenu::customEvent(QEvent *event) 
    424424                QString timestamp_setting = QString("%1Time").arg(button.password);
    425425                QDateTime curr_time = QDateTime::currentDateTime();
    426426                QString last_time_stamp = curr_time.toString(Qt::TextDate);
    427                 GetMythDB()->SetSetting(timestamp_setting, last_time_stamp);
    428427                GetMythDB()->SaveSetting(timestamp_setting, last_time_stamp);
    429428                buttonAction(item, true);
    430429            }
    bool MythThemedMenu::checkPinCode(const QString &password_setting) 
    923922        if (last_time.secsTo(curr_time) < 120)
    924923        {
    925924            last_time_stamp = curr_time.toString(Qt::TextDate);
    926             GetMythDB()->SetSetting(timestamp_setting, last_time_stamp);
    927925            GetMythDB()->SaveSetting(timestamp_setting, last_time_stamp);
    928926            return true;
    929927        }
  • mythtv/libs/libmythupnp/configuration.cpp

    diff --git a/mythtv/libs/libmythupnp/configuration.cpp b/mythtv/libs/libmythupnp/configuration.cpp
    index 1447355..e818974 100644
    a b  
    2121//
    2222//////////////////////////////////////////////////////////////////////////////
    2323
     24#include <unistd.h> // for fsync
     25
    2426#include <iostream>
    2527
    2628#include <QDir>
    bool XmlConfiguration::Save( void ) 
    98100    if (m_sFileName.isEmpty())   // Special case. No file is created
    99101        return true;
    100102
    101     QString sName = m_sPath + '/' + m_sFileName;
     103    QString config_temppath = m_sPath + '/' + m_sFileName + ".new";
     104    QString config_filepath = m_sPath + '/' + m_sFileName;
     105    QString config_origpath = m_sPath + '/' + m_sFileName + ".orig";
    102106
    103     QFile file( sName );
     107    QFile file(config_temppath);
    104108   
    105109    if (!file.exists())
    106110    {
    107         QDir createDir( m_sPath );
    108 
     111        QDir createDir(m_sPath);
    109112        if (!createDir.exists())
    110113        {
    111114            if (!createDir.mkdir(m_sPath))
    bool XmlConfiguration::Save( void ) 
    117120        }
    118121    }
    119122
    120     if (!file.open( QIODevice::WriteOnly | QIODevice::Truncate ))
     123    if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
    121124    {
    122125        LOG(VB_GENERAL, LOG_ERR,
    123             QString("Could not open settings file %1 for writing").arg(sName));
     126            QString("Could not open settings file %1 for writing")
     127            .arg(config_temppath));
    124128
    125129        return false;
    126130    }
    127131
    128     QTextStream ts( &file );
     132    {
     133        QTextStream ts(&file);
     134        m_config.save(ts, 2);
     135    }
     136
     137    file.flush();
    129138
    130     m_config.save( ts, 2 );
     139    fsync(file.handle());
    131140
    132141    file.close();
    133142
    134     return true;
     143    bool ok = true;
     144    if (QFile::exists(config_filepath))
     145        ok = QFile::rename(config_filepath, config_origpath);
     146
     147    if (ok)
     148    {
     149        ok = file.rename(config_filepath);
     150        if (ok)
     151            QFile::remove(config_origpath);
     152        else if (QFile::exists(config_origpath))
     153            QFile::rename(config_origpath, config_filepath);
     154    }
     155
     156    if (!ok)
     157    {
     158        LOG(VB_GENERAL, LOG_ERR,
     159            QString("Could not save settings file %1").arg(config_filepath));
     160    }
     161
     162    return ok;
    135163}
    136164
    137165//////////////////////////////////////////////////////////////////////////////
  • mythtv/programs/mythbackend/mythsettings.cpp

    diff --git a/mythtv/programs/mythbackend/mythsettings.cpp b/mythtv/programs/mythbackend/mythsettings.cpp
    index 4b033cc..cfdebfa 100644
    a b QMap<QString,QString> GetSettingsMap(MythSettingList &settings, 
    355355    QMap<QString,QString> result;
    356356    MSqlQuery query(MSqlQuery::InitCon());
    357357
    358     QString list = extract_query_list(settings, MythSetting::kFile);
    359     if (!list.isEmpty())
    360     {
    361         result = GetConfigFileSettingValues();
    362         if (result.isEmpty())
    363             return result;
    364     }
    365 
    366     list = extract_query_list(settings, MythSetting::kHost);
     358    QString list = extract_query_list(settings, MythSetting::kHost);
    367359    QString qstr =
    368360        "SELECT value, data "
    369361        "FROM settings "
    QString StringListToJSON(const QString &key, 
    474466    return result;
    475467}
    476468
    477 QMap<QString,QString> GetConfigFileSettingValues(void)
    478 {
    479     QMap<QString,QString> map;
    480     DatabaseParams params;
    481     if (!MythDB::LoadDatabaseParamsFromDisk(params))
    482         MythDB::LoadDefaultDatabaseParams(params);
    483 
    484     map["dbHostName"]           = params.dbHostName;
    485     map["dbPort"]               = QString::number(params.dbPort);
    486     map["dbPing"]               = QString::number(params.dbHostPing);
    487     map["dbName"]               = params.dbName;
    488     map["dbUserName"]           = params.dbUserName;
    489     map["dbPassword"]           = params.dbPassword;
    490     map["dbHostID"]             = params.localHostName;
    491     map["dbWOLEnabled"]         =
    492         QString::number(params.wolEnabled);
    493     map["dbWOLReconnectCount"]  =
    494         QString::number(params.wolReconnect);
    495     map["dbWOLRetryCount"]      =
    496         QString::number(params.wolRetry);
    497     map["dbWOLCommand"]         = params.wolCommand;
    498 
    499     return map;
    500 }
    501 
    502469bool parse_dom(MythSettingList &settings, const QDomElement &element,
    503470               const QString &filename, const QString &group,
    504471               bool includeAllChildren, bool &foundGroup)
    bool load_settings(MythSettingList &settings, const QString &hostname) 
    706673{
    707674    MSqlQuery query(MSqlQuery::InitCon());
    708675
    709     QString list = extract_query_list(settings, MythSetting::kFile);
    710     if (!list.isEmpty())
    711     {
    712         QMap<QString,QString> map = GetConfigFileSettingValues();
    713         if (map.isEmpty())
    714             return false;
    715 
    716         MythSettingList::const_iterator it = settings.begin();
    717         for (; it != settings.end(); ++it)
    718             fill_setting(*it, map, MythSetting::kFile);
    719     }
    720 
    721     list = extract_query_list(settings, MythSetting::kHost);
     676    QString list = extract_query_list(settings, MythSetting::kHost);
    722677    QString qstr =
    723678        "SELECT value, data "
    724679        "FROM settings "
  • mythtv/programs/mythbackend/mythsettings.h

    diff --git a/mythtv/programs/mythbackend/mythsettings.h b/mythtv/programs/mythbackend/mythsettings.h
    index 43fa892..2c6f812 100644
    a b bool check_settings(MythSettingList &database_settings, 
    125125QStringList           GetSettingValueList(const QString &type);
    126126QString               StringMapToJSON(const QMap<QString,QString> &map);
    127127QString               StringListToJSON(const QString &key, const QStringList &sList);
    128 QMap<QString,QString> GetConfigFileSettingValues();
    129128QMap<QString,QString> GetSettingsMap(MythSettingList &settings, const QString &hostname);
    130129
    131130#endif
  • mythtv/programs/mythtv-setup/main.cpp

    diff --git a/mythtv/programs/mythtv-setup/main.cpp b/mythtv/programs/mythtv-setup/main.cpp
    index 266256a..2e82fdd 100644
    a b int main(int argc, char *argv[]) 
    342342
    343343    if (use_display)
    344344    {
    345         gCoreContext->SetSetting("Theme", DEFAULT_UI_THEME);
     345        gCoreContext->OverrideSettingForSession("Theme", DEFAULT_UI_THEME);
    346346        GetMythUI()->LoadQtConfig();
    347347
    348348        QString fileprefix = GetConfDir();
  • mythtv/programs/mythtv-setup/startprompt.cpp

    diff --git a/mythtv/programs/mythtv-setup/startprompt.cpp b/mythtv/programs/mythtv-setup/startprompt.cpp
    index b49385a..e61cf12 100644
    a b void StartPrompter::handleStart() 
    4444void StartPrompter::leaveBackendRunning()
    4545{
    4646    LOG(VB_GENERAL, LOG_INFO, "Continuing with backend running");
    47     gCoreContext->SetSetting("AutoRestartBackend", "0");
     47    gCoreContext->OverrideSettingForSession("AutoRestartBackend", "0");
    4848}
    4949
    5050void StartPrompter::stopBackend()
    void StartPrompter::stopBackend() 
    5656    {
    5757        myth_system(commandString);
    5858    }
    59     gCoreContext->SetSetting("AutoRestartBackend", "1");
     59    gCoreContext->OverrideSettingForSession("AutoRestartBackend", "1");
    6060}
    6161
    6262void StartPrompter::backendRunningPrompt(void)