bool CPVRDatabase::PersistGroupMembers(CPVRChannelGroup &group) { bool bReturn = false; bool bRemoveChannels = false; CStdString strQuery; CSingleLock lock(group.m_critSection); if (group.size() > 0) { for (unsigned int iChannelPtr = 0; iChannelPtr < group.size(); iChannelPtr++) { PVRChannelGroupMember member = group.at(iChannelPtr); CStdString strWhereClause = FormatSQL("idChannel = %u AND idGroup = %u AND iChannelNumber = %u", member.channel->ChannelID(), group.GroupID(), member.iChannelNumber); CStdString strValue = GetSingleValue("map_channelgroups_channels", "idChannel", strWhereClause); if (strValue.IsEmpty()) { strQuery = FormatSQL("REPLACE INTO map_channelgroups_channels (" "idGroup, idChannel, iChannelNumber) " "VALUES (%i, %i, %i);", group.GroupID(), member.channel->ChannelID(), member.iChannelNumber); QueueInsertQuery(strQuery); } } lock.Leave(); bReturn = CommitInsertQueries(); bRemoveChannels = RemoveStaleChannelsFromGroup(group); } return bReturn && bRemoveChannels; }
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 CPVRChannelGroup::AddAndUpdateChannels(const CPVRChannelGroup &channels, bool bUseBackendChannelNumbers) { bool bReturn(false); CSingleLock lock(m_critSection); /* go through the channel list and check for new channels. channels will only by updated in CPVRChannelGroupInternal to prevent dupe updates */ for (unsigned int iChannelPtr = 0; iChannelPtr < channels.size(); iChannelPtr++) { PVRChannelGroupMember member = channels.at(iChannelPtr); if (!member.channel) continue; /* check whether this channel is known in the internal group */ CPVRChannel *existingChannel = (CPVRChannel *) g_PVRChannelGroups->GetGroupAll(m_bRadio)->GetByClient(member.channel->UniqueID(), member.channel->ClientID()); if (!existingChannel) continue; /* if it's found, add the channel to this group */ if (!IsGroupMember(*existingChannel)) { int iChannelNumber = bUseBackendChannelNumbers ? member.channel->ClientChannelNumber() : 0; AddToGroup(*existingChannel, iChannelNumber, false); bReturn = true; CLog::Log(LOGINFO,"PVRChannelGroup - %s - added %s channel '%s' at position %d in group '%s'", __FUNCTION__, m_bRadio ? "radio" : "TV", existingChannel->ChannelName().c_str(), iChannelNumber, GroupName().c_str()); } } return bReturn; }
bool CPVRChannelGroupInternal::AddAndUpdateChannels(const CPVRChannelGroup &channels, bool bUseBackendChannelNumbers) { bool bReturn(false); CSingleLock lock(m_critSection); /* go through the channel list and check for updated or new channels */ for (unsigned int iChannelPtr = 0; iChannelPtr < channels.size(); iChannelPtr++) { PVRChannelGroupMember member = channels.at(iChannelPtr); if (!member.channel) continue; /* check whether this channel is present in this container */ CPVRChannel *existingChannel = (CPVRChannel *) GetByClient(member.channel->UniqueID(), member.channel->ClientID()); if (existingChannel) { /* if it's present, update the current tag */ if (existingChannel->UpdateFromClient(*member.channel)) { existingChannel->Persist(!m_bLoaded); bReturn = true; CLog::Log(LOGINFO,"PVRChannelGroupInternal - %s - updated %s channel '%s'", __FUNCTION__, m_bRadio ? "radio" : "TV", member.channel->ChannelName().c_str()); } } else { /* new channel */ CPVRChannel *newChannel = new CPVRChannel(*member.channel); /* insert the new channel in this group */ int iChannelNumber = bUseBackendChannelNumbers ? member.channel->ClientChannelNumber() : 0; InsertInGroup(*newChannel, iChannelNumber, false); bReturn = true; CLog::Log(LOGINFO,"PVRChannelGroupInternal - %s - added %s channel '%s' at position %d", __FUNCTION__, m_bRadio ? "radio" : "TV", member.channel->ChannelName().c_str(), iChannelNumber); } } return bReturn; }
bool CPVRDatabase::PersistChannels(CPVRChannelGroup &group) { bool bReturn(true); int iLastChannel(0); /* we can only safely get this from a local db */ if (m_sqlite) iLastChannel = GetLastChannelId(); for (unsigned int iChannelPtr = 0; iChannelPtr < group.size(); iChannelPtr++) { PVRChannelGroupMember member = group.at(iChannelPtr); if (member.channel->IsChanged() || member.channel->IsNew()) { if (m_sqlite && member.channel->IsNew()) member.channel->SetChannelID(++iLastChannel, false); bReturn &= Persist(*member.channel, m_sqlite || !member.channel->IsNew()); } } return CommitInsertQueries(); }
bool CPVRChannelGroupInternal::UpdateGroupEntries(const CPVRChannelGroup &channels) { bool bChanged = false; int iCurSize = size(); CPVRChannelGroup *newChannels = new CPVRChannelGroup(m_bRadio); CPVRDatabase *database = g_PVRManager.GetTVDatabase(); if (!database || !database->Open()) return bChanged; /* go through the channel list and check for updated or new channels */ for (unsigned int iChannelPtr = 0; iChannelPtr < channels.size(); iChannelPtr++) { const CPVRChannel *channel = channels.at(iChannelPtr).channel; /* check if this channel is present in this container */ CPVRChannel *existingChannel = (CPVRChannel *) GetByClient(channel->UniqueID(), channel->ClientID()); if (existingChannel) { /* if it's present, update the current tag */ if (existingChannel->UpdateFromClient(*channel)) { bChanged = true; CLog::Log(LOGINFO,"PVRChannelGroupInternal - %s - updated %s channel '%s'", __FUNCTION__, m_bRadio ? "radio" : "TV", channel->ChannelName().c_str()); } } else { /* new channel */ CPVRChannel *newChannel = new CPVRChannel(m_bRadio); newChannel->SetUniqueID(channel->UniqueID(), false); newChannel->UpdateFromClient(*channel); newChannels->AddToGroup(newChannel); int iChannelNumber = iCurSize == 0 ? channel->ClientChannelNumber() : 0; InsertInGroup(newChannel, iChannelNumber, false); bChanged = true; CLog::Log(LOGINFO,"PVRChannelGroupInternal - %s - added %s channel '%s' at position %d", __FUNCTION__, m_bRadio ? "radio" : "TV", channel->ChannelName().c_str(), iChannelNumber); } } /* persist changes */ for (unsigned int iChannelPtr = 0; iChannelPtr < newChannels->size(); iChannelPtr++) ((CPVRChannel *) newChannels->GetByIndex(iChannelPtr))->Persist(false); /* write immediately to get a db id */ delete newChannels; /* check for deleted channels */ unsigned int iSize = size(); for (unsigned int iChannelPtr = 0; iChannelPtr < iSize; iChannelPtr++) { CPVRChannel *channel = (CPVRChannel *) GetByIndex(iChannelPtr); if (!channel) continue; if (channels.GetByClient(channel->UniqueID(), channel->ClientID()) == NULL) { /* channel was not found */ CLog::Log(LOGINFO,"PVRChannelGroupInternal - %s - deleted %s channel '%s'", __FUNCTION__, m_bRadio ? "radio" : "TV", channel->ChannelName().c_str()); /* remove this channel from all non-system groups */ ((CPVRChannelGroups *) g_PVRChannelGroups->Get(m_bRadio))->RemoveFromAllGroups(channel); delete at(iChannelPtr).channel; erase(begin() + iChannelPtr); iChannelPtr--; iSize--; bChanged = true; } } database->Close(); /* try to find channel icons */ SearchAndSetChannelIcons(); CacheIcons(); if (bChanged || HasChanges()) { /* remove invalid channels */ RemoveInvalidChannels(); /* sort by client channel number if this is the first time */ if (iCurSize == 0) SortByClientChannelNumber(); /* renumber to make sure all channels have a channel number. new channels were added at the back, so they'll get the highest numbers */ Renumber(); return Persist(); } else { return true; } }
bool CPVRChannelGroup::UpdateGroupEntries(const CPVRChannelGroup &channels) { bool bChanged(false); CSingleLock lock(m_critSection); int iCurSize = size(); CPVRDatabase *database = CPVRManager::Get()->GetTVDatabase(); if (!database || !database->Open()) return false; /* go through the channel list and check for updated or new channels */ for (unsigned int iChannelPtr = 0; iChannelPtr < channels.size(); iChannelPtr++) { CPVRChannel *channel = channels.at(iChannelPtr).channel; int iChannelNumber = channels.at(iChannelPtr).iChannelNumber; if (!channel) continue; CPVRChannel *realChannel = (CPVRChannel *) CPVRManager::GetChannelGroups()->GetGroupAll(m_bRadio)->GetByClient(channel->UniqueID(), channel->ClientID()); if (!realChannel) continue; if (!IsGroupMember(realChannel)) { AddToGroup(realChannel, iChannelNumber, false); bChanged = true; m_bChanged = true; CLog::Log(LOGINFO,"PVRChannelGroup - %s - added %s channel '%s' at position %d in group '%s'", __FUNCTION__, m_bRadio ? "radio" : "TV", realChannel->ChannelName().c_str(), iChannelNumber, GroupName().c_str()); } } /* check for deleted channels */ unsigned int iSize = size(); for (unsigned int iChannelPtr = 0; iChannelPtr < iSize; iChannelPtr++) { CPVRChannel *channel = (CPVRChannel *) GetByIndex(iChannelPtr); if (!channel) continue; if (channels.GetByClient(channel->UniqueID(), channel->ClientID()) == NULL) { /* channel was not found */ CLog::Log(LOGINFO,"PVRChannelGroup - %s - deleted %s channel '%s' from group '%s'", __FUNCTION__, m_bRadio ? "radio" : "TV", channel->ChannelName().c_str(), GroupName().c_str()); /* remove this channel from all non-system groups */ RemoveFromGroup(channel); m_bChanged = true; bChanged = true; iChannelPtr--; iSize--; } } if (bChanged) { /* sort by client channel number if this is the first time */ if (iCurSize == 0) SortByClientChannelNumber(); /* renumber to make sure all channels have a channel number. new channels were added at the back, so they'll get the highest numbers */ Renumber(); return Persist(); } return true; }