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