Ejemplo n.º 1
0
bool CAddonDatabase::GetRepositoryContent(const std::string& id, VECADDONS& addons)
{
  try
  {
    if (NULL == m_pDB.get()) return false;
    if (NULL == m_pDS.get()) return false;

    auto start = XbmcThreads::SystemClockMillis();

    // Ensure that the repositories we fetch from are enabled and valid.
    std::vector<std::string> repoIds;
    {
      std::string sql = PrepareSQL(
          " SELECT repo.id FROM repo"
          " WHERE repo.checksum IS NOT NULL AND repo.checksum != ''"
          " AND EXISTS (SELECT * FROM installed WHERE installed.addonID=repo.addonID AND"
          " installed.enabled=1)");

      if (!id.empty())
        sql += PrepareSQL(" AND repo.addonId='%s'", id.c_str());

      m_pDS->query(sql);
      while (!m_pDS->eof())
      {
        repoIds.emplace_back(m_pDS->fv(0).get_asString());
        m_pDS->next();
      }
    }

    CLog::Log(LOGDEBUG, "CAddonDatabase: SELECT repo.id FROM repo .. took %d ms", XbmcThreads::SystemClockMillis() - start);

    if (repoIds.empty())
    {
      CLog::Log(LOGDEBUG, "CAddonDatabase: no valid repository matching '%s'", id.c_str());
      return false;
    }

    {
      std::string sql = PrepareSQL(
          " SELECT * FROM addons"
          " JOIN addonlinkrepo ON addons.id=addonlinkrepo.idAddon"
          " WHERE addonlinkrepo.idRepo IN (%s)"
          " ORDER BY addons.addonID", StringUtils::Join(repoIds, ",").c_str());

      auto start = XbmcThreads::SystemClockMillis();
      m_pDS->query(sql);
      CLog::Log(LOGDEBUG, "CAddonDatabase: query %s returned %d rows in %d ms", sql.c_str(),
          m_pDS->num_rows(), XbmcThreads::SystemClockMillis() - start);
    }

    VECADDONS result;
    while (!m_pDS->eof())
    {
      std::string addonId = m_pDS->fv("addonID").get_asString();
      AddonVersion version(m_pDS->fv("version").get_asString());

      if (!result.empty() && result.back()->ID() == addonId && result.back()->Version() >= version)
      {
        // We already have a version of this addon in our list which is newer.
        m_pDS->next();
        continue;
      }

      CAddonBuilder builder;
      builder.SetId(addonId);
      builder.SetVersion(version);
      builder.SetName(m_pDS->fv("name").get_asString());
      builder.SetSummary(m_pDS->fv("summary").get_asString());
      builder.SetDescription(m_pDS->fv("description").get_asString());
      DeserializeMetadata(m_pDS->fv("metadata").get_asString(), builder);

      auto addon = builder.Build();
      if (addon)
      {
        if (!result.empty() && result.back()->ID() == addonId)
          result.back() = std::move(addon);
        else
          result.push_back(std::move(addon));
      }
      else
        CLog::Log(LOGWARNING, "CAddonDatabase: failed to build %s", addonId.c_str());
      m_pDS->next();
    }
    m_pDS->close();
    addons = std::move(result);

    CLog::Log(LOGDEBUG, "CAddonDatabase::GetAddons took %i ms", XbmcThreads::SystemClockMillis() - start);
    return true;
  }
  catch (...)
  {
    CLog::Log(LOGERROR, "%s failed", __FUNCTION__);
  }
  return false;
}