book.c (1768B)
1 #include<sqlite3.h> 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include"bibleverse.h" 6 7 #define BOOK_NAME_LEN 202 8 9 static char* book_sql = "SELECT id, name FROM books WHERE name LIKE ?1"; 10 11 struct book* find_book(char* book_name, sqlite3* db) { 12 13 sqlite3_stmt* res; 14 int rc = sqlite3_prepare_v2(db, book_sql, -1, &res, 0); 15 16 if(rc == SQLITE_OK) { 17 char wildcarded_book[BOOK_NAME_LEN] = {0}; 18 19 snprintf(wildcarded_book, sizeof(wildcarded_book), "%%%s%%", book_name); 20 21 rc = sqlite3_bind_text(res, 1, wildcarded_book, -1, SQLITE_STATIC); 22 23 if(rc != SQLITE_OK) { 24 fprintf(stderr, "Cannot bind argument: %s\n", sqlite3_errmsg(db)); 25 26 return NULL; 27 } 28 } else { 29 fprintf(stderr, "Failed to prepare statement: %s\n", sqlite3_errmsg(db)); 30 31 return NULL; 32 } 33 34 int i = 0; 35 struct book* books; 36 37 while(sqlite3_step(res) == SQLITE_ROW) { 38 if(!i) { 39 books = malloc(sizeof(struct book)); 40 } else { 41 books = realloc(books, sizeof(struct book) * (i + 1)); 42 } 43 44 int id = sqlite3_column_int(res, 0); 45 char* name = (char*) sqlite3_column_text(res, 1); 46 47 books[i].id = id; 48 books[i].name = (char*) malloc((strlen(name) + 1) * sizeof(char*)); 49 strcpy(books[i].name, name); 50 51 ++i; 52 53 if(!strcmp(name, book_name)) { 54 break; //I'm sinning here and assuming first result will be the one that matches in full 55 } 56 } 57 58 if(i != 1) { 59 if(i == 0) { 60 fprintf(stderr, "No books found under the name \"%s\"\n", book_name); 61 } 62 else if(i > 1) { 63 fprintf(stderr, "There are multiple books matching the query \"%s\". Please narrow down your search:\n", book_name); 64 65 for(int h = 0; h < i; h++) { 66 fprintf(stderr, "%s\n", books[h].name); 67 free(books[h].name); 68 } 69 70 free(books); 71 } 72 73 return NULL; 74 } 75 76 sqlite3_finalize(res); 77 78 return books; 79 } 80