comparison db.c @ 5:566bc028cdcb

tests: initial tests coming - Add tests for database access. - While here transform common code into libsci.a
author David Demelier <markand@malikania.fr>
date Wed, 16 Jun 2021 13:25:42 +0200
parents 9c4fea43803c
children 8c408176d2b1
comparison
equal deleted inserted replaced
4:9c4fea43803c 5:566bc028cdcb
1 /*
2 * db.c -- scid database access
3 *
4 * Copyright (c) 2021 David Demelier <markand@malikania.fr>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
1 #include <sys/queue.h> 19 #include <sys/queue.h>
2 #include <assert.h> 20 #include <assert.h>
3 #include <stdlib.h> 21 #include <stdlib.h>
4 #include <string.h> 22 #include <string.h>
5 23
76 SLIST_FOREACH_SAFE(s, l, link, tmp) { 94 SLIST_FOREACH_SAFE(s, l, link, tmp) {
77 free(s->str); 95 free(s->str);
78 free(s); 96 free(s);
79 } 97 }
80 98
81 SLIST_INIT(l); 99 free(l);
82 } 100 }
83 101
84 static void 102 static void
85 project_unpacker(sqlite3_stmt *stmt, struct db_ctx *ctx, struct project *project) 103 project_unpacker(sqlite3_stmt *stmt, struct db_ctx *ctx, struct project *project)
86 { 104 {
133 assert(sql); 151 assert(sql);
134 assert(fmt); 152 assert(fmt);
135 153
136 sqlite3_stmt *stmt = NULL; 154 sqlite3_stmt *stmt = NULL;
137 va_list ap; 155 va_list ap;
156 int ret = -1;
138 157
139 if (sqlite3_prepare(db, sql, -1, &stmt, NULL) != SQLITE_OK) 158 if (sqlite3_prepare(db, sql, -1, &stmt, NULL) != SQLITE_OK)
140 return log_warn("db: %s", sqlite3_errmsg(db)), -1; 159 return log_warn("db: %s", sqlite3_errmsg(db)), -1;
141 160
142 va_start(ap, fmt); 161 va_start(ap, fmt);
143 vbind(stmt, fmt, ap); 162 vbind(stmt, fmt, ap);
144 va_end(ap); 163 va_end(ap);
145 164
146 if (sqlite3_step(stmt) != SQLITE_DONE) { 165 if (sqlite3_step(stmt) != SQLITE_DONE)
147 log_warn("db: %s", sqlite3_errmsg(db)); 166 log_warn("db: %s", sqlite3_errmsg(db));
148 sqlite3_finalize(stmt); 167 else
149 return -1; 168 ret = sqlite3_last_insert_rowid(db);
150 } 169
151 170 sqlite3_finalize(stmt);
152 return sqlite3_last_insert_rowid(db); 171
172 return ret;
153 } 173 }
154 174
155 static ssize_t 175 static ssize_t
156 list(struct list *sel, const char *sql, const char *args, ...) 176 list(struct list *sel, const char *sql, const char *args, ...)
157 { 177 {
192 int 212 int
193 db_open(const char *path) 213 db_open(const char *path)
194 { 214 {
195 assert(path); 215 assert(path);
196 216
197 if (sqlite3_open(path, &db) != SQLITE_OK) { 217 if (sqlite3_open(path, &db) != SQLITE_OK)
198 log_warn("db: open error: %s", sqlite3_errmsg(db)); 218 return log_warn("db: open error: %s", sqlite3_errmsg(db)), -1;
199 return -1;
200 }
201 219
202 /* Wait for 30 seconds to lock the database. */ 220 /* Wait for 30 seconds to lock the database. */
203 sqlite3_busy_timeout(db, 30000); 221 sqlite3_busy_timeout(db, 30000);
204 222
205 if (sqlite3_exec(db, CHAR(sql_init), NULL, NULL, NULL) != SQLITE_OK) { 223 if (sqlite3_exec(db, CHAR(sql_init), NULL, NULL, NULL) != SQLITE_OK)
206 log_warn("db: initialization error: %s", sqlite3_errmsg(db)); 224 return log_warn("db: initialization error: %s", sqlite3_errmsg(db)), -1;
207 return -1;
208 }
209 225
210 return 0; 226 return 0;
211 } 227 }
212 228
213 int 229 int
293 .datasz = 1, 309 .datasz = 1,
294 .elemwidth = sizeof (*wk), 310 .elemwidth = sizeof (*wk),
295 .ctx = ctx 311 .ctx = ctx
296 }; 312 };
297 313
298 return list(&sel, CHAR(sql_worker_find), "s", wk->name); 314 return list(&sel, CHAR(sql_worker_find), "s", wk->name) == 1 ? 0 : -1;
299 } 315 }
300 316
301 int 317 int
302 db_worker_find_id(struct db_ctx *ctx, struct worker *wk) 318 db_worker_find_id(struct db_ctx *ctx, struct worker *wk)
303 { 319 {
307 .datasz = 1, 323 .datasz = 1,
308 .elemwidth = sizeof (*wk), 324 .elemwidth = sizeof (*wk),
309 .ctx = ctx 325 .ctx = ctx
310 }; 326 };
311 327
312 return list(&sel, CHAR(sql_worker_find_id), "i", wk->id); 328 return list(&sel, CHAR(sql_worker_find_id), "i", wk->id) == 1 ? 0 : -1;
313 } 329 }
314 330
315 int 331 int
316 db_job_add(struct job *job) 332 db_job_add(struct job *job)
317 { 333 {