aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorphate89 <phates89@gmail.com>2016-10-24 19:03:11 +0200
committerphate89 <phates89@gmail.com>2016-10-25 17:23:47 +0200
commitf344ca0ecfb59e50c6f58b5f313036a93582677b (patch)
tree23b772586e7a91daf05bf87419fb806072d06d8e
parenta3dba41fcd8880f85b5b7a1d33eb07e276f46048 (diff)
Change splash db upgrade logic
-rw-r--r--addons/resource.language.en_gb/resources/strings.po4
-rw-r--r--xbmc/Application.cpp44
-rw-r--r--xbmc/DatabaseManager.cpp124
-rw-r--r--xbmc/DatabaseManager.h4
-rw-r--r--xbmc/dbwrappers/Database.cpp120
-rw-r--r--xbmc/dbwrappers/Database.h4
-rw-r--r--xbmc/utils/Splash.cpp11
-rw-r--r--xbmc/utils/Splash.h3
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();