#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); }