distroquery: start implementing Distroquery API and some C to C++ string management conversions
This commit is contained in:
parent
6732bdccfe
commit
e6616f603b
@ -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
|
||||||
|
DistroqueryAPI.cpp
|
||||||
distroquery.cpp
|
distroquery.cpp
|
||||||
functions.c
|
functions.c
|
||||||
headerlist.c
|
headerlist.c
|
||||||
@ -94,6 +95,8 @@ target_include_directories(distroquery PUBLIC
|
|||||||
${LIBUNWIND_INCLUDE_DIRS}
|
${LIBUNWIND_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_compile_options(distroquery PUBLIC -O2 -g -Wall $<$<COMPILE_LANGUAGE:CXX>:-std=c++14> -pedantic ${RPM_CFLAGS_OTHER})
|
||||||
|
|
||||||
install(
|
install(
|
||||||
TARGETS distromatic
|
TARGETS distromatic
|
||||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
|
DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
|
||||||
|
@ -17,7 +17,8 @@
|
|||||||
* 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.hpp"
|
||||||
|
#include "DistroqueryAPI.hpp"
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -217,23 +218,23 @@ sqlite3* openRepositoryDatabase(struct configTag* ct, char* arch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void attachCtDatabases(struct configTag* ct, sqlite3 *db, char* arch) {
|
void attachCtDatabases(struct configTag* ct, sqlite3 *db, char* arch) {
|
||||||
char dbname[PATH_MAX];
|
string dbname;
|
||||||
|
string sql;
|
||||||
int i=0;
|
int i=0;
|
||||||
char sql[PATH_MAX];
|
|
||||||
char *errmsg;
|
char *errmsg;
|
||||||
|
|
||||||
while (ct->repository[i]) {
|
while (ct->repository[i]) {
|
||||||
if (arch) {
|
if (arch) {
|
||||||
snprintf(dbname, PATH_MAX, "%s%s-%s.db", ct->repository[i]->repository_dir, ct->repository[i]->tag, arch);
|
dbname = string(ct->repository[i]->repository_dir) + ct->repository[i]->tag + "-" + arch + ".db";
|
||||||
snprintf(sql, PATH_MAX, "ATTACH DATABASE '%s' as '%s_%s'", dbname, ct->repository[i]->tag, arch);
|
sql = "ATTACH DATABASE '" + dbname + "' as '" + ct->repository[i]->tag + "_" + arch + "'";
|
||||||
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg)) {
|
if (sqlite3_exec(db, sql.c_str(), NULL, NULL, &errmsg)) {
|
||||||
fprintf(stderr, "ERROR: unable to exec statement for %s: %s\n", sql, errmsg);
|
cerr << "ERROR: unable to exec statement for " << sql << ": " << errmsg << endl;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
snprintf(dbname, PATH_MAX, "%s%s-sources.db", ct->repository[i]->repository_dir, ct->repository[i]->tag);
|
dbname = string(ct->repository[i]->repository_dir) + ct->repository[i]->tag + "-sources.db";
|
||||||
snprintf(sql, PATH_MAX, "ATTACH DATABASE '%s' as '%s_sources'", dbname, ct->repository[i]->tag);
|
sql = "ATTACH DATABASE '" + dbname + "' as '" + ct->repository[i]->tag + "_sources'";
|
||||||
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg)) {
|
if (sqlite3_exec(db, sql.c_str(), NULL, NULL, &errmsg)) {
|
||||||
fprintf(stderr, "ERROR: unable to exec statement for %s: %s\n", sql, errmsg);
|
cerr << "ERROR: unable to exec statement for " << sql << ": " << errmsg << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
@ -241,22 +242,22 @@ void attachCtDatabases(struct configTag* ct, sqlite3 *db, char* arch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void attachRepositoryDatabases(struct configTag* ct, sqlite3 *db, char* arch, int source) {
|
void attachRepositoryDatabases(struct configTag* ct, sqlite3 *db, char* arch, int source) {
|
||||||
char dbname[PATH_MAX];
|
string dbname;
|
||||||
char sql[PATH_MAX];
|
string sql;
|
||||||
char *errmsg;
|
char *errmsg;
|
||||||
|
|
||||||
snprintf(dbname, PATH_MAX, "%s%s-%s.db", ct->repository_dir, ct->tag, arch);
|
dbname = string(ct->repository_dir) + ct->tag + "-" + arch + ".db";
|
||||||
snprintf(sql, PATH_MAX, "ATTACH DATABASE '%s' as '%s_%s'", dbname, ct->tag, arch);
|
sql = "ATTACH DATABASE '" + dbname + "' as '" + ct->tag + "_" + arch;
|
||||||
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg)) {
|
if (sqlite3_exec(db, sql.c_str(), NULL, NULL, &errmsg)) {
|
||||||
fprintf(stderr, "ERROR: unable to exec statement for %s: %s\n", sql, errmsg);
|
cerr << "ERROR: unable to exec statement for " << sql << ": " << errmsg << endl;
|
||||||
}
|
}
|
||||||
if (source) {
|
if (source) {
|
||||||
snprintf(dbname, PATH_MAX, "%s%s-sources.db", ct->repository_dir, ct->tag);
|
dbname = string(ct->repository_dir) + ct->tag + "-sources.db";
|
||||||
snprintf(sql, PATH_MAX, "ATTACH DATABASE '%s' as '%s_sources'", dbname, ct->tag);
|
sql = "ATTACH DATABASE '" + dbname + "' as '" + ct->tag + "_sources'";
|
||||||
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg)) {
|
if (sqlite3_exec(db, sql.c_str(), NULL, NULL, &errmsg)) {
|
||||||
fprintf(stderr, "ERROR: unable to exec statement for %s: %s\n", sql, 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) {
|
||||||
@ -363,11 +364,11 @@ void printInputForm() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int findFileIdFromPath(sqlite3 *db, char** path) {
|
int findFileIdFromPath(sqlite3 *db, char** path) {
|
||||||
int frompos = 1, topos;
|
size_t frompos = 1, topos;
|
||||||
int parent = -1;
|
int parent = -1;
|
||||||
char* pt;
|
char* pt;
|
||||||
char buffer[PATH_MAX];
|
char buffer[PATH_MAX];
|
||||||
char sql[PATH_MAX];
|
string sql;
|
||||||
char* linkpath = (char*)calloc(strlen(*path),1);
|
char* linkpath = (char*)calloc(strlen(*path),1);
|
||||||
sqlite3_stmt* stmt1;
|
sqlite3_stmt* stmt1;
|
||||||
|
|
||||||
@ -378,9 +379,8 @@ int findFileIdFromPath(sqlite3 *db, char** path) {
|
|||||||
if (pt) topos = pt - *path; else topos = strlen(*path);
|
if (pt) topos = pt - *path; else topos = strlen(*path);
|
||||||
strncpy(buffer, *path + frompos, topos - frompos);
|
strncpy(buffer, *path + frompos, topos - frompos);
|
||||||
buffer[topos-frompos]=0;
|
buffer[topos-frompos]=0;
|
||||||
snprintf(sql, PATH_MAX, "SELECT id FROM files WHERE parent=%d"
|
sql = "SELECT id FROM files WHERE parent=" + to_string(parent) + " AND name='" + buffer + "'";
|
||||||
" AND name='%s'", parent, buffer);
|
if (sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt1, NULL) == SQLITE_OK && sqlite3_step(stmt1) == SQLITE_ROW) {
|
||||||
if (sqlite3_prepare_v2(db, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK && sqlite3_step(stmt1) == SQLITE_ROW) {
|
|
||||||
parent = sqlite3_column_int(stmt1,0);
|
parent = sqlite3_column_int(stmt1,0);
|
||||||
sqlite3_finalize(stmt1);
|
sqlite3_finalize(stmt1);
|
||||||
strncat(linkpath, "/", strlen(*path) - strlen(linkpath));
|
strncat(linkpath, "/", strlen(*path) - strlen(linkpath));
|
||||||
@ -490,28 +490,28 @@ int packageVerCmp(int e1, const char* v1, const char* r1, int e2, const char* v2
|
|||||||
|
|
||||||
void printQueryResponse() {
|
void printQueryResponse() {
|
||||||
|
|
||||||
int a, i, j, k, numresults = 0, otherresults = 0, localresults = 0, localprovidesresults = 0, localsourceresults = 0;
|
int a, j, k, numresults = 0, otherresults = 0, localresults = 0, localprovidesresults = 0, localsourceresults = 0;
|
||||||
char dbname[PATH_MAX];
|
char dbname[PATH_MAX];
|
||||||
sqlite3 *dbf;
|
sqlite3 *dbf;
|
||||||
sqlite3_stmt *statement, *stmt1;
|
sqlite3_stmt *statement, *stmt1;
|
||||||
char sql[PATH_MAX];
|
char sql[PATH_MAX];
|
||||||
char buffer[PATH_MAX];
|
char buffer[PATH_MAX];
|
||||||
char queryenc[PATH_MAX];
|
string queryenc;
|
||||||
|
|
||||||
if (!reply_plain) printf("<%s><![CDATA[", reply_xmltag);
|
if (!reply_plain) printf("<%s><![CDATA[", reply_xmltag);
|
||||||
strncpy(queryenc, query, PATH_MAX);
|
queryenc = string(query);
|
||||||
for (i = 0; i < strlen(queryenc); i++) {
|
for (size_t i = 0; i < queryenc.length(); i++) {
|
||||||
if (queryenc[i] == ' ') queryenc[i] = '%';
|
if (queryenc[i] == ' ') queryenc[i] = '%';
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; query_repositories[i] != NULL; i++) {
|
for (auto i = 0; query_repositories[i] != NULL; i++) {
|
||||||
for (a = 0; a < ARCHS_MAX && query_repositories[i]->arch[a]; a++) {
|
for (a = 0; a < ARCHS_MAX && query_repositories[i]->arch[a]; a++) {
|
||||||
if (find_query_arch(query_repositories[i]->arch[a]) >= 0) {
|
if (find_query_arch(query_repositories[i]->arch[a]) >= 0) {
|
||||||
if (!query_repositories[i]->db[a]) {
|
if (!query_repositories[i]->db[a]) {
|
||||||
snprintf(dbname, PATH_MAX, "%s%s-%s.db",
|
snprintf(dbname, PATH_MAX, "%s%s-%s.db",
|
||||||
query_repositories[i]->repository_dir, query_repositories[i]->tag, query_repositories[i]->arch[a]);
|
query_repositories[i]->repository_dir, query_repositories[i]->tag, query_repositories[i]->arch[a]);
|
||||||
if (sqlite3_open_v2(dbname, (sqlite3**)&query_repositories[i]->db[a], SQLITE_OPEN_READONLY, NULL)) {
|
if (sqlite3_open_v2(dbname, (sqlite3**)&query_repositories[i]->db[a], SQLITE_OPEN_READONLY, NULL)) {
|
||||||
if (query_repositories[i]->db) sqlite3_close((sqlite3*)query_repositories[i]->db[a]);
|
sqlite3_close((sqlite3*)query_repositories[i]->db[a]);
|
||||||
query_repositories[i]->db[a] = NULL;
|
query_repositories[i]->db[a] = NULL;
|
||||||
fprintf(stderr, "ERROR: unable to open sqlite3 db %s; ignoring.\n", dbname);
|
fprintf(stderr, "ERROR: unable to open sqlite3 db %s; ignoring.\n", dbname);
|
||||||
}
|
}
|
||||||
@ -533,7 +533,8 @@ void printQueryResponse() {
|
|||||||
"groupdescr LIKE 'Graphical Desktop/%%' DESC, groupdescr LIKE 'Applications/%%' DESC, "
|
"groupdescr LIKE 'Graphical Desktop/%%' DESC, groupdescr LIKE 'Applications/%%' DESC, "
|
||||||
"groupdescr LIKE 'Development/%%' ASC, groupdescr LIKE 'Documentation%%' ASC, groupdescr LIKE 'System/Libraries%%' ASC, "
|
"groupdescr LIKE 'Development/%%' ASC, groupdescr LIKE 'Documentation%%' ASC, groupdescr LIKE 'System/Libraries%%' ASC, "
|
||||||
"name LIKE '%%-devel' ASC, name LIKE '%%-debug' ASC "
|
"name LIKE '%%-devel' ASC, name LIKE '%%-debug' ASC "
|
||||||
"LIMIT %d OFFSET %d", queryenc, queryenc, queryenc, queryenc, queryenc, queryenc, queryenc, query_limit, query_offset);
|
"LIMIT %d OFFSET %d", queryenc.c_str(), queryenc.c_str(), queryenc.c_str(), queryenc.c_str(), queryenc.c_str(),
|
||||||
|
queryenc.c_str(), queryenc.c_str(), query_limit, query_offset);
|
||||||
if (sqlite3_prepare_v2((sqlite3*)query_repositories[i]->db[a], sql, strlen(sql), &statement, NULL) == SQLITE_OK) {
|
if (sqlite3_prepare_v2((sqlite3*)query_repositories[i]->db[a], sql, strlen(sql), &statement, NULL) == SQLITE_OK) {
|
||||||
while (sqlite3_step(statement) == SQLITE_ROW) {
|
while (sqlite3_step(statement) == SQLITE_ROW) {
|
||||||
numresults++;
|
numresults++;
|
||||||
@ -630,7 +631,8 @@ void printQueryResponse() {
|
|||||||
"(provides.id_package=packages.id AND provided.id=provides.id_provided) "
|
"(provides.id_package=packages.id AND provided.id=provides.id_provided) "
|
||||||
"AND provided.name LIKE '%%%s%%' "
|
"AND provided.name LIKE '%%%s%%' "
|
||||||
"ORDER BY provided.name = '%s' DESC, provided.name LIKE '%s%%' DESC, provided.name LIKE '%%%s%%' DESC "
|
"ORDER BY provided.name = '%s' DESC, provided.name LIKE '%s%%' DESC, provided.name LIKE '%%%s%%' DESC "
|
||||||
"LIMIT %d OFFSET %d", queryenc, queryenc, queryenc, queryenc, query_limit, query_offset);
|
"LIMIT %d OFFSET %d", queryenc.c_str(), queryenc.c_str(), queryenc.c_str(), queryenc.c_str(),
|
||||||
|
query_limit, query_offset);
|
||||||
if (sqlite3_prepare_v2((sqlite3*)query_repositories[i]->db[a], sql, strlen(sql), &statement, NULL) == SQLITE_OK) {
|
if (sqlite3_prepare_v2((sqlite3*)query_repositories[i]->db[a], sql, strlen(sql), &statement, NULL) == SQLITE_OK) {
|
||||||
while (sqlite3_step(statement) == SQLITE_ROW) {
|
while (sqlite3_step(statement) == SQLITE_ROW) {
|
||||||
numresults++;
|
numresults++;
|
||||||
@ -685,7 +687,8 @@ void printQueryResponse() {
|
|||||||
"packages_files_rel.id_file = files.id "
|
"packages_files_rel.id_file = files.id "
|
||||||
"ORDER BY files.name = '%s' DESC, files.name LIKE '%s%%' DESC, "
|
"ORDER BY files.name = '%s' DESC, files.name LIKE '%s%%' DESC, "
|
||||||
"files.name LIKE '%%%s%%' DESC LIMIT %d OFFSET %d",
|
"files.name LIKE '%%%s%%' DESC LIMIT %d OFFSET %d",
|
||||||
queryenc, queryenc, queryenc, queryenc, query_limit, query_offset);
|
queryenc.c_str(), queryenc.c_str(), queryenc.c_str(), queryenc.c_str(),
|
||||||
|
query_limit, query_offset);
|
||||||
if (sqlite3_prepare_v2(dbf, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
|
if (sqlite3_prepare_v2(dbf, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) {
|
||||||
while (sqlite3_step(stmt1) == SQLITE_ROW) {
|
while (sqlite3_step(stmt1) == SQLITE_ROW) {
|
||||||
numresults++;
|
numresults++;
|
||||||
@ -734,8 +737,9 @@ void printQueryResponse() {
|
|||||||
snprintf(sql, PATH_MAX,
|
snprintf(sql, PATH_MAX,
|
||||||
"SELECT * FROM sources WHERE name LIKE '%%%s%%' OR summary LIKE '%%%s%%' OR description LIKE '%%%s%%' OR version LIKE '%%%s%%' "
|
"SELECT * FROM sources WHERE name LIKE '%%%s%%' OR summary LIKE '%%%s%%' OR description LIKE '%%%s%%' OR version LIKE '%%%s%%' "
|
||||||
"ORDER BY name = '%s' DESC, name LIKE '%s%%' DESC, name LIKE '%%%s%%' DESC LIMIT %d OFFSET %d",
|
"ORDER BY name = '%s' DESC, name LIKE '%s%%' DESC, name LIKE '%%%s%%' DESC LIMIT %d OFFSET %d",
|
||||||
queryenc, queryenc, queryenc, queryenc, queryenc, queryenc, queryenc, query_limit, query_offset);
|
queryenc.c_str(), queryenc.c_str(), queryenc.c_str(), queryenc.c_str(), queryenc.c_str(), queryenc.c_str(),
|
||||||
for (i = 0; query_repositories[i] != NULL; i++) {
|
queryenc.c_str(), query_limit, query_offset);
|
||||||
|
for (auto i = 0; query_repositories[i] != NULL; i++) {
|
||||||
if (!query_repositories[i]->db[ARCHS_MAX]) {
|
if (!query_repositories[i]->db[ARCHS_MAX]) {
|
||||||
snprintf(dbname, PATH_MAX, "%s%s-sources.db", query_repositories[i]->repository_dir, query_repositories[i]->tag);
|
snprintf(dbname, PATH_MAX, "%s%s-sources.db", query_repositories[i]->repository_dir, query_repositories[i]->tag);
|
||||||
if (sqlite3_open_v2(dbname, (sqlite3**)&query_repositories[i]->db[ARCHS_MAX], SQLITE_OPEN_READONLY, NULL)) {
|
if (sqlite3_open_v2(dbname, (sqlite3**)&query_repositories[i]->db[ARCHS_MAX], SQLITE_OPEN_READONLY, NULL)) {
|
||||||
@ -814,7 +818,7 @@ void printQueryResponse() {
|
|||||||
} else a=j+9; /* a = number of page links displayed */
|
} else a=j+9; /* a = number of page links displayed */
|
||||||
if (a > 1) {
|
if (a > 1) {
|
||||||
printf(" [ ");
|
printf(" [ ");
|
||||||
for (i = j; i <= a; i++) {
|
for (auto i = j; i <= a; i++) {
|
||||||
if (i != k) printf("<a href=#reply onclick='distroquery_request(\"%s&limit=%d&offset=%d\")'>",
|
if (i != k) printf("<a href=#reply onclick='distroquery_request(\"%s&limit=%d&offset=%d\")'>",
|
||||||
query_next, query_limit, query_limit * (i-1));
|
query_next, query_limit, query_limit * (i-1));
|
||||||
printf("%d", i);
|
printf("%d", i);
|
||||||
@ -829,7 +833,7 @@ void printQueryResponse() {
|
|||||||
printf("]]></title>");
|
printf("]]></title>");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; query_repositories[i] != NULL; i++) {
|
for (auto i = 0; query_repositories[i] != NULL; i++) {
|
||||||
for (a = 0; a <= ARCHS_MAX && query_repositories[i]->arch[a]; a++) {
|
for (a = 0; a <= ARCHS_MAX && query_repositories[i]->arch[a]; a++) {
|
||||||
if (query_repositories[i]->db[a]) {
|
if (query_repositories[i]->db[a]) {
|
||||||
sqlite3_close((sqlite3*)query_repositories[i]->db[a]);
|
sqlite3_close((sqlite3*)query_repositories[i]->db[a]);
|
||||||
@ -1608,7 +1612,7 @@ void parse_request_variables(char *data) {
|
|||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char *data;
|
char *path_info, *query_string;
|
||||||
int responsed = 0;
|
int responsed = 0;
|
||||||
|
|
||||||
// install backtrace handler
|
// install backtrace handler
|
||||||
@ -1620,11 +1624,22 @@ main(int argc, char *argv[])
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
data = getenv("QUERY_STRING");
|
path_info = getenv("PATH_INFO");
|
||||||
if (data && strlen(data)) {
|
query_string = getenv("QUERY_STRING");
|
||||||
parse_request_variables(data);
|
|
||||||
|
if (strncmp(path_info, "/api/v1/", strlen(API_PREFIX)) == 0) {
|
||||||
|
DistroqueryAPI api;
|
||||||
|
api.getApiResponse(&path_info[strlen(API_PREFIX)]);
|
||||||
|
} else if (strlen(path_info) > 0) {
|
||||||
|
cout << "Content-Type: text/html;charset=utf-8" << endl;
|
||||||
|
cout << "Status: 400 Bad request" << endl << endl;
|
||||||
|
cout << "ERROR: invalid path: " << path_info;
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (query_string && strlen(query_string)) {
|
||||||
|
parse_request_variables(query_string);
|
||||||
|
}
|
||||||
|
|
||||||
if (!reply_plain)
|
if (!reply_plain)
|
||||||
printf("Content-Type: text/xml;charset=utf-8\n\n<distroquery>");
|
printf("Content-Type: text/xml;charset=utf-8\n\n<distroquery>");
|
||||||
|
Loading…
Reference in New Issue
Block a user