diff --git a/src/cli/CMakeLists.txt b/src/cli/CMakeLists.txt index dc3c98a..bac7ac3 100644 --- a/src/cli/CMakeLists.txt +++ b/src/cli/CMakeLists.txt @@ -1,4 +1,4 @@ -add_executable(klist main.c process.c config.c) +add_executable(klist main.c process.c config.c util.c) target_include_directories(klist PRIVATE include) target_link_libraries(klist libklist) target_compile_options(klist PRIVATE -Werror -Wall) #-Wextra) \ No newline at end of file diff --git a/src/cli/include/process.h b/src/cli/include/process.h index 85696af..ad7d6a6 100644 --- a/src/cli/include/process.h +++ b/src/cli/include/process.h @@ -1,17 +1,17 @@ #pragma once -#include "klist.h" +#include "util.h" -int klist_app_user_get(const klist *); -int klist_app_user_create(const klist *); -int klist_app_user_delete(const klist *); +int klist_app_user_get(const klist_app *); +int klist_app_user_create(const klist_app *); +int klist_app_user_delete(const klist_app *); -int klist_app_list_add(const klist *); -int klist_app_list_edit(const klist *); -int klist_app_list_get(const klist *); -int klist_app_list_delete(const klist *); +int klist_app_list_add(const klist_app *); +int klist_app_list_edit(const klist_app *); +int klist_app_list_get(const klist_app *); +int klist_app_list_delete(const klist_app *); -int klist_app_task_add(const klist *); -int klist_app_task_edit(const klist *); -int klist_app_task_get(const klist *); -int klist_app_task_delete(const klist *); \ No newline at end of file +int klist_app_task_add(const klist_app *); +int klist_app_task_edit(const klist_app *); +int klist_app_task_get(const klist_app *); +int klist_app_task_delete(const klist_app *); \ No newline at end of file diff --git a/src/cli/include/util.h b/src/cli/include/util.h new file mode 100644 index 0000000..006bd0d --- /dev/null +++ b/src/cli/include/util.h @@ -0,0 +1,72 @@ +#pragma once +#include "util.h" +#include +#include + +#include "klist.h" + +enum klist_command { + USER, + LIST, + TASK, +}; + +struct klist_app { + enum klist_command cmd; + void *cmd_ctx; + int error; + klist_logging_ctx *log_ctx; + klist *handle; +}; +typedef struct klist_app klist_app; + +klist_app *klist_app_init(char *db); +void klist_app_deinit(klist_app *app); + +enum klist_user_command { USER_GET, USER_CREATE, USER_DELETE }; +struct klist_user_context { + enum klist_user_command cmd; +}; +typedef struct klist_user_context klist_user_context; + +klist_user_context *klist_user_context_init(void); +void klist_user_context_deinit(klist_user_context *ctx); + +enum klist_list_command { + LIST_ADD, + LIST_EDIT, + LIST_GET, + LIST_DELETE, +}; +struct klist_list_context { + enum klist_list_command cmd; + char *name; + char *desc; + char **stages; + size_t stages_len; + char *preset; +}; +typedef struct klist_list_context klist_list_context; + +klist_list_context *klist_list_context_init(void); +klist_list_context *klist_list_context_get_by_id(klist_list_context *ctx, + u_int id); +void klist_list_context_deinit(klist_list_context *ctx); + +enum klist_task_command { + TASK_ADD, + TASK_EDIT, + TASK_GET, + TASK_DELETE, +}; +struct klist_task_context { + enum klist_task_command cmd; + char *list; + char *name; + char *desc; + char *stage; +}; +typedef struct klist_task_context klist_task_context; + +klist_task_context *klist_task_context_init(void); +void klist_task_context_deinit(klist_task_context *ctx); \ No newline at end of file diff --git a/src/cli/main.c b/src/cli/main.c index 8c1d1af..d81c879 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -7,8 +7,8 @@ #include "process.h" #include "util.h" -void print_help(klist *ctx, char **argv); -void setup(klist *ctx, int argc, char **argv); +void print_help(char **argv); +void setup(klist_app *ctx, int argc, char **argv); int main(int argc, char **argv) { char *name = "klist"; @@ -25,13 +25,13 @@ int main(int argc, char **argv) { klist_config_parse(&config, config_file); - klist *ctx = klist_init(config[CONFIG_DATABASE_NAME]); + klist_app *ctx = klist_app_init(config[CONFIG_DATABASE_NAME]); free(config_file_name); free(config[CONFIG_DATABASE_NAME]); if (argc == 1) { - print_help(ctx, argv); + print_help(argv); ctx->error = 1; } @@ -56,7 +56,7 @@ int main(int argc, char **argv) { case LIST: klist_list_context *list_ctx = ctx->cmd_ctx; if (!list_ctx->name && list_ctx->cmd != LIST_GET) { - klist_print(ctx, KLIST_LOG_ERROR, "Missing name.\n"); + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "Missing name.\n"); break; } switch (list_ctx->cmd) { @@ -94,15 +94,13 @@ int main(int argc, char **argv) { } const int error = ctx->error; - klist_deinit(ctx); + klist_app_deinit(ctx); return error; } -void print_help(klist *ctx, char **argv) { - printf("Usage: %s \n", argv[0]); -} +void print_help(char **argv) { printf("Usage: %s \n", argv[0]); } -void setup(klist *ctx, int argc, char **argv) { +void setup(klist_app *ctx, int argc, char **argv) { if (strcmp(argv[1], "user") == 0) ctx->cmd = USER; else if (strcmp(argv[1], "list") == 0) @@ -110,7 +108,7 @@ void setup(klist *ctx, int argc, char **argv) { else if (strcmp(argv[1], "task") == 0) ctx->cmd = TASK; else - print_help(ctx, argv); + print_help(argv); int opt; switch (ctx->cmd) { @@ -129,7 +127,7 @@ void setup(klist *ctx, int argc, char **argv) { user_ctx->cmd = USER_GET; break; default: - print_help(ctx, argv); + print_help(argv); } ctx->cmd_ctx = user_ctx; break; @@ -171,22 +169,21 @@ void setup(klist *ctx, int argc, char **argv) { } break; default: - print_help(ctx, argv); - klist_print( - ctx, KLIST_LOG_ERROR, - "" - "list options:\n" - "-a\t\tadd a list\n" - "-e\t\tedit a list\n" - "-d\t\tdelete a list\n" - "-p \tdefine as preset or use existing one with name " - "\n" - "Not providing a parameter prints all lists and existing " - "presets.\n\n"); + print_help(argv); + fprintf(stderr, + "" + "list options:\n" + "-a\t\tadd a list\n" + "-e\t\tedit a list\n" + "-d\t\tdelete a list\n" + "-p \tdefine as preset or use existing one with name " + "\n" + "Not providing a parameter prints all lists and existing " + "presets.\n\n"); } break; case TASK: - klist_task_context *task_ctx = klist_task_context_init(ctx); + klist_task_context *task_ctx = klist_task_context_init(); optind = 2; @@ -214,8 +211,8 @@ void setup(klist *ctx, int argc, char **argv) { task_ctx->stage = strdup(optarg); break; default: - print_help(ctx, argv); - klist_print(ctx, KLIST_LOG_ERROR, + print_help(argv); + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "" "task options:" "-a\tadd a task" @@ -228,8 +225,8 @@ void setup(klist *ctx, int argc, char **argv) { ctx->cmd_ctx = task_ctx; break; default: - klist_print(ctx, KLIST_LOG_ERROR, + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "How did we land here?! Pls report argv[1] = %s\n", argv[1]); - print_help(ctx, argv); + print_help(argv); } } diff --git a/src/cli/process.c b/src/cli/process.c index 7796a51..911e16d 100644 --- a/src/cli/process.c +++ b/src/cli/process.c @@ -4,83 +4,88 @@ #include #include -int klist_app_user_get(const klist *ctx) { - klist_user *user = klist_user_get_by_local(ctx, getuid()); +#include "models.h" + +int klist_app_user_get(const klist_app *ctx) { + klist_user *user = klist_user_get_by_local(ctx->handle, getuid()); if (user) { printf("User: %s\nID: %lu\n", (char *)user->name, user->id); size_t lists_len = 0; - klist_list **lists = klist_list_get_all_by_user(ctx, user->id, &lists_len); + klist_list **lists = + klist_list_get_all_by_user(ctx->handle, user->id, &lists_len); printf("Lists: %lu\n", lists_len); int i = 0; for (; i < lists_len; i++) klist_list_deinit(lists[i]); } else - klist_print(ctx, KLIST_LOG_ERROR, "No user for '%s' found.\n", getlogin()); + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "No user for '%s' found.\n", + getlogin()); return 0; } -int klist_app_user_create(const klist *ctx) { - klist_print(ctx, KLIST_LOG_INFO, - (klist_assure_user(ctx, getuid(), getlogin())) +int klist_app_user_create(const klist_app *ctx) { + klist_print(ctx->log_ctx, KLIST_LOG_INFO, + (klist_assure_user(ctx->handle, getuid(), getlogin())) ? "User created.\n" : "User already exists.\n"); return 0; } -int klist_app_user_delete(const klist *ctx) { - klist_user *user = klist_user_get_by_local(ctx, getuid()); +int klist_app_user_delete(const klist_app *ctx) { + klist_user *user = klist_user_get_by_local(ctx->handle, getuid()); if (user) { - klist_user_delete(ctx, user); + klist_user_delete(ctx->handle, user); printf("User deleted.\n"); } else - klist_print(ctx, KLIST_LOG_ERROR, "User not found, no changes done.\n"); + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, + "User not found, no changes done.\n"); return 0; } -int klist_app_list_add(const klist *ctx) { +int klist_app_list_add(const klist_app *ctx) { klist_list_context *list_ctx = ctx->cmd_ctx; if (!list_ctx->stages_len) { - klist_print(ctx, KLIST_LOG_ERROR, "Missing stages.\n"); + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "Missing stages.\n"); return 1; } - klist_assure_user(ctx, getuid(), getlogin()); - klist_user *user = klist_user_get_by_local(ctx, getuid()); + klist_assure_user(ctx->handle, getuid(), getlogin()); + klist_user *user = klist_user_get_by_local(ctx->handle, getuid()); klist_list *list = - klist_list_get_by_user_and_name(ctx, user->id, list_ctx->name); + klist_list_get_by_user_and_name(ctx->handle, user->id, list_ctx->name); if (!list) list = klist_list_init(); list->name = (unsigned char *)strdup(list_ctx->name); if (list->desc) list->desc = (unsigned char *)strdup(list_ctx->desc); list->is_preset = false; - klist_list_save(ctx, list, user); + klist_list_save(ctx->handle, list, user); printf("Added list '%s'\n", (char *)list->name); int i = 0; for (; i < list_ctx->stages_len; i++) { klist_stage *stage = klist_stage_init(); stage->name = (unsigned char *)strdup(list_ctx->stages[i]); stage->list_id = list->id; - klist_stage_save(ctx, stage); + klist_stage_save(ctx->handle, stage); klist_stage_deinit(stage); } return 0; } -int klist_app_list_edit(const klist *ctx) { - klist_print(ctx, KLIST_LOG_ERROR, "Not implemented\n"); +int klist_app_list_edit(const klist_app *ctx) { + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "Not implemented\n"); return 0; } -int klist_app_list_get(const klist *ctx) { +int klist_app_list_get(const klist_app *ctx) { klist_list_context *list_ctx = ctx->cmd_ctx; - klist_user *user = klist_user_get_by_local(ctx, getuid()); + klist_user *user = klist_user_get_by_local(ctx->handle, getuid()); size_t lists_len = 0; klist_list **lists = NULL; if (list_ctx->name) { klist_list *list = - klist_list_get_by_user_and_name(ctx, user->id, list_ctx->name); + klist_list_get_by_user_and_name(ctx->handle, user->id, list_ctx->name); if (list) { lists_len = 1; lists = malloc(lists_len * sizeof(klist_list)); @@ -88,14 +93,15 @@ int klist_app_list_get(const klist *ctx) { klist_list_deinit(list); }; } else - lists = klist_list_get_all_by_user(ctx, user->id, &lists_len); + lists = klist_list_get_all_by_user(ctx->handle, user->id, &lists_len); if (lists_len) { int i = 0; for (; i < lists_len; i++) { klist_list *list = lists[i]; size_t tasks_len = 0; - klist_task **tasks = klist_task_get_for_list(ctx, list->id, &tasks_len); + klist_task **tasks = + klist_task_get_for_list(ctx->handle, list->id, &tasks_len); printf("Name: %s\n", (char *)list->name); printf("Description: %s\n", list->desc ? (char *)list->desc : "N/A"); printf("Tasks: %ld\n", tasks_len); @@ -107,61 +113,76 @@ int klist_app_list_get(const klist *ctx) { } free(lists); } else if (list_ctx->name) - klist_print(ctx, KLIST_LOG_ERROR, "List '%s' not found.\n", list_ctx->name); + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "List '%s' not found.\n", + list_ctx->name); else - klist_print(ctx, KLIST_LOG_WARNING, "No lists found.\n"); + klist_print(ctx->log_ctx, KLIST_LOG_WARNING, "No lists found.\n"); return 0; } -int klist_app_list_delete(const klist *ctx) { +int klist_app_list_delete(const klist_app *ctx) { klist_list_context *list_ctx = ctx->cmd_ctx; - klist_assure_user(ctx, getuid(), getlogin()); - klist_user *user = klist_user_get_by_local(ctx, getuid()); + klist_assure_user(ctx->handle, getuid(), getlogin()); + klist_user *user = klist_user_get_by_local(ctx->handle, getuid()); if (!user) { - klist_print(ctx, KLIST_LOG_ERROR, "User doesn't exist.\n"); + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "User doesn't exist.\n"); return 1; } klist_list *list = - klist_list_get_by_user_and_name(ctx, user->id, list_ctx->name); + klist_list_get_by_user_and_name(ctx->handle, user->id, list_ctx->name); if (list) { - size_t tasks_len = 0; - klist_task **tasks = klist_task_get_for_list(ctx, list->id, &tasks_len); + size_t len = 0; + klist_task **tasks = klist_task_get_for_list(ctx->handle, list->id, &len); int i = 0; - for (; i < tasks_len; i++) { - klist_task_delete(ctx, tasks[i]); + for (; i < len; i++) { + klist_task_delete(ctx->handle, tasks[i]); klist_task_deinit(tasks[i]); } + klist_stage **stages = + klist_stage_get_all_for_list(ctx->handle, list->id, &len); + for (i = 0; i < len; i++) { + klist_stage_delete(ctx->handle, stages[i]); + klist_stage_deinit(stages[i]); + } + klist_list_delete(ctx->handle, list); + klist_list_deinit(list); + free(stages); free(tasks); + } else { + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "List '%s' not found.\n", + list_ctx->name); } return 0; } -int klist_app_task_add(const klist *ctx) { return klist_app_task_edit(ctx); } +int klist_app_task_add(const klist_app *ctx) { + return klist_app_task_edit(ctx); +} -int klist_app_task_edit(const klist *ctx) { +int klist_app_task_edit(const klist_app *ctx) { klist_task_context *task_ctx = ctx->cmd_ctx; - klist_assure_user(ctx, getuid(), getlogin()); - klist_user *user = klist_user_get_by_local(ctx, getuid()); + klist_assure_user(ctx->handle, getuid(), getlogin()); + klist_user *user = klist_user_get_by_local(ctx->handle, getuid()); klist_list *list = NULL; if (!user) { - klist_print(ctx, KLIST_LOG_ERROR, "User doesn't exist.\n"); + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "User doesn't exist.\n"); return 1; } - list = klist_list_get_by_user_and_name(ctx, user->id, task_ctx->list); + list = klist_list_get_by_user_and_name(ctx->handle, user->id, task_ctx->list); if (list) { size_t stages_len = 0; int i = 0; klist_stage **stages = - klist_stage_get_all_for_list(ctx, list->id, &stages_len); + klist_stage_get_all_for_list(ctx->handle, list->id, &stages_len); if (!task_ctx->stage) { - klist_print(ctx, KLIST_LOG_ERROR, + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "Stage missing/wrong, please pass one of: "); for (i = 0; i < stages_len; i++) - fprintf(ctx->log_target, "%s ", (char *)stages[i]->name); - fprintf(ctx->log_target, "\n"); + fprintf(ctx->log_ctx->log_target, "%s ", (char *)stages[i]->name); + fprintf(ctx->log_ctx->log_target, "\n"); } long stage_id = -1; for (i = 0; i < stages_len; i++) @@ -169,18 +190,18 @@ int klist_app_task_edit(const klist *ctx) { stage_id = stages[i]->id; if (stage_id == -1) { - klist_print(ctx, KLIST_LOG_ERROR, + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "Stage %s not found. Use one of: ", task_ctx->stage); for (i = 0; i < stages_len; i++) - fprintf(ctx->log_target, "%s ", (char *)stages[i]->name); - fprintf(ctx->log_target, "\n"); + fprintf(ctx->log_ctx->log_target, "%s ", (char *)stages[i]->name); + fprintf(ctx->log_ctx->log_target, "\n"); } for (i = 0; i < stages_len; i++) klist_stage_deinit(stages[i]); free(stages); klist_task *task = - klist_task_get_for_list_by_name(ctx, list->id, task_ctx->name); + klist_task_get_for_list_by_name(ctx->handle, list->id, task_ctx->name); if (!task) task = klist_task_init(); if (task->name) @@ -191,43 +212,44 @@ int klist_app_task_edit(const klist *ctx) { if (task_ctx->desc) task->desc = (unsigned char *)strdup(task_ctx->desc); task->stage_id = stage_id; - klist_task_save(ctx, task); + klist_task_save(ctx->handle, task); klist_task_deinit(task); } else - klist_print(ctx, KLIST_LOG_ERROR, "List not found.\n"); + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "List not found.\n"); klist_user_deinit(user); if (list) klist_list_deinit(list); return 0; } -int klist_app_task_get(const klist *ctx) { +int klist_app_task_get(const klist_app *ctx) { klist_task_context *task_ctx = ctx->cmd_ctx; - klist_assure_user(ctx, getuid(), getlogin()); - klist_user *user = klist_user_get_by_local(ctx, getuid()); + klist_assure_user(ctx->handle, getuid(), getlogin()); + klist_user *user = klist_user_get_by_local(ctx->handle, getuid()); if (!user) { - klist_print(ctx, KLIST_LOG_ERROR, "User doesn't exist.\n"); + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "User doesn't exist.\n"); return 1; } klist_list *list = - klist_list_get_by_user_and_name(ctx, user->id, task_ctx->list); + klist_list_get_by_user_and_name(ctx->handle, user->id, task_ctx->list); if (list) { if (task_ctx->name) { - klist_task *task = - klist_task_get_for_list_by_name(ctx, list->id, task_ctx->name); + klist_task *task = klist_task_get_for_list_by_name(ctx->handle, list->id, + task_ctx->name); if (task) { printf("Name: %s\n", (char *)task->name); printf("Description: %s\n", task->desc ? (char *)task->desc : "N/A"); - klist_stage *stage = klist_stage_get_by_id(ctx, task->stage_id); + klist_stage *stage = klist_stage_get_by_id(ctx->handle, task->stage_id); printf("Stage: %s\n", (char *)stage->name); klist_stage_deinit(stage); klist_task_deinit(task); } else - klist_print(ctx, KLIST_LOG_ERROR, "Task not found.\n"); + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "Task not found.\n"); } else { size_t tasks_len = 0; - klist_task **tasks = klist_task_get_for_list(ctx, list->id, &tasks_len); - klist_print_list(ctx, list, tasks, tasks_len); + klist_task **tasks = + klist_task_get_for_list(ctx->handle, list->id, &tasks_len); + klist_print_list(ctx->handle, list, tasks, tasks_len); int i = 0; for (; i < tasks_len; i++) @@ -235,39 +257,39 @@ int klist_app_task_get(const klist *ctx) { free(tasks); } } else - klist_print(ctx, KLIST_LOG_ERROR, "list not found\n"); + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "list not found\n"); klist_user_deinit(user); if (list) klist_list_deinit(list); return 0; } -int klist_app_task_delete(const klist *ctx) { +int klist_app_task_delete(const klist_app *ctx) { klist_task_context *task_ctx = ctx->cmd_ctx; - klist_assure_user(ctx, getuid(), getlogin()); - klist_user *user = klist_user_get_by_local(ctx, getuid()); + klist_assure_user(ctx->handle, getuid(), getlogin()); + klist_user *user = klist_user_get_by_local(ctx->handle, getuid()); if (!user) { - klist_print(ctx, KLIST_LOG_ERROR, "User doesn't exist.\n"); + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "User doesn't exist.\n"); return 1; } klist_list *list = - klist_list_get_by_user_and_name(ctx, user->id, task_ctx->list); + klist_list_get_by_user_and_name(ctx->handle, user->id, task_ctx->list); if (list) { if (task_ctx->name) { - klist_task *task = - klist_task_get_for_list_by_name(ctx, list->id, task_ctx->name); + klist_task *task = klist_task_get_for_list_by_name(ctx->handle, list->id, + task_ctx->name); if (task) { - klist_print(ctx, KLIST_LOG_WARNING, "Deleting task '%s'.\n", + klist_print(ctx->log_ctx, KLIST_LOG_WARNING, "Deleting task '%s'.\n", (char *)task->name); - klist_task_delete(ctx, task); + klist_task_delete(ctx->handle, task); klist_task_deinit(task); } else - klist_print(ctx, KLIST_LOG_ERROR, "Task not found.\n"); + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "Task not found.\n"); } else - klist_print(ctx, KLIST_LOG_ERROR, + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "Task not found, only deletion by name is " "currently supoprted.\n"); } else - klist_print(ctx, KLIST_LOG_ERROR, "Not implemented\n"); + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "Not implemented\n"); return 0; } \ No newline at end of file diff --git a/src/cli/util.c b/src/cli/util.c new file mode 100644 index 0000000..46d188a --- /dev/null +++ b/src/cli/util.c @@ -0,0 +1,80 @@ +#include "util.h" + +#include + +klist_app *klist_app_init(char *db) { + klist_app *app = malloc(sizeof(klist_app)); + app->cmd = 0; + app->cmd_ctx = 0; + app->error = 0; + app->log_ctx = malloc(sizeof(klist_logging_ctx)); + app->log_ctx->log_level = KLIST_LOG_DEBUG; + app->log_ctx->log_target = stderr; + app->handle = klist_init(db); + app->handle->log_ctx->log_level = app->log_ctx->log_level; + app->handle->log_ctx->log_target = app->log_ctx->log_target; + return app; +} +void klist_app_deinit(klist_app *ctx) { + free(ctx->log_ctx); + if (ctx->handle) + klist_deinit(ctx->handle); + free(ctx); +} + +klist_user_context *klist_user_context_init() { + klist_user_context *ctx = malloc(sizeof(klist_user_context)); + ctx->cmd = -1; + return ctx; +} +void klist_user_context_deinit(klist_user_context *ctx) { + free(ctx); + ctx = NULL; +} + +klist_list_context *klist_list_context_init() { + klist_list_context *ctx = malloc(sizeof(klist_list_context)); + ctx->cmd = -1; + ctx->name = NULL; + ctx->desc = NULL; + ctx->stages = NULL; + ctx->stages_len = 0; + ctx->preset = NULL; + return ctx; +} +void klist_list_context_deinit(klist_list_context *ctx) { + if (ctx->name) + free(ctx->name); + if (ctx->desc) + free(ctx->desc); + if (ctx->preset) + free(ctx->preset); + if (ctx->stages) { + int i = 0; + for (; i < ctx->stages_len; i++) + free(ctx->stages[i]); + free(ctx->stages); + } + free(ctx); + ctx = NULL; +} + +klist_task_context *klist_task_context_init() { + klist_task_context *ctx = malloc(sizeof(klist_task_context)); + ctx->cmd = -1; + ctx->name = NULL; + ctx->desc = NULL; + ctx->list = NULL; + ctx->stage = NULL; + return ctx; +} +void klist_task_context_deinit(klist_task_context *ctx) { + if (ctx->name) + free(ctx->name); + if (ctx->list) + free(ctx->list); + if (ctx->stage) + free(ctx->stage); + free(ctx); + ctx = NULL; +} diff --git a/src/libklist/include/util.h b/src/libklist/include/util.h index ffdf4b4..e2ce270 100644 --- a/src/libklist/include/util.h +++ b/src/libklist/include/util.h @@ -16,73 +16,24 @@ enum KLIST_LOG_LEVEL { }; typedef enum KLIST_LOG_LEVEL KLIST_LOG_LEVEL; -enum klist_command { - USER, - LIST, - TASK, +struct klist_logging_ctx { + KLIST_LOG_LEVEL log_level; + FILE *log_target; }; + +typedef struct klist_logging_ctx klist_logging_ctx; + struct klist { sqlite3 *db; sqlite3_stmt **stmts; - u_int cmd; - void *cmd_ctx; int error; - KLIST_LOG_LEVEL log_level; - FILE *log_target; + klist_logging_ctx *log_ctx; }; typedef struct klist klist; klist *klist_init(char *db); void klist_deinit(klist *list); -enum klist_user_command { USER_GET, USER_CREATE, USER_DELETE }; -struct klist_user_context { - enum klist_user_command cmd; -}; -typedef struct klist_user_context klist_user_context; - -klist_user_context *klist_user_context_init(void); -void klist_user_context_deinit(klist_user_context *ctx); - -enum klist_list_command { - LIST_ADD, - LIST_EDIT, - LIST_GET, - LIST_DELETE, -}; -struct klist_list_context { - enum klist_list_command cmd; - char *name; - char *desc; - char **stages; - size_t stages_len; - char *preset; -}; -typedef struct klist_list_context klist_list_context; - -klist_list_context *klist_list_context_init(void); -klist_list_context *klist_list_context_get_by_id(klist_list_context *ctx, - u_int id); -void klist_list_context_deinit(klist_list_context *ctx); - -enum klist_task_command { - TASK_ADD, - TASK_EDIT, - TASK_GET, - TASK_DELETE, -}; -struct klist_task_context { - enum klist_task_command cmd; - char *list; - char *name; - char *desc; - char *stage; -}; -typedef struct klist_task_context klist_task_context; - -klist_task_context *klist_task_context_init(klist *list); -void klist_task_context_deinit(klist_task_context *ctx); - /* * sql preparations */ @@ -103,4 +54,4 @@ void klist_assure_task(klist *, char *); * json printing will be implemented eventually */ -void klist_print(const klist *, KLIST_LOG_LEVEL, const char *format, ...); \ No newline at end of file +void klist_print(klist_logging_ctx *, KLIST_LOG_LEVEL, const char *, ...); \ No newline at end of file diff --git a/src/libklist/models.c b/src/libklist/models.c index edfab9a..bf810d7 100644 --- a/src/libklist/models.c +++ b/src/libklist/models.c @@ -42,8 +42,9 @@ klist_user *klist_user_get_by_local(const klist *ctx, u_int local_id) { if (sqlite3_step(stmt) == SQLITE_ROW) { user = klist_user_init_from_sql(stmt); } else - klist_print(ctx, KLIST_LOG_ERROR, "failed to get user by local id %u: %s\n", - local_id, sqlite3_errmsg(ctx->db)); + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, + "failed to get user by local id %u: %s\n", local_id, + sqlite3_errmsg(ctx->db)); sqlite3_reset(stmt); return user; @@ -59,7 +60,7 @@ void klist_user_save(const klist *ctx, klist_user *user) { if ((result = sqlite3_step(stmt)) == SQLITE_ROW) user->id = sqlite3_column_int(stmt, 0); else - klist_print(ctx, KLIST_LOG_ERROR, "failed to save user: %s - %d\n", + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "failed to save user: %s - %d\n", sqlite3_errmsg(ctx->db), result); sqlite3_reset(stmt); @@ -68,12 +69,12 @@ void klist_user_save(const klist *ctx, klist_user *user) { sqlite3_bind_int(stmt, 1, user->id); sqlite3_bind_int(stmt, 2, user->local_id); if (sqlite3_step(stmt) != SQLITE_ROW) - klist_print(ctx, KLIST_LOG_ERROR, + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "failed to save logins for user: %s - %d\n", sqlite3_errmsg(ctx->db), result); sqlite3_reset(stmt); } else - klist_print(ctx, KLIST_LOG_ERROR, "no local uid saved for user %s", + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "no local uid saved for user %s", (char *)user->name); } @@ -150,8 +151,19 @@ void klist_stage_save(const klist *ctx, klist_stage *stage) { stage->id = sqlite3_column_int(stmt, 0); sqlite3_reset(stmt); } else - klist_print(ctx, KLIST_LOG_ERROR, "failed to save stage: %s - %d\n", - sqlite3_errmsg(ctx->db), result); + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, + "failed to save stage: %s - %d\n", sqlite3_errmsg(ctx->db), + result); +} + +void klist_stage_delete(const klist *ctx, const klist_stage *stage) { + sqlite3_stmt *stmt = ctx->stmts[DEL_STAGE]; + sqlite3_bind_int(stmt, 1, stage->id); + if (sqlite3_step(stmt) == SQLITE_DONE) + sqlite3_reset(stmt); + else + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "failed to delete task: %s\n", + sqlite3_errmsg(ctx->db)); } void klist_stage_deinit(klist_stage *stage) { @@ -221,8 +233,8 @@ klist_list *klist_list_get_by_user_and_name(const klist *ctx, u_int user_id, if (sqlite3_step(stmt) == SQLITE_ROW) list = klist_list_init_from_sql(stmt); else - klist_print(ctx, KLIST_LOG_ERROR, "failed to get lists for user: %s\n", - sqlite3_errmsg(ctx->db)); + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, + "failed to get lists for user: %s\n", sqlite3_errmsg(ctx->db)); sqlite3_reset(stmt); return list; } @@ -239,23 +251,33 @@ void klist_list_save(const klist *ctx, klist_list *list, if ((result = sqlite3_step(stmt)) == SQLITE_ROW) list->id = sqlite3_column_int(stmt, 0); else - klist_print(ctx, KLIST_LOG_ERROR, "failed to save list: %s - %d\n", + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "failed to save list: %s - %d\n", sqlite3_errmsg(ctx->db), result); sqlite3_reset(stmt); if (list->id > -1) { stmt = ctx->stmts[ADD_USER_LIST]; - sqlite3_bind_int(stmt, 1, list->id); - sqlite3_bind_int(stmt, 2, user->id); + sqlite3_bind_int(stmt, 1, user->id); + sqlite3_bind_int(stmt, 2, list->id); if (sqlite3_step(stmt) == SQLITE_DONE) sqlite3_reset(stmt); else - klist_print(ctx, KLIST_LOG_ERROR, + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "failed to save user - list relation in join table: %s\n", sqlite3_errmsg(ctx->db)); } } +void klist_list_delete(const klist *ctx, klist_list *list) { + sqlite3_stmt *stmt = ctx->stmts[DEL_LIST]; + sqlite3_bind_int(stmt, 1, list->id); + if (sqlite3_step(stmt) == SQLITE_DONE) + sqlite3_reset(stmt); + else + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "failed to delete task: %s\n", + sqlite3_errmsg(ctx->db)); +} + void klist_list_deinit(klist_list *list) { if (list->name) free(list->name); @@ -325,7 +347,7 @@ klist_task *klist_task_get_for_list_by_name(const klist *ctx, u_int list_id, if (sqlite3_step(stmt) == SQLITE_ROW) task = klist_task_init_from_sql(stmt); else - klist_print(ctx, KLIST_LOG_WARNING, + klist_print(ctx->log_ctx, KLIST_LOG_WARNING, "no tasks found for list %d, name '%s': %s\n", list_id, name, sqlite3_errmsg(ctx->db)); sqlite3_reset(stmt); @@ -347,7 +369,7 @@ void klist_task_save(const klist *ctx, klist_task *task) { if ((result = sqlite3_step(stmt)) == SQLITE_ROW) { task->id = sqlite3_column_int(stmt, 0); } else - klist_print(ctx, KLIST_LOG_ERROR, "failed to save list: %s - %d\n", + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "failed to save list: %s - %d\n", sqlite3_errmsg(ctx->db), result); sqlite3_reset(stmt); } @@ -357,7 +379,7 @@ void klist_task_delete(const klist *ctx, const klist_task *task) { if (sqlite3_step(stmt) == SQLITE_DONE) sqlite3_reset(stmt); else - klist_print(ctx, KLIST_LOG_ERROR, "failed to delete task: %s\n", + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "failed to delete task: %s\n", sqlite3_errmsg(ctx->db)); } @@ -374,7 +396,7 @@ void klist_task_deinit(klist_task *task) { */ void klist_print_user(klist *ctx, const klist_user *user) { - printf("" + fprintf(ctx->log_ctx->log_target, "" "Name: %s\n" "has local account: %s\n", (char *)user->name, user->local_id > 0 ? "yes" : "no"); @@ -400,6 +422,7 @@ void klist_print_list(const klist *ctx, const klist_list *list, int i = 0; ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); u_int width = w.ws_col > 0 ? w.ws_col : 40; + for (i = 0; i < tasks_len; i++) fprintf(stderr, "%d, %s\n", i, (char*)tasks[i]->name); size_t stages_len = 0; klist_stage **stages = @@ -421,6 +444,7 @@ void klist_print_list(const klist *ctx, const klist_list *list, if (task_length > max_task_length) max_task_length = task_length; } + u_int content_width = (int)((double)max_task_length * 1.6 * (double)stages_len); if (content_width) @@ -428,10 +452,9 @@ void klist_print_list(const klist *ctx, const klist_list *list, size_t stage_col_width = (width - 3 - (stages_len - 1)) / stages_len; int tasks_max = 0; - for (i = 0; i < max_stages_id; i++) { + for (i = 0; i < max_stages_id + 1; i++) if (tasks_count_per_stage[i] > tasks_max) tasks_max = tasks_count_per_stage[i]; - } print_table_line("╭", stages_len, "─", stage_col_width, "─", "╮"); @@ -487,28 +510,27 @@ void klist_print_list(const klist *ctx, const klist_list *list, print_table_line("├", stages_len, "─", stage_col_width, "┼", "┤"); // tasks - int stages_idx[max_stages_id]; - for (i = 0; i < max_stages_id; i++) + int stages_idx[stages_len]; + for (i = 0; i < stages_len; i++) stages_idx[i] = 0; for (i = 0; i < tasks_max; i++) { printf("│"); int j = 0; for (; j < stages_len; j++) { - int k = stages_idx[stages[j]->id]; + int k = stages_idx[j]; u_long printed = 0; for (; k < tasks_len; k++) if (tasks[k]->stage_id == stages[j]->id) { - printf(" %s", (char *)tasks[k]->name); - printed = strlen((char *)tasks[k]->name) + 1; - stages_idx[stages[j]->id] = k + 1; + printed = printf(" %s", (char *)tasks[k]->name); + stages_idx[j] = k + 1; break; } int l = 0; for (; l < stage_col_width - printed; l++) printf(" "); - if (j + 1 != stages_len) { + if (j + 1 != stages_len) printf(" │"); - } + } printf("│\n"); } diff --git a/src/libklist/sql.c b/src/libklist/sql.c index 13238a4..2315149 100644 --- a/src/libklist/sql.c +++ b/src/libklist/sql.c @@ -17,7 +17,7 @@ const char *klist_sql_get(const enum KLIST_SQL sql) { " id integer primary key,\n" " user_id integer not null,\n" " local_id integer,\n" - " foreign key (user_id) references users(id),\n" + " foreign key (user_id) references users(id) on delete cascade,\n" " unique(user_id, local_id) on conflict ignore,\n" " unique(user_id)\n" ");\n" @@ -25,8 +25,8 @@ const char *klist_sql_get(const enum KLIST_SQL sql) { " id integer primary key,\n" " user_id integer not null,\n" " list_id integer not null,\n" - " foreign key (user_id) references users(id),\n" - " foreign key (list_id) references lists(id)\n" + " foreign key (user_id) references users(id) on delete cascade,\n" + " foreign key (list_id) references lists(id) on delete cascade\n" ");\n" "create table if not exists lists (\n" " id integer primary key,\n" diff --git a/src/libklist/util.c b/src/libklist/util.c index 98c1fcf..7660308 100644 --- a/src/libklist/util.c +++ b/src/libklist/util.c @@ -15,11 +15,8 @@ klist *klist_init(char *db) { klist *ctx = malloc(sizeof(klist)); ctx->stmts = malloc(_KLIST_SQL_COUNT * sizeof(sqlite3_stmt *)); - ctx->cmd_ctx = NULL; ctx->error = 0; - ctx->log_level = KLIST_LOG_WARNING; - ctx->log_target = stderr; - + ctx->log_ctx = malloc(sizeof(klist_logging_ctx)); klist_sql_prepare(ctx, db); return ctx; @@ -29,65 +26,12 @@ void klist_deinit(klist *ctx) { for (; i < _KLIST_SQL_COUNT; i++) sqlite3_finalize(ctx->stmts[i]); sqlite3_close(ctx->db); - // if (ctx->cmd_ctx) free(ctx->cmd_ctx); - free(ctx->stmts); - free(ctx); - ctx = NULL; -} - -klist_user_context *klist_user_context_init() { - klist_user_context *ctx = malloc(sizeof(klist_user_context)); - ctx->cmd = -1; - return ctx; -} -void klist_user_context_deinit(klist_user_context *ctx) { - free(ctx); - ctx = NULL; -} - -klist_list_context *klist_list_context_init() { - klist_list_context *ctx = malloc(sizeof(klist_list_context)); - ctx->cmd = -1; - ctx->name = NULL; - ctx->desc = NULL; - ctx->stages = NULL; - ctx->stages_len = 0; - ctx->preset = NULL; - return ctx; -} -void klist_list_context_deinit(klist_list_context *ctx) { - if (ctx->name) - free(ctx->name); - if (ctx->desc) - free(ctx->desc); - if (ctx->preset) - free(ctx->preset); - if (ctx->stages) { - int i = 0; - for (; i < ctx->stages_len; i++) - free(ctx->stages[i]); - free(ctx->stages); + if (ctx->log_ctx) { + if (ctx->log_ctx->log_target) + fclose(ctx->log_ctx->log_target); + free(ctx->log_ctx); } - free(ctx); - ctx = NULL; -} - -klist_task_context *klist_task_context_init(klist *list) { - klist_task_context *ctx = malloc(sizeof(klist_task_context)); - ctx->cmd = -1; - ctx->name = NULL; - ctx->desc = NULL; - ctx->list = NULL; - ctx->stage = NULL; - return ctx; -} -void klist_task_context_deinit(klist_task_context *ctx) { - if (ctx->name) - free(ctx->name); - if (ctx->list) - free(ctx->list); - if (ctx->stage) - free(ctx->stage); + free(ctx->stmts); free(ctx); ctx = NULL; } @@ -99,17 +43,17 @@ void klist_task_context_deinit(klist_task_context *ctx) { void klist_sql_prepare(klist *ctx, char *db) { if (!db) klist_print( - ctx, KLIST_LOG_WARNING, + ctx->log_ctx, KLIST_LOG_WARNING, "Database will be in-memory only, changes are not persistent!\n"); if (sqlite3_open(db ? db : ":memory:", &ctx->db) != SQLITE_OK) { - klist_print(ctx, KLIST_LOG_ERROR, "Can't open database: %s\n", + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "Can't open database: %s\n", sqlite3_errmsg(ctx->db)); return; } char *errmsg = NULL; sqlite3_exec(ctx->db, klist_sql_get(INIT), NULL, NULL, &errmsg); if (errmsg) { - klist_print(ctx, KLIST_LOG_ERROR, + klist_print(ctx->log_ctx, KLIST_LOG_ERROR, "Database initialization failed (%s), expect issues.\n", sqlite3_errmsg(ctx->db)); sqlite3_free(errmsg); @@ -118,7 +62,7 @@ void klist_sql_prepare(klist *ctx, char *db) { for (; i < _KLIST_SQL_COUNT; i++) if (sqlite3_prepare(ctx->db, klist_sql_get(i), -1, &ctx->stmts[i], NULL) != SQLITE_OK) - klist_print(ctx, KLIST_LOG_WARNING, + klist_print(ctx->log_ctx, KLIST_LOG_WARNING, "sqlite3_prepare for '%s' failed: %s\n", klist_sql_get(i), sqlite3_errmsg(ctx->db)); } @@ -148,7 +92,7 @@ bool klist_assure_user(const klist *ctx, const __uid_t id, const char *name) { * printing methods */ -void klist_print(const klist *ctx, KLIST_LOG_LEVEL log_level, +void klist_print(klist_logging_ctx *ctx, KLIST_LOG_LEVEL log_level, const char *format, ...) { if (ctx->log_level >= log_level) { switch (log_level) {