Skip to content

Commit

Permalink
Display database upgrade message only when we actually do it
Browse files Browse the repository at this point in the history
  • Loading branch information
phate89 committed Oct 24, 2016
1 parent 6dc21aa commit a184181
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 132 deletions.
4 changes: 2 additions & 2 deletions addons/resource.language.en_gb/resources/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -14654,13 +14654,13 @@ msgstr ""
#. Progress text on splash screen
#: xbmc/Application.cpp
msgctxt "#24150"
msgid "Database migration in progress - please wait..."
msgid "Database migration in progress - please wait"
msgstr ""

#. Progress text on splash screen
#: xbmc/Application.cpp
msgctxt "#24151"
msgid "Add-on migration in progress - please wait..."
msgid "Add-on migration in progress - please wait"
msgstr ""

#empty strings from id 24152 to 24990
Expand Down
41 changes: 36 additions & 5 deletions xbmc/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "events/EventLog.h"
#include "events/NotificationEvent.h"
#include "interfaces/builtins/Builtins.h"
#include "utils/JobManager.h"
#include "utils/Variant.h"
#include "utils/Splash.h"
#include "LangInfo.h"
Expand Down Expand Up @@ -1123,8 +1124,22 @@ bool CApplication::Initialize()
g_curlInterface.Unload();

// initialize (and update as needed) our databases
CSplash::GetInstance().Show(g_localizeStrings.Get(24150));
CDatabaseManager::GetInstance().Initialize();
std::atomic<bool> notFinished(true);
CJobManager::GetInstance().Submit([&notFinished]() {
CDatabaseManager::GetInstance().Initialize();
notFinished = false;
});
std::string localizedStr = g_localizeStrings.Get(24150);
while (notFinished)
{
for (int i = 1; i <= 3 && notFinished; ++i)
{
if (CDatabaseManager::GetInstance().m_bIsUpgrading)
CSplash::GetInstance().Show(std::string(i, ' ') + localizedStr + std::string(i, '.'));
if (notFinished)
Sleep(1000);
}
}
CSplash::GetInstance().Show();

StartServices();
Expand All @@ -1139,11 +1154,27 @@ bool CApplication::Initialize()
g_windowManager.CreateWindows();

m_confirmSkinChange = false;
m_incompatibleAddons = CAddonSystemSettings::GetInstance().MigrateAddons([](){
CSplash::GetInstance().Show(g_localizeStrings.Get(24151));

notFinished = true;
std::vector<std::string> incompatibleAddons;
CJobManager::GetInstance().Submit([&notFinished, &incompatibleAddons]() {
incompatibleAddons = CAddonSystemSettings::GetInstance().MigrateAddons();
notFinished = false;
});
m_confirmSkinChange = true;
localizedStr = g_localizeStrings.Get(24151);
while (notFinished)
{
for (int i = 1; i <= 3 && notFinished; ++i)
{
if (CAddonSystemSettings::GetInstance().m_bIsMigratingAddons)
CSplash::GetInstance().Show(std::string(i, ' ') + localizedStr + std::string(i, '.'));
if (notFinished)
Sleep(1000);
}
}
CSplash::GetInstance().Show();
m_incompatibleAddons = incompatibleAddons;
m_confirmSkinChange = true;

std::string defaultSkin = ((const CSettingString*)CSettings::GetInstance().GetSetting(CSettings::SETTING_LOOKANDFEEL_SKIN))->GetDefault();
if (!LoadSkin(CSettings::GetInstance().GetString(CSettings::SETTING_LOOKANDFEEL_SKIN)))
Expand Down
124 changes: 122 additions & 2 deletions xbmc/DatabaseManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ CDatabaseManager &CDatabaseManager::GetInstance()
return s_manager;
}

CDatabaseManager::CDatabaseManager()
CDatabaseManager::CDatabaseManager(): m_bIsUpgrading(false)
{
}

Expand All @@ -66,6 +66,7 @@ void CDatabaseManager::Initialize(bool addonsOnly)
{ CEpgDatabase db; UpdateDatabase(db, &g_advancedSettings.m_databaseEpg); }
{ CActiveAEDSPDatabase db; UpdateDatabase(db, &g_advancedSettings.m_databaseADSP); }
CLog::Log(LOGDEBUG, "%s, updating databases... DONE", __FUNCTION__);
m_bIsUpgrading = false;
}

void CDatabaseManager::Deinitialize()
Expand All @@ -87,12 +88,131 @@ void CDatabaseManager::UpdateDatabase(CDatabase &db, DatabaseSettings *settings)
{
std::string name = db.GetBaseDBName();
UpdateStatus(name, DB_UPDATING);
if (db.Update(settings ? *settings : DatabaseSettings()))
if (Update(db, settings ? *settings : DatabaseSettings()))
UpdateStatus(name, DB_READY);
else
UpdateStatus(name, DB_FAILED);
}

bool CDatabaseManager::Update(CDatabase &db, const DatabaseSettings &settings)
{
DatabaseSettings dbSettings = settings;
db.InitSettings(dbSettings);

int version = db.GetSchemaVersion();
std::string latestDb = dbSettings.name;
latestDb += StringUtils::Format("%d", version);

while (version >= db.GetMinSchemaVersion())
{
std::string dbName = dbSettings.name;
if (version)
dbName += StringUtils::Format("%d", version);

if (db.Connect(dbName, dbSettings, false))
{
// Database exists, take a copy for our current version (if needed) and reopen that one
if (version < db.GetSchemaVersion())
{
CLog::Log(LOGNOTICE, "Old database found - updating from version %i to %i", version, db.GetSchemaVersion());
m_bIsUpgrading = true;

bool copy_fail = false;

try
{
db.CopyDB(latestDb);
}
catch (...)
{
CLog::Log(LOGERROR, "Unable to copy old database %s to new version %s", dbName.c_str(), latestDb.c_str());
copy_fail = true;
}

db.Close();

if (copy_fail)
return false;

if (!db.Connect(latestDb, dbSettings, false))
{
CLog::Log(LOGERROR, "Unable to open freshly copied database %s", latestDb.c_str());
return false;
}
}

// yay - we have a copy of our db, now do our worst with it
if (UpdateVersion(db, latestDb))
return true;

// update failed - loop around and see if we have another one available
db.Close();
}

// drop back to the previous version and try that
version--;
}
// try creating a new one
if (db.Connect(latestDb, dbSettings, true))
return true;

// failed to update or open the database
db.Close();
CLog::Log(LOGERROR, "Unable to create new database");
return false;
}

bool CDatabaseManager::UpdateVersion(CDatabase &db, const std::string &dbName)
{
int version = db.GetDBVersion();
bool bReturn = false;

if (version < db.GetMinSchemaVersion())
{
CLog::Log(LOGERROR, "Can't update database %s from version %i - it's too old", dbName.c_str(), version);
return false;
}
else if (version < db.GetSchemaVersion())
{
CLog::Log(LOGNOTICE, "Attempting to update the database %s from version %i to %i", dbName.c_str(), version, db.GetSchemaVersion());
bool success = true;
db.BeginTransaction();
try
{
// drop old analytics, update table(s), recreate analytics, update version
db.DropAnalytics();
db.UpdateTables(version);
db.CreateAnalytics();
db.UpdateVersionNumber();
}
catch (...)
{
CLog::Log(LOGERROR, "Exception updating database %s from version %i to %i", dbName.c_str(), version, db.GetSchemaVersion());
success = false;
}
if (!success)
{
CLog::Log(LOGERROR, "Error updating database %s from version %i to %i", dbName.c_str(), version, db.GetSchemaVersion());
db.RollbackTransaction();
return false;
}
bReturn = db.CommitTransaction();
CLog::Log(LOGINFO, "Update to version %i successful", db.GetSchemaVersion());
}
else if (version > db.GetSchemaVersion())
{
bReturn = false;
CLog::Log(LOGERROR, "Can't open the database %s as it is a NEWER version than what we were expecting?", dbName.c_str());
}
else
{
bReturn = true;
CLog::Log(LOGNOTICE, "Running database version %s", dbName.c_str());
}

return bReturn;
}

void CDatabaseManager::UpdateStatus(const std::string &name, DB_STATUS status)
{
CSingleLock lock(m_section);
Expand Down
4 changes: 4 additions & 0 deletions xbmc/DatabaseManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#pragma once

#include <atomic>
#include <map>
#include <string>
#include "threads/CriticalSection.h"
Expand Down Expand Up @@ -63,6 +64,7 @@ class CDatabaseManager
\return true if the database can be opened, false otherwise.
*/
bool CanOpen(const std::string &name);
std::atomic<bool> m_bIsUpgrading;

private:
// private construction, and no assignements; use the provided singleton methods
Expand All @@ -74,6 +76,8 @@ class CDatabaseManager
enum DB_STATUS { DB_CLOSED, DB_UPDATING, DB_READY, DB_FAILED };
void UpdateStatus(const std::string &name, DB_STATUS status);
void UpdateDatabase(CDatabase &db, DatabaseSettings *settings = NULL);
bool Update(CDatabase &db, const DatabaseSettings &settings);
bool UpdateVersion(CDatabase &db, const std::string &dbName);

CCriticalSection m_section; ///< Critical section protecting m_dbStatus.
std::map<std::string, DB_STATUS> m_dbStatus; ///< Our database status map.
Expand Down
10 changes: 6 additions & 4 deletions xbmc/addons/AddonSystemSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@

namespace ADDON
{

CAddonSystemSettings::CAddonSystemSettings() :
CAddonSystemSettings::CAddonSystemSettings() : m_bIsMigratingAddons(false),
m_activeSettings{
{ADDON_VIZ, CSettings::SETTING_MUSICPLAYER_VISUALISATION},
{ADDON_SCREENSAVER, CSettings::SETTING_SCREENSAVER_MODE},
Expand Down Expand Up @@ -126,7 +126,7 @@ bool CAddonSystemSettings::UnsetActive(const AddonPtr& addon)
}


std::vector<std::string> CAddonSystemSettings::MigrateAddons(std::function<void(void)> onMigrate)
std::vector<std::string> CAddonSystemSettings::MigrateAddons()
{
auto getIncompatible = [](){
VECADDONS incompatible;
Expand All @@ -141,13 +141,15 @@ std::vector<std::string> CAddonSystemSettings::MigrateAddons(std::function<void(

if (CSettings::GetInstance().GetInt(CSettings::SETTING_ADDONS_AUTOUPDATES) == AUTO_UPDATES_ON)
{
onMigrate();
m_bIsMigratingAddons = true;

if (CRepositoryUpdater::GetInstance().CheckForUpdates())
CRepositoryUpdater::GetInstance().Await();

CLog::Log(LOGINFO, "ADDON: waiting for add-ons to update...");
CAddonInstaller::GetInstance().InstallUpdates();

m_bIsMigratingAddons = false;
}

auto incompatible = getIncompatible();
Expand Down
5 changes: 3 additions & 2 deletions xbmc/addons/AddonSystemSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
*
*/

#include <atomic>
#include "addons/IAddon.h"
#include "settings/lib/ISettingCallback.h"
#include <functional>
#include <string>

namespace ADDON
Expand Down Expand Up @@ -54,7 +54,8 @@ class CAddonSystemSettings : public ISettingCallback
* @param onMigrate Called when a long running migration task takes place.
* @return list of addons that was modified.
*/
std::vector<std::string> MigrateAddons(std::function<void(void)> onMigrate);
std::vector<std::string> MigrateAddons();
std::atomic<bool> m_bIsMigratingAddons;

private:
CAddonSystemSettings();
Expand Down
Loading

0 comments on commit a184181

Please sign in to comment.