From 6d37bd9734a943f8672a897d8471db72fa204e94 Mon Sep 17 00:00:00 2001 From: Tobias Reisinger Date: Thu, 13 Aug 2020 16:29:26 +0200 Subject: [PATCH] add: cache (WIP) --- CMakeLists.txt | 2 +- include/cache.h | 43 ++++ include/models/controller.h | 3 +- include/models/junction_tag.h | 3 - include/models/relay.h | 5 +- include/models/schedule.h | 3 +- sql/cache.sql | 11 +- src/cache.c | 203 +++++++++++++++++- src/database.c | 2 +- src/endpoints/api_v1_controllers.c | 2 +- src/endpoints/api_v1_controllers_STR.c | 4 +- src/endpoints/api_v1_controllers_STR_relays.c | 2 +- .../api_v1_controllers_STR_relays_INT.c | 4 +- src/endpoints/api_v1_relays.c | 2 +- src/endpoints/api_v1_relays_tag_STR.c | 2 +- src/endpoints/api_v1_schedules.c | 4 +- src/endpoints/api_v1_schedules_STR.c | 4 +- src/endpoints/api_v1_schedules_tag_STR.c | 2 +- src/endpoints/api_v1_tags_STR.c | 4 +- src/main.c | 4 +- src/models/controller.c | 21 +- src/models/junction_tag.c | 39 ++-- src/models/relay.c | 32 ++- src/models/schedule.c | 18 +- src/models/tag.c | 3 + src/status.c | 4 +- 26 files changed, 365 insertions(+), 61 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d2bddf2..e86616b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 3.7) project(core - VERSION 0.2.6 + VERSION 0.2.7 LANGUAGES C) add_executable(core src/main.c) diff --git a/include/cache.h b/include/cache.h index 3e1ca63..0c86efc 100644 --- a/include/cache.h +++ b/include/cache.h @@ -3,9 +3,52 @@ #include +#include +#include +#include + extern sqlite3 *cache_database; void cache_init(); +void +cache_free(); + + +void +cache_put_json_schedule(int schedule_id, char *schedule_json); + +char* +cache_get_json_schedule(int schedule_id); + +void +cache_invalidate_schedule(int schedule_id); + + +void +cache_put_json_relay(int relay_id, char *relay_json); + +char* +cache_get_json_relay(int relay_id); + +void +cache_invalidate_relay(int relay_id); + + + +void +cache_put_json_controller(int controller_id, char *controller_json); + +char* +cache_get_json_controller(int controller_id); + +void +cache_invalidate_controller(int controller_id); + + + +void +cache_invalidate_tagged(int tag_id); + #endif /* CORE_CACHE_H */ diff --git a/include/models/controller.h b/include/models/controller.h index 0aaff64..15026d8 100644 --- a/include/models/controller.h +++ b/include/models/controller.h @@ -5,7 +5,6 @@ #include #include -#include #include #include @@ -32,7 +31,7 @@ controller_save(controller_t* contoller); int controller_remove(controller_t* contoller); -cJSON* +char* controller_to_json(controller_t* contoller); controller_t* diff --git a/include/models/junction_tag.h b/include/models/junction_tag.h index f362c62..a8772e9 100644 --- a/include/models/junction_tag.h +++ b/include/models/junction_tag.h @@ -19,9 +19,6 @@ junction_tag_insert(int tag_id, int relay_id, int schedule_id); int junction_tag_remove(int tag_id, int relay_id, int schedule_id); -int -junction_tag_remove_for_tag(int tag_id); - int junction_tag_remove_for_relay(int relay_id); diff --git a/include/models/relay.h b/include/models/relay.h index d5a4785..2e3af1e 100644 --- a/include/models/relay.h +++ b/include/models/relay.h @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -28,10 +27,10 @@ relay_save(); void relay_reload_active_schedule(relay_t *relay); -cJSON* +char* relay_to_json(relay_t *relay); -cJSON* +char* relay_list_to_json(relay_t **relays); void diff --git a/include/models/schedule.h b/include/models/schedule.h index 1950c58..0225a28 100644 --- a/include/models/schedule.h +++ b/include/models/schedule.h @@ -3,7 +3,6 @@ #include -#include #include #include @@ -31,7 +30,7 @@ schedule_free(schedule_t *schedule); void schedule_free_list(schedule_t **schedule); -cJSON* +char* schedule_to_json(schedule_t *schedule); void diff --git a/sql/cache.sql b/sql/cache.sql index a8904b5..5ca7471 100644 --- a/sql/cache.sql +++ b/sql/cache.sql @@ -1,5 +1,8 @@ -CREATE TABLE `cache` ( - `key` STRING PRIMARY KEY, - `value` TEXT NOT NULL, - `expiration` INT DEFAULT 0 +CREATE TABLE cache ( + key STRING + PRIMARY KEY, + value TEXT + NOT NULL, + expiration INT + DEFAULT 0 ); diff --git a/src/cache.c b/src/cache.c index e6c80d3..50bfbc2 100644 --- a/src/cache.c +++ b/src/cache.c @@ -1,9 +1,86 @@ #include #include +#include +#include sqlite3 *cache_database; +static char* +cache_get_value(char *key) +{ + sqlite3_stmt *stmt; + sqlite3_prepare_v2(cache_database, "SELECT value FROM cache WHERE key=?1;", -1, &stmt, NULL); + sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC); + + char *result = NULL; + + while(1) + { + int s; + + s = sqlite3_step(stmt); + if (s == SQLITE_ROW) + { + const char *found_value = (const char *)sqlite3_column_text(stmt, 0); + result = (char*)malloc(sizeof(char) * (strlen(found_value) + 1)); + strcpy(result, found_value); + } + else + { + if (s == SQLITE_DONE) + { + break; + } + else + { + LOGGER_WARNING("failed selecting %s from cache: %s\n", key, sqlite3_errstr(s)); + break; + } + } + } + + sqlite3_finalize(stmt); + + return result; +} + +static void +cache_insert_value(char *key, char *value) +{ + sqlite3_stmt *stmt; + sqlite3_prepare_v2(cache_database, "INSERT INTO cache (key, value, expiration) VALUES (?1, ?2, 0);", -1, &stmt, NULL); + sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 2, value, -1, SQLITE_STATIC); + + int rc = sqlite3_step(stmt); + + sqlite3_finalize(stmt); + + if(rc != SQLITE_DONE) + { + LOGGER_WARNING("failed to save %s to cache: %s\n", key, sqlite3_errstr(rc)); + } +} + +static void +cache_invalidate(char *key) +{ + sqlite3_stmt *stmt; + int rc; + + sqlite3_prepare_v2(cache_database, "DELETE FROM cache WHERE key=?1;", -1, &stmt, NULL); + sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC); + + rc = sqlite3_step(stmt); + sqlite3_finalize(stmt); + + if(rc != SQLITE_DONE) + { + LOGGER_WARNING("failed to invalidate %s in cache: %s\n", key, sqlite3_errstr(rc)); + } +} + void cache_init() { @@ -12,6 +89,130 @@ cache_init() if(rc) { LOGGER_CRIT("can't open cache database: %s\n", sqlite3_errmsg(cache_database)); - return; + exit(1); } + + char* err_msg; + rc = sqlite3_exec(cache_database, (const char *)sql_cache_sql, NULL, NULL, &err_msg); + if(rc) + { + LOGGER_CRIT("couldn't initialize cache (%s)\n", err_msg); + exit(1); + } + LOGGER_DEBUG("cache initalized\n"); +} + +void +cache_free() +{ + sqlite3_close(cache_database); +} + + + +void +cache_put_json_schedule(int schedule_id, char *schedule_json) +{ + char key[32]; + sprintf(key, "schedule_json:%d", schedule_id); + cache_insert_value(key, schedule_json); +} + +char* +cache_get_json_schedule(int schedule_id) +{ + char key[32]; + sprintf(key, "schedule_json:%d", schedule_id); + return cache_get_value(key); +} + +void +cache_invalidate_schedule(int schedule_id) +{ + char key[32]; + sprintf(key, "schedule_json:%d", schedule_id); + cache_invalidate(key); + + relay_t **relays = relay_get_with_schedule(schedule_id); + + for(int i = 0; relays[i] != NULL; ++i) + { + cache_invalidate_relay(relays[i]->id); + } + + relay_free_list(relays); +} + + + +void +cache_put_json_relay(int relay_id, char *relay_json) +{ + char key[32]; + sprintf(key, "relay_json:%d", relay_id); + cache_insert_value(key, relay_json); +} + +char* +cache_get_json_relay(int relay_id) +{ + char key[32]; + sprintf(key, "relay_json:%d", relay_id); + return cache_get_value(key); +} + +void +cache_invalidate_relay(int relay_id) +{ + char key[32]; + sprintf(key, "relay_json:%d", relay_id); + cache_invalidate(key); + + relay_t *relay = relay_get_by_id(relay_id); + cache_invalidate_controller(relay->controller_id); + relay_free(relay); +} + + + +void +cache_put_json_controller(int controller_id, char *controller_json) +{ + char key[32]; + sprintf(key, "controller_json:%d", controller_id); + cache_insert_value(key, controller_json); +} + +char* +cache_get_json_controller(int controller_id) +{ + char key[32]; + sprintf(key, "controller_json:%d", controller_id); + return cache_get_value(key); +} + +void +cache_invalidate_controller(int controller_id) +{ + char key[32]; + sprintf(key, "controller_json:%d", controller_id); + cache_invalidate(key); +} + +void +cache_invalidate_tagged(int tag_id) +{ + int *schedule_ids = junction_tag_get_schedules_for_tag_id(tag_id); + for(int i = 0; schedule_ids[i] != 0; ++i) + { + cache_invalidate_schedule(schedule_ids[i]); + } + free(schedule_ids); + + int *relay_ids = junction_tag_get_relays_for_tag_id(tag_id); + for(int i = 0; relay_ids[i] != 0; ++i) + { + cache_invalidate_relay(relay_ids[i]); + } + free(relay_ids); } diff --git a/src/database.c b/src/database.c index cb8baa7..50587cf 100644 --- a/src/database.c +++ b/src/database.c @@ -35,7 +35,7 @@ database_migrate() case 0: LOGGER_INFO("migrating LEVEL 0\n"); rc = sqlite3_exec(global_database, (const char *)sql_migration_0_sql, NULL, NULL, &err_msg); - if(rc != 0) + if(rc) { LOGGER_CRIT("couldn't migrate LEVEL 0 (%s)\n", err_msg); break; diff --git a/src/endpoints/api_v1_controllers.c b/src/endpoints/api_v1_controllers.c index f233bec..6d474d5 100644 --- a/src/endpoints/api_v1_controllers.c +++ b/src/endpoints/api_v1_controllers.c @@ -19,7 +19,7 @@ api_v1_controllers_GET(struct mg_connection *nc, struct http_message *hm, endpoi for(int i = 0; all_controllers[i] != NULL; ++i) { - cJSON *json_controller = controller_to_json(all_controllers[i]); + cJSON *json_controller = cJSON_CreateRaw(controller_to_json(all_controllers[i])); cJSON_AddItemToArray(json, json_controller); } diff --git a/src/endpoints/api_v1_controllers_STR.c b/src/endpoints/api_v1_controllers_STR.c index 293506d..dbe3494 100644 --- a/src/endpoints/api_v1_controllers_STR.c +++ b/src/endpoints/api_v1_controllers_STR.c @@ -36,7 +36,7 @@ api_v1_controllers_STR_GET(struct mg_connection *nc, struct http_message *hm, en return; } - cJSON *json = controller_to_json(controller); + cJSON *json = cJSON_CreateRaw(controller_to_json(controller)); endpoint_response_json(response, 200, json); cJSON_Delete(json); @@ -140,7 +140,7 @@ api_v1_controllers_STR_PUT(struct mg_connection *nc, struct http_message *hm, en } cJSON_Delete(json); - json = controller_to_json(controller); + json = cJSON_CreateRaw(controller_to_json(controller)); command_set_controller_name(controller); diff --git a/src/endpoints/api_v1_controllers_STR_relays.c b/src/endpoints/api_v1_controllers_STR_relays.c index 87c866f..281e2ef 100644 --- a/src/endpoints/api_v1_controllers_STR_relays.c +++ b/src/endpoints/api_v1_controllers_STR_relays.c @@ -39,7 +39,7 @@ api_v1_controllers_STR_relays_GET(struct mg_connection *nc, struct http_message for(int i = 0; all_relays[i] != NULL; ++i) { - cJSON *json_relay = relay_to_json(all_relays[i]); + cJSON *json_relay = cJSON_CreateRaw(relay_to_json(all_relays[i])); cJSON_AddItemToArray(json, json_relay); } diff --git a/src/endpoints/api_v1_controllers_STR_relays_INT.c b/src/endpoints/api_v1_controllers_STR_relays_INT.c index e6fa078..c10eb0d 100644 --- a/src/endpoints/api_v1_controllers_STR_relays_INT.c +++ b/src/endpoints/api_v1_controllers_STR_relays_INT.c @@ -47,7 +47,7 @@ api_v1_controllers_STR_relays_INT_GET(struct mg_connection *nc, struct http_mess return; } - cJSON *json = relay_to_json(relay); + cJSON *json = cJSON_CreateRaw(relay_to_json(relay)); endpoint_response_json(response, 200, json); cJSON_Delete(json); @@ -220,7 +220,7 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess } cJSON_Delete(json); - json = relay_to_json(relay); + json = cJSON_CreateRaw(relay_to_json(relay)); command_set_relay_schedule(relay); diff --git a/src/endpoints/api_v1_relays.c b/src/endpoints/api_v1_relays.c index b56d5da..ef76485 100644 --- a/src/endpoints/api_v1_relays.c +++ b/src/endpoints/api_v1_relays.c @@ -20,7 +20,7 @@ api_v1_relays_GET(struct mg_connection *nc, struct http_message *hm, endpoint_ar for(int i = 0; all_relays[i] != NULL; ++i) { - cJSON *json_relay = relay_to_json(all_relays[i]); + cJSON *json_relay = cJSON_CreateRaw(relay_to_json(all_relays[i])); cJSON_AddItemToArray(json, json_relay); } diff --git a/src/endpoints/api_v1_relays_tag_STR.c b/src/endpoints/api_v1_relays_tag_STR.c index 4690a55..7d98962 100644 --- a/src/endpoints/api_v1_relays_tag_STR.c +++ b/src/endpoints/api_v1_relays_tag_STR.c @@ -40,7 +40,7 @@ api_v1_relays_tag_STR_GET(struct mg_connection *nc, struct http_message *hm, end { continue; } - cJSON *json_relay = relay_to_json(relay); + cJSON *json_relay = cJSON_CreateRaw(relay_to_json(relay)); cJSON_AddItemToArray(json, json_relay); diff --git a/src/endpoints/api_v1_schedules.c b/src/endpoints/api_v1_schedules.c index 2dad24d..6729f2f 100644 --- a/src/endpoints/api_v1_schedules.c +++ b/src/endpoints/api_v1_schedules.c @@ -145,7 +145,7 @@ api_v1_schedules_POST(struct mg_connection *nc, struct http_message *hm, endpoin } cJSON_Delete(json); - json = schedule_to_json(new_schedule); + json = cJSON_CreateRaw(schedule_to_json(new_schedule)); endpoint_response_json(response, 201, json); cJSON_Delete(json); @@ -165,7 +165,7 @@ api_v1_schedules_GET(struct mg_connection *nc, struct http_message *hm, endpoint for(int i = 0; all_schedules[i] != NULL; ++i) { - cJSON *json_schedule = schedule_to_json(all_schedules[i]); + cJSON *json_schedule = cJSON_CreateRaw(schedule_to_json(all_schedules[i])); cJSON_AddItemToArray(json, json_schedule); } diff --git a/src/endpoints/api_v1_schedules_STR.c b/src/endpoints/api_v1_schedules_STR.c index ca315b4..b241fc9 100644 --- a/src/endpoints/api_v1_schedules_STR.c +++ b/src/endpoints/api_v1_schedules_STR.c @@ -37,7 +37,7 @@ api_v1_schedules_STR_GET(struct mg_connection *nc, struct http_message *hm, endp return; } - cJSON *json = schedule_to_json(schedule); + cJSON *json = cJSON_CreateRaw(schedule_to_json(schedule)); endpoint_response_json(response, 200, json); cJSON_Delete(json); @@ -176,7 +176,7 @@ api_v1_schedules_STR_PUT(struct mg_connection *nc, struct http_message *hm, endp } cJSON_Delete(json); - json = schedule_to_json(schedule); + json = cJSON_CreateRaw(schedule_to_json(schedule)); endpoint_response_json(response, 200, json); cJSON_Delete(json); diff --git a/src/endpoints/api_v1_schedules_tag_STR.c b/src/endpoints/api_v1_schedules_tag_STR.c index b0d22ec..89dca44 100644 --- a/src/endpoints/api_v1_schedules_tag_STR.c +++ b/src/endpoints/api_v1_schedules_tag_STR.c @@ -40,7 +40,7 @@ api_v1_schedules_tag_STR_GET(struct mg_connection *nc, struct http_message *hm, { continue; } - cJSON *json_schedule = schedule_to_json(schedule); + cJSON *json_schedule = cJSON_CreateRaw(schedule_to_json(schedule)); cJSON_AddItemToArray(json, json_schedule); diff --git a/src/endpoints/api_v1_tags_STR.c b/src/endpoints/api_v1_tags_STR.c index 6cff7df..3f09a5c 100644 --- a/src/endpoints/api_v1_tags_STR.c +++ b/src/endpoints/api_v1_tags_STR.c @@ -52,7 +52,7 @@ api_v1_tags_STR_GET(struct mg_connection *nc, struct http_message *hm, endpoint_ { continue; } - cJSON *json_relay = relay_to_json(relay); + cJSON *json_relay = cJSON_CreateRaw(relay_to_json(relay)); cJSON_AddItemToArray(json_relays, json_relay); @@ -66,7 +66,7 @@ api_v1_tags_STR_GET(struct mg_connection *nc, struct http_message *hm, endpoint_ { continue; } - cJSON *json_schedule = schedule_to_json(schedule); + cJSON *json_schedule = cJSON_CreateRaw(schedule_to_json(schedule)); cJSON_AddItemToArray(json_schedules, json_schedule); diff --git a/src/main.c b/src/main.c index a618bc9..367259e 100644 --- a/src/main.c +++ b/src/main.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -30,6 +31,7 @@ terminate(int signum) router_free(); status_free(); + cache_free(); closelog(); @@ -54,7 +56,6 @@ main(int argc, const char** argv) setlogmask(LOG_UPTO(LOG_INFO)); - /******************** LOAD CONFIG ********************/ global_config.file = "core.ini"; @@ -152,6 +153,7 @@ main(int argc, const char** argv) /******************** INIT COMPONENTS ********************/ + cache_init(); router_init(); status_init(); diff --git a/src/models/controller.c b/src/models/controller.c index 7e72671..91df69d 100644 --- a/src/models/controller.c +++ b/src/models/controller.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -144,6 +145,9 @@ controller_save(controller_t *controller) controller->id = sqlite3_last_insert_rowid(global_database); } } + + cache_invalidate_controller(controller->id); + return result; } @@ -183,9 +187,15 @@ controller_free_list(controller_t **controllers) free(controllers); } -cJSON* +char* controller_to_json(controller_t *controller) { + char *cached = cache_get_json_controller(controller->id); + if(cached) + { + return cached; + } + char uuid_str[UUID_STR_LEN]; uuid_unparse(controller->uid, uuid_str); @@ -245,12 +255,17 @@ controller_to_json(controller_t *controller) cJSON *json_relays = cJSON_CreateArray(); for(int i = 0; relays[i] != NULL; ++i) { - cJSON_AddItemToArray(json_relays, relay_to_json(relays[i])); + cJSON *json_relay = cJSON_CreateRaw(relay_to_json(relays[i])); + cJSON_AddItemToArray(json_relays, json_relay); } cJSON_AddItemToObject(json, "relays", json_relays); relay_free_list(relays); - return json; + char *result = cJSON_Print(json); + cJSON_Delete(json); + + cache_put_json_controller(controller->id, result); + return result; } controller_t* diff --git a/src/models/junction_tag.c b/src/models/junction_tag.c index 1526c02..21b40ae 100644 --- a/src/models/junction_tag.c +++ b/src/models/junction_tag.c @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -38,12 +39,21 @@ junction_tag_insert(int tag_id, int relay_id, int schedule_id) if (rc != SQLITE_DONE) { printf("ERROR inserting data: %s\n", sqlite3_errmsg(global_database)); - return false; + return 1; } sqlite3_finalize(stmt); - return true; + if(relay_id) + { + cache_invalidate_relay(relay_id); + } + if(schedule_id) + { + cache_invalidate_schedule(schedule_id); + } + + return 0; } static int* @@ -148,19 +158,14 @@ junction_tag_remove(int tag_id, int relay_id, int schedule_id) rc = sqlite3_step(stmt); sqlite3_finalize(stmt); - return rc == SQLITE_DONE; -} - -int -junction_tag_remove_for_tag(int tag_id) -{ - sqlite3_stmt *stmt; - int rc; - - sqlite3_prepare_v2(global_database, "DELETE FROM junction_tag WHERE tag_id=?1;", -1, &stmt, NULL); - sqlite3_bind_int(stmt, 1, tag_id); - rc = sqlite3_step(stmt); - sqlite3_finalize(stmt); + if(relay_id) + { + cache_invalidate_relay(relay_id); + } + if(schedule_id) + { + cache_invalidate_schedule(schedule_id); + } return rc == SQLITE_DONE; } @@ -176,6 +181,8 @@ junction_tag_remove_for_relay(int relay_id) rc = sqlite3_step(stmt); sqlite3_finalize(stmt); + cache_invalidate_relay(relay_id); + return rc == SQLITE_DONE; } @@ -190,5 +197,7 @@ junction_tag_remove_for_schedule(int schedule_id) rc = sqlite3_step(stmt); sqlite3_finalize(stmt); + cache_invalidate_schedule(schedule_id); + return rc == SQLITE_DONE; } diff --git a/src/models/relay.c b/src/models/relay.c index 8c86e8c..4783459 100644 --- a/src/models/relay.c +++ b/src/models/relay.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -161,7 +162,9 @@ relay_save(relay_t *relay) junction_relay_schedule_insert(i, relay->id, relay->schedules[i]->id); } + cache_invalidate_relay(relay->id); status_reload_entry(relay->id); + return result; } @@ -193,9 +196,15 @@ relay_free_list(relay_t **relays) free(relays); } -cJSON* +char* relay_to_json(relay_t *relay) { + char *cached = cache_get_json_relay(relay->id); + if(cached) + { + return cached; + } + controller_t *controller = controller_get_by_id(relay->controller_id); if(!controller) { @@ -255,12 +264,14 @@ relay_to_json(relay_t *relay) } cJSON_AddItemToObject(json, "is_on", json_is_on); - cJSON_AddItemToObject(json, "active_schedule", schedule_to_json(relay->active_schedule)); + cJSON *json_active_schedule = cJSON_CreateRaw(schedule_to_json(relay->active_schedule)); + cJSON_AddItemToObject(json, "active_schedule", json_active_schedule); cJSON *json_schedules = cJSON_CreateArray(); for(int i = 0; i < 7; ++i) { - cJSON_AddItemToArray(json_schedules, schedule_to_json(relay->schedules[i])); + cJSON *json_schedule = cJSON_CreateRaw(schedule_to_json(relay->schedules[i])); + cJSON_AddItemToArray(json_schedules, json_schedule); } cJSON_AddItemToObject(json, "schedules", json_schedules); @@ -290,20 +301,27 @@ relay_to_json(relay_t *relay) } cJSON_AddItemToObject(json, "tags", json_tags); - return json; + char *result = cJSON_Print(json); + cJSON_Delete(json); + + cache_put_json_relay(relay->id, result); + return result; } -cJSON* +char* relay_list_to_json(relay_t **relays) { cJSON *json = cJSON_CreateArray(); for(int i = 0; relays[i] != NULL; ++i) { - cJSON *json_relay = relay_to_json(relays[i]); + cJSON *json_relay = cJSON_CreateRaw(relay_to_json(relays[i])); cJSON_AddItemToArray(json, json_relay); } - return json; + + char *result = cJSON_Print(json); + cJSON_Delete(json); + return result; } relay_t* diff --git a/src/models/schedule.c b/src/models/schedule.c index 27c78b1..49292b1 100644 --- a/src/models/schedule.c +++ b/src/models/schedule.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -139,6 +140,9 @@ schedule_save(schedule_t *schedule) schedule->id = sqlite3_last_insert_rowid(global_database); } } + + cache_invalidate_schedule(schedule->id); + return result; } @@ -215,9 +219,15 @@ schedule_periods_to_blob(schedule_t *schedule) return blob; } -cJSON* +char* schedule_to_json(schedule_t *schedule) { + char *cached = cache_get_json_schedule(schedule->id); + if(cached) + { + return cached; + } + char uuid_str[UUID_STR_LEN]; schedule_uid_unparse(schedule->uid, uuid_str); @@ -309,7 +319,11 @@ schedule_to_json(schedule_t *schedule) } cJSON_AddItemToObject(json, "tags", json_tags); - return json; + char *result = cJSON_Print(json); + cJSON_Delete(json); + + cache_put_json_schedule(schedule->id, result); + return result; } schedule_t* diff --git a/src/models/tag.c b/src/models/tag.c index e86541c..f86f08b 100644 --- a/src/models/tag.c +++ b/src/models/tag.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -163,6 +164,8 @@ tag_get_id(const char *tag) int tag_remove(int id) { + cache_invalidate_tagged(id); + sqlite3_stmt *stmt; int rc; diff --git a/src/status.c b/src/status.c index ee08c09..3b90385 100644 --- a/src/status.c +++ b/src/status.c @@ -1,3 +1,5 @@ +#include + #include #include @@ -65,7 +67,7 @@ validate_json_str_cache() { relay_t **relays = global_relay_status_list; - cJSON *json = relay_list_to_json(relays); + cJSON *json = cJSON_CreateRaw(relay_list_to_json(relays)); char *json_str = cJSON_Print(json); size_t json_str_len = strlen(json_str);