diff options
| author | Emil | 2023-08-04 09:13:47 -0600 |
|---|---|---|
| committer | Emil | 2023-08-04 09:13:47 -0600 |
| commit | 935243d8b4ea992c50315f0c8fcb300365a5762d (patch) | |
| tree | c22d800773997b7b267d5d6cba5931f22ee2be64 /src/api.c | |
| download | emil-probotic-master.tar.xz emil-probotic-master.tar.zst | |
Diffstat (limited to 'src/api.c')
| -rw-r--r-- | src/api.c | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/src/api.c b/src/api.c new file mode 100644 index 0000000..09799a5 --- /dev/null +++ b/src/api.c @@ -0,0 +1,230 @@ +#define DBFILE "probotic_data.sqlite" + +#define stmt_prepare(stmt) \ + sqlite3_prepare_v2(connection, stmt ## _template, -1, &stmt, NULL) + +VARDECL char const * db = DBFILE; + +VARDECL sqlite3 * connection = NULL; + +DECL void DBERR(const int l){ + if(l != SQLITE_OK && l != SQLITE_ROW && l != SQLITE_DONE) + { + fprintf(stderr, + "sqlite (%d): %s\n", + sqlite3_errcode(connection), sqlite3_errmsg(connection)); + exit(DB_ERROR); + } +} + +DECL int +api_init(void) +{ + DBERR(sqlite3_open_v2(db, &connection, SQLITE_OPEN_READWRITE, NULL)); + // dont you fucking dare to remove this spacing + DBERR(stmt_prepare(remind_stmt)); + DBERR(stmt_prepare(set_repo_stmt)); + DBERR(stmt_prepare(get_nth_id_stmt)); + DBERR(stmt_prepare(new_assignment_stmt)); + DBERR(stmt_prepare(purge_assignments_stmt)); + DBERR(stmt_prepare(is_no_assignment_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)); + DBERR(sqlite3_finalize(new_assignment_stmt)); + DBERR(sqlite3_finalize(purge_assignments_stmt)); + DBERR(sqlite3_finalize(is_no_assignment_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_reset(remind_stmt)); + 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); + if (desc) { desc = strdup(desc); } else { desc = ""; } + repo = (char *) sqlite3_column_text(remind_stmt, 3); + if (repo) { repo = strdup(repo); } else { repo = "<no link available>"; } + asprintf(&r, + IRC_RED "%s: " IRC_YELLOW "%s" IRC_GREEN + " (@" IRC_BLUE "%s" IRC_GREEN ")" IRC_STOP, + title, desc, repo); + } + else + { + r = strdup(IRC_RED "No current assignment." IRC_STOP); + } + return r; +} + +DECL void +set_repo(char const * const who, + char const * const link) +{ + DBERR(sqlite3_reset(set_repo_stmt)); + 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 ** r = (char**)data; + + size_t data_len = 0; + for(int i = 0; i < argc; i++) + { + if(argv[i]) + { + data_len += strlen(argv[i]); + } + else + { + /* strlen("NULL") == 4 */ + data_len += 4; + } + /* strlen("|") * 2 == 2 */ + data_len += 2; + } + ++data_len; + + *r = (char *)calloc(data_len, sizeof(char)); + + 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 = NULL; + + DBERR(sqlite3_exec(connection, dump_stmt, rtos, &r, &errmsg)); + + return r; +} + +DECL char * +raw(char const * const sql) +{ + char* errmsg; + char *r = NULL; + + 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; + + char const * 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_reset(get_nth_id_stmt)); + 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(char const * const who, const int project) +{ + DBERR(sqlite3_reset(new_assignment_stmt)); + 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(char const * const who) +{ + int i = rand() % get_project_count(); + i = get_nth_id(i); + new_assignment(who, i); +} + +DECL void +purge_assignments(char const * const who) +{ + DBERR(sqlite3_reset(purge_assignments_stmt)); + DBERR(sqlite3_bind_text(purge_assignments_stmt, 1, who, -1, SQLITE_STATIC)); + DBERR(sqlite3_step(purge_assignments_stmt)); +} + +DECL int +is_no_assignment(char const * const who){ + DBERR(sqlite3_reset(is_no_assignment_stmt)); + DBERR(sqlite3_bind_text(is_no_assignment_stmt, 1, who, -1, SQLITE_STATIC)); + const int e = sqlite3_step(is_no_assignment_stmt); + DBERR(e); + return (e == SQLITE_DONE); +} |
