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