aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets/html_footer.html (renamed from assets/footer.html)0
-rw-r--r--assets/html_header.html (renamed from assets/header.html)0
-rw-r--r--assets/table_footer.html (renamed from assets/index_footer.html)0
-rw-r--r--assets/table_header.html (renamed from assets/index_header.html)2
-rw-r--r--assets/table_row.html (renamed from assets/index_row.html)0
-rw-r--r--conf/clog.conf9
-rw-r--r--src/clog.c123
-rw-r--r--src/queries.h4
8 files changed, 113 insertions, 25 deletions
diff --git a/assets/footer.html b/assets/html_footer.html
index 6131a40..6131a40 100644
--- a/assets/footer.html
+++ b/assets/html_footer.html
diff --git a/assets/header.html b/assets/html_header.html
index 0ff3660..0ff3660 100644
--- a/assets/header.html
+++ b/assets/html_header.html
diff --git a/assets/index_footer.html b/assets/table_footer.html
index 000ca4b..000ca4b 100644
--- a/assets/index_footer.html
+++ b/assets/table_footer.html
diff --git a/assets/index_header.html b/assets/table_header.html
index a768089..eded2a7 100644
--- a/assets/index_header.html
+++ b/assets/table_header.html
@@ -1,3 +1 @@
-<h1>clog.bunkergate.org</h1>
-
<table><tr><th>title</th><th>created</th><th>updated</th></tr>
diff --git a/assets/index_row.html b/assets/table_row.html
index c9b9c68..c9b9c68 100644
--- a/assets/index_row.html
+++ b/assets/table_row.html
diff --git a/conf/clog.conf b/conf/clog.conf
index 89e9880..cf870b1 100644
--- a/conf/clog.conf
+++ b/conf/clog.conf
@@ -35,9 +35,18 @@ domain * {
methods get
}
+ route ^/search$ {
+ handler search_entries
+ methods get
+
+ validate qs:get query v_text
+ }
+
route ^/entries/search$ {
handler search_entries
methods get
+
+ validate qs:get query v_text
}
route ^/entries/[a-z0-9\-]+$ {
diff --git a/src/clog.c b/src/clog.c
index feedd98..5111b06 100644
--- a/src/clog.c
+++ b/src/clog.c
@@ -35,6 +35,7 @@ struct entry {
struct entry_query {
char *id;
+ char *query;
struct entry **entries;
int num_entries;
@@ -52,7 +53,7 @@ static const char * const error_msg[] = {
[HTTP_STATUS_INTERNAL_ERROR] = "There was an error processing the request.", // 500
};
-void entry_query_init(struct entry_query *eq, const char *id);
+void entry_query_init(struct entry_query *eq, const char *id, const char *query);
void entry_query_cleanup(struct entry_query *eq);
int validate_uuid(const char *uuid);
@@ -77,12 +78,22 @@ int sql_update(const char *id, const char *title, const char *body);
static void process_md_output(const MD_CHAR *html, MD_SIZE size, void *buf);
static int render_md(const char *in, struct kore_buf *out);
-void entry_query_init(struct entry_query *eq, const char *id) {
- if (id != NULL)
+void entry_query_init(struct entry_query *eq, const char *id, const char *query) {
+ if (id != NULL) {
eq->id = kore_strdup(id);
- else
+ }
+ else {
eq->id = NULL;
+ }
+ if (query != NULL) {
+ eq->query = kore_strdup(query);
+ }
+ else {
+ eq->query = NULL;
+ }
+
+ // FIXME: define MAX_ENTRIES and LIMIT queries with it.
eq->entries = kore_malloc(sizeof(struct entry *) * 100);
eq->num_entries = 0;
@@ -90,10 +101,16 @@ void entry_query_init(struct entry_query *eq, const char *id) {
}
void entry_query_cleanup(struct entry_query *eq) {
- if (eq->id != NULL)
+ if (eq->id != NULL) {
kore_free((void *) eq->id);
+ }
eq->id = NULL;
+ if (eq->query != NULL) {
+ kore_free((void *) eq->query);
+ }
+ eq->query = NULL;
+
for (int i = 0; i < eq->num_entries; i++) {
if (eq->entries[i]->id != NULL)
kore_free((void *) eq->entries[i]->id);
@@ -108,6 +125,7 @@ void entry_query_cleanup(struct entry_query *eq) {
kore_free((void *) eq->entries[i]);
}
kore_free((void *) eq->entries);
+ eq->entries = NULL;
}
int validate_uuid(const char *uuid) {
@@ -135,7 +153,7 @@ int validate_uuid(const char *uuid) {
}
int validate_text(struct http_request *req, char *data) {
- kore_log(LOG_NOTICE, "v_example_func called %s", data);
+ kore_log(LOG_NOTICE, "validate_text called with data '%s'", data);
return KORE_RESULT_OK;
}
@@ -148,9 +166,9 @@ int http_ok_resp(
const char *body = kore_buf_stringify(content, NULL);
http_response_header(req, "content-type", "text/html; charset=utf-8");
- kore_buf_append(resp_buf, asset_header_html, asset_len_header_html);
+ kore_buf_append(resp_buf, asset_html_header_html, asset_len_html_header_html);
kore_buf_append(resp_buf, body, strlen(body));
- kore_buf_append(resp_buf, asset_footer_html, asset_len_footer_html);
+ kore_buf_append(resp_buf, asset_html_footer_html, asset_len_html_footer_html);
http_response(req, status, resp_buf->data, resp_buf->offset);
@@ -166,9 +184,9 @@ int http_err_resp(
struct kore_buf *resp_buf = kore_buf_alloc(0);
http_response_header(req, "content-type", "text/html; charset=utf-8");
- kore_buf_append(resp_buf, asset_header_html, asset_len_header_html);
+ kore_buf_append(resp_buf, asset_html_header_html, asset_len_html_header_html);
kore_buf_appendf(resp_buf, (const char *) asset_error_html, error_msg[status]);
- kore_buf_append(resp_buf, asset_footer_html, asset_len_footer_html);
+ kore_buf_append(resp_buf, asset_html_footer_html, asset_len_html_footer_html);
http_response(req, status, resp_buf->data, resp_buf->offset);
@@ -192,7 +210,7 @@ int get_index(struct http_request *req) {
content = kore_buf_alloc(0);
- entry_query_init(&eq, NULL);
+ entry_query_init(&eq, NULL, NULL);
(void) sql_select(&eq);
if (eq.status != QUERY_STATUS_OK) {
@@ -200,21 +218,24 @@ int get_index(struct http_request *req) {
goto out;
}
+ // Write header.
+ kore_buf_append(content, asset_header_html, asset_len_header_html);
+
// Write table header.
- kore_buf_append(content, asset_index_header_html, asset_len_index_header_html);
+ kore_buf_append(content, asset_table_header_html, asset_len_table_header_html);
// Iterate over entries and render them.
for (row = 0; row < eq.num_entries; row++) {
// Append rendered MD entry.
kore_buf_appendf(
content,
- (const char *) asset_index_row_html,
+ (const char *) asset_table_row_html,
eq.entries[row]->id, eq.entries[row]->title, eq.entries[row]->created_at, eq.entries[row]->updated_at
);
}
// Write table footer.
- kore_buf_append(content, asset_index_footer_html, asset_len_index_footer_html);
+ kore_buf_append(content, asset_table_footer_html, asset_len_table_footer_html);
http_ok_resp(req, HTTP_STATUS_OK, content);
@@ -238,7 +259,7 @@ int get_entry(struct http_request *req) {
content = kore_buf_alloc(0);
rendered_body = kore_buf_alloc(0);
- entry_query_init(&eq, req->path + strlen("/entries/"));
+ entry_query_init(&eq, req->path + strlen("/entries/"), NULL);
// Check for valid resource UUID
kore_log(LOG_DEBUG, "Resource id /entries/%s.", eq.id);
@@ -300,7 +321,7 @@ int edit_entry(struct http_request *req) {
id = kore_strdup(req->path + strlen("/entries/"));
id[strlen(id) - strlen("/edit")] = '\0';
- entry_query_init(&eq, (const char*) id);
+ entry_query_init(&eq, (const char*) id, NULL);
// Check for valid resource UUID
kore_log(LOG_DEBUG, "Resource id /entries/%s.", eq.id);
@@ -410,13 +431,64 @@ out: ;
int search_entries(struct http_request *req) {
- // int err = 0;
+ int err = 0;
- kore_log(LOG_INFO, "search ....");
+ int row = 0;
- http_err_resp(req, HTTP_STATUS_OK);
+ char *query = NULL;
-// out: ;
+ struct entry_query eq;
+
+ struct kore_buf *content = NULL;
+
+ content = kore_buf_alloc(0);
+
+ http_populate_get(req);
+
+ err = http_argument_get_string(req, "query", &query);
+ if (err == KORE_RESULT_OK) {
+ kore_log(LOG_INFO, "query string: '%s'", query);
+ }
+
+ entry_query_init(&eq, NULL, query);
+
+ (void) sql_select(&eq);
+ if (eq.status != QUERY_STATUS_OK) {
+ http_err_resp(req, HTTP_STATUS_INTERNAL_ERROR);
+ goto out;
+ }
+
+ // Write header.
+ kore_buf_append(content, asset_header_html, asset_len_header_html);
+
+ // Write search form.
+ kore_buf_append(content, asset_search_html, asset_len_search_html);
+
+ if (eq.num_entries > 0) {
+ // Write table header.
+ kore_buf_append(content, asset_table_header_html, asset_len_table_header_html);
+
+ // Iterate over entries and render them.
+ for (row = 0; row < eq.num_entries; row++) {
+ // Append rendered MD entry.
+ kore_buf_appendf(
+ content,
+ (const char *) asset_table_row_html,
+ eq.entries[row]->id, eq.entries[row]->title, eq.entries[row]->created_at, eq.entries[row]->updated_at
+ );
+ }
+
+ // Write table footer.
+ kore_buf_append(content, asset_table_footer_html, asset_len_table_footer_html);
+ }
+
+ http_ok_resp(req, HTTP_STATUS_OK, content);
+
+out: ;
+
+ entry_query_cleanup(&eq);
+
+ kore_free(content);
return KORE_RESULT_OK;
}
@@ -449,7 +521,16 @@ int sql_select(struct entry_query *eq) {
1, // param count
KORE_PGSQL_PARAM_TEXT(eq->id)
);
- } else {
+ }
+ else if (eq->query != NULL) {
+ err = kore_pgsql_query_params(&sql, q_search_entries,
+ 0, // return string data
+ 2, // param count
+ KORE_PGSQL_PARAM_TEXT(eq->query),
+ KORE_PGSQL_PARAM_TEXT(eq->query)
+ );
+ }
+ else {
// Query for index.
err = kore_pgsql_query(&sql, q_select_entries);
}
diff --git a/src/queries.h b/src/queries.h
index a55fafb..7fbe898 100644
--- a/src/queries.h
+++ b/src/queries.h
@@ -11,13 +11,13 @@ const char *q_select_entries =
const char *q_search_entries =
"WITH query AS "
"( "
-" SELECT id, title, created_at::DATE, updated_at::DATE, "
+" SELECT id, title, created_at::DATE, updated_at::DATE, body, "
" TS_RANK(search_vector, TO_TSQUERY('english', $1)) AS rank "
" FROM entries "
" WHERE search_vector @@ TO_TSQUERY('english', $2) "
" ORDER BY rank DESC "
") "
-"SELECT id, title, created_at::DATE, updated_at::DATE FROM query;";
+"SELECT id, title, created_at::DATE, updated_at::DATE, body FROM query;";
const char *q_update_entry =
"UPDATE entries "