aboutsummaryrefslogtreecommitdiffstats
path: root/src/delete.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/delete.c')
-rw-r--r--src/delete.c176
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;
+}