#include #include #include #include "stmt.h" #include "irccolors.h" #include "error.h" #include "irc.h" #define DBFILE "test.sqlite" #define DBERR(line) do { \ const int e = line; \ if(e != SQLITE_OK && e != SQLITE_ROW && e != SQLITE_DONE) \ { \ fprintf(stderr, \ "sqlite (%d): %s\n", \ sqlite3_errcode(connection), sqlite3_errmsg(connection)); \ exit(DB_ERROR); \ } \ } while (0) #define DBUSERERR(line) do { \ const int e = line; \ if(e != SQLITE_OK && e != SQLITE_ROW && e != SQLITE_DONE) { \ r = sqlite3_errmsg(connection); \ } \ } while(0) static sqlite3 * connection = NULL; DECL int api_init(void) { DBERR(sqlite3_open(DBFILE, &connection)); DBERR(stmt_prepare(remind_stmt)); DBERR(stmt_prepare(set_repo_stmt)); DBERR(stmt_prepare(get_nth_id_stmt)); return 0; } DECL void api_rope(void) { DBERR(sqlite3_finalize(remind_stmt)); DBERR(sqlite3_finalize(set_repo_stmt)); DBERR(sqlite3_finalize(get_nth_id_stmt)); sqlite3_close(connection); } DECL void rope(void) { if (session) { irc_destroy_session(session); } api_rope(); } DECL char * remind(char * who) { char * r; char * title; char * desc; char * repo; DBERR(sqlite3_bind_text(remind_stmt, 1, who, -1, SQLITE_STATIC)); const int i = sqlite3_step(remind_stmt); DBERR(i); if (i == SQLITE_ROW) { title = (char *) sqlite3_column_text(remind_stmt, 0); title = strdup(title); desc = (char *) sqlite3_column_text(remind_stmt, 1); desc = strdup(desc); repo = (char *) sqlite3_column_text(remind_stmt, 3); repo = strdup(repo); asprintf(&r, IRC_COLOR_RED "%s: " IRC_COLOR_YELLOW "%s (@%s)", title, desc, repo); } else { r = strdup("No current assignment."); } return r; } DECL void set_repo(const char * const who, const char * const link) { DBERR(sqlite3_bind_text(set_repo_stmt, 1, link, -1, SQLITE_STATIC)); DBERR(sqlite3_bind_text(set_repo_stmt, 2, who, -1, SQLITE_STATIC)); DBERR(sqlite3_step(set_repo_stmt)); } DECL int rtos(void* data, int argc, char** argv, char** colname ){ (void) colname; char *const *const r = (char**)data; for(int i = 0; i < argc; i++){ strcat(*r, "|"); if(argv[i]){ strcat(*r, argv[i]); } else { strcat(*r, "NULL"); } } strcat(*r, "|\n"); return 0; } DECL char * dump(){ char* errmsg; char* r = (char*)calloc(sizeof(char), 10000); // TODO: allow for reallocing in rtos, start with a smaller value DBERR(sqlite3_exec(connection, dump_stmt, rtos, &r, &errmsg)); return r; } DECL char * raw(const char * const sql) { char* errmsg; char* r = (char*)calloc(sizeof(char), 10000); // TODO: allow for reallocing in rtos, start with a smaller value DBUSERERR(sqlite3_exec(connection, sql, rtos, &r, &errmsg)); if (errmsg){ free(r); r = errmsg; } else { strcat(r, "\00"); } return r; } DECL int get_project_count_callback(void* data, int argc, char** argv, char** colname) { (void)argc; (void)colname; int* count = (int*)data; *count = atoi(argv[0]); return 0; } DECL int get_project_count(){ int r = 0; const char* sql = "SELECT COUNT(*) FROM project;"; DBERR(sqlite3_exec(connection, sql, get_project_count_callback, &r, NULL)); return r; } DECL int get_nth_id(const int i){ int r; DBERR(sqlite3_bind_int(get_nth_id_stmt, 1, i)); DBERR(sqlite3_step(get_nth_id_stmt)); r = sqlite3_column_int(get_nth_id_stmt, 0); return r; } DECL void new_assignment(const char * const who, const int project){ DBERR(sqlite3_bind_text(new_assignment_stmt, 1, who, -1, SQLITE_STATIC)); DBERR(sqlite3_bind_int(new_assignment_stmt, 2, project)); DBERR(sqlite3_step(new_assignment_stmt)); } DECL void random_assign(const char * const who){ int i = rand() % get_project_count(); i = get_nth_id(i); new_assignment(who, i); }