aboutsummaryrefslogtreecommitdiff
path: root/data/server.c
diff options
context:
space:
mode:
authorPaul Oliver <contact@pauloliver.dev>2026-05-26 00:02:01 +0200
committerPaul Oliver <contact@pauloliver.dev>2026-05-30 15:06:02 +0200
commit2fc73d820d0442ab813c1ac11dff6d7cb1d8f50b (patch)
treef3a4920ca09555fe3a684b4935a7cc2117b3f2d9 /data/server.c
parent848c5cca715c514ce6e57e0fa7ef8e71b09c0b08 (diff)
Adds working data client
Diffstat (limited to 'data/server.c')
-rw-r--r--data/server.c89
1 files changed, 83 insertions, 6 deletions
diff --git a/data/server.c b/data/server.c
index 8581b83..d54d853 100644
--- a/data/server.c
+++ b/data/server.c
@@ -15,9 +15,44 @@ struct Socket {
struct sockaddr_in addr;
};
+struct json_object *g_response_header;
+
// ----------------------------------------------------------------------------
-// SQL functions
+// SQL callbacks
// ----------------------------------------------------------------------------
+void sql_callback_add_column_name(sqlite3_stmt *sql_stmt, void *data) {
+ assert(sql_stmt);
+ assert(data);
+ assert(sqlite3_column_type(sql_stmt, 0) == SQLITE_TEXT);
+ assert(!strcmp(sqlite3_column_name(sql_stmt, 0), "name"));
+
+ const char *col_name = (const char *)sqlite3_column_text(sql_stmt, 0);
+ struct json_object *response = (struct json_object *)data;
+
+ if (!json_object_object_get_ex(response, col_name, NULL)) {
+ json_object_object_add(response, col_name, json_object_new_array());
+ }
+}
+
+void sql_callback_add_data(sqlite3_stmt *sql_stmt, void *data) {
+ assert(sql_stmt);
+ assert(data);
+
+ struct json_object *response = (struct json_object *)data;
+
+ for (int i = 0; i < sqlite3_column_count(sql_stmt); i++) {
+ const char *col_name = sqlite3_column_name(sql_stmt, i);
+ struct json_object *col_data = json_object_object_get(response, col_name);
+
+ if (col_data) {
+ if (sqlite3_column_type(sql_stmt, i) == SQLITE_BLOB) {
+ // TODO: render blobs in parallel
+ } else {
+ json_object_array_add(col_data, json_object_new_int64(sqlite3_column_int64(sql_stmt, i)));
+ }
+ }
+ }
+}
// ----------------------------------------------------------------------------
// Main functions
@@ -25,6 +60,7 @@ struct Socket {
void sig_handler(int signo) {
(void)signo;
log_warn("Signal received, will stop SALIS data server");
+ json_object_put(g_response_header);
sql_close();
exit(0);
}
@@ -65,15 +101,45 @@ void respond_data(int socket_fd, struct json_object *request) {
const char *request_str = json_object_to_json_string(request);
log_info("Client requested simulation data with the following parameters: %s", request_str);
+ const char *x_axis = json_object_get_string(json_object_object_get(request, "x-axis"));
+ int64_t x_current = json_object_get_int64(json_object_object_get(request, "x-current"));
+ int64_t x_high = json_object_get_int64(json_object_object_get(request, "x-high"));
+ int64_t nth = json_object_get_int64(json_object_object_get(request, "nth"));
+ int64_t entries = json_object_get_int64(json_object_object_get(request, "entries"));
+
+ const char *x_axis_pref = (!strcmp(x_axis, "rowid") || !strcmp(x_axis, "step")) ? "core." : "";
+
+ struct json_object *response = NULL;
+ json_object_deep_copy(g_response_header, &response, NULL);
+
+ sql_exec(
+ 0, NULL, NULL,
+ sql_callback_add_data,
+ response,
+ "select * from ("
+ "select core.rowid, core.step, * from core inner join arch "
+ "where core.rowid = arch.rowid and %s%s > %ld and %s%s <= %ld and core.rowid %% %ld == 0 "
+ "order by %s%s desc limit %ld"
+ ") order by %s asc;",
+ x_axis_pref,
+ x_axis,
+ x_current,
+ x_axis_pref,
+ x_axis,
+ x_high,
+ nth,
+ x_axis_pref,
+ x_axis,
+ entries,
+ x_axis
+ );
- struct json_object *response = json_object_new_object();
- json_object_object_add(response, "response", json_object_new_string("hello!"));
const char *response_str = json_object_to_json_string(response);
- log_info("Sending response to client: %s", response_str);
+ log_info("Responding to client with: %s", response_str);
json_object_to_fd(socket_fd, response, 0);
+ json_object_put(response);
shutdown(socket_fd, SHUT_WR);
- json_object_put(response);
}
int handle_client(struct Socket *socket) {
@@ -120,6 +186,17 @@ int main(void) {
signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler);
+ log_info("Creating response header");
+ g_response_header = json_object_new_object();
+ json_object_object_add(g_response_header, "rowid", json_object_new_array());
+ sql_exec(
+ 0, NULL, NULL,
+ sql_callback_add_column_name,
+ g_response_header,
+ "select name from pragma_table_info('core') union "
+ "select name from pragma_table_info('arch');"
+ );
+
log_info("Binding to port: %d", PORT);
int opt = 1;
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
@@ -130,8 +207,8 @@ int main(void) {
socket_addr.sin_port = htons(PORT);
bind(socket_fd, (struct sockaddr *)&socket_addr, sizeof(struct sockaddr_in));
- log_info("Listening...");
listen(socket_fd, BACKLOG);
+ log_info("Listening...");
while (true) {
struct Socket *socket = calloc(1, sizeof(struct Socket));