From 443c9f04cd6e7ac442f8b04e6e9732677c4b957b Mon Sep 17 00:00:00 2001 From: xavi Date: Mon, 9 Sep 2024 21:59:24 -0700 Subject: [PATCH] Added a main.c and moved calls to functs to main() --- src/dodo.c | 337 ++++++++++++++++++++++------------------------------- src/dodo.h | 55 +++++++++ src/main.c | 50 ++++++++ 3 files changed, 243 insertions(+), 199 deletions(-) create mode 100644 src/dodo.h create mode 100644 src/main.c diff --git a/src/dodo.c b/src/dodo.c index e030097..512dc2c 100644 --- a/src/dodo.c +++ b/src/dodo.c @@ -3,53 +3,8 @@ #include "sqlite3.h" #include "x_string.h" #include "x_curses.h" +#include "dodo.h" -#define SQLQUERY_MAX 100 -#define ARG_MAX 100 -#define TODAY_COL_START -1 -#define BACKLOG_COL_START 33 -#define BLOCKED_COL_START 66 -#define FIXED_WIDTH 19 - -typedef struct{ - int year; - int month; - int day; -}date; - -typedef struct { - int task_id; - char* title; - int active_id; - char* status; - date creation_date; - date due_date; -}task_entry; - -int checksqlerr(int rc, char *errmsg){ - if( rc!=SQLITE_OK ){ - fprintf(stderr, "rc = %d\n", rc); - fprintf(stderr, "SQL error: %s\n", errmsg); - sqlite3_free(errmsg); - return -1; - } - return 0; -} - - -int opendb(sqlite3 **db, char* filename){ - int rc = 0; - - rc = sqlite3_open(filename, db); - - if ( rc != 0 ){ - fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(*db)); - sqlite3_close(*db); - return(rc); - } - - return(rc); -} // FOR DEBUG int callback(void *NotUsed, int argc, char **argv, char **azColName){ @@ -73,20 +28,8 @@ int view_all(sqlite3 *db){ return rc; } -// Print Heading TODO: obvi make this better -void display_heading(){ - printf("\n"); - printf("%s Today %s", X_BOLD, X_RST); - printf(" %s Backlog %s", X_BOLD, X_RST); - printf(" %s Blocked %s", X_BOLD, X_RST); - printf("\n"); - - printf("%s%stitle due date %s", X_BOLD, X_UNDL, X_RST); - printf(" %s%stitle due date %s", X_BOLD, X_UNDL, X_RST); - printf(" %s%stitle due date %s", X_BOLD, X_UNDL, X_RST); - printf("\n"); -} +// sql generators TODO: might be able to boil this down to 1 func int gen_sql_update_stmt(sqlite3 *db, sqlite3_stmt** out_stmt, char* table, char* status, char* title){ char sql_query[SQLQUERY_MAX]; int rc = 0; @@ -149,6 +92,58 @@ int gen_sql_select_stmt(sqlite3 *db, sqlite3_stmt** out_stmt, char* colnames, ch return 0; } +int checksqlerr(int rc, char *errmsg){ + if( rc!=SQLITE_OK ){ + fprintf(stderr, "rc = %d\n", rc); + fprintf(stderr, "SQL error: %s\n", errmsg); + sqlite3_free(errmsg); + return -1; + } + return 0; +} + +int opendb(sqlite3 **db, char* filename){ + int rc = 0; + + rc = sqlite3_open(filename, db); + + if ( rc != 0 ){ + fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(*db)); + sqlite3_close(*db); + return(rc); + } + + return(rc); +} + +// Print Heading TODO: obvi make this better +void display_heading(){ + printf("\n"); + printf("%s Today %s", X_BOLD, X_RST); + printf(" %s Backlog %s", X_BOLD, X_RST); + printf(" %s Blocked %s", X_BOLD, X_RST); + printf("\n"); + + printf("%s%stitle due date %s", X_BOLD, X_UNDL, X_RST); + printf(" %s%stitle due date %s", X_BOLD, X_UNDL, X_RST); + printf(" %s%stitle due date %s", X_BOLD, X_UNDL, X_RST); + printf("\n"); +} + +// pass in the args and return the title and due date +// due date passed as NULL if for delete +// TODO input validation for strings implement in strings! +int parse_args(int argc, char** argv, char** title, char** due_date){ + if ( argc > 2 ){ + *title = argv[2]; + } + + if ( argc > 3 ){ + *due_date = argv[3]; + } + +} + // Get number of tasks from tasks table give status int get_num_rows(sqlite3 *db, char* table, char* status){ sqlite3_stmt *out_stmt; @@ -236,110 +231,6 @@ int display_task_list(int start_col, sqlite3 *db, char* colnames, char* table, c return 0; } -// pass in the args and return the title and due date -// due date passed as NULL if for delete -// TODO input validation for strings implement in strings! -int parse_args(int argc, char** argv, char** title, char** due_date){ - if ( argc > 2 ){ - *title = argv[2]; - } - - if ( argc > 3 ){ - *due_date = argv[3]; - } - -} - -int complete_task(sqlite3 *db, int argc, char** argv){ - int rc = 0; - char* table = "tasks"; - char* title; - sqlite3_stmt* out_stmt; - - parse_args(argc, argv, &title, NULL); - if ( gen_sql_update_stmt(db, &out_stmt, table, NULL, title) ){ - return -1; - } - - if ( ( rc = sqlite3_step(out_stmt) ) == SQLITE_DONE){ - return 0; - } - - checksqlerr(rc, "broken in complete_task"); - return 1; -} - -int update_task_status(sqlite3 *db, int argc, char** argv){ - int rc = 0; - char* table = "tasks"; - char* title; - sqlite3_stmt* out_stmt; - parse_args(argc, argv, &title, NULL); - - if ( gen_sql_update_stmt(db, &out_stmt, table, argv[1], title) ){ - return -1; - } - - if ( ( rc = sqlite3_step(out_stmt) ) == SQLITE_DONE){ - return 0; - } - - checksqlerr(rc, "broken in update_task_status"); - return 1; - -} - -int del_task(sqlite3 *db, int argc, char** argv){ - int rc = 0; - char* table = "tasks"; - char* title; - sqlite3_stmt* out_stmt; - - parse_args(argc, argv, &title, NULL); - if ( gen_sql_delete_stmt(db, &out_stmt, table, title) ){ - return -1; - } - - if ( ( rc = sqlite3_step(out_stmt) ) == SQLITE_DONE){ - return 0; - } - - checksqlerr(rc, "broken in del_task"); - return 1; -} - - -// TODO: the way this ensures that we are only passing in -// valid inputs is stupid and ugly FIX -int add_new_task(sqlite3 *db, int argc, char** argv){ - int rc = 0; - char* table = "tasks"; - char* title = NULL; - char* due_date = NULL; - char* colnames = "(title, due_date)"; - char values[100]; - sqlite3_stmt* out_stmt; - - parse_args(argc, argv, &title, &due_date); - - if ( due_date != NULL ){ - snprintf(values, 100, "('%s', '%s')", title, due_date); - }else{ - colnames = "(title)"; - snprintf(values, 100, "('%s')", title); - } - - if ( gen_sql_insert_stmt(db, &out_stmt, table, colnames, values) ){ - return -1; - } - if ( ( rc = sqlite3_step(out_stmt) ) == SQLITE_DONE){ - return 0; - } - - checksqlerr(rc, "broken in add_new_task"); - return 1; -} - // Print kanban table // All lists with task name and due date int view_tasks(sqlite3 *db){ @@ -370,45 +261,93 @@ int view_tasks(sqlite3 *db){ return 0; } -int main( int argc, char **argv ){ - sqlite3 *db; +// TODO: the way this ensures that we are only passing in +// valid inputs is stupid and ugly FIX +int add_new_task(sqlite3 *db, int argc, char** argv){ int rc = 0; - char* home_dir = getenv("HOME"); - char* filename = x_strconcat(home_dir, DB_PATH); + char* table = "tasks"; + char* title = NULL; + char* due_date = NULL; + char* colnames = "(title, due_date)"; + char values[100]; + sqlite3_stmt* out_stmt; - rc = opendb(&db, filename); - if ( argv[1] ){ - if (x_strcmp(argv[1], "view") == 0){ - rc = view_tasks(db); - } - else if (x_strcmp(argv[1], "new") == 0){ - rc = add_new_task(db,argc,argv); - } - else if (x_strcmp(argv[1], "del") == 0){ - rc = del_task(db,argc,argv); - } - else if (x_strcmp(argv[1], "today") == 0){ - rc = update_task_status(db,argc,argv); - } - else if (x_strcmp(argv[1], "blocked") == 0){ - rc = update_task_status(db,argc,argv); - } - else if (x_strcmp(argv[1], "backlog") == 0){ - rc = update_task_status(db,argc,argv); - } - else if (x_strcmp(argv[1], "done") == 0){ - rc = complete_task(db,argc,argv); - } - else if (x_strcmp(argv[1], "view_all") == 0){ - rc = view_all(db); - } - } - else{ - rc = view_tasks(db); + parse_args(argc, argv, &title, &due_date); + + if ( due_date != NULL ){ + snprintf(values, 100, "('%s', '%s')", title, due_date); + }else{ + colnames = "(title)"; + snprintf(values, 100, "('%s')", title); } - sqlite3_close(db); + if ( gen_sql_insert_stmt(db, &out_stmt, table, colnames, values) ){ + return -1; + } + if ( ( rc = sqlite3_step(out_stmt) ) == SQLITE_DONE){ + return 0; + } - - return 0; + checksqlerr(rc, "broken in add_new_task"); + return -1; +} + + +int update_task_status(sqlite3 *db, int argc, char** argv){ + int rc = 0; + char* table = "tasks"; + char* title; + sqlite3_stmt* out_stmt; + parse_args(argc, argv, &title, NULL); + + if ( gen_sql_update_stmt(db, &out_stmt, table, argv[1], title) ){ + return -1; + } + + if ( ( rc = sqlite3_step(out_stmt) ) == SQLITE_DONE){ + return 0; + } + + checksqlerr(rc, "broken in update_task_status"); + return -1; + +} + + +int complete_task(sqlite3 *db, int argc, char** argv){ + int rc = 0; + char* table = "tasks"; + char* title; + sqlite3_stmt* out_stmt; + + parse_args(argc, argv, &title, NULL); + if ( gen_sql_update_stmt(db, &out_stmt, table, NULL, title) ){ + return -1; + } + + if ( ( rc = sqlite3_step(out_stmt) ) == SQLITE_DONE){ + return 0; + } + + checksqlerr(rc, "broken in complete_task"); + return -1; +} + +int del_task(sqlite3 *db, int argc, char** argv){ + int rc = 0; + char* table = "tasks"; + char* title; + sqlite3_stmt* out_stmt; + + parse_args(argc, argv, &title, NULL); + if ( gen_sql_delete_stmt(db, &out_stmt, table, title) ){ + return -1; + } + + if ( ( rc = sqlite3_step(out_stmt) ) == SQLITE_DONE){ + return 0; + } + + checksqlerr(rc, "broken in del_task"); + return -1; } diff --git a/src/dodo.h b/src/dodo.h new file mode 100644 index 0000000..3123d50 --- /dev/null +++ b/src/dodo.h @@ -0,0 +1,55 @@ +#ifndef DODO_H +#define DODO_H + +#define SQLQUERY_MAX 100 +#define ARG_MAX 100 +#define TODAY_COL_START -1 +#define BACKLOG_COL_START 33 +#define BLOCKED_COL_START 66 +#define FIXED_WIDTH 19 + +typedef struct{ + int year; + int month; + int day; +}date; + +typedef struct { + int task_id; + char* title; + int active_id; + char* status; + date creation_date; + date due_date; +}task_entry; + +// FOR DEBUG +int callback(void *NotUsed, int argc, char **argv, char **azColName); +int view_all(sqlite3 *db); + +// sql generators TODO: might be able to boil this down to 1 func +int gen_sql_update_stmt(sqlite3 *db, sqlite3_stmt** out_stmt, char* table, char* status, char* title); +int gen_sql_delete_stmt(sqlite3 *db, sqlite3_stmt** out_stmt, char* table, char* title); +int gen_sql_insert_stmt(sqlite3 *db, sqlite3_stmt** out_stmt, char* table, char* colnames, char* values); +int gen_sql_select_stmt(sqlite3 *db, sqlite3_stmt** out_stmt, char* colnames, char* table, char* status); + +// helpers +int checksqlerr(int rc, char *errmsg); +int opendb(sqlite3 **db, char* filename); +void display_heading(); +int parse_args(int argc, char** argv, char** title, char** due_date); +int get_num_rows(sqlite3 *db, char* table, char* status); +int print_fixed_width(const unsigned char* str); +int display_task_list(int start_col, sqlite3 *db, char* colnames, char* table, char* status); + +// main functions +int view_tasks(sqlite3 *db); +int add_new_task(sqlite3 *db, int argc, char** argv); +int update_task_status(sqlite3 *db, int argc, char** argv); +int complete_task(sqlite3 *db, int argc, char** argv); +int modify_task(sqlite3 *db, int argc, char** argv); + + +int del_task(sqlite3 *db, int argc, char** argv); + +#endif diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..586cc9f --- /dev/null +++ b/src/main.c @@ -0,0 +1,50 @@ +#include +#include +#include "sqlite3.h" +#include "x_string.h" +#include "x_curses.h" +#include "dodo.h" + +int main( int argc, char **argv ){ + sqlite3 *db; + int rc = 0; + char* home_dir = getenv("HOME"); + char* filename = x_strconcat(home_dir, DB_PATH); + + rc = opendb(&db, filename); + if ( argv[1] ){ + if (x_strcmp(argv[1], "view") == 0){ + rc = view_tasks(db); + } + else if (x_strcmp(argv[1], "new") == 0){ + rc = add_new_task(db,argc,argv); + } + else if (x_strcmp(argv[1], "del") == 0){ + rc = del_task(db,argc,argv); + } + else if (x_strcmp(argv[1], "today") == 0){ + rc = update_task_status(db,argc,argv); + } + else if (x_strcmp(argv[1], "blocked") == 0){ + rc = update_task_status(db,argc,argv); + } + else if (x_strcmp(argv[1], "backlog") == 0){ + rc = update_task_status(db,argc,argv); + } + else if (x_strcmp(argv[1], "done") == 0){ + rc = complete_task(db,argc,argv); + } + else if (x_strcmp(argv[1], "view_all") == 0){ + rc = view_all(db); + } + } + else{ + rc = view_tasks(db); + } + + sqlite3_close(db); + + + return 0; +} +