emacsql.c (4989B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include "sqlite3.h" 5 6 #define TRUE 1 7 #define FALSE 0 8 9 char* escape(const char *message) { 10 int i, count = 0, length_orig = strlen(message); 11 for (i = 0; i < length_orig; i++) { 12 if (strchr("\"\\", message[i])) { 13 count++; 14 } 15 } 16 char *copy = malloc(length_orig + count + 1); 17 char *p = copy; 18 while (*message) { 19 if (strchr("\"\\", *message)) { 20 *p = '\\'; 21 p++; 22 } 23 *p = *message; 24 message++; 25 p++; 26 } 27 *p = '\0'; 28 return copy; 29 } 30 31 void send_error(int code, const char *message) { 32 char *escaped = escape(message); 33 printf("error %d \"%s\"\n", code, escaped); 34 free(escaped); 35 } 36 37 typedef struct { 38 char *buffer; 39 size_t size; 40 } buffer; 41 42 buffer* buffer_create() { 43 buffer *buffer = malloc(sizeof(buffer)); 44 buffer->size = 4096; 45 buffer->buffer = malloc(buffer->size * sizeof(char)); 46 return buffer; 47 } 48 49 int buffer_grow(buffer *buffer) { 50 unsigned factor = 2; 51 char *newbuffer = realloc(buffer->buffer, buffer->size * factor); 52 if (newbuffer == NULL) { 53 return FALSE; 54 } 55 buffer->buffer = newbuffer; 56 buffer->size *= factor; 57 return TRUE; 58 } 59 60 int buffer_read(buffer *buffer, size_t count) { 61 while (buffer->size < count + 1) { 62 if (buffer_grow(buffer) == FALSE) { 63 return FALSE; 64 } 65 } 66 size_t in = fread((void *) buffer->buffer, 1, count, stdin); 67 buffer->buffer[count] = '\0'; 68 return in == count; 69 } 70 71 void buffer_free(buffer *buffer) { 72 free(buffer->buffer); 73 free(buffer); 74 } 75 76 int main(int argc, char **argv) { 77 char *file = NULL; 78 if (argc != 2) { 79 fprintf(stderr, 80 "error: require exactly one argument, the DB filename\n"); 81 exit(EXIT_FAILURE); 82 } else { 83 file = argv[1]; 84 } 85 86 /* On Windows stderr is not always unbuffered. */ 87 #if defined(_WIN32) || defined(WIN32) || defined(__MINGW32__) 88 setvbuf(stderr, NULL, _IONBF, 0); 89 #endif 90 91 sqlite3* db = NULL; 92 if (sqlite3_initialize() != SQLITE_OK) { 93 fprintf(stderr, "error: failed to initialize sqlite\n"); 94 exit(EXIT_FAILURE); 95 } 96 int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; 97 if (sqlite3_open_v2(file, &db, flags, NULL) != SQLITE_OK) { 98 fprintf(stderr, "error: failed to open %s\n", file); 99 exit(EXIT_FAILURE); 100 } 101 102 buffer *input = buffer_create(); 103 while (TRUE) { 104 printf("#\n"); 105 fflush(stdout); 106 107 /* Gather input from Emacs. */ 108 unsigned length; 109 int result = scanf("%u ", &length); 110 if (result == EOF) { 111 break; 112 } else if (result != 1) { 113 send_error(SQLITE_ERROR, "middleware parsing error"); 114 break; /* stream out of sync: quit program */ 115 } 116 if (!buffer_read(input, length)) { 117 send_error(SQLITE_NOMEM, "middleware out of memory"); 118 continue; 119 } 120 121 /* Parse SQL statement. */ 122 sqlite3_stmt *stmt = NULL; 123 result = sqlite3_prepare_v2(db, input->buffer, length, &stmt, NULL); 124 if (result != SQLITE_OK) { 125 send_error(sqlite3_errcode(db), sqlite3_errmsg(db)); 126 continue; 127 } 128 129 /* Print out rows. */ 130 int first = TRUE, ncolumns = sqlite3_column_count(stmt); 131 printf("("); 132 while (sqlite3_step(stmt) == SQLITE_ROW) { 133 if (first) { 134 printf("("); 135 first = FALSE; 136 } else { 137 printf("\n ("); 138 } 139 int i; 140 for (i = 0; i < ncolumns; i++) { 141 if (i > 0) { 142 printf(" "); 143 } 144 int type = sqlite3_column_type(stmt, i); 145 switch (type) { 146 case SQLITE_INTEGER: 147 printf("%lld", sqlite3_column_int64(stmt, i)); 148 break; 149 case SQLITE_FLOAT: 150 printf("%f", sqlite3_column_double(stmt, i)); 151 break; 152 case SQLITE_NULL: 153 printf("nil"); 154 break; 155 case SQLITE_TEXT: 156 fwrite(sqlite3_column_text(stmt, i), 1, 157 sqlite3_column_bytes(stmt, i), stdout); 158 break; 159 case SQLITE_BLOB: 160 printf("nil"); 161 break; 162 } 163 } 164 printf(")"); 165 } 166 printf(")\n"); 167 if (sqlite3_finalize(stmt) != SQLITE_OK) { 168 /* Despite any error code, the statement is still freed. 169 * http://stackoverflow.com/a/8391872 170 */ 171 send_error(sqlite3_errcode(db), sqlite3_errmsg(db)); 172 } else { 173 printf("success\n"); 174 } 175 } 176 buffer_free(input); 177 178 sqlite3_close(db); 179 sqlite3_shutdown(); 180 return EXIT_SUCCESS; 181 }