#define _POSIX_C_SOURCE 200809L #include #include #include #include #include "sqlite3.h" #include "zpm.h" void zpm_note_ack(struct zpm *zpm, int64_t note) { char *in = "update notes set ack = 1 where id = %" PRId64; zpm_db_run(zpm, in, note); } void zpm_note_unack(struct zpm *zpm, int64_t note) { char *in = "update notes set ack = 0 where id = %" PRId64; zpm_db_run(zpm, in, note); } void zpm_note_del(struct zpm *zpm, int64_t note) { char *in = "delete from notes where id = %" PRId64; zpm_db_run(zpm, in, note); } static char *colstring(sqlite3_stmt *s, int col) { const char *val; char *dup = 0; val = (const char *)sqlite3_column_text(s, col); if (val) { dup = strdup(val); } return dup; } /* normally unacked only */ /* 0x1 = next note, * 0x2 = include acked * 0x4 = suppress unack, implies 0x2 */ /* TODO filter on pkgid/path/hash if not null */ int64_t zpm_note(struct zpm *zpm, struct zpm_note *n, unsigned int flags) { char *op = "=", *ack = " and ack = 0"; sqlite3_stmt *st; int64_t id = 0; if (flags & 0x1) { op = ">"; } if (flags & 0x4) { ack = " and ack = 1"; } else if (flags & 0x2) { ack = ""; } st = zpm_dbquery(zpm, "select id,ts,note,pkgid,path,file,ack " "from notes where id %s %" PRId64 "%s %s", op, n->id, ack); switch (sqlite3_step(st)) { case SQLITE_DONE: /* not found */ break; case SQLITE_ROW: n->note = colstring(st, 2); n->pkgid = colstring(st, 3); n->path = colstring(st, 4); n->file = colstring(st, 5); n->ack = sqlite3_column_int(st, 6); n->ts = colstring(st, 1); n->id = sqlite3_column_int64(st, 0); id = n->id; break; default: zpm->error = 1; zpm->errmsg = strdup(sqlite3_errmsg(zpm->db)); break; } return id; } /* free any memory */ void zpm_note_free(struct zpm_note *n) { free(n->note); free(n->pkgid); free(n->path); free(n->file); free(n->ts); n->note = n->ts = n->pkgid = n->path = n->file = 0; } int zpm_notes_available(struct zpm *zpm, int flags) { int total; char *sql; if (!flags) { sql = "select count(*) from notes where ack = 0"; } else { sql = "select count(*) from notes"; } total = zpm_db_int(zpm, sql); return total; } /* get up to n notes following. return total number of notes found */ /* set the first note id to the id before the first one you want * or to 0 to start at the beginning. This can then * be iterated up to n notes at a time by setting the id of the * first one to the id found in the last one. */ int zpm_notes(struct zpm *zpm, int n, struct zpm_note *note) { int64_t id; int i; for (i = 0; i < n; i++) { id = zpm_note(zpm, note, 1); if (!id) { break; } note++; if (i < 0) { note->id = id; } } return i; } int64_t zpm_note_next(struct zpm *zpm, struct zpm_note *n) { return zpm_note(zpm, n, 1); } int64_t zpm_note_add(struct zpm *zpm, char *pkgid, char *path, char *filehash, char *notefmt, ...) { sqlite3_stmt *st; char *note; va_list ap; int64_t id = 0; char *in = "insert into notes (note,pkgid,path,file) values (?,?,?,?);"; if (!notefmt) { return 0; } st = zpm_dbquery(zpm, in); if (!st) { zpm->error = 1; zpm->errmsg = strdup(sqlite3_errmsg(zpm->db)); return 0; } va_start(ap, notefmt); note = sqlite3_vmprintf(notefmt, ap); va_end(ap); if (!note) { zpm->error = 1; zpm_seterror(zpm, "can't alloc"); } sqlite3_bind_text(st, 1, note, -1, SQLITE_STATIC); sqlite3_bind_text(st, 2, pkgid, -1, SQLITE_STATIC); sqlite3_bind_text(st, 3, path, -1, SQLITE_STATIC); sqlite3_bind_text(st, 4, filehash, -1, SQLITE_STATIC); switch (sqlite3_step(st)) { case SQLITE_DONE: id = sqlite3_last_insert_rowid(zpm->db); break; default: zpm->error = 1; zpm->errmsg = strdup(sqlite3_errmsg(zpm->db)); break; } sqlite3_finalize(st); sqlite3_free(note); return id; }