Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Separate db update from CDatabase::Open() #1128

Merged
merged 8 commits into from

2 participants

jmarshallnz Sascha Montellese
jmarshallnz
Owner

We've been talking about this for a while. This is an attempt.

There's a couple of gotchas. The first is that the addon manager is configured very early, thus the Addon Database has to be updated early (before the addon manager). The rest are happy with things done in Initialize(). The second is we need to re-initialize everything on profile switch.

There's the potential that this could be threaded if we want - CDatabaseManager::CanOpen() would have to be blocking if so - personally I find it only takes about 5 seconds or so to update from quite old databases on load, so possibly not worth it.

jmarshallnz
Owner

Needs testing on mysql + build tests on linux + OSX.

xbmc/DatabaseManager.cpp
((60 lines not shown))
+ CLog::Log(LOGDEBUG, "%s, updating databases... DONE", __FUNCTION__);
+}
+
+void CDatabaseManager::Deinitialize()
+{
+ CSingleLock lock(m_section);
+ m_dbStatus.clear();
+}
+
+bool CDatabaseManager::CanOpen(const std::string &name)
+{
+ CSingleLock lock(m_section);
+ map<string, DB_STATUS>::const_iterator i = m_dbStatus.find(name);
+ if (i != m_dbStatus.end())
+ {
+ if (i->second == DB_READY)
Sascha Montellese Owner

A simple return i->second == DB_READY; should be enough?

jmarshallnz Owner

Yup - originally had a case for DB_UPDATING as well (busy wait) but decided it was best to leave it out - will clean as suggested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Sascha Montellese
Owner

Looks good and as I merged those db_optimization commits you will be able to rebase them away (got me confused for a minute when I looked at the whole diff of the PR).

jmarshallnz jmarshallnz was assigned
Jonathan Mar... added some commits
Jonathan Marshall Revert "CDatabase: remember the databases we already updated and don'…
…t check them on every connect/open"

This reverts commit d78c7195cc81babdd048737b412b99a0848f4c7c.
a80621f
Jonathan Marshall pass the db name to CDatabase::Connect rather than altering DatabaseS…
…ettings::name
614714b
Jonathan Marshall get rid of unneeded UpdateVersion when creating a new database, and d…
…rop the fallback to sqlite - it's unlikely that the sqlite db is in any way in sync with the mysql one
3e93cc5
Jonathan Marshall factor out CDatabase::GetDBVersion f656311
Jonathan Marshall factor out the Update() function in CDatabase::Open fd165ea
Jonathan Marshall factor out the initializing of database settings from CDatabase::Open adc1313
Jonathan Marshall adds new CDatabaseManager, and allow it to access CDatabase::Update d…
…irectly.
7e05bb2
Jonathan Marshall Initialize the database manager on start and on change of profile, so…
… that database updates are attempted only once rather than on every Open().
0d0eb55
jmarshallnz jmarshallnz merged commit d9ca8ee into from
Tobias Hieta tru referenced this pull request from a commit in RasPlex/plex-home-theatre
Tobias Hieta tru Allow local access of files even when we don't own the server.
If we can access the file locally we can access the file locally. No
need to just check for local files when the server is our own.

Fixes #1128
bd86672
Tobias Hieta tru referenced this pull request from a commit in RasPlex/plex-home-theatre
Tobias Hieta tru Allow local access of files even when we don't own the server.
If we can access the file locally we can access the file locally. No
need to just check for local files when the server is our own.

Fixes #1128
2a9d76e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 9, 2012
  1. Revert "CDatabase: remember the databases we already updated and don'…

    Jonathan Marshall authored
    …t check them on every connect/open"
    
    This reverts commit d78c7195cc81babdd048737b412b99a0848f4c7c.
  2. pass the db name to CDatabase::Connect rather than altering DatabaseS…

    Jonathan Marshall authored
    …ettings::name
  3. get rid of unneeded UpdateVersion when creating a new database, and d…

    Jonathan Marshall authored
    …rop the fallback to sqlite - it's unlikely that the sqlite db is in any way in sync with the mysql one
  4. factor out CDatabase::GetDBVersion

    Jonathan Marshall authored
  5. factor out the Update() function in CDatabase::Open

    Jonathan Marshall authored
  6. adds new CDatabaseManager, and allow it to access CDatabase::Update d…

    Jonathan Marshall authored
    …irectly.
  7. Initialize the database manager on start and on change of profile, so…

    Jonathan Marshall authored
    … that database updates are attempted only once rather than on every Open().
This page is out of date. Refresh to see the latest.
6 XBMC-ATV2.xcodeproj/project.pbxproj
View
@@ -29,6 +29,7 @@
7C0A7FCC13A9E76E00AFC2BD /* GUIWindowDebugInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0A7FCA13A9E76E00AFC2BD /* GUIWindowDebugInfo.cpp */; };
7C0B990A154B80200065A238 /* AEDeviceInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0B9908154B80200065A238 /* AEDeviceInfo.cpp */; };
7C1A89BB152671FB00C63311 /* TextureCacheJob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1A89B9152671FB00C63311 /* TextureCacheJob.cpp */; };
+ 7C1D698B15A8142F00658B65 /* DatabaseManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1D698915A8142F00658B65 /* DatabaseManager.cpp */; };
7C1F6F8C13ED17CC001726AB /* LibraryDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1F6F8A13ED17CC001726AB /* LibraryDirectory.cpp */; };
7C6EB586155E3EC80080368A /* ImageFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C6EB584155E3EC80080368A /* ImageFile.cpp */; };
7C6EB708155F3B160080368A /* HTTPImageHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C6EB706155F3B160080368A /* HTTPImageHandler.cpp */; };
@@ -1028,6 +1029,8 @@
7C1A494015A968D6004AF4A4 /* SaveFileStateJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaveFileStateJob.h; sourceTree = "<group>"; };
7C1A89B9152671FB00C63311 /* TextureCacheJob.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureCacheJob.cpp; sourceTree = "<group>"; };
7C1A89BA152671FB00C63311 /* TextureCacheJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextureCacheJob.h; sourceTree = "<group>"; };
+ 7C1D698915A8142F00658B65 /* DatabaseManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseManager.cpp; sourceTree = "<group>"; };
+ 7C1D698A15A8142F00658B65 /* DatabaseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatabaseManager.h; sourceTree = "<group>"; };
7C1F6F8A13ED17CC001726AB /* LibraryDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LibraryDirectory.cpp; sourceTree = "<group>"; };
7C1F6F8B13ED17CC001726AB /* LibraryDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LibraryDirectory.h; sourceTree = "<group>"; };
7C6EB584155E3EC80080368A /* ImageFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageFile.cpp; sourceTree = "<group>"; };
@@ -3573,6 +3576,8 @@
F56C77CB131EC154000AD0F6 /* config.h */,
F56C77D8131EC154000AD0F6 /* CueDocument.cpp */,
F56C77D9131EC154000AD0F6 /* CueDocument.h */,
+ 7C1D698915A8142F00658B65 /* DatabaseManager.cpp */,
+ 7C1D698A15A8142F00658B65 /* DatabaseManager.h */,
F56C77DC131EC154000AD0F6 /* DynamicDll.cpp */,
F56C77DD131EC154000AD0F6 /* DynamicDll.h */,
F56C77DE131EC154000AD0F6 /* Favourites.cpp */,
@@ -7227,6 +7232,7 @@
36A9445D15821FAC00727135 /* SortUtils.cpp in Sources */,
DF08E84515829BA600058C77 /* Exception.cpp in Sources */,
36A9465315AA269B00727135 /* DirectoryNodeTags.cpp in Sources */,
+ 7C1D698B15A8142F00658B65 /* DatabaseManager.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
6 XBMC-IOS.xcodeproj/project.pbxproj
View
@@ -30,6 +30,7 @@
7C0A7FB313A9E72E00AFC2BD /* DirtyRegionTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0A7FB013A9E72E00AFC2BD /* DirtyRegionTracker.cpp */; };
7C0B98F9154B7FF30065A238 /* AEDeviceInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0B98F7154B7FF30065A238 /* AEDeviceInfo.cpp */; };
7C1A89CE1526722200C63311 /* TextureCacheJob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1A89CC1526722200C63311 /* TextureCacheJob.cpp */; };
+ 7C1D697815A8141000658B65 /* DatabaseManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1D697615A8141000658B65 /* DatabaseManager.cpp */; };
7C1F6F7A13ED178F001726AB /* LibraryDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1F6F7813ED178F001726AB /* LibraryDirectory.cpp */; };
7C6EB570155E3E680080368A /* ImageFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C6EB56E155E3E680080368A /* ImageFile.cpp */; };
7C6EB71A155F3B330080368A /* HTTPImageHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C6EB718155F3B330080368A /* HTTPImageHandler.cpp */; };
@@ -1028,6 +1029,8 @@
7C1A495415A96908004AF4A4 /* SaveFileStateJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaveFileStateJob.h; sourceTree = "<group>"; };
7C1A89CC1526722200C63311 /* TextureCacheJob.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureCacheJob.cpp; sourceTree = "<group>"; };
7C1A89CD1526722200C63311 /* TextureCacheJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextureCacheJob.h; sourceTree = "<group>"; };
+ 7C1D697615A8141000658B65 /* DatabaseManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseManager.cpp; sourceTree = "<group>"; };
+ 7C1D697715A8141000658B65 /* DatabaseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatabaseManager.h; sourceTree = "<group>"; };
7C1F6F7813ED178F001726AB /* LibraryDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LibraryDirectory.cpp; sourceTree = "<group>"; };
7C1F6F7913ED178F001726AB /* LibraryDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LibraryDirectory.h; sourceTree = "<group>"; };
7C6EB56E155E3E680080368A /* ImageFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageFile.cpp; sourceTree = "<group>"; };
@@ -3929,6 +3932,8 @@
F56C87B8131F42ED000AD0F6 /* config.h */,
F56C87C5131F42ED000AD0F6 /* CueDocument.cpp */,
F56C87C6131F42ED000AD0F6 /* CueDocument.h */,
+ 7C1D697615A8141000658B65 /* DatabaseManager.cpp */,
+ 7C1D697715A8141000658B65 /* DatabaseManager.h */,
F56C87C9131F42ED000AD0F6 /* DynamicDll.cpp */,
F56C87CA131F42ED000AD0F6 /* DynamicDll.h */,
F56C87CB131F42ED000AD0F6 /* Favourites.cpp */,
@@ -7238,6 +7243,7 @@
36A9445215821F5300727135 /* SortUtils.cpp in Sources */,
DFC3867E158296EC008AE277 /* Exception.cpp in Sources */,
36A9465B15AA26BC00727135 /* DirectoryNodeTags.cpp in Sources */,
+ 7C1D697815A8141000658B65 /* DatabaseManager.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
6 XBMC.xcodeproj/project.pbxproj
View
@@ -259,6 +259,7 @@
7C0A7EC013A5DBCE00AFC2BD /* AppParamParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0A7EBE13A5DBCE00AFC2BD /* AppParamParser.cpp */; };
7C0B98A4154B79C30065A238 /* AEDeviceInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0B98A1154B79C30065A238 /* AEDeviceInfo.cpp */; };
7C1A85661520522500C63311 /* TextureCacheJob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1A85631520522500C63311 /* TextureCacheJob.cpp */; };
+ 7C1D682915A7D2FD00658B65 /* DatabaseManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1D682715A7D2FD00658B65 /* DatabaseManager.cpp */; };
7C1F6EBB13ECCFA7001726AB /* LibraryDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1F6EB913ECCFA7001726AB /* LibraryDirectory.cpp */; };
7C2D6AE40F35453E00DD2E85 /* SpecialProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C2D6AE20F35453E00DD2E85 /* SpecialProtocol.cpp */; };
7C45DBE910F325C400D4BBF3 /* DAVDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C45DBE710F325C400D4BBF3 /* DAVDirectory.cpp */; };
@@ -1534,6 +1535,8 @@
7C1A495B15A96918004AF4A4 /* SaveFileStateJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaveFileStateJob.h; sourceTree = "<group>"; };
7C1A85631520522500C63311 /* TextureCacheJob.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureCacheJob.cpp; sourceTree = "<group>"; };
7C1A85641520522500C63311 /* TextureCacheJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextureCacheJob.h; sourceTree = "<group>"; };
+ 7C1D682715A7D2FD00658B65 /* DatabaseManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseManager.cpp; sourceTree = "<group>"; };
+ 7C1D682815A7D2FD00658B65 /* DatabaseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatabaseManager.h; sourceTree = "<group>"; };
7C1F6EB913ECCFA7001726AB /* LibraryDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LibraryDirectory.cpp; sourceTree = "<group>"; };
7C1F6EBA13ECCFA7001726AB /* LibraryDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LibraryDirectory.h; sourceTree = "<group>"; };
7C2D6AE20F35453E00DD2E85 /* SpecialProtocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpecialProtocol.cpp; sourceTree = "<group>"; };
@@ -4336,6 +4339,8 @@
F5B413131065900C0035D105 /* config.h */,
E38E167E0D25F9FA00618676 /* CueDocument.cpp */,
E38E167F0D25F9FA00618676 /* CueDocument.h */,
+ 7C1D682715A7D2FD00658B65 /* DatabaseManager.cpp */,
+ 7C1D682815A7D2FD00658B65 /* DatabaseManager.h */,
E38E168C0D25F9FA00618676 /* DynamicDll.cpp */,
E38E168D0D25F9FA00618676 /* DynamicDll.h */,
E38E16900D25F9FA00618676 /* Favourites.cpp */,
@@ -7319,6 +7324,7 @@
36A9444115821E7C00727135 /* SortUtils.cpp in Sources */,
1DE0443515828F4B005DDB4D /* Exception.cpp in Sources */,
36A9464C15AA25FD00727135 /* DirectoryNodeTags.cpp in Sources */,
+ 7C1D682915A7D2FD00658B65 /* DatabaseManager.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
4 project/VS2010Express/XBMC.vcxproj
View
@@ -893,6 +893,7 @@
<ClCompile Include="..\..\xbmc\TextureCache.cpp" />
<ClCompile Include="..\..\xbmc\TextureCacheJob.cpp" />
<ClCompile Include="..\..\xbmc\TextureDatabase.cpp" />
+ <ClCompile Include="..\..\xbmc\DatabaseManager.cpp" />
<ClInclude Include="..\..\xbmc\cores\AudioEngine\AEAudioFormat.h" />
<ClInclude Include="..\..\xbmc\cores\AudioEngine\AEFactory.h" />
<ClInclude Include="..\..\xbmc\cores\AudioEngine\AESinkFactory.h" />
@@ -1846,6 +1847,7 @@
<ClInclude Include="..\..\xbmc\TextureCache.h" />
<ClInclude Include="..\..\xbmc\TextureCacheJob.h" />
<ClInclude Include="..\..\xbmc\TextureDatabase.h" />
+ <ClInclude Include="..\..\xbmc\DatabaseManager.h" />
<ClInclude Include="..\..\xbmc\ThumbLoader.h" />
<ClInclude Include="..\..\xbmc\ThumbnailCache.h" />
<ClInclude Include="..\..\xbmc\URL.h" />
@@ -2283,4 +2285,4 @@
</VisualStudio>
</ProjectExtensions>
<Import Project="$(SolutionDir)\$(ProjectFileName).targets.user" Condition="Exists('$(SolutionDir)\$(ProjectFileName).targets.user')" />
-</Project>
+</Project>
4 project/VS2010Express/XBMC.vcxproj.filters
View
@@ -2533,6 +2533,7 @@
<ClCompile Include="..\..\xbmc\TextureCache.cpp" />
<ClCompile Include="..\..\xbmc\TextureCacheJob.cpp" />
<ClCompile Include="..\..\xbmc\TextureDatabase.cpp" />
+ <ClCompile Include="..\..\xbmc\DatabaseManager.cpp" />
<ClCompile Include="..\..\xbmc\ThumbnailCache.cpp" />
<ClCompile Include="..\..\xbmc\URL.cpp" />
<ClCompile Include="..\..\xbmc\Util.cpp" />
@@ -5158,6 +5159,7 @@
<ClInclude Include="..\..\xbmc\TextureCache.h" />
<ClInclude Include="..\..\xbmc\TextureCacheJob.h" />
<ClInclude Include="..\..\xbmc\TextureDatabase.h" />
+ <ClInclude Include="..\..\xbmc\DatabaseManager.h" />
<ClInclude Include="..\..\xbmc\ThumbnailCache.h" />
<ClInclude Include="..\..\xbmc\URL.h" />
<ClInclude Include="..\..\xbmc\Util.h" />
@@ -5233,4 +5235,4 @@
<Filter>win32</Filter>
</CustomBuild>
</ItemGroup>
-</Project>
+</Project>
7 xbmc/Application.cpp
View
@@ -306,6 +306,7 @@
#include "utils/SaveFileStateJob.h"
#include "utils/AlarmClock.h"
#include "utils/StringUtils.h"
+#include "DatabaseManager.h"
#ifdef _LINUX
#include "XHandle.h"
@@ -709,6 +710,9 @@ bool CApplication::Create()
CAEFactory::SetMute (g_settings.m_bMute);
CAEFactory::SetSoundMode(g_guiSettings.GetInt("audiooutput.guisoundmode"));
+ // initialize the addon database (must be before the addon manager is init'd)
+ CDatabaseManager::Get().Initialize(true);
+
// start-up Addons Framework
// currently bails out if either cpluff Dll is unavailable or system dir can not be scanned
if (!CAddonMgr::Get().Init())
@@ -1153,6 +1157,9 @@ bool CApplication::Initialize()
g_curlInterface.Load();
g_curlInterface.Unload();
+ // initialize (and update as needed) our databases
+ CDatabaseManager::Get().Initialize();
+
#ifdef HAS_WEB_SERVER
CWebServer::RegisterRequestHandler(&m_httpImageHandler);
CWebServer::RegisterRequestHandler(&m_httpVfsHandler);
92 xbmc/DatabaseManager.cpp
View
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "DatabaseManager.h"
+#include "utils/log.h"
+#include "addons/AddonDatabase.h"
+#include "ViewDatabase.h"
+#include "TextureDatabase.h"
+#include "programs/ProgramDatabase.h"
+#include "music/MusicDatabase.h"
+#include "video/VideoDatabase.h"
+#include "settings/AdvancedSettings.h"
+
+using namespace std;
+
+CDatabaseManager &CDatabaseManager::Get()
+{
+ static CDatabaseManager s_manager;
+ return s_manager;
+}
+
+CDatabaseManager::CDatabaseManager()
+{
+}
+
+CDatabaseManager::~CDatabaseManager()
+{
+}
+
+void CDatabaseManager::Initialize(bool addonsOnly)
+{
+ Deinitialize();
+ { CAddonDatabase db; UpdateDatabase(db); }
+ if (addonsOnly)
+ return;
+ CLog::Log(LOGDEBUG, "%s, updating databases...", __FUNCTION__);
+ { CViewDatabase db; UpdateDatabase(db); }
+ { CTextureDatabase db; UpdateDatabase(db); }
+ { CProgramDatabase db; UpdateDatabase(db); }
+ { CMusicDatabase db; UpdateDatabase(db, &g_advancedSettings.m_databaseMusic); }
+ { CVideoDatabase db; UpdateDatabase(db, &g_advancedSettings.m_databaseVideo); }
+ CLog::Log(LOGDEBUG, "%s, updating databases... DONE", __FUNCTION__);
+}
+
+void CDatabaseManager::Deinitialize()
+{
+ CSingleLock lock(m_section);
+ m_dbStatus.clear();
+}
+
+bool CDatabaseManager::CanOpen(const std::string &name)
+{
+ CSingleLock lock(m_section);
+ map<string, DB_STATUS>::const_iterator i = m_dbStatus.find(name);
+ if (i != m_dbStatus.end())
+ return i->second == DB_READY;
+ return false; // db isn't even attempted to update yet
+}
+
+void CDatabaseManager::UpdateDatabase(CDatabase &db, DatabaseSettings *settings)
+{
+ std::string name = db.GetBaseDBName();
+ UpdateStatus(name, DB_UPDATING);
+ if (db.Update(settings ? *settings : DatabaseSettings()))
+ UpdateStatus(name, DB_READY);
+ else
+ UpdateStatus(name, DB_FAILED);
+}
+
+void CDatabaseManager::UpdateStatus(const std::string &name, DB_STATUS status)
+{
+ CSingleLock lock(m_section);
+ m_dbStatus[name] = status;
+}
82 xbmc/DatabaseManager.h
View
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include <map>
+#include <string>
+#include "threads/CriticalSection.h"
+#include "threads/Event.h"
+
+class CDatabase;
+class DatabaseSettings;
+
+/*!
+ \ingroup database
+ \brief Database manager class for handling database updating
+
+ Ensures that databases used in XBMC are up to date, and if a database can't be
+ opened, ensures we don't continuously try it.
+
+ */
+class CDatabaseManager
+{
+public:
+ /*!
+ \brief The only way through which the global instance of the CDatabaseManager should be accessed.
+ \return the global instance.
+ */
+ static CDatabaseManager &Get();
+
+ /*! \brief Initalize the database manager
+ Checks that all databases are up to date, otherwise updates them.
+ */
+ void Initialize(bool addonsOnly = false);
+
+ /*! \brief Deinitialize the database manager
+ */
+ void Deinitialize();
+
+ /*! \brief Check whether we can open a database.
+
+ Checks whether the database has been updated correctly, if so returns true.
+ If the database update failed, returns false immediately.
+ If the database update is in progress, returns false.
+
+ \param name the name of the database to check.
+ \return true if the database can be opened, false otherwise.
+ */
+ bool CanOpen(const std::string &name);
+
+private:
+ // private construction, and no assignements; use the provided singleton methods
+ CDatabaseManager();
+ CDatabaseManager(const CDatabaseManager&);
+ CDatabaseManager const& operator=(CDatabaseManager const&);
+ virtual ~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);
+
+ CCriticalSection m_section; ///< Critical section protecting m_dbStatus.
+ std::map<std::string, DB_STATUS> m_dbStatus; ///< Our database status map.
+};
1  xbmc/Makefile.in
View
@@ -4,6 +4,7 @@ SRCS=Application.cpp \
AutoSwitch.cpp \
BackgroundInfoLoader.cpp \
CueDocument.cpp \
+ DatabaseManager.cpp \
DynamicDll.cpp \
Favourites.cpp \
FileItem.cpp \
92 xbmc/dbwrappers/Database.cpp
View
@@ -31,7 +31,7 @@
#include "utils/URIUtils.h"
#include "mysqldataset.h"
#include "sqlitedataset.h"
-#include "threads/SingleLock.h"
+#include "DatabaseManager.h"
using namespace AUTOPTR;
@@ -39,8 +39,6 @@ using namespace dbiplus;
#define MAX_COMPRESS_COUNT 20
-std::map<std::string, bool> CDatabase::m_updated;
-
CDatabase::CDatabase(void)
{
m_openCount = 0;
@@ -252,15 +250,26 @@ bool CDatabase::Open()
bool CDatabase::Open(const DatabaseSettings &settings)
{
- // take a copy - we're gonna be messing with it and we don't want to touch the original
- DatabaseSettings dbSettings = settings;
-
if (IsOpen())
{
m_openCount++;
return true;
}
+ // check our database manager to see if this database can be opened
+ if (!CDatabaseManager::Get().CanOpen(GetBaseDBName()))
+ return false;
+
+ DatabaseSettings dbSettings = settings;
+ InitSettings(dbSettings);
+
+ CStdString dbName = dbSettings.name;
+ dbName.AppendFormat("%d", GetMinVersion());
+ return Connect(dbName, dbSettings, false);
+}
+
+void CDatabase::InitSettings(DatabaseSettings &dbSettings)
+{
m_sqlite = true;
if ( dbSettings.type.Equals("mysql") )
@@ -276,23 +285,29 @@ bool CDatabase::Open(const DatabaseSettings &settings)
{
dbSettings.type = "sqlite3";
dbSettings.host = CSpecialProtocol::TranslatePath(g_settings.GetDatabaseFolder());
- dbSettings.name = GetBaseDBName();
}
// use separate, versioned database
+ if (dbSettings.name.IsEmpty())
+ dbSettings.name = GetBaseDBName();
+}
+
+bool CDatabase::Update(const DatabaseSettings &settings)
+{
+ DatabaseSettings dbSettings = settings;
+ InitSettings(dbSettings);
+
int version = GetMinVersion();
- CStdString baseDBName = (dbSettings.name.IsEmpty() ? GetBaseDBName() : dbSettings.name.c_str());
- CStdString latestDb;
- latestDb.Format("%s%d", baseDBName, version);
+ CStdString latestDb = dbSettings.name;
+ latestDb.AppendFormat("%d", version);
while (version >= 0)
{
+ CStdString dbName = dbSettings.name;
if (version)
- dbSettings.name.Format("%s%d", baseDBName, version);
- else
- dbSettings.name.Format("%s", baseDBName);
+ dbName.AppendFormat("%d", version);
- if (Connect(dbSettings, false))
+ if (Connect(dbName, dbSettings, false))
{
// Database exists, take a copy for our current version (if needed) and reopen that one
if (version < GetMinVersion())
@@ -307,7 +322,7 @@ bool CDatabase::Open(const DatabaseSettings &settings)
}
catch(...)
{
- CLog::Log(LOGERROR, "Unable to copy old database %s to new version %s", dbSettings.name.c_str(), latestDb.c_str());
+ CLog::Log(LOGERROR, "Unable to copy old database %s to new version %s", dbName.c_str(), latestDb.c_str());
copy_fail = true;
}
@@ -316,16 +331,15 @@ bool CDatabase::Open(const DatabaseSettings &settings)
if ( copy_fail )
return false;
- dbSettings.name = latestDb;
- if (!Connect(dbSettings, false))
+ if (!Connect(latestDb, dbSettings, false))
{
- CLog::Log(LOGERROR, "Unable to open freshly copied database %s", dbSettings.name.c_str());
+ 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(dbSettings.name))
+ if (UpdateVersion(latestDb))
return true;
// update failed - loop around and see if we have another one available
@@ -335,31 +349,17 @@ bool CDatabase::Open(const DatabaseSettings &settings)
// drop back to the previous version and try that
version--;
}
-
-
- // unable to open any version fall through to create a new one
- dbSettings.name = latestDb;
-
- if (Connect(dbSettings, true) && UpdateVersion(dbSettings.name))
- {
+ // try creating a new one
+ if (Connect(latestDb, dbSettings, true))
return true;
- }
- // safely fall back to sqlite as appropriate
- else if ( ! m_sqlite )
- {
- CLog::Log(LOGDEBUG, "Falling back to sqlite.");
- dbSettings = settings;
- dbSettings.type = "sqlite3";
- return Open(dbSettings);
- }
// failed to update or open the database
Close();
- CLog::Log(LOGERROR, "Unable to open database %s", dbSettings.name.c_str());
+ CLog::Log(LOGERROR, "Unable to create new database");
return false;
}
-bool CDatabase::Connect(const DatabaseSettings &dbSettings, bool create)
+bool CDatabase::Connect(const CStdString &dbName, const DatabaseSettings &dbSettings, bool create)
{
// create the appropriate database structure
if (dbSettings.type.Equals("sqlite3"))
@@ -389,7 +389,7 @@ bool CDatabase::Connect(const DatabaseSettings &dbSettings, bool create)
m_pDB->setPasswd(dbSettings.pass.c_str());
// database name is always required
- m_pDB->setDatabase(dbSettings.name.c_str());
+ m_pDB->setDatabase(dbName.c_str());
// create the datasets
m_pDS.reset(m_pDB->CreateDataset());
@@ -438,17 +438,17 @@ bool CDatabase::Connect(const DatabaseSettings &dbSettings, bool create)
return true;
}
-bool CDatabase::UpdateVersion(const CStdString &dbName)
+int CDatabase::GetDBVersion()
{
- CSingleLock lock(m_critSect);
- if (m_updated[dbName])
- return true;
-
- int version = 0;
m_pDS->query("SELECT idVersion FROM version\n");
if (m_pDS->num_rows() > 0)
- version = m_pDS->fv("idVersion").get_asInt();
+ return m_pDS->fv("idVersion").get_asInt();
+ return 0;
+}
+bool CDatabase::UpdateVersion(const CStdString &dbName)
+{
+ int version = GetDBVersion();
if (version < GetMinVersion())
{
CLog::Log(LOGNOTICE, "Attempting to update the database %s from version %i to %i", dbName.c_str(), version, GetMinVersion());
@@ -479,8 +479,6 @@ bool CDatabase::UpdateVersion(const CStdString &dbName)
CLog::Log(LOGERROR, "Can't open the database %s as it is a NEWER version than what we were expecting?", dbName.c_str());
return false;
}
-
- m_updated[dbName] = true;
return true;
}
16 xbmc/dbwrappers/Database.h
View
@@ -21,10 +21,6 @@
*
*/
-#include <map>
-#include <memory>
-
-#include "threads/CriticalSection.h"
#include "utils/StdString.h"
namespace dbiplus {
@@ -32,6 +28,8 @@ namespace dbiplus {
class Dataset;
}
+#include <memory>
+
class DatabaseSettings; // forward
class CDatabase
@@ -116,6 +114,9 @@ class CDatabase
bool CommitInsertQueries();
protected:
+ friend class CDatabaseManager;
+ bool Update(const DatabaseSettings &db);
+
void Split(const CStdString& strFileNameAndPath, CStdString& strPath, CStdString& strFileName);
uint32_t ComputeCRC(const CStdString &text);
@@ -127,6 +128,7 @@ class CDatabase
virtual int GetMinVersion() const=0;
virtual const char *GetBaseDBName() const=0;
+ int GetDBVersion();
bool UpdateVersion(const CStdString &dbName);
bool m_sqlite; ///< \brief whether we use sqlite (defaults to true)
@@ -136,12 +138,10 @@ class CDatabase
std::auto_ptr<dbiplus::Dataset> m_pDS2;
private:
- bool Connect(const DatabaseSettings &db, bool create);
+ void InitSettings(DatabaseSettings &dbSettings);
+ bool Connect(const CStdString &dbName, const DatabaseSettings &db, bool create);
bool UpdateVersionNumber();
bool m_bMultiWrite; /*!< True if there are any queries in the queue, false otherwise */
unsigned int m_openCount;
-
- CCriticalSection m_critSect;
- static std::map<std::string, bool> m_updated;
};
3  xbmc/settings/Settings.cpp
View
@@ -56,6 +56,7 @@
#include "input/MouseStat.h"
#include "filesystem/File.h"
#include "filesystem/DirectoryCache.h"
+#include "DatabaseManager.h"
using namespace std;
using namespace XFILE;
@@ -950,6 +951,8 @@ bool CSettings::LoadProfile(unsigned int index)
CButtonTranslator::GetInstance().Load(true);
g_localizeStrings.Load("special://xbmc/language/", strLanguage);
+ CDatabaseManager::Get().Initialize();
+
g_Mouse.SetEnabled(g_guiSettings.GetBool("input.enablemouse"));
g_infoManager.ResetCache();
Something went wrong with that request. Please try again.