Mercurial > sci
view db.c @ 1:5afdb14df924
sci: add support for storing results
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 08 Jun 2021 08:40:01 +0200 |
parents | f1de39079243 |
children | 5fa3d2f479b2 |
line wrap: on
line source
#include <assert.h> #include <stdlib.h> #include <string.h> #include <sqlite3.h> #include "db.h" #include "job.h" #include "log.h" #include "project.h" #include "worker.h" #include "sql/init.h" #include "sql/job-queue.h" #include "sql/job-queue-list.h" #include "sql/job-save.h" #include "sql/project-insert.h" #include "sql/project-get.h" #include "sql/project-find.h" #include "sql/worker-get.h" #include "sql/worker-find.h" #include "sql/worker-insert.h" #define CHAR(v) (const char *)(v) static sqlite3 *db; static inline void convert_project(struct project *project, sqlite3_stmt *stmt) { project->id = sqlite3_column_int64(stmt, 0); strlcpy(project->name, CHAR(sqlite3_column_text(stmt, 1)), sizeof (project->name)); strlcpy(project->desc, CHAR(sqlite3_column_text(stmt, 2)), sizeof (project->desc)); strlcpy(project->url, CHAR(sqlite3_column_text(stmt, 3)), sizeof (project->url)); strlcpy(project->script, CHAR(sqlite3_column_text(stmt, 4)), sizeof (project->script)); } int db_open(const char *path) { assert(path); if (sqlite3_open(path, &db) != SQLITE_OK) { log_warn("db: open error: %s", sqlite3_errmsg(db)); return -1; } /* Wait for 30 seconds to lock the database. */ sqlite3_busy_timeout(db, 30000); if (sqlite3_exec(db, CHAR(sql_init), NULL, NULL, NULL) != SQLITE_OK) { log_warn("db: initialization error: %s", sqlite3_errmsg(db)); return -1; } return 0; } int db_project_add(struct project *pj) { assert(pj); sqlite3_stmt *stmt = NULL; int ret = -1; if (sqlite3_prepare(db, CHAR(sql_project_insert), -1, &stmt, NULL) != SQLITE_OK) goto sqlite3_err; sqlite3_bind_text(stmt, 1, pj->name, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 2, pj->desc, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 3, pj->url, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 4, pj->script, -1, SQLITE_STATIC); if (sqlite3_step(stmt) != SQLITE_DONE) goto sqlite3_err; pj->id = sqlite3_last_insert_rowid(db); ret = 0; sqlite3_err: if (stmt) sqlite3_finalize(stmt); return ret; } ssize_t db_project_get(struct project *projects, size_t projectsz) { assert(projects); sqlite3_stmt *stmt = NULL; struct project *p = projects; ssize_t ret = 0; if (sqlite3_prepare(db, CHAR(sql_project_get), -1, &stmt, NULL) != SQLITE_OK) { log_warn("db: %s", sqlite3_errmsg(db)); return -1; } sqlite3_bind_int64(stmt, 1, projectsz); for (; sqlite3_step(stmt) == SQLITE_ROW && (size_t)ret < projectsz; ++ret, ++p) convert_project(p, stmt); if (stmt) sqlite3_finalize(stmt); return ret; } int db_project_find(struct project *project) { assert(project); sqlite3_stmt *stmt = NULL; int ret = -1; if (sqlite3_prepare(db, CHAR(sql_project_find), -1, &stmt, NULL) != SQLITE_OK) goto sqlite3_err; sqlite3_bind_text(stmt, 1, project->name, -1, SQLITE_STATIC); if (sqlite3_step(stmt) != SQLITE_ROW) goto sqlite3_err; ret = 0; convert_project(project, stmt); sqlite3_err: if (ret < 0) log_warn("db: %s", sqlite3_errmsg(db)); if (stmt) sqlite3_finalize(stmt); return ret; } int db_worker_add(struct worker *wk) { assert(wk); sqlite3_stmt *stmt = NULL; int ret = -1; if (sqlite3_prepare(db, CHAR(sql_worker_insert), -1, &stmt, NULL) != SQLITE_OK) goto sqlite3_err; sqlite3_bind_text(stmt, 1, wk->name, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 2, wk->desc, -1, SQLITE_STATIC); if (sqlite3_step(stmt) != SQLITE_DONE) goto sqlite3_err; wk->id = sqlite3_last_insert_rowid(db); ret = 0; sqlite3_err: if (stmt) sqlite3_finalize(stmt); return ret; } ssize_t db_worker_get(struct worker *wk, size_t wksz) { assert(wk); sqlite3_stmt *stmt = NULL; struct worker *w = wk; ssize_t ret = -1; if (sqlite3_prepare(db, CHAR(sql_worker_get), -1, &stmt, NULL) != SQLITE_OK) goto sqlite3_err; sqlite3_bind_int64(stmt, 1, wksz); for (ret = 0; sqlite3_step(stmt) == SQLITE_ROW && (size_t)ret < wksz; ++ret, ++w) { w->id = sqlite3_column_int64(stmt, 0); strlcpy(w->name, CHAR(sqlite3_column_text(stmt, 1)), sizeof (w->name)); strlcpy(w->desc, CHAR(sqlite3_column_text(stmt, 2)), sizeof (w->desc)); } sqlite3_err: if (ret < 0) log_warn("db: %s", sqlite3_errmsg(db)); if (stmt) sqlite3_finalize(stmt); return ret; } int db_worker_find(struct worker *w, const char *name) { assert(w); assert(name); sqlite3_stmt *stmt = NULL; int ret = -1; if (sqlite3_prepare(db, CHAR(sql_worker_find), -1, &stmt, NULL) != SQLITE_OK) goto sqlite3_err; sqlite3_bind_text(stmt, 1, name, -1, SQLITE_STATIC); if (sqlite3_step(stmt) != SQLITE_ROW) goto sqlite3_err; ret = 0; w->id = sqlite3_column_int64(stmt, 0); strlcpy(w->name, CHAR(sqlite3_column_text(stmt, 1)), sizeof (w->name)); strlcpy(w->desc, CHAR(sqlite3_column_text(stmt, 2)), sizeof (w->desc)); sqlite3_err: if (ret < 0) log_warn("db: %s", sqlite3_errmsg(db)); if (stmt) sqlite3_finalize(stmt); return ret; } int db_job_queue(struct job *job) { assert(job); sqlite3_stmt *stmt = NULL; int ret = -1; if (sqlite3_prepare(db, CHAR(sql_job_queue), -1, &stmt, NULL) != SQLITE_OK) goto sqlite3_err; sqlite3_bind_text(stmt, 1, job->tag, -1, SQLITE_STATIC); sqlite3_bind_int64(stmt, 2, job->project.id); if (sqlite3_step(stmt) != SQLITE_DONE) goto sqlite3_err; job->id = sqlite3_last_insert_rowid(db); ret = 0; sqlite3_err: if (ret < 0) log_warn("db: %s", sqlite3_errmsg(db)); if (stmt) sqlite3_finalize(stmt); return ret; } ssize_t db_job_result_todo(struct job_result *re, size_t resz, int64_t project_id) { assert(re); sqlite3_stmt *stmt = NULL; ssize_t ret = 0; if (sqlite3_prepare(db, CHAR(sql_job_queue_list), -1, &stmt, NULL) != SQLITE_OK) { log_warn("db: %s", sqlite3_errmsg(db)); return -1; } sqlite3_bind_int64(stmt, 1, project_id); sqlite3_bind_int64(stmt, 2, resz); while (sqlite3_step(stmt) == SQLITE_ROW && (size_t)ret++ < resz) { memset(re, 0, sizeof (*re)); re->job.id = sqlite3_column_int64(stmt, 0); strlcpy(re->job.tag, CHAR(sqlite3_column_text(stmt, 1)), sizeof (re->job.tag)); re->worker.id = sqlite3_column_int64(stmt, 2); strlcpy(re->worker.name, CHAR(sqlite3_column_text(stmt, 3)), sizeof (re->worker.name)); strlcpy(re->worker.desc, CHAR(sqlite3_column_text(stmt, 4)), sizeof (re->worker.desc)); re->job.project.id = sqlite3_column_int64(stmt, 5); strlcpy(re->job.project.name, CHAR(sqlite3_column_text(stmt, 6)), sizeof (re->job.project.name)); strlcpy(re->job.project.desc, CHAR(sqlite3_column_text(stmt, 7)), sizeof (re->job.project.desc)); strlcpy(re->job.project.url, CHAR(sqlite3_column_text(stmt, 8)), sizeof (re->job.project.url)); strlcpy(re->job.project.script, CHAR(sqlite3_column_text(stmt, 9)), sizeof (re->job.project.script)); ++re; }; if (stmt) sqlite3_finalize(stmt); return ret; } int db_job_save(struct job_result *r) { assert(r); sqlite3_stmt *stmt = NULL; int ret = -1; if (sqlite3_prepare(db, CHAR(sql_job_save), -1, &stmt, NULL) != SQLITE_OK) goto sqlite3_err; sqlite3_bind_int64(stmt, 1, r->job.id); sqlite3_bind_int64(stmt, 2, r->worker.id); sqlite3_bind_int(stmt, 3, r->status); sqlite3_bind_int(stmt, 4, r->retcode); sqlite3_bind_text(stmt, 5, r->console, -1, SQLITE_STATIC); if (sqlite3_step(stmt) != SQLITE_DONE) goto sqlite3_err; ret = 0; r->id = sqlite3_last_insert_rowid(db); sqlite3_err: if (ret < 0) log_warn("db: %s", sqlite3_errmsg(db)); if (stmt) sqlite3_finalize(stmt); return ret; } void db_finish(void) { if (db) { sqlite3_close(db); db = NULL; } }