2021-03-08 16:59:27 -05:00
|
|
|
/* <https://gist.github.com/enile8/2424514> */
|
2021-03-08 23:16:14 -05:00
|
|
|
#define _POSIX_C_SOURCE 200809L /* strtok_r, strndup */
|
|
|
|
#include <string.h>
|
2021-03-08 16:59:27 -05:00
|
|
|
#include <assert.h> /* assert */
|
|
|
|
#include <sqlite3.h>
|
|
|
|
#include <stdio.h> /* size_t */
|
2021-03-11 17:23:43 -05:00
|
|
|
#include <stdlib.h> /* free */
|
2021-03-08 23:16:14 -05:00
|
|
|
#include "io.h"
|
2021-03-11 20:48:32 -05:00
|
|
|
#include "strings.h"
|
|
|
|
#include "unused.h"
|
2021-03-08 16:59:27 -05:00
|
|
|
|
2021-03-11 20:48:32 -05:00
|
|
|
struct params {
|
|
|
|
int type;
|
|
|
|
void *arg;
|
|
|
|
};
|
2021-03-11 12:48:15 -05:00
|
|
|
|
2021-03-11 17:23:43 -05:00
|
|
|
static int print_col(sqlite3_stmt * pTableInfo, int col) {
|
2021-03-11 12:48:15 -05:00
|
|
|
int n, rc;
|
|
|
|
static int ct = 0;
|
|
|
|
char outfile[50];
|
|
|
|
size_t size;
|
|
|
|
printf("%s: ", sqlite3_column_name(pTableInfo, col));
|
|
|
|
switch (sqlite3_column_type(pTableInfo, col)) {
|
|
|
|
case SQLITE_INTEGER:
|
|
|
|
printf("%d ", sqlite3_column_int(pTableInfo, col));
|
|
|
|
break;
|
|
|
|
case SQLITE_FLOAT:
|
|
|
|
printf("%f ", sqlite3_column_double(pTableInfo, col));
|
|
|
|
break;
|
|
|
|
case SQLITE_TEXT:
|
|
|
|
printf("%s ", sqlite3_column_text(pTableInfo, col));
|
|
|
|
break;
|
|
|
|
case SQLITE_BLOB: //printf("%s",sqlite3_column_blob(pTableInfo, col));
|
|
|
|
/* fprintf(stderr, "IN BLOB bytes %d\n",
|
|
|
|
sqlite3_column_bytes(pTableInfo, col)); */
|
|
|
|
snprintf(outfile, 20, "outdata.%d.png", ct++);
|
|
|
|
n = sqlite3_column_bytes(pTableInfo, col);
|
|
|
|
if (n > 0)
|
|
|
|
size = (size_t)n;
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
if ((rc = (int)file_write(outfile, sqlite3_column_blob(pTableInfo, col), size))) {
|
|
|
|
assert(rc == (int)size);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SQLITE_NULL:
|
2021-03-11 20:48:32 -05:00
|
|
|
printf("(null)\n");
|
2021-03-11 12:48:15 -05:00
|
|
|
break;
|
|
|
|
default:
|
2021-03-11 20:48:32 -05:00
|
|
|
printf(" *Cannot determine SQLITE TYPE* col=%d\n", col);
|
2021-03-11 12:48:15 -05:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2021-03-11 17:23:43 -05:00
|
|
|
static int run_script_callback(void *NotUsed, int argc, char **argv, char **azColName) {
|
2021-03-08 16:59:27 -05:00
|
|
|
int i;
|
|
|
|
UNUSED(NotUsed);
|
|
|
|
for (i = 0; i < argc; i++) {
|
|
|
|
printf(" => %s = %s\n", azColName[i], (argv[i] ? argv[i] : "NULL"));
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2021-03-11 12:48:15 -05:00
|
|
|
int run_script(sqlite3 * db, const char *script_filename) {
|
2021-03-11 20:48:32 -05:00
|
|
|
int rc;
|
|
|
|
char *statements, *zErrMsg;
|
2021-03-08 16:59:27 -05:00
|
|
|
zErrMsg = 0;
|
2021-03-11 20:48:32 -05:00
|
|
|
if (!(statements = file_read(script_filename, NULL))) {
|
|
|
|
fprintf(stderr, string_errmsg_readfile, script_filename);
|
2021-03-09 01:39:19 -05:00
|
|
|
return -1;
|
2021-03-08 16:59:27 -05:00
|
|
|
}
|
2021-03-11 20:48:32 -05:00
|
|
|
rc = sqlite3_exec(db, statements, run_script_callback, 0, &zErrMsg);
|
|
|
|
if (SQLITE_OK != rc) {
|
|
|
|
fprintf(stderr, " !! SQL error: %s\n", sqlite3_errmsg(db));
|
|
|
|
sqlite3_free(zErrMsg);
|
|
|
|
}
|
|
|
|
#if 0
|
|
|
|
for (j = 1, str1 = statements;; j++, str1 = NULL) {
|
2021-03-08 16:59:27 -05:00
|
|
|
token = strtok_r(str1, "\n", &saveptr1);
|
|
|
|
if (token == NULL)
|
|
|
|
break;
|
2021-03-08 23:16:14 -05:00
|
|
|
if (strlen(token) > 2 && token[0] == '-' && token[1] == '-')
|
2021-03-11 12:48:15 -05:00
|
|
|
continue; /* Comment line; TODO multiline comment */
|
2021-03-08 16:59:27 -05:00
|
|
|
printf("%d: %s\n", j, token);
|
2021-03-11 17:23:43 -05:00
|
|
|
rc = sqlite3_exec(db, token, run_script_callback, 0, &zErrMsg);
|
2021-03-11 12:48:15 -05:00
|
|
|
if (SQLITE_OK != rc) {
|
2021-03-09 01:39:19 -05:00
|
|
|
fprintf(stderr, " !! SQL error: %s\n", sqlite3_errmsg(db));
|
2021-03-08 16:59:27 -05:00
|
|
|
sqlite3_free(zErrMsg);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-03-11 20:48:32 -05:00
|
|
|
#endif
|
|
|
|
free(statements);
|
2021-03-08 16:59:27 -05:00
|
|
|
fprintf(stderr, "Bye!\n");
|
2021-03-11 12:48:15 -05:00
|
|
|
return SQLITE_OK;
|
2021-03-08 16:59:27 -05:00
|
|
|
}
|
2021-03-11 12:48:15 -05:00
|
|
|
int run_one(sqlite3 * db, const char *query) {
|
2021-03-11 13:25:53 -05:00
|
|
|
int i, n, rc;
|
2021-03-11 12:48:15 -05:00
|
|
|
sqlite3_stmt *stmt = NULL;
|
|
|
|
printf("> %s\n", query);
|
|
|
|
if (SQLITE_OK != (rc = sqlite3_prepare_v2(db, query, -1, &stmt, 0))) {
|
2021-03-11 20:48:32 -05:00
|
|
|
fprintf(stderr, string_errmsg_prepare, sqlite3_errmsg(db));
|
2021-03-11 12:48:15 -05:00
|
|
|
return SQLITE_ERROR;
|
|
|
|
}
|
|
|
|
while (SQLITE_ROW == (rc = sqlite3_step(stmt))) {
|
2021-03-11 13:25:53 -05:00
|
|
|
n = sqlite3_column_count(stmt);
|
|
|
|
for (i = 0; i < n; ++i) {
|
2021-03-11 12:48:15 -05:00
|
|
|
printf(" => ");
|
|
|
|
print_col(stmt, i);
|
|
|
|
puts("");
|
|
|
|
}
|
2021-03-08 16:59:27 -05:00
|
|
|
}
|
2021-03-11 13:25:53 -05:00
|
|
|
if (SQLITE_DONE != rc) {
|
2021-03-11 20:48:32 -05:00
|
|
|
fprintf(stderr, string_errmsg_update, sqlite3_errmsg(db));
|
2021-03-11 12:48:15 -05:00
|
|
|
}
|
|
|
|
if (SQLITE_OK != (rc = sqlite3_reset(stmt))) {
|
2021-03-11 20:48:32 -05:00
|
|
|
fprintf(stderr, string_errmsg_reset, sqlite3_errmsg(db));
|
2021-03-11 12:48:15 -05:00
|
|
|
}
|
|
|
|
if (SQLITE_OK != (rc = sqlite3_clear_bindings(stmt))) {
|
2021-03-11 20:48:32 -05:00
|
|
|
fprintf(stderr, string_errmsg_clear, sqlite3_errmsg(db));
|
2021-03-11 12:48:15 -05:00
|
|
|
}
|
|
|
|
return sqlite3_finalize(stmt);
|
|
|
|
}
|
|
|
|
int update_one(sqlite3 * db, int rowid, const char *param1, const char *param2) {
|
|
|
|
const char insert_stmt[] = "update quotedb set ? = ? where quote_id = ?";
|
|
|
|
int n, rc;
|
|
|
|
size_t maxlen;
|
|
|
|
sqlite3_stmt *stmt = NULL;
|
|
|
|
maxlen = 4096;
|
|
|
|
n = 0;
|
|
|
|
if (SQLITE_OK != (rc = sqlite3_prepare_v2(db, insert_stmt, -1, &stmt, 0))) {
|
2021-03-11 20:48:32 -05:00
|
|
|
fprintf(stderr, string_errmsg_prepare, sqlite3_errmsg(db));
|
2021-03-11 12:48:15 -05:00
|
|
|
return SQLITE_ERROR;
|
|
|
|
}
|
|
|
|
#define S(x) if (SQLITE_OK != (rc = sqlite3_bind_text(stmt, ++n, x, (int)strnlen(x, maxlen), SQLITE_STATIC))) { \
|
2021-03-11 20:48:32 -05:00
|
|
|
fprintf(stderr, string_errmsg_bind, sqlite3_errmsg(db)); \
|
2021-03-11 12:48:15 -05:00
|
|
|
return SQLITE_ERROR; \
|
|
|
|
}
|
|
|
|
S(param1);
|
|
|
|
S(param2);
|
|
|
|
#undef S
|
|
|
|
sqlite3_bind_int(stmt, 3, rowid);
|
|
|
|
if (SQLITE_DONE != (rc = sqlite3_step(stmt))) {
|
2021-03-11 20:48:32 -05:00
|
|
|
fprintf(stderr, string_errmsg_update, sqlite3_errmsg(db));
|
2021-03-11 12:48:15 -05:00
|
|
|
}
|
|
|
|
if (SQLITE_OK != (rc = sqlite3_reset(stmt))) {
|
2021-03-11 20:48:32 -05:00
|
|
|
fprintf(stderr, string_errmsg_reset, sqlite3_errmsg(db));
|
2021-03-11 12:48:15 -05:00
|
|
|
}
|
|
|
|
return sqlite3_finalize(stmt);
|
|
|
|
}
|
|
|
|
int insert_row(sqlite3 * db, const char *channel, const char *added_by, const char *subject, const char *words) {
|
|
|
|
const char insert_stmt[] = "insert into quotedb (date_added, channel, added_by, subject, words) values (datetime('now'), ?, ?, ?, ?)";
|
|
|
|
int n, rc;
|
|
|
|
size_t maxlen;
|
|
|
|
sqlite3_stmt *stmt = NULL;
|
|
|
|
maxlen = 4096;
|
|
|
|
n = 0;
|
|
|
|
if (SQLITE_OK != (rc = sqlite3_prepare_v2(db, insert_stmt, -1, &stmt, 0))) {
|
2021-03-11 20:48:32 -05:00
|
|
|
fprintf(stderr, string_errmsg_prepare, sqlite3_errmsg(db));
|
2021-03-11 12:48:15 -05:00
|
|
|
return SQLITE_ERROR;
|
|
|
|
}
|
|
|
|
#define S(x) if (SQLITE_OK != (rc = sqlite3_bind_text(stmt, ++n, x, (int)strnlen(x, maxlen), SQLITE_STATIC))) { \
|
2021-03-11 20:48:32 -05:00
|
|
|
fprintf(stderr, string_errmsg_bind, sqlite3_errmsg(db)); \
|
2021-03-11 12:48:15 -05:00
|
|
|
return SQLITE_ERROR; \
|
|
|
|
}
|
|
|
|
S(channel);
|
|
|
|
S(added_by);
|
|
|
|
S(subject);
|
|
|
|
S(words);
|
|
|
|
#undef S
|
|
|
|
if (SQLITE_DONE != (rc = sqlite3_step(stmt))) {
|
2021-03-11 20:48:32 -05:00
|
|
|
fprintf(stderr, string_errmsg_insert, sqlite3_errmsg(db));
|
2021-03-11 12:48:15 -05:00
|
|
|
}
|
|
|
|
if (SQLITE_OK != (rc = sqlite3_reset(stmt))) {
|
2021-03-11 20:48:32 -05:00
|
|
|
fprintf(stderr, string_errmsg_reset, sqlite3_errmsg(db));
|
2021-03-11 12:48:15 -05:00
|
|
|
}
|
|
|
|
return sqlite3_finalize(stmt);
|
|
|
|
}
|
|
|
|
int sqlite_version(sqlite3 * db) {
|
|
|
|
int rc;
|
|
|
|
sqlite3_stmt *stmt = NULL;
|
|
|
|
if (SQLITE_OK != (rc = sqlite3_prepare_v2(db, "SELECT SQLITE_VERSION()", -1, &stmt, 0))) {
|
2021-03-11 20:48:32 -05:00
|
|
|
fprintf(stderr, string_errmsg_prepare, sqlite3_errmsg(db));
|
2021-03-11 12:48:15 -05:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (SQLITE_ROW == (rc = sqlite3_step(stmt))) {
|
|
|
|
printf("SQLite version: %s\n", sqlite3_column_text(stmt, 0));
|
|
|
|
}
|
2021-03-11 20:48:32 -05:00
|
|
|
return sqlite3_finalize(stmt);
|
2021-03-08 16:59:27 -05:00
|
|
|
}
|