#include #include #include "sqlite3.h" #include "x_string.h" #include "x_curses.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 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){ int i; for(i=0; i max_rows){ max_rows = num_rows; } // Generate the sql statement by giving the columns, table, and current task list wanted if ( gen_sql_select_stmt(db, &out_stmt, colnames, table, status) ){ return -1; } // TODO: prob should be a func begin // while there is still rows available while ( rc = sqlite3_step(out_stmt) == SQLITE_ROW ){ // for each column print the column num_cols = sqlite3_column_count(out_stmt); for (i = 0; i < num_cols; i++){ col_val = sqlite3_column_text(out_stmt, i); print_fixed_width(col_val); } // move down one and over to the start of the current task column printf("\n"); // end X_goright(start_col); } // if while loop broke and rc returned an error if ( rc == SQLITE_ERROR ){ X_godown(max_rows); checksqlerr(rc, "step broken in display_task_list"); return -1; } // Once the task list is completely printed // reset to the top of the task lists if (num_rows > 0){ X_goup(num_rows); } // if it is the last task list move down one past the longest list if ( status == "blocked"){ X_godown(max_rows); } 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 > 1 ){ *title = argv[2]; } if ( argc > 2 ){ *due_date = argv[3]; } } // TODO: the way this ensures that we are only passing in // valid inputs is stupid and ugly FIX int add_task(sqlite3 *db, int argc, char** argv){ int rc = 0; char* table = "tasks"; char* title; char* due_date; 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_task"); return 1; } // Print kanban table // All lists with task name and due date int view(sqlite3 *db){ char* table = "tasks"; char* status = "today"; char* colnames = "title,due_date"; // Print Heading display_heading(); // Print "today" tasks if ( display_task_list(TODAY_COL_START, db, colnames, table, status) ){ return -1; } // Print "backlog" tasks status = "backlog"; if ( display_task_list(BACKLOG_COL_START, db, colnames, table, status) ){ return -1; } // Print "blocked" tasks status = "blocked"; if ( display_task_list(BLOCKED_COL_START, db, colnames, table, status) ){ return -1; } return 0; } 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 (argv[1][0] == 'b'){ rc = view(db); } else if ( argv[1][0] == 'a'){ rc = add_task(db,argc,argv); } else if ( argv[1][0] == 'v'){ rc = view_all(db); } } else{ rc = view(db); } sqlite3_close(db); return 0; }