DistroqueryAPI: getRepositoryPackages: added pagination from query string support
This commit is contained in:
parent
aa283cd60c
commit
f1fd8ef275
@ -104,11 +104,26 @@ json DistroqueryAPI::getPackageSourceDetailsById(configTag* ct, long id) {
|
||||
return j;
|
||||
}
|
||||
|
||||
json DistroqueryAPI::getRepositoryPackages(string repository) {
|
||||
json DistroqueryAPI::getRepositoryPackages(string repository, int per_page, int page) {
|
||||
json j;
|
||||
string sql;
|
||||
sqlite3_stmt *stmt;
|
||||
|
||||
j["query"] = {};
|
||||
j["query"]["repository"] = repository;
|
||||
j["query"]["per_page"] = per_page;
|
||||
j["query"]["page"] = page;
|
||||
|
||||
if (per_page < 1) {
|
||||
j["error"] = "'per_page' query var must be >= 1";
|
||||
return j;
|
||||
}
|
||||
|
||||
if (page < 1) {
|
||||
j["error"] = "'page' query var must be >= 1";
|
||||
return j;
|
||||
}
|
||||
|
||||
struct configTag* ct = findRepositoryByTag(repository.c_str());
|
||||
if (ct == NULL) {
|
||||
j["error"] = "repository with tag '" + repository + "' does not exist";
|
||||
@ -121,16 +136,29 @@ json DistroqueryAPI::getRepositoryPackages(string repository) {
|
||||
return j;
|
||||
}
|
||||
|
||||
sql = "SELECT * FROM sources ORDER BY name COLLATE NOCASE ASC";
|
||||
sql = "SELECT COUNT(*) OVER() AS total_count,* FROM sources ORDER BY name COLLATE NOCASE ASC"
|
||||
" LIMIT " + to_string(per_page) +
|
||||
" OFFSET " + to_string(per_page * (page -1));
|
||||
if (sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt, NULL) == SQLITE_OK) {
|
||||
j = json::array();
|
||||
json packages = json::array();
|
||||
long count = 0;
|
||||
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
count++;
|
||||
// Set total packages count
|
||||
if (j["query"].find("total") == j["query"].end()) {
|
||||
long total_count = sqlite3_column_int(stmt,sqlite3_find_column_id(stmt, NULL, "total_count"));
|
||||
j["query"]["total"] = total_count;
|
||||
j["query"]["pages"] = total_count / per_page + 1;
|
||||
j["query"]["from"] = per_page * (page - 1) + 1;
|
||||
}
|
||||
json package;
|
||||
package["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "name")));
|
||||
package["summary"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "summary")));
|
||||
j.push_back(package);
|
||||
packages.push_back(package);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
j["query"]["to"] = per_page * (page - 1) + count;
|
||||
j["packages"] = packages;
|
||||
} else {
|
||||
j["error"] = "error preparing query '" + sql + "'";
|
||||
return j;
|
||||
@ -300,7 +328,7 @@ json DistroqueryAPI::getPackageDetails(string repository, string package, string
|
||||
}
|
||||
|
||||
// Provides
|
||||
sql = "SELECT * FROM provides,provided WHERE provides.id_package=" + to_string(id) +
|
||||
sql = "SELECT * FROM provides,provided WHERE provides.id_package=" + to_string(id) +
|
||||
" AND provided.id=provides.id_provided ORDER BY provided.name";
|
||||
j["provides"] = json::array();
|
||||
if (sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt2, NULL) == SQLITE_OK) {
|
||||
@ -375,15 +403,31 @@ void DistroqueryAPI::getApiResponse(string path_info) {
|
||||
cout << "Content-Type: application/json;charset=utf-8\n\n" << endl;
|
||||
|
||||
string path, query_string;
|
||||
std::vector<std::string> path_split;
|
||||
vector<string> path_split;
|
||||
map<string,string> query_vars;
|
||||
|
||||
std::vector<std::string> v = split(path_info, "?");
|
||||
vector<string> v = split(path_info, "?");
|
||||
|
||||
if (v.size() > 0) {
|
||||
path = v[0];
|
||||
path_split = split(path, "/");
|
||||
}
|
||||
if (v.size() > 1) query_string = v[1];
|
||||
|
||||
if (v.size() > 1) {
|
||||
query_string = v[1];
|
||||
vector<string> query_split = split(query_string, "&");
|
||||
|
||||
for (auto q:query_split) {
|
||||
vector<string> arg_split = split(q, "=");
|
||||
if (arg_split.size() == 1) {
|
||||
query_vars[arg_split[0]] = "";
|
||||
} else if (arg_split.size() == 2) {
|
||||
query_vars[arg_split[0]] = arg_split[1];
|
||||
} else {
|
||||
cerr << "Error parsing query_string entry '" << q << "'" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (path_split.size() > 0 ) {
|
||||
if (path_split[0] == "repositories") {
|
||||
@ -395,7 +439,24 @@ void DistroqueryAPI::getApiResponse(string path_info) {
|
||||
// API service: repository
|
||||
if (path_split.size() != 2)
|
||||
sendErrorResponse("expected exactly 2 arguments for " + path_split[0]);
|
||||
auto packages = getRepositoryPackages(path_split[1]);
|
||||
// Pagination
|
||||
unsigned int per_page = 100;
|
||||
unsigned int page = 1;
|
||||
if (query_vars.find("per_page") != query_vars.end()) {
|
||||
try {
|
||||
per_page = atoi(query_vars["per_page"].c_str());
|
||||
} catch (exception const & e) {
|
||||
cerr << "Error converting '" << query_vars["per_page"] << " to int: " << e.what() << endl;
|
||||
}
|
||||
}
|
||||
if (query_vars.find("page") != query_vars.end()) {
|
||||
try {
|
||||
page = atoi(query_vars["page"].c_str());
|
||||
} catch (exception const & e) {
|
||||
cerr << "Error converting '" << query_vars["page"] << " to int: " << e.what() << endl;
|
||||
}
|
||||
}
|
||||
auto packages = getRepositoryPackages(path_split[1], per_page, page);
|
||||
cout << packages.dump();
|
||||
} else if (path_split[0] == "package") {
|
||||
// API service: package
|
||||
|
@ -41,7 +41,7 @@ class DistroqueryAPI {
|
||||
configTag *config;
|
||||
json configToJsonRepositories();
|
||||
void sendErrorResponse(string message);
|
||||
json getRepositoryPackages(string repository);
|
||||
json getRepositoryPackages(string repository, int per_page, int page);
|
||||
json getPackageSourceDetailsById(configTag* ct, long id);
|
||||
json getPackageSourceDetails(string repository, string package);
|
||||
json getBuiltPackagesFromSourceID(configTag* ct, long id);
|
||||
|
Loading…
Reference in New Issue
Block a user