Probiotics (in bot form) for programming.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

240 line
5.3KB

  1. /* api.c - Database API */
  2. #define stmt_prepare(stmt) \
  3. sqlite3_prepare_v2(connection, stmt ## _template, -1, &stmt, NULL)
  4. VARDECL char const * db = DBFILE;
  5. VARDECL sqlite3 * connection = NULL;
  6. DECL void DBERR(const int l)
  7. {
  8. if(l != SQLITE_OK && l != SQLITE_ROW && l != SQLITE_DONE)
  9. {
  10. fprintf(stderr,
  11. "sqlite (%d): %s\n",
  12. sqlite3_errcode(connection), sqlite3_errmsg(connection));
  13. exit(DB_ERROR);
  14. }
  15. }
  16. DECL int
  17. api_init(void)
  18. {
  19. DBERR(sqlite3_open_v2(db, &connection, SQLITE_OPEN_READWRITE, NULL));
  20. /* dont you fucking dare to remove this spacing */
  21. DBERR(stmt_prepare(remind_stmt));
  22. DBERR(stmt_prepare(set_repo_stmt));
  23. DBERR(stmt_prepare(get_nth_id_stmt));
  24. DBERR(stmt_prepare(new_assignment_stmt));
  25. DBERR(stmt_prepare(purge_assignments_stmt));
  26. DBERR(stmt_prepare(is_no_assignment_stmt));
  27. return 0;
  28. }
  29. DECL void
  30. api_rope(void)
  31. {
  32. DBERR(sqlite3_finalize(remind_stmt));
  33. DBERR(sqlite3_finalize(set_repo_stmt));
  34. DBERR(sqlite3_finalize(get_nth_id_stmt));
  35. DBERR(sqlite3_finalize(new_assignment_stmt));
  36. DBERR(sqlite3_finalize(purge_assignments_stmt));
  37. DBERR(sqlite3_finalize(is_no_assignment_stmt));
  38. sqlite3_close(connection);
  39. }
  40. DECL char *
  41. remind(char * who)
  42. {
  43. char * r;
  44. char * title;
  45. char * desc;
  46. /* char * repo; */
  47. DBERR(sqlite3_reset(remind_stmt));
  48. DBERR(sqlite3_bind_text(remind_stmt, 1, who, -1, SQLITE_STATIC));
  49. const int i = sqlite3_step(remind_stmt);
  50. DBERR(i);
  51. if (i == SQLITE_ROW)
  52. {
  53. title = (char *) sqlite3_column_text(remind_stmt, 0);
  54. title = strdup(title);
  55. desc = (char *) sqlite3_column_text(remind_stmt, 1);
  56. if (desc) { desc = strdup(desc); } else { desc = ""; }
  57. /* repo = (char *) sqlite3_column_text(remind_stmt, 3); */
  58. /* if (repo) { repo = strdup(repo); } else { repo = "<no link available>"; } */
  59. /* if (-1 == asprintf(&r, */
  60. /* IRC_RED "%s: " IRC_YELLOW "%s" IRC_GREEN */
  61. /* " (@" IRC_BLUE "%s" IRC_GREEN ")" IRC_STOP, */
  62. /* title, desc, repo)) */
  63. if (-1 == asprintf(&r,
  64. IRC_RED "%s: " IRC_YELLOW "%s" IRC_GREEN,
  65. title, desc))
  66. { /* this will probably never happen. But it implies a memory failure */
  67. r = strdup(IRC_RED "No memory!" IRC_STOP);
  68. }
  69. else
  70. {
  71. r = strdup(IRC_RED "No current assignment." IRC_STOP);
  72. }
  73. }
  74. return r;
  75. }
  76. DECL void
  77. set_repo(char const * const who,
  78. char const * const link)
  79. {
  80. DBERR(sqlite3_reset(set_repo_stmt));
  81. DBERR(sqlite3_bind_text(set_repo_stmt, 1, link, -1, SQLITE_STATIC));
  82. DBERR(sqlite3_bind_text(set_repo_stmt, 2, who, -1, SQLITE_STATIC));
  83. DBERR(sqlite3_step(set_repo_stmt));
  84. }
  85. #ifndef NO_VULN_COMMANDS
  86. /* Note that this function is may not be vuln,
  87. but is included as it's only used by vulns */
  88. DECL int
  89. rtos(void * data,
  90. int argc,
  91. char** argv,
  92. char** colname)
  93. {
  94. (void) colname;
  95. char ** r = (char**)data;
  96. size_t data_len = 0;
  97. for(int i = 0; i < argc; i++)
  98. {
  99. if(argv[i])
  100. {
  101. data_len += strlen(argv[i]);
  102. }
  103. else
  104. {
  105. /* strlen("NULL") == 4 */
  106. data_len += 4;
  107. }
  108. /* strlen("|") * 2 == 2 */
  109. data_len += 2;
  110. }
  111. ++data_len;
  112. *r = (char *)calloc(data_len, sizeof(char));
  113. for(int i = 0; i < argc; i++){
  114. strcat(*r, "|");
  115. if(argv[i]){
  116. strcat(*r, argv[i]);
  117. }
  118. else
  119. {
  120. strcat(*r, "NULL");
  121. }
  122. }
  123. strcat(*r, "|\n");
  124. return 0;
  125. }
  126. DECL char *
  127. dump()
  128. {
  129. char* errmsg;
  130. char* r = NULL;
  131. DBERR(sqlite3_exec(connection, dump_stmt, rtos, &r, &errmsg));
  132. return r;
  133. }
  134. DECL char *
  135. raw(char const * const sql)
  136. {
  137. char* errmsg;
  138. char *r = NULL;
  139. sqlite3_exec(connection, sql, rtos, &r, &errmsg);
  140. if (errmsg){
  141. free(r);
  142. r = errmsg;
  143. } else { strcat(r, "\00"); }
  144. return r;
  145. }
  146. #endif /* !NO_VULN_COMMANDS */
  147. DECL int
  148. get_project_count_callback(void* data, int argc, char** argv, char** colname)
  149. {
  150. (void)argc;
  151. (void)colname;
  152. int* count = (int*)data;
  153. *count = atoi(argv[0]);
  154. return 0;
  155. }
  156. DECL int
  157. get_project_count(void)
  158. {
  159. int r = 0;
  160. char const * sql = "SELECT COUNT(*) FROM project;";
  161. DBERR(sqlite3_exec(connection, sql, get_project_count_callback, &r, NULL));
  162. return r;
  163. }
  164. DECL int
  165. get_nth_id(const int i)
  166. {
  167. int r;
  168. DBERR(sqlite3_reset(get_nth_id_stmt));
  169. DBERR(sqlite3_bind_int(get_nth_id_stmt, 1, i));
  170. DBERR(sqlite3_step(get_nth_id_stmt));
  171. r = sqlite3_column_int(get_nth_id_stmt, 0);
  172. return r;
  173. }
  174. DECL void
  175. new_assignment(char const * const who,
  176. int const project)
  177. {
  178. DBERR(sqlite3_reset(new_assignment_stmt));
  179. DBERR(sqlite3_bind_text(new_assignment_stmt, 1, who, -1, SQLITE_STATIC));
  180. DBERR(sqlite3_bind_int(new_assignment_stmt, 2, project));
  181. DBERR(sqlite3_step(new_assignment_stmt));
  182. }
  183. DECL void
  184. random_assign(char const * const who)
  185. {
  186. int i = rand() % get_project_count();
  187. i = get_nth_id(i);
  188. new_assignment(who, i);
  189. }
  190. DECL void
  191. purge_assignments(char const * const who)
  192. {
  193. DBERR(sqlite3_reset(purge_assignments_stmt));
  194. DBERR(sqlite3_bind_text(purge_assignments_stmt, 1, who, -1, SQLITE_STATIC));
  195. DBERR(sqlite3_step(purge_assignments_stmt));
  196. }
  197. #ifdef INITIAL_ASSIGNMENT_MESSAGE
  198. DECL int
  199. is_no_assignment(char const * const who)
  200. {
  201. const int e;
  202. DBERR(sqlite3_reset(is_no_assignment_stmt));
  203. DBERR(sqlite3_bind_text(is_no_assignment_stmt, 1, who, -1, SQLITE_STATIC));
  204. e = sqlite3_step(is_no_assignment_stmt);
  205. DBERR(e);
  206. return (e == SQLITE_DONE);
  207. }
  208. #endif /* INITIAL_ASSIGNMENT_MESSAGE */