#define _POSIX_C_SOURCE 200809L #include #include #include #include "sqlite3.h" #include "zpm.h" #define SQLERROR(x) fprintf(stderr, "%s %d: %s\n", __func__, __LINE__, (x)) sqlite3_stmt *zpm_dbqueryv(struct zpm *zpm, char *query, va_list args) { sqlite3 *db; char *sql; sqlite3_stmt *st; int rv; if (!zpm || zpm->error) { return 0; } if (!zpm->db) { zpm->error = 1; return 0; } db = zpm->db; sql = sqlite3_vmprintf(query, args); if (!sql) { zpm->error = 1; return 0; } rv = sqlite3_prepare_v2(db, sql, strlen(sql), &st, NULL); if (rv != SQLITE_OK) { SQLERROR(sqlite3_errmsg(db)); fprintf(stderr, "sql (%d): %s\n", rv, sql); zpm->error = rv; return 0; } sqlite3_free(sql); return st; } sqlite3_stmt *zpm_dbquery(struct zpm *zpm, char *query, ...) { va_list args; sqlite3_stmt *st; if (!zpm || zpm->error) { return 0; } if (!zpm->db) { zpm->error = 1; return 0; } va_start(args, query); st = zpm_dbqueryv(zpm, query, args); va_end(args); return st; } int zpm_db_run(struct zpm *zpm, char *query, ...) { sqlite3_stmt *st; va_list args; int rv; va_start(args, query); st = zpm_dbqueryv(zpm, query, args); va_end(args); rv = sqlite3_step(st); if (rv != SQLITE_DONE) { zpm->error = 1; zpm_seterror(zpm, "db error: %s", sqlite3_errstr(rv)); } return sqlite3_finalize(st); } int zpm_findhash(struct zpm *zpm, char *find, char *dest) { int count; char *found; count = zpm_db_int(zpm, "select count(*) from files where hash like '%q%%';", find); if (count != 1) { return count; } if (dest) { found = zpm_db_string(zpm, "select hash from files where hash like '%s%%' limit 1;", find); if (find) { strcpy(dest, found); free(found); } else { count = 0; } } return count; } char *zpm_db_string(struct zpm *zpm, char *query, ...) { sqlite3_stmt *st; va_list args; int rv; char *result = 0; va_start(args, query); st = zpm_dbqueryv(zpm, query, args); va_end(args); rv = sqlite3_step(st); switch (rv) { case SQLITE_ROW: result = (char *)sqlite3_column_text(st, 0); if (result) { result = strdup(result); } break; case SQLITE_DONE: break; default: zpm->error = 1; zpm_seterror(zpm, "db error: %s", sqlite3_errstr(rv)); break; } sqlite3_finalize(st); return result; } int zpm_db_int(struct zpm *zpm, char *query, ...) { sqlite3_stmt *st; va_list args; int rv; int result = 0; va_start(args, query); st = zpm_dbqueryv(zpm, query, args); va_end(args); rv = sqlite3_step(st); if (rv == SQLITE_ROW) { result = sqlite3_column_int(st, 0); } /* TODO set error if it's not SQLITE_ROW */ sqlite3_finalize(st); return result; }