DistroqueryAPI: first part of implementation of /package API service
This commit is contained in:
parent
758da30631
commit
ee5803e622
@ -67,6 +67,7 @@ target_compile_options(distromatic PUBLIC -O2 -g -Wall -std=gnu11 -pedantic ${RP
|
|||||||
# -fno-toplevel-reorder
|
# -fno-toplevel-reorder
|
||||||
|
|
||||||
add_executable(distroquery
|
add_executable(distroquery
|
||||||
|
distroquery_functions.cpp
|
||||||
DistroqueryAPI.cpp
|
DistroqueryAPI.cpp
|
||||||
distroquery.cpp
|
distroquery.cpp
|
||||||
functions.c
|
functions.c
|
||||||
|
@ -18,29 +18,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "DistroqueryAPI.hpp"
|
#include "DistroqueryAPI.hpp"
|
||||||
|
#include <functions.h>
|
||||||
vector<string> split(string str, string token) {
|
|
||||||
vector<string>result;
|
|
||||||
while(str.size()){
|
|
||||||
auto index = str.find(token);
|
|
||||||
if(index!=string::npos){
|
|
||||||
result.push_back(str.substr(0,index));
|
|
||||||
str = str.substr(index+token.size());
|
|
||||||
if(str.size()==0)result.push_back(str);
|
|
||||||
}else{
|
|
||||||
result.push_back(str);
|
|
||||||
str = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
DistroqueryAPI::DistroqueryAPI(configTag* conf): config(conf) {
|
DistroqueryAPI::DistroqueryAPI(configTag* conf): config(conf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
json DistroqueryAPI::configToJsonRepositories() {
|
json DistroqueryAPI::configToJsonRepositories() {
|
||||||
json j;
|
json j;
|
||||||
j["repositories"] = {};
|
|
||||||
struct configTag *ct = config;
|
struct configTag *ct = config;
|
||||||
while (ct) {
|
while (ct) {
|
||||||
json archs = {};
|
json archs = {};
|
||||||
@ -59,12 +43,141 @@ json DistroqueryAPI::configToJsonRepositories() {
|
|||||||
{ "description", ct->description },
|
{ "description", ct->description },
|
||||||
{ "parents", parents }
|
{ "parents", parents }
|
||||||
};
|
};
|
||||||
j["repositories"].push_back(repository);
|
j.push_back(repository);
|
||||||
ct = ct->next;
|
ct = ct->next;
|
||||||
}
|
}
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DistroqueryAPI::sendErrorResponse(string message) {
|
||||||
|
json j;
|
||||||
|
j["error"] = message;
|
||||||
|
cout << j.dump();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
json DistroqueryAPI::getPackageSourceDetailsById(string repository, long id) {
|
||||||
|
json j;
|
||||||
|
string sql;
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
|
struct configTag* ct = findRepositoryByTag(repository.c_str());
|
||||||
|
if (ct == NULL) {
|
||||||
|
j["error"] = "repository with tag '" + repository + "' does not exist";
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dbs = openRepositoryDatabase(ct);
|
||||||
|
if (!dbs) {
|
||||||
|
j["error"] = "error opening sources database for repository " + repository;
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
sql = "SELECT * FROM sources,packagers WHERE sources.id=" + to_string(id) +
|
||||||
|
" AND sources.id_packager=packagers.id";
|
||||||
|
if (!sqlite3_prepare_v2(dbs, sql.c_str(), sql.length(), &stmt, NULL) == SQLITE_OK) {
|
||||||
|
j["error"] = "error preparing query '" + sql + "'";
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
if (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||||
|
j["id"] = sqlite3_column_int(stmt,sqlite3_find_column_id(stmt, NULL, "id"));
|
||||||
|
j["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "name")));
|
||||||
|
j["summary"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "summary")));
|
||||||
|
j["epoch"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "epoch")));
|
||||||
|
j["version"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "version")));
|
||||||
|
j["release"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "release")));
|
||||||
|
j["group"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "groupdescr")));
|
||||||
|
j["license"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "license")));
|
||||||
|
j["url"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "url")));
|
||||||
|
//get_favicon_from_url((const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "url")),buffer,PATH_MAX);
|
||||||
|
j["size"] = sqlite3_column_int(stmt,sqlite3_find_column_id(stmt, NULL, "size"));
|
||||||
|
j["maintainer"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, "packagers", "name")));
|
||||||
|
// Convert buildtime to ISO-8601
|
||||||
|
auto itt = (time_t)sqlite3_column_int(stmt,sqlite3_find_column_id(stmt, NULL, "buildtime"));
|
||||||
|
ostringstream ss;
|
||||||
|
ss << std::put_time(gmtime(&itt), "%FT%TZ");
|
||||||
|
j["buildtime"] = ss.str();
|
||||||
|
// Source URL
|
||||||
|
j["source_url"] = "https://src.openmamba.org/rpms/" + string(j["name"]);
|
||||||
|
} else {
|
||||||
|
j["error"] = "no results from query '" + sql + "'";
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
json DistroqueryAPI::getPackageDetails(string repository, string package, string arch) {
|
||||||
|
json j;
|
||||||
|
string sql;
|
||||||
|
sqlite3_stmt *stmt, *stmt2;
|
||||||
|
|
||||||
|
struct configTag* ct = findRepositoryByTag(repository.c_str());
|
||||||
|
if (ct == NULL) {
|
||||||
|
j["error"] = "repository with tag '" + repository + "' does not exist";
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto db = openRepositoryDatabase(ct, arch);
|
||||||
|
if (!db) {
|
||||||
|
j["error"] = "error opening database for repository " + repository + " and arch " + arch;
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = "SELECT * FROM packages WHERE name = '" + package + "'";
|
||||||
|
if (sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt, NULL) == SQLITE_OK) {
|
||||||
|
long id;
|
||||||
|
if (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||||
|
id = sqlite3_column_int(stmt,sqlite3_find_column_id(stmt, NULL, "id"));
|
||||||
|
j["id"] = id;
|
||||||
|
j["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "name")));
|
||||||
|
j["summary"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "summary")));
|
||||||
|
j["epoch"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "epoch")));
|
||||||
|
j["version"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "version")));
|
||||||
|
j["release"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "release")));
|
||||||
|
j["group"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "groupdescr")));
|
||||||
|
string pkg_arch = arch;
|
||||||
|
if (sqlite3_find_column_id(stmt, NULL, "arch") > 0) {
|
||||||
|
pkg_arch = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "arch")));
|
||||||
|
}
|
||||||
|
j["arch"] = pkg_arch;
|
||||||
|
j["size"] = sqlite3_column_int(stmt,sqlite3_find_column_id(stmt, NULL, "size"));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
j["error"] = "no results from query '" + sql + "'";
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Source info
|
||||||
|
long id_source = sqlite3_column_int(stmt,sqlite3_find_column_id(stmt, NULL, "id_source"));
|
||||||
|
j["source"] = getPackageSourceDetailsById(repository, id_source);
|
||||||
|
|
||||||
|
// Download URL
|
||||||
|
j["download_url"] = string(ct->download_prefix) + ct->download_dir + "/RPMS." + string(j["arch"]) + "/" +
|
||||||
|
string(j["name"]) + "-" + string(j["version"]) + "-" + string(j["release"]) + "." + string(j["arch"]) + ".rpm";
|
||||||
|
|
||||||
|
// Brothers
|
||||||
|
sql = "SELECT * FROM packages WHERE id_source=" + to_string(id_source) + " AND NOT id=" + to_string(id);
|
||||||
|
j["brothers"] = json::array();
|
||||||
|
if (sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt2, NULL) == SQLITE_OK) {
|
||||||
|
while (sqlite3_step(stmt2) == SQLITE_ROW) {
|
||||||
|
j["brothers"].push_back(reinterpret_cast<const char*>(sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, NULL, "name"))));
|
||||||
|
}
|
||||||
|
sqlite3_finalize(stmt2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obsoletes
|
||||||
|
sql = "SELECT * FROM obsoletes WHERE id_package=" + to_string(id);
|
||||||
|
j["obsoletesbrothers"] = json::array();
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
j["error"] = "error preparing query '" + sql + "'";
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
return j;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void DistroqueryAPI::getApiResponse(string path_info) {
|
void DistroqueryAPI::getApiResponse(string path_info) {
|
||||||
cout << "Content-Type: application/json;charset=utf-8\n\n" << endl;
|
cout << "Content-Type: application/json;charset=utf-8\n\n" << endl;
|
||||||
|
|
||||||
@ -80,15 +193,21 @@ void DistroqueryAPI::getApiResponse(string path_info) {
|
|||||||
if (v.size() > 1) query_string = v[1];
|
if (v.size() > 1) query_string = v[1];
|
||||||
|
|
||||||
if (path_split.size() > 0 ) {
|
if (path_split.size() > 0 ) {
|
||||||
if (path_split[0] == "get_repositories") {
|
if (path_split[0] == "repositories") {
|
||||||
// API service: get_repository
|
// API service: repositories
|
||||||
|
if (path_split.size() != 1)
|
||||||
|
sendErrorResponse("expected exactly 1 argument for " + path_split[0]);
|
||||||
cout << configToJsonRepositories();
|
cout << configToJsonRepositories();
|
||||||
|
} else if (path_split[0] == "package") {
|
||||||
|
// API service: package
|
||||||
|
if (path_split.size() != 4)
|
||||||
|
sendErrorResponse("expected exactly 4 arguments for " + path_split[0]);
|
||||||
|
auto details = getPackageDetails(path_split[1], path_split[2], path_split[3]);
|
||||||
|
cout << details.dump();
|
||||||
} else {
|
} else {
|
||||||
cout << setw(4) << json::meta() << endl;
|
sendErrorResponse("invalid request for service '" + path_split[0]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cout << "{\"path_info\":\"" << path << "\",\"query_string\":\"" << query_string << "\"}";
|
sendErrorResponse("empty request");
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
|
@ -24,13 +24,13 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "distroquery_functions.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::ordered_json;
|
||||||
|
|
||||||
class DistroqueryAPI {
|
class DistroqueryAPI {
|
||||||
public:
|
public:
|
||||||
@ -40,6 +40,9 @@ class DistroqueryAPI {
|
|||||||
private:
|
private:
|
||||||
configTag *config;
|
configTag *config;
|
||||||
json configToJsonRepositories();
|
json configToJsonRepositories();
|
||||||
|
void sendErrorResponse(string message);
|
||||||
|
json getPackageDetails(string repository, string package, string arch);
|
||||||
|
json getPackageSourceDetailsById(string repository, long id);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __DISTROQUERY_API_H
|
#endif // __DISTROQUERY_API_H
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "distroquery.hpp"
|
#include "distroquery_functions.hpp"
|
||||||
#include "DistroqueryAPI.hpp"
|
#include "DistroqueryAPI.hpp"
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -114,23 +114,6 @@ char *url_decode(char *str) {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sqlite3_find_column_id(sqlite3_stmt *stmt, const char* table, const char* name) {
|
|
||||||
const char* colname;
|
|
||||||
int id = 0;
|
|
||||||
|
|
||||||
while ((colname = sqlite3_column_name(stmt, id))) {
|
|
||||||
if (!strcmp(colname, name)) {
|
|
||||||
if (table) {
|
|
||||||
if (!strcmp(sqlite3_column_table_name(stmt, id), table)) return id;
|
|
||||||
} else {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
id++;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int find_query_arch(char* arch) {
|
int find_query_arch(char* arch) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -195,28 +178,6 @@ char* resolveFilePath(sqlite3 *db, long id, char *buffer) {
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3* openRepositoryDatabase(struct configTag* ct, char* arch) {
|
|
||||||
char dbname[PATH_MAX];
|
|
||||||
sqlite3* db;
|
|
||||||
|
|
||||||
if (arch) {
|
|
||||||
snprintf(dbname, PATH_MAX, "%s%s-%s.db", ct->repository_dir, ct->tag, arch);
|
|
||||||
if (sqlite3_open_v2(dbname, (sqlite3**)&db, SQLITE_OPEN_READONLY, NULL)) {
|
|
||||||
if (db) sqlite3_close(db);
|
|
||||||
fprintf(stderr, "ERROR: unable to open sqlite3 db %s\n", dbname);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
snprintf(dbname, PATH_MAX, "%s%s-sources.db", ct->repository_dir, ct->tag);
|
|
||||||
if (sqlite3_open_v2(dbname, (sqlite3**)&db, SQLITE_OPEN_READONLY, NULL)) {
|
|
||||||
if (db) sqlite3_close(db);
|
|
||||||
fprintf(stderr, "ERROR: unable to open sqlite3 db %s\n", dbname);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return db;
|
|
||||||
}
|
|
||||||
|
|
||||||
void attachCtDatabases(struct configTag* ct, sqlite3 *db, char* arch) {
|
void attachCtDatabases(struct configTag* ct, sqlite3 *db, char* arch) {
|
||||||
string dbname;
|
string dbname;
|
||||||
string sql;
|
string sql;
|
||||||
@ -875,11 +836,12 @@ void printSpecialQueryResponse() {
|
|||||||
repository = query + 8;
|
repository = query + 8;
|
||||||
ct = findRepositoryByTag(repository);
|
ct = findRepositoryByTag(repository);
|
||||||
if (!ct) return;
|
if (!ct) return;
|
||||||
db = openRepositoryDatabase(ct, NULL);
|
db = openRepositoryDatabase(ct);
|
||||||
|
if (!db) return;
|
||||||
attachCtDatabases(ct, db, NULL);
|
attachCtDatabases(ct, db, NULL);
|
||||||
|
|
||||||
if (ct->arch[0]) {
|
if (ct->arch[0]) {
|
||||||
dbb = openRepositoryDatabase(ct, NULL);
|
dbb = openRepositoryDatabase(ct);
|
||||||
if (!dbb) return;
|
if (!dbb) return;
|
||||||
for (a = 0; a < ARCHS_MAX && ct->arch[a]; a++) {
|
for (a = 0; a < ARCHS_MAX && ct->arch[a]; a++) {
|
||||||
attachRepositoryDatabases(ct, dbb, ct->arch[a], 0);
|
attachRepositoryDatabases(ct, dbb, ct->arch[a], 0);
|
||||||
@ -1041,7 +1003,6 @@ void printSpecialQueryResponse() {
|
|||||||
void printPackageData() {
|
void printPackageData() {
|
||||||
|
|
||||||
int i, j;
|
int i, j;
|
||||||
char dbname[PATH_MAX];
|
|
||||||
sqlite3 *db, *dbs, *dbf;
|
sqlite3 *db, *dbs, *dbf;
|
||||||
sqlite3_stmt *statement, *stmt1, *stmt2;
|
sqlite3_stmt *statement, *stmt1, *stmt2;
|
||||||
char sql[PATH_MAX];
|
char sql[PATH_MAX];
|
||||||
@ -1053,12 +1014,8 @@ void printPackageData() {
|
|||||||
int package_id;
|
int package_id;
|
||||||
char *package_name = NULL, *package_summary = NULL;
|
char *package_name = NULL, *package_summary = NULL;
|
||||||
|
|
||||||
snprintf(dbname, PATH_MAX, "%s%s-%s.db", ct->repository_dir, ct->tag, query_arch);
|
db = openRepositoryDatabase(ct, query_arch);
|
||||||
if (sqlite3_open_v2(dbname, (sqlite3**)&db, SQLITE_OPEN_READONLY, NULL)) {
|
if (!db) return;
|
||||||
if (db) sqlite3_close(db);
|
|
||||||
fprintf(stderr, "ERROR: unable to open sqlite3 db %s\n", dbname);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!reply_plain) printf("<%s><![CDATA[", reply_xmltag);
|
if (!reply_plain) printf("<%s><![CDATA[", reply_xmltag);
|
||||||
|
|
||||||
@ -1071,13 +1028,9 @@ void printPackageData() {
|
|||||||
package_name = strdup((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")));
|
package_name = strdup((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")));
|
||||||
package_summary = strdup((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "summary")));
|
package_summary = strdup((const char*)sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "summary")));
|
||||||
|
|
||||||
snprintf(dbname, PATH_MAX, "%s%s-sources.db", ct->repository_dir, ct->tag);
|
dbs = openRepositoryDatabase(ct);
|
||||||
if (sqlite3_open_v2(dbname, &dbs, SQLITE_OPEN_READONLY, NULL)) {
|
if (!dbs) return;
|
||||||
if (dbs) sqlite3_close(dbs);
|
|
||||||
dbs = NULL;
|
|
||||||
fprintf(stderr, "ERROR: unable to open sqlite3 db %s; aborting.\n", dbname);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
snprintf(sql, PATH_MAX,
|
snprintf(sql, PATH_MAX,
|
||||||
"SELECT * FROM sources,packagers WHERE sources.id=%d AND sources.id_packager=packagers.id",
|
"SELECT * FROM sources,packagers WHERE sources.id=%d AND sources.id_packager=packagers.id",
|
||||||
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id_source")));
|
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id_source")));
|
||||||
@ -1289,8 +1242,8 @@ void printPackageData() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* files list */
|
/* files list */
|
||||||
snprintf(dbname, PATH_MAX, "%s%s-%s-files.db", ct->repository_dir, ct->tag, query_arch);
|
dbf = openRepositoryDatabase(ct, query_arch, "-files");
|
||||||
if (!sqlite3_open_v2(dbname, &dbf, SQLITE_OPEN_READONLY, NULL)) {
|
if (dbf != NULL) {
|
||||||
printf("<br><br>%s:<br><table class='queryfiletable'>", _("Files list"));
|
printf("<br><br>%s:<br><table class='queryfiletable'>", _("Files list"));
|
||||||
snprintf(sql, PATH_MAX, "SELECT * FROM packages_files_rel,fileusers,filegroups WHERE"
|
snprintf(sql, PATH_MAX, "SELECT * FROM packages_files_rel,fileusers,filegroups WHERE"
|
||||||
" packages_files_rel.name='%s' AND"
|
" packages_files_rel.name='%s' AND"
|
||||||
@ -1630,6 +1583,7 @@ main(int argc, char *argv[])
|
|||||||
if (strncmp(path_info, "/api/v1/", strlen(API_PREFIX)) == 0) {
|
if (strncmp(path_info, "/api/v1/", strlen(API_PREFIX)) == 0) {
|
||||||
DistroqueryAPI *api = new DistroqueryAPI(firstconfigtag);
|
DistroqueryAPI *api = new DistroqueryAPI(firstconfigtag);
|
||||||
api->getApiResponse(&path_info[strlen(API_PREFIX)]);
|
api->getApiResponse(&path_info[strlen(API_PREFIX)]);
|
||||||
|
exit(0);
|
||||||
} else if (strlen(path_info) > 0) {
|
} else if (strlen(path_info) > 0) {
|
||||||
cout << "Content-Type: text/html;charset=utf-8" << endl;
|
cout << "Content-Type: text/html;charset=utf-8" << endl;
|
||||||
cout << "Status: 400 Bad request" << endl << endl;
|
cout << "Status: 400 Bad request" << endl << endl;
|
||||||
|
77
src/distroquery_functions.cpp
Normal file
77
src/distroquery_functions.cpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* distroquery_functions - Basic functions used by distroquery
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 by Silvan Calarco <silvan.calarco@mambasoft.it>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under
|
||||||
|
* the terms of version 2 of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY, to the extent permitted by law; without even the implied
|
||||||
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "distroquery_functions.hpp"
|
||||||
|
#include "config.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
vector<string> split(string str, string token) {
|
||||||
|
vector<string>result;
|
||||||
|
while(str.size()){
|
||||||
|
auto index = str.find(token);
|
||||||
|
if(index!=string::npos){
|
||||||
|
result.push_back(str.substr(0,index));
|
||||||
|
str = str.substr(index+token.size());
|
||||||
|
if(str.size()==0)result.push_back(str);
|
||||||
|
}else{
|
||||||
|
result.push_back(str);
|
||||||
|
str = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3* openRepositoryDatabase(struct configTag* ct, string arch, string append) {
|
||||||
|
string dbname;
|
||||||
|
sqlite3* db;
|
||||||
|
|
||||||
|
if (arch != "" && arch != "sources") {
|
||||||
|
dbname = string(ct->repository_dir) + ct->tag + "-" + arch + append + ".db";
|
||||||
|
if (sqlite3_open_v2(dbname.c_str(), (sqlite3**)&db, SQLITE_OPEN_READONLY, NULL)) {
|
||||||
|
if (db) sqlite3_close(db);
|
||||||
|
fprintf(stderr, "ERROR: unable to open sqlite3 db %s\n", dbname.c_str());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dbname = string(ct->repository_dir) + ct->tag + "-sources" + append + ".db";
|
||||||
|
if (sqlite3_open_v2(dbname.c_str(), (sqlite3**)&db, SQLITE_OPEN_READONLY, NULL)) {
|
||||||
|
if (db) sqlite3_close(db);
|
||||||
|
fprintf(stderr, "ERROR: unable to open sqlite3 db %s\n", dbname.c_str());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sqlite3_find_column_id(sqlite3_stmt *stmt, const char* table, const char* name) {
|
||||||
|
const char* colname;
|
||||||
|
int id = 0;
|
||||||
|
|
||||||
|
while ((colname = sqlite3_column_name(stmt, id))) {
|
||||||
|
if (!strcmp(colname, name)) {
|
||||||
|
if (table) {
|
||||||
|
if (!strcmp(sqlite3_column_table_name(stmt, id), table)) return id;
|
||||||
|
} else {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
id++;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* distroquery - tool for querying data generated by distromatic
|
* distroquery_functions - Basic functions used by distroquery
|
||||||
*
|
*
|
||||||
* Copyright (C) 2024 by Silvan Calarco <silvan.calarco@mambasoft.it>
|
* Copyright (C) 2024 by Silvan Calarco <silvan.calarco@mambasoft.it>
|
||||||
*
|
*
|
||||||
@ -16,6 +16,20 @@
|
|||||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __DISTROQUERY_FUNCTIONS_H
|
||||||
|
#define __DISTROQUERY_FUNCTIONS_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
vector<string> split(string str, string token);
|
||||||
|
sqlite3* openRepositoryDatabase(struct configTag* ct, string arch = "", string append = "");
|
||||||
|
int sqlite3_find_column_id(sqlite3_stmt *stmt, const char* table, const char* name);
|
||||||
|
|
||||||
#define HDSIZE 16
|
#define HDSIZE 16
|
||||||
#define SSSIZE 24
|
#define SSSIZE 24
|
||||||
|
|
||||||
@ -31,3 +45,5 @@ extern "C" int get_favicon_from_url(const char* url,char *buf,int bufsize);
|
|||||||
extern "C" void backtraceHandler(int sig);
|
extern "C" void backtraceHandler(int sig);
|
||||||
extern "C" struct configTag* findRepositoryByTag(const char *tag);
|
extern "C" struct configTag* findRepositoryByTag(const char *tag);
|
||||||
extern "C" struct configTag* read_configuration(const char *confFile);
|
extern "C" struct configTag* read_configuration(const char *confFile);
|
||||||
|
|
||||||
|
#endif // __DISTROQUERY_FUNCTIONS_H
|
Loading…
Reference in New Issue
Block a user