From f67b7e9e0fe0a0a0c3a14622fe2f4aae25e85786 Mon Sep 17 00:00:00 2001 From: Tobias Reisinger Date: Sat, 29 Aug 2020 22:58:02 +0200 Subject: [PATCH] add: basic macro functions add: better migration handling (transactions) --- CMakeLists.txt | 26 +++++++++--------- include/models/junction_macro.h | 7 +++++ sql/cache.sql | 2 ++ sql/migration_0.sql | 14 +++++----- sql/migration_1.sql | 28 +++++++++++++++++++ src/database.c | 48 +++++++++++++++++++++------------ src/models/junction_macro.c | 33 +++++++++++++++++++++++ 7 files changed, 122 insertions(+), 36 deletions(-) create mode 100644 include/models/junction_macro.h create mode 100644 sql/migration_1.sql create mode 100644 src/models/junction_macro.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f6f722..532a906 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,24 +44,18 @@ add_custom_target(run WORKING_DIRECTORY ${CMAKE_BINARY_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 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(test-callgrind - COMMAND ./run_tests.sh ${CMAKE_BINARY_DIR}/core "--tool=callgrind" - DEPENDS core - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests -) - -IF(CMAKE_BUILD_TYPE MATCHES DEBUG) +IF(CMAKE_BUILD_TYPE MATCHES Debug) message("debug mode") add_custom_target(debug COMMAND valgrind -s ./core start @@ -83,4 +77,10 @@ IF(CMAKE_BUILD_TYPE MATCHES DEBUG) DEPENDS test WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ) -ENDIF(CMAKE_BUILD_TYPE MATCHES DEBUG) + + 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/models/junction_macro.h b/include/models/junction_macro.h new file mode 100644 index 0000000..6998c50 --- /dev/null +++ b/include/models/junction_macro.h @@ -0,0 +1,7 @@ +#ifndef CORE_JUNCTION_MACRO_H +#define CORE_JUNCTION_MACRO_H + +int +junction_macro_insert(int macro_id, int relay_id, int schedule_id, uint8_t weekday); + +#endif /* CORE_JUNCTION_MACRO_H */ diff --git a/sql/cache.sql b/sql/cache.sql index 5ca7471..3e4ce21 100644 --- a/sql/cache.sql +++ b/sql/cache.sql @@ -1,3 +1,5 @@ +-- 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 12dda72..939b907 100644 --- a/sql/migration_0.sql +++ b/sql/migration_0.sql @@ -1,4 +1,6 @@ -create table controllers +-- base migration + +CREATE TABLE controllers ( id INTEGER PRIMARY KEY @@ -14,7 +16,7 @@ create table controllers NOT NULL ); -create table relays +CREATE TABLE relays ( id INTEGER PRIMARY KEY @@ -28,7 +30,7 @@ create table relays ON DELETE CASCADE ); -create table schedules +CREATE TABLE schedules ( id INTEGER PRIMARY KEY @@ -40,7 +42,7 @@ create table schedules periods BLOB ); -create table tags +CREATE TABLE tags ( id INTEGER PRIMARY KEY @@ -50,7 +52,7 @@ create table tags UNIQUE ); -create table junction_tag +CREATE TABLE junction_tag ( tag_id INTEGER NOT NULL @@ -64,7 +66,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 new file mode 100644 index 0000000..da01bf0 --- /dev/null +++ b/sql/migration_1.sql @@ -0,0 +1,28 @@ +-- migration to add macros + +CREATE TABLE macros +( + id INTEGER + PRIMARY KEY + AUTOINCREMENT, + uid BLOB + NOT NULL + UNIQUE, + name VARCHAR(128) +); + +CREATE TABLE junction_macro +( + 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/database.c b/src/database.c index 02fd75a..a0f5aeb 100644 --- a/src/database.c +++ b/src/database.c @@ -5,6 +5,7 @@ #include #include +#include sqlite3 *global_database; static int in_transaction; @@ -32,11 +33,35 @@ 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, rc; + int s; sqlite3_stmt *stmt; sqlite3_prepare_v2(global_database, "PRAGMA user_version;", -1, &stmt, NULL); s = sqlite3_step(stmt); @@ -49,31 +74,20 @@ database_migrate() version_num = 0; } - uint16_t new_version_num = version_num; - char* err_msg; - sqlite3_finalize(stmt); switch(version_num) { case 0: - LOGGER_INFO("migrating LEVEL 0\n"); - rc = sqlite3_exec(global_database, (const char *)sql_migration_0_sql, NULL, NULL, &err_msg); - if(rc) - { - LOGGER_CRIT("couldn't migrate LEVEL 0 (%s)\n", err_msg); - exit(1); - } - new_version_num = 1; + 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)); 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; } diff --git a/src/models/junction_macro.c b/src/models/junction_macro.c new file mode 100644 index 0000000..6ff7b89 --- /dev/null +++ b/src/models/junction_macro.c @@ -0,0 +1,33 @@ +#include +#include +#include + +#include +#include +#include +#include + +int +junction_macro_insert(int macro_id, int relay_id, int schedule_id, uint8_t weekday) +{ + int rc; + sqlite3_stmt *stmt; + + sqlite3_prepare_v2(global_database, "INSERT INTO junction_macro(macro_id, schedule_id, relay_id, weekday) values (?1, ?2, ?3);", -1, &stmt, NULL); + + sqlite3_bind_int(stmt, 1, macro_id); + sqlite3_bind_int(stmt, 2, relay_id); + sqlite3_bind_int(stmt, 3, schedule_id); + sqlite3_bind_int(stmt, 4, weekday); + + rc = sqlite3_step(stmt); + if (rc != SQLITE_DONE) + { + LOGGER_ERR("error inserting data: %s", sqlite3_errmsg(global_database)); + return 1; + } + + sqlite3_finalize(stmt); + + return 0; +}