diff options
Diffstat (limited to 'src/delete.c')
-rw-r--r-- | src/delete.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/src/delete.c b/src/delete.c new file mode 100644 index 0000000..ce7017f --- /dev/null +++ b/src/delete.c @@ -0,0 +1,176 @@ +#include <libgen.h> + +#include "actions.h" +#include "dblayer.h" +#include "queries.h" +#include "ckerrlog.h" + +ERRLOG(delete); + +static int delete_prog(DB *db, int pid) { + sqlite3_stmt *stmt; + int rc; + + char sql[STR_M] = ""; + dbh_form_query_delete_x_from_y(sql, COL_PROGRAM_ID, TBL_PROGRAM); + + rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0); + if (rc != SQLITE_OK) { + return -1; + } + sqlite3_bind_int(stmt, 1, pid); + sqlite3_step(stmt); + if (rc != SQLITE_OK) { + return -1; + } + + sqlite3_finalize(stmt); + return 0; +} + +static int delete_conf(DB *db, int cid) { + sqlite3_stmt *stmt; + int rc; + + char sql[STR_M] = ""; + dbh_form_query_delete_x_from_y(sql, COL_CONFIG_ID, TBL_CONFIG); + + rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0); + if (rc != SQLITE_OK) { + return -1; + } + sqlite3_bind_int(stmt, 1, cid); + sqlite3_step(stmt); + if (rc != SQLITE_OK) { + return -1; + } + + sqlite3_finalize(stmt); + return 0; +} + +/* Removes the relationship of `cid` with the corresponding program. + * Returns the program's pid on succes, negative integer otherwise. + */ +static int remove_conf_rel(DB *db, int cid) { + sqlite3_stmt *stmt; + int rc; + + int pid = get_pid_from_cid(db, cid); + + char sql[STR_M] = ""; + dbh_form_query_delete_x_from_y(sql, COL_REL_CONFIG_ID, TBL_REL); + rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0); + if (rc != SQLITE_OK) { + return -1; + } + sqlite3_bind_int(stmt, 1, cid); + sqlite3_step(stmt); + if (rc != SQLITE_OK) { + return -1; + } + + sqlite3_finalize(stmt); + + return pid; +} + +static int remove_all_configs(DB *db, int pid) { + sqlite3_stmt *stmt; + int rc; + + char sql[STR_M] = ""; + dbh_form_query_select_from_joined_eq(sql, COL_REL_CONFIG_ID, COL_REL_PROGRAM_ID); + rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0); + if (rc != SQLITE_OK) { + return -2; + } + + sqlite3_bind_int(stmt, 1, pid); + + while (sqlite3_step(stmt) == SQLITE_ROW) { + delete_conf(db, sqlite3_column_int(stmt, 0)); + remove_conf_rel(db, sqlite3_column_int(stmt, 0)); + } + sqlite3_finalize(stmt); + + return 0; +} + +static int get_cid_from_pname_and_basename(DB *db, const char *pName, const char *cBaseName) { + sqlite3_stmt *stmt; + int rc; + + char sql[STR_L] = ""; + char selection[STR_M] = TBL_CONFIG; + strcat(selection, "."); + strcat(selection, COL_CONFIG_ID); + strcat(selection, ", "); + strcat(selection, COL_CONFIG_PATH); + + char condition[STR_M] = TBL_PROGRAM; + strcat(condition, "."); + strcat(condition, COL_PROGRAM_NAME); + + dbh_form_query_select_from_joined_eq(sql, selection, condition); + rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0); + if (rc != SQLITE_OK) { + ERR("while preparing get_cid_from_pname_and_basename"); + db->error = SQL_ERR_SQLITE; + return -1; + } + + sqlite3_bind_text(stmt, 1, pName, -1, 0); + int _cid = -1; + while (sqlite3_step(stmt) == SQLITE_ROW) { + if (strcmp(cBaseName, basename((char *)sqlite3_column_text(stmt, 1))) == 0) { + _cid = sqlite3_column_int(stmt, 0); + break; + } + } + sqlite3_finalize(stmt); + return _cid; +} + +int del_transaction_try(DB *db, const char *pName, const char *cBaseName) { + __BEGIN_TRANSACTION__ + int pid = -1; + if (cBaseName) { + // del conf + int cid = get_cid_from_pname_and_basename(db, pName, cBaseName); + if (cid < 0) { + ERR("Config %s doesn't exist in the database.", cBaseName); + return -1; + } + if (delete_conf(db, cid)) { + ERR("Could not delete config %s from db.", cBaseName); + return -1; + } + // handle relations + pid = remove_conf_rel(db, cid); + HELP("Deleted %s config: %s", pName, cBaseName); + if (get_program_relations(db, pid) > 0) { + goto end; + } + } + else { + pid = get_program_id(db, pName); + } + if (pid < 0) { + ERR("Program not found in the db."); + return -1; + } + /* If we are deleting a program we should delete everything that + * refferences it (configs and relationships) */ + if (!cBaseName) { + remove_all_configs(db, pid); + } + if(delete_prog(db, pid)) { + ERR("Could not delete program %s from db.", pName); + return -1; + } + HELP("Deleted program %s", pName); + end: + __END_TRANSACTION__ + return 0; +} |