bool CPVRDatabase::RemoveStaleChannelsFromGroup(const CPVRChannelGroup &group) { bool bDelete(true); if (!group.IsInternalGroup()) { /* First remove channels that don't exist in the main channels table */ CStdString strWhereClause = FormatSQL("idChannel IN (SELECT map_channelgroups_channels.idChannel FROM map_channelgroups_channels LEFT JOIN channels on map_channelgroups_channels.idChannel = channels.idChannel WHERE channels.idChannel IS NULL)"); bDelete = DeleteValues("map_channelgroups_channels", strWhereClause); } if (group.size() > 0) { vector<int> currentMembers; if (GetCurrentGroupMembers(group, currentMembers)) { vector<int> channelsToDelete; for (unsigned int iChannelPtr = 0; iChannelPtr < currentMembers.size(); iChannelPtr++) { if (!group.IsGroupMember(currentMembers.at(iChannelPtr))) channelsToDelete.push_back(currentMembers.at(iChannelPtr)); } bDelete = DeleteChannelsFromGroup(group, channelsToDelete) && bDelete; } } else { CStdString strWhereClause = FormatSQL("idGroup = %u", group.GroupID()); bDelete = DeleteValues("map_channelgroups_channels", strWhereClause) && bDelete; } return bDelete; }
bool CPVRChannelGroups::DeleteGroup(const CPVRChannelGroup &group) { // don't delete internal groups if (group.IsInternalGroup()) { CLog::Log(LOGERROR, "PVR - %s - cannot delete internal group '%s'", __FUNCTION__, group.GroupName().c_str()); return false; } // delete the group in this container CSingleLock lock(m_critSection); for (std::vector<CPVRChannelGroupPtr>::iterator it = m_groups.begin(); it != m_groups.end(); it++) { if ((*it)->GroupID() == group.GroupID()) { // update the selected group in the gui if it's deleted CPVRChannelGroupPtr selectedGroup = GetSelectedGroup(); if (selectedGroup && *selectedGroup == group) g_PVRManager.SetPlayingGroup(GetGroupAll()); m_groups.erase(it); break; } } // delete the group from the database CPVRDatabase *database = GetPVRDatabase(); return database ? database->Delete(group) : false; }
bool CPVRDatabase::RemoveStaleChannelsFromGroup(const CPVRChannelGroup &group) { bool bDelete(true); /* invalid group id */ if (group.GroupID() <= 0) { CLog::Log(LOGERROR, "PVR - %s - invalid group id: %d", __FUNCTION__, group.GroupID()); return false; } if (!group.IsInternalGroup()) { /* First remove channels that don't exist in the main channels table */ // XXX work around for frodo: fix this up so it uses one query for all db types // 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"); bDelete = ExecuteQuery(strQuery); } else { Filter filter; filter.AppendWhere("idChannel IN (SELECT m.idChannel FROM map_channelgroups_channels m LEFT JOIN channels on m.idChannel = channels.idChannel WHERE channels.idChannel IS NULL)"); bDelete = DeleteValues("map_channelgroups_channels", filter); } } if (group.HasChannels()) { std::vector<int> currentMembers; if (GetCurrentGroupMembers(group, currentMembers)) { std::vector<int> channelsToDelete; for (unsigned int iChannelPtr = 0; iChannelPtr < currentMembers.size(); iChannelPtr++) { if (!group.IsGroupMember(currentMembers.at(iChannelPtr))) channelsToDelete.push_back(currentMembers.at(iChannelPtr)); } bDelete = DeleteChannelsFromGroup(group, channelsToDelete) && bDelete; } } else { Filter filter; filter.AppendWhere(PrepareSQL("idGroup = %u", group.GroupID())); bDelete = DeleteValues("map_channelgroups_channels", filter) && bDelete; } return bDelete; }
bool CPVRChannelGroups::Update(const CPVRChannelGroup &group, bool bUpdateFromClient /* = false */) { if (group.GroupName().empty() && group.GroupID() <= 0) return true; CPVRChannelGroupPtr updateGroup; { CSingleLock lock(m_critSection); // There can be only one internal group! Make sure we never push a new one! if (group.IsInternalGroup()) updateGroup = GetGroupAll(); // try to find the group by id if (!updateGroup && group.GroupID() > 0) updateGroup = GetById(group.GroupID()); // try to find the group by name if we didn't find it yet if (!updateGroup) updateGroup = GetByName(group.GroupName()); if (!updateGroup) { // create a new group if none was found. Copy the properties immediately // so the group doesn't get flagged as "changed" further down. updateGroup = CPVRChannelGroupPtr(new CPVRChannelGroup(group.IsRadio(), group.GroupID(), group.GroupName())); m_groups.push_back(updateGroup); } updateGroup->SetRadio(group.IsRadio()); updateGroup->SetGroupID(group.GroupID()); updateGroup->SetGroupName(group.GroupName()); updateGroup->SetGroupType(group.GroupType()); updateGroup->SetPosition(group.GetPosition()); // don't override properties we only store locally in our PVR database if (!bUpdateFromClient) { updateGroup->SetLastWatched(group.LastWatched()); updateGroup->SetHidden(group.IsHidden()); } } // sort groups SortGroups(); // persist changes if (bUpdateFromClient) return updateGroup->Persist(); return true; }
bool CPVRChannelGroups::DeleteGroup(const CPVRChannelGroup &group) { // don't delete internal groups if (group.IsInternalGroup()) { CLog::Log(LOGERROR, "CPVRChannelGroups - %s - cannot delete internal group '%s'", __FUNCTION__, group.GroupName().c_str()); return false; } bool bFound(false); CPVRChannelGroupPtr playingGroup; // delete the group in this container { CSingleLock lock(m_critSection); for (std::vector<CPVRChannelGroupPtr>::iterator it = m_groups.begin(); !bFound && it != m_groups.end();) { if (*(*it) == group || (group.GroupID() > 0 && (*it)->GroupID() == group.GroupID())) { // update the selected group in the gui if it's deleted CPVRChannelGroupPtr selectedGroup = GetSelectedGroup(); if (selectedGroup && *selectedGroup == group) playingGroup = GetGroupAll(); it = m_groups.erase(it); bFound = true; } else { ++it; } } } if (playingGroup) g_PVRManager.SetPlayingGroup(playingGroup); if (group.GroupID() > 0) { // delete the group from the database const CPVRDatabasePtr database(g_PVRManager.GetTVDatabase()); return database ? database->Delete(group) : false; } return bFound; }
bool CPVRDatabase::Persist(CPVRChannelGroup &group) { bool bReturn(false); if (group.GroupName().empty()) { CLog::LogF(LOGERROR, "Empty group name"); return bReturn; } std::string strQuery; bReturn = true; CSingleLock lock(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)", (group.IsRadio() ? 1 :0), group.GroupType(), group.GroupName().c_str(), static_cast<unsigned int>(group.LastWatched()), group.IsHidden(), group.GetPosition()); else strQuery = PrepareSQL("REPLACE INTO channelgroups (idGroup, bIsRadio, iGroupType, sName, iLastWatched, bIsHidden, iPosition) VALUES (%i, %i, %i, '%s', %u, %i, %i)", group.GroupID(), (group.IsRadio() ? 1 :0), group.GroupType(), group.GroupName().c_str(), static_cast<unsigned int>(group.LastWatched()), group.IsHidden(), group.GetPosition()); bReturn = ExecuteQuery(strQuery); /* 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 */ if (group.IsInternalGroup()) bReturn &= PersistChannels(group); /* persist the group member entries */ if (bReturn) bReturn = PersistGroupMembers(group); return bReturn; }
bool CPVRDatabase::RemoveStaleChannelsFromGroup(const CPVRChannelGroup &group) { bool bDelete(true); /* invalid group id */ if (group.GroupID() <= 0) { CLog::Log(LOGERROR, "PVR - %s - invalid group id: %d", __FUNCTION__, group.GroupID()); return false; } if (!group.IsInternalGroup()) { /* First remove channels that don't exist in the main channels table */ CStdString strQuery = FormatSQL("DELETE m FROM map_channelgroups_channels m LEFT JOIN channels c ON (c.idChannel = m.idChannel) WHERE c.idChannel IS NULL"); bDelete = ExecuteQuery(strQuery); } if (group.m_members.size() > 0) { vector<int> currentMembers; if (GetCurrentGroupMembers(group, currentMembers)) { vector<int> channelsToDelete; for (unsigned int iChannelPtr = 0; iChannelPtr < currentMembers.size(); iChannelPtr++) { if (!group.IsGroupMember(currentMembers.at(iChannelPtr))) channelsToDelete.push_back(currentMembers.at(iChannelPtr)); } bDelete = DeleteChannelsFromGroup(group, channelsToDelete) && bDelete; } } else { CStdString strWhereClause = FormatSQL("idGroup = %u", group.GroupID()); bDelete = DeleteValues("map_channelgroups_channels", strWhereClause) && bDelete; } return bDelete; }
bool CPVRDatabase::Persist(CPVRChannelGroup &group) { bool bReturn(false); if (group.GroupName().IsEmpty()) { CLog::Log(LOGERROR, "%s - empty group name", __FUNCTION__); return bReturn; } CStdString strQuery; bReturn = true; { 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 = FormatSQL("INSERT INTO channelgroups (bIsRadio, iGroupType, sName) VALUES (%i, %i, '%s')", (group.IsRadio() ? 1 :0), group.GroupType(), group.GroupName().c_str()); else strQuery = FormatSQL("REPLACE INTO channelgroups (idGroup, bIsRadio, iGroupType, sName) VALUES (%i, %i, %i, '%s')", group.GroupID(), (group.IsRadio() ? 1 :0), group.GroupType(), group.GroupName().c_str()); bReturn = ExecuteQuery(strQuery); /* set the group id if it was <= 0 */ if (bReturn && group.GroupID() <= 0) group.m_iGroupId = (int) m_pDS->lastinsertid(); } /* only persist the channel data for the internal groups */ if (group.IsInternalGroup()) bReturn &= PersistChannels(group); /* persist the group member entries */ if (bReturn) bReturn = PersistGroupMembers(group); return bReturn; }
bool CPVRChannelGroups::DeleteGroup(const CPVRChannelGroup &group) { bool bReturn = false; if (group.IsInternalGroup()) { CLog::Log(LOG_ERROR, "CPVRChannelGroups - %s - cannot delete internal group '%s'", __FUNCTION__, group.GroupName().c_str()); return bReturn; } CPVRDatabase *database = CPVRManager::Get()->GetTVDatabase(); if (!database || !database->Open()) { CLog::Log(LOG_ERROR, "CPVRChannelGroups - %s - unable to open the database", __FUNCTION__); return bReturn; } /* remove all channels from the group */ database->RemoveChannelsFromGroup(group.GroupID()); /* delete the group from the database */ bReturn = database->DeleteChannelGroup(group.GroupID(), m_bRadio); database->Close(); /* delete the group in this container */ for (unsigned int iGroupPtr = 0; iGroupPtr < size(); iGroupPtr++) { if (at(iGroupPtr)->GroupID() == group.GroupID()) { delete at(iGroupPtr); erase(begin() + iGroupPtr); break; } } return bReturn; }
bool CPVRChannelGroups::DeleteGroup(const CPVRChannelGroup &group) { bool bReturn = false; CSingleLock lock(m_critSection); if (group.IsInternalGroup()) { CLog::Log(LOGERROR, "CPVRChannelGroups - %s - cannot delete internal group '%s'", __FUNCTION__, group.GroupName().c_str()); return bReturn; } CPVRDatabase *database = GetPVRDatabase(); if (!database) return bReturn; /* remove all channels from the group */ database->RemoveChannelsFromGroup(group); /* delete the group from the database */ bReturn = database->Delete(group); /* delete the group in this container */ for (unsigned int iGroupPtr = 0; iGroupPtr < size(); iGroupPtr++) { if (at(iGroupPtr)->GroupID() == group.GroupID()) { CPVRChannelGroup *selectedGroup = GetSelectedGroup(); if (selectedGroup && *selectedGroup == group) g_PVRManager.SetPlayingGroup(GetGroupAll()); delete at(iGroupPtr); erase(begin() + iGroupPtr); break; } } return bReturn; }
bool CPVRDatabase::RemoveStaleChannelsFromGroup(const CPVRChannelGroup &group) { bool bDelete(true); /* invalid group id */ if (group.GroupID() <= 0) { CLog::LogF(LOGERROR, "Invalid channel group id: %d", group.GroupID()); return false; } CSingleLock lock(m_critSection); if (!group.IsInternalGroup()) { /* First remove channels that don't exist in the main channels table */ // XXX work around for frodo: fix this up so it uses one query for all db types // mysql doesn't support subqueries when deleting and sqlite doesn't support joins when deleting if (StringUtils::EqualsNoCase(g_advancedSettings.m_databaseTV.type, "mysql")) { 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 { Filter filter; filter.AppendWhere("idChannel IN (SELECT m.idChannel FROM map_channelgroups_channels m LEFT JOIN channels on m.idChannel = channels.idChannel WHERE channels.idChannel IS NULL)"); bDelete = DeleteValues("map_channelgroups_channels", filter); } } if (group.HasChannels()) { std::vector<int> currentMembers; if (GetCurrentGroupMembers(group, currentMembers)) { std::vector<int> channelsToDelete; for (int iChannelId : currentMembers) { if (!group.IsGroupMember(iChannelId)) { int iClientId = GetClientIdByChannelId(iChannelId); if (iClientId == PVR_INVALID_CLIENT_ID || !group.IsMissingChannelsFromClient(iClientId)) { channelsToDelete.emplace_back(iChannelId); } } } if (!channelsToDelete.empty()) bDelete = DeleteChannelsFromGroup(group, channelsToDelete) && bDelete; } } else { Filter filter; filter.AppendWhere(PrepareSQL("idGroup = %u", group.GroupID())); bDelete = DeleteValues("map_channelgroups_channels", filter) && bDelete; } return bDelete; }