diff --git a/.drone.yml b/.drone.yml index e0ed31a..ce40462 100644 --- a/.drone.yml +++ b/.drone.yml @@ -29,12 +29,12 @@ steps: image: serguzim/emgauwa-builder pull: always commands: - - tar xzf emgauwa-controller.tar.gz - - cd controller - - mkdir build - - cd build - - cmake -DWIRING_PI_DEBUG=on .. - - make + - tar xzf emgauwa-controller.tar.gz + - cd controller + - mkdir build + - cd build + - cmake -DWIRING_PI_DEBUG=on .. + - make - name: test image: serguzim/emgauwa-builder diff --git a/.editorconfig b/.editorconfig index 146a218..ab2168d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,7 +10,3 @@ end_of_line = lf insert_final_newline = true indent_style = space indent_size = 4 - -[*.yml] -indent_style = space -indent_size = 2 diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a34ecd..a763453 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 3.7) project(core - VERSION 0.3.5 + VERSION 0.3.4 LANGUAGES C) add_executable(core src/main.c) @@ -43,44 +43,38 @@ add_custom_target(run DEPENDS core WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) +add_custom_target(debug + COMMAND valgrind -s ./core start + DEPENDS core + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} +) +add_custom_target(debug-leak + COMMAND valgrind --leak-check=full --show-leak-kinds=all ./core start + DEPENDS core + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} +) +add_custom_target(debug-callgrind + COMMAND valgrind --tool=callgrind ./core start + DEPENDS core + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} +) +add_custom_target(docs + COMMAND doxygen + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} +) add_custom_target(test COMMAND ./run_tests.sh ${CMAKE_BINARY_DIR}/core "--leak-check=full --show-leak-kinds=all --track-origins=yes" DEPENDS core WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests ) - -add_custom_target(docs - COMMAND doxygen +add_custom_target(test-callgrind + COMMAND ./run_tests.sh ${CMAKE_BINARY_DIR}/core "--tool=callgrind" + DEPENDS core + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests +) +add_custom_target(coverage + COMMAND gcovr -s --root ${CMAKE_SOURCE_DIR} -e ${CMAKE_SOURCE_DIR}/vendor --html-details ${CMAKE_BINARY_DIR}/coverage.html --html-title "Emgauwa Core Coverage" ${CMAKE_BINARY_DIR}/CMakeFiles/core.dir + DEPENDS test WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ) - -IF(CMAKE_BUILD_TYPE MATCHES Debug) - message("debug mode") - add_custom_target(debug - COMMAND valgrind -s ./core start - DEPENDS core - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - ) - add_custom_target(debug-leak - COMMAND valgrind --leak-check=full --show-leak-kinds=all ./core start - DEPENDS core - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - ) - add_custom_target(debug-callgrind - COMMAND valgrind --tool=callgrind ./core start - DEPENDS core - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - ) - add_custom_target(coverage - COMMAND gcovr -s --root ${CMAKE_SOURCE_DIR} -e ${CMAKE_SOURCE_DIR}/vendor --html-details ${CMAKE_BINARY_DIR}/coverage.html --html-title "Emgauwa Core Coverage" ${CMAKE_BINARY_DIR}/CMakeFiles/core.dir - DEPENDS test - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - ) - - add_custom_target(test-callgrind - COMMAND ./run_tests.sh ${CMAKE_BINARY_DIR}/core "--tool=callgrind" - DEPENDS core - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests - ) -ENDIF(CMAKE_BUILD_TYPE MATCHES Debug) diff --git a/include/cache.h b/include/cache.h index 3e2ff7c..8fde368 100644 --- a/include/cache.h +++ b/include/cache.h @@ -36,6 +36,7 @@ void cache_invalidate_relay(int relay_id, int status_relay); + void cache_put_json_controller(int controller_id, char *controller_json); @@ -46,16 +47,6 @@ void cache_invalidate_controller(int controller_id); -void -cache_put_json_macro(int macro_id, char *macro_json); - -char* -cache_get_json_macro(int macro_id); - -void -cache_invalidate_macro(int macro_id); - - void cache_invalidate_tagged(int tag_id); diff --git a/include/database.h b/include/database.h index c393013..dde8177 100644 --- a/include/database.h +++ b/include/database.h @@ -3,8 +3,6 @@ #include <sqlite3.h> -typedef int database_transaction_lock; - extern sqlite3 *global_database; void @@ -17,14 +15,14 @@ void database_migrate(); -void -database_transaction_begin(database_transaction_lock *lock); +int +database_transaction_begin(); void -database_transaction_commit(database_transaction_lock *lock); +database_transaction_commit(); void -database_transaction_rollback(database_transaction_lock *lock); +database_transaction_rollback(); int diff --git a/include/endpoints/api_v1_macros.h b/include/endpoints/api_v1_macros.h deleted file mode 100644 index 9a79271..0000000 --- a/include/endpoints/api_v1_macros.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef CORE_ENDPOINTS_API_V1_MACROS_H -#define CORE_ENDPOINTS_API_V1_MACROS_H - -#include <router.h> - -void -api_v1_macros_GET(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response); - -void -api_v1_macros_POST(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response); - -void -api_v1_macros_STR_GET(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response); - -void -api_v1_macros_STR_PUT(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response); - -void -api_v1_macros_STR_DELETE(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response); - -void -api_v1_macros_STR_execute_PUT(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response); - -#endif /* CORE_ENDPOINTS_API_V1_MACROS_H */ diff --git a/include/logger.h b/include/logger.h index 20c30e0..fc207f5 100644 --- a/include/logger.h +++ b/include/logger.h @@ -8,12 +8,9 @@ #include <colors.h> #include <config.h> -#define LOG_NONE INT_MAX - void logger_log(int level, const char *filename, int line, const char *func, const char *msg, ...); -#define LOGGER_NONE(...) logger_log(LOG_NONE , __FILE__, __LINE__, __func__, ##__VA_ARGS__) #define LOGGER_DEBUG(...) logger_log(LOG_DEBUG , __FILE__, __LINE__, __func__, ##__VA_ARGS__) #define LOGGER_INFO(...) logger_log(LOG_INFO , __FILE__, __LINE__, __func__, ##__VA_ARGS__) #define LOGGER_NOTICE(...) logger_log(LOG_NOTICE , __FILE__, __LINE__, __func__, ##__VA_ARGS__) diff --git a/include/macros.h b/include/macros.h index 062081a..4242abe 100644 --- a/include/macros.h +++ b/include/macros.h @@ -1,24 +1,6 @@ #ifndef CORE_MACROS_H #define CORE_MACROS_H -#include <logger.h> - -#define M_STRLEN(s) ((sizeof(s)/sizeof(s[0])) - sizeof(s[0])) - -#define M_RESPONSE_TEXT_STATIC(logger_func, response, code, content) do { logger_func("%s\n", content); endpoint_response_text(response, code, content, M_STRLEN(content)); } while(0) -#define M_RESPONSE_400_NO_VALID_JSON(response) M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request is not valid json") -#define M_RESPONSE_400_NO_VALID_ID(response) M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request does not contain valid id (uuid)") -#define M_RESPONSE_400_NO_NAME(response) M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request does not contain a name") - -#define M_RESPONSE_403_PROTECTED_SCHEDULE(response) M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 403, "the target schedule is protected") - -#define M_RESPONSE_404_NO_CONTROLLER_FOUND_FOR_ID(response) M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "no controller was found for the requested id") -#define M_RESPONSE_404_NO_SCHEDULE_FOUND_FOR_ID(response) M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "no schedule was found for the requested id") -#define M_RESPONSE_404_NO_MACRO_FOUND_FOR_ID(response) M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "no schedule was found for the requested id") -#define M_RESPONSE_404_NO_TAG_FOUND(response) M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "the requested tag was not found") - -#define M_RESPONSE_500_FAILED_TO_SAVE_TO_DATABASE(response) M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "the server failed to save to the database") -#define M_RESPONSE_500_FAILED_TO_READ_FROM_DATABASE(response) M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "the server failed to read from the database") -#define M_RESPONSE_500_FAILED_TO_DELETE_FROM_DATABASE(response) M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "the server failed to delete from the database") +#define STRLEN(s) ((sizeof(s)/sizeof(s[0])) - sizeof(s[0])) #endif /* CORE_MACROS_H */ diff --git a/include/models/junction_relay_schedule.h b/include/models/junction_relay_schedule.h index e3c81ac..d8ef168 100644 --- a/include/models/junction_relay_schedule.h +++ b/include/models/junction_relay_schedule.h @@ -10,7 +10,4 @@ junction_relay_schedule_remove_for_relay(int relay_id); int junction_relay_schedule_insert_weekdays(int relay_id, int *schedule_ids); -int* -junction_relay_schedule_get_relay_ids_with_schedule(int schedule_id); - #endif /* CORE_MODELS_JUNCTION_RELAY_SCHEDULE_H */ diff --git a/include/models/macro.h b/include/models/macro.h deleted file mode 100644 index d532902..0000000 --- a/include/models/macro.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef CORE_MACRO_H -#define CORE_MACRO_H - -#include <uuid/uuid.h> - -#include <cJSON.h> - -#include <constants.h> -#include <models/macro_action.h> - -typedef struct -{ - int id; - uuid_t uid; - char name[MAX_NAME_LENGTH + 1]; -} macro_t; - -int -macro_save(macro_t *macro); - -int -macro_remove(macro_t *macro); - -void -macro_free(macro_t *macro); - -void -macro_free_list(macro_t **macro); - -cJSON* -macro_to_json(macro_t *macro); - -void -macro_free_list(macro_t **macros_list); - -macro_t* -macro_get_by_id(int id); - -macro_t* -macro_get_by_uid(uuid_t uid); - -macro_t** -macro_get_all(); - -int* -macro_get_target_relay_ids(int macro_id); - -#endif /* CORE_MACRO_H */ diff --git a/include/models/macro_action.h b/include/models/macro_action.h deleted file mode 100644 index bd61d09..0000000 --- a/include/models/macro_action.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef CORE_MODELS_MACRO_ACTION_H -#define CORE_MODELS_MACRO_ACTION_H - -typedef struct -{ - int macro_id; - int relay_id; - int schedule_id; - uint8_t weekday; -} macro_action_t; - -int -macro_action_insert(macro_action_t *macro_action); - -int -macro_action_delete_for_macro(int macro_id); - -macro_action_t** -macro_action_get_for_macro(int macro_id); - -int -macro_action_execute(macro_action_t *macro_action); - -void -macro_action_free_list(macro_action_t **macro_actions); - -int* -macro_action_get_macro_ids_with_schedule(int schedule_id); - -int* -macro_action_get_macro_ids_with_relay(int relay_id); - -#endif /* CORE_MODELS_MACRO_ACTION_H */ diff --git a/sql/cache.sql b/sql/cache.sql index 3e4ce21..5ca7471 100644 --- a/sql/cache.sql +++ b/sql/cache.sql @@ -1,5 +1,3 @@ --- a key-value table used for the json-cache - CREATE TABLE cache ( key STRING PRIMARY KEY, diff --git a/sql/migration_0.sql b/sql/migration_0.sql index 939b907..12dda72 100644 --- a/sql/migration_0.sql +++ b/sql/migration_0.sql @@ -1,6 +1,4 @@ --- base migration - -CREATE TABLE controllers +create table controllers ( id INTEGER PRIMARY KEY @@ -16,7 +14,7 @@ CREATE TABLE controllers NOT NULL ); -CREATE TABLE relays +create table relays ( id INTEGER PRIMARY KEY @@ -30,7 +28,7 @@ CREATE TABLE relays ON DELETE CASCADE ); -CREATE TABLE schedules +create table schedules ( id INTEGER PRIMARY KEY @@ -42,7 +40,7 @@ CREATE TABLE schedules periods BLOB ); -CREATE TABLE tags +create table tags ( id INTEGER PRIMARY KEY @@ -52,7 +50,7 @@ CREATE TABLE tags UNIQUE ); -CREATE TABLE junction_tag +create table junction_tag ( tag_id INTEGER NOT NULL @@ -66,7 +64,7 @@ CREATE TABLE junction_tag ON DELETE CASCADE ); -CREATE TABLE junction_relay_schedule +create table junction_relay_schedule ( weekday SMALLINT NOT NULL, diff --git a/sql/migration_1.sql b/sql/migration_1.sql deleted file mode 100644 index 5078763..0000000 --- a/sql/migration_1.sql +++ /dev/null @@ -1,28 +0,0 @@ --- migration to add macros - -CREATE TABLE macros -( - id INTEGER - PRIMARY KEY - AUTOINCREMENT, - uid BLOB - NOT NULL - UNIQUE, - name VARCHAR(128) -); - -CREATE TABLE macro_actions -( - macro_id INTEGER - NOT NULL - REFERENCES macros (id) - ON DELETE CASCADE, - relay_id INTEGER - REFERENCES relays (id) - ON DELETE CASCADE, - schedule_id INTEGER - REFERENCES schedules (id) - ON DELETE CASCADE, - weekday SMALLINT - NOT NULL -); diff --git a/src/cache.c b/src/cache.c index 5345801..2636ead 100644 --- a/src/cache.c +++ b/src/cache.c @@ -1,9 +1,7 @@ #include <cache.h> #include <logger.h> #include <sql/cache.h> -#include <models/macro_action.h> #include <models/junction_tag.h> -#include <models/junction_relay_schedule.h> sqlite3 *cache_database; @@ -136,19 +134,14 @@ cache_invalidate_schedule(int schedule_id) sprintf(key, "schedule_json:%d", schedule_id); cache_invalidate(key); - int *relay_ids = junction_relay_schedule_get_relay_ids_with_schedule(schedule_id); - for(int i = 0; relay_ids[i] != 0; ++i) - { - cache_invalidate_relay(relay_ids[i], -1); - } - free(relay_ids); + relay_t **relays = relay_get_with_schedule(schedule_id); - int *macro_ids = macro_action_get_macro_ids_with_schedule(schedule_id); - for(int i = 0; macro_ids[i] != 0; ++i) + for(int i = 0; relays[i] != NULL; ++i) { - cache_invalidate_macro(macro_ids[i]); + cache_invalidate_relay(relays[i]->id, -1); } - free(macro_ids); + + relay_free_list(relays); } @@ -187,13 +180,6 @@ cache_invalidate_relay(int relay_id, int status_relay) { cache_invalidate_controller(controller_id); } - - int *macro_ids = macro_action_get_macro_ids_with_relay(relay_id); - for(int i = 0; macro_ids[i] != 0; ++i) - { - cache_invalidate_macro(macro_ids[i]); - } - free(macro_ids); } @@ -222,34 +208,6 @@ cache_invalidate_controller(int controller_id) cache_invalidate(key); } - - -void -cache_put_json_macro(int macro_id, char *macro_json) -{ - char key[32]; - sprintf(key, "macro_json:%d", macro_id); - cache_insert_value(key, macro_json); -} - -char* -cache_get_json_macro(int macro_id) -{ - char key[32]; - sprintf(key, "macro_json:%d", macro_id); - return cache_get_value(key); -} - -void -cache_invalidate_macro(int macro_id) -{ - char key[32]; - sprintf(key, "macro_json:%d", macro_id); - cache_invalidate(key); -} - - - void cache_invalidate_tagged(int tag_id) { diff --git a/src/command.c b/src/command.c index 9091a53..ec299ad 100644 --- a/src/command.c +++ b/src/command.c @@ -90,17 +90,13 @@ command_schedule_update(schedule_t *schedule) LOGGER_ERR("couldn't find controller for relay %d\n", relays[i]->id); continue; } + controller_free(controller); LOGGER_DEBUG("sending command to controller %s\n", controller->name); - result |= command_send(controller, payload, payload_size); - - controller_free(controller); } relay_free_list(relays); - free(payload); - return result; } diff --git a/src/database.c b/src/database.c index 7a46488..02fd75a 100644 --- a/src/database.c +++ b/src/database.c @@ -5,10 +5,9 @@ #include <database.h> #include <sql/migration_0.h> -#include <sql/migration_1.h> sqlite3 *global_database; -static database_transaction_lock *transaction_lock; +static int in_transaction; void database_init() @@ -24,7 +23,7 @@ database_init() database_migrate(); sqlite3_exec(global_database, "PRAGMA foreign_keys = ON", 0, 0, 0); - transaction_lock = NULL; + in_transaction = 0; } void @@ -33,35 +32,11 @@ database_free() sqlite3_close(global_database); } -static void -database_migrate_step_simple(int level, const char* sql_migration) -{ - LOGGER_INFO("migrating LEVEL %d\n", level); - char* err_msg; - - sqlite3_exec(global_database, "BEGIN TRANSACTION;", NULL, NULL, NULL); - - int rc = sqlite3_exec(global_database, sql_migration, NULL, NULL, &err_msg); - if(rc) - { - LOGGER_CRIT("couldn't migrate LEVEL %d (%s)\n", level, err_msg); - sqlite3_exec(global_database, "ROLLBACK TRANSACTION;", NULL, NULL, NULL); - exit(1); - } - - LOGGER_DEBUG("storing new user_version %d\n", level + 1); - char pragma_query[32]; - sprintf(pragma_query, "PRAGMA user_version=%d;", level + 1); - sqlite3_exec(global_database, pragma_query, 0, 0, 0); - - sqlite3_exec(global_database, "COMMIT TRANSACTION;", NULL, NULL, NULL); -} - void database_migrate() { uint16_t version_num = 0; - int s; + int s, rc; sqlite3_stmt *stmt; sqlite3_prepare_v2(global_database, "PRAGMA user_version;", -1, &stmt, NULL); s = sqlite3_step(stmt); @@ -74,54 +49,61 @@ database_migrate() version_num = 0; } + uint16_t new_version_num = version_num; + char* err_msg; + sqlite3_finalize(stmt); switch(version_num) { case 0: - database_migrate_step_simple(0, (const char*)sql_migration_0_sql); - __attribute__ ((fallthrough)); - case 1: - database_migrate_step_simple(1, (const char*)sql_migration_1_sql); - __attribute__ ((fallthrough)); + LOGGER_INFO("migrating LEVEL 0\n"); + rc = sqlite3_exec(global_database, (const char *)sql_migration_0_sql, NULL, NULL, &err_msg); + if(rc) + { + LOGGER_CRIT("couldn't migrate LEVEL 0 (%s)\n", err_msg); + exit(1); + } + new_version_num = 1; default: break; } + char pragma_query[32]; + sprintf(pragma_query, "PRAGMA user_version=%d;", new_version_num); + sqlite3_exec(global_database, pragma_query, 0, 0, 0); + LOGGER_DEBUG("storing new user_version %d\n", new_version_num); + return; } -void -database_transaction_begin(database_transaction_lock *lock) +int +database_transaction_begin() { - if(transaction_lock == NULL) + if(!in_transaction) { LOGGER_DEBUG("beginning transaction\n"); sqlite3_exec(global_database, "BEGIN TRANSACTION;", NULL, NULL, NULL); - transaction_lock = lock; + in_transaction = 1; + return 1; } + return 0; } void -database_transaction_commit(database_transaction_lock *lock) +database_transaction_commit() { - if(transaction_lock == lock) - { - LOGGER_DEBUG("commiting transaction\n"); - sqlite3_exec(global_database, "COMMIT TRANSACTION;", NULL, NULL, NULL); - transaction_lock = NULL; - } + LOGGER_DEBUG("commiting transaction\n"); + sqlite3_exec(global_database, "COMMIT TRANSACTION;", NULL, NULL, NULL); + in_transaction = 0; } void -database_transaction_rollback(database_transaction_lock *lock) +database_transaction_rollback() { - if(transaction_lock == lock) - { - LOGGER_DEBUG("rolling back transaction\n"); - sqlite3_exec(global_database, "ROLLBACK TRANSACTION;", NULL, NULL, NULL); - transaction_lock = NULL; - } + LOGGER_DEBUG("rolling back transaction\n"); + sqlite3_exec(global_database, "ROLLBACK TRANSACTION;", NULL, NULL, NULL); + in_transaction = 0; } int diff --git a/src/endpoint.c b/src/endpoint.c index 5173538..a56f277 100644 --- a/src/endpoint.c +++ b/src/endpoint.c @@ -53,7 +53,7 @@ endpoint_response_text(endpoint_response_t *response, int status_code, const cha response->status_code = status_code; response->content_type = "text/plain"; - if(content_length) + if(content_length >= 0) { response->content_length = content_length; response->alloced_content = false; @@ -84,5 +84,8 @@ endpoint_response_json(endpoint_response_t *response, int status_code, const cJS } } - M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "failed to print json"); + LOGGER_ERR("failed to print schedule json\n"); + + static const char content[] = "failed to print json"; + endpoint_response_text(response, status_code, content, STRLEN(content)); } diff --git a/src/endpoints/api_v1_controllers_STR.c b/src/endpoints/api_v1_controllers_STR.c index 0a6c0ba..eb4c24d 100644 --- a/src/endpoints/api_v1_controllers_STR.c +++ b/src/endpoints/api_v1_controllers_STR.c @@ -18,7 +18,10 @@ api_v1_controllers_STR_GET(struct mg_connection *nc, struct http_message *hm, en uuid_t target_uid; if(uuid_parse(args[0].value.v_str, target_uid)) { - M_RESPONSE_400_NO_VALID_ID(response); + LOGGER_DEBUG("failed to unparse uid\n"); + + static const char content[] = "given id was invalid"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } @@ -26,7 +29,10 @@ api_v1_controllers_STR_GET(struct mg_connection *nc, struct http_message *hm, en if(!controller) { - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "no controller found for id"); + LOGGER_DEBUG("could not find a controller for uid '%s'\n", args[0].value.v_str); + + static const char content[] = "no controller for id found"; + endpoint_response_text(response, 404, content, STRLEN(content)); return; } LOGGER_DEBUG("returning controller for uid '%s'\n", args[0].value.v_str); @@ -47,7 +53,10 @@ api_v1_controllers_STR_PUT(struct mg_connection *nc, struct http_message *hm, en uuid_t target_uid; if(uuid_parse(args[0].value.v_str, target_uid)) { - M_RESPONSE_400_NO_VALID_ID(response); + LOGGER_DEBUG("failed to unparse uid\n"); + + static const char content[] = "given id was invalid"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } @@ -55,7 +64,10 @@ api_v1_controllers_STR_PUT(struct mg_connection *nc, struct http_message *hm, en if(!controller) { - M_RESPONSE_404_NO_CONTROLLER_FOUND_FOR_ID(response); + LOGGER_DEBUG("could not find a controller for uid '%s'\n", args[0].value.v_str); + + static const char content[] = "no controller for id found"; + endpoint_response_text(response, 404, content, STRLEN(content)); return; } LOGGER_DEBUG("starting overwrite for controller %s\n", args[0].value.v_str); @@ -64,64 +76,70 @@ api_v1_controllers_STR_PUT(struct mg_connection *nc, struct http_message *hm, en if(json == NULL) { + static const char content[] = "no valid json was supplied"; + endpoint_response_text(response, 400, content, STRLEN(content)); controller_free(controller); - - M_RESPONSE_400_NO_VALID_JSON(response); return; } cJSON *json_name = cJSON_GetObjectItemCaseSensitive(json, "name"); if(json_name) { - if(!cJSON_IsString(json_name) || json_name->valuestring == NULL) + if(cJSON_IsString(json_name) && json_name->valuestring) { + strncpy(controller->name, json_name->valuestring, MAX_NAME_LENGTH); + controller->name[MAX_NAME_LENGTH] = '\0'; + LOGGER_DEBUG("new controller name: %s\n", controller->name); + } + else + { + static const char content[] = "the given name is no valid string"; + endpoint_response_text(response, 400, content, STRLEN(content)); cJSON_Delete(json); controller_free(controller); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the given name is invalid"); return; } - - strncpy(controller->name, json_name->valuestring, MAX_NAME_LENGTH); - controller->name[MAX_NAME_LENGTH] = '\0'; - LOGGER_DEBUG("new controller name: %s\n", controller->name); } cJSON *json_ip = cJSON_GetObjectItemCaseSensitive(json, "ip"); if(json_ip) { - if(!cJSON_IsString(json_ip) || json_ip->valuestring == NULL) + if(cJSON_IsString(json_ip) && json_ip->valuestring) { - cJSON_Delete(json); - controller_free(controller); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "no ip address given"); - return; - } - - unsigned char buf[sizeof(struct in_addr)]; - if(inet_pton(AF_INET, json_ip->valuestring, buf)) - { - strncpy(controller->ip, json_ip->valuestring, IP_LENGTH); - controller->ip[IP_LENGTH] = '\0'; - LOGGER_DEBUG("new controller ip: %s\n", controller->ip); + unsigned char buf[sizeof(struct in_addr)]; + if(inet_pton(AF_INET, json_ip->valuestring, buf)) + { + strncpy(controller->ip, json_ip->valuestring, IP_LENGTH); + controller->ip[IP_LENGTH] = '\0'; + LOGGER_DEBUG("new controller ip: %s\n", controller->ip); + } + else + { + static const char content[] = "the given ip address is no valid IPv4 address"; + endpoint_response_text(response, 400, content, STRLEN(content)); + cJSON_Delete(json); + controller_free(controller); + return; + } } else { + static const char content[] = "the given ip address is no valid string"; + endpoint_response_text(response, 400, content, STRLEN(content)); cJSON_Delete(json); controller_free(controller); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the given ip address is not valid"); return; } } if(controller_save(controller)) { + LOGGER_ERR("failed to save controller\n"); controller_free(controller); cJSON_Delete(json); - M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "failed to save controller to database"); + static const char content[] = "failed to save controller to database"; + endpoint_response_text(response, 500, content, STRLEN(content)); return; } LOGGER_DEBUG("saved controller %s\n", args[0].value.v_str); @@ -147,7 +165,10 @@ api_v1_controllers_STR_DELETE(struct mg_connection *nc, struct http_message *hm, uuid_t target_uid; if(uuid_parse(target_uid_str, target_uid)) { - M_RESPONSE_400_NO_VALID_ID(response); + LOGGER_DEBUG("failed to unparse uid\n"); + + static const char content[] = "given id was invalid"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } @@ -155,17 +176,24 @@ api_v1_controllers_STR_DELETE(struct mg_connection *nc, struct http_message *hm, if(!controller) { - M_RESPONSE_404_NO_CONTROLLER_FOUND_FOR_ID(response); + LOGGER_DEBUG("could not find a controller for uid '%s'\n", args[0].value.v_str); + + static const char content[] = "no controller for id found"; + endpoint_response_text(response, 404, content, STRLEN(content)); return; } if(controller_remove(controller)) { - M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "failed to remove controller from database"); + LOGGER_ERR("failed to remove controller from database\n"); + + static const char content[] = "failed to remove controller from database"; + endpoint_response_text(response, 500, content, STRLEN(content)); } else { - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 200, "deleted controller"); + LOGGER_DEBUG("deleted controller %s\n", args[0].value.v_str); + endpoint_response_text(response, 200, "", 0); } controller_free(controller); return; diff --git a/src/endpoints/api_v1_controllers_STR_relays.c b/src/endpoints/api_v1_controllers_STR_relays.c index ad8a83e..6accc90 100644 --- a/src/endpoints/api_v1_controllers_STR_relays.c +++ b/src/endpoints/api_v1_controllers_STR_relays.c @@ -15,7 +15,10 @@ api_v1_controllers_STR_relays_GET(struct mg_connection *nc, struct http_message uuid_t target_uid; if(uuid_parse(args[0].value.v_str, target_uid)) { - M_RESPONSE_400_NO_VALID_ID(response); + LOGGER_DEBUG("failed to unparse uid\n"); + + static const char content[] = "given id was invalid"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } @@ -23,7 +26,10 @@ api_v1_controllers_STR_relays_GET(struct mg_connection *nc, struct http_message if(!controller) { - M_RESPONSE_404_NO_CONTROLLER_FOUND_FOR_ID(response); + LOGGER_DEBUG("could not find a controller for uid '%s'\n", args[0].value.v_str); + + static const char content[] = "no controller for id found"; + endpoint_response_text(response, 404, content, STRLEN(content)); return; } diff --git a/src/endpoints/api_v1_controllers_STR_relays_INT.c b/src/endpoints/api_v1_controllers_STR_relays_INT.c index d6ec00d..738ad39 100644 --- a/src/endpoints/api_v1_controllers_STR_relays_INT.c +++ b/src/endpoints/api_v1_controllers_STR_relays_INT.c @@ -18,7 +18,10 @@ api_v1_controllers_STR_relays_INT_GET(struct mg_connection *nc, struct http_mess uuid_t target_uid; if(uuid_parse(args[0].value.v_str, target_uid)) { - M_RESPONSE_400_NO_VALID_ID(response); + LOGGER_DEBUG("failed to unparse uid\n"); + + static const char content[] = "given id was invalid"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } @@ -26,18 +29,21 @@ api_v1_controllers_STR_relays_INT_GET(struct mg_connection *nc, struct http_mess if(!controller) { - M_RESPONSE_404_NO_CONTROLLER_FOUND_FOR_ID(response); + LOGGER_DEBUG("could not find a controller for uid '%s'\n", args[0].value.v_str); + + static const char content[] = "no controller for id found"; + endpoint_response_text(response, 404, content, STRLEN(content)); return; } - int controller_id = controller->id; - controller_free(controller); - - relay_t* relay = relay_get_for_controller(controller_id, args[1].value.v_int); + relay_t* relay = relay_get_for_controller(controller->id, args[1].value.v_int); if(!relay) { - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "no relay for this controller found"); + LOGGER_DEBUG("could not find a relay with num %d for controller '%s'\n", args[1].value.v_int, args[0].value.v_str); + + static const char content[] = "no relay for this controller found"; + endpoint_response_text(response, 404, content, STRLEN(content)); return; } @@ -47,6 +53,7 @@ api_v1_controllers_STR_relays_INT_GET(struct mg_connection *nc, struct http_mess endpoint_response_json(response, 200, json); cJSON_Delete(json); relay_free(relay); + controller_free(controller); } void @@ -58,7 +65,10 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess uuid_t target_uid; if(uuid_parse(args[0].value.v_str, target_uid)) { - M_RESPONSE_400_NO_VALID_ID(response); + LOGGER_DEBUG("failed to unparse uid\n"); + + static const char content[] = "given id was invalid"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } @@ -66,21 +76,23 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess if(!controller) { - M_RESPONSE_404_NO_CONTROLLER_FOUND_FOR_ID(response); + LOGGER_DEBUG("could not find a controller for uid '%s'\n", args[0].value.v_str); + + static const char content[] = "no controller for id found"; + endpoint_response_text(response, 404, content, STRLEN(content)); return; } - int controller_id = controller->id; - int controller_relay_count = controller->relay_count; - controller_free(controller); - - if(args[1].value.v_int > controller_relay_count) + if(args[1].value.v_int > controller->relay_count) { - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "relay number is too high for this controller"); + LOGGER_DEBUG("relay num %d is too high for %s\n", args[1].value.v_int, args[0].value.v_str); + + static const char content[] = "relay number is too high for this controller"; + endpoint_response_text(response, 404, content, STRLEN(content)); return; } - relay_t* relay = relay_get_for_controller(controller_id, args[1].value.v_int); + relay_t* relay = relay_get_for_controller(controller->id, args[1].value.v_int); if(!relay) { @@ -90,7 +102,7 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess relay->number = args[1].value.v_int; snprintf(relay->name, MAX_NAME_LENGTH, "Relay %d", relay->number); relay->name[MAX_NAME_LENGTH] = '\0'; - relay->controller_id = controller_id; + relay->controller_id = controller->id; uuid_t tmp_uuid; memset(tmp_uuid, 0, sizeof(uuid_t)); @@ -105,13 +117,15 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess relay->active_schedule = relay->schedules[helper_get_weekday(time_struct)]; } + controller_free(controller); LOGGER_DEBUG("overwriting relay %d for controller %s\n", args[1].value.v_int, args[0].value.v_str); cJSON *json = cJSON_ParseWithLength(hm->body.p, hm->body.len); if(json == NULL) { - M_RESPONSE_400_NO_VALID_JSON(response); + static const char content[] = "no valid json was supplied"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } @@ -135,17 +149,21 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess cJSON *json_schedule_uid = cJSON_GetObjectItemCaseSensitive(json_schedule, "id"); if(!cJSON_IsString(json_schedule_uid) || (json_schedule_uid->valuestring == NULL)) { + LOGGER_DEBUG("schedules[%d] is missing uid\n", schedule_position); cJSON_Delete(json); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one schedule is missing an id"); + static const char content[] = "at least one schedule is missing an id"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } uuid_t target_uid; if(schedule_uid_parse(json_schedule_uid->valuestring, target_uid)) { + LOGGER_DEBUG("schedules[%d] has bad uid\n", schedule_position); cJSON_Delete(json); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "at least one schedule has a bad id"); + static const char content[] = "at least one schedule has a bad id"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } @@ -172,9 +190,11 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess uuid_t target_uid; if(schedule_uid_parse(json_active_schedule_uid->valuestring, target_uid)) { + LOGGER_DEBUG("active_schedule has bad uid\n"); cJSON_Delete(json); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "active schedule has a bad uid"); + static const char content[] = "active_schedule has a bad id"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } relay->schedules[day_of_week] = schedule_get_by_uid_or_off(target_uid); @@ -182,15 +202,21 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess } } - database_transaction_lock lock; - database_transaction_begin(&lock); + int opened_transaction = database_transaction_begin(); if(relay_save(relay)) { - database_transaction_rollback(&lock); + LOGGER_ERR("failed to save relay\n"); + + if(opened_transaction) + { + database_transaction_rollback(); + } + cJSON_Delete(json); - M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "failed to save relay to database"); + static const char content[] = "failed to save relay to database"; + endpoint_response_text(response, 500, content, STRLEN(content)); return; } @@ -209,12 +235,19 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess { if(!cJSON_IsString(json_tag) || (json_tag->valuestring == NULL)) { - database_transaction_rollback(&lock); + LOGGER_DEBUG("invalid tag in tags\n"); + + if(opened_transaction) + { + database_transaction_rollback(); + } + relay_free(relay); cJSON_Delete(json); free(tag_ids); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "invalid tag in tags"); + static const char content[] = "invalid tag in tags"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } const char *tag = json_tag->valuestring; @@ -226,12 +259,13 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess } tag_ids[i++] = tag_id; } - junction_tag_insert_list(tag_ids, relay->id, 0, json_tags_count); - free(tag_ids); } - database_transaction_commit(&lock); + if(opened_transaction) + { + database_transaction_commit(); + } cJSON_Delete(json); json = relay_to_json(relay, 0); diff --git a/src/endpoints/api_v1_controllers_STR_relays_INT_pulse.c b/src/endpoints/api_v1_controllers_STR_relays_INT_pulse.c index f72812a..22b158a 100644 --- a/src/endpoints/api_v1_controllers_STR_relays_INT_pulse.c +++ b/src/endpoints/api_v1_controllers_STR_relays_INT_pulse.c @@ -18,7 +18,10 @@ api_v1_controllers_STR_relays_INT_pulse_POST(struct mg_connection *nc, struct ht uuid_t target_uid; if(uuid_parse(args[0].value.v_str, target_uid)) { - M_RESPONSE_400_NO_VALID_ID(response); + LOGGER_DEBUG("failed to unparse uid\n"); + + static const char content[] = "given id was invalid"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } @@ -26,18 +29,21 @@ api_v1_controllers_STR_relays_INT_pulse_POST(struct mg_connection *nc, struct ht if(!controller) { - M_RESPONSE_404_NO_CONTROLLER_FOUND_FOR_ID(response); + LOGGER_DEBUG("could not find a controller for uid '%s'\n", args[0].value.v_str); + + static const char content[] = "no controller for id found"; + endpoint_response_text(response, 404, content, STRLEN(content)); return; } - int controller_id = controller->id; - controller_free(controller); - - relay_t* relay = relay_get_for_controller(controller_id, args[1].value.v_int); + relay_t* relay = relay_get_for_controller(controller->id, args[1].value.v_int); if(!relay) { - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "no relay found"); + LOGGER_DEBUG("could not find a relay with num %d for controller '%s'\n", args[1].value.v_int, args[0].value.v_str); + + static const char content[] = "no relay for this controller found"; + endpoint_response_text(response, 404, content, STRLEN(content)); return; } @@ -58,6 +64,7 @@ api_v1_controllers_STR_relays_INT_pulse_POST(struct mg_connection *nc, struct ht LOGGER_DEBUG("commanding pulse to relay %d for controller %s\n", args[1].value.v_int, args[0].value.v_str); command_relay_pulse(relay, duration); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 200, "sent pulse"); + endpoint_response_text(response, 200, "", 0); relay_free(relay); + controller_free(controller); } diff --git a/src/endpoints/api_v1_controllers_discover.c b/src/endpoints/api_v1_controllers_discover.c index c6d7648..d2e00d7 100644 --- a/src/endpoints/api_v1_controllers_discover.c +++ b/src/endpoints/api_v1_controllers_discover.c @@ -114,7 +114,13 @@ api_v1_controllers_discover_POST(struct mg_connection *nc, struct http_message * if(discover_server_port == -1) { - M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "the server failed to prepare discovery"); + LOGGER_ERR("failed to get server port for discovery\n"); + static const char content[] = ""; + response->status_code = 500; + response->content_type = "text/plain"; + response->content_length = STRLEN(content);; + response->content = content; + response->alloced_content = false; return; } @@ -124,7 +130,13 @@ api_v1_controllers_discover_POST(struct mg_connection *nc, struct http_message * LOGGER_DEBUG("sending udp broadcast\n"); if(send_udp_broadcast("255.255.255.255", global_config.discovery_port, payload, sizeof(payload)) < 0) { - M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "the server failed to send discovery broadcast"); + LOGGER_ERR("failed to send UDP broadcast\n"); + static const char content[] = ""; + response->status_code = 500; + response->content_type = "text/plain"; + response->content_length = STRLEN(content);; + response->content = content; + response->alloced_content = false; return; } diff --git a/src/endpoints/api_v1_macros.c b/src/endpoints/api_v1_macros.c deleted file mode 100644 index e78b14f..0000000 --- a/src/endpoints/api_v1_macros.c +++ /dev/null @@ -1,240 +0,0 @@ -#include <cJSON.h> -#include <macros.h> -#include <constants.h> -#include <database.h> -#include <endpoints/api_v1_macros.h> -#include <logger.h> -#include <models/macro.h> -#include <models/macro_action.h> -#include <models/schedule.h> -#include <models/relay.h> -#include <models/controller.h> - -void -api_v1_macros_GET(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response) -{ - (void)args; - (void)hm; - (void)nc; - - macro_t** all_macros = macro_get_all(); - - cJSON *json = cJSON_CreateArray(); - - for(int i = 0; all_macros[i] != NULL; ++i) - { - cJSON_AddItemToArray(json, macro_to_json(all_macros[i])); - free(all_macros[i]); - } - - endpoint_response_json(response, 200, json); - cJSON_Delete(json); - free(all_macros); -} - -void -api_v1_macros_POST(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response) -{ - (void)args; - (void)nc; - - cJSON *json = cJSON_ParseWithLength(hm->body.p, hm->body.len); - - if(json == NULL) - { - M_RESPONSE_400_NO_VALID_JSON(response); - return; - } - - cJSON *json_name = cJSON_GetObjectItemCaseSensitive(json, "name"); - if(!cJSON_IsString(json_name) || (json_name->valuestring == NULL)) - { - M_RESPONSE_400_NO_NAME(response); - return; - } - - cJSON *json_actions = cJSON_GetObjectItemCaseSensitive(json, "actions"); - if(!cJSON_IsArray(json_actions)) - { - cJSON_Delete(json); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request does not contains actions for the macro"); - return; - } - - database_transaction_lock lock; - database_transaction_begin(&lock); - - macro_t *new_macro = malloc(sizeof(macro_t)); - - new_macro->id = 0; - uuid_generate(new_macro->uid); - - strncpy(new_macro->name, json_name->valuestring, MAX_NAME_LENGTH); - new_macro->name[MAX_NAME_LENGTH] = '\0'; - - if(macro_save(new_macro)) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(new_macro); - - M_RESPONSE_500_FAILED_TO_SAVE_TO_DATABASE(response); - return; - } - - cJSON *json_action; - cJSON_ArrayForEach(json_action, json_actions) - { - cJSON *json_action_weekday = cJSON_GetObjectItemCaseSensitive(json_action, "weekday"); - if(!cJSON_IsNumber(json_action_weekday) || (json_action_weekday->valueint < 0) || (json_action_weekday->valueint > 6)) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(new_macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains an action without weekday"); - return; - } - - cJSON *json_action_schedule = cJSON_GetObjectItemCaseSensitive(json_action, "schedule"); - if(!cJSON_IsObject(json_action_schedule)) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(new_macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains an action without schedule"); - return; - } - cJSON *json_action_schedule_uid = cJSON_GetObjectItemCaseSensitive(json_action_schedule, "id"); - if(!cJSON_IsString(json_action_schedule_uid) || (json_action_schedule_uid->valuestring == NULL)) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(new_macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains an action without schedule id"); - return; - } - uuid_t action_schedule_uid; - if(schedule_uid_parse(json_action_schedule_uid->valuestring, action_schedule_uid)) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(new_macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains an action with an invalid schedule id"); - return; - } - - schedule_t *action_schedule = schedule_get_by_uid(action_schedule_uid); - if(action_schedule == NULL) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(new_macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "the schedule for at least one action was not found"); - return; - } - - int action_schedule_id = action_schedule->id; - schedule_free(action_schedule); - - - cJSON *json_action_relay = cJSON_GetObjectItemCaseSensitive(json_action, "relay"); - if(!cJSON_IsObject(json_action_relay)) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(new_macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains an action without relay"); - return; - } - cJSON *json_action_relay_number = cJSON_GetObjectItemCaseSensitive(json_action_relay, "number"); - if(!cJSON_IsNumber(json_action_relay_number)) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(new_macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains an action without relay number"); - return; - } - cJSON *json_action_relay_controller_uid = cJSON_GetObjectItemCaseSensitive(json_action_relay, "controller_id"); - if(!cJSON_IsString(json_action_relay_controller_uid) || (json_action_relay_controller_uid->valuestring == NULL)) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(new_macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains an action without relay controller id"); - return; - } - uuid_t action_controller_uid; - if(uuid_parse(json_action_relay_controller_uid->valuestring, action_controller_uid)) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(new_macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains an action with an invalid relay controller id"); - return; - } - - controller_t *action_controller = controller_get_by_uid(action_controller_uid); - if(action_controller == NULL) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(new_macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "the controller for at least one action relay was not found"); - return; - } - - int controller_id = action_controller->id; - int relay_num = json_action_relay_number->valueint; - - controller_free(action_controller); - - relay_t *action_relay = relay_get_for_controller(controller_id, relay_num); - if(action_relay == NULL) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(new_macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "the relay for at least one action was not found"); - return; - } - - int action_relay_id = action_relay->id; - relay_free(action_relay); - - - macro_action_t *new_action = malloc(sizeof(macro_action_t)); - new_action->macro_id = new_macro->id; - new_action->relay_id = action_relay_id; - new_action->schedule_id = action_schedule_id; - new_action->weekday = json_action_weekday->valueint; - - macro_action_insert(new_action); - free(new_action); - } - - - - database_transaction_commit(&lock); - - cJSON_Delete(json); - json = macro_to_json(new_macro); - - endpoint_response_json(response, 201, json); - - cJSON_Delete(json); - macro_free(new_macro); -} - diff --git a/src/endpoints/api_v1_macros_STR.c b/src/endpoints/api_v1_macros_STR.c deleted file mode 100644 index 44a5e18..0000000 --- a/src/endpoints/api_v1_macros_STR.c +++ /dev/null @@ -1,281 +0,0 @@ -#include <cJSON.h> -#include <macros.h> -#include <constants.h> -#include <endpoints/api_v1_macros.h> -#include <logger.h> -#include <command.h> -#include <models/macro_action.h> -#include <models/macro.h> -#include <models/relay.h> -#include <models/tag.h> - -void -api_v1_macros_STR_GET(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response) -{ - (void)hm; - (void)nc; - - uuid_t target_uid; - if(uuid_parse(args[0].value.v_str, target_uid)) - { - M_RESPONSE_400_NO_VALID_ID(response); - return; - } - - macro_t* macro = macro_get_by_uid(target_uid); - - if(!macro) - { - M_RESPONSE_404_NO_MACRO_FOUND_FOR_ID(response); - return; - } - - cJSON *json = macro_to_json(macro); - - endpoint_response_json(response, 200, json); - cJSON_Delete(json); - macro_free(macro); -} - -void -api_v1_macros_STR_PUT(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response) -{ - (void)hm; - (void)nc; - - uuid_t target_uid; - if(uuid_parse(args[0].value.v_str, target_uid)) - { - M_RESPONSE_400_NO_VALID_ID(response); - return; - } - - macro_t* macro = macro_get_by_uid(target_uid); - - if(!macro) - { - M_RESPONSE_404_NO_MACRO_FOUND_FOR_ID(response); - return; - } - - cJSON *json = cJSON_ParseWithLength(hm->body.p, hm->body.len); - - if(json == NULL) - { - M_RESPONSE_400_NO_VALID_JSON(response); - return; - } - - database_transaction_lock lock; - database_transaction_begin(&lock); - - cJSON *json_name = cJSON_GetObjectItemCaseSensitive(json, "name"); - if(cJSON_IsString(json_name) && (json_name->valuestring != NULL)) - { - strncpy(macro->name, json_name->valuestring, MAX_NAME_LENGTH); - macro->name[MAX_NAME_LENGTH] = '\0'; - - if(macro_save(macro)) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "macro could not be saved"); - return; - } - } - - macro_action_delete_for_macro(macro->id); - - cJSON *json_actions = cJSON_GetObjectItemCaseSensitive(json, "actions"); - if(cJSON_IsArray(json_actions)) - { - cJSON *json_action; - cJSON_ArrayForEach(json_action, json_actions) - { - cJSON *json_action_weekday = cJSON_GetObjectItemCaseSensitive(json_action, "weekday"); - if(!cJSON_IsNumber(json_action_weekday) || (json_action_weekday->valueint < 0) || (json_action_weekday->valueint > 6)) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action is missing a weekday"); - return; - } - - cJSON *json_action_schedule = cJSON_GetObjectItemCaseSensitive(json_action, "schedule"); - if(!cJSON_IsObject(json_action_schedule)) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action is missing a schedule"); - return; - } - cJSON *json_action_schedule_uid = cJSON_GetObjectItemCaseSensitive(json_action_schedule, "id"); - if(!cJSON_IsString(json_action_schedule_uid) || (json_action_schedule_uid->valuestring == NULL)) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action is missing a schedule id"); - return; - } - uuid_t action_schedule_uid; - if(schedule_uid_parse(json_action_schedule_uid->valuestring, action_schedule_uid)) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action has a bad schedule id"); - return; - } - - schedule_t *action_schedule = schedule_get_by_uid(action_schedule_uid); - if(action_schedule == NULL) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action schedule was not found"); - return; - } - - int action_schedule_id = action_schedule->id; - schedule_free(action_schedule); - - - cJSON *json_action_relay = cJSON_GetObjectItemCaseSensitive(json_action, "relay"); - if(!cJSON_IsObject(json_action_relay)) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action is missing a relay"); - return; - } - cJSON *json_action_relay_number = cJSON_GetObjectItemCaseSensitive(json_action_relay, "number"); - if(!cJSON_IsNumber(json_action_relay_number)) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action is missing a relay number"); - return; - } - cJSON *json_action_relay_controller_uid = cJSON_GetObjectItemCaseSensitive(json_action_relay, "controller_id"); - if(!cJSON_IsString(json_action_relay_controller_uid) || (json_action_relay_controller_uid->valuestring == NULL)) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action is missing a relay controller id"); - return; - } - uuid_t action_controller_uid; - if(uuid_parse(json_action_relay_controller_uid->valuestring, action_controller_uid)) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action has a bad relay controller id"); - return; - } - - controller_t *action_controller = controller_get_by_uid(action_controller_uid); - if(action_controller == NULL) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action relay controller was not found"); - return; - } - - int controller_id = action_controller->id; - int relay_num = json_action_relay_number->valueint; - - controller_free(action_controller); - - relay_t *action_relay = relay_get_for_controller(controller_id, relay_num); - if(action_relay == NULL) - { - database_transaction_rollback(&lock); - cJSON_Delete(json); - macro_free(macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "action relay was not found"); - return; - } - - int action_relay_id = action_relay->id; - relay_free(action_relay); - - - macro_action_t *action = malloc(sizeof(macro_action_t)); - action->macro_id = macro->id; - action->relay_id = action_relay_id; - action->schedule_id = action_schedule_id; - action->weekday = json_action_weekday->valueint; - - macro_action_insert(action); - free(action); - } - } - - database_transaction_commit(&lock); - - cJSON_Delete(json); - json = macro_to_json(macro); - - endpoint_response_json(response, 201, json); - - cJSON_Delete(json); - macro_free(macro); -} - -void -api_v1_macros_STR_DELETE(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response) -{ - (void)hm; - (void)nc; - - const char *target_uid_str = args[0].value.v_str; - - uuid_t target_uid; - if(uuid_parse(target_uid_str, target_uid)) - { - M_RESPONSE_400_NO_VALID_ID(response); - return; - } - - macro_t* macro = macro_get_by_uid(target_uid); - - if(!macro) - { - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "no macro with id found"); - return; - } - - if(macro_remove(macro)) - { - M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "failed to remove macro from database"); - } - else - { - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 200, "deleted macro"); - } - macro_free(macro); - return; -} diff --git a/src/endpoints/api_v1_macros_STR_execute.c b/src/endpoints/api_v1_macros_STR_execute.c deleted file mode 100644 index 33f3952..0000000 --- a/src/endpoints/api_v1_macros_STR_execute.c +++ /dev/null @@ -1,64 +0,0 @@ -#include <cJSON.h> -#include <macros.h> -#include <constants.h> -#include <endpoints/api_v1_macros.h> -#include <logger.h> -#include <command.h> -#include <models/macro_action.h> -#include <models/macro.h> -#include <models/relay.h> -#include <models/tag.h> - -void -api_v1_macros_STR_execute_PUT(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response) -{ - (void)hm; - (void)nc; - - uuid_t target_uid; - if(uuid_parse(args[0].value.v_str, target_uid)) - { - M_RESPONSE_400_NO_VALID_ID(response); - return; - } - - macro_t* macro = macro_get_by_uid(target_uid); - - if(!macro) - { - M_RESPONSE_404_NO_MACRO_FOUND_FOR_ID(response); - return; - } - - macro_action_t** macro_actions = macro_action_get_for_macro(macro->id); - - database_transaction_lock lock; - database_transaction_begin(&lock); - - for(int i = 0; macro_actions[i] != NULL; ++i) - { - macro_action_execute(macro_actions[i]); - } - - database_transaction_commit(&lock); - - int *target_relay_ids = macro_get_target_relay_ids(macro->id); - for(int i = 0; target_relay_ids[i] != 0; ++i) - { - relay_t *target_relay = relay_get_by_id(target_relay_ids[i]); - if(!target_relay) - { - LOGGER_ERR("failed to load target relay from database\n"); - continue; - } - command_relay_schedules_set(target_relay); - - relay_free(target_relay); - } - - free(target_relay_ids); - macro_action_free_list(macro_actions); - macro_free(macro); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 200, "macro got executed"); -} diff --git a/src/endpoints/api_v1_relays_tag_STR.c b/src/endpoints/api_v1_relays_tag_STR.c index ffce429..06a6adc 100644 --- a/src/endpoints/api_v1_relays_tag_STR.c +++ b/src/endpoints/api_v1_relays_tag_STR.c @@ -16,13 +16,17 @@ api_v1_relays_tag_STR_GET(struct mg_connection *nc, struct http_message *hm, end int tag_id = tag_get_id(args[0].value.v_str); if(tag_id == 0) { - M_RESPONSE_404_NO_TAG_FOUND(response); + static const char content[] = "tag was not found"; + endpoint_response_text(response, 404, content, STRLEN(content)); return; } int *relays_ids = junction_tag_get_relays_for_tag_id(tag_id); if(relays_ids == NULL) { - M_RESPONSE_500_FAILED_TO_READ_FROM_DATABASE(response); + LOGGER_ERR("failed to load relays for tag from database\n"); + + static const char content[] = "failed to load relays for tag from database"; + endpoint_response_text(response, 500, content, STRLEN(content)); return; } diff --git a/src/endpoints/api_v1_schedules.c b/src/endpoints/api_v1_schedules.c index 7a9ad6e..2dad24d 100644 --- a/src/endpoints/api_v1_schedules.c +++ b/src/endpoints/api_v1_schedules.c @@ -16,23 +16,29 @@ api_v1_schedules_POST(struct mg_connection *nc, struct http_message *hm, endpoin if(json == NULL) { - M_RESPONSE_400_NO_VALID_JSON(response); + static const char content[] = "no valid json was supplied"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } cJSON *json_name = cJSON_GetObjectItemCaseSensitive(json, "name"); if(!cJSON_IsString(json_name) || (json_name->valuestring == NULL)) { - M_RESPONSE_400_NO_NAME(response); + LOGGER_DEBUG("no name for schedule provided\n"); + cJSON_Delete(json); + + static const char content[] = "no name for schedule provided"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } - cJSON *json_periods = cJSON_GetObjectItemCaseSensitive(json, "periods"); if(!cJSON_IsArray(json_periods)) { + LOGGER_DEBUG("no periods for schedule provided\n"); cJSON_Delete(json); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request does not contain periods"); + static const char content[] = "no periods for schedule provided"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } @@ -42,9 +48,11 @@ api_v1_schedules_POST(struct mg_connection *nc, struct http_message *hm, endpoin { if(!cJSON_IsString(json_tag) || (json_tag->valuestring == NULL)) { + LOGGER_DEBUG("invalid tag in tags\n"); cJSON_Delete(json); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one invalid tag"); + static const char content[] = "invalid tag in tags"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } } @@ -70,18 +78,22 @@ api_v1_schedules_POST(struct mg_connection *nc, struct http_message *hm, endpoin if(!cJSON_IsString(json_period_start) || (json_period_start->valuestring == NULL)) { + LOGGER_DEBUG("period is missing start\n"); cJSON_Delete(json); schedule_free(new_schedule); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one period without a start"); + static const char content[] = "one period is missing a start"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } if(!cJSON_IsString(json_period_end) || (json_period_end->valuestring == NULL)) { + LOGGER_DEBUG("period is missing end\n"); cJSON_Delete(json); schedule_free(new_schedule); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one period without an end"); + static const char content[] = "one period is missing an end"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } @@ -89,18 +101,22 @@ api_v1_schedules_POST(struct mg_connection *nc, struct http_message *hm, endpoin uint16_t end; if(period_helper_parse_hhmm(json_period_start->valuestring, &start)) { + LOGGER_DEBUG("couldn't parse start '%s'\n", json_period_start->valuestring); cJSON_Delete(json); schedule_free(new_schedule); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one period with an invalid start"); + static const char content[] = "the start for one period is invalid"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } if(period_helper_parse_hhmm(json_period_end->valuestring, &end)) { + LOGGER_DEBUG("couldn't parse end '%s'\n", json_period_end->valuestring); cJSON_Delete(json); schedule_free(new_schedule); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one period with an invalid end"); + static const char content[] = "the end for one period is invalid"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } diff --git a/src/endpoints/api_v1_schedules_STR.c b/src/endpoints/api_v1_schedules_STR.c index 3abc0c8..03613d1 100644 --- a/src/endpoints/api_v1_schedules_STR.c +++ b/src/endpoints/api_v1_schedules_STR.c @@ -19,7 +19,10 @@ api_v1_schedules_STR_GET(struct mg_connection *nc, struct http_message *hm, endp uuid_t target_uid; if(schedule_uid_parse(args[0].value.v_str, target_uid)) { - M_RESPONSE_400_NO_VALID_ID(response); + LOGGER_DEBUG("failed to unparse uid\n"); + + static const char content[] = "given id was invalid"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } @@ -27,7 +30,10 @@ api_v1_schedules_STR_GET(struct mg_connection *nc, struct http_message *hm, endp if(!schedule) { - M_RESPONSE_404_NO_SCHEDULE_FOUND_FOR_ID(response); + LOGGER_DEBUG("could not find a schedule for uid '%s'\n", args[0].value.v_str); + + static const char content[] = "no schedule for id found"; + endpoint_response_text(response, 404, content, STRLEN(content)); return; } @@ -47,7 +53,10 @@ api_v1_schedules_STR_PUT(struct mg_connection *nc, struct http_message *hm, endp uuid_t target_uid; if(schedule_uid_parse(args[0].value.v_str, target_uid)) { - M_RESPONSE_400_NO_VALID_ID(response); + LOGGER_DEBUG("failed to unparse uid\n"); + + static const char content[] = "given id was invalid"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } @@ -55,7 +64,10 @@ api_v1_schedules_STR_PUT(struct mg_connection *nc, struct http_message *hm, endp if(!schedule) { - M_RESPONSE_404_NO_SCHEDULE_FOUND_FOR_ID(response); + LOGGER_DEBUG("could not find a schedule for uid '%s'\n", args[0].value.v_str); + + static const char content[] = "no schedule for id found"; + endpoint_response_text(response, 404, content, STRLEN(content)); return; } @@ -63,7 +75,8 @@ api_v1_schedules_STR_PUT(struct mg_connection *nc, struct http_message *hm, endp if(json == NULL) { - M_RESPONSE_400_NO_VALID_JSON(response); + static const char content[] = "no valid json was supplied"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } @@ -124,10 +137,12 @@ api_v1_schedules_STR_PUT(struct mg_connection *nc, struct http_message *hm, endp if(schedule_save(schedule)) { + LOGGER_ERR("failed to save schedule\n"); free(schedule); cJSON_Delete(json); - M_RESPONSE_500_FAILED_TO_SAVE_TO_DATABASE(response); + static const char content[] = "failed to save schedule to database"; + endpoint_response_text(response, 500, content, STRLEN(content)); return; } @@ -175,7 +190,10 @@ api_v1_schedules_STR_DELETE(struct mg_connection *nc, struct http_message *hm, e uuid_t target_uid; if(schedule_uid_parse(target_uid_str, target_uid)) { - M_RESPONSE_400_NO_VALID_ID(response); + LOGGER_DEBUG("failed to unparse uid\n"); + + static const char content[] = "given id was invalid"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } @@ -183,25 +201,32 @@ api_v1_schedules_STR_DELETE(struct mg_connection *nc, struct http_message *hm, e if(!schedule) { - M_RESPONSE_404_NO_SCHEDULE_FOUND_FOR_ID(response); + LOGGER_DEBUG("could not find a schedule for uid '%s'\n", args[0].value.v_str); + + static const char content[] = "no schedule for id found"; + endpoint_response_text(response, 404, content, STRLEN(content)); return; } if(schedule_is_protected(schedule)) { - schedule_free(schedule); + static const char content[] = "target schedule is protected"; + endpoint_response_text(response, 403, content, STRLEN(content)); - M_RESPONSE_403_PROTECTED_SCHEDULE(response); + schedule_free(schedule); return; } if(schedule_remove(schedule)) { - M_RESPONSE_500_FAILED_TO_DELETE_FROM_DATABASE(response); + LOGGER_ERR("failed to remove schedule from database\n"); + + static const char content[] = "failed to remove schedule from database"; + endpoint_response_text(response, 500, content, STRLEN(content)); } else { - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 200, "the target schedule got deleted"); + endpoint_response_text(response, 200, "", 0); } schedule_free(schedule); return; diff --git a/src/endpoints/api_v1_schedules_list.c b/src/endpoints/api_v1_schedules_list.c index 46d2b8a..ede980b 100644 --- a/src/endpoints/api_v1_schedules_list.c +++ b/src/endpoints/api_v1_schedules_list.c @@ -20,23 +20,29 @@ api_v1_schedules_list_POST(struct mg_connection *nc, struct http_message *hm, en { if(json == NULL) { - M_RESPONSE_400_NO_VALID_JSON(response); + static const char content[] = "no valid json was supplied"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } cJSON *json_name = cJSON_GetObjectItemCaseSensitive(json, "name"); if(!cJSON_IsString(json_name) || (json_name->valuestring == NULL)) { - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request does not contain a name for at least one schedule"); + LOGGER_DEBUG("no name for schedule provided\n"); + cJSON_Delete(json_list); + + static const char content[] = "no name for schedule provided"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } - cJSON *json_periods = cJSON_GetObjectItemCaseSensitive(json, "periods"); if(!cJSON_IsArray(json_periods)) { + LOGGER_DEBUG("no periods for schedule provided\n"); cJSON_Delete(json_list); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request does not contain periods for at least one schedule"); + static const char content[] = "no periods for schedule provided"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } @@ -46,9 +52,11 @@ api_v1_schedules_list_POST(struct mg_connection *nc, struct http_message *hm, en { if(!cJSON_IsString(json_tag) || (json_tag->valuestring == NULL)) { + LOGGER_DEBUG("invalid tag in tags\n"); cJSON_Delete(json_list); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one invalid tag"); + static const char content[] = "invalid tag in tags"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } } @@ -74,18 +82,22 @@ api_v1_schedules_list_POST(struct mg_connection *nc, struct http_message *hm, en if(!cJSON_IsString(json_period_start) || (json_period_start->valuestring == NULL)) { + LOGGER_DEBUG("period is missing start\n"); cJSON_Delete(json_list); schedule_free(new_schedule); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one period without a start"); + static const char content[] = "one period is missing a start"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } if(!cJSON_IsString(json_period_end) || (json_period_end->valuestring == NULL)) { + LOGGER_DEBUG("period is missing end\n"); cJSON_Delete(json_list); schedule_free(new_schedule); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one period without an end"); + static const char content[] = "one period is missing an end"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } @@ -93,18 +105,22 @@ api_v1_schedules_list_POST(struct mg_connection *nc, struct http_message *hm, en uint16_t end; if(period_helper_parse_hhmm(json_period_start->valuestring, &start)) { + LOGGER_DEBUG("couldn't parse start '%s'\n", json_period_start->valuestring); cJSON_Delete(json_list); schedule_free(new_schedule); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one period with an invalid start"); + static const char content[] = "the start for one period is invalid"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } if(period_helper_parse_hhmm(json_period_end->valuestring, &end)) { + LOGGER_DEBUG("couldn't parse end '%s'\n", json_period_end->valuestring); cJSON_Delete(json_list); schedule_free(new_schedule); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one period with an invalid end"); + static const char content[] = "the end for one period is invalid"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } diff --git a/src/endpoints/api_v1_schedules_tag_STR.c b/src/endpoints/api_v1_schedules_tag_STR.c index 08723dc..b0d22ec 100644 --- a/src/endpoints/api_v1_schedules_tag_STR.c +++ b/src/endpoints/api_v1_schedules_tag_STR.c @@ -16,13 +16,17 @@ api_v1_schedules_tag_STR_GET(struct mg_connection *nc, struct http_message *hm, int tag_id = tag_get_id(args[0].value.v_str); if(tag_id == 0) { - M_RESPONSE_404_NO_TAG_FOUND(response); + static const char content[] = "tag was not found"; + endpoint_response_text(response, 404, content, STRLEN(content)); return; } int *schedules_ids = junction_tag_get_schedules_for_tag_id(tag_id); if(schedules_ids == NULL) { - M_RESPONSE_500_FAILED_TO_READ_FROM_DATABASE(response); + LOGGER_ERR("failed to load schedules for tag from database\n"); + + static const char content[] = "failed to load schedules for tag from database"; + endpoint_response_text(response, 500, content, STRLEN(content)); return; } diff --git a/src/endpoints/api_v1_tags.c b/src/endpoints/api_v1_tags.c index 928ec17..2bd4afa 100644 --- a/src/endpoints/api_v1_tags.c +++ b/src/endpoints/api_v1_tags.c @@ -44,47 +44,54 @@ api_v1_tags_POST(struct mg_connection *nc, struct http_message *hm, endpoint_arg if(json == NULL) { - M_RESPONSE_400_NO_VALID_JSON(response); + static const char content[] = "no valid json was supplied"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } cJSON *json_tag = cJSON_GetObjectItemCaseSensitive(json, "tag"); if(!cJSON_IsString(json_tag) || (json_tag->valuestring == NULL)) { + LOGGER_DEBUG("no tag provided\n"); cJSON_Delete(json); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request does not contain a tag"); - return; - } - - if(strlen(json_tag->valuestring) == 0) - { - cJSON_Delete(json); - - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains an empty tag"); + static const char content[] = "no tag provided"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } if(tag_get_id(json_tag->valuestring)) { + LOGGER_DEBUG("tag existed already\n"); cJSON_Delete(json); - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the tag does already exist"); + static const char content[] = "tag existed already"; + endpoint_response_text(response, 400, content, STRLEN(content)); + return; + } + + if(strlen(json_tag->valuestring) == 0) + { + LOGGER_DEBUG("tag is empty\n"); + cJSON_Delete(json); + + static const char content[] = "tag is empty"; + endpoint_response_text(response, 400, content, STRLEN(content)); return; } if(tag_save(0, json_tag->valuestring)) { - M_RESPONSE_500_FAILED_TO_SAVE_TO_DATABASE(response); + LOGGER_DEBUG("tag could not be saved\n"); + + static const char content[] = "tag could not be saved"; + endpoint_response_text(response, 500, content, STRLEN(content)); } else { LOGGER_DEBUG("new tag saved\n"); - char *tag = malloc(sizeof(char) * (strlen(json_tag->valuestring) + 1)); - strcpy(tag, json_tag->valuestring); - - endpoint_response_text(response, 201, tag, 0); + endpoint_response_text(response, 201, json_tag->valuestring, 0); } cJSON_Delete(json); diff --git a/src/endpoints/api_v1_tags_STR.c b/src/endpoints/api_v1_tags_STR.c index e0e7c55..c9f0426 100644 --- a/src/endpoints/api_v1_tags_STR.c +++ b/src/endpoints/api_v1_tags_STR.c @@ -16,19 +16,26 @@ api_v1_tags_STR_GET(struct mg_connection *nc, struct http_message *hm, endpoint_ int tag_id = tag_get_id(args[0].value.v_str); if(tag_id == 0) { - M_RESPONSE_404_NO_TAG_FOUND(response); + static const char content[] = "tag was not found"; + endpoint_response_text(response, 404, content, STRLEN(content)); return; } int *relays_ids = junction_tag_get_relays_for_tag_id(tag_id); if(relays_ids == NULL) { - M_RESPONSE_500_FAILED_TO_READ_FROM_DATABASE(response); + LOGGER_ERR("failed to load relays for tag from database\n"); + + static const char content[] = "failed to load relays for tag from database"; + endpoint_response_text(response, 500, content, STRLEN(content)); return; } int *schedules_ids = junction_tag_get_schedules_for_tag_id(tag_id); if(schedules_ids == NULL) { - M_RESPONSE_500_FAILED_TO_READ_FROM_DATABASE(response); + LOGGER_ERR("failed to load schedules for tag from database\n"); + + static const char content[] = "failed to load schedules for tag from database"; + endpoint_response_text(response, 500, content, STRLEN(content)); return; } @@ -84,16 +91,20 @@ api_v1_tags_STR_DELETE(struct mg_connection *nc, struct http_message *hm, endpoi int tag_id = tag_get_id(args[0].value.v_str); if(tag_id == 0) { - M_RESPONSE_404_NO_TAG_FOUND(response); + static const char content[] = "tag was not found"; + endpoint_response_text(response, 404, content, STRLEN(content)); return; } if(tag_remove(tag_id)) { - M_RESPONSE_500_FAILED_TO_DELETE_FROM_DATABASE(response); + LOGGER_ERR("failed to remove tag from database\n"); + + static const char content[] = "failed to remove tag from database"; + endpoint_response_text(response, 500, content, STRLEN(content)); } else { - M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 200, "the tag got deleted"); + endpoint_response_text(response, 200, "", 0); } } diff --git a/src/handlers/http.c b/src/handlers/http.c index 84c4a36..87d2908 100644 --- a/src/handlers/http.c +++ b/src/handlers/http.c @@ -82,8 +82,8 @@ handle_http_request(struct mg_connection *nc, struct http_message *hm) endpoint_t *endpoint = router_find_endpoint(hm->uri.p, hm->uri.len, &hm->method); endpoint_response_t response; - - M_RESPONSE_TEXT_STATIC(LOGGER_NONE, &response, 500, "server did not create a response"); + static const char content[] = "the server did not create a response"; + endpoint_response_text(&response, 500, content, STRLEN(content)); if(!endpoint) { diff --git a/src/logger.c b/src/logger.c index 1839d38..2869668 100644 --- a/src/logger.c +++ b/src/logger.c @@ -17,7 +17,7 @@ const char *COLOR_EMERG = COLOR_MAGENTA; void logger_log(int level, const char *filename, int line, const char *func, const char *msg, ...) { - if(global_config.log_level < level || level == LOG_NONE ) + if(global_config.log_level < level) { return; } diff --git a/src/models/controller.c b/src/models/controller.c index 60a2553..807853c 100644 --- a/src/models/controller.c +++ b/src/models/controller.c @@ -117,8 +117,7 @@ controller_db_select(sqlite3_stmt *stmt) int controller_save(controller_t *controller) { - database_transaction_lock lock; - database_transaction_begin(&lock); + int opened_transaction = database_transaction_begin(); sqlite3_stmt *stmt; if(controller->id) @@ -143,7 +142,10 @@ controller_save(controller_t *controller) LOGGER_ERR("error updating data: %s\n", sqlite3_errmsg(global_database)); } - database_transaction_rollback(&lock); + if(opened_transaction) + { + database_transaction_rollback(); + } } else { @@ -152,7 +154,10 @@ controller_save(controller_t *controller) controller->id = sqlite3_last_insert_rowid(global_database); } - database_transaction_commit(&lock); + if(opened_transaction) + { + database_transaction_commit(); + } } cache_invalidate_controller(controller->id); diff --git a/src/models/junction_relay_schedule.c b/src/models/junction_relay_schedule.c index 50bedb7..e2b2309 100644 --- a/src/models/junction_relay_schedule.c +++ b/src/models/junction_relay_schedule.c @@ -40,14 +40,14 @@ junction_relay_schedule_insert_weekdays(int relay_id, int *schedule_ids) static const char query_base[] = "INSERT INTO junction_relay_schedule (weekday, schedule_id, relay_id) VALUES"; static const char query_extender[] = " (?, ?, ?)"; - size_t query_len = M_STRLEN(query_base) + (7 * (M_STRLEN(query_extender) + 1)) + 1; + size_t query_len = STRLEN(query_base) + (7 * (STRLEN(query_extender) + 1)) + 1; char *query = malloc(sizeof(char) * query_len + 1); strncpy(query, query_base, query_len); - query_len -= M_STRLEN(query_base); + query_len -= STRLEN(query_base); for(int i = 0; i < 7; ++i) { strncat(query, query_extender, query_len); - query_len -= M_STRLEN(query_extender); + query_len -= STRLEN(query_extender); char *query_divider = (i < 7 - 1) ? "," : ";"; strncat(query, query_divider, query_len); query_len -= 1; @@ -62,18 +62,16 @@ junction_relay_schedule_insert_weekdays(int relay_id, int *schedule_ids) sqlite3_bind_int(stmt, i * 3 + 3, relay_id); } - free(query); - rc = sqlite3_step(stmt); if (rc != SQLITE_DONE) { LOGGER_ERR("error inserting data: %s", sqlite3_errmsg(global_database)); - return 1; + return false; } sqlite3_finalize(stmt); - return 0; + return true; } int @@ -89,14 +87,3 @@ junction_relay_schedule_remove_for_relay(int relay_id) return rc == SQLITE_DONE; } - -int* -junction_relay_schedule_get_relay_ids_with_schedule(int schedule_id) -{ - sqlite3_stmt *stmt; - - sqlite3_prepare_v2(global_database, "SELECT DISTINCT relay_id FROM junction_relay_schedule WHERE schedule_id=?1;", -1, &stmt, NULL); - sqlite3_bind_int(stmt, 1, schedule_id); - - return database_helper_get_ids(stmt); -} diff --git a/src/models/junction_tag.c b/src/models/junction_tag.c index 7d84af5..a62bed8 100644 --- a/src/models/junction_tag.c +++ b/src/models/junction_tag.c @@ -67,14 +67,14 @@ junction_tag_insert_list(int *tag_ids, int relay_id, int schedule_id, int count) static const char query_base[] = "INSERT INTO junction_tag(tag_id, schedule_id, relay_id) VALUES"; static const char query_extender[] = " (?, ?, ?)"; - size_t query_len = M_STRLEN(query_base) + (count * (M_STRLEN(query_extender) + 1)) + 1; + size_t query_len = STRLEN(query_base) + (count * (STRLEN(query_extender) + 1)) + 1; char *query = malloc(sizeof(char) * query_len + 1); strncpy(query, query_base, query_len); - query_len -= M_STRLEN(query_base); + query_len -= STRLEN(query_base); for(int i = 0; i < count; ++i) { strncat(query, query_extender, query_len); - query_len -= M_STRLEN(query_extender); + query_len -= STRLEN(query_extender); char *query_divider = (i < count - 1) ? "," : ";"; strncat(query, query_divider, query_len); query_len -= 1; @@ -105,8 +105,6 @@ junction_tag_insert_list(int *tag_ids, int relay_id, int schedule_id, int count) } } - free(query); - rc = sqlite3_step(stmt); if (rc != SQLITE_DONE) { diff --git a/src/models/macro.c b/src/models/macro.c deleted file mode 100644 index 0d19075..0000000 --- a/src/models/macro.c +++ /dev/null @@ -1,330 +0,0 @@ -#include <stdlib.h> -#include <string.h> -#include <sqlite3.h> - -#include <cache.h> -#include <cJSON.h> -#include <logger.h> -#include <database.h> -#include <models/macro.h> -#include <models/macro_action.h> -#include <models/schedule.h> -#include <models/tag.h> - -static int -db_update_insert(macro_t *macro, sqlite3_stmt *stmt) -{ - LOGGER_DEBUG("saving macro '%s' into database (id: %d)\n", macro->name, macro->id); - - int rc; - - sqlite3_bind_int(stmt, 1, macro->id); - sqlite3_bind_blob(stmt, 2, macro->uid, sizeof(uuid_t), SQLITE_STATIC); - sqlite3_bind_text(stmt, 3, macro->name, -1, SQLITE_STATIC); - - rc = sqlite3_step(stmt); - - sqlite3_finalize(stmt); - - return rc != SQLITE_DONE; -} - -static macro_t* -macro_db_select_mapper(sqlite3_stmt *stmt) -{ - macro_t *new_macro = malloc(sizeof(macro_t)); - for(int i = 0; i < sqlite3_column_count(stmt); i++) - { - const char *name = sqlite3_column_name(stmt, i); - switch(name[0]) - { - case 'i': // id - new_macro->id = sqlite3_column_int(stmt, i); - break; - case 'n': // name - strncpy(new_macro->name, (const char*)sqlite3_column_text(stmt, i), MAX_NAME_LENGTH); - new_macro->name[MAX_NAME_LENGTH] = '\0'; - break; - case 'u': // uid - uuid_copy(new_macro->uid, (const unsigned char*)sqlite3_column_blob(stmt, i)); - break; - default: // ignore columns not implemented - break; - } - } - return new_macro; -} - -static macro_t** -macro_db_select(sqlite3_stmt *stmt) -{ - macro_t **all_macros = malloc(sizeof(macro_t*)); - - int row = 0; - - for(;;) - { - int s; - - s = sqlite3_step(stmt); - if (s == SQLITE_ROW) - { - macro_t *new_macro = macro_db_select_mapper(stmt); - row++; - - all_macros = (macro_t**)realloc(all_macros, sizeof(macro_t*) * (row + 1)); - all_macros[row - 1] = new_macro; - } - else - { - if(s == SQLITE_DONE) - { - break; - } - else - { - LOGGER_ERR("error selecting macros from database: %s\n", sqlite3_errstr(s)); - break; - } - } - } - sqlite3_finalize(stmt); - all_macros[row] = NULL; - return all_macros; -} - -int -macro_save(macro_t *macro) -{ - database_transaction_lock lock; - database_transaction_begin(&lock); - - sqlite3_stmt *stmt; - if(macro->id) - { - sqlite3_prepare_v2(global_database, "UPDATE macros SET uid = ?2, name = ?3 WHERE id=?1;", -1, &stmt, NULL); - } - else - { - sqlite3_prepare_v2(global_database, "INSERT INTO macros(uid, name) values (?2, ?3);", -1, &stmt, NULL); - } - - int result = db_update_insert(macro, stmt); - - if(result) - { - if(macro->id) - { - LOGGER_ERR("error inserting data: %s\n", sqlite3_errmsg(global_database)); - } - else - { - LOGGER_ERR("error updating data: %s\n", sqlite3_errmsg(global_database)); - } - - database_transaction_rollback(&lock); - } - else - { - if(!macro->id) - { - macro->id = sqlite3_last_insert_rowid(global_database); - } - - database_transaction_commit(&lock); - } - - cache_invalidate_macro(macro->id); - - return result; -} - -int -macro_remove(macro_t *macro) -{ - sqlite3_stmt *stmt; - if(macro->id == 0) - { - return 0; - } - - sqlite3_prepare_v2(global_database, "DELETE FROM macros WHERE id=?1;", -1, &stmt, NULL); - sqlite3_bind_int(stmt, 1, macro->id); - - int rc = sqlite3_step(stmt); - - sqlite3_finalize(stmt); - - cache_invalidate_macro(macro->id); - - return rc != SQLITE_DONE; -} - -void -macro_free(macro_t *macro) -{ - free(macro); -} - -void -macro_free_list(macro_t **macros) -{ - for(int i = 0; macros[i] != NULL; ++i) - { - macro_free(macros[i]); - } - free(macros); -} - -cJSON* -macro_to_json(macro_t *macro) -{ - cJSON *json; - - char *cached = cache_get_json_macro(macro->id); - if(cached) - { - json = cJSON_CreateRaw(cached); - free(cached); - return json; - } - - char uuid_str[UUID_STR_LEN]; - uuid_unparse(macro->uid, uuid_str); - - LOGGER_DEBUG("JSONifying macro %s\n", uuid_str); - - json = cJSON_CreateObject(); - - cJSON *json_name = cJSON_CreateString(macro->name); - if(json_name == NULL) - { - cJSON_Delete(json); - return NULL; - } - cJSON_AddItemToObject(json, "name", json_name); - - cJSON *json_id = cJSON_CreateString(uuid_str); - if(json_name == NULL) - { - cJSON_Delete(json); - return NULL; - } - cJSON_AddItemToObject(json, "id", json_id); - - cJSON *json_actions = cJSON_CreateArray(); - macro_action_t **macro_actions = macro_action_get_for_macro(macro->id); - for(int i = 0; macro_actions[i] != NULL; ++i) - { - cJSON *json_action = cJSON_CreateObject(); - - cJSON *json_action_weekday = cJSON_CreateNumber(macro_actions[i]->weekday); - if(json_action_weekday == NULL) - { - LOGGER_DEBUG("failed to create weekday from number %d\n", macro_actions[i]->weekday); - continue; - } - - relay_t *relay = relay_get_by_id(macro_actions[i]->relay_id); - if(!relay) - { - LOGGER_DEBUG("failed to get relay\n"); - continue; - } - schedule_t *schedule = schedule_get_by_id(macro_actions[i]->schedule_id); - if(!schedule) - { - LOGGER_DEBUG("failed to get schedule\n"); - relay_free(relay); - continue; - } - - cJSON_AddItemToObject(json_action, "weekday", json_action_weekday); - cJSON_AddItemToObject(json_action, "relay", relay_to_json(relay, 0)); - cJSON_AddItemToObject(json_action, "schedule", schedule_to_json(schedule)); - - cJSON_AddItemToArray(json_actions, json_action); - } - cJSON_AddItemToObject(json, "actions", json_actions); - - macro_action_free_list(macro_actions); - - char *json_str = cJSON_Print(json); - cache_put_json_macro(macro->id, json_str); - cJSON_Delete(json); - - json = cJSON_CreateRaw(json_str); - free(json_str); - return json; -} - -macro_t* -macro_get_by_id(int id) -{ - LOGGER_DEBUG("getting macro [id=%d] from database\n", id); - sqlite3_stmt *stmt; - - sqlite3_prepare_v2(global_database, "SELECT * FROM macros WHERE id = ?1;", -1, &stmt, NULL); - sqlite3_bind_int(stmt, 1, id); - - macro_t **sql_result = macro_db_select(stmt); - - macro_t *result = sql_result[0]; - free(sql_result); - - return result; -} - -macro_t* -macro_get_by_uid(uuid_t uid) -{ - char uuid_str[UUID_STR_LEN]; - uuid_unparse(uid, uuid_str); - LOGGER_DEBUG("getting macro [uid=%s] from database\n", uuid_str); - sqlite3_stmt *stmt; - - sqlite3_prepare_v2(global_database, "SELECT * FROM macros WHERE uid = ?1;", -1, &stmt, NULL); - sqlite3_bind_blob(stmt, 1, uid, sizeof(uuid_t), SQLITE_STATIC); - - macro_t **sql_result = macro_db_select(stmt); - - macro_t *result = sql_result[0]; - free(sql_result); - - return result; -} - -macro_t** -macro_get_relay_weekdays(int relay_id) -{ - LOGGER_DEBUG("getting macros [relay_id=%d] from database\n", relay_id); - sqlite3_stmt *stmt; - - sqlite3_prepare_v2(global_database, "SELECT macros.* FROM macros INNER JOIN junction_relay_macro ON macros.id == junction_relay_macro.macro_id WHERE junction_relay_macro.relay_id = ?1 ORDER BY junction_relay_macro.weekday ASC", -1, &stmt, NULL); - sqlite3_bind_int(stmt, 1, relay_id); - - return macro_db_select(stmt); -} - -macro_t** -macro_get_all() -{ - LOGGER_DEBUG("getting all macros from database\n"); - sqlite3_stmt *stmt; - - sqlite3_prepare_v2(global_database, "SELECT * FROM macros;", -1, &stmt, NULL); - - return macro_db_select(stmt); - -} - -int* -macro_get_target_relay_ids(int macro_id) -{ - sqlite3_stmt *stmt; - - sqlite3_prepare_v2(global_database, "SELECT DISTINCT relay_id FROM macro_actions WHERE macro_id=?1;", -1, &stmt, NULL); - sqlite3_bind_int(stmt, 1, macro_id); - - return database_helper_get_ids(stmt); -} diff --git a/src/models/macro_action.c b/src/models/macro_action.c deleted file mode 100644 index 97cbfc6..0000000 --- a/src/models/macro_action.c +++ /dev/null @@ -1,178 +0,0 @@ -#include <stdlib.h> -#include <stdint.h> -#include <stddef.h> - -#include <models/macro_action.h> -#include <logger.h> -#include <cache.h> -#include <database.h> - -static macro_action_t* -macro_action_db_select_mapper(sqlite3_stmt *stmt) -{ - macro_action_t *new_macro_action = malloc(sizeof(macro_action_t)); - for(int i = 0; i < sqlite3_column_count(stmt); i++) - { - const char *name = sqlite3_column_name(stmt, i); - switch(name[0]) - { - case 'm': // macro_id - new_macro_action->macro_id = sqlite3_column_int(stmt, i); - break; - case 'r': // relay_id - new_macro_action->relay_id = sqlite3_column_int(stmt, i); - break; - case 's': // schedule_id - new_macro_action->schedule_id = sqlite3_column_int(stmt, i); - break; - case 'w': // weekday - new_macro_action->weekday = (uint8_t)sqlite3_column_int(stmt, i); - break; - default: // ignore columns not implemented - break; - } - } - return new_macro_action; -} - -static macro_action_t** -macro_action_db_select(sqlite3_stmt *stmt) -{ - macro_action_t **all_macro_actions = malloc(sizeof(macro_action_t*)); - - int row = 0; - - for(;;) - { - int s; - - s = sqlite3_step(stmt); - if (s == SQLITE_ROW) - { - macro_action_t *new_macro_action = macro_action_db_select_mapper(stmt); - row++; - - all_macro_actions = (macro_action_t**)realloc(all_macro_actions, sizeof(macro_action_t*) * (row + 1)); - all_macro_actions[row - 1] = new_macro_action; - } - else - { - if(s == SQLITE_DONE) - { - break; - } - else - { - LOGGER_ERR("error selecting macro_actions from database: %s\n", sqlite3_errstr(s)); - break; - } - } - } - sqlite3_finalize(stmt); - all_macro_actions[row] = NULL; - return all_macro_actions; -} - -int -macro_action_insert(macro_action_t *macro_action) -{ - sqlite3_stmt *stmt; - - sqlite3_prepare_v2(global_database, "INSERT INTO macro_actions(macro_id, relay_id, schedule_id, weekday) values (?1, ?2, ?3, ?4);", -1, &stmt, NULL); - - sqlite3_bind_int(stmt, 1, macro_action->macro_id); - sqlite3_bind_int(stmt, 2, macro_action->relay_id); - sqlite3_bind_int(stmt, 3, macro_action->schedule_id); - sqlite3_bind_int(stmt, 4, macro_action->weekday); - - int rc = sqlite3_step(stmt); - - sqlite3_finalize(stmt); - - cache_invalidate_macro(macro_action->macro_id); - - return rc != SQLITE_DONE; -} - -int -macro_action_delete_for_macro(int macro_id) -{ - sqlite3_stmt *stmt; - - sqlite3_prepare_v2(global_database, "DELETE FROM macro_actions WHERE macro_id=?1;", -1, &stmt, NULL); - sqlite3_bind_int(stmt, 1, macro_id); - - int rc = sqlite3_step(stmt); - - sqlite3_finalize(stmt); - - cache_invalidate_macro(macro_id); - - return rc != SQLITE_DONE; -} - -macro_action_t** -macro_action_get_for_macro(int macro_id) -{ - LOGGER_DEBUG("getting macro_actions [macro_id=%d] from database\n", macro_id); - sqlite3_stmt *stmt; - - sqlite3_prepare_v2(global_database, "SELECT * FROM macro_actions WHERE macro_id=?", -1, &stmt, NULL); - sqlite3_bind_int(stmt, 1, macro_id); - - return macro_action_db_select(stmt); -} - -int -macro_action_execute(macro_action_t *macro_action) -{ - schedule_t *schedule = schedule_get_by_id(macro_action->schedule_id); - if(!schedule) - { - return 1; - } - - relay_t *relay = relay_get_by_id(macro_action->relay_id); - if(!relay) - { - free(schedule); - return 1; - } - - schedule_free(relay->schedules[macro_action->weekday]); - relay->schedules[macro_action->weekday] = schedule; - - return relay_save(relay); -} - -void -macro_action_free_list(macro_action_t **macro_actions) -{ - for(int i = 0; macro_actions[i] != NULL; ++i) - { - free(macro_actions[i]); - } - free(macro_actions); -} - -int* -macro_action_get_macro_ids_with_schedule(int schedule_id) -{ - sqlite3_stmt *stmt; - - sqlite3_prepare_v2(global_database, "SELECT macro_id FROM macro_actions WHERE schedule_id=?1;", -1, &stmt, NULL); - sqlite3_bind_int(stmt, 1, schedule_id); - - return database_helper_get_ids(stmt); -} - -int* -macro_action_get_macro_ids_with_relay(int relay_id) -{ - sqlite3_stmt *stmt; - - sqlite3_prepare_v2(global_database, "SELECT macro_id FROM macro_actions WHERE relay_id=?1;", -1, &stmt, NULL); - sqlite3_bind_int(stmt, 1, relay_id); - - return database_helper_get_ids(stmt); -} diff --git a/src/models/relay.c b/src/models/relay.c index 4efe837..df196f0 100644 --- a/src/models/relay.c +++ b/src/models/relay.c @@ -115,8 +115,7 @@ relay_db_select(sqlite3_stmt *stmt) int relay_save(relay_t *relay) { - database_transaction_lock lock; - database_transaction_begin(&lock); + int opened_transaction = database_transaction_begin(); sqlite3_stmt *stmt; if(relay->id) @@ -141,7 +140,10 @@ relay_save(relay_t *relay) LOGGER_ERR("error updating data: %s\n", sqlite3_errmsg(global_database)); } - database_transaction_rollback(&lock); + if(opened_transaction) + { + database_transaction_rollback(); + } } else { @@ -161,7 +163,10 @@ relay_save(relay_t *relay) } junction_relay_schedule_insert_weekdays(relay->id, schedule_ids); - database_transaction_commit(&lock); + if(opened_transaction) + { + database_transaction_commit(); + } } cache_invalidate_relay(relay->id, -1); diff --git a/src/models/schedule.c b/src/models/schedule.c index 3fc89e8..abb6850 100644 --- a/src/models/schedule.c +++ b/src/models/schedule.c @@ -46,8 +46,8 @@ schedule_db_select_mapper(sqlite3_stmt *stmt) new_schedule->id = sqlite3_column_int(stmt, i); break; case 'n': // name - strncpy(new_schedule->name, (const char*)sqlite3_column_text(stmt, i), MAX_NAME_LENGTH); - new_schedule->name[MAX_NAME_LENGTH] = '\0'; + strncpy(new_schedule->name, (const char*)sqlite3_column_text(stmt, i), 127); + new_schedule->name[127] = '\0'; break; case 'p': // periods periods_blob = sqlite3_column_blob(stmt, i); @@ -112,8 +112,7 @@ schedule_db_select(sqlite3_stmt *stmt) int schedule_save(schedule_t *schedule) { - database_transaction_lock lock; - database_transaction_begin(&lock); + int opened_transaction = database_transaction_begin(); sqlite3_stmt *stmt; if(schedule->id) @@ -138,7 +137,10 @@ schedule_save(schedule_t *schedule) LOGGER_ERR("error updating data: %s\n", sqlite3_errmsg(global_database)); } - database_transaction_rollback(&lock); + if(opened_transaction) + { + database_transaction_rollback(); + } } else { @@ -147,7 +149,10 @@ schedule_save(schedule_t *schedule) schedule->id = sqlite3_last_insert_rowid(global_database); } - database_transaction_commit(&lock); + if(opened_transaction) + { + database_transaction_commit(); + } } cache_invalidate_schedule(schedule->id); diff --git a/src/router.c b/src/router.c index 13b8299..6c74428 100644 --- a/src/router.c +++ b/src/router.c @@ -10,7 +10,6 @@ #include <endpoints/api_v1_controllers.h> #include <endpoints/api_v1_relays.h> #include <endpoints/api_v1_tags.h> -#include <endpoints/api_v1_macros.h> #include <endpoints/api_v1_ws.h> static endpoint_t endpoints[ROUTER_ENDPOINTS_MAX_COUNT]; @@ -91,13 +90,6 @@ router_init() router_register_endpoint("/api/v1/tags/{str}", HTTP_METHOD_GET, api_v1_tags_STR_GET); router_register_endpoint("/api/v1/tags/{str}", HTTP_METHOD_DELETE, api_v1_tags_STR_DELETE); - router_register_endpoint("/api/v1/macros/", HTTP_METHOD_GET, api_v1_macros_GET); - router_register_endpoint("/api/v1/macros/", HTTP_METHOD_POST, api_v1_macros_POST); - router_register_endpoint("/api/v1/macros/{str}", HTTP_METHOD_GET, api_v1_macros_STR_GET); - router_register_endpoint("/api/v1/macros/{str}", HTTP_METHOD_PUT, api_v1_macros_STR_PUT); - router_register_endpoint("/api/v1/macros/{str}", HTTP_METHOD_DELETE, api_v1_macros_STR_DELETE); - router_register_endpoint("/api/v1/macros/{str}/execute", HTTP_METHOD_PUT, api_v1_macros_STR_execute_PUT); - router_register_endpoint("/api/v1/ws/relays", HTTP_METHOD_WEBSOCKET, api_v1_ws_relays); } diff --git a/tests/core.testing.ini b/tests/core.testing.ini index 811a43b..c3710a1 100644 --- a/tests/core.testing.ini +++ b/tests/core.testing.ini @@ -1,7 +1,7 @@ [core] server-port = 5000 database = core.sqlite -content-dir = . +content-dir = /usr/share/webapps/emgauwa not-found-file = 404.html not-found-file-mime = text/html not-found-content = 404 - NOT FOUND diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 476b3ba..cbfbdb1 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -4,7 +4,7 @@ source_dir=$PWD working_dir=$PWD/testing_latest working_bak=$PWD/testing_bak -alias valgrind_emgauwa="valgrind -s $2 --log-file=$working_dir/valgrind.log" +alias valgrind_emgauwa="valgrind $2 --log-file=$working_dir/valgrind.log" rm -rf $working_bak @@ -40,8 +40,6 @@ controller_id=$! cd $working_dir -touch $working_dir/index.html - cp $1 $working_dir/core cp $source_dir/core.testing.ini $working_dir/core.ini diff --git a/tests/tavern_tests/0.1.test_basics.tavern.yaml b/tests/tavern_tests/0.1.test_basics.tavern.yaml deleted file mode 100644 index 14ac8b5..0000000 --- a/tests/tavern_tests/0.1.test_basics.tavern.yaml +++ /dev/null @@ -1,16 +0,0 @@ -test_name: "[test_basics] Test basic calls" - -stages: -- name: "[test_basics] get index" - request: - url: "http://localhost:5000/" - method: GET - response: - status_code: 200 - -- name: "[test_basics] get 404" - request: - url: "http://localhost:5000/invalid_url_for_testing_do_not_use" - method: GET - response: - status_code: 404 diff --git a/tests/tavern_tests/1.1.controller_relays_basic.tavern.yaml b/tests/tavern_tests/1.1.controller_relays_basic.tavern.yaml index 285d2d5..f0d1750 100644 --- a/tests/tavern_tests/1.1.controller_relays_basic.tavern.yaml +++ b/tests/tavern_tests/1.1.controller_relays_basic.tavern.yaml @@ -26,7 +26,7 @@ stages: extra_kwargs: relay_count: !int "{returned_relay_count:d}" -- name: "[controller_relays_basic] get controller relay" +- name: "[controller_relays_basic] get controller relays, check length" request: method: GET url: "http://localhost:5000/api/v1/controllers/{returned_id}/relays/5" @@ -40,69 +40,3 @@ stages: function: validate_relay:check_number extra_kwargs: number: 5 - -- name: "[controller_relays_basic] get controller relay with invalid uid" - request: - method: GET - url: "http://localhost:5000/api/v1/controllers/INVALID-UUID/relays/5" - response: - status_code: 400 - -- name: "[controller_relays_basic] get controller relay with unavailable uid" - request: - method: GET - url: "http://localhost:5000/api/v1/controllers/00000000-0000-0000-0000-000000000000/relays/5" - response: - status_code: 404 - -- name: "[controller_relays_basic] get controller relay with invalid number" - request: - method: GET - url: "http://localhost:5000/api/v1/controllers/{returned_id}/relays/not_a_number" - response: - status_code: 404 - -- name: "[controller_relays_basic] get controller relay with unavailable number" - request: - method: GET - url: "http://localhost:5000/api/v1/controllers/{returned_id}/relays/9001" - response: - status_code: 404 - - - - -- name: "[controller_relays_basic] pulse relay" - request: - method: POST - url: "http://localhost:5000/api/v1/controllers/{returned_id}/relays/6/pulse" - response: - status_code: 200 - -- name: "[controller_relays_basic] pulse relay with invalid uid" - request: - method: POST - url: "http://localhost:5000/api/v1/controllers/INVALID-UUID/relays/6/pulse" - response: - status_code: 400 - -- name: "[controller_relays_basic] pulse relay with unavailable uid" - request: - method: POST - url: "http://localhost:5000/api/v1/controllers/00000000-0000-0000-0000-000000000000/relays/6/pulse" - response: - status_code: 404 - -- name: "[controller_relays_basic] pulse relay with invalid number" - request: - method: POST - url: "http://localhost:5000/api/v1/controllers/{returned_id}/relays/not_a_number/pulse" - response: - status_code: 404 - -- name: "[controller_relays_basic] pulse relay with unavailable number" - request: - method: POST - url: "http://localhost:5000/api/v1/controllers/{returned_id}/relays/9001/pulse" - response: - status_code: 404 diff --git a/tests/tavern_tests/3.0.tags.tavern.yaml b/tests/tavern_tests/3.0.tags.tavern.yaml index 37734f8..d4ef67f 100644 --- a/tests/tavern_tests/3.0.tags.tavern.yaml +++ b/tests/tavern_tests/3.0.tags.tavern.yaml @@ -98,13 +98,6 @@ stages: controller_id: "{returned_id}" tag: "{returned_tag}" -- name: "[tags] get returned tag with relays and schedules" - request: - method: GET - url: "http://localhost:5000/api/v1/tags/{returned_tag}" - response: - status_code: 200 - - name: "[tags] get tags" request: method: GET @@ -113,47 +106,3 @@ stages: status_code: 200 verify_response_with: function: validate_tag:multiple - -- name: "[tags] get unavailable tag" - request: - method: GET - url: "http://localhost:5000/api/v1/tags/invalid_unavailable_tag" - response: - status_code: 404 - -- name: "[tags] post tag" - request: - method: POST - url: "http://localhost:5000/api/v1/tags/" - json: - tag: "unused_tag_1" - response: - status_code: 201 - -- name: "[tags] get posted tag" - request: - method: GET - url: "http://localhost:5000/api/v1/tags/unused_tag_1" - response: - status_code: 200 - -- name: "[tags] delete posted tag" - request: - method: DELETE - url: "http://localhost:5000/api/v1/tags/unused_tag_1" - response: - status_code: 200 - -- name: "[tags] get deleted tag" - request: - method: GET - url: "http://localhost:5000/api/v1/tags/unused_tag_1" - response: - status_code: 404 - -- name: "[tags] delete deleted tag again" - request: - method: DELETE - url: "http://localhost:5000/api/v1/tags/unused_tag_1" - response: - status_code: 404 diff --git a/tests/tavern_utils/validate_tag.py b/tests/tavern_utils/validate_tag.py index 6a3004a..1e907e5 100644 --- a/tests/tavern_utils/validate_tag.py +++ b/tests/tavern_utils/validate_tag.py @@ -11,9 +11,24 @@ def multiple(response): for tag in response.json(): _verify_single(tag) -def find(response, tag): - print(response.json()) - for response_tag in response.json(): - if response_tag == tag: - return - assert False, "tag not found in list" +#def find(response, name=None, number=None, controller_id=None, tag=None): +# print(response.json()) +# for tag in response.json(): +# if number != None and number != tag.get("number"): +# continue +# +# if name != None and name != tag.get("name"): +# continue +# +# if controller_id != None and controller_id != tag.get("controller_id"): +# continue +# +# if tag != None: +# found_in_response = False +# for response_tag in tag.get("tags"): +# if response_tag == tag: +# found_in_response = True +# if not found_in_response: +# continue +# return +# assert False, "tag not found in list"