Exemplo n.º 1
0
static void DeserializeMetadata(const std::string& document, CAddonBuilder& builder)
{
  CVariant variant = CJSONVariantParser::Parse(document);

  builder.SetAuthor(variant["author"].asString());
  builder.SetDisclaimer(variant["disclaimer"].asString());
  builder.SetBroken(variant["broken"].asString());
  builder.SetPackageSize(variant["size"].asUnsignedInteger());

  builder.SetPath(variant["path"].asString());
  builder.SetFanart(variant["fanart"].asString());
  builder.SetIcon(variant["icon"].asString());

  std::vector<std::string> screenshots;
  for (auto it = variant["screenshots"].begin_array(); it != variant["screenshots"].end_array(); ++it)
    screenshots.push_back(it->asString());
  builder.SetScreenshots(std::move(screenshots));

  builder.SetType(TranslateType(variant["extensions"][0].asString()));

  ADDONDEPS deps;
  for (auto it = variant["dependencies"].begin_array(); it != variant["dependencies"].end_array(); ++it)
  {
    AddonVersion version((*it)["version"].asString());
    deps.emplace((*it)["addonId"].asString(), std::make_pair(std::move(version), (*it)["optional"].asBoolean()));
  }
  builder.SetDependencies(std::move(deps));

  InfoMap extraInfo;
  for (auto it = variant["extrainfo"].begin_array(); it != variant["extrainfo"].end_array(); ++it)
    extraInfo.emplace((*it)["key"].asString(), (*it)["value"].asString());
  builder.SetExtrainfo(std::move(extraInfo));
}
Exemplo n.º 2
0
static void DeserializeMetadata(const std::string& document, CAddonBuilder& builder)
{
  CVariant variant;
  if (!CJSONVariantParser::Parse(document, variant))
    return;

  builder.SetAuthor(variant["author"].asString());
  builder.SetDisclaimer(variant["disclaimer"].asString());
  builder.SetBroken(variant["broken"].asString());
  builder.SetPackageSize(variant["size"].asUnsignedInteger());

  builder.SetPath(variant["path"].asString());
  builder.SetIcon(variant["icon"].asString());

  std::map<std::string, std::string> art;
  for (auto it = variant["art"].begin_map(); it != variant["art"].end_map(); ++it)
    art.emplace(it->first, it->second.asString());
  builder.SetArt(std::move(art));

  std::vector<std::string> screenshots;
  for (auto it = variant["screenshots"].begin_array(); it != variant["screenshots"].end_array(); ++it)
    screenshots.push_back(it->asString());
  builder.SetScreenshots(std::move(screenshots));

  builder.SetType(CAddonInfo::TranslateType(variant["extensions"][0].asString()));

  {
    std::vector<DependencyInfo> deps;
    for (auto it = variant["dependencies"].begin_array(); it != variant["dependencies"].end_array(); ++it)
    {
      deps.emplace_back(
          (*it)["addonId"].asString(),
          AddonVersion((*it)["version"].asString()),
          (*it)["optional"].asBoolean());
    }
    builder.SetDependencies(std::move(deps));
  }

  InfoMap extraInfo;
  for (auto it = variant["extrainfo"].begin_array(); it != variant["extrainfo"].end_array(); ++it)
    extraInfo.emplace((*it)["key"].asString(), (*it)["value"].asString());
  builder.SetExtrainfo(std::move(extraInfo));
}
Exemplo n.º 3
0
bool CAddonDatabase::GetRepositoryContent(const std::string& repoId, VECADDONS& addons)
{
  try
  {
    if (NULL == m_pDB.get()) return false;
    if (NULL == m_pDS.get()) return false;

    auto start = XbmcThreads::SystemClockMillis();

    std::string commonConstraint = PrepareSQL(
        "JOIN addonlinkrepo ON addon.id=addonlinkrepo.idAddon "
        "JOIN repo ON addonlinkrepo.idRepo=repo.id "
        "WHERE repo.checksum IS NOT NULL AND repo.checksum != ''");

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

    commonConstraint += PrepareSQL(" ORDER BY addon.addonID");

    std::vector<CAddonBuilder> result;
    // Read basic info from the `addon` table
    {
      std::string sql = PrepareSQL("SELECT addon.*, broken.reason FROM addon "
          "LEFT JOIN broken ON broken.addonID=addon.addonID ") + commonConstraint;
      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);

      while (!m_pDS->eof())
      {
        std::string addonId = m_pDS->fv(addon_addonID).get_asString();
        AddonVersion version(m_pDS->fv(addon_version).get_asString());

        if (!result.empty() && result.back().GetId() == addonId && result.back().GetVersion() >= 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.SetType(TranslateType(m_pDS->fv(addon_type).get_asString()));
        builder.SetMinVersion(AddonVersion(m_pDS->fv(addon_minversion).get_asString()));
        builder.SetName(m_pDS->fv(addon_name).get_asString());
        builder.SetSummary(m_pDS->fv(addon_summary).get_asString());
        builder.SetDescription(m_pDS->fv(addon_description).get_asString());
        builder.SetChangelog(m_pDS->fv(addon_changelog).get_asString());
        builder.SetDisclaimer(m_pDS->fv(addon_disclaimer).get_asString());
        builder.SetAuthor(m_pDS->fv(addon_author).get_asString());
        builder.SetPath(m_pDS->fv(addon_path).get_asString());
        builder.SetIcon(m_pDS->fv(addon_icon).get_asString());
        builder.SetFanart(m_pDS->fv(addon_fanart).get_asString());
        builder.SetBroken(m_pDS->fv(broken_reason).get_asString());
        if (!result.empty() && result.back().GetId() == addonId)
          result.back() = std::move(builder);
        else
          result.push_back(std::move(builder));
        m_pDS->next();
      }
    }

    // Read extra info.
    {
      std::string sql = PrepareSQL(
          "SELECT addon.addonID as owner, addonextra.key, addonextra.value "
          "FROM addon JOIN addonextra ON addon.id=addonextra.id ") + commonConstraint;

      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);

      for (auto& builder : result)
      {
        //move cursor to current or next addon
        while (!m_pDS->eof() && m_pDS->fv(0).get_asString() < builder.GetId())
          m_pDS->next();

        InfoMap extraInfo;
        while (!m_pDS->eof() && m_pDS->fv(0).get_asString() == builder.GetId())
        {
          extraInfo.emplace(m_pDS->fv(1).get_asString(), m_pDS->fv(2).get_asString());
          m_pDS->next();
        }
        builder.SetExtrainfo(std::move(extraInfo));
      }
    }

    // Read dependency info.
    {
      std::string sql = PrepareSQL(
          "SELECT addon.addonID as owner, dependencies.addon, dependencies.version, dependencies.optional "
          "FROM addon JOIN dependencies ON addon.id=dependencies.id ") + commonConstraint;

      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);

      for (auto& builder : result)
      {
        //move cursor to the current or next addon
        while (!m_pDS->eof() && m_pDS->fv(0).get_asString() < builder.GetId())
          m_pDS->next();

        ADDONDEPS dependencies;
        while (!m_pDS->eof() && m_pDS->fv(0).get_asString() == builder.GetId())
        {
          dependencies.emplace(m_pDS->fv(1).get_asString(),
              std::make_pair(AddonVersion(m_pDS->fv(2).get_asString()), m_pDS->fv(3).get_asBool()));
          m_pDS->next();
        }
        builder.SetDependencies(std::move(dependencies));
      }
    }
    m_pDS->close();

    for (auto& builder : result)
    {
      auto addon = builder.Build();
      if (addon)
        addons.push_back(std::move(addon));
    }

    CLog::Log(LOGDEBUG, "CAddonDatabase::GetAddons took %i ms", XbmcThreads::SystemClockMillis() - start);
    return true;
  }
  catch (...)
  {
    CLog::Log(LOGERROR, "%s failed", __FUNCTION__);
  }
  return false;
}
Exemplo n.º 4
0
bool CAddonDatabase::GetAddon(int id, AddonPtr &addon)
{
  try
  {
    if (NULL == m_pDB.get()) return false;
    if (NULL == m_pDS2.get()) return false;

    std::string sql = "SELECT addon.*,"
                      "       broken.reason,"
                      "       addonextra.key, addonextra.value,"
                      "       dependencies.addon, dependencies.version, dependencies.optional"
                      "  FROM addon"
                      "    LEFT JOIN broken"
                      "      ON broken.addonID = addon.addonID"
                      "    LEFT JOIN addonextra"
                      "      ON addonextra.id = addon.id"
                      "    LEFT JOIN dependencies"
                      "      ON dependencies.id = addon.id";

    sql += PrepareSQL(" WHERE addon.id=%i", id);

    m_pDS2->query(sql);
    if (!m_pDS2->eof())
    {
      const dbiplus::query_data &data = m_pDS2->get_result_set().records;
      const dbiplus::sql_record* const record = data[0];

      CAddonBuilder builder;
      builder.SetId(record->at(addon_addonID).get_asString());
      builder.SetType(TranslateType(record->at(addon_type).get_asString()));
      builder.SetVersion(AddonVersion(record->at(addon_version).get_asString()));
      builder.SetMinVersion(AddonVersion(record->at(addon_minversion).get_asString()));
      builder.SetName(record->at(addon_name).get_asString());
      builder.SetSummary(record->at(addon_summary).get_asString());
      builder.SetDescription(record->at(addon_description).get_asString());
      builder.SetChangelog(record->at(addon_changelog).get_asString());
      builder.SetDisclaimer(record->at(addon_disclaimer).get_asString());
      builder.SetAuthor(record->at(addon_author).get_asString());
      builder.SetBroken(record->at(broken_reason).get_asString());
      builder.SetPath(record->at(addon_path).get_asString());
      builder.SetIcon(record->at(addon_icon).get_asString());
      builder.SetFanart(record->at(addon_fanart).get_asString());

      InfoMap extrainfo;
      ADDONDEPS dependencies;
      /* while this is a cartesion join and we'll typically get multiple rows, we rely on the fact that
         extrainfo and dependencies are maps, so insert() will insert the first instance only */
      for (dbiplus::query_data::const_iterator i = data.begin(); i != data.end(); ++i)
      {
        const dbiplus::sql_record* const record = *i;
        if (!record->at(addonextra_key).get_asString().empty())
          extrainfo.insert(std::make_pair(record->at(addonextra_key).get_asString(), record->at(addonextra_value).get_asString()));
        if (!m_pDS2->fv(dependencies_addon).get_asString().empty())
          dependencies.insert(std::make_pair(record->at(dependencies_addon).get_asString(), std::make_pair(AddonVersion(record->at(dependencies_version).get_asString()), record->at(dependencies_optional).get_asBool())));
      }
      builder.SetExtrainfo(std::move(extrainfo));
      builder.SetDependencies(std::move(dependencies));

      addon = builder.Build();
      return NULL != addon.get();
    }
  }
  catch (...)
  {
    CLog::Log(LOGERROR, "%s failed on addon %i", __FUNCTION__, id);
  }
  addon.reset();
  return false;
}