Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
0
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;
}
Пример #11
0
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;
}