]> pd.if.org Git - zpackage/blob - lib/notes.c
fixes for zpm-update
[zpackage] / lib / notes.c
1 #define _POSIX_C_SOURCE 200809L
2
3 #include <inttypes.h>
4 #include <stdarg.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include "sqlite3.h"
9 #include "zpm.h"
10
11 void zpm_note_ack(struct zpm *zpm, int64_t note) {
12         char *in = "update notes set ack = 1 where id = %" PRId64;
13         zpm_db_run(zpm, in, note);
14 }
15
16 void zpm_note_unack(struct zpm *zpm, int64_t note) {
17         char *in = "update notes set ack = 0 where id = %" PRId64;
18         zpm_db_run(zpm, in, note);
19 }
20
21 void zpm_note_del(struct zpm *zpm, int64_t note) {
22         char *in = "delete from notes where id = %" PRId64;
23         zpm_db_run(zpm, in, note);
24 }
25
26 static char *colstring(sqlite3_stmt *s, int col) {
27         const char *val;
28         char *dup = 0;
29
30         val = (const char *)sqlite3_column_text(s, col);
31         if (val) {
32                 dup = strdup(val);
33         }
34         return dup;
35 }
36
37 /* normally unacked only */
38 /* 0x1 = next note,
39  * 0x2 = include acked
40  * 0x4 = suppress unack, implies 0x2
41  */
42 /* TODO filter on pkgid/path/hash if not null */
43 int64_t zpm_note(struct zpm *zpm, struct zpm_note *n, unsigned int flags) {
44         char *op = "=", *ack = " and ack = 0";
45
46         sqlite3_stmt *st;
47         int64_t id = 0;
48
49         if (flags & 0x1) {
50                 op = ">";
51         }
52
53         if (flags & 0x4) {
54                 ack = " and ack = 1";
55         } else if (flags & 0x2) {
56                 ack = "";
57         }
58
59         st = zpm_dbquery(zpm, "select id,ts,note,pkgid,path,file,ack "
60                         "from notes where id %s %" PRId64 "%s %s",
61                         op, n->id, ack);
62
63         switch (sqlite3_step(st)) {
64                 case SQLITE_DONE: /* not found */
65                         break;
66                 case SQLITE_ROW:
67                         n->note = colstring(st, 2);
68                         n->pkgid = colstring(st, 3);
69                         n->path = colstring(st, 4);
70                         n->file = colstring(st, 5);
71                         n->ack = sqlite3_column_int(st, 6);
72                         n->ts = colstring(st, 1);
73                         n->id = sqlite3_column_int64(st, 0);
74                         id = n->id;
75                         break;
76                 default: zpm->error = 1;
77                          zpm->errmsg = strdup(sqlite3_errmsg(zpm->db));
78                          break;
79         }
80
81         return id;
82 }
83
84 /* free any memory */
85 void zpm_note_free(struct zpm_note *n) {
86         free(n->note);
87         free(n->pkgid);
88         free(n->path);
89         free(n->file);
90         free(n->ts);
91         n->note = n->ts = n->pkgid = n->path = n->file = 0;
92 }
93
94 int zpm_notes_available(struct zpm *zpm, int flags) {
95         int total;
96         char *sql;
97
98         if (!flags) {
99                 sql = "select count(*) from notes where ack = 0";
100         } else {
101                 sql = "select count(*) from notes";
102         }
103
104         total = zpm_db_int(zpm, sql);
105         return total;
106 }
107
108 /* get up to n notes following.  return total number of notes found */
109 /* set the first note id to the id before the first one you want
110  * or to 0 to start at the beginning.  This can then
111  * be iterated up to n notes at a time by setting the id of the
112  * first one to the id found in the last one.
113  */
114 int zpm_notes(struct zpm *zpm, int n, struct zpm_note *note) {
115         int64_t id;
116         int i;
117
118         for (i = 0; i < n; i++) {
119                 id = zpm_note(zpm, note, 1);
120                 if (!id) {
121                         break;
122                 }
123                 note++;
124                 if (i < 0) {
125                         note->id = id;
126                 }
127         }
128
129         return i;
130 }
131
132 int64_t zpm_note_next(struct zpm *zpm, struct zpm_note *n) {
133         return zpm_note(zpm, n, 1);
134 }
135
136 int64_t zpm_note_add(struct zpm *zpm, char *pkgid, char *path, char *filehash,
137                 char *notefmt, ...) {
138         sqlite3_stmt *st;
139         char *note;
140         va_list ap;
141         int64_t id = 0;
142         char *in = "insert into notes (note,pkgid,path,file) values (?,?,?,?);";
143
144         if (!notefmt) {
145                 return 0;
146         }
147
148         st = zpm_dbquery(zpm, in);
149
150         if (!st) {
151                 zpm->error = 1;
152                 zpm->errmsg = strdup(sqlite3_errmsg(zpm->db));
153                 return 0;
154         }
155
156         va_start(ap, notefmt);
157         note = sqlite3_vmprintf(notefmt, ap);
158         va_end(ap);
159
160         if (!note) {
161                 zpm->error = 1;
162                 zpm_seterror(zpm, "can't alloc");
163         }
164
165         sqlite3_bind_text(st, 1, note, -1, SQLITE_STATIC);
166         sqlite3_bind_text(st, 2, pkgid, -1, SQLITE_STATIC);
167         sqlite3_bind_text(st, 3, path, -1, SQLITE_STATIC);
168         sqlite3_bind_text(st, 4, filehash, -1, SQLITE_STATIC);
169
170         switch (sqlite3_step(st)) {
171                 case SQLITE_DONE:
172                         id = sqlite3_last_insert_rowid(zpm->db);
173                         break;
174                 default: zpm->error = 1;
175                          zpm->errmsg = strdup(sqlite3_errmsg(zpm->db));
176                          break;
177         }
178
179         sqlite3_finalize(st);
180         sqlite3_free(note);
181         return id;
182 }