diff options
author | Kai Sommerfeld <kai.sommerfeld@gmx.com> | 2017-09-30 13:54:31 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-30 13:54:31 +0200 |
commit | 1bca5092c50a5da20599a2edb7831a41e1066827 (patch) | |
tree | 3db91e99ebcca6f638d04e22269b673d7cadaf04 | |
parent | ec46f30fd04140b00a38ccc79f6e97422b5bf51f (diff) | |
parent | 82abc43122ead0d8cba4d5444026335515a3fabc (diff) |
Merge pull request #12844 from ksooo/pvr-database-concurrency
[PVR] Make PVR database threadsafe.
-rw-r--r-- | xbmc/dbwrappers/Database.h | 2 | ||||
-rw-r--r-- | xbmc/pvr/PVRDatabase.cpp | 148 | ||||
-rw-r--r-- | xbmc/pvr/PVRDatabase.h | 22 | ||||
-rw-r--r-- | xbmc/pvr/PVRManager.cpp | 2 | ||||
-rw-r--r-- | xbmc/pvr/channels/PVRChannel.cpp | 3 | ||||
-rw-r--r-- | xbmc/pvr/channels/PVRChannelGroup.cpp | 28 | ||||
-rw-r--r-- | xbmc/pvr/channels/PVRChannelGroup.h | 1 | ||||
-rw-r--r-- | xbmc/pvr/channels/PVRChannelGroupInternal.cpp | 10 | ||||
-rw-r--r-- | xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp | 2 |
9 files changed, 129 insertions, 89 deletions
diff --git a/xbmc/dbwrappers/Database.h b/xbmc/dbwrappers/Database.h index 435f5d8686..9aabf5f8cb 100644 --- a/xbmc/dbwrappers/Database.h +++ b/xbmc/dbwrappers/Database.h @@ -76,7 +76,7 @@ public: CDatabase(void); virtual ~CDatabase(void); bool IsOpen(); - void Close(); + virtual void Close(); bool Compress(bool bForce=true); void Interrupt(); diff --git a/xbmc/pvr/PVRDatabase.cpp b/xbmc/pvr/PVRDatabase.cpp index 5958cdc0b8..df8db76c32 100644 --- a/xbmc/pvr/PVRDatabase.cpp +++ b/xbmc/pvr/PVRDatabase.cpp @@ -24,28 +24,32 @@ #include "ServiceBroker.h" #include "dbwrappers/dataset.h" -#include "addons/PVRClient.h" #include "settings/AdvancedSettings.h" #include "settings/Settings.h" #include "utils/StringUtils.h" #include "utils/log.h" -#include "pvr/channels/PVRChannelGroupInternal.h" -#include "pvr/channels/PVRChannelGroupsContainer.h" +#include "pvr/channels/PVRChannelGroups.h" using namespace dbiplus; using namespace PVR; -using namespace ADDON; - -#define PVRDB_DEBUGGING 0 bool CPVRDatabase::Open() { + CSingleLock lock(m_critSection); return CDatabase::Open(g_advancedSettings.m_databaseTV); } +void CPVRDatabase::Close() +{ + CSingleLock lock(m_critSection); + CDatabase::Close(); +} + void CPVRDatabase::CreateTables() { + CSingleLock lock(m_critSection); + CLog::Log(LOGINFO, "PVR - %s - creating tables", __FUNCTION__); CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channels'", __FUNCTION__); @@ -95,6 +99,8 @@ void CPVRDatabase::CreateTables() void CPVRDatabase::CreateAnalytics() { + CSingleLock lock(m_critSection); + CLog::Log(LOGINFO, "%s - creating indices", __FUNCTION__); m_pDS->exec("CREATE UNIQUE INDEX idx_channels_iClientId_iUniqueId on channels(iClientId, iUniqueId);"); m_pDS->exec("CREATE INDEX idx_channelgroups_bIsRadio on channelgroups(bIsRadio);"); @@ -103,6 +109,8 @@ void CPVRDatabase::CreateAnalytics() void CPVRDatabase::UpdateTables(int iVersion) { + CSingleLock lock(m_critSection); + if (iVersion < 13) m_pDS->exec("ALTER TABLE channels ADD idEpg integer;"); @@ -147,6 +155,8 @@ void CPVRDatabase::UpdateTables(int iVersion) bool CPVRDatabase::DeleteChannels(void) { CLog::Log(LOGDEBUG, "PVR - %s - deleting all channels from the database", __FUNCTION__); + + CSingleLock lock(m_critSection); return DeleteValues("channels"); } @@ -161,12 +171,14 @@ bool CPVRDatabase::Delete(const CPVRChannel &channel) Filter filter; filter.AppendWhere(PrepareSQL("idChannel = %u", channel.ChannelID())); + CSingleLock lock(m_critSection); return DeleteValues("channels", filter); } -int CPVRDatabase::Get(CPVRChannelGroupInternal &results) +int CPVRDatabase::Get(CPVRChannelGroup &results, bool bCompressDB) { int iReturn(0); + bool bIgnoreEpgDB = CServiceBroker::GetSettings().GetBool(CSettings::SETTING_EPG_IGNOREDBFORCLIENT); std::string strQuery = PrepareSQL("SELECT channels.idChannel, channels.iUniqueId, channels.bIsRadio, channels.bIsHidden, channels.bIsUserSetIcon, channels.bIsUserSetName, " "channels.sIconPath, channels.sChannelName, channels.bIsVirtual, channels.bEPGEnabled, channels.sEPGScraper, channels.iLastWatched, channels.iClientId, channels.bIsLocked, " @@ -174,11 +186,12 @@ int CPVRDatabase::Get(CPVRChannelGroupInternal &results) "FROM map_channelgroups_channels " "LEFT JOIN channels ON channels.idChannel = map_channelgroups_channels.idChannel " "WHERE map_channelgroups_channels.idGroup = %u", results.GroupID()); + + CSingleLock lock(m_critSection); if (ResultQuery(strQuery)) { try { - bool bIgnoreEpgDB = CServiceBroker::GetSettings().GetBool(CSettings::SETTING_EPG_IGNOREDBFORCLIENT); while (!m_pDS->eof()) { CPVRChannelPtr channel = CPVRChannelPtr(new CPVRChannel()); @@ -194,19 +207,13 @@ int CPVRDatabase::Get(CPVRChannelGroupInternal &results) channel->m_strChannelName = m_pDS->fv("sChannelName").get_asString(); channel->m_bEPGEnabled = m_pDS->fv("bEPGEnabled").get_asBool(); channel->m_strEPGScraper = m_pDS->fv("sEPGScraper").get_asString(); - channel->m_iLastWatched = (time_t) m_pDS->fv("iLastWatched").get_asInt(); + channel->m_iLastWatched = static_cast<time_t>(m_pDS->fv("iLastWatched").get_asInt()); channel->m_iClientId = m_pDS->fv("iClientId").get_asInt(); - if (bIgnoreEpgDB) - channel->m_iEpgId = -1; - else - channel->m_iEpgId = m_pDS->fv("idEpg").get_asInt(); + channel->m_iEpgId = bIgnoreEpgDB ? -1 : m_pDS->fv("idEpg").get_asInt(); channel->UpdateEncryptionName(); -#if PVRDB_DEBUGGING - CLog::Log(LOGDEBUG, "PVR - %s - channel '%s' loaded from the database", __FUNCTION__, channel->m_strChannelName.c_str()); -#endif - PVRChannelGroupMember newMember = { channel, (unsigned int)m_pDS->fv("iChannelNumber").get_asInt() }; - results.m_sortedMembers.push_back(newMember); + PVRChannelGroupMember newMember = { channel, static_cast<unsigned int>(m_pDS->fv("iChannelNumber").get_asInt()) }; + results.m_sortedMembers.emplace_back(newMember); results.m_members.insert(std::make_pair(channel->StorageId(), newMember)); m_pDS->next(); @@ -225,6 +232,10 @@ int CPVRDatabase::Get(CPVRChannelGroupInternal &results) } m_pDS->close(); + + if (iReturn > 0 && bCompressDB) + Compress(true); + return iReturn; } @@ -235,6 +246,7 @@ bool CPVRDatabase::RemoveChannelsFromGroup(const CPVRChannelGroup &group) Filter filter; filter.AppendWhere(PrepareSQL("idGroup = %u", group.GroupID())); + CSingleLock lock(m_critSection); return DeleteValues("map_channelgroups_channels", filter); } @@ -248,14 +260,16 @@ bool CPVRDatabase::GetCurrentGroupMembers(const CPVRChannelGroup &group, std::ve return false; } - std::string strCurrentMembersQuery = PrepareSQL("SELECT idChannel FROM map_channelgroups_channels WHERE idGroup = %u", group.GroupID()); + CSingleLock lock(m_critSection); + + const std::string strCurrentMembersQuery = PrepareSQL("SELECT idChannel FROM map_channelgroups_channels WHERE idGroup = %u", group.GroupID()); if (ResultQuery(strCurrentMembersQuery)) { try { while (!m_pDS->eof()) { - members.push_back(m_pDS->fv("idChannel").get_asInt()); + members.emplace_back(m_pDS->fv("idChannel").get_asInt()); m_pDS->next(); } m_pDS->close(); @@ -285,6 +299,8 @@ bool CPVRDatabase::DeleteChannelsFromGroup(const CPVRChannelGroup &group, const return false; } + CSingleLock lock(m_critSection); + while (iDeletedChannels < channelsToDelete.size()) { std::string strChannelsToDelete; @@ -319,6 +335,8 @@ bool CPVRDatabase::RemoveStaleChannelsFromGroup(const CPVRChannelGroup &group) return false; } + CSingleLock lock(m_critSection); + if (!group.IsInternalGroup()) { /* First remove channels that don't exist in the main channels table */ @@ -327,7 +345,7 @@ bool CPVRDatabase::RemoveStaleChannelsFromGroup(const CPVRChannelGroup &group) // mysql doesn't support subqueries when deleting and sqlite doesn't support joins when deleting if (StringUtils::EqualsNoCase(g_advancedSettings.m_databaseTV.type, "mysql")) { - std::string strQuery = PrepareSQL("DELETE m FROM map_channelgroups_channels m LEFT JOIN channels c ON (c.idChannel = m.idChannel) WHERE c.idChannel IS NULL"); + const std::string strQuery = PrepareSQL("DELETE m FROM map_channelgroups_channels m LEFT JOIN channels c ON (c.idChannel = m.idChannel) WHERE c.idChannel IS NULL"); bDelete = ExecuteQuery(strQuery); } else @@ -348,7 +366,7 @@ bool CPVRDatabase::RemoveStaleChannelsFromGroup(const CPVRChannelGroup &group) for (unsigned int iChannelPtr = 0; iChannelPtr < currentMembers.size(); iChannelPtr++) { if (!group.IsGroupMember(currentMembers.at(iChannelPtr))) - channelsToDelete.push_back(currentMembers.at(iChannelPtr)); + channelsToDelete.emplace_back(currentMembers.at(iChannelPtr)); } bDelete = DeleteChannelsFromGroup(group, channelsToDelete) && bDelete; @@ -369,8 +387,8 @@ bool CPVRDatabase::DeleteChannelGroups(void) { CLog::Log(LOGDEBUG, "PVR - %s - deleting all channel groups from the database", __FUNCTION__); - return DeleteValues("channelgroups") && - DeleteValues("map_channelgroups_channels"); + CSingleLock lock(m_critSection); + return DeleteValues("channelgroups") && DeleteValues("map_channelgroups_channels"); } bool CPVRDatabase::Delete(const CPVRChannelGroup &group) @@ -386,15 +404,16 @@ bool CPVRDatabase::Delete(const CPVRChannelGroup &group) filter.AppendWhere(PrepareSQL("idGroup = %u", group.GroupID())); filter.AppendWhere(PrepareSQL("bIsRadio = %u", group.IsRadio())); - return RemoveChannelsFromGroup(group) && - DeleteValues("channelgroups", filter); + CSingleLock lock(m_critSection); + return RemoveChannelsFromGroup(group) && DeleteValues("channelgroups", filter); } bool CPVRDatabase::Get(CPVRChannelGroups &results) { bool bReturn = false; - std::string strQuery = PrepareSQL("SELECT * from channelgroups WHERE bIsRadio = %u", results.IsRadio()); + CSingleLock lock(m_critSection); + const std::string strQuery = PrepareSQL("SELECT * from channelgroups WHERE bIsRadio = %u", results.IsRadio()); if (ResultQuery(strQuery)) { try @@ -403,7 +422,7 @@ bool CPVRDatabase::Get(CPVRChannelGroups &results) { CPVRChannelGroup data(m_pDS->fv("bIsRadio").get_asBool(), m_pDS->fv("idGroup").get_asInt(), m_pDS->fv("sName").get_asString()); data.SetGroupType(m_pDS->fv("iGroupType").get_asInt()); - data.SetLastWatched((time_t) m_pDS->fv("iLastWatched").get_asInt()); + data.SetLastWatched(static_cast<time_t>(m_pDS->fv("iLastWatched").get_asInt())); data.SetHidden(m_pDS->fv("bIsHidden").get_asBool()); data.SetPosition(m_pDS->fv("iPosition").get_asInt()); results.Update(data); @@ -423,7 +442,7 @@ bool CPVRDatabase::Get(CPVRChannelGroups &results) return bReturn; } -int CPVRDatabase::Get(CPVRChannelGroup &group) +int CPVRDatabase::Get(CPVRChannelGroup &group, const std::map<int, CPVRChannelPtr> &allChannels) { int iReturn = -1; @@ -434,7 +453,9 @@ int CPVRDatabase::Get(CPVRChannelGroup &group) return -1; } - std::string strQuery = PrepareSQL("SELECT idChannel, iChannelNumber FROM map_channelgroups_channels WHERE idGroup = %u ORDER BY iChannelNumber", group.GroupID()); + CSingleLock lock(m_critSection); + + const std::string strQuery = PrepareSQL("SELECT idChannel, iChannelNumber FROM map_channelgroups_channels WHERE idGroup = %u ORDER BY iChannelNumber", group.GroupID()); if (ResultQuery(strQuery)) { iReturn = 0; @@ -445,16 +466,13 @@ int CPVRDatabase::Get(CPVRChannelGroup &group) { int iChannelId = m_pDS->fv("idChannel").get_asInt(); int iChannelNumber = m_pDS->fv("iChannelNumber").get_asInt(); - CPVRChannelPtr channel = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAll(group.IsRadio())->GetByChannelID(iChannelId); + const auto& channel = allChannels.find(iChannelId); - if (channel) + if (channel != allChannels.end()) { -#if PVRDB_DEBUGGING - CLog::Log(LOGDEBUG, "PVR - %s - channel '%s' loaded from the database", __FUNCTION__, channel->m_strChannelName.c_str()); -#endif - PVRChannelGroupMember newMember = { channel, (unsigned int)iChannelNumber }; - group.m_sortedMembers.push_back(newMember); - group.m_members.insert(std::make_pair(channel->StorageId(), newMember)); + PVRChannelGroupMember newMember = { channel->second, static_cast<unsigned int>(iChannelNumber) }; + group.m_sortedMembers.emplace_back(newMember); + group.m_members.insert(std::make_pair(channel->second->StorageId(), newMember)); ++iReturn; } else @@ -487,13 +505,15 @@ bool CPVRDatabase::PersistChannels(CPVRChannelGroup &group) { bool bReturn(true); - for (PVR_CHANNEL_GROUP_MEMBERS::iterator it = group.m_members.begin(); it != group.m_members.end(); ++it) + CPVRChannelPtr channel; + for (const auto& groupMember : group.m_members) { - if (it->second.channel->IsChanged() || it->second.channel->IsNew()) + channel = groupMember.second.channel; + if (channel->IsChanged() || channel->IsNew()) { - if (Persist(*it->second.channel)) + if (Persist(*channel, false)) { - it->second.channel->Persisted(); + groupMember.second.channel->Persisted(); bReturn = true; } } @@ -505,12 +525,13 @@ bool CPVRDatabase::PersistChannels(CPVRChannelGroup &group) { std::string strQuery; std::string strValue; - for (PVR_CHANNEL_GROUP_MEMBERS::iterator it = group.m_members.begin(); it != group.m_members.end(); ++it) + for (const auto& groupMember : group.m_members) { - strQuery = PrepareSQL("iUniqueId = %u AND iClientId = %u", it->second.channel->UniqueID(), it->second.channel->ClientID()); + channel = groupMember.second.channel; + strQuery = PrepareSQL("iUniqueId = %u AND iClientId = %u", channel->UniqueID(), channel->ClientID()); strValue = GetSingleValue("channels", "idChannel", strQuery); if (!strValue.empty() && StringUtils::IsInteger(strValue)) - it->second.channel->SetChannelID(atoi(strValue.c_str())); + channel->SetChannelID(atoi(strValue.c_str())); } } @@ -526,22 +547,21 @@ bool CPVRDatabase::PersistGroupMembers(const CPVRChannelGroup &group) if (group.HasChannels()) { - for (PVR_CHANNEL_GROUP_SORTED_MEMBERS::const_iterator it = group.m_sortedMembers.begin(); it != group.m_sortedMembers.end(); ++it) + for (const auto& groupMember : group.m_sortedMembers) { - std::string strWhereClause = PrepareSQL("idChannel = %u AND idGroup = %u AND iChannelNumber = %u AND iSubChannelNumber = %u", - (*it).channel->ChannelID(), group.GroupID(), (*it).iChannelNumber, (*it).iSubChannelNumber); + const std::string strWhereClause = PrepareSQL("idChannel = %u AND idGroup = %u AND iChannelNumber = %u AND iSubChannelNumber = %u", + groupMember.channel->ChannelID(), group.GroupID(), groupMember.iChannelNumber, groupMember.iSubChannelNumber); - std::string strValue = GetSingleValue("map_channelgroups_channels", "idChannel", strWhereClause); + const std::string strValue = GetSingleValue("map_channelgroups_channels", "idChannel", strWhereClause); if (strValue.empty()) { strQuery = PrepareSQL("REPLACE INTO map_channelgroups_channels (" "idGroup, idChannel, iChannelNumber, iSubChannelNumber) " "VALUES (%i, %i, %i, %i);", - group.GroupID(), (*it).channel->ChannelID(), (*it).iChannelNumber, (*it).iSubChannelNumber); + group.GroupID(), groupMember.channel->ChannelID(), groupMember.iChannelNumber, groupMember.iSubChannelNumber); QueueInsertQuery(strQuery); } } - lock.Leave(); bReturn = CommitInsertQueries(); bRemoveChannels = RemoveStaleChannelsFromGroup(group); @@ -554,7 +574,8 @@ bool CPVRDatabase::PersistGroupMembers(const CPVRChannelGroup &group) bool CPVRDatabase::ResetEPG(void) { - std::string strQuery = PrepareSQL("UPDATE channels SET idEpg = 0"); + CSingleLock lock(m_critSection); + const std::string strQuery = PrepareSQL("UPDATE channels SET idEpg = 0"); return ExecuteQuery(strQuery); } @@ -569,9 +590,8 @@ bool CPVRDatabase::Persist(CPVRChannelGroup &group) std::string strQuery; bReturn = true; + CSingleLock lock(m_critSection); { - CSingleLock lock(group.m_critSection); - /* insert a new entry when this is a new group, or replace the existing one otherwise */ if (group.GroupID() <= 0) strQuery = PrepareSQL("INSERT INTO channelgroups (bIsRadio, iGroupType, sName, iLastWatched, bIsHidden, iPosition) VALUES (%i, %i, '%s', %u, %i, %i)", @@ -584,7 +604,10 @@ bool CPVRDatabase::Persist(CPVRChannelGroup &group) /* set the group id if it was <= 0 */ if (bReturn && group.GroupID() <= 0) + { + CSingleLock lock(group.m_critSection); group.m_iGroupId = (int) m_pDS->lastinsertid(); + } } /* only persist the channel data for the internal groups */ @@ -598,7 +621,7 @@ bool CPVRDatabase::Persist(CPVRChannelGroup &group) return bReturn; } -bool CPVRDatabase::Persist(CPVRChannel &channel) +bool CPVRDatabase::Persist(CPVRChannel &channel, bool bCommit) { bool bReturn(false); @@ -610,6 +633,8 @@ bool CPVRDatabase::Persist(CPVRChannel &channel) } std::string strQuery; + CSingleLock lock(m_critSection); + if (channel.ChannelID() <= 0) { /* new channel */ @@ -640,9 +665,12 @@ bool CPVRDatabase::Persist(CPVRChannel &channel) { /* update the channel ID for new channels */ if (channel.ChannelID() <= 0) - channel.SetChannelID((int)m_pDS->lastinsertid()); + channel.SetChannelID(static_cast<int>(m_pDS->lastinsertid())); bReturn = true; + + if (bCommit) + bReturn = CommitInsertQueries(); } return bReturn; @@ -650,16 +678,16 @@ bool CPVRDatabase::Persist(CPVRChannel &channel) bool CPVRDatabase::UpdateLastWatched(const CPVRChannel &channel) { - std::string strQuery = PrepareSQL("UPDATE channels SET iLastWatched = %u WHERE idChannel = %d", + CSingleLock lock(m_critSection); + const std::string strQuery = PrepareSQL("UPDATE channels SET iLastWatched = %u WHERE idChannel = %d", static_cast<unsigned int>(channel.LastWatched()), channel.ChannelID()); - return ExecuteQuery(strQuery); } bool CPVRDatabase::UpdateLastWatched(const CPVRChannelGroup &group) { - std::string strQuery = PrepareSQL("UPDATE channelgroups SET iLastWatched = %u WHERE idGroup = %d", + CSingleLock lock(m_critSection); + const std::string strQuery = PrepareSQL("UPDATE channelgroups SET iLastWatched = %u WHERE idGroup = %d", static_cast<unsigned int>(group.LastWatched()), group.GroupID()); - return ExecuteQuery(strQuery); } diff --git a/xbmc/pvr/PVRDatabase.h b/xbmc/pvr/PVRDatabase.h index a8267b7edb..128d4221f0 100644 --- a/xbmc/pvr/PVRDatabase.h +++ b/xbmc/pvr/PVRDatabase.h @@ -19,17 +19,17 @@ * */ +#include <map> #include <vector> #include "dbwrappers/Database.h" -#include "utils/log.h" +#include "threads/CriticalSection.h" -#include "pvr/PVRManager.h" +#include "pvr/PVRTypes.h" namespace PVR { class CPVRChannelGroup; - class CPVRChannelGroupInternal; class CPVRChannel; class CPVRChannelGroups; @@ -51,6 +51,11 @@ namespace PVR bool Open() override; /*! + * @brief Close the database. + */ + void Close() override; + + /*! * @brief Get the minimal database version that is required to operate correctly. * @return The minimal database version. */ @@ -74,9 +79,10 @@ namespace PVR /*! * @brief Add or update a channel entry in the database * @param channel The channel to persist. + * @param bCommit queue only or queue and commit * @return True when persisted or queued, false otherwise. */ - bool Persist(CPVRChannel &channel); + bool Persist(CPVRChannel &channel, bool bCommit); /*! * @brief Remove a channel entry from the database @@ -88,9 +94,10 @@ namespace PVR /*! * @brief Get the list of channels from the database * @param results The channel group to store the results in. + * @param bCompressDB Compress the DB after getting the list * @return The amount of channels that were added. */ - int Get(CPVRChannelGroupInternal &results); + int Get(CPVRChannelGroup &results, bool bCompressDB); //@} @@ -120,9 +127,10 @@ namespace PVR /*! * @brief Add the group members to a group. * @param group The group to get the channels for. + * @param allChannels All channels contained in the "all channels group" matching param group's 'IsRadio' property. * @return The amount of channels that were added. */ - int Get(CPVRChannelGroup &group); + int Get(CPVRChannelGroup &group, const std::map<int, CPVRChannelPtr> &allChannels); /*! * @brief Add or update a channel group entry in the database. @@ -180,5 +188,7 @@ namespace PVR bool PersistChannels(CPVRChannelGroup &group); bool RemoveChannelsFromGroup(const CPVRChannelGroup &group); + + CCriticalSection m_critSection; }; } diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp index 9d103b4261..c516734d43 100644 --- a/xbmc/pvr/PVRManager.cpp +++ b/xbmc/pvr/PVRManager.cpp @@ -343,7 +343,7 @@ void CPVRManager::Stop(void) /* close database */ const CPVRDatabasePtr database(GetTVDatabase()); - if (database && database->IsOpen()) + if (database) database->Close(); SetState(ManagerStateStopped); diff --git a/xbmc/pvr/channels/PVRChannel.cpp b/xbmc/pvr/channels/PVRChannel.cpp index dee2d9a4c5..e2146806ba 100644 --- a/xbmc/pvr/channels/PVRChannel.cpp +++ b/xbmc/pvr/channels/PVRChannel.cpp @@ -29,6 +29,7 @@ #include "utils/log.h" #include "pvr/PVRDatabase.h" +#include "pvr/PVRManager.h" #include "pvr/addons/PVRClients.h" #include "pvr/channels/PVRChannelGroupInternal.h" #include "pvr/epg/EpgContainer.h" @@ -235,7 +236,7 @@ bool CPVRChannel::Persist() const CPVRDatabasePtr database(CServiceBroker::GetPVRManager().GetTVDatabase()); if (database) { - bool bReturn = database->Persist(*this) && database->CommitInsertQueries(); + bool bReturn = database->Persist(*this, true); CSingleLock lock(m_critSection); m_bChanged = !bReturn; return bReturn; diff --git a/xbmc/pvr/channels/PVRChannelGroup.cpp b/xbmc/pvr/channels/PVRChannelGroup.cpp index f46efc7b1d..c48a4b5c00 100644 --- a/xbmc/pvr/channels/PVRChannelGroup.cpp +++ b/xbmc/pvr/channels/PVRChannelGroup.cpp @@ -589,7 +589,20 @@ int CPVRChannelGroup::LoadFromDb(bool bCompress /* = false */) int iChannelCount = Size(); - database->Get(*this); + const CPVRChannelGroupPtr allGroup = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAll(IsRadio()); + if (!allGroup) + return -1; + + std::map<int, CPVRChannelPtr> allChannels; + { + CSingleLock lock(allGroup->m_critSection); + for (const auto& groupMember : allGroup->m_members) + { + allChannels.insert(std::make_pair(groupMember.second.channel->ChannelID(), groupMember.second.channel)); + } + } + + database->Get(*this, allChannels); return Size() - iChannelCount; } @@ -700,10 +713,6 @@ bool CPVRChannelGroup::UpdateGroupEntries(const CPVRChannelGroup &channels) bool bChanged(false); bool bRemoved(false); - const CPVRDatabasePtr database(CServiceBroker::GetPVRManager().GetTVDatabase()); - if (!database) - return bReturn; - CSingleLock lock(m_critSection); /* sort by client channel number if this is the first time or if pvrmanager.backendchannelorder is true */ bool bUseBackendChannelNumbers(m_members.empty() || m_bUsingBackendChannelOrder); @@ -717,12 +726,12 @@ bool CPVRChannelGroup::UpdateGroupEntries(const CPVRChannelGroup &channels) new channels were added at the back, so they'll get the highest numbers */ bool bRenumbered = SortAndRenumber(); + bReturn = Persist(); + SetChanged(); - lock.Leave(); + lock.Leave(); NotifyObservers(HasNewChannels() || bRemoved || bRenumbered ? ObservableMessageChannelGroupReset : ObservableMessageChannelGroup); - - bReturn = Persist(); } else { @@ -855,7 +864,6 @@ bool CPVRChannelGroup::Persist(void) CLog::Log(LOGDEBUG, "CPVRChannelGroup - %s - persisting channel group '%s' with %d channels", __FUNCTION__, GroupName().c_str(), (int) m_members.size()); m_bChanged = false; - lock.Leave(); bReturn = database->Persist(*this); } @@ -981,7 +989,6 @@ void CPVRChannelGroup::OnSettingChanged(std::shared_ptr<const CSetting> setting) m_bUsingBackendChannelOrder = bUsingBackendChannelOrder; m_bUsingBackendChannelNumbers = bUsingBackendChannelNumbers; - lock.Leave(); /* check whether this channel group has to be renumbered */ if (bChannelOrderChanged || bChannelNumbersChanged) @@ -1143,7 +1150,6 @@ bool CPVRChannelGroup::SetLastWatched(time_t iLastWatched) if (m_iLastWatched != iLastWatched) { m_iLastWatched = iLastWatched; - lock.Leave(); /* update the database immediately */ if (database) diff --git a/xbmc/pvr/channels/PVRChannelGroup.h b/xbmc/pvr/channels/PVRChannelGroup.h index 26ceec8923..e14ea5ef9a 100644 --- a/xbmc/pvr/channels/PVRChannelGroup.h +++ b/xbmc/pvr/channels/PVRChannelGroup.h @@ -19,6 +19,7 @@ * */ +#include <map> #include <memory> #include <utility> #include <vector> diff --git a/xbmc/pvr/channels/PVRChannelGroupInternal.cpp b/xbmc/pvr/channels/PVRChannelGroupInternal.cpp index 7aa286f0a5..2a852c1797 100644 --- a/xbmc/pvr/channels/PVRChannelGroupInternal.cpp +++ b/xbmc/pvr/channels/PVRChannelGroupInternal.cpp @@ -224,15 +224,9 @@ int CPVRChannelGroupInternal::LoadFromDb(bool bCompress /* = false */) int iChannelCount = Size(); - if (database->Get(*this) > 0) + if (database->Get(*this, bCompress) == 0) { - if (bCompress) - database->Compress(true); - } - else - { - CLog::Log(LOGINFO, "PVRChannelGroupInternal - %s - no channels in the database", - __FUNCTION__); + CLog::Log(LOGINFO, "PVRChannelGroupInternal - %s - no channels in the database", __FUNCTION__); } SortByChannelNumber(); diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp b/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp index 597c7b6a76..cedb81ea0c 100644 --- a/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp +++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp @@ -125,7 +125,7 @@ void CGUIDialogPVRChannelsOSD::OnDeinitWindow(int nextWindowID) { CGUIWindowPVRBase::SetSelectedItemPath(m_group->IsRadio(), m_viewControl.GetSelectedItemPath()); - // next OnInitWindow will set the group which is then selceted + // next OnInitWindow will set the group which is then selected m_group.reset(); } |