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/" +
|
||||
string(j["name"]) + "-" + string(j["version"]) + "-" + string(j["release"]) + ".src.rpm";
|
||||
// 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 {
|
||||
j["error"] = "no results from query '" + sql + "'";
|
||||
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;
|
||||
return j;
|
||||
}
|
||||
attachCtDatabases(ct, db, arch);
|
||||
|
||||
sql = "SELECT * FROM packages WHERE name = '" + package + "'";
|
||||
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
|
||||
sql = "SELECT * FROM requires,provided WHERE requires.id_package=" + to_string(id) +
|
||||
" AND provided.id=requires.id_provided ORDER BY provided.name";
|
||||
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, "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["version"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, NULL, "requireversion")));
|
||||
require["providers"] = json::array();
|
||||
@ -330,11 +332,31 @@ json DistroqueryAPI::getPackageDetails(string repository, string package, string
|
||||
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["altrepository"] = sqlite3_column_int(stmt3,sqlite3_find_column_id(stmt3, NULL, "altrepostory"));
|
||||
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);
|
||||
}
|
||||
sqlite3_finalize(stmt2);
|
||||
@ -380,10 +402,11 @@ void DistroqueryAPI::getApiResponse(string path_info) {
|
||||
if (path_split.size() < 3 || path_split.size() > 4)
|
||||
sendErrorResponse("expected 3 or 4 arguments for " + path_split[0]);
|
||||
json details;
|
||||
string package = urlDecode(path_split[2]);
|
||||
if (path_split.size() == 3) {
|
||||
details = getPackageSourceDetails(path_split[1], path_split[2]);
|
||||
details = getPackageSourceDetails(path_split[1], package);
|
||||
} else {
|
||||
details = getPackageDetails(path_split[1], path_split[2], path_split[3]);
|
||||
details = getPackageDetails(path_split[1], package, path_split[3]);
|
||||
}
|
||||
cout << details.dump();
|
||||
} else {
|
||||
|
@ -323,10 +323,10 @@ long generateSQLite_add_changelog(sqlite3 *db, struct changeLog* firstchangelog,
|
||||
"id_package INTEGER, obsoletename STRING, obsoleteflags INTEGER, obsoleteversion STRING"
|
||||
|
||||
#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, "\
|
||||
"id_package INTEGER, id_provided STRING, requireflags INTEGER, requireversion STRING"
|
||||
"id_package INTEGER, id_provided STRING, requirename STRING, requireflags INTEGER, requireversion STRING"
|
||||
|
||||
int
|
||||
generateSQLite_packages(struct configTag *ct, sqlite3 *db, int arch) {
|
||||
@ -388,7 +388,7 @@ generateSQLite_packages(struct configTag *ct, sqlite3 *db, int arch) {
|
||||
|
||||
/* provides */
|
||||
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->provided[i]->id,
|
||||
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)) {
|
||||
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) {
|
||||
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
|
||||
return 3;
|
||||
@ -407,7 +408,7 @@ generateSQLite_packages(struct configTag *ct, sqlite3 *db, int arch) {
|
||||
/* requires */
|
||||
for (i = 0; i < currpackage->requirecount; i++) {
|
||||
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->require[i]->resolved->id,
|
||||
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)) {
|
||||
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) {
|
||||
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
|
||||
return 3;
|
||||
|
@ -178,49 +178,6 @@ char* resolveFilePath(sqlite3 *db, long id, char *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) {
|
||||
char sql[PATH_MAX];
|
||||
char *errmsg;
|
||||
@ -838,7 +795,7 @@ void printSpecialQueryResponse() {
|
||||
if (!ct) return;
|
||||
db = openRepositoryDatabase(ct);
|
||||
if (!db) return;
|
||||
attachCtDatabases(ct, db, NULL);
|
||||
attachCtDatabases(ct, db);
|
||||
|
||||
if (ct->arch[0]) {
|
||||
dbb = openRepositoryDatabase(ct);
|
||||
|
@ -67,6 +67,49 @@ sqlite3* openRepositoryDatabase(struct configTag* ct, string arch, string append
|
||||
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) {
|
||||
const char* colname;
|
||||
int id = 0;
|
||||
@ -83,3 +126,34 @@ int sqlite3_find_column_id(sqlite3_stmt *stmt, const char* table, const char* na
|
||||
}
|
||||
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);
|
||||
vector<string> split(string str, string token);
|
||||
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);
|
||||
string urlDecode(string str);
|
||||
string replaceAll(string str, const string& from, const string& to);
|
||||
|
||||
#define HDSIZE 16
|
||||
#define SSSIZE 24
|
||||
|
Loading…
Reference in New Issue
Block a user