backend-sqlite3,DistroqueryAPI: improve requirements management in sqlite db and distroquery API
This commit is contained in:
parent
7ae467a639
commit
aa283cd60c
@ -95,7 +95,8 @@ json DistroqueryAPI::getPackageSourceDetailsById(configTag* ct, long id) {
|
|||||||
j["download_url"] = string(ct->download_prefix) + ct->download_dir + "/SRPMS.base/" +
|
j["download_url"] = string(ct->download_prefix) + ct->download_dir + "/SRPMS.base/" +
|
||||||
string(j["name"]) + "-" + string(j["version"]) + "-" + string(j["release"]) + ".src.rpm";
|
string(j["name"]) + "-" + string(j["version"]) + "-" + string(j["release"]) + ".src.rpm";
|
||||||
// Source URL
|
// Source URL
|
||||||
j["source_url"] = "https://src.openmamba.org/rpms/" + string(j["name"]);
|
string name = string(j["name"]);
|
||||||
|
j["source_url"] = "https://src.openmamba.org/rpms/" + replaceAll(name, "+", "Plus");
|
||||||
} else {
|
} else {
|
||||||
j["error"] = "no results from query '" + sql + "'";
|
j["error"] = "no results from query '" + sql + "'";
|
||||||
return j;
|
return j;
|
||||||
@ -239,6 +240,7 @@ json DistroqueryAPI::getPackageDetails(string repository, string package, string
|
|||||||
j["error"] = "error opening database for repository " + repository + " and arch " + arch;
|
j["error"] = "error opening database for repository " + repository + " and arch " + arch;
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
attachCtDatabases(ct, db, arch);
|
||||||
|
|
||||||
sql = "SELECT * FROM packages WHERE name = '" + package + "'";
|
sql = "SELECT * FROM packages WHERE name = '" + package + "'";
|
||||||
if (sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt, NULL) == SQLITE_OK) {
|
if (sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt, NULL) == SQLITE_OK) {
|
||||||
@ -313,14 +315,14 @@ json DistroqueryAPI::getPackageDetails(string repository, string package, string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Requires
|
// Requires
|
||||||
sql = "SELECT * FROM requires,provided 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";
|
// " 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"));
|
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, "name")));
|
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();
|
require["providers"] = json::array();
|
||||||
@ -330,11 +332,31 @@ json DistroqueryAPI::getPackageDetails(string repository, string package, string
|
|||||||
while (sqlite3_step(stmt3) == SQLITE_ROW) {
|
while (sqlite3_step(stmt3) == SQLITE_ROW) {
|
||||||
json provider = {};
|
json provider = {};
|
||||||
provider["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt3,sqlite3_find_column_id(stmt3, NULL, "name")));
|
provider["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt3,sqlite3_find_column_id(stmt3, NULL, "name")));
|
||||||
provider["altrepository"] = sqlite3_column_int(stmt3,sqlite3_find_column_id(stmt3, NULL, "altrepostory"));
|
provider["repository"] = ct->tag;
|
||||||
require["providers"].push_back(provider);
|
require["providers"].push_back(provider);
|
||||||
}
|
}
|
||||||
sqlite3_finalize(stmt3);
|
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);
|
||||||
@ -380,10 +402,11 @@ void DistroqueryAPI::getApiResponse(string path_info) {
|
|||||||
if (path_split.size() < 3 || path_split.size() > 4)
|
if (path_split.size() < 3 || path_split.size() > 4)
|
||||||
sendErrorResponse("expected 3 or 4 arguments for " + path_split[0]);
|
sendErrorResponse("expected 3 or 4 arguments for " + path_split[0]);
|
||||||
json details;
|
json details;
|
||||||
|
string package = urlDecode(path_split[2]);
|
||||||
if (path_split.size() == 3) {
|
if (path_split.size() == 3) {
|
||||||
details = getPackageSourceDetails(path_split[1], path_split[2]);
|
details = getPackageSourceDetails(path_split[1], package);
|
||||||
} else {
|
} else {
|
||||||
details = getPackageDetails(path_split[1], path_split[2], path_split[3]);
|
details = getPackageDetails(path_split[1], package, path_split[3]);
|
||||||
}
|
}
|
||||||
cout << details.dump();
|
cout << details.dump();
|
||||||
} else {
|
} else {
|
||||||
|
@ -323,10 +323,10 @@ long generateSQLite_add_changelog(sqlite3 *db, struct changeLog* firstchangelog,
|
|||||||
"id_package INTEGER, obsoletename STRING, obsoleteflags INTEGER, obsoleteversion STRING"
|
"id_package INTEGER, obsoletename STRING, obsoleteflags INTEGER, obsoleteversion STRING"
|
||||||
|
|
||||||
#define SQLITE_TABLE_provides "id INTEGER PRIMARY KEY, "\
|
#define SQLITE_TABLE_provides "id INTEGER PRIMARY KEY, "\
|
||||||
"id_package INTEGER, id_provided INTEGER, provideflags INTEGER, provideversion STRING"
|
"id_package INTEGER, id_provided INTEGER, providename STRING, provideflags INTEGER, provideversion STRING"
|
||||||
|
|
||||||
#define SQLITE_TABLE_requires "id INTEGER PRIMARY KEY, "\
|
#define SQLITE_TABLE_requires "id INTEGER PRIMARY KEY, "\
|
||||||
"id_package INTEGER, id_provided STRING, requireflags INTEGER, requireversion STRING"
|
"id_package INTEGER, id_provided STRING, requirename STRING, requireflags INTEGER, requireversion STRING"
|
||||||
|
|
||||||
int
|
int
|
||||||
generateSQLite_packages(struct configTag *ct, sqlite3 *db, int arch) {
|
generateSQLite_packages(struct configTag *ct, sqlite3 *db, int arch) {
|
||||||
@ -388,7 +388,7 @@ generateSQLite_packages(struct configTag *ct, sqlite3 *db, int arch) {
|
|||||||
|
|
||||||
/* provides */
|
/* provides */
|
||||||
for (i = 0; i < currpackage->providecount; i++) {
|
for (i = 0; i < currpackage->providecount; i++) {
|
||||||
snprintf(sqlite3_query, PATH_MAX, "INSERT INTO provides VALUES(NULL,%ld,%ld,%d,?);",
|
snprintf(sqlite3_query, PATH_MAX, "INSERT INTO provides VALUES(NULL,%ld,%ld,?,%d,?);",
|
||||||
currpackage->id,
|
currpackage->id,
|
||||||
currpackage->provided[i]->id,
|
currpackage->provided[i]->id,
|
||||||
currpackage->provideflags[i]);
|
currpackage->provideflags[i]);
|
||||||
@ -396,7 +396,8 @@ generateSQLite_packages(struct configTag *ct, sqlite3 *db, int arch) {
|
|||||||
if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
|
if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
|
||||||
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
|
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
|
||||||
}
|
}
|
||||||
sqlite3_bind_text(stmt, 1, currpackage->provideversion[i], -1, SQLITE_STATIC);
|
sqlite3_bind_text(stmt, 1, currpackage->providename[i], -1, SQLITE_STATIC);
|
||||||
|
sqlite3_bind_text(stmt, 2, currpackage->provideversion[i], -1, SQLITE_STATIC);
|
||||||
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
||||||
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
|
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
|
||||||
return 3;
|
return 3;
|
||||||
@ -407,7 +408,7 @@ generateSQLite_packages(struct configTag *ct, sqlite3 *db, int arch) {
|
|||||||
/* requires */
|
/* requires */
|
||||||
for (i = 0; i < currpackage->requirecount; i++) {
|
for (i = 0; i < currpackage->requirecount; i++) {
|
||||||
if (currpackage->require[i]->resolved) {
|
if (currpackage->require[i]->resolved) {
|
||||||
snprintf(sqlite3_query, PATH_MAX, "INSERT INTO requires VALUES(NULL,%ld,%ld,%ld,?);",
|
snprintf(sqlite3_query, PATH_MAX, "INSERT INTO requires VALUES(NULL,%ld,%ld,?,%ld,?);",
|
||||||
currpackage->id,
|
currpackage->id,
|
||||||
currpackage->require[i]->resolved->id,
|
currpackage->require[i]->resolved->id,
|
||||||
currpackage->require[i]->flags);
|
currpackage->require[i]->flags);
|
||||||
@ -415,7 +416,8 @@ generateSQLite_packages(struct configTag *ct, sqlite3 *db, int arch) {
|
|||||||
if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
|
if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
|
||||||
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
|
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
|
||||||
}
|
}
|
||||||
sqlite3_bind_text(stmt, 1, currpackage->require[i]->version, -1, SQLITE_STATIC);
|
sqlite3_bind_text(stmt, 1, currpackage->require[i]->name, -1, SQLITE_STATIC);
|
||||||
|
sqlite3_bind_text(stmt, 2, currpackage->require[i]->version, -1, SQLITE_STATIC);
|
||||||
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
||||||
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
|
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
|
||||||
return 3;
|
return 3;
|
||||||
|
@ -178,49 +178,6 @@ char* resolveFilePath(sqlite3 *db, long id, char *buffer) {
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void attachCtDatabases(struct configTag* ct, sqlite3 *db, char* arch) {
|
|
||||||
string dbname;
|
|
||||||
string sql;
|
|
||||||
int i=0;
|
|
||||||
char *errmsg;
|
|
||||||
|
|
||||||
while (ct->repository[i]) {
|
|
||||||
if (arch) {
|
|
||||||
dbname = string(ct->repository[i]->repository_dir) + ct->repository[i]->tag + "-" + arch + ".db";
|
|
||||||
sql = "ATTACH DATABASE '" + dbname + "' as '" + ct->repository[i]->tag + "_" + arch + "'";
|
|
||||||
if (sqlite3_exec(db, sql.c_str(), NULL, NULL, &errmsg)) {
|
|
||||||
cerr << "ERROR: unable to exec statement for " << sql << ": " << errmsg << endl;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dbname = string(ct->repository[i]->repository_dir) + ct->repository[i]->tag + "-sources.db";
|
|
||||||
sql = "ATTACH DATABASE '" + dbname + "' as '" + ct->repository[i]->tag + "_sources'";
|
|
||||||
if (sqlite3_exec(db, sql.c_str(), NULL, NULL, &errmsg)) {
|
|
||||||
cerr << "ERROR: unable to exec statement for " << sql << ": " << errmsg << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void attachRepositoryDatabases(struct configTag* ct, sqlite3 *db, char* arch, int source) {
|
|
||||||
string dbname;
|
|
||||||
string sql;
|
|
||||||
char *errmsg;
|
|
||||||
|
|
||||||
dbname = string(ct->repository_dir) + ct->tag + "-" + arch + ".db";
|
|
||||||
sql = "ATTACH DATABASE '" + dbname + "' as '" + ct->tag + "_" + arch;
|
|
||||||
if (sqlite3_exec(db, sql.c_str(), NULL, NULL, &errmsg)) {
|
|
||||||
cerr << "ERROR: unable to exec statement for " << sql << ": " << errmsg << endl;
|
|
||||||
}
|
|
||||||
if (source) {
|
|
||||||
dbname = string(ct->repository_dir) + ct->tag + "-sources.db";
|
|
||||||
sql = "ATTACH DATABASE '" + dbname + "' as '" + ct->tag + "_sources'";
|
|
||||||
if (sqlite3_exec(db, sql.c_str(), NULL, NULL, &errmsg)) {
|
|
||||||
cerr << "ERROR: unable to exec statement for " << sql << ":: " << errmsg << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void detachRepositoryDatabases(struct configTag* ct, sqlite3 *db, char* arch, int source) {
|
void detachRepositoryDatabases(struct configTag* ct, sqlite3 *db, char* arch, int source) {
|
||||||
char sql[PATH_MAX];
|
char sql[PATH_MAX];
|
||||||
char *errmsg;
|
char *errmsg;
|
||||||
@ -838,7 +795,7 @@ void printSpecialQueryResponse() {
|
|||||||
if (!ct) return;
|
if (!ct) return;
|
||||||
db = openRepositoryDatabase(ct);
|
db = openRepositoryDatabase(ct);
|
||||||
if (!db) return;
|
if (!db) return;
|
||||||
attachCtDatabases(ct, db, NULL);
|
attachCtDatabases(ct, db);
|
||||||
|
|
||||||
if (ct->arch[0]) {
|
if (ct->arch[0]) {
|
||||||
dbb = openRepositoryDatabase(ct);
|
dbb = openRepositoryDatabase(ct);
|
||||||
|
@ -67,6 +67,49 @@ sqlite3* openRepositoryDatabase(struct configTag* ct, string arch, string append
|
|||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void attachCtDatabases(struct configTag* ct, sqlite3 *db, string arch) {
|
||||||
|
string dbname;
|
||||||
|
string sql;
|
||||||
|
int i=0;
|
||||||
|
char *errmsg;
|
||||||
|
|
||||||
|
while (ct->repository[i]) {
|
||||||
|
if (arch != "" && arch != "sources") {
|
||||||
|
dbname = string(ct->repository[i]->repository_dir) + ct->repository[i]->tag + "-" + arch + ".db";
|
||||||
|
sql = "ATTACH DATABASE '" + dbname + "' as '" + ct->repository[i]->tag + "_" + arch + "'";
|
||||||
|
if (sqlite3_exec(db, sql.c_str(), NULL, NULL, &errmsg)) {
|
||||||
|
cerr << "ERROR: unable to exec statement for " << sql << ": " << errmsg << endl;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dbname = string(ct->repository[i]->repository_dir) + ct->repository[i]->tag + "-sources.db";
|
||||||
|
sql = "ATTACH DATABASE '" + dbname + "' as '" + ct->repository[i]->tag + "_sources'";
|
||||||
|
if (sqlite3_exec(db, sql.c_str(), NULL, NULL, &errmsg)) {
|
||||||
|
cerr << "ERROR: unable to exec statement for " << sql << ": " << errmsg << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void attachRepositoryDatabases(struct configTag* ct, sqlite3 *db, string arch, int source) {
|
||||||
|
string dbname;
|
||||||
|
string sql;
|
||||||
|
char *errmsg;
|
||||||
|
|
||||||
|
dbname = string(ct->repository_dir) + ct->tag + "-" + arch + ".db";
|
||||||
|
sql = "ATTACH DATABASE '" + dbname + "' as '" + ct->tag + "_" + arch;
|
||||||
|
if (sqlite3_exec(db, sql.c_str(), NULL, NULL, &errmsg)) {
|
||||||
|
cerr << "ERROR: unable to exec statement for " << sql << ": " << errmsg << endl;
|
||||||
|
}
|
||||||
|
if (source) {
|
||||||
|
dbname = string(ct->repository_dir) + ct->tag + "-sources.db";
|
||||||
|
sql = "ATTACH DATABASE '" + dbname + "' as '" + ct->tag + "_sources'";
|
||||||
|
if (sqlite3_exec(db, sql.c_str(), NULL, NULL, &errmsg)) {
|
||||||
|
cerr << "ERROR: unable to exec statement for " << sql << ":: " << errmsg << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int sqlite3_find_column_id(sqlite3_stmt *stmt, const char* table, const char* name) {
|
int sqlite3_find_column_id(sqlite3_stmt *stmt, const char* table, const char* name) {
|
||||||
const char* colname;
|
const char* colname;
|
||||||
int id = 0;
|
int id = 0;
|
||||||
@ -83,3 +126,34 @@ int sqlite3_find_column_id(sqlite3_stmt *stmt, const char* table, const char* na
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string urlDecode(string str) {
|
||||||
|
string ret;
|
||||||
|
char ch;
|
||||||
|
int i, len = str.length();
|
||||||
|
unsigned int ii;
|
||||||
|
|
||||||
|
for (i=0; i < len; i++){
|
||||||
|
if (str[i] != '%') {
|
||||||
|
if (str[i] == '+')
|
||||||
|
ret += ' ';
|
||||||
|
else
|
||||||
|
ret += str[i];
|
||||||
|
} else {
|
||||||
|
sscanf(str.substr(i + 1, 2).c_str(), "%x", &ii);
|
||||||
|
ch = static_cast<char>(ii);
|
||||||
|
ret += ch;
|
||||||
|
i = i + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
string replaceAll(string str, const string& from, const string& to) {
|
||||||
|
size_t start_pos = 0;
|
||||||
|
while((start_pos = str.find(from, start_pos)) != string::npos) {
|
||||||
|
str.replace(start_pos, from.length(), to);
|
||||||
|
start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
@ -29,7 +29,11 @@ using namespace std;
|
|||||||
string rpmSenseFlagsToString(int flags);
|
string rpmSenseFlagsToString(int flags);
|
||||||
vector<string> split(string str, string token);
|
vector<string> split(string str, string token);
|
||||||
sqlite3* openRepositoryDatabase(struct configTag* ct, string arch = "", string append = "");
|
sqlite3* openRepositoryDatabase(struct configTag* ct, string arch = "", string append = "");
|
||||||
|
void attachCtDatabases(struct configTag* ct, sqlite3 *db, string arch = "");
|
||||||
|
void attachRepositoryDatabases(struct configTag* ct, sqlite3 *db, string arch, int source);
|
||||||
int sqlite3_find_column_id(sqlite3_stmt *stmt, const char* table, const char* name);
|
int sqlite3_find_column_id(sqlite3_stmt *stmt, const char* table, const char* name);
|
||||||
|
string urlDecode(string str);
|
||||||
|
string replaceAll(string str, const string& from, const string& to);
|
||||||
|
|
||||||
#define HDSIZE 16
|
#define HDSIZE 16
|
||||||
#define SSSIZE 24
|
#define SSSIZE 24
|
||||||
|
Loading…
Reference in New Issue
Block a user