diff options
author | phate89 <phates89@gmail.com> | 2016-10-24 19:03:11 +0200 |
---|---|---|
committer | phate89 <phates89@gmail.com> | 2016-10-25 17:23:47 +0200 |
commit | f344ca0ecfb59e50c6f58b5f313036a93582677b (patch) | |
tree | 23b772586e7a91daf05bf87419fb806072d06d8e | |
parent | a3dba41fcd8880f85b5b7a1d33eb07e276f46048 (diff) |
Change splash db upgrade logic
-rw-r--r-- | addons/resource.language.en_gb/resources/strings.po | 4 | ||||
-rw-r--r-- | xbmc/Application.cpp | 44 | ||||
-rw-r--r-- | xbmc/DatabaseManager.cpp | 124 | ||||
-rw-r--r-- | xbmc/DatabaseManager.h | 4 | ||||
-rw-r--r-- | xbmc/dbwrappers/Database.cpp | 120 | ||||
-rw-r--r-- | xbmc/dbwrappers/Database.h | 4 | ||||
-rw-r--r-- | xbmc/utils/Splash.cpp | 11 | ||||
-rw-r--r-- | xbmc/utils/Splash.h | 3 |
8 files changed, 179 insertions, 135 deletions
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 5d2af8d870..49d05961a8 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -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 diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index 07f7e5fdbc..d65f1f5ed0 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -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" @@ -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(); + CEvent event(true); + CJobManager::GetInstance().Submit([&event]() { + CDatabaseManager::GetInstance().Initialize(); + event.Set(); + }); + std::string localizedStr = g_localizeStrings.Get(24150); + int iDots = 1; + while (!event.WaitMSec(1000)) + { + if (CDatabaseManager::GetInstance().m_bIsUpgrading) + CSplash::GetInstance().Show(std::string(iDots, ' ') + localizedStr + std::string(iDots, '.')); + if (iDots == 3) + iDots = 1; + else + ++iDots; + } CSplash::GetInstance().Show(); StartServices(); @@ -1139,11 +1154,30 @@ bool CApplication::Initialize() g_windowManager.CreateWindows(); m_confirmSkinChange = false; - m_incompatibleAddons = CAddonSystemSettings::GetInstance().MigrateAddons([](){ - CSplash::GetInstance().Show(g_localizeStrings.Get(24151)); + + std::vector<std::string> incompatibleAddons; + event.Reset(); + std::atomic<bool> isMigratingAddons(false); + CJobManager::GetInstance().Submit([&event, &incompatibleAddons, &isMigratingAddons]() { + incompatibleAddons = CAddonSystemSettings::GetInstance().MigrateAddons([&isMigratingAddons]() { + isMigratingAddons = true; + }); + event.Set(); }); - m_confirmSkinChange = true; + localizedStr = g_localizeStrings.Get(24151); + iDots = 1; + while (!event.WaitMSec(1000)) + { + if (isMigratingAddons) + CSplash::GetInstance().Show(std::string(iDots, ' ') + localizedStr + std::string(iDots, '.')); + if (iDots == 3) + iDots = 1; + else + ++iDots; + } 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))) diff --git a/xbmc/DatabaseManager.cpp b/xbmc/DatabaseManager.cpp index ed0178d616..cfd839f4cf 100644 --- a/xbmc/DatabaseManager.cpp +++ b/xbmc/DatabaseManager.cpp @@ -40,7 +40,7 @@ CDatabaseManager &CDatabaseManager::GetInstance() return s_manager; } -CDatabaseManager::CDatabaseManager() +CDatabaseManager::CDatabaseManager(): m_bIsUpgrading(false) { } @@ -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() @@ -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); diff --git a/xbmc/DatabaseManager.h b/xbmc/DatabaseManager.h index c3bfba56d4..b6b4b22e07 100644 --- a/xbmc/DatabaseManager.h +++ b/xbmc/DatabaseManager.h @@ -20,6 +20,7 @@ #pragma once +#include <atomic> #include <map> #include <string> #include "threads/CriticalSection.h" @@ -63,6 +64,7 @@ public: \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 @@ -74,6 +76,8 @@ private: 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. diff --git a/xbmc/dbwrappers/Database.cpp b/xbmc/dbwrappers/Database.cpp index 4dc71c5482..7d9abc0356 100644 --- a/xbmc/dbwrappers/Database.cpp +++ b/xbmc/dbwrappers/Database.cpp @@ -356,71 +356,14 @@ void CDatabase::InitSettings(DatabaseSettings &dbSettings) dbSettings.name = GetBaseDBName(); } -bool CDatabase::Update(const DatabaseSettings &settings) +void CDatabase::CopyDB(const std::string& latestDb) { - DatabaseSettings dbSettings = settings; - InitSettings(dbSettings); - - int version = GetSchemaVersion(); - std::string latestDb = dbSettings.name; - latestDb += StringUtils::Format("%d", version); - - while (version >= GetMinSchemaVersion()) - { - std::string dbName = dbSettings.name; - if (version) - dbName += StringUtils::Format("%d", version); - - if (Connect(dbName, dbSettings, false)) - { - // Database exists, take a copy for our current version (if needed) and reopen that one - if (version < GetSchemaVersion()) - { - CLog::Log(LOGNOTICE, "Old database found - updating from version %i to %i", version, GetSchemaVersion()); - - bool copy_fail = false; - - try - { - m_pDB->copy(latestDb.c_str()); - } - catch(...) - { - CLog::Log(LOGERROR, "Unable to copy old database %s to new version %s", dbName.c_str(), latestDb.c_str()); - copy_fail = true; - } - - Close(); - - if ( copy_fail ) - return false; - - if (!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(latestDb)) - return true; - - // update failed - loop around and see if we have another one available - Close(); - } - - // drop back to the previous version and try that - version--; - } - // try creating a new one - if (Connect(latestDb, dbSettings, true)) - return true; + m_pDB->copy(latestDb.c_str()); +} - // failed to update or open the database - Close(); - CLog::Log(LOGERROR, "Unable to create new database"); - return false; +void CDatabase::DropAnalytics() +{ + m_pDB->drop_analytics(); } bool CDatabase::Connect(const std::string &dbName, const DatabaseSettings &dbSettings, bool create) @@ -520,57 +463,6 @@ int CDatabase::GetDBVersion() return 0; } -bool CDatabase::UpdateVersion(const std::string &dbName) -{ - int version = GetDBVersion(); - bool bReturn = false; - - if (version < 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 < GetSchemaVersion()) - { - CLog::Log(LOGNOTICE, "Attempting to update the database %s from version %i to %i", dbName.c_str(), version, GetSchemaVersion()); - bool success = true; - BeginTransaction(); - try - { - // drop old analytics, update table(s), recreate analytics, update version - m_pDB->drop_analytics(); - UpdateTables(version); - CreateAnalytics(); - UpdateVersionNumber(); - } - catch (...) - { - CLog::Log(LOGERROR, "Exception updating database %s from version %i to %i", dbName.c_str(), version, GetSchemaVersion()); - success = false; - } - if (!success) - { - CLog::Log(LOGERROR, "Error updating database %s from version %i to %i", dbName.c_str(), version, GetSchemaVersion()); - RollbackTransaction(); - return false; - } - bReturn = CommitTransaction(); - CLog::Log(LOGINFO, "Update to version %i successful", GetSchemaVersion()); - } - else if (version > 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; -} - bool CDatabase::IsOpen() { return m_openCount > 0; diff --git a/xbmc/dbwrappers/Database.h b/xbmc/dbwrappers/Database.h index 6370a4e003..d4c753b15f 100644 --- a/xbmc/dbwrappers/Database.h +++ b/xbmc/dbwrappers/Database.h @@ -70,6 +70,8 @@ public: virtual bool CommitTransaction(); void RollbackTransaction(); bool InTransaction(); + void CopyDB(const std::string& latestDb); + void DropAnalytics(); std::string PrepareSQL(std::string strStmt, ...) const; @@ -157,7 +159,6 @@ public: protected: friend class CDatabaseManager; - bool Update(const DatabaseSettings &db); void Split(const std::string& strFileNameAndPath, std::string& strPath, std::string& strFileName); @@ -194,7 +195,6 @@ protected: virtual const char *GetBaseDBName() const=0; int GetDBVersion(); - bool UpdateVersion(const std::string &dbName); bool BuildSQL(const std::string &strQuery, const Filter &filter, std::string &strSQL); diff --git a/xbmc/utils/Splash.cpp b/xbmc/utils/Splash.cpp index d7d4812103..e66428494b 100644 --- a/xbmc/utils/Splash.cpp +++ b/xbmc/utils/Splash.cpp @@ -39,14 +39,9 @@ CSplash& CSplash::GetInstance() return instance; } -void CSplash::Show() +void CSplash::Show(const std::string& message /* = "" */) { - Show(""); -} - -void CSplash::Show(const std::string& message) -{ - if (!g_advancedSettings.m_splashImage) + if (!g_advancedSettings.m_splashImage && !(m_image || !message.empty())) return; if (!m_image) @@ -90,7 +85,7 @@ void CSplash::Show(const std::string& message) int width = g_graphicsContext.GetWidth(); int height = g_graphicsContext.GetHeight(); - float y = height - textHeight - 30; // -30 for safe viewing area + float y = height - textHeight - 100; m_messageLayout->RenderOutline(width/2, y, 0, 0xFF000000, XBFONT_CENTER_X, width); } } diff --git a/xbmc/utils/Splash.h b/xbmc/utils/Splash.h index 03ade137ab..3563da47c8 100644 --- a/xbmc/utils/Splash.h +++ b/xbmc/utils/Splash.h @@ -31,8 +31,7 @@ class CSplash public: static CSplash& GetInstance(); - void Show(); - void Show(const std::string& message); + void Show(const std::string& message = ""); protected: CSplash(); |