DistroqueryAPI: getProvidersForRequirements: fix version with flags check

This commit is contained in:
Silvan Calarco 2024-07-07 16:03:27 +02:00
parent 436a177a2e
commit 44b651292f
6 changed files with 27 additions and 46 deletions

View File

@ -4,6 +4,7 @@
"iostream": "cpp", "iostream": "cpp",
"vector": "cpp", "vector": "cpp",
"string": "cpp", "string": "cpp",
"format": "cpp" "format": "cpp",
"string.h": "c"
} }
} }

View File

@ -232,7 +232,7 @@ json DistroqueryAPI::getBuiltPackagesFromSourceID(configTag* ct, long id) {
return j; return j;
} }
json DistroqueryAPI::getProvidersForRequirement(string repository, string requirement, string flags, string version) { json DistroqueryAPI::getProvidersForRequirement(string repository, string requirement, string flags, string version, string onlyarch) {
json j; json j;
sqlite3_stmt *stmt; sqlite3_stmt *stmt;
@ -255,6 +255,7 @@ json DistroqueryAPI::getProvidersForRequirement(string repository, string requir
int a = 0; int a = 0;
for (auto arch: ct->arch) { for (auto arch: ct->arch) {
if (arch == NULL) break; if (arch == NULL) break;
if (onlyarch != "" && onlyarch != arch) continue;
attachCtDatabases(ct, db, arch); attachCtDatabases(ct, db, arch);
int i = 0; int i = 0;
while (ct->repository[i]) { while (ct->repository[i]) {
@ -264,9 +265,6 @@ json DistroqueryAPI::getProvidersForRequirement(string repository, string requir
"FROM '" + string(ct->repository[i]->tag) + "_" + arch + "'.provides,'" + "FROM '" + string(ct->repository[i]->tag) + "_" + arch + "'.provides,'" +
string(ct->repository[i]->tag) + "_" + arch + "'.packages " string(ct->repository[i]->tag) + "_" + arch + "'.packages "
"WHERE providename='" + requirement + "' AND packages.id=provides.id_package"; "WHERE providename='" + requirement + "' AND packages.id=provides.id_package";
if (flags != "") {
sql += " AND provideflags='" + to_string(intflags) + "' AND provideversion='" + version + "'";
}
i++; i++;
} }
a++; a++;
@ -287,7 +285,15 @@ json DistroqueryAPI::getProvidersForRequirement(string repository, string requir
provider["repository"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "repository"))); provider["repository"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "repository")));
provider["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "name"))); provider["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "name")));
provider["flags"] = rpmSenseFlagsToString(sqlite3_column_int(stmt,sqlite3_find_column_id(stmt, NULL, "provideflags"))); provider["flags"] = rpmSenseFlagsToString(sqlite3_column_int(stmt,sqlite3_find_column_id(stmt, NULL, "provideflags")));
provider["version"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "provideversion"))); string provideVersion = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "provideversion")));
provider["version"] = provideVersion;
if (flags != "") {
// Check that provide version matches with required flags and version
if (checkVersionWithFlags(version.c_str(), intflags, provideVersion.c_str()) != 1)
continue;
}
archs[arch].push_back(provider); archs[arch].push_back(provider);
} }
//j["providers"] = providers; //j["providers"] = providers;
@ -298,7 +304,10 @@ json DistroqueryAPI::getProvidersForRequirement(string repository, string requir
return j; return j;
} }
j["providers"] = {}; j["providers"] = {};
j["providers"]["archs"] = archs; if (onlyarch == "")
j["providers"]["archs"] = archs;
else
j["providers"] = archs[onlyarch];
return j; return j;
} }
@ -381,7 +390,7 @@ json DistroqueryAPI::getPackageSourceDetails(string repository, string package)
json DistroqueryAPI::getPackageDetails(string repository, string package, string arch) { json DistroqueryAPI::getPackageDetails(string repository, string package, string arch) {
json j; json j;
string sql; string sql;
sqlite3_stmt *stmt, *stmt2, *stmt3; sqlite3_stmt *stmt, *stmt2;
struct configTag* ct = findRepositoryByTag(repository.c_str()); struct configTag* ct = findRepositoryByTag(repository.c_str());
if (ct == NULL) { if (ct == NULL) {
@ -470,47 +479,15 @@ json DistroqueryAPI::getPackageDetails(string repository, string package, string
// Requires // Requires
sql = "SELECT * FROM requires WHERE requires.id_package=" + to_string(id); sql = "SELECT * FROM requires WHERE requires.id_package=" + to_string(id);
// " AND provided.id=requires.id_provided ORDER BY provided.name";
j["requires"] = json::array(); j["requires"] = json::array();
if (sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt2, NULL) == SQLITE_OK) { if (sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt2, NULL) == SQLITE_OK) {
while (sqlite3_step(stmt2) == SQLITE_ROW) { while (sqlite3_step(stmt2) == SQLITE_ROW) {
json require = {}; json require = {};
long id_provided = sqlite3_column_int(stmt2,sqlite3_find_column_id(stmt2, NULL, "id_provided"));
require["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, NULL, "requirename"))); require["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, NULL, "requirename")));
require["flags"] = rpmSenseFlagsToString(sqlite3_column_int(stmt2,sqlite3_find_column_id(stmt2, NULL, "requireflags"))); require["flags"] = rpmSenseFlagsToString(sqlite3_column_int(stmt2,sqlite3_find_column_id(stmt2, NULL, "requireflags")));
require["version"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, NULL, "requireversion"))); require["version"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, NULL, "requireversion")));
require["providers"] = json::array(); json jproviders = getProvidersForRequirement(repository, require["name"], require["flags"], require["version"], arch);
sql = "SELECT * FROM provides,packages WHERE id_provided=" + to_string(id_provided) + require["providers"] = jproviders["providers"];
" AND packages.id=provides.id_package";
if (sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt3, NULL) == SQLITE_OK) {
while (sqlite3_step(stmt3) == SQLITE_ROW) {
json provider = {};
provider["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt3,sqlite3_find_column_id(stmt3, NULL, "name")));
provider["repository"] = ct->tag;
require["providers"].push_back(provider);
}
sqlite3_finalize(stmt3);
}
// Resolve requires provided in upstream (alternative) repositories
int i = 0;
while (ct->repository[i]) {
if (ct->repository[i] != ct) {
string altprefix = string(ct->repository[i]->tag) + "_" + arch + ".";
sql = "SELECT * FROM " + altprefix + "provides," + altprefix +
"packages WHERE providename='" + string(require["name"]) +
"' AND " + altprefix + "packages.id=id_package";
if (sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt3, NULL) == SQLITE_OK) {
while (sqlite3_step(stmt3) == SQLITE_ROW) {
json provider = {};
provider["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt3,sqlite3_find_column_id(stmt3, NULL, "name")));
provider["repository"] = ct->repository[i]->tag;
require["providers"].push_back(provider);
}
sqlite3_finalize(stmt3);
}
}
i++;
}
j["requires"].push_back(require); j["requires"].push_back(require);
} }
sqlite3_finalize(stmt2); sqlite3_finalize(stmt2);

View File

@ -26,8 +26,8 @@
#include <sstream> #include <sstream>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include "config.h"
#include "distroquery_functions.hpp" #include "distroquery_functions.hpp"
#include "config.h"
using namespace std; using namespace std;
using json = nlohmann::ordered_json; using json = nlohmann::ordered_json;
@ -43,7 +43,8 @@ class DistroqueryAPI {
void sendErrorResponse(string message); void sendErrorResponse(string message);
json getRepositoryPackages(string repository, int per_page, int page, string query); json getRepositoryPackages(string repository, int per_page, int page, string query);
json getPackageSourceDetailsById(configTag* ct, long id); json getPackageSourceDetailsById(configTag* ct, long id);
json getProvidersForRequirement(string repository, string requirement, string flags, string version); json getProvidersForRequirement(string repository, string requirement, string flags,
string version, string onlyarch="");
json getPackageSourceDetails(string repository, string package); json getPackageSourceDetails(string repository, string package);
json getBuiltPackagesFromSourceID(configTag* ct, long id); json getBuiltPackagesFromSourceID(configTag* ct, long id);
json getPackageDetails(string repository, string package, string arch); json getPackageDetails(string repository, string package, string arch);

View File

@ -23,6 +23,7 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <sqlite3.h> #include <sqlite3.h>
#include <stdint.h>
using namespace std; using namespace std;
@ -51,5 +52,6 @@ extern "C" int get_favicon_from_url(const char* url,char *buf,int bufsize);
extern "C" void backtraceHandler(int sig); extern "C" void backtraceHandler(int sig);
extern "C" struct configTag* findRepositoryByTag(const char *tag); extern "C" struct configTag* findRepositoryByTag(const char *tag);
extern "C" struct configTag* read_configuration(const char *confFile); extern "C" struct configTag* read_configuration(const char *confFile);
extern "C" unsigned int checkVersionWithFlags(const char* cmp1, const uint32_t flags, const char* cmp2);
#endif // __DISTROQUERY_FUNCTIONS_H #endif // __DISTROQUERY_FUNCTIONS_H

View File

@ -37,7 +37,7 @@
#define HEADERS_BUFFER_SIZE 2000000 #define HEADERS_BUFFER_SIZE 2000000
unsigned int checkVersionWithFlags(const char* cmp1, const uint_32 flags, const char* cmp2); unsigned int checkVersionWithFlags(const char* cmp1, const uint32_t flags, const char* cmp2);
void rpminit(void); void rpminit(void);

View File

@ -58,7 +58,7 @@ void rpmEVRsplit(const char* ver, struct EVR_s *evr) {
if (evr->v == NULL) evr->v = evr->data; if (evr->v == NULL) evr->v = evr->data;
} }
unsigned int checkVersionWithFlags(const char* cmp1, uint_32 flags, const char* cmp2) { unsigned int checkVersionWithFlags(const char* cmp1, const uint32_t flags, const char* cmp2) {
int vercmp = 0; int vercmp = 0;
struct EVR_s evr1, evr2; struct EVR_s evr1, evr2;