changeset 9:3ef8128e244f

sci: add project-update command
author David Demelier <markand@malikania.fr>
date Wed, 23 Jun 2021 14:05:36 +0200
parents ec800a5fb7e3
children eb76429ce112
files Makefile db.c db.h req.c req.h scictl.c scid.c sql/project-update.sql tests/test-db.c
diffstat 9 files changed, 181 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Wed Jun 23 11:45:07 2021 +0200
+++ b/Makefile	Wed Jun 23 14:05:36 2021 +0200
@@ -31,9 +31,10 @@
                         sql/job-todo.h \
                         sql/jobresult-add.h \
                         sql/project-add.h \
+                        sql/project-find-id.h \
                         sql/project-find.h \
-                        sql/project-find-id.h \
                         sql/project-list.h \
+                        sql/project-update.h \
                         sql/worker-add.h \
                         sql/worker-find.h \
                         sql/worker-find-id.h \
--- a/db.c	Wed Jun 23 11:45:07 2021 +0200
+++ b/db.c	Wed Jun 23 14:05:36 2021 +0200
@@ -33,6 +33,7 @@
 #include "sql/job-todo.h"
 #include "sql/jobresult-add.h"
 #include "sql/project-add.h"
+#include "sql/project-update.h"
 #include "sql/project-find.h"
 #include "sql/project-find-id.h"
 #include "sql/project-list.h"
@@ -172,6 +173,33 @@
 	return ret;
 }
 
+static int
+update(const char *sql, const char *fmt, ...)
+{
+	assert(sql);
+	assert(fmt);
+
+	sqlite3_stmt *stmt = NULL;
+	va_list ap;
+	int ret = 1;
+
+	if (sqlite3_prepare(db, sql, -1, &stmt, NULL) != SQLITE_OK)
+		return log_warn("db: %s", sqlite3_errmsg(db)), -1;
+
+	va_start(ap, fmt);
+	vbind(stmt, fmt, ap);
+	va_end(ap);
+
+	if (sqlite3_step(stmt) != SQLITE_DONE)
+		log_warn("db: %s", sqlite3_errmsg(db));
+	else
+		ret = 0;
+
+	sqlite3_finalize(stmt);
+
+	return ret;
+}
+
 static ssize_t
 list(struct list *sel, const char *sql, const char *args, ...)
 {
@@ -233,6 +261,15 @@
 	    p->url, p->script)) < 0 ? -1 : 0;
 }
 
+int
+db_project_update(const struct project *p)
+{
+	assert(p);
+
+	return update(CHAR(sql_project_update), "ssssi", p->name, p->desc,
+	    p->url, p->script, p->id);
+}
+
 ssize_t
 db_project_list(struct db_ctx *ctx, struct project *projects, size_t projectsz)
 {
--- a/db.h	Wed Jun 23 11:45:07 2021 +0200
+++ b/db.h	Wed Jun 23 14:05:36 2021 +0200
@@ -46,6 +46,9 @@
 int
 db_project_add(struct project *);
 
+int
+db_project_update(const struct project *);
+
 ssize_t
 db_project_list(struct db_ctx *, struct project *, size_t);
 
--- a/req.c	Wed Jun 23 11:45:07 2021 +0200
+++ b/req.c	Wed Jun 23 14:05:36 2021 +0200
@@ -154,6 +154,14 @@
 }
 
 struct req
+req_project_update(const struct project *p)
+{
+	assert(p);
+
+	return exchange("project-update", project_to(p, 1));
+}
+
+struct req
 req_project_find(struct project *p, const char *name)
 {
 	assert(p);
--- a/req.h	Wed Jun 23 11:45:07 2021 +0200
+++ b/req.h	Wed Jun 23 14:05:36 2021 +0200
@@ -31,6 +31,9 @@
 req_project_add(const struct project *);
 
 struct req
+req_project_update(const struct project *);
+
+struct req
 req_project_find(struct project *, const char *);
 
 struct req
--- a/scictl.c	Wed Jun 23 11:45:07 2021 +0200
+++ b/scictl.c	Wed Jun 23 14:05:36 2021 +0200
@@ -24,6 +24,7 @@
 	fprintf(stderr, "       %s job-todo worker\n", getprogname());
 	fprintf(stderr, "       %s jobresult-add id worker exitcode console\n", getprogname());
 	fprintf(stderr, "       %s project-add name desc url script\n", getprogname());
+	fprintf(stderr, "       %s project-update name key value\n", getprogname());
 	fprintf(stderr, "       %s project-list\n", getprogname());
 	fprintf(stderr, "       %s worker-add name desc\n", getprogname());
 	fprintf(stderr, "       %s worker-list\n", getprogname());
@@ -176,6 +177,36 @@
 }
 
 static struct req
+cmd_project_update(int argc, char **argv)
+{
+	struct project pc;
+	struct req rget, rsend;
+	char *script = NULL;
+
+	if (argc < 3)
+		help();
+
+	if ((rget = req_project_find(&pc, argv[0])).status)
+		return rget;
+
+	if (strcmp(argv[1], "name") == 0)
+		pc.name = argv[2];
+	else if (strcmp(argv[1], "desc") == 0)
+		pc.desc = argv[2];
+	else if (strcmp(argv[1], "url") == 0)
+		pc.url = argv[2];
+	else if (strcmp(argv[1], "script") == 0)
+		pc.script = script = readfile(argv[2]);
+
+	rsend = req_project_update(&pc);
+
+	req_finish(&rget);
+	free(script);
+
+	return rsend;
+}
+
+static struct req
 cmd_project_find(int argc, char **argv)
 {
 	struct project project = {0};
@@ -271,6 +302,7 @@
 	{ "project-add",        cmd_project_add         },
 	{ "project-find",       cmd_project_find        },
 	{ "project-list",       cmd_project_list        },
+	{ "project-update",     cmd_project_update      },
 	{ "worker-add",         cmd_worker_add          },
 	{ "worker-list",        cmd_worker_list         },
 	{ NULL,                 NULL                    }
@@ -308,10 +340,8 @@
 			res = commands[i].exec(--argc, ++argv);
 			cmdfound = 1;
 
-#if 0
 			if (res.status)
-				warnx("%s", res.msg);
-#endif
+				warnx("%s", json_string_value(json_object_get(res.msg, "error")));
 
 			req_finish(&res);
 			break;
--- a/scid.c	Wed Jun 23 11:45:07 2021 +0200
+++ b/scid.c	Wed Jun 23 14:05:36 2021 +0200
@@ -235,6 +235,19 @@
 }
 
 static int
+cmd_project_update(int fd, json_t *doc)
+{
+	struct project pc;
+
+	if (project_from(&pc, 1, doc) < 0)
+		return EINVAL;
+	if (db_project_update(&pc) < 0)
+		return error(fd, "unable to update project");
+
+	return ok(fd);
+}
+
+static int
 cmd_worker_add(int fd, json_t *doc)
 {
 	struct worker wk = {0};
@@ -318,6 +331,7 @@
 		{ "project-find",       cmd_project_find        },
 		{ "project-find-id",    cmd_project_find_id     },
 		{ "project-list",       cmd_project_list        },
+		{ "project-update",     cmd_project_update      },
 		{ "worker-add",         cmd_worker_add          },
 		{ "worker-find",        cmd_worker_find         },
 		{ "worker-find-id",     cmd_worker_find_id      },
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sql/project-update.sql	Wed Jun 23 14:05:36 2021 +0200
@@ -0,0 +1,6 @@
+UPDATE project
+   SET name = ?
+     , desc = ?
+     , url = ?
+     , script = ?
+ WHERE id = ?
--- a/tests/test-db.c	Wed Jun 23 11:45:07 2021 +0200
+++ b/tests/test-db.c	Wed Jun 23 14:05:36 2021 +0200
@@ -183,6 +183,80 @@
 	GREATEST_PASS();
 }
 
+GREATEST_TEST
+test_projects_update(void)
+{
+	struct project proj = {
+		.name = "example 1",
+		.desc = "Example project 1",
+		.url = "example.org",
+		.script = "#!/bin/sh exit 0"
+	};
+	struct project find;
+	struct db_ctx ctx;
+
+	GREATEST_ASSERT_EQ(db_project_add(&proj), 0);
+	GREATEST_ASSERT(proj.id > 0);
+
+	/* Update name. */
+	memset(&find, 0, sizeof (find));
+	find.id = 1;
+	proj.name = "updated example 1";
+
+	GREATEST_ASSERT_EQ(db_project_update(&proj), 0);
+	GREATEST_ASSERT_EQ(db_project_find_id(&ctx, &find), 0);
+	GREATEST_ASSERT_STR_EQ(find.name, "updated example 1");
+	GREATEST_ASSERT_STR_EQ(find.desc, "Example project 1");
+	GREATEST_ASSERT_STR_EQ(find.url, "example.org");
+	GREATEST_ASSERT_STR_EQ(find.script, "#!/bin/sh exit 0");
+
+	db_ctx_finish(&ctx);
+
+	/* Update desc. */
+	memset(&find, 0, sizeof (find));
+	find.id = 1;
+	proj.desc = "updated Example project 1";
+
+	GREATEST_ASSERT_EQ(db_project_update(&proj), 0);
+	GREATEST_ASSERT_EQ(db_project_find_id(&ctx, &find), 0);
+	GREATEST_ASSERT_STR_EQ(find.name, "updated example 1");
+	GREATEST_ASSERT_STR_EQ(find.desc, "updated Example project 1");
+	GREATEST_ASSERT_STR_EQ(find.url, "example.org");
+	GREATEST_ASSERT_STR_EQ(find.script, "#!/bin/sh exit 0");
+
+	db_ctx_finish(&ctx);
+
+	/* Update url. */
+	memset(&find, 0, sizeof (find));
+	find.id = 1;
+	proj.url = "updated example.org";
+
+	GREATEST_ASSERT_EQ(db_project_update(&proj), 0);
+	GREATEST_ASSERT_EQ(db_project_find_id(&ctx, &find), 0);
+	GREATEST_ASSERT_STR_EQ(find.name, "updated example 1");
+	GREATEST_ASSERT_STR_EQ(find.desc, "updated Example project 1");
+	GREATEST_ASSERT_STR_EQ(find.url, "updated example.org");
+	GREATEST_ASSERT_STR_EQ(find.script, "#!/bin/sh exit 0");
+
+	db_ctx_finish(&ctx);
+
+	/* Update script. */
+	memset(&find, 0, sizeof (find));
+	find.id = 1;
+	proj.script = "#!/bin/sh exit 1";
+
+	GREATEST_ASSERT_EQ(db_project_update(&proj), 0);
+	GREATEST_ASSERT_EQ(db_project_find_id(&ctx, &find), 0);
+	GREATEST_ASSERT_STR_EQ(find.name, "updated example 1");
+	GREATEST_ASSERT_STR_EQ(find.desc, "updated Example project 1");
+	GREATEST_ASSERT_STR_EQ(find.url, "updated example.org");
+	GREATEST_ASSERT_STR_EQ(find.script, "#!/bin/sh exit 1");
+
+	db_ctx_finish(&ctx);
+
+	GREATEST_PASS();
+}
+
 GREATEST_SUITE(suite_projects)
 {
 	GREATEST_SET_SETUP_CB(setup, NULL);
@@ -191,6 +265,7 @@
 	GREATEST_RUN_TEST(test_projects_list);
 	GREATEST_RUN_TEST(test_projects_find);
 	GREATEST_RUN_TEST(test_projects_find_id);
+	GREATEST_RUN_TEST(test_projects_update);
 }
 
 GREATEST_TEST
@@ -385,7 +460,6 @@
 	GREATEST_RUN_TEST(test_jobs_todo);
 }
 
-
 GREATEST_TEST
 test_jobresults_add(void)
 {