diff --git a/.vscode/settings.json b/.vscode/settings.json index bc543d2..79e1088 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,6 +4,7 @@ "iostream": "cpp", "vector": "cpp", "string": "cpp", - "format": "cpp" + "format": "cpp", + "string.h": "c" } } \ No newline at end of file diff --git a/src/DistroqueryAPI.cpp b/src/DistroqueryAPI.cpp index 05b1d9a..89f41b0 100644 --- a/src/DistroqueryAPI.cpp +++ b/src/DistroqueryAPI.cpp @@ -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(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "repository"))); provider["name"] = reinterpret_cast(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(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "provideversion"))); + string provideVersion = reinterpret_cast(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(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(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(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(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); diff --git a/src/DistroqueryAPI.hpp b/src/DistroqueryAPI.hpp index 41d146f..b18ee30 100644 --- a/src/DistroqueryAPI.hpp +++ b/src/DistroqueryAPI.hpp @@ -26,8 +26,8 @@ #include #include -#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); diff --git a/src/include/distroquery_functions.hpp b/src/include/distroquery_functions.hpp index f9f0a5f..68de5b8 100644 --- a/src/include/distroquery_functions.hpp +++ b/src/include/distroquery_functions.hpp @@ -23,6 +23,7 @@ #include #include #include +#include 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 diff --git a/src/include/rpmfunctions.h b/src/include/rpmfunctions.h index 4f8b59c..5aed840 100644 --- a/src/include/rpmfunctions.h +++ b/src/include/rpmfunctions.h @@ -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); diff --git a/src/rpmfunctions.c b/src/rpmfunctions.c index 3c5c345..f8156e0 100644 --- a/src/rpmfunctions.c +++ b/src/rpmfunctions.c @@ -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;