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",
"vector": "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;
}
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;
sqlite3_stmt *stmt;
@ -255,6 +255,7 @@ json DistroqueryAPI::getProvidersForRequirement(string repository, string requir
int a = 0;
for (auto arch: ct->arch) {
if (arch == NULL) break;
if (onlyarch != "" && onlyarch != arch) continue;
attachCtDatabases(ct, db, arch);
int i = 0;
while (ct->repository[i]) {
@ -264,9 +265,6 @@ json DistroqueryAPI::getProvidersForRequirement(string repository, string requir
"FROM '" + string(ct->repository[i]->tag) + "_" + arch + "'.provides,'" +
string(ct->repository[i]->tag) + "_" + arch + "'.packages "
"WHERE providename='" + requirement + "' AND packages.id=provides.id_package";
if (flags != "") {
sql += " AND provideflags='" + to_string(intflags) + "' AND provideversion='" + version + "'";
}
i++;
}
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["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["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);
}
//j["providers"] = providers;
@ -298,7 +304,10 @@ json DistroqueryAPI::getProvidersForRequirement(string repository, string requir
return j;
}
j["providers"] = {};
j["providers"]["archs"] = archs;
if (onlyarch == "")
j["providers"]["archs"] = archs;
else
j["providers"] = archs[onlyarch];
return j;
}
@ -381,7 +390,7 @@ json DistroqueryAPI::getPackageSourceDetails(string repository, string package)
json DistroqueryAPI::getPackageDetails(string repository, string package, string arch) {
json j;
string sql;
sqlite3_stmt *stmt, *stmt2, *stmt3;
sqlite3_stmt *stmt, *stmt2;
struct configTag* ct = findRepositoryByTag(repository.c_str());
if (ct == NULL) {
@ -470,47 +479,15 @@ json DistroqueryAPI::getPackageDetails(string repository, string package, string
// Requires
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();
if (sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt2, NULL) == SQLITE_OK) {
while (sqlite3_step(stmt2) == SQLITE_ROW) {
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["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["providers"] = json::array();
sql = "SELECT * FROM provides,packages WHERE id_provided=" + to_string(id_provided) +
" 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++;
}
json jproviders = getProvidersForRequirement(repository, require["name"], require["flags"], require["version"], arch);
require["providers"] = jproviders["providers"];
j["requires"].push_back(require);
}
sqlite3_finalize(stmt2);

View File

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

View File

@ -23,6 +23,7 @@
#include <iostream>
#include <vector>
#include <sqlite3.h>
#include <stdint.h>
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" struct configTag* findRepositoryByTag(const char *tag);
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

View File

@ -37,7 +37,7 @@
#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);

View File

@ -58,7 +58,7 @@ void rpmEVRsplit(const char* ver, struct EVR_s *evr) {
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;
struct EVR_s evr1, evr2;